Skip to content

Commit

Permalink
Add a test for multiprocess stepping
Browse files Browse the repository at this point in the history
Summary: ^

Reviewed By: jcpetruzza

Differential Revision: D68572780

fbshipit-source-id: a63a8baf7a0969c3a7c0f27c73c592d7163a8d5c
  • Loading branch information
Thibault Suzanne authored and facebook-github-bot committed Jan 24, 2025
1 parent 6777492 commit 35f5929
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 2 deletions.
97 changes: 96 additions & 1 deletion test/edb_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
-export([test_step_over_into_caller_handler/1]).
-export([test_step_over_progresses_from_breakpoint/1]).
-export([test_breakpoint_consumes_step/1]).
-export([test_multiprocess_parallel_steps/1]).

%% Test cases for the test_step_out group
-export([test_step_out_of_external_closure/1]).
Expand Down Expand Up @@ -115,7 +116,8 @@ groups() ->
test_step_over_into_local_handler,
test_step_over_into_caller_handler,
test_step_over_progresses_from_breakpoint,
test_breakpoint_consumes_step
test_breakpoint_consumes_step,
test_multiprocess_parallel_steps
]},
{test_step_out, [], [
test_step_out_of_external_closure,
Expand Down Expand Up @@ -1734,6 +1736,99 @@ test_breakpoint_consumes_step(_Config) ->

ok.

test_multiprocess_parallel_steps(_Config) ->
% Helper function that we'll use to check that processes are currently executing a step
% Each step being awaiting on receiving a message, the Pid status can be either running or waiting
AssertInStep = fun(Pid) ->
{status, Status} = process_info(Pid, status),
?assert(Status =:= waiting orelse Status =:= running)
end,

% Add a breakpoint to start stepping from
ok = edb:add_breakpoint(test_step_over, 100),

% Spawn one process that will hit the breakpoint
Pid1 = erlang:spawn(test_step_over, awaiting_steps, []),
{ok, stopped} = edb:wait(),

% Sanity check that we hit the breakpoint
?assertEqual(
#{Pid1 => #{line => 100, module => test_step_over}},
edb:get_breakpoints_hit()
),

% Engage the process into an awaiting step
ok = edb:step_over(Pid1),

% Spawn another process that will hit the breakpoint while the first is awaiting a step
Pid2 = erlang:spawn(test_step_over, awaiting_steps, []),
{ok, stopped} = edb:wait(),

% Pid2 should have hit its breakpoint
?assertEqual(
#{Pid2 => #{line => 100, module => test_step_over}},
edb:get_breakpoints_hit()
),

% Pid1 in await, Pid2 on a step
% Step Pid2 to resume the execution
ok = edb:step_over(Pid2),

% Now both processes should be awaiting
AssertInStep(Pid1),
AssertInStep(Pid2),

% Unblock Pid1 and wait for it to complete its step
Pid1 ! continue,
edb:wait(),

% Check that Pid1 has completed its step
?assertMatch(
{ok, [
#{mfa := {test_step_over, awaiting_steps, 0}, line := 101}
]},
edb:stack_frames(Pid1)
),

% Engage Pid1 on a step again to resume the execution
ok = edb:step_over(Pid1),

% Both processes await
AssertInStep(Pid1),
AssertInStep(Pid2),

% Unblock Pid2 and wait for it to complete its (still first) step
Pid2 ! continue,
edb:wait(),

% Pid2 should now have finally completed its step
?assertMatch(
{ok, [
#{mfa := {test_step_over, awaiting_steps, 0}, line := 101}
]},
edb:stack_frames(Pid2)
),

% Check the delivered events
?assertEqual(
[
{stopped, {paused, all}},
{stopped, {breakpoint, Pid1, {test_step_over, awaiting_steps, 0}, {line, 100}}},
{resumed, {continue, all}},
{stopped, {paused, all}},
{stopped, {breakpoint, Pid2, {test_step_over, awaiting_steps, 0}, {line, 100}}},
{resumed, {continue, all}},
{stopped, {paused, all}},
{stopped, {step, Pid1}},
{resumed, {continue, all}},
{stopped, {paused, all}},
{stopped, {step, Pid2}}
],
edb_test_support:collected_events()
),

ok.

%% ------------------------------------------------------------------
%% Test cases for test_step_out fixture
%% ------------------------------------------------------------------
Expand Down
16 changes: 15 additions & 1 deletion test/edb_SUITE_data/test_step_over.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

-compile([warn_missing_spec_all]).

-export([go/1, cycle/2, just_sync/1, just_sync/2, call_closure/1, call_external_closure/1, catch_exception/1, raise_exception/1]).
-export([go/1, cycle/2, just_sync/1, just_sync/2, call_closure/1, call_external_closure/1, catch_exception/1, raise_exception/1, awaiting_steps/0]).

%% Utility function to check executed lines

Expand Down Expand Up @@ -94,3 +94,17 @@ raise_exception(Controller) ->
sync(Controller, ?LINE),
error(oops),
unreachable.

-spec awaiting_steps() -> ok.
awaiting_steps() ->
await(),
await(),
await(),
await(),
ok.

-spec await() -> ok.
await() ->
receive
continue -> ok
end.

0 comments on commit 35f5929

Please sign in to comment.