diff options
-rw-r--r-- | erts/emulator/test/Makefile | 5 | ||||
-rw-r--r-- | erts/emulator/test/socket_SUITE.erl | 2000 | ||||
-rw-r--r-- | erts/emulator/test/socket_test_evaluator.erl | 491 | ||||
-rw-r--r-- | erts/emulator/test/socket_test_evaluator.hrl | 68 | ||||
-rw-r--r-- | erts/emulator/test/socket_test_lib.erl | 72 |
5 files changed, 1454 insertions, 1182 deletions
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile index 39a3ef2a3d..22c2f24a80 100644 --- a/erts/emulator/test/Makefile +++ b/erts/emulator/test/Makefile @@ -32,6 +32,8 @@ SOCKET_MODULES = \ socket_lib \ socket_server \ socket_client \ + socket_test_lib \ + socket_test_evaluator \ socket_SUITE MODULES= \ @@ -156,6 +158,7 @@ NATIVE_MODULES= $(NATIVE:%=%_native_SUITE) NATIVE_ERL_FILES= $(NATIVE_MODULES:%=%.erl) ERL_FILES= $(MODULES:%=%.erl) +HRL_FILES= socket_test_evaluator.hrl TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) SOCKET_TARGETS = $(SOCKET_MODULES:%=$(EBIN)/%.$(EMULATOR)) @@ -228,7 +231,7 @@ release_spec: release_tests_spec: make_emakefile $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(EMAKEFILE) $(TEST_SPEC_FILES) \ - $(ERL_FILES) "$(RELSYSDIR)" + $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" $(INSTALL_DATA) $(NO_OPT_ERL_FILES) "$(RELSYSDIR)" $(INSTALL_DATA) $(NATIVE_ERL_FILES) "$(RELSYSDIR)" chmod -R u+w "$(RELSYSDIR)" diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 8d96065076..3308b9364e 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -93,23 +93,26 @@ %% Tickets ]). + +-include("socket_test_evaluator.hrl"). + %% Internal exports %% -export([]). --record(ev, {name :: string(), - pid :: pid(), - mref :: reference()}). --type ev() :: #ev{}. +%% -record(ev, {name :: string(), +%% pid :: pid(), +%% mref :: reference()}). +%% -type ev() :: #ev{}. -define(MKEV(N,P,R), #ev{name = N, pid = P, mref = R}). --type initial_evaluator_state() :: map(). --type evaluator_state() :: term(). --type command_fun() :: - fun((State :: evaluator_state()) -> ok) | - fun((State :: evaluator_state()) -> {ok, evaluator_state()}) | - fun((State :: evaluator_state()) -> {error, term()}). +%% -type initial_evaluator_state() :: map(). +%% -type evaluator_state() :: map(). +%% -type command_fun() :: +%% fun((State :: evaluator_state()) -> ok) | +%% fun((State :: evaluator_state()) -> {ok, evaluator_state()}) | +%% fun((State :: evaluator_state()) -> {error, term()}). --type command() :: #{desc := string(), - cmd := command_fun()}. +%% -type command() :: #{desc := string(), +%% cmd := command_fun()}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -126,6 +129,7 @@ -define(TT(T), ct:timetrap(T)). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% suite() -> @@ -249,7 +253,7 @@ sc_rc_cases() -> %% traffic_cases() -> -%% []. +%% [snr_send_and_recv_chunks]. %% ticket_cases() -> @@ -403,12 +407,16 @@ api_b_open_and_close(InitState) -> end}, #{desc => "validate socket close", cmd => fun({_, ok}) -> - {ok, normal}; + ok; ({_, {error, _} = ERROR}) -> ERROR - end}], - Evaluator = evaluator_start("tester", Seq, InitState), - ok = await_evaluator_finish([Evaluator]). + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + Evaluator = ?SEV_START("tester", Seq, InitState), + ok = ?SEV_AWAIT_FINISH([Evaluator]). @@ -543,12 +551,14 @@ api_b_send_and_recv_udp(InitState) -> end}, #{desc => "close dst socket", cmd => fun(#{sock_dst := Sock}) -> - ok = socket:close(Sock), - {ok, normal} - end} + ok = socket:close(Sock) + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL ], - Evaluator = evaluator_start("tester", Seq, InitState), - ok = await_evaluator_finish([Evaluator]). + Evaluator = ?SEV_START("tester", Seq, InitState), + ok = ?SEV_AWAIT_FINISH([Evaluator]). @@ -618,7 +628,7 @@ api_b_send_and_recv_tcp(InitState) -> %% *** Wait for start order *** #{desc => "await start (from tester)", cmd => fun(State) -> - Tester = ev_await_start(), + Tester = ?SEV_AWAIT_START(), {ok, State#{tester => Tester}} end}, #{desc => "monitor tester", @@ -658,20 +668,20 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester, lport := Port}) -> - ev_ready(Tester, init, Port), + ?SEV_ANNOUNCE_READY(Tester, init, Port), ok end}, %% The actual test #{desc => "await continue (accept)", cmd => fun(#{tester := Tester}) -> - ev_await_continue(Tester, tester, accept) + ?SEV_AWAIT_CONTINUE(Tester, tester, accept) end}, #{desc => "await connection", cmd => fun(#{lsock := LSock} = State) -> case socket:accept(LSock) of {ok, Sock} -> - ei("accepted: ~n ~p", [Sock]), + ?SEV_IPRINT("accepted: ~n ~p", [Sock]), {ok, State#{csock => Sock}}; {error, _} = ERROR -> ERROR @@ -679,7 +689,7 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "announce ready (accept)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, accept), + ?SEV_ANNOUNCE_READY(Tester, accept), ok end}, #{desc => "await (recv) request", @@ -693,13 +703,12 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "announce ready (recv request)", cmd => fun(#{tester := Tester}) -> - %% Tester ! {ready, self(), Port}, - ev_ready(Tester, recv_req), + ?SEV_ANNOUNCE_READY(Tester, recv_req), ok end}, #{desc => "await continue (with send reply)", cmd => fun(#{tester := Tester}) -> - ev_await_continue(Tester, tester, send_reply) + ?SEV_AWAIT_CONTINUE(Tester, tester, send_reply) end}, #{desc => "send reply", cmd => fun(#{csock := Sock, send := Send}) -> @@ -707,15 +716,14 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "announce ready (send reply)", cmd => fun(#{tester := Tester}) -> - %% Tester ! {ready, self(), Port}, - ev_ready(Tester, send_reply), + ?SEV_ANNOUNCE_READY(Tester, send_reply), ok end}, %% *** Termination *** #{desc => "await terminate", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -732,10 +740,7 @@ api_b_send_and_recv_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], ClientSeq = @@ -743,7 +748,7 @@ api_b_send_and_recv_tcp(InitState) -> %% *** Wait for start order *** #{desc => "await start (from tester)", cmd => fun(State) -> - {Tester, Port} = ev_await_start(), + {Tester, Port} = ?SEV_AWAIT_START(), {ok, State#{tester => Tester, server_port => Port}} end}, #{desc => "monitor tester", @@ -781,14 +786,14 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, init), + ?SEV_ANNOUNCE_READY(Tester, init), ok end}, %% *** The actual test *** #{desc => "await continue (connect)", cmd => fun(#{tester := Tester} = _State) -> - ev_await_continue(Tester, tester, connect) + ?SEV_AWAIT_CONTINUE(Tester, tester, connect) end}, #{desc => "connect to server", cmd => fun(#{sock := Sock, server_sa := SSA}) -> @@ -796,12 +801,12 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "announce ready (connect)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, connect), + ?SEV_ANNOUNCE_READY(Tester, connect), ok end}, #{desc => "await continue (send request)", cmd => fun(#{tester := Tester} = _State) -> - ev_await_continue(Tester, tester, send_req) + ?SEV_AWAIT_CONTINUE(Tester, tester, send_req) end}, #{desc => "send request (to server)", cmd => fun(#{sock := Sock, send := Send}) -> @@ -809,7 +814,7 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "announce ready (send request)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, send_req), + ?SEV_ANNOUNCE_READY(Tester, send_req), ok end}, #{desc => "await recv reply (from server)", @@ -819,14 +824,14 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "announce ready (recv reply)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, recv_reply), + ?SEV_ANNOUNCE_READY(Tester, recv_reply), ok end}, %% *** Termination *** #{desc => "await terminate", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -839,10 +844,7 @@ api_b_send_and_recv_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], TesterSeq = @@ -862,31 +864,31 @@ api_b_send_and_recv_tcp(InitState) -> %% Start the server #{desc => "order server start", cmd => fun(#{server := Pid} = _State) -> - ev_start(Pid), + ?SEV_ANNOUNCE_START(Pid), ok end}, #{desc => "await server ready (init)", cmd => fun(#{server := Pid} = State) -> - {ok, Port} = ev_await_ready(Pid, server, init), + {ok, Port} = ?SEV_AWAIT_READY(Pid, server, init), {ok, State#{server_port => Port}} end}, %% Start the client #{desc => "order client start", cmd => fun(#{client := Pid, server_port := Port} = _State) -> - ev_start(Pid, Port), + ?SEV_ANNOUNCE_START(Pid, Port), ok end}, #{desc => "await client ready (init)", cmd => fun(#{client := Pid} = _State) -> - ev_await_ready(Pid, client, init), + ?SEV_AWAIT_READY(Pid, client, init), ok end}, %% *** The actual test *** #{desc => "order server to continue (with accept)", cmd => fun(#{server := Server} = _State) -> - ev_continue(Server, accept), + ?SEV_ANNOUNCE_CONTINUE(Server, accept), ok end}, #{desc => "sleep", @@ -896,89 +898,86 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "order client to continue (with connect)", cmd => fun(#{client := Client} = _State) -> - ev_continue(Client, connect), + ?SEV_ANNOUNCE_CONTINUE(Client, connect), ok end}, #{desc => "await client ready (connect)", cmd => fun(#{client := Client} = _State) -> - ev_await_ready(Client, client, connect) + ?SEV_AWAIT_READY(Client, client, connect) end}, #{desc => "await server ready (accept)", cmd => fun(#{server := Server} = _State) -> - ev_await_ready(Server, server, accept) + ?SEV_AWAIT_READY(Server, server, accept) end}, #{desc => "order client to continue (with send request)", cmd => fun(#{client := Client} = _State) -> - ev_continue(Client, send_req), + ?SEV_ANNOUNCE_CONTINUE(Client, send_req), ok end}, #{desc => "await client ready (with send request)", cmd => fun(#{client := Client} = _State) -> - ev_await_ready(Client, client, send_req) + ?SEV_AWAIT_READY(Client, client, send_req) end}, #{desc => "await server ready (request recv)", cmd => fun(#{server := Server} = _State) -> - ev_await_ready(Server, server, recv_req) + ?SEV_AWAIT_READY(Server, server, recv_req) end}, #{desc => "order server to continue (with send reply)", cmd => fun(#{server := Server} = _State) -> - ev_continue(Server, send_reply), + ?SEV_ANNOUNCE_CONTINUE(Server, send_reply), ok end}, #{desc => "await server ready (with reply sent)", cmd => fun(#{server := Server} = _State) -> - ev_await_ready(Server, server, send_reply) + ?SEV_AWAIT_READY(Server, server, send_reply) end}, #{desc => "await client ready (reply recv)", cmd => fun(#{client := Client} = _State) -> - ev_await_ready(Client, client, recv_reply) + ?SEV_AWAIT_READY(Client, client, recv_reply) end}, %% *** Termination *** #{desc => "order client to terminate", cmd => fun(#{client := Client} = _State) -> - ev_terminate(Client), + ?SEV_ANNOUNCE_TERMINATE(Client), ok end}, #{desc => "await client termination", cmd => fun(#{client := Client} = State) -> - ev_await_termination(Client), + ?SEV_AWAIT_TERMINATION(Client), State1 = maps:remove(client, State), {ok, State1} end}, #{desc => "order server to terminate", cmd => fun(#{server := Server} = _State) -> - ev_terminate(Server), + ?SEV_ANNOUNCE_TERMINATE(Server), ok end}, #{desc => "await server termination", cmd => fun(#{server := Server} = State) -> - ev_await_termination(Server), + ?SEV_AWAIT_TERMINATION(Server), State1 = maps:remove(server, State), {ok, State1} end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("start server evaluator"), - Server = evaluator_start("server", ServerSeq, InitState), + Server = ?SEV_START("server", ServerSeq, InitState), i("start client evaluator"), - Client = evaluator_start("client", ClientSeq, InitState), + Client = ?SEV_START("client", ClientSeq, InitState), i("await evaluator(s)"), i("start tester evaluator"), TesterInitState = #{server => Server#ev.pid, client => Client#ev.pid}, - Tester = evaluator_start("tester", TesterSeq, TesterInitState), + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), - ok = await_evaluator_finish([Server, Client, Tester]). + ok = ?SEV_AWAIT_FINISH([Server, Client, Tester]). @@ -1240,15 +1239,15 @@ api_opt_simple_otp_options() -> i("start tcp (stream) evaluator"), InitState1 = #{domain => inet, type => stream, protocol => tcp}, - Tester1 = evaluator_start("tcp-tester", Seq, InitState1), + Tester1 = ?SEV_START("tcp-tester", Seq, InitState1), i("await tcp evaluator"), - ok = await_evaluator_finish([Tester1]), + ok = ?SEV_AWAIT_FINISH([Tester1]), i("start udp (dgram) socket"), InitState2 = #{domain => inet, type => dgram, protocol => udp}, - Tester2 = evaluator_start("udp-tester", Seq, InitState2), + Tester2 = ?SEV_START("udp-tester", Seq, InitState2), i("await udp evaluator"), - ok = await_evaluator_finish([Tester2]). + ok = ?SEV_AWAIT_FINISH([Tester2]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1276,12 +1275,7 @@ api_opt_simple_otp_controlling_process() -> %% *** Init part *** #{desc => "await start", cmd => fun(State) -> - %% receive - %% {start, Tester, Socket} -> - %% {ok, State#{tester => Tester, - %% sock => Socket}} - %% end - {Tester, Sock} = ev_await_start(), + {Tester, Sock} = ?SEV_AWAIT_START(), {ok, State#{tester => Tester, sock => Sock}} end}, @@ -1316,13 +1310,12 @@ api_opt_simple_otp_controlling_process() -> end}, #{desc => "announce ready (not owner)", cmd => fun(#{tester := Tester} = _State) -> - ev_ready(Tester, not_owner), - %% Tester ! {ready, self()}, + ?SEV_ANNOUNCE_READY(Tester, not_owner), ok end}, #{desc => "await continue (owner)", cmd => fun(#{tester := Tester} = _State) -> - ev_await_continue(Tester, tester, owner) + ?SEV_AWAIT_CONTINUE(Tester, tester, owner) end}, #{desc => "verify self as controlling-process", cmd => fun(#{sock := Sock} = _State) -> @@ -1353,8 +1346,7 @@ api_opt_simple_otp_controlling_process() -> end}, #{desc => "announce ready (owner)", cmd => fun(#{tester := Tester} = _State) -> - %% Tester ! {ready, self()}, - ev_ready(Tester, owner), + ?SEV_ANNOUNCE_READY(Tester, owner), ok end}, @@ -1362,23 +1354,14 @@ api_opt_simple_otp_controlling_process() -> %% *** Termination *** #{desc => "await termination", cmd => fun(#{tester := Tester} = State) -> - %% receive - %% {terminate, Tester} -> - %% State1 = maps:remove(tester, State), - %% State2 = maps:remove(sock, State1), - %% {ok, State2} - %% end - ev_await_terminate(Tester, tester), + ?SEV_AWAIT_TERMINATE(Tester, tester), State1 = maps:remove(tester, State), State2 = maps:remove(sock, State1), {ok, State2} end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], TesterSeq = @@ -1412,17 +1395,12 @@ api_opt_simple_otp_controlling_process() -> end}, #{desc => "order (client) start", cmd => fun(#{client := Client, sock := Sock} = _State) -> - %% Client ! {start, self(), Sock}, - ev_start(Client, Sock), + ?SEV_ANNOUNCE_START(Client, Sock), ok end}, #{desc => "await (client) ready (not owner)", cmd => fun(#{client := Client} = _State) -> - %% receive - %% {ready, Client} -> - %% ok - %% end - ev_await_ready(Client, client, not_owner) + ?SEV_AWAIT_READY(Client, client, not_owner) end}, #{desc => "attempt controlling-process transfer to client", cmd => fun(#{client := Client, sock := Sock} = _State) -> @@ -1452,17 +1430,12 @@ api_opt_simple_otp_controlling_process() -> end}, #{desc => "order (client) continue (owner)", cmd => fun(#{client := Client} = _State) -> - %% Client ! {continue, self()}, - ev_continue(Client, owner), + ?SEV_ANNOUNCE_CONTINUE(Client, owner), ok end}, #{desc => "await (client) ready (2)", cmd => fun(#{client := Client} = _State) -> - %% receive - %% {ready, Client} -> - %% ok - %% end - ev_await_ready(Client, client, owner), + ?SEV_AWAIT_READY(Client, client, owner), ok end}, #{desc => "verify self as controlling-process", @@ -1481,17 +1454,12 @@ api_opt_simple_otp_controlling_process() -> %% *** Termination *** #{desc => "order (client) terminate", cmd => fun(#{client := Client} = _State) -> - %% Client ! {terminate, self()}, - ev_terminate(Client), + ?SEV_ANNOUNCE_TERMINATE(Client), ok end}, #{desc => "await client termination", cmd => fun(#{client := Client} = State) -> - %% receive - %% {'DOWN', _, process, Client, _} -> - %% {ok, maps:remove(client, State)} - %% end - ev_await_termination(Client), + ?SEV_AWAIT_TERMINATION(Client), {ok, maps:remove(client, State)} end}, #{desc => "close socket", @@ -1501,33 +1469,36 @@ api_opt_simple_otp_controlling_process() -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], - i("start tcp (stream) socket"), + i("start tcp (stream) client evaluator"), ClientInitState1 = #{}, - Client1 = evaluator_start("tcp-client", ClientSeq, ClientInitState1), + Client1 = ?SEV_START("tcp-client", ClientSeq, ClientInitState1), + + i("start tcp (stream) tester evaluator"), TesterInitState1 = #{domain => inet, type => stream, protocol => tcp, client => Client1#ev.pid}, - Tester1 = evaluator_start("tcp-tester", TesterSeq, TesterInitState1), - i("await tcp evaluator"), - ok = await_evaluator_finish([Tester1, Client1]), + Tester1 = ?SEV_START("tcp-tester", TesterSeq, TesterInitState1), - i("start udp (dgram) socket"), + i("await tcp evaluator(s)"), + ok = ?SEV_AWAIT_FINISH([Tester1, Client1]), + + i("start udp (dgram) client evaluator"), ClientInitState2 = #{}, - Client2 = evaluator_start("udp-client", ClientSeq, ClientInitState2), + Client2 = ?SEV_START("udp-client", ClientSeq, ClientInitState2), + + i("start udp (dgram) tester evaluator"), TesterInitState2 = #{domain => inet, type => dgram, protocol => udp, client => Client2#ev.pid}, - Tester2 = evaluator_start("udp-tester", TesterSeq, TesterInitState2), - i("await udp evaluator"), - ok = await_evaluator_finish([Tester2, Client2]). + Tester2 = ?SEV_START("udp-tester", TesterSeq, TesterInitState2), + + i("await udp evaluator(s)"), + ok = ?SEV_AWAIT_FINISH([Tester2, Client2]). @@ -1589,7 +1560,7 @@ api_to_connect_tcp(InitState) -> %% *** Wait for start order part *** #{desc => "await start (from tester)", cmd => fun(State) -> - Tester = ev_await_start(), + Tester = ?SEV_AWAIT_START(), {ok, State#{tester => Tester}} end}, #{desc => "monitor tester", @@ -1629,14 +1600,14 @@ api_to_connect_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester, lport := Port}) -> - ev_ready(Tester, init, Port), + ?SEV_ANNOUNCE_READY(Tester, init, Port), ok end}, %% Termination #{desc => "await terminate", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -1652,10 +1623,7 @@ api_to_connect_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], TesterSeq = @@ -1730,12 +1698,12 @@ api_to_connect_tcp(InitState) -> %% *** Synchronize with the server *** #{desc => "order server start", cmd => fun(#{server := Server}) -> - ev_start(Server), + ?SEV_ANNOUNCE_START(Server), ok end}, #{desc => "await server ready (init)", cmd => fun(#{server := Server, local_sa := LSA} = State) -> - {ok, Port} = ev_await_ready(Server, server, init), + {ok, Port} = ?SEV_AWAIT_READY(Server, server, init), ServerSA = LSA#{port => Port}, {ok, State#{server_sa => ServerSA}} end}, @@ -1754,12 +1722,12 @@ api_to_connect_tcp(InitState) -> %% *** Terminate server *** #{desc => "order (server) terminate", cmd => fun(#{server := Server} = _State) -> - ev_terminate(Server), + ?SEV_ANNOUNCE_TERMINATE(Server), ok end}, #{desc => "await (server) down", cmd => fun(#{server := Server} = State) -> - ev_await_termination(Server), + ?SEV_AWAIT_TERMINATION(Server), State1 = maps:remove(server, State), State2 = maps:remove(server_sa, State1), {ok, State2} @@ -1784,22 +1752,19 @@ api_to_connect_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("create server evaluator"), ServerInitState = InitState, - Server = evaluator_start("server", ServerSeq, ServerInitState), + Server = ?SEV_START("server", ServerSeq, ServerInitState), i("create tester evaluator"), TesterInitState = InitState#{server => Server#ev.pid}, - Tester = evaluator_start("tester", TesterSeq, TesterInitState), + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), i("await evaluator(s)"), - ok = await_evaluator_finish([Server, Tester]). + ok = ?SEV_AWAIT_FINISH([Server, Tester]). api_to_connect_tcp_await_timeout(Socks, To, ServerSA) -> @@ -1808,11 +1773,11 @@ api_to_connect_tcp_await_timeout(Socks, To, ServerSA) -> api_to_connect_tcp_await_timeout([], _To, _ServerSA, _ID) -> ?FAIL(unexpected_success); api_to_connect_tcp_await_timeout([Sock|Socks], To, ServerSA, ID) -> - ei("~w: try connect", [ID]), + ?SEV_IPRINT("~w: try connect", [ID]), Start = t(), case socket:connect(Sock, ServerSA, To) of {error, timeout} -> - ei("expected timeout (~w)", [ID]), + ?SEV_IPRINT("expected timeout (~w)", [ID]), Stop = t(), TDiff = tdiff(Start, Stop), if @@ -1822,13 +1787,13 @@ api_to_connect_tcp_await_timeout([Sock|Socks], To, ServerSA, ID) -> {error, {unexpected_timeout, TDiff, To}} end; {error, econnreset = Reason} -> - ei("failed connecting: ~p - giving up", [Reason]), + ?SEV_IPRINT("failed connecting: ~p - giving up", [Reason]), ok; {error, Reason} -> - ee("failed connecting: ~p", [Reason]), + ?SEV_EPRINT("failed connecting: ~p", [Reason]), ?FAIL({connect, Reason}); ok -> - ei("unexpected success (~w) - try next", [ID]), + ?SEV_IPRINT("unexpected success (~w) - try next", [ID]), api_to_connect_tcp_await_timeout(Socks, To, ServerSA, ID+1) end. @@ -1937,17 +1902,14 @@ api_to_accept_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("create tester evaluator"), - Tester = evaluator_start("tester", TesterSeq, InitState), + Tester = ?SEV_START("tester", TesterSeq, InitState), i("await evaluator"), - ok = await_evaluator_finish([Tester]). + ok = ?SEV_AWAIT_FINISH([Tester]). @@ -1995,7 +1957,7 @@ api_to_maccept_tcp(InitState) -> %% *** Init part *** #{desc => "await start", cmd => fun(State) -> - Tester = ev_await_start(), + Tester = ?SEV_AWAIT_START(), {ok, State#{tester => Tester}} end}, #{desc => "monitor tester", @@ -2033,14 +1995,14 @@ api_to_maccept_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{lsock := LSock, tester := Tester}) -> - ev_ready(Tester, init, LSock), + ?SEV_ANNOUNCE_READY(Tester, init, LSock), ok end}, %% *** The actual test *** #{desc => "await continue (accept)", cmd => fun(#{tester := Tester} = _State) -> - ev_await_continue(Tester, tester, accept) + ?SEV_AWAIT_CONTINUE(Tester, tester, accept) end}, #{desc => "attempt to accept (without success)", cmd => fun(#{lsock := LSock, timeout := To} = State) -> @@ -2049,8 +2011,8 @@ api_to_maccept_tcp(InitState) -> {error, timeout} -> {ok, State#{start => Start, stop => t()}}; {ok, Sock} -> - ee("Unexpected accept success: " - "~n ~p", [Sock]), + ?SEV_EPRINT("Unexpected accept success: " + "~n ~p", [Sock]), (catch socket:close(Sock)), {error, unexpected_success}; {error, _} = ERROR -> @@ -2069,14 +2031,14 @@ api_to_maccept_tcp(InitState) -> end}, #{desc => "announce ready (accept)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, accept), + ?SEV_ANNOUNCE_READY(Tester, accept), ok end}, %% *** Terminate *** #{desc => "await terminate", cmd => fun(#{tester := Tester} = _State) -> - ev_await_terminate(Tester, tester), + ?SEV_AWAIT_TERMINATE(Tester, tester), ok end}, %% *** Close (listen) socket *** @@ -2087,10 +2049,7 @@ api_to_maccept_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], @@ -2099,7 +2058,7 @@ api_to_maccept_tcp(InitState) -> %% *** Init part *** #{desc => "await start", cmd => fun(State) -> - {Tester, LSock} = ev_await_start(), + {Tester, LSock} = ?SEV_AWAIT_START(), {ok, State#{tester => Tester, lsock => LSock}} @@ -2111,14 +2070,14 @@ api_to_maccept_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester} = _State) -> - ev_ready(Tester, init), + ?SEV_ANNOUNCE_READY(Tester, init), ok end}, %% *** The actual test part *** #{desc => "await continue (accept)", cmd => fun(#{tester := Tester} = _State) -> - ev_await_continue(Tester, tester, accept) + ?SEV_AWAIT_CONTINUE(Tester, tester, accept) end}, #{desc => "attempt to accept (without success)", cmd => fun(#{lsock := LSock, timeout := To} = State) -> @@ -2147,14 +2106,14 @@ api_to_maccept_tcp(InitState) -> end}, #{desc => "announce ready (accept)", cmd => fun(#{tester := Tester} = _State) -> - ev_ready(Tester, accept), + ?SEV_ANNOUNCE_READY(Tester, accept), ok end}, %% *** Terminate *** #{desc => "await terminate", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -2163,10 +2122,7 @@ api_to_maccept_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], @@ -2193,133 +2149,139 @@ api_to_maccept_tcp(InitState) -> %% Start the prim-acceptor #{desc => "start prim-acceptor", cmd => fun(#{prim_acceptor := Pid} = _State) -> - ev_start(Pid), + ?SEV_ANNOUNCE_START(Pid), ok end}, #{desc => "await prim-acceptor ready (init)", cmd => fun(#{prim_acceptor := Pid} = State) -> - {ok, Sock} = ev_await_ready(Pid, prim_acceptor, init), + {ok, Sock} = ?SEV_AWAIT_READY(Pid, prim_acceptor, init), {ok, State#{lsock => Sock}} end}, %% Start sec-acceptor-1 #{desc => "start sec-acceptor 1", cmd => fun(#{sec_acceptor1 := Pid, lsock := LSock} = _State) -> - ev_start(Pid, LSock), + ?SEV_ANNOUNCE_START(Pid, LSock), ok end}, #{desc => "await sec-acceptor 1 ready (init)", cmd => fun(#{sec_acceptor1 := Pid} = _State) -> - ev_await_ready(Pid, sec_acceptor1, init) + ?SEV_AWAIT_READY(Pid, sec_acceptor1, init) end}, %% Start sec-acceptor-2 #{desc => "start sec-acceptor 2", cmd => fun(#{sec_acceptor2 := Pid, lsock := LSock} = _State) -> - ev_start(Pid, LSock), + ?SEV_ANNOUNCE_START(Pid, LSock), ok end}, #{desc => "await sec-acceptor 2 ready (init)", cmd => fun(#{sec_acceptor2 := Pid} = _State) -> - ev_await_ready(Pid, sec_acceptor2, init) + ?SEV_AWAIT_READY(Pid, sec_acceptor2, init) end}, %% Activate the acceptor(s) #{desc => "active prim-acceptor", cmd => fun(#{prim_acceptor := Pid} = _State) -> - ev_continue(Pid, accept), + ?SEV_ANNOUNCE_CONTINUE(Pid, accept), ok end}, #{desc => "active sec-acceptor 1", cmd => fun(#{sec_acceptor1 := Pid} = _State) -> - ev_continue(Pid, accept), + ?SEV_ANNOUNCE_CONTINUE(Pid, accept), ok end}, #{desc => "active sec-acceptor 2", cmd => fun(#{sec_acceptor2 := Pid} = _State) -> - ev_continue(Pid, accept), + ?SEV_ANNOUNCE_CONTINUE(Pid, accept), ok end}, %% Await acceptor(s) completions #{desc => "await prim-acceptor ready (accept)", cmd => fun(#{prim_acceptor := Pid} = _State) -> - ev_await_ready(Pid, prim_acceptor, accept) + ?SEV_AWAIT_READY(Pid, prim_acceptor, accept) end}, #{desc => "await sec-acceptor 1 ready (accept)", cmd => fun(#{sec_acceptor1 := Pid} = _State) -> - ev_await_ready(Pid, sec_acceptor1, accept) + ?SEV_AWAIT_READY(Pid, sec_acceptor1, accept) end}, #{desc => "await sec-acceptor 2 ready (accept)", cmd => fun(#{sec_acceptor2 := Pid} = _State) -> - ev_await_ready(Pid, sec_acceptor2, accept) + ?SEV_AWAIT_READY(Pid, sec_acceptor2, accept) end}, %% Terminate #{desc => "order prim-acceptor to terminate", cmd => fun(#{prim_acceptor := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await prim-acceptor termination", cmd => fun(#{prim_acceptor := Pid} = State) -> - ev_await_termination(Pid), - State1 = maps:remove(prim_acceptor, State), - {ok, State1} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + State1 = maps:remove(prim_acceptor, State), + {ok, State1}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order sec-acceptor 1 to terminate", cmd => fun(#{sec_acceptor1 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await sec-acceptor 1 termination", cmd => fun(#{sec_acceptor1 := Pid} = State) -> - ev_await_termination(Pid), - State1 = maps:remove(sec_acceptor1, State), - {ok, State1} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + State1 = maps:remove(sec_acceptor1, State), + {ok, State1}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order sec-acceptor 2 to terminate", cmd => fun(#{sec_acceptor2 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await sec-acceptor 2 termination", cmd => fun(#{sec_acceptor2 := Pid} = State) -> - ev_await_termination(Pid), - State1 = maps:remove(sec_acceptor2, State), - {ok, State1} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + State1 = maps:remove(sec_acceptor2, State), + {ok, State1}; + {error, _} = ERROR -> + ERROR + end end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("create prim-acceptor evaluator"), PrimAInitState = InitState, - PrimAcceptor = evaluator_start("prim-acceptor", - PrimAcceptorSeq, PrimAInitState), + PrimAcceptor = ?SEV_START("prim-acceptor", PrimAcceptorSeq, PrimAInitState), i("create sec-acceptor 1 evaluator"), SecAInitState1 = maps:remove(domain, InitState), - SecAcceptor1 = evaluator_start("sec-acceptor-1", - SecAcceptorSeq, SecAInitState1), + SecAcceptor1 = ?SEV_START("sec-acceptor-1", SecAcceptorSeq, SecAInitState1), i("create sec-acceptor 2 evaluator"), SecAInitState2 = SecAInitState1, - SecAcceptor2 = evaluator_start("sec-acceptor-2", - SecAcceptorSeq, SecAInitState2), + SecAcceptor2 = ?SEV_START("sec-acceptor-2", SecAcceptorSeq, SecAInitState2), i("create tester evaluator"), TesterInitState = #{prim_acceptor => PrimAcceptor#ev.pid, sec_acceptor1 => SecAcceptor1#ev.pid, sec_acceptor2 => SecAcceptor2#ev.pid}, - Tester = evaluator_start("tester", TesterSeq, TesterInitState), + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), i("await evaluator(s)"), - ok = await_evaluator_finish([PrimAcceptor, SecAcceptor1, SecAcceptor2, Tester]). + ok = ?SEV_AWAIT_FINISH([PrimAcceptor, SecAcceptor1, SecAcceptor2, Tester]). @@ -2511,7 +2473,7 @@ api_to_receive_tcp(InitState) -> %% *** Wait for start order *** #{desc => "await start (from tester)", cmd => fun(State) -> - Tester = ev_await_start(), + Tester = ?SEV_AWAIT_START(), {ok, State#{tester => Tester}} end}, #{desc => "monitor tester", @@ -2551,14 +2513,14 @@ api_to_receive_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester, lport := Port}) -> - ev_ready(Tester, init, Port), + ?SEV_ANNOUNCE_READY(Tester, init, Port), ok end}, %% *** The actual test *** #{desc => "await continue (accept and recv)", cmd => fun(#{tester := Tester}) -> - ev_await_continue(Tester, tester, accept_recv) + ?SEV_AWAIT_CONTINUE(Tester, tester, accept_recv) end}, #{desc => "attempt accept", cmd => fun(#{lsock := LSock} = State) -> @@ -2595,15 +2557,14 @@ api_to_receive_tcp(InitState) -> end}, #{desc => "announce ready (recv timeout success)", cmd => fun(#{tester := Tester} = _State) -> - %% ok - ev_ready(Tester, accept_recv), + ?SEV_ANNOUNCE_READY(Tester, accept_recv), ok end}, %% *** Termination *** #{desc => "await terminate", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -2622,10 +2583,7 @@ api_to_receive_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], ClientSeq = @@ -2633,7 +2591,7 @@ api_to_receive_tcp(InitState) -> %% *** Wait for start order part *** #{desc => "await start (from tester)", cmd => fun(State) -> - {Tester, Port} = ev_await_start(), + {Tester, Port} = ?SEV_AWAIT_START(), {ok, State#{tester => Tester, server_port => Port}} end}, @@ -2672,14 +2630,14 @@ api_to_receive_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester} = _State) -> - ev_ready(Tester, init), + ?SEV_ANNOUNCE_READY(Tester, init), ok end}, %% *** The actual test *** #{desc => "await continue (with connect)", cmd => fun(#{tester := Tester} = _State) -> - ev_await_continue(Tester, tester, connect) + ?SEV_AWAIT_CONTINUE(Tester, tester, connect) end}, #{desc => "connect", cmd => fun(#{sock := Sock, server_sa := SSA}) -> @@ -2690,7 +2648,7 @@ api_to_receive_tcp(InitState) -> %% *** Termination *** #{desc => "await terminate", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -2704,10 +2662,7 @@ api_to_receive_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], TesterSeq = @@ -2727,90 +2682,95 @@ api_to_receive_tcp(InitState) -> %% *** Activate server *** #{desc => "start server", cmd => fun(#{server := Server} = _State) -> - ev_start(Server), + ?SEV_ANNOUNCE_START(Server), ok end}, #{desc => "await server ready (init)", cmd => fun(#{server := Server} = State) -> - {ok, Port} = ev_await_ready(Server, server, init), + {ok, Port} = ?SEV_AWAIT_READY(Server, server, init), {ok, State#{server_port => Port}} end}, #{desc => "order server to continue (with accept)", cmd => fun(#{server := Server} = _State) -> - ev_continue(Server, accept_recv), + ?SEV_ANNOUNCE_CONTINUE(Server, accept_recv), ok end}, %% *** Activate client *** #{desc => "start client", cmd => fun(#{client := Client, server_port := Port} = _State) -> - ev_start(Client, Port), + ?SEV_ANNOUNCE_START(Client, Port), ok end}, #{desc => "await client ready (init)", cmd => fun(#{client := Client} = _State) -> - ev_await_ready(Client, client, init) + ?SEV_AWAIT_READY(Client, client, init) end}, %% *** The actual test *** #{desc => "order client to continue (with connect)", cmd => fun(#{client := Client} = _State) -> - ev_continue(Client, connect), + ?SEV_ANNOUNCE_CONTINUE(Client, connect), ok end}, #{desc => "await server ready (accept/recv)", cmd => fun(#{server := Server} = _State) -> - ev_await_ready(Server, server, accept_recv) + ?SEV_AWAIT_READY(Server, server, accept_recv) end}, %% *** Termination *** #{desc => "order client to terminate", cmd => fun(#{client := Client} = _State) -> - ev_terminate(Client), + ?SEV_ANNOUNCE_TERMINATE(Client), ok end}, #{desc => "await client termination", cmd => fun(#{client := Client} = State) -> - ev_await_termination(Client), - State1 = maps:remove(client, State), - {ok, State1} + case ?SEV_AWAIT_TERMINATION(Client) of + ok -> + State1 = maps:remove(client, State), + {ok, State1}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order server to terminate", cmd => fun(#{server := Server} = _State) -> - ev_terminate(Server), + ?SEV_ANNOUNCE_TERMINATE(Server), ok end}, #{desc => "await server termination", cmd => fun(#{server := Server} = State) -> - ev_await_termination(Server), - State1 = maps:remove(server, State), - State2 = maps:remove(server_port, State1), - {ok, State2} + case ?SEV_AWAIT_TERMINATION(Server) of + ok -> + State1 = maps:remove(server, State), + State2 = maps:remove(server_port, State1), + {ok, State2}; + {error, _} = ERROR -> + ERROR + end end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("start server evaluator"), ServerInitState = InitState, - Server = evaluator_start("server", ServerSeq, ServerInitState), + Server = ?SEV_START("server", ServerSeq, ServerInitState), i("start client evaluator"), ClientInitState = InitState, - Client = evaluator_start("client", ClientSeq, ClientInitState), + Client = ?SEV_START("client", ClientSeq, ClientInitState), i("start tester evaluator"), TesterInitState = #{server => Server#ev.pid, client => Client#ev.pid}, - Tester = evaluator_start("tester", TesterSeq, TesterInitState), + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), i("await evaluator(s)"), - ok = await_evaluator_finish([Server, Client, Tester]). + ok = ?SEV_AWAIT_FINISH([Server, Client, Tester]). @@ -2918,17 +2878,14 @@ api_to_receive_udp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("start tester evaluator"), - Tester = evaluator_start("tester", TesterSeq, InitState), + Tester = ?SEV_START("tester", TesterSeq, InitState), i("await evaluator"), - ok = await_evaluator_finish([Tester]). + ok = ?SEV_AWAIT_FINISH([Tester]). @@ -3115,16 +3072,16 @@ sc_cpe_socket_cleanup(InitState) -> %% *** Wait for start order part *** #{desc => "await start (from tester)", cmd => fun(State) -> - Tester = ev_await_start(), + Tester = ?SEV_AWAIT_START(), {ok, State#{tester => Tester}} end}, - - %% *** Init part *** #{desc => "monitor tester", cmd => fun(#{tester := Tester} = _State) -> _MRef = erlang:monitor(process, Tester), ok end}, + + %% *** Init part *** #{desc => "create socket", cmd => fun(#{domain := Domain, type := Type, @@ -3138,7 +3095,7 @@ sc_cpe_socket_cleanup(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester, sock := Sock} = _State) -> - ev_ready(Tester, init, Sock), + ?SEV_ANNOUNCE_READY(Tester, init, Sock), ok end}, @@ -3146,7 +3103,7 @@ sc_cpe_socket_cleanup(InitState) -> %% We *intentially* leave the socket "as is", no explicit close #{desc => "await terminate (from tester)", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -3155,10 +3112,7 @@ sc_cpe_socket_cleanup(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], TesterSeq = @@ -3171,12 +3125,12 @@ sc_cpe_socket_cleanup(InitState) -> end}, #{desc => "order (owner) start", cmd => fun(#{owner := Pid} = _State) -> - ev_start(Pid), + ?SEV_ANNOUNCE_START(Pid), ok end}, #{desc => "await (owner) ready", cmd => fun(#{owner := Pid} = State) -> - {ok, Sock} = ev_await_ready(Pid, owner, init), + {ok, Sock} = ?SEV_AWAIT_READY(Pid, owner, init), {ok, State#{sock => Sock}} end}, #{desc => "verify owner as controlling-process", @@ -3192,13 +3146,17 @@ sc_cpe_socket_cleanup(InitState) -> end}, #{desc => "order (owner) terminate", cmd => fun(#{owner := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await (owner) termination", cmd => fun(#{owner := Pid} = _State) -> - ev_await_termination(Pid), - ok + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + ok; + {error, _} = ERROR -> + ERROR + end end}, %% The reason we get closed, is that as long as there is a ref to %% the resource (socket), then it will not be garbage collected. @@ -3210,27 +3168,24 @@ sc_cpe_socket_cleanup(InitState) -> {error, closed} -> ok; {error, Reason} -> - ei("expected failure: ~p", [Reason]), + ?SEV_IPRINT("expected failure: ~p", [Reason]), {error, {unexpected_failure, Reason}} end end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("start (socket) owner evaluator"), - #ev{pid = Pid} = Owner = evaluator_start("owner", OwnerSeq, InitState), + Owner = ?SEV_START("owner", OwnerSeq, InitState), i("start tester evaluator"), - TesterInitState = #{owner => Pid}, - Tester = evaluator_start("tester", TesterSeq, TesterInitState), + TesterInitState = #{owner => Owner#ev.pid}, + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), i("await evaluator"), - ok = await_evaluator_finish([Owner, Tester]). + ok = ?SEV_AWAIT_FINISH([Owner, Tester]). @@ -3298,7 +3253,7 @@ sc_lc_receive_response_tcp(InitState) -> %% *** Wait for start order part *** #{desc => "await start (from tester)", cmd => fun(State) -> - Tester = ev_await_start(), + Tester = ?SEV_AWAIT_START(), {ok, State#{tester => Tester}} end}, #{desc => "monitor tester", @@ -3340,24 +3295,27 @@ sc_lc_receive_response_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester, lport := Port}) -> - ev_ready(Tester, init, Port), + ?SEV_ANNOUNCE_READY(Tester, init, Port), ok end}, %% The actual test #{desc => "await continue (accept)", cmd => fun(#{tester := Tester} = State) -> - {ok, {H1, H2, H3}} = - ev_await_continue(Tester, tester, accept), - {ok, State#{handler1 => H1, - handler2 => H2, - handler3 => H3}} + case ?SEV_AWAIT_CONTINUE(Tester, tester, accept) of + {ok, {H1, H2, H3}} -> + {ok, State#{handler1 => H1, + handler2 => H2, + handler3 => H3}}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "await accept", cmd => fun(#{lsock := LSock} = State) -> case socket:accept(LSock) of {ok, Sock} -> - ei("connection accepted"), + ?SEV_IPRINT("connection accepted"), {ok, State#{csock => Sock}}; {error, _} = ERROR -> ERROR @@ -3365,27 +3323,27 @@ sc_lc_receive_response_tcp(InitState) -> end}, #{desc => "announce ready (accept)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, accept), + ?SEV_ANNOUNCE_READY(Tester, accept), ok end}, #{desc => "transfer connection to handler 1", cmd => fun(#{handler1 := Handler, csock := Sock}) -> - ev_continue(Handler, transfer, Sock), + ?SEV_ANNOUNCE_CONTINUE(Handler, transfer, Sock), ok end}, #{desc => "transfer connection to handler 2", cmd => fun(#{handler2 := Handler, csock := Sock}) -> - ev_continue(Handler, transfer, Sock), + ?SEV_ANNOUNCE_CONTINUE(Handler, transfer, Sock), ok end}, #{desc => "transfer connection to handler 3", cmd => fun(#{handler3 := Handler, csock := Sock}) -> - ev_continue(Handler, transfer, Sock), + ?SEV_ANNOUNCE_CONTINUE(Handler, transfer, Sock), ok end}, #{desc => "await continue (close)", cmd => fun(#{tester := Tester} = _State) -> - ev_await_continue(Tester, tester, close), + ?SEV_AWAIT_CONTINUE(Tester, tester, close), ok end}, #{desc => "close the connection socket", @@ -3399,14 +3357,14 @@ sc_lc_receive_response_tcp(InitState) -> end}, #{desc => "announce ready (close)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, close), + ?SEV_ANNOUNCE_READY(Tester, close), ok end}, %% *** Terminate *** #{desc => "await terminate", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -3426,10 +3384,7 @@ sc_lc_receive_response_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], %% The point of this is to perform the recv for which we are testing the reponse @@ -3438,7 +3393,7 @@ sc_lc_receive_response_tcp(InitState) -> %% *** Wait for start order part *** #{desc => "await start (from tester)", cmd => fun(State) -> - {Tester, Acceptor} = ev_await_start(), + {Tester, Acceptor} = ?SEV_AWAIT_START(), {ok, State#{tester => Tester, acceptor => Acceptor}} end}, @@ -3454,48 +3409,51 @@ sc_lc_receive_response_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, init), + ?SEV_ANNOUNCE_READY(Tester, init), ok end}, %% The actual test #{desc => "await continue (transfer)", cmd => fun(#{acceptor := Pid} = State) -> - {ok, Sock} = - ev_await_continue(Pid, acceptor, transfer), - {ok, State#{sock => Sock}} + case ?SEV_AWAIT_CONTINUE(Pid, acceptor, transfer) of + {ok, Sock} -> + {ok, State#{sock => Sock}}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "announce ready (transfer)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, transfer), + ?SEV_ANNOUNCE_READY(Tester, transfer), ok end}, #{desc => "attempt recv (=> closed)", cmd => fun(#{sock := Sock, recv := Recv} = State) -> case Recv(Sock) of {ok, _Data} -> - ee("Unexpected data received"), + ?SEV_EPRINT("Unexpected data received"), {error, unexpected_success}; {error, closed} -> - ei("received expected 'closed' result"), + ?SEV_IPRINT("received expected 'closed' result"), State1 = maps:remove(sock, State), {ok, State1}; {error, Reason} = ERROR -> - ee("Unexpected read faulure: " - "~n ~p", [Reason]), + ?SEV_EPRINT("Unexpected read faulure: " + "~n ~p", [Reason]), ERROR end end}, #{desc => "announce ready (recv closed)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, recv_closed), + ?SEV_ANNOUNCE_READY(Tester, recv_closed), ok end}, %% *** Terminate *** #{desc => "await terminate", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -3505,10 +3463,7 @@ sc_lc_receive_response_tcp(InitState) -> %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], %% The point of this is basically just to create the connection. @@ -3517,7 +3472,7 @@ sc_lc_receive_response_tcp(InitState) -> %% *** Wait for start order part *** #{desc => "await start (from tester)", cmd => fun(State) -> - Tester = ev_await_start(), + Tester = ?SEV_AWAIT_START(), {ok, State#{tester => Tester}} end}, #{desc => "monitor tester", @@ -3555,16 +3510,20 @@ sc_lc_receive_response_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester} = _State) -> - ev_ready(Tester, init), + ?SEV_ANNOUNCE_READY(Tester, init), ok end}, %% The actual test #{desc => "await continue (connect)", cmd => fun(#{tester := Tester, local_sa := LSA} = State) -> - {ok, Port} = ev_await_continue(Tester, tester, connect), - ServerSA = LSA#{port => Port}, - {ok, State#{server_sa => ServerSA}} + case ?SEV_AWAIT_CONTINUE(Tester, tester, connect) of + {ok, Port} -> + ServerSA = LSA#{port => Port}, + {ok, State#{server_sa => ServerSA}}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "connect to server", cmd => fun(#{sock := Sock, server_sa := ServerSA}) -> @@ -3572,14 +3531,14 @@ sc_lc_receive_response_tcp(InitState) -> end}, #{desc => "announce ready (connect)", cmd => fun(#{tester := Tester} = _State) -> - ev_ready(Tester, connect), + ?SEV_ANNOUNCE_READY(Tester, connect), ok end}, %% *** Terminate *** #{desc => "await terminate (from tester)", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -3593,10 +3552,7 @@ sc_lc_receive_response_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], TesterSeq = @@ -3631,53 +3587,57 @@ sc_lc_receive_response_tcp(InitState) -> %% Start the acceptor #{desc => "order acceptor start", cmd => fun(#{acceptor := Pid} = _State) -> - ev_start(Pid), + ?SEV_ANNOUNCE_START(Pid), ok end}, #{desc => "await acceptor ready (init)", cmd => fun(#{acceptor := Pid} = State) -> - {ok, Port} = ev_await_ready(Pid, acceptor, init), - {ok, State#{lport => Port}} + case ?SEV_AWAIT_READY(Pid, acceptor, init) of + {ok, Port} -> + {ok, State#{lport => Port}}; + {error, _} = ERROR -> + ERROR + end end}, %% Start the handler(s) #{desc => "order handler 1 start", cmd => fun(#{acceptor := Acceptor, handler1 := Pid} = _State) -> - ev_start(Pid, Acceptor), + ?SEV_ANNOUNCE_START(Pid, Acceptor), ok end}, #{desc => "await handler 1 ready (init)", cmd => fun(#{handler1 := Pid} = _State) -> - ev_await_ready(Pid, handler1, init) + ?SEV_AWAIT_READY(Pid, handler1, init) end}, #{desc => "order handler 2 start", cmd => fun(#{acceptor := Acceptor, handler2 := Pid} = _State) -> - ev_start(Pid, Acceptor), + ?SEV_ANNOUNCE_START(Pid, Acceptor), ok end}, #{desc => "await handler 2 ready (init)", cmd => fun(#{handler2 := Pid} = _State) -> - ev_await_ready(Pid, handler2, init) + ?SEV_AWAIT_READY(Pid, handler2, init) end}, #{desc => "order handler 3 start", cmd => fun(#{acceptor := Acceptor, handler3 := Pid} = _State) -> - ev_start(Pid, Acceptor), + ?SEV_ANNOUNCE_START(Pid, Acceptor), ok end}, #{desc => "await handler 3 ready (init)", cmd => fun(#{handler3 := Pid} = _State) -> - ev_await_ready(Pid, handler3, init) + ?SEV_AWAIT_READY(Pid, handler3, init) end}, %% Start the client #{desc => "order client start", cmd => fun(#{client := Pid} = _State) -> - ev_start(Pid), + ?SEV_ANNOUNCE_START(Pid), ok end}, #{desc => "await client ready (init)", cmd => fun(#{client := Pid} = _State) -> - ev_await_ready(Pid, client, init) + ?SEV_AWAIT_READY(Pid, client, init) end}, %% The actual test @@ -3686,143 +3646,152 @@ sc_lc_receive_response_tcp(InitState) -> handler1 := H1, handler2 := H2, handler3 := H3} = _State) -> - ev_continue(Pid, accept, {H1, H2, H3}), - ok - end}, - #{desc => "sleep", - cmd => fun(_) -> - ?SLEEP(?SECS(1)), + ?SEV_ANNOUNCE_CONTINUE(Pid, accept, {H1, H2, H3}), ok end}, + ?SEV_SLEEP(?SECS(1)), #{desc => "order client to continue (connect)", cmd => fun(#{client := Pid, lport := Port} = _State) -> - ev_continue(Pid, connect, Port), + ?SEV_ANNOUNCE_CONTINUE(Pid, connect, Port), ok end}, #{desc => "await acceptor ready (accept)", cmd => fun(#{acceptor := Pid} = _State) -> - ok = ev_await_ready(Pid, acceptor, accept) + ok = ?SEV_AWAIT_READY(Pid, acceptor, accept) end}, #{desc => "await client ready (connect)", cmd => fun(#{client := Pid} = _State) -> - ok = ev_await_ready(Pid, client, connect) + ok = ?SEV_AWAIT_READY(Pid, client, connect) end}, #{desc => "await handler 1 ready (transfer)", cmd => fun(#{handler1 := Pid} = _State) -> - ok = ev_await_ready(Pid, handler1, transfer) + ok = ?SEV_AWAIT_READY(Pid, handler1, transfer) end}, #{desc => "await handler 2 ready (transfer)", cmd => fun(#{handler2 := Pid} = _State) -> - ok = ev_await_ready(Pid, handler2, transfer) + ok = ?SEV_AWAIT_READY(Pid, handler2, transfer) end}, #{desc => "await handler 3 ready (transfer)", cmd => fun(#{handler3 := Pid} = _State) -> - ok = ev_await_ready(Pid, handler3, transfer) - end}, - #{desc => "sleep", - cmd => fun(_State) -> - ?SLEEP(?SECS(1)), - ok + ok = ?SEV_AWAIT_READY(Pid, handler3, transfer) end}, + ?SEV_SLEEP(?SECS(1)), #{desc => "order acceptor to continue (close connection socket)", cmd => fun(#{acceptor := Pid} = _State) -> - ev_continue(Pid, close), + ?SEV_ANNOUNCE_CONTINUE(Pid, close), ok end}, #{desc => "await acceptor ready (close)", cmd => fun(#{acceptor := Pid} = _State) -> - ok = ev_await_ready(Pid, acceptor, close) + ok = ?SEV_AWAIT_READY(Pid, acceptor, close) end}, #{desc => "await handler 1 ready (recv closed)", cmd => fun(#{handler1 := Pid} = _State) -> - ok = ev_await_ready(Pid, handler1, recv_closed) + ok = ?SEV_AWAIT_READY(Pid, handler1, recv_closed) end}, #{desc => "await handler 2 ready (recv closed)", cmd => fun(#{handler2 := Pid} = _State) -> - ok = ev_await_ready(Pid, handler2, recv_closed) + ok = ?SEV_AWAIT_READY(Pid, handler2, recv_closed) end}, #{desc => "await handler 3 ready (recv closed)", cmd => fun(#{handler3 := Pid} = _State) -> - ok = ev_await_ready(Pid, handler3, recv_closed) + ok = ?SEV_AWAIT_READY(Pid, handler3, recv_closed) end}, %% Terminations #{desc => "order client to terminate", cmd => fun(#{client := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await client termination", cmd => fun(#{client := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(client, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(client, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order handler 1 to terminate", cmd => fun(#{handler1 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await handler 1 termination", cmd => fun(#{handler1 := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(handler1, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(handler1, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order handler 2 to terminate", cmd => fun(#{handler2 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await handler 2 termination", cmd => fun(#{handler2 := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(handler2, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(handler2, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order handler 3 to terminate", cmd => fun(#{handler3 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await handler 3 termination", cmd => fun(#{handler3 := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(handler3, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(handler3, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order acceptor to terminate", cmd => fun(#{acceptor := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await acceptor termination", cmd => fun(#{acceptor := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(acceptor, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(acceptor, State)}; + {error, _} = ERROR -> + ERROR + end end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("start acceptor evaluator"), AccInitState = InitState, - Acceptor = evaluator_start("acceptor", AcceptorSeq, AccInitState), + Acceptor = ?SEV_START("acceptor", AcceptorSeq, AccInitState), i("start handler 1 evaluator"), HandlerInitState = #{recv => maps:get(recv, InitState)}, - Handler1 = evaluator_start("handler-1", HandlerSeq, HandlerInitState), + Handler1 = ?SEV_START("handler-1", HandlerSeq, HandlerInitState), i("start handler 2 evaluator"), - Handler2 = evaluator_start("handler-2", HandlerSeq, HandlerInitState), + Handler2 = ?SEV_START("handler-2", HandlerSeq, HandlerInitState), i("start handler 3 evaluator"), - Handler3 = evaluator_start("handler-3", HandlerSeq, HandlerInitState), + Handler3 = ?SEV_START("handler-3", HandlerSeq, HandlerInitState), i("start client evaluator"), ClientInitState = InitState, - Client = evaluator_start("client", ClientSeq, ClientInitState), + Client = ?SEV_START("client", ClientSeq, ClientInitState), i("start tester evaluator"), TesterInitState = #{acceptor => Acceptor#ev.pid, @@ -3830,12 +3799,12 @@ sc_lc_receive_response_tcp(InitState) -> handler2 => Handler2#ev.pid, handler3 => Handler3#ev.pid, client => Client#ev.pid}, - Tester = evaluator_start("tester", TesterSeq, TesterInitState), + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), i("await evaluator"), - ok = await_evaluator_finish([Acceptor, - Handler1, Handler2, Handler3, - Client, Tester]). + ok = ?SEV_AWAIT_FINISH([Acceptor, + Handler1, Handler2, Handler3, + Client, Tester]). @@ -3888,10 +3857,10 @@ sc_lc_recvfrom_response_udp6(_Config) when is_list(_Config) -> sc_lc_receive_response_udp(InitState) -> PrimServerSeq = [ - %% *** Init part *** + %% *** Wait for start order part *** #{desc => "await start", cmd => fun(State) -> - Tester = ev_await_start(), + Tester = ?SEV_AWAIT_START(), {ok, State#{tester => Tester}} end}, #{desc => "monitor tester", @@ -3899,6 +3868,8 @@ sc_lc_receive_response_udp(InitState) -> _MRef = erlang:monitor(process, Tester), ok end}, + + %% *** Init part *** #{desc => "local address", cmd => fun(#{domain := Domain} = State) -> LAddr = which_local_addr(Domain), @@ -3918,15 +3889,19 @@ sc_lc_receive_response_udp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester, sock := Sock}) -> - ev_ready(Tester, init, Sock), + ?SEV_ANNOUNCE_READY(Tester, init, Sock), ok end}, %% The actual test #{desc => "await continue (recv, with timeout)", cmd => fun(#{tester := Tester} = State) -> - {ok, Timeout} = ev_await_continue(Tester, tester, recv), - {ok, State#{timeout => Timeout}} + case ?SEV_AWAIT_CONTINUE(Tester, tester, recv) of + {ok, Timeout} -> + {ok, State#{timeout => Timeout}}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "receive, with timeout", cmd => fun(#{sock := Sock, recv := Recv, timeout := Timeout}) -> @@ -3941,12 +3916,12 @@ sc_lc_receive_response_udp(InitState) -> end}, #{desc => "announce ready (recv, with timeout)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, recv), + ?SEV_ANNOUNCE_READY(Tester, recv), ok end}, #{desc => "await continue (close)", cmd => fun(#{tester := Tester} = _State) -> - ok = ev_await_continue(Tester, tester, close) + ok = ?SEV_AWAIT_CONTINUE(Tester, tester, close) end}, #{desc => "close socket", cmd => fun(#{sock := Sock} = State) -> @@ -3959,14 +3934,14 @@ sc_lc_receive_response_udp(InitState) -> end}, #{desc => "announce ready (close)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, close), + ?SEV_ANNOUNCE_READY(Tester, close), ok end}, %% Termination #{desc => "await terminate (from tester)", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, terminate) of + case ?SEV_AWAIT_TERMINATE(Tester, terminate) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -3975,10 +3950,7 @@ sc_lc_receive_response_udp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], SecServerSeq = @@ -3986,7 +3958,7 @@ sc_lc_receive_response_udp(InitState) -> %% *** Init part *** #{desc => "await start", cmd => fun(State) -> - {Tester, Sock} = ev_await_start(), + {Tester, Sock} = ?SEV_AWAIT_START(), {ok, State#{tester => Tester, sock => Sock}} end}, #{desc => "monitor tester", @@ -3996,14 +3968,14 @@ sc_lc_receive_response_udp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, init), + ?SEV_ANNOUNCE_READY(Tester, init), ok end}, %% The actual test #{desc => "await continue (recv)", cmd => fun(#{tester := Tester} = _State) -> - ok = ev_await_continue(Tester, tester, recv) + ok = ?SEV_AWAIT_CONTINUE(Tester, tester, recv) end}, #{desc => "receive", @@ -4019,14 +3991,14 @@ sc_lc_receive_response_udp(InitState) -> end}, #{desc => "announce ready (recv closed)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, recv_closed), + ?SEV_ANNOUNCE_READY(Tester, recv_closed), ok end}, %% Termination #{desc => "await terminate (from tester)", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -4035,10 +4007,7 @@ sc_lc_receive_response_udp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], @@ -4069,46 +4038,46 @@ sc_lc_receive_response_udp(InitState) -> %% Start the primary server #{desc => "order 'primary server' start", cmd => fun(#{prim_server := Pid} = _State) -> - ev_start(Pid), + ?SEV_ANNOUNCE_START(Pid), ok end}, #{desc => "await 'primary server' ready (init)", cmd => fun(#{prim_server := Pid} = State) -> - {ok, Sock} = ev_await_ready(Pid, prim_server, init), + {ok, Sock} = ?SEV_AWAIT_READY(Pid, prim_server, init), {ok, State#{sock => Sock}} end}, %% Start the secondary server 1 #{desc => "order 'secondary server 1' start", cmd => fun(#{sec_server1 := Pid, sock := Sock} = _State) -> - ev_start(Pid, Sock), + ?SEV_ANNOUNCE_START(Pid, Sock), ok end}, #{desc => "await 'secondary server 1' ready (init)", cmd => fun(#{sec_server1 := Pid} = _State) -> - ok = ev_await_ready(Pid, sec_server1, init) + ok = ?SEV_AWAIT_READY(Pid, sec_server1, init) end}, %% Start the secondary server 2 #{desc => "order 'secondary server 2' start", cmd => fun(#{sec_server2 := Pid, sock := Sock} = _State) -> - ev_start(Pid, Sock), + ?SEV_ANNOUNCE_START(Pid, Sock), ok end}, #{desc => "await 'secondary server 2' ready (init)", cmd => fun(#{sec_server2 := Pid} = _State) -> - ok = ev_await_ready(Pid, sec_server2, init) + ok = ?SEV_AWAIT_READY(Pid, sec_server2, init) end}, %% Start the secondary server 3 #{desc => "order 'secondary server 3' start", cmd => fun(#{sec_server3 := Pid, sock := Sock} = _State) -> - ev_start(Pid, Sock), + ?SEV_ANNOUNCE_START(Pid, Sock), ok end}, #{desc => "await 'secondary server 3' ready (init)", cmd => fun(#{sec_server3 := Pid} = _State) -> - ok = ev_await_ready(Pid, sec_server3, init) + ok = ?SEV_AWAIT_READY(Pid, sec_server3, init) end}, @@ -4121,142 +4090,142 @@ sc_lc_receive_response_udp(InitState) -> #{desc => "order 'secondary server 1' to continue (recv)", cmd => fun(#{sec_server1 := Pid} = _State) -> - ev_continue(Pid, recv), - ok - end}, - #{desc => "sleep", - cmd => fun(_) -> - ?SLEEP(?SECS(1)), + ?SEV_ANNOUNCE_CONTINUE(Pid, recv), ok end}, + ?SEV_SLEEP(?SECS(1)), #{desc => "order 'secondary server 2' to continue (recv)", cmd => fun(#{sec_server2 := Pid} = _State) -> - ev_continue(Pid, recv), - ok - end}, - #{desc => "sleep", - cmd => fun(_) -> - ?SLEEP(?SECS(1)), + ?SEV_ANNOUNCE_CONTINUE(Pid, recv), ok end}, + ?SEV_SLEEP(?SECS(1)), #{desc => "order 'secondary server 3' to continue (recv)", cmd => fun(#{sec_server3 := Pid} = _State) -> - ev_continue(Pid, recv), - ok - end}, - #{desc => "sleep", - cmd => fun(_) -> - ?SLEEP(?SECS(1)), + ?SEV_ANNOUNCE_CONTINUE(Pid, recv), ok end}, + ?SEV_SLEEP(?SECS(1)), #{desc => "order 'primary server' to continue (recv, with timeout)", cmd => fun(#{prim_server := Pid} = _State) -> - ev_continue(Pid, recv, ?SECS(5)), + ?SEV_ANNOUNCE_CONTINUE(Pid, recv, ?SECS(5)), ok end}, #{desc => "await 'primary server' ready (recv, with timeout)", cmd => fun(#{prim_server := Pid} = _State) -> - ev_await_ready(Pid, prim_server, recv) + ?SEV_AWAIT_READY(Pid, prim_server, recv) end}, #{desc => "order 'primary server' to continue (close)", cmd => fun(#{prim_server := Pid} = _State) -> - %% Pid ! {continue, self()}, - ev_continue(Pid, close), + ?SEV_ANNOUNCE_CONTINUE(Pid, close), ok end}, #{desc => "await 'primary server' ready (close)", cmd => fun(#{prim_server := Pid} = _State) -> - ev_await_ready(Pid, prim_server, close) + ?SEV_AWAIT_READY(Pid, prim_server, close) end}, #{desc => "await 'secondary server 1' ready (closed)", cmd => fun(#{sec_server1 := Pid} = _State) -> - ev_await_ready(Pid, sec_server1, recv_closed) + ?SEV_AWAIT_READY(Pid, sec_server1, recv_closed) end}, #{desc => "await 'secondary server 2' ready (closed)", cmd => fun(#{sec_server2 := Pid} = _State) -> - ev_await_ready(Pid, sec_server2, recv_closed) + ?SEV_AWAIT_READY(Pid, sec_server2, recv_closed) end}, #{desc => "await 'secondary server 3' ready (closed)", cmd => fun(#{sec_server3 := Pid} = _State) -> - ev_await_ready(Pid, sec_server3, recv_closed) + ?SEV_AWAIT_READY(Pid, sec_server3, recv_closed) end}, %% Terminations #{desc => "order 'secondary server 3' to terminate", cmd => fun(#{sec_server3 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await 'secondary server 3' termination", cmd => fun(#{sec_server3 := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(sec_server3, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(sec_server3, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order 'secondary server 2' to terminate", cmd => fun(#{sec_server2 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await 'secondary server 2' termination", cmd => fun(#{sec_server2 := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(sec_server2, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(sec_server2, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order 'secondary server 1' to terminate", cmd => fun(#{sec_server1 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await 'secondary server 1' termination", cmd => fun(#{sec_server1 := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(sec_server1, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(sec_server1, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order 'primary server' to terminate", cmd => fun(#{prim_server := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await 'primary server' termination", cmd => fun(#{prim_server := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(prim_server, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(prim_server, State)}; + {error, _} = ERROR -> + ERROR + end end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("start 'primary server' evaluator"), PrimSrvInitState = InitState, - PrimServer = evaluator_start("prim-server", PrimServerSeq, PrimSrvInitState), + PrimServer = ?SEV_START("prim-server", PrimServerSeq, PrimSrvInitState), i("start 'secondary server 1' evaluator"), SecSrvInitState = #{recv => maps:get(recv, InitState)}, - SecServer1 = evaluator_start("sec-server-1", SecServerSeq, SecSrvInitState), + SecServer1 = ?SEV_START("sec-server-1", SecServerSeq, SecSrvInitState), i("start 'secondary server 2' evaluator"), - SecServer2 = evaluator_start("sec-server-2", SecServerSeq, SecSrvInitState), + SecServer2 = ?SEV_START("sec-server-2", SecServerSeq, SecSrvInitState), i("start 'secondary server 3' evaluator"), - SecServer3 = evaluator_start("sec-server-3", SecServerSeq, SecSrvInitState), + SecServer3 = ?SEV_START("sec-server-3", SecServerSeq, SecSrvInitState), i("start 'tester' evaluator"), TesterInitState = #{prim_server => PrimServer#ev.pid, sec_server1 => SecServer1#ev.pid, sec_server2 => SecServer2#ev.pid, sec_server3 => SecServer3#ev.pid}, - Tester = evaluator_start("tester", TesterSeq, TesterInitState), + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), i("await evaluator"), - ok = await_evaluator_finish([PrimServer, - SecServer1, SecServer2, SecServer3, - Tester]). + ok = ?SEV_AWAIT_FINISH([PrimServer, + SecServer1, SecServer2, SecServer3, + Tester]). @@ -4404,10 +4373,10 @@ sc_rc_receive_response_tcp(InitState) -> %% by the server! ServerSeq = [ - %% *** Init part *** + %% *** Wait for start order part *** #{desc => "await start", cmd => fun(State) -> - Tester = ev_await_start(), + Tester = ?SEV_AWAIT_START(), {ok, State#{tester => Tester}} end}, #{desc => "monitor tester", @@ -4415,6 +4384,8 @@ sc_rc_receive_response_tcp(InitState) -> _MRef = erlang:monitor(process, Tester), ok end}, + + %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> LAddr = which_local_addr(Domain), @@ -4446,127 +4417,142 @@ sc_rc_receive_response_tcp(InitState) -> #{desc => "announce ready (init)", cmd => fun(#{tester := Tester, local_sa := LSA, lport := Port}) -> ServerSA = LSA#{port => Port}, - ev_ready(Tester, init, ServerSA), + ?SEV_ANNOUNCE_READY(Tester, init, ServerSA), ok end}, %% The actual test (we expect three connections) #{desc => "await continue (accept all three connections)", cmd => fun(#{tester := Tester} = _State) -> - ev_await_continue(Tester, tester, accept) + ?SEV_ANNOUNCE_CONTINUE(Tester, tester, accept) end}, #{desc => "accept 1", cmd => fun(#{lsock := LSock, recv := Recv} = State) -> case socket:accept(LSock) of {ok, Sock} -> - ei("accepted: try start handler"), - {ok, Handler} = sc_rc_tcp_handler_start(1, - Recv, - Sock), - ei("handler started"), + ?SEV_IPRINT("accepted: try start handler"), + Handler = sc_rc_tcp_handler_start(1, Recv, Sock), + ?SEV_IPRINT("handler started"), {ok, State#{csock1 => Sock, handler1 => Handler}}; {error, _} = ERROR -> ERROR end end}, + #{desc => "await handle 1 ready (init)", + cmd => fun(#{tester := Tester, + handler1 := Handler1} = _State) -> + ?SEV_AWAIT_READY(Handler1, handler1, init, + [{tester, Tester}]) + end}, #{desc => "accept 2", cmd => fun(#{lsock := LSock, recv := Recv} = State) -> case socket:accept(LSock) of {ok, Sock} -> - ei("accepted: try start handler"), - {ok, Handler} = sc_rc_tcp_handler_start(2, - Recv, - Sock), - ei("handler started"), + ?SEV_IPRINT("accepted: try start handler"), + Handler = sc_rc_tcp_handler_start(2, Recv, Sock), + ?SEV_IPRINT("handler started"), {ok, State#{csock2 => Sock, handler2 => Handler}}; {error, _} = ERROR -> ERROR end end}, + #{desc => "await handle 2 ready (init)", + cmd => fun(#{tester := Tester, + handler1 := Handler1, + handler2 := Handler2} = _State) -> + ?SEV_AWAIT_READY(Handler2, handler2, init, + [{tester, Tester}, + {handler1, Handler1}]) + end}, #{desc => "accept 3", cmd => fun(#{lsock := LSock, recv := Recv} = State) -> case socket:accept(LSock) of {ok, Sock} -> - ei("accepted: try start handler"), - {ok, Handler} = sc_rc_tcp_handler_start(3, - Recv, - Sock), - ei("handler started"), + ?SEV_IPRINT("accepted: try start handler"), + Handler = sc_rc_tcp_handler_start(3, Recv, Sock), + ?SEV_IPRINT("handler started"), {ok, State#{csock3 => Sock, handler3 => Handler}}; {error, _} = ERROR -> ERROR end end}, + #{desc => "await handle 3 ready (init)", + cmd => fun(#{tester := Tester, + handler1 := Handler1, + handler2 := Handler2, + handler3 := Handler3} = _State) -> + ?SEV_AWAIT_READY(Handler3, handler3, init, + [{tester, Tester}, + {handler1, Handler1}, + {handler2, Handler2}]) + end}, #{desc => "announce ready (accept all three connections)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, accept), + ?SEV_ANNOUNCE_READY(Tester, accept), ok end}, #{desc => "await continue (recv)", cmd => fun(#{tester := Tester} = _State) -> - ev_await_continue(Tester, tester, recv) + ?SEV_AWAIT_CONTINUE(Tester, tester, recv) end}, #{desc => "order handler 1 to receive", cmd => fun(#{handler1 := Pid} = _State) -> - Pid ! {recv, self()}, + ?SEV_ANNOUNCE_CONTINUE(Pid, recv), ok end}, #{desc => "order handler 2 to receive", cmd => fun(#{handler2 := Pid} = _State) -> - Pid ! {recv, self()}, + ?SEV_ANNOUNCE_CONTINUE(Pid, recv), ok end}, #{desc => "order handler 3 to receive", cmd => fun(#{handler3 := Pid} = _State) -> - Pid ! {recv, self()}, + ?SEV_ANNOUNCE_CONTINUE(Pid, recv), ok end}, #{desc => "await ready from handler 1 (recv)", - cmd => fun(#{handler1 := Pid} = _State) -> - receive - {ready, Pid, ok} -> - ok; - {ready, Pid, Result} -> + cmd => fun(#{tester := Tester, handler1 := Pid} = _State) -> + case ?SEV_AWAIT_READY(Pid, handler1, recv, + [{tester, Tester}]) of + {ok, Result} -> Result; - {'DOWN', _, process, Pid, Reason} -> - {error, {handler1_exit, Reason}} + {error, _} = ERROR -> + ERROR end end}, #{desc => "await ready from handler 2 (recv)", - cmd => fun(#{handler2 := Pid} = _State) -> - receive - {ready, Pid, ok} -> - ok; - {ready, Pid, Result} -> + cmd => fun(#{tester := Tester, handler2 := Pid} = _State) -> + case ?SEV_AWAIT_READY(Pid, handler2, recv, + [{tester, Tester}]) of + {ok, Result} -> Result; - {'DOWN', _, process, Pid, Reason} -> - {error, {handler2_exit, Reason}} + {error, _} = ERROR -> + ERROR end end}, #{desc => "await ready from handler 3 (recv)", - cmd => fun(#{handler3 := Pid} = _State) -> - receive - {ready, Pid, ok} -> - ok; - {ready, Pid, Result} -> + cmd => fun(#{tester := Tester, handler3 := Pid} = _State) -> + case ?SEV_AWAIT_READY(Pid, handler3, recv, + [{tester, Tester}]) of + {ok, Result} -> Result; - {'DOWN', _, process, Pid, Reason} -> - {error, {handler3_exit, Reason}} + {error, _} = ERROR -> + ERROR end end}, #{desc => "announce ready (recv closed from all handlers)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, recv_closed), + ?SEV_ANNOUNCE_READY(Tester, recv_closed), ok end}, %% Termination #{desc => "await terminate (from tester)", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -4575,45 +4561,40 @@ sc_rc_receive_response_tcp(InitState) -> end}, #{desc => "order handler 1 to terminate", cmd => fun(#{handler1 := Pid} = _State) -> - Pid ! {terminate, self(), ok}, + %% Pid ! {terminate, self(), ok}, + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await handler 1 termination", cmd => fun(#{handler1 := Pid} = State) -> - receive - {'DOWN', _, process, Pid, _} -> - State1 = maps:remove(csock1, State), - State2 = maps:remove(handler1, State1), - {ok, State2} - end + ?SEV_AWAIT_TERMINATION(Pid), + State1 = maps:remove(csock1, State), + State2 = maps:remove(handler1, State1), + {ok, State2} end}, #{desc => "order handler 2 to terminate", cmd => fun(#{handler2 := Pid} = _State) -> - Pid ! {terminate, self(), ok}, + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await handler 2 termination", cmd => fun(#{handler2 := Pid} = State) -> - receive - {'DOWN', _, process, Pid, _} -> - State1 = maps:remove(csock2, State), - State2 = maps:remove(handler2, State1), - {ok, State2} - end + ?SEV_AWAIT_TERMINATION(Pid), + State1 = maps:remove(csock2, State), + State2 = maps:remove(handler2, State1), + {ok, State2} end}, #{desc => "order handler 3 to terminate", cmd => fun(#{handler3 := Pid} = _State) -> - Pid ! {terminate, self(), ok}, + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await handler 3 termination", cmd => fun(#{handler3 := Pid} = State) -> - receive - {'DOWN', _, process, Pid, _} -> - State1 = maps:remove(csock3, State), - State2 = maps:remove(handler3, State1), - {ok, State2} - end + ?SEV_AWAIT_TERMINATION(Pid), + State1 = maps:remove(csock3, State), + State2 = maps:remove(handler3, State1), + {ok, State2} end}, #{desc => "close listen socket", cmd => fun(#{lsock := LSock} = State) -> @@ -4626,20 +4607,17 @@ sc_rc_receive_response_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], ClientSeq = [ - %% *** Init part *** + %% *** Wait for start order part *** #{desc => "await start", cmd => fun(State) -> - {Tester, {Node, ServerSA}} = ev_await_start(), + {Tester, {NodeID, ServerSA}} = ?SEV_AWAIT_START(), {ok, State#{tester => Tester, - node => Node, + node_id => NodeID, server_sa => ServerSA}} end}, #{desc => "monitor tester", @@ -4647,186 +4625,143 @@ sc_rc_receive_response_tcp(InitState) -> _MRef = erlang:monitor(process, Tester), ok end}, + + %% *** Init part *** + #{desc => "create node", + cmd => fun(#{host := Host, node_id := NodeID} = State) -> + case start_node(Host, l2a(f("client_~w", [NodeID]))) of + {ok, Node} -> + ?SEV_IPRINT("client node ~p started", [Node]), + {ok, State#{node => Node}}; + {error, Reason, _} -> + {error, Reason} + end + end}, + #{desc => "monitor client node 1", + cmd => fun(#{node := Node} = _State) -> + true = erlang:monitor_node(Node, true), + ok + end}, #{desc => "start remote client on client node", cmd => fun(#{node := Node} = State) -> Pid = sc_rc_tcp_client_start(Node), - ei("client ~p started", [Pid]), - {ok, State#{client => Pid}} + ?SEV_IPRINT("client ~p started", [Pid]), + {ok, State#{rclient => Pid}} end}, #{desc => "monitor remote client", - cmd => fun(#{client := Pid}) -> + cmd => fun(#{rclient := Pid}) -> _MRef = erlang:monitor(process, Pid), ok end}, #{desc => "order remote client to start", - cmd => fun(#{client := Client, server_sa := ServerSA}) -> - Client ! {start, self(), ServerSA}, + cmd => fun(#{rclient := Client, server_sa := ServerSA}) -> + ?SEV_ANNOUNCE_START(Client, ServerSA), ok end}, #{desc => "await remote client ready", - cmd => fun(#{tester := Tester, - client := Client} = _State) -> - receive - {ready, Client} -> - ok; - {'DOWN', _, process, Tester, Reason} -> - ee("Unexpected DOWN regarding tester ~p: " - "~n ~p", [Tester, Reason]), - {error, {unexpected_exit, tester}}; - {'DOWN', _, process, Client, Reason} -> - ee("Unexpected DOWN regarding client ~p: " - "~n ~p", [Client, Reason]), - {error, {unexpected_exit, client}} - end + cmd => fun(#{tester := Tester, + rclient := Client} = _State) -> + ?SEV_AWAIT_READY(Client, rclient, init, + [{tester, Tester}]) end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, init), + ?SEV_ANNOUNCE_READY(Tester, init), ok end}, %% The actual test #{desc => "await continue (connect)", - cmd => fun(#{tester := Tester, - client := Client} = _State) -> - ev_await_continue(Tester, tester, connect, - [{rclient, Client}]), + cmd => fun(#{tester := Tester, + rclient := Client} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, connect, + [{rclient, Client}]), ok end}, #{desc => "order remote client to continue (connect)", - cmd => fun(#{client := Client}) -> - Client ! {continue, self()}, + cmd => fun(#{rclient := Client}) -> + ?SEV_ANNOUNCE_CONTINUE(Client, connect), ok end}, #{desc => "await client process ready (connect)", - cmd => fun(#{tester := Tester, - client := Client} = _State) -> - receive - {ready, Client} -> - ok; - {'DOWN', _, process, Tester, Reason} -> - ee("Unexpected DOWN regarding tester ~p: " - "~n ~p", [Tester, Reason]), - {error, {unexpected_exit, tester}}; - {'DOWN', _, process, Client, Reason} -> - ee("Unexpected DOWN regarding client ~p: " - "~n ~p", [Client, Reason]), - {error, {unexpected_exit, client}} - end + cmd => fun(#{tester := Tester, + rclient := Client} = _State) -> + ?SEV_AWAIT_READY(Client, rclient, connect, + [{tester, Tester}]) end}, #{desc => "announce ready (connected)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, connect), + ?SEV_ANNOUNCE_READY(Tester, connect), ok end}, #{desc => "await continue (close)", - cmd => fun(#{tester := Tester, - client := Client} = _State) -> - ev_await_continue(Tester, tester, close, - [{rclient, Client}]), + cmd => fun(#{tester := Tester, + rclient := Client} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, close, + [{rclient, Client}]), ok end}, #{desc => "order remote client to close", - cmd => fun(#{client := Client}) -> - Client ! {continue, self()}, + cmd => fun(#{rclient := Client}) -> + ?SEV_ANNOUNCE_CONTINUE(Client, close), ok end}, #{desc => "await remote client ready (closed)", - cmd => fun(#{tester := Tester, - client := Client} = _State) -> - receive - {ready, Client} -> - ok; - {'DOWN', _, process, Tester, Reason} -> - ee("Unexpected DOWN regarding tester ~p: " - "~n ~p", [Tester, Reason]), - {error, {unexpected_exit, tester}}; - {'DOWN', _, process, Client, Reason} -> - ee("Unexpected DOWN regarding client ~p: " - "~n ~p", [Client, Reason]), - {error, {unexpected_exit, client}} - end + cmd => fun(#{tester := Tester, + rclient := Client} = _State) -> + ?SEV_AWAIT_READY(Client, rclient, close, + [{tester, Tester}]) end}, #{desc => "announce ready (close)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, close), + ?SEV_ANNOUNCE_READY(Tester, close), ok end}, %% Termination #{desc => "await terminate (from tester)", - cmd => fun(#{tester := Tester, client := Client} = State) -> - ev_await_terminate(Tester, tester, [{rclient, Client}]), - {ok, maps:remove(tester, State)} + cmd => fun(#{tester := Tester, + rclient := Client} = State) -> + case ?SEV_AWAIT_TERMINATE(Tester, tester, + [{rclient, Client}]) of + ok -> + {ok, maps:remove(tester, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "kill remote client", - cmd => fun(#{client := Client}) -> - Client ! {terminate, self(), normal}, + cmd => fun(#{rclient := Client}) -> + ?SEV_ANNOUNCE_TERMINATE(Client), ok end}, #{desc => "await remote client termination", - cmd => fun(#{client := Client} = State) -> + cmd => fun(#{rclient := Client} = State) -> + ?SEV_AWAIT_TERMINATION(Client), + State1 = maps:remove(rclient, State), + {ok, State1} + end}, + #{desc => "stop client node", + cmd => fun(#{node := Node} = _State) -> + stop_node(Node) + end}, + #{desc => "await client node termination", + cmd => fun(#{node := Node} = State) -> receive - {'DOWN', _, process, Client, _} -> - {ok, maps:remove(client, State)} + {nodedown, Node} -> + State1 = maps:remove(node_id, State), + State2 = maps:remove(node, State1), + {ok, State2} end end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], TesterSeq = [ %% *** Init part *** - #{desc => "create client node 1", - cmd => fun(#{host := Host} = State) -> - case start_node(Host, client_1) of - {ok, Node} -> - ei("client node (1) ~p started", [Node]), - {ok, State#{client_node1 => Node}}; - {error, Reason, _} -> - {error, Reason} - end - end}, - #{desc => "monitor client node 1", - cmd => fun(#{client_node1 := Node} = _State) -> - true = erlang:monitor_node(Node, true), - ok - end}, - #{desc => "create client node 2", - cmd => fun(#{host := Host} = State) -> - case start_node(Host, client_2) of - {ok, Node} -> - ei("client node (2) ~p started", [Node]), - {ok, State#{client_node2 => Node}}; - {error, Reason, _} -> - {error, Reason} - end - end}, - #{desc => "monitor client node 2", - cmd => fun(#{client_node2 := Node} = _State) -> - true = erlang:monitor_node(Node, true), - ok - end}, - #{desc => "create client node 3", - cmd => fun(#{host := Host} = State) -> - case start_node(Host, client_3) of - {ok, Node} -> - ei("client node (3) ~p started", [Node]), - {ok, State#{client_node3 => Node}}; - {error, Reason, _} -> - {error, Reason} - end - end}, - #{desc => "monitor client node 3", - cmd => fun(#{client_node3 := Node} = _State) -> - true = erlang:monitor_node(Node, true), - ok - end}, #{desc => "monitor server", cmd => fun(#{server := Pid} = _State) -> _MRef = erlang:monitor(process, Pid), @@ -4851,64 +4786,57 @@ sc_rc_receive_response_tcp(InitState) -> %% Start the server #{desc => "order server start", cmd => fun(#{server := Pid} = _State) -> - ev_start(Pid), + ?SEV_ANNOUNCE_START(Pid), ok end}, #{desc => "await server ready (init)", cmd => fun(#{server := Pid} = State) -> - {ok, ServerSA} = ev_await_ready(Pid, server, init), + {ok, ServerSA} = ?SEV_AWAIT_READY(Pid, server, init), {ok, State#{server_sa => ServerSA}} end}, %% Start the client(s) #{desc => "order client 1 start", - cmd => fun(#{client1 := Pid, - client_node1 := Node, - server_sa := ServerSA} = _State) -> - ev_start(Pid, {Node, ServerSA}), + cmd => fun(#{client1 := Pid, + server_sa := ServerSA} = _State) -> + ?SEV_ANNOUNCE_START(Pid, {1, ServerSA}), ok end}, #{desc => "await client 1 ready (init)", cmd => fun(#{client1 := Pid} = _State) -> - ok = ev_await_ready(Pid, client, init) + ok = ?SEV_AWAIT_READY(Pid, client1, init) end}, #{desc => "order client 2 start", - cmd => fun(#{client2 := Pid, - client_node2 := Node, - server_sa := ServerSA} = _State) -> - ev_start(Pid, {Node, ServerSA}), + cmd => fun(#{client2 := Pid, + server_sa := ServerSA} = _State) -> + ?SEV_ANNOUNCE_START(Pid, {2, ServerSA}), ok end}, #{desc => "await client 2 ready (init)", cmd => fun(#{client2 := Pid} = _State) -> - ok = ev_await_ready(Pid, client, init) + ok = ?SEV_AWAIT_READY(Pid, client2, init) end}, #{desc => "order client 3 start", - cmd => fun(#{client3 := Pid, - client_node3 := Node, - server_sa := ServerSA} = _State) -> - ev_start(Pid, {Node, ServerSA}), + cmd => fun(#{client3 := Pid, + server_sa := ServerSA} = _State) -> + ?SEV_ANNOUNCE_START(Pid, {3, ServerSA}), ok end}, #{desc => "await client 3 ready (init)", cmd => fun(#{client3 := Pid} = _State) -> - ok = ev_await_ready(Pid, client, init) + ok = ?SEV_AWAIT_READY(Pid, client3, init) end}, %% The actual test #{desc => "order server continue (accept)", cmd => fun(#{server := Pid} = _State) -> - ev_continue(Pid, accept), - ok - end}, - #{desc => "sleep", - cmd => fun(_) -> - ?SLEEP(?SECS(1)), + ?SEV_ANNOUNCE_CONTINUE(Pid, accept), ok end}, + ?SEV_SLEEP(?SECS(1)), #{desc => "order client 1 continue (connect)", cmd => fun(#{client1 := Pid} = _State) -> - ev_continue(Pid, connect), + ?SEV_ANNOUNCE_CONTINUE(Pid, connect), ok end}, #{desc => "await client 1 ready (connect)", @@ -4916,15 +4844,15 @@ sc_rc_receive_response_tcp(InitState) -> client1 := Client1, client2 := Client2, client3 := Client3} = _State) -> - ev_await_ready(Client1, client1, connect, - [{server, Server}, - {client2, Client2}, - {client3, Client3}]), + ?SEV_AWAIT_READY(Client1, client1, connect, + [{server, Server}, + {client2, Client2}, + {client3, Client3}]), ok end}, #{desc => "order client 2 continue (connect)", cmd => fun(#{client2 := Pid} = _State) -> - ev_continue(Pid, connect), + ?SEV_ANNOUNCE_CONTINUE(Pid, connect), ok end}, #{desc => "await client 2 ready (connect)", @@ -4932,15 +4860,15 @@ sc_rc_receive_response_tcp(InitState) -> client1 := Client1, client2 := Client2, client3 := Client3} = _State) -> - ev_await_ready(Client2, client2, connect, - [{server, Server}, - {client1, Client1}, - {client3, Client3}]), + ?SEV_AWAIT_READY(Client2, client2, connect, + [{server, Server}, + {client1, Client1}, + {client3, Client3}]), ok end}, #{desc => "order client 3 continue (connect)", cmd => fun(#{client3 := Pid} = _State) -> - ev_continue(Pid, connect), + ?SEV_ANNOUNCE_CONTINUE(Pid, connect), ok end}, #{desc => "await client 3 ready (connect)", @@ -4948,10 +4876,10 @@ sc_rc_receive_response_tcp(InitState) -> client1 := Client1, client2 := Client2, client3 := Client3} = _State) -> - ev_await_ready(Client3, client3, connect, - [{server, Server}, - {client1, Client1}, - {client2, Client2}]), + ?SEV_AWAIT_READY(Client3, client3, connect, + [{server, Server}, + {client1, Client1}, + {client2, Client2}]), ok end}, #{desc => "await server ready (accept from all connections)", @@ -4959,25 +4887,21 @@ sc_rc_receive_response_tcp(InitState) -> client1 := Client1, client2 := Client2, client3 := Client3} = _State) -> - ev_await_ready(Server, server, accept, - [{client1, Client1}, - {client2, Client2}, - {client3, Client3}]), + ?SEV_AWAIT_READY(Server, server, accept, + [{client1, Client1}, + {client2, Client2}, + {client3, Client3}]), ok end}, #{desc => "order server continue (recv for all connections)", cmd => fun(#{server := Pid} = _State) -> - ev_continue(Pid, recv), - ok - end}, - #{desc => "sleep", - cmd => fun(_) -> - ?SLEEP(?SECS(1)), + ?SEV_ANNOUNCE_CONTINUE(Pid, recv), ok end}, + ?SEV_SLEEP(?SECS(1)), #{desc => "order client 1 continue (close)", cmd => fun(#{client1 := Pid} = _State) -> - ev_continue(Pid, close), + ?SEV_ANNOUNCE_CONTINUE(Pid, close), ok end}, #{desc => "await client 1 ready (close)", @@ -4985,15 +4909,15 @@ sc_rc_receive_response_tcp(InitState) -> client1 := Client1, client2 := Client2, client3 := Client3} = _State) -> - ev_await_ready(Client1, client1, close, - [{server, Server}, - {client2, Client2}, - {client3, Client3}]), + ?SEV_AWAIT_READY(Client1, client1, close, + [{server, Server}, + {client2, Client2}, + {client3, Client3}]), ok end}, #{desc => "order client 2 continue (close)", cmd => fun(#{client2 := Pid} = _State) -> - ev_continue(Pid, close), + ?SEV_ANNOUNCE_CONTINUE(Pid, close), ok end}, #{desc => "await client 2 ready (close)", @@ -5001,15 +4925,15 @@ sc_rc_receive_response_tcp(InitState) -> client1 := Client1, client2 := Client2, client3 := Client3} = _State) -> - ev_await_ready(Client2, client2, close, - [{server, Server}, - {client1, Client1}, - {client3, Client3}]), + ?SEV_AWAIT_READY(Client2, client2, close, + [{server, Server}, + {client1, Client1}, + {client3, Client3}]), ok end}, #{desc => "order client 3 continue (close)", cmd => fun(#{client3 := Pid} = _State) -> - ev_continue(Pid, close), + ?SEV_ANNOUNCE_CONTINUE(Pid, close), ok end}, #{desc => "await client 3 ready (close)", @@ -5017,10 +4941,10 @@ sc_rc_receive_response_tcp(InitState) -> client1 := Client1, client2 := Client2, client3 := Client3} = _State) -> - ev_await_ready(Client3, client1, close, - [{server, Server}, - {client1, Client1}, - {client2, Client2}]), + ?SEV_AWAIT_READY(Client3, client1, close, + [{server, Server}, + {client1, Client1}, + {client2, Client2}]), ok end}, #{desc => "await server ready (close for all connections)", @@ -5028,121 +4952,100 @@ sc_rc_receive_response_tcp(InitState) -> client1 := Client1, client2 := Client2, client3 := Client3} = _State) -> - ev_await_ready(Server, server, recv_closed, - [{client1, Client1}, - {client2, Client2}, - {client3, Client3}]), + ?SEV_AWAIT_READY(Server, server, recv_closed, + [{client1, Client1}, + {client2, Client2}, + {client3, Client3}]), ok end}, %% Terminations #{desc => "order client 1 to terminate", cmd => fun(#{client1 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await client 1 termination", cmd => fun(#{client1 := Pid} = State) -> - ev_await_termination(Pid), - State1 = maps:remove(client1, State), - {ok, State1} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + State1 = maps:remove(client1, State), + {ok, State1}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order client 2 to terminate", cmd => fun(#{client2 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await client 2 termination", cmd => fun(#{client2 := Pid} = State) -> - ev_await_termination(Pid), - State1 = maps:remove(client2, State), - {ok, State1} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + State1 = maps:remove(client2, State), + {ok, State1}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order client 3 to terminate", cmd => fun(#{client3 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await client 3 termination", cmd => fun(#{client3 := Pid} = State) -> - ev_await_termination(Pid), - State1 = maps:remove(client3, State), - {ok, State1} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + State1 = maps:remove(client3, State), + {ok, State1}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order server to terminate", cmd => fun(#{server := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await server termination", cmd => fun(#{server := Pid} = State) -> - ev_await_termination(Pid), - State1 = maps:remove(server, State), - {ok, State1} - end}, - #{desc => "stop client node 1", - cmd => fun(#{client_node1 := Node} = _State) -> - stop_node(Node) - end}, - #{desc => "await client node 1 termination", - cmd => fun(#{client_node1 := Node} = State) -> - receive - {nodedown, Node} -> - {ok, maps:remove(client_node1, State)} - end - end}, - #{desc => "stop client node 2", - cmd => fun(#{client_node2 := Node} = _State) -> - stop_node(Node) - end}, - #{desc => "await client node 2 termination", - cmd => fun(#{client_node2 := Node} = State) -> - receive - {nodedown, Node} -> - {ok, maps:remove(client_node2, State)} - end - end}, - #{desc => "stop client node 3", - cmd => fun(#{client_node3 := Node} = _State) -> - stop_node(Node) - end}, - #{desc => "await client node 3 termination", - cmd => fun(#{client_node3 := Node} = State) -> - receive - {nodedown, Node} -> - {ok, maps:remove(client_node3, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + State1 = maps:remove(server, State), + {ok, State1}; + {error, _} = ERROR -> + ERROR end end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("start server evaluator"), ServerInitState = InitState, - Server = evaluator_start("server", ServerSeq, ServerInitState), + Server = ?SEV_START("server", ServerSeq, ServerInitState), i("start client evaluator(s)"), - ClientInitState = InitState, - Client1 = evaluator_start("client-1", ClientSeq, ClientInitState), - Client2 = evaluator_start("client-2", ClientSeq, ClientInitState), - Client3 = evaluator_start("client-3", ClientSeq, ClientInitState), + ClientInitState = InitState#{host => local_host()}, + Client1 = ?SEV_START("client-1", ClientSeq, ClientInitState), + Client2 = ?SEV_START("client-2", ClientSeq, ClientInitState), + Client3 = ?SEV_START("client-3", ClientSeq, ClientInitState), i("start 'tester' evaluator"), - TesterInitState = #{host => local_host(), - server => Server#ev.pid, + TesterInitState = #{server => Server#ev.pid, client1 => Client1#ev.pid, client2 => Client2#ev.pid, client3 => Client3#ev.pid}, - Tester = evaluator_start("tester", TesterSeq, TesterInitState), + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), i("await evaluator"), - ok = await_evaluator_finish([Server, - Client1, Client2, Client3, - Tester]). + ok = ?SEV_AWAIT_FINISH([Server, + Client1, Client2, Client3, + Tester]). start_node(Host, NodeName) -> @@ -5193,13 +5096,13 @@ sc_rc_tcp_client(Parent, GL) -> Domain = maps:get(family, ServerSA), Sock = sc_rc_tcp_client_create(Domain), sc_rc_tcp_client_bind(Sock, Domain), - sc_rc_tcp_client_announce_ready(Parent), - sc_rc_tcp_client_await_continue(Parent), + sc_rc_tcp_client_announce_ready(Parent, init), + sc_rc_tcp_client_await_continue(Parent, connect), sc_rc_tcp_client_connect(Sock, ServerSA), - sc_rc_tcp_client_announce_ready(Parent), - sc_rc_tcp_client_await_continue(Parent), + sc_rc_tcp_client_announce_ready(Parent, connect), + sc_rc_tcp_client_await_continue(Parent, close), sc_rc_tcp_client_close(Sock), - sc_rc_tcp_client_announce_ready(Parent), + sc_rc_tcp_client_announce_ready(Parent, close), Reason = sc_rc_tcp_client_await_terminate(Parent), exit(Reason). @@ -5211,12 +5114,7 @@ sc_rc_tcp_client_init(Parent, GL) -> sc_rc_tcp_client_await_start(Parent) -> i("sc_rc_tcp_client_await_start -> entry"), - receive - {start, Parent, ServerSA} -> - ServerSA; - {'DOWN', _, process, Parent, _Reason} -> - init:stop() - end. + ?SEV_AWAIT_START(Parent). sc_rc_tcp_client_create(Domain) -> i("sc_rc_tcp_client_create -> entry"), @@ -5239,18 +5137,12 @@ sc_rc_tcp_client_bind(Sock, Domain) -> exit({bind, Reason}) end. -sc_rc_tcp_client_announce_ready(Parent) -> - Parent ! {ready, self()}, - ok. +sc_rc_tcp_client_announce_ready(Parent, Slogan) -> + ?SEV_ANNOUNCE_READY(Parent, Slogan). -sc_rc_tcp_client_await_continue(Parent) -> +sc_rc_tcp_client_await_continue(Parent, Slogan) -> i("sc_rc_tcp_client_await_continue -> entry"), - receive - {continue, Parent} -> - ok; - {'DOWN', _, process, Parent, _Reason} -> - init:stop() - end. + ?SEV_AWAIT_CONTINUE(Parent, parent, Slogan). sc_rc_tcp_client_connect(Sock, ServerSA) -> i("sc_rc_tcp_client_connect -> entry"), @@ -5272,11 +5164,11 @@ sc_rc_tcp_client_close(Sock) -> sc_rc_tcp_client_await_terminate(Parent) -> i("sc_rc_tcp_client_await_terminate -> entry"), - receive - {terminate, Parent, Reason} -> - Reason; - {'DOWN', _, process, Parent, _Reason} -> - init:stop() + case ?SEV_AWAIT_TERMINATE(Parent, parent) of + ok -> + ok; + {error, Reason} -> + Reason end. @@ -5286,76 +5178,56 @@ sc_rc_tcp_handler_start(ID, Recv, Sock) -> Self = self(), Fun = fun() -> sc_rc_tcp_handler(ID, Self, Recv, Sock) end, {Pid, _} = erlang:spawn_monitor(Fun), - receive - {started, Pid} -> - {ok, Pid}; - {'DOWN', _, process, Pid, Reason} -> - {error, Reason} - end. + Pid. sc_rc_tcp_handler(ID, Parent, Recv, Sock) -> sc_rc_tcp_handler_init(ID, Parent), - sc_rc_tcp_handler_await_recv(Parent), + sc_rc_tcp_handler_await(Parent, recv), RecvRes = sc_rc_tcp_handler_recv(Recv, Sock), - sc_rc_tcp_handler_announce_ready(Parent, RecvRes), - Reason = sc_rc_tcp_handler_await_terminate(Parent), + sc_rc_tcp_handler_announce_ready(Parent, recv, RecvRes), + Reason = sc_rc_tcp_handler_await(Parent, terminate), exit(Reason). sc_rc_tcp_handler_init(ID, Parent) -> put(sname, f("handler-~w", [ID])), _MRef = erlang:monitor(process, Parent), - Parent ! {started, self()}, - ei("started"), + ?SEV_IPRINT("started"), + ?SEV_ANNOUNCE_READY(Parent, init), ok. -sc_rc_tcp_handler_await_recv(Parent) -> - ei("await recv"), - receive - {recv, Parent} -> - ok; - {'DOWN', _, process, Parent, Reason} -> - ee("received DOWN regarding parent: " - "~n ~p", [Reason]), - exit({parent, Reason}) - end. +sc_rc_tcp_handler_await(Parent, terminate) -> + ?SEV_IPRINT("await terminate"), + ?SEV_AWAIT_TERMINATE(Parent, tester); +sc_rc_tcp_handler_await(Parent, Slogan) -> + ?SEV_IPRINT("await ~w", [Slogan]), + ?SEV_AWAIT_CONTINUE(Parent, parent, Slogan). sc_rc_tcp_handler_recv(Recv, Sock) -> - ei("recv"), + ?SEV_IPRINT("recv"), try Recv(Sock) of {error, closed} -> ok; {ok, _} -> - ei("unexpected success"), + ?SEV_IPRINT("unexpected success"), {error, unexpected_success}; {error, Reason} = ERROR -> - ei("receive error: " + ?SEV_IPRINT("receive error: " "~n ~p", [Reason]), ERROR catch C:E:S -> - ei("receive failure: " + ?SEV_IPRINT("receive failure: " "~n Class: ~p" "~n Error: ~p" "~n Stack: ~p", [C, E, S]), {error, {recv, C, E, S}} end. -sc_rc_tcp_handler_announce_ready(Parent, Result) -> - ei("announce ready"), - Parent ! {ready, self(), Result}, +sc_rc_tcp_handler_announce_ready(Parent, Slogan, Result) -> + ?SEV_IPRINT("announce ready"), + ?SEV_ANNOUNCE_READY(Parent, Slogan, Result), ok. -sc_rc_tcp_handler_await_terminate(Parent) -> - ei("await terminate"), - receive - {terminate, Parent, Reason} -> - Reason; - {'DOWN', _, process, Parent, Reason} -> - ee("received DOWN regarding parent: " - "~n ~p", [Reason]), - {parent, Reason} - end. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test what happens when a socket is @@ -5455,7 +5327,7 @@ sc_lc_acceptor_response_tcp(InitState) -> %% *** Wait for start order part *** #{desc => "await start (from tester)", cmd => fun(State) -> - Tester = ev_await_start(), + Tester = ?SEV_AWAIT_START(), {ok, State#{tester => Tester}} end}, #{desc => "monitor tester", @@ -5497,16 +5369,19 @@ sc_lc_acceptor_response_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester, sock := Sock} = _State) -> - ev_ready(Tester, init, Sock), + ?SEV_ANNOUNCE_READY(Tester, init, Sock), ok end}, %% The actual test #{desc => "await continue (accept)", cmd => fun(#{tester := Tester} = State) -> - {ok, Timeout} = - ev_await_continue(Tester, tester, accept), - {ok, State#{timeout => Timeout}} + case ?SEV_AWAIT_CONTINUE(Tester, tester, accept) of + {ok, Timeout} -> + {ok, State#{timeout => Timeout}}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "await connection", cmd => fun(#{sock := Sock, timeout := Timeout} = _State) -> @@ -5514,7 +5389,7 @@ sc_lc_acceptor_response_tcp(InitState) -> {error, timeout} -> ok; {ok, Sock} -> - ee("unexpected success"), + ?SEV_EPRINT("unexpected success"), (catch socket:close(Sock)), {error, unexpected_success}; {error, _} = ERROR -> @@ -5523,13 +5398,12 @@ sc_lc_acceptor_response_tcp(InitState) -> end}, #{desc => "announce ready (accept timeout)", cmd => fun(#{tester := Tester}) -> - Tester ! {ready, self()}, - ev_ready(Tester, accept_timeout), + ?SEV_ANNOUNCE_READY(Tester, accept_timeout), ok end}, #{desc => "await continue (close)", cmd => fun(#{tester := Tester} = _State) -> - ok = ev_await_continue(Tester, tester, close) + ok = ?SEV_AWAIT_CONTINUE(Tester, tester, close) end}, #{desc => "close socket", cmd => fun(#{sock := Sock} = State) -> @@ -5542,14 +5416,14 @@ sc_lc_acceptor_response_tcp(InitState) -> end}, #{desc => "announce ready (close)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, close), + ?SEV_ANNOUNCE_READY(Tester, close), ok end}, % Termination #{desc => "await terminate", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -5558,10 +5432,7 @@ sc_lc_acceptor_response_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], SecAcceptorSeq = @@ -5569,7 +5440,7 @@ sc_lc_acceptor_response_tcp(InitState) -> %% *** Init part *** #{desc => "await start", cmd => fun(State) -> - {Tester, Sock} = ev_await_start(), + {Tester, Sock} = ?SEV_AWAIT_START(), {ok, State#{tester => Tester, sock => Sock}} end}, #{desc => "monitor tester", @@ -5579,15 +5450,13 @@ sc_lc_acceptor_response_tcp(InitState) -> end}, #{desc => "announce ready (init)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, init), - ok + ?SEV_ANNOUNCE_READY(Tester, init) end}, %% The actual test #{desc => "await continue (accept)", cmd => fun(#{tester := Tester} = _State) -> - ev_await_continue(Tester, tester, accept), - ok + ok = ?SEV_AWAIT_CONTINUE(Tester, tester, accept) end}, #{desc => "accept", cmd => fun(#{sock := Sock} = State) -> @@ -5602,14 +5471,13 @@ sc_lc_acceptor_response_tcp(InitState) -> end}, #{desc => "announce ready (accept closed)", cmd => fun(#{tester := Tester}) -> - ev_ready(Tester, accept_closed), - ok + ?SEV_ANNOUNCE_READY(Tester, accept_closed) end}, %% Termination #{desc => "await terminate (from tester)", cmd => fun(#{tester := Tester} = State) -> - case ev_await_terminate(Tester, tester) of + case ?SEV_AWAIT_TERMINATE(Tester, tester) of ok -> {ok, maps:remove(tester, State)}; {error, _} = ERROR -> @@ -5618,10 +5486,7 @@ sc_lc_acceptor_response_tcp(InitState) -> end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], TesterSeq = @@ -5651,49 +5516,46 @@ sc_lc_acceptor_response_tcp(InitState) -> %% Start the primary server #{desc => "order 'primary acceptor' start", cmd => fun(#{prim_acc := Pid} = _State) -> - ev_start(Pid), + ?SEV_ANNOUNCE_START(Pid), ok end}, #{desc => "await 'primary acceptor' ready (init)", cmd => fun(#{prim_acc := Pid} = State) -> - {ok, Sock} = ev_await_ready(Pid, prim_acc, init), + {ok, Sock} = ?SEV_AWAIT_READY(Pid, prim_acc, init), {ok, State#{sock => Sock}} end}, %% Start the secondary acceptor 1 #{desc => "order 'secondary acceptor 1' start", cmd => fun(#{sec_acc1 := Pid, sock := Sock} = _State) -> - ev_start(Pid, Sock), + ?SEV_ANNOUNCE_START(Pid, Sock), ok end}, #{desc => "await 'secondary acceptor 1' ready (init)", cmd => fun(#{sec_acc1 := Pid} = _State) -> - ev_await_ready(Pid, sec_acc1, init), - ok + ok = ?SEV_AWAIT_READY(Pid, sec_acc1, init) end}, %% Start the secondary acceptor 2 #{desc => "order 'secondary acceptor 2' start", cmd => fun(#{sec_acc2 := Pid, sock := Sock} = _State) -> - ev_start(Pid, Sock), + ?SEV_ANNOUNCE_START(Pid, Sock), ok end}, #{desc => "await 'secondary acceptor 2' ready (init)", cmd => fun(#{sec_acc2 := Pid} = _State) -> - ev_await_ready(Pid, sec_acc2, init), - ok + ok = ?SEV_AWAIT_READY(Pid, sec_acc2, init) end}, %% Start the secondary acceptor 3 #{desc => "order 'secondary acceptor 3' start", cmd => fun(#{sec_acc3 := Pid, sock := Sock} = _State) -> - ev_start(Pid, Sock), + ?SEV_ANNOUNCE_START(Pid, Sock), ok end}, #{desc => "await 'secondary acceptor 3' ready (init)", cmd => fun(#{sec_acc3 := Pid} = _State) -> - ev_await_ready(Pid, sec_acc3, init), - ok + ok = ?SEV_AWAIT_READY(Pid, sec_acc3, init) end}, @@ -5706,145 +5568,141 @@ sc_lc_acceptor_response_tcp(InitState) -> #{desc => "order 'secondary acceptor 1' to continue (accept)", cmd => fun(#{sec_acc1 := Pid} = _State) -> - ev_continue(Pid, accept), - ok - end}, - #{desc => "sleep", - cmd => fun(_) -> - ?SLEEP(?SECS(1)), + ?SEV_ANNOUNCE_CONTINUE(Pid, accept), ok end}, + ?SEV_SLEEP(?SECS(1)), #{desc => "order 'secondary acceptor 2' to continue (accept)", cmd => fun(#{sec_acc2 := Pid} = _State) -> - ev_continue(Pid, accept), - ok - end}, - #{desc => "sleep", - cmd => fun(_) -> - ?SLEEP(?SECS(1)), + ?SEV_ANNOUNCE_CONTINUE(Pid, accept), ok end}, + ?SEV_SLEEP(?SECS(1)), #{desc => "order 'secondary acceptor 3' to continue (accept)", cmd => fun(#{sec_acc3 := Pid} = _State) -> - ev_continue(Pid, accept), - ok - end}, - #{desc => "sleep", - cmd => fun(_) -> - ?SLEEP(?SECS(1)), + ?SEV_ANNOUNCE_CONTINUE(Pid, accept), ok end}, + ?SEV_SLEEP(?SECS(1)), #{desc => "order 'primary acceptor' to continue", cmd => fun(#{prim_acc := Pid} = _State) -> - ev_continue(Pid, accept, ?SECS(5)), + ?SEV_ANNOUNCE_CONTINUE(Pid, accept, ?SECS(5)), ok end}, #{desc => "await 'primary acceptor' ready (accept timeout)", cmd => fun(#{prim_acc := Pid} = _State) -> - ev_await_ready(Pid, prim_acc, accept_timeout), - ok + ok = ?SEV_AWAIT_READY(Pid, prim_acc, accept_timeout) end}, #{desc => "order 'primary acceptor' to continue (close)", cmd => fun(#{prim_acc := Pid} = _State) -> - ev_continue(Pid, close), + ?SEV_ANNOUNCE_CONTINUE(Pid, close), ok end}, #{desc => "await 'primary acceptor' ready (close)", cmd => fun(#{prim_acc := Pid} = _State) -> - ev_await_ready(Pid, prim_acc, close), - ok + ok = ?SEV_AWAIT_READY(Pid, prim_acc, close) end}, #{desc => "await 'secondary acceptor 1' ready (accept closed)", cmd => fun(#{sec_acc1 := Pid} = _State) -> - ev_await_ready(Pid, sec_acc1, accept_closed), - ok + ok = ?SEV_AWAIT_READY(Pid, sec_acc1, accept_closed) end}, #{desc => "await 'secondary acceptor 2' ready (accept closed)", cmd => fun(#{sec_acc2 := Pid} = _State) -> - ev_await_ready(Pid, sec_acc2, accept_closed), - ok + ok = ?SEV_AWAIT_READY(Pid, sec_acc2, accept_closed) end}, #{desc => "await 'secondary acceptor 3' ready (accept closed)", cmd => fun(#{sec_acc3 := Pid} = _State) -> - ev_await_ready(Pid, sec_acc3, accept_closed), - ok + ok = ?SEV_AWAIT_READY(Pid, sec_acc3, accept_closed) end}, %% Terminations #{desc => "order 'secondary acceptor 3' to terminate", cmd => fun(#{sec_acc3 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await 'secondary acceptor 3' termination", cmd => fun(#{sec_acc3 := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(sec_acc3, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(sec_acc3, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order 'secondary acceptor 2' to terminate", cmd => fun(#{sec_acc2 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await 'secondary acceptor 2' termination", cmd => fun(#{sec_acc2 := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(sec_acc2, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(sec_acc2, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order 'secondary acceptor 1' to terminate", cmd => fun(#{sec_acc1 := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await 'secondary acceptor 1' termination", cmd => fun(#{sec_acc1 := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(sec_acc1, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(sec_acc1, State)}; + {error, _} = ERROR -> + ERROR + end end}, #{desc => "order 'primary acceptor' to terminate", cmd => fun(#{prim_acc := Pid} = _State) -> - ev_terminate(Pid), + ?SEV_ANNOUNCE_TERMINATE(Pid), ok end}, #{desc => "await 'primary acceptor' termination", cmd => fun(#{prim_acc := Pid} = State) -> - ev_await_termination(Pid), - {ok, maps:remove(prim_acc, State)} + case ?SEV_AWAIT_TERMINATION(Pid) of + ok -> + {ok, maps:remove(prim_acc, State)}; + {error, _} = ERROR -> + ERROR + end end}, %% *** We are done *** - #{desc => "finish", - cmd => fun(_) -> - {ok, normal} - end} + ?SEV_FINISH_NORMAL ], i("start 'primary acceptor' evaluator"), PrimAccInitState = InitState, - PrimAcc = evaluator_start("prim-acceptor", PrimAcceptorSeq, PrimAccInitState), + PrimAcc = ?SEV_START("prim-acceptor", PrimAcceptorSeq, PrimAccInitState), i("start 'secondary acceptor 1' evaluator"), SecAccInitState = #{}, - SecAcc1 = evaluator_start("sec-acceptor-1", SecAcceptorSeq, SecAccInitState), + SecAcc1 = ?SEV_START("sec-acceptor-1", SecAcceptorSeq, SecAccInitState), i("start 'secondary acceptor 2' evaluator"), - SecAcc2 = evaluator_start("sec-acceptor-2", SecAcceptorSeq, SecAccInitState), + SecAcc2 = ?SEV_START("sec-acceptor-2", SecAcceptorSeq, SecAccInitState), i("start 'secondary acceptor 3' evaluator"), - SecAcc3 = evaluator_start("sec-acceptor-3", SecAcceptorSeq, SecAccInitState), + SecAcc3 = ?SEV_START("sec-acceptor-3", SecAcceptorSeq, SecAccInitState), i("start 'tester' evaluator"), TesterInitState = #{prim_acc => PrimAcc#ev.pid, sec_acc1 => SecAcc1#ev.pid, sec_acc2 => SecAcc2#ev.pid, sec_acc3 => SecAcc3#ev.pid}, - Tester = evaluator_start("tester", TesterSeq, TesterInitState), + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), i("await evaluator"), - ok = await_evaluator_finish([PrimAcc, SecAcc1, SecAcc2, SecAcc3, Tester]). + ok = ?SEV_AWAIT_FINISH([PrimAcc, SecAcc1, SecAcc2, SecAcc3, Tester]). @@ -5882,229 +5740,6 @@ which_addr2(Domain, [_|IFO]) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% An evaluator is a process that executes a command sequence. -%% A test case will consist of atleast one evaluator (one for -%% each actor). -%% The evaluator process *always* run locally. Which means that -%% it will act as a "proxy" for remote nodes in necessary. -%% When the command sequence has been processed, the final state -%% will be used as exit reason. -%% A successful command shall evaluate to ok | {ok, NewState} - --spec evaluator_start(Name, Seq, Init) -> ev() when - Name :: string(), - Seq :: [command()], - Init :: initial_evaluator_state(). - -evaluator_start(Name, Seq, Init) - when is_list(Name) andalso is_list(Seq) andalso (Seq =/= []) -> - Init2 = Init#{parent => self()}, - {Pid, MRef} = erlang:spawn_monitor( - fun() -> evaluator_init(Name, Seq, Init2) end), - ?MKEV(Name, Pid, MRef). - -evaluator_init(Name, Seq, Init) -> - put(sname, Name), - evaluator_loop(1, Seq, Init). - -evaluator_loop(_ID, [], FinalState) -> - exit(FinalState); -evaluator_loop(ID, [#{desc := Desc, - cmd := Cmd}|Cmds], State) when is_function(Cmd, 1) -> - ei("evaluate command ~2w: ~s", [ID, Desc]), - try Cmd(State) of - ok -> - evaluator_loop(ID + 1, Cmds, State); - {ok, NewState} -> - evaluator_loop(ID + 1, Cmds, NewState); - {error, Reason} -> - ee("command ~w failed: " - "~n Reason: ~p", [ID, Reason]), - exit({command_failed, ID, Reason, State}) - catch - C:E:S -> - ee("command ~w crashed: " - "~n Class: ~p" - "~n Error: ~p" - "~n Call Stack: ~p", [ID, C, E, S]), - exit({command_crashed, ID, {C,E,S}, State}) - end. - -await_evaluator_finish(Evs) -> - await_evaluator_finish(Evs, []). - -await_evaluator_finish([], []) -> - ok; -await_evaluator_finish([], Fails) -> - Fails; -await_evaluator_finish(Evs, Fails) -> - receive - {'DOWN', _MRef, process, Pid, normal} -> - case lists:keysearch(Pid, #ev.pid, Evs) of - {value, #ev{name = Name}} -> - i("evaluator '~s' (~p) success", [Name, Pid]), - NewEvs = lists:keydelete(Pid, #ev.pid, Evs), - await_evaluator_finish(NewEvs, Fails); - false -> - i("unknown process ~p died (normal)", [Pid]), - await_evaluator_finish(Evs, Fails) - end; - {'DOWN', _MRef, process, Pid, Reason} -> - case lists:keysearch(Pid, #ev.pid, Evs) of - {value, #ev{name = Name}} -> - i("evaluator '~s' (~p) failed", [Name, Pid]), - NewEvs = lists:keydelete(Pid, #ev.pid, Evs), - await_evaluator_finish(NewEvs, [{Pid, Reason}|Fails]); - false -> - i("unknown process ~p died: " - "~n ~p", [Pid, Reason]), - await_evaluator_finish(Evs, Fails) - end - end. - - -ei(F) -> - ei(F, []). -ei(F, A) -> - eprint("", F, A). - -ee(F) -> - ee(F, []). -ee(F, A) -> - eprint("<ERROR> ", F, A). - -eprint(Prefix, F, A) -> - %% The two prints is to get the output both in the shell (for when - %% "personal" testing is going on) and in the logs. - FStr = f("[~s][~s][~p] ~s" ++ F, - [formated_timestamp(), get(sname), self(), Prefix | A]), - io:format(user, FStr ++ "~n", []), - io:format(FStr, []). - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -ev_start(Pid) -> - ev_announce(Pid, start, undefined). - -ev_start(Pid, Extra) -> - ev_announce(Pid, start, undefined, Extra). - -ev_continue(Pid, Slogan) -> - ev_announce(Pid, continue, Slogan). - -ev_continue(Pid, Slogan, Extra) -> - ev_announce(Pid, continue, Slogan, Extra). - -ev_ready(Pid, Slogan) -> - ev_announce(Pid, ready, Slogan). - -ev_ready(Pid, Slogan, Extra) -> - ev_announce(Pid, ready, Slogan, Extra). - -ev_terminate(Pid) -> - Pid ! {terminate, self()}. - -ev_announce(To, Tag, Slogan) -> - ev_announce(To, Tag, Slogan, undefined). - -ev_announce(To, Tag, Slogan, Extra) -> - To ! {Tag, self(), Slogan, Extra}. - -ev_await_start() -> - receive - {start, Pid, _, undefined} -> - Pid; - {start, Pid, _, Extra} -> - {Pid, Extra} - end. - -ev_await_continue(Pid, Name, Slogan) -> - ev_await_continue(Pid, Name, Slogan, []). -ev_await_continue(Pid, Name, Slogan, Pids) when is_pid(Pid) andalso is_list(Pids) -> - ev_await(Pid, Name, continue, Slogan, Pids). - -ev_await_ready(Pid, Name, Slogan) -> - ev_await_ready(Pid, Name, Slogan, []). -ev_await_ready(Pid, Name, Slogan, Pids) when is_pid(Pid) andalso is_list(Pids) -> - ev_await(Pid, Name, ready, Slogan, Pids). - -ev_await_terminate(Pid, Name) -> - ev_await_terminate(Pid, Name, []). -ev_await_terminate(Pid, Name, Pids) -> - receive - {terminate, Pid} -> - ok; - {'DOWN', _, process, Pid, Reason} -> - ee("Unexpected DOWN regarding ~w ~p: " - "~n ~p", [Name, Pid, Reason]), - {error, {unexpected_exit, Name}}; - {'DOWN', _, process, DownPid, Reason} -> - case ev_await_check_down(DownPid, Reason, Pids) of - ok -> - ei("DOWN from unknown process ~p: " - "~n ~p", [DownPid, Reason]), - ev_await_terminate(Pid, Name, Pids); - {error, _} = ERROR -> - ERROR - end - end. - -ev_await_termination(Pid) -> - receive - {'DOWN', _, process, Pid, _} -> - ok - end. - -%% We expect a message from Pid, but we also watch for DOWN from -%% both Pid and Pids, in which case the test has failed! -ev_await(Pid, Name, Tag, Slogan, Pids) -> - receive - {Tag, Pid, Slogan, undefined} -> - ok; - {Tag, Pid, Slogan, Extra} -> - {ok, Extra}; - {'DOWN', _, process, Pid, Reason} -> - ee("Unexpected DOWN regarding ~w ~p: " - "~n ~p", [Name, Pid, Reason]), - {error, {unexpected_exit, Name}}; - {'DOWN', _, process, DownPid, Reason} -> - case ev_await_check_down(DownPid, Reason, Pids) of - ok -> - ei("DOWN from unknown process ~p: " - "~n ~p", [DownPid, Reason]), - ev_await(Pid, Name, Tag, Slogan, Pids); - {error, _} = ERROR -> - ERROR - end - after infinity -> - ei("ev_await -> timeout for msg from ~p (~w): " - "~n Messages: ~p", [Pid, Name, pi(messages)]), - ev_await(Pid, Name, Tag, Slogan, Pids) - end. - -ev_await_check_down(DownPid, DownReason, Pids) -> - case lists:keymember(DownPid, 1, Pids) of - {value, {_, Name}} -> - ee("Unexpected DOWN regarding ~w ~p: " - "~n ~p", [Name, DownPid, DownReason]), - {error, {unexpected_exit, Name}}; - false -> - ok - end. - - -pi(Item) -> - pi(self(), Item). - -pi(Pid, Item) -> - {Item, Info} = process_info(Pid, Item), - Info. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - sock_open(Domain, Type, Proto) -> try socket:open(Domain, Type, Proto) of {ok, Socket} -> @@ -6298,6 +5933,9 @@ tc_which_name() -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +l2a(S) when is_list(S) -> + list_to_atom(S). + f(F, A) -> lists:flatten(io_lib:format(F, A)). diff --git a/erts/emulator/test/socket_test_evaluator.erl b/erts/emulator/test/socket_test_evaluator.erl new file mode 100644 index 0000000000..e8755a9512 --- /dev/null +++ b/erts/emulator/test/socket_test_evaluator.erl @@ -0,0 +1,491 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2018-2018. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-module(socket_test_evaluator). + +%% Evaluator control functions +-export([ + start/3, + await_finish/1 + ]). + +%% Functions used by evaluators to interact with eachother +-export([ + %% Announce functions + %% (Send an announcement from one evaluator to another) + announce_start/1, announce_start/2, + announce_continue/2, announce_continue/3, + announce_ready/2, announce_ready/3, + announce_terminate/1, + + %% Await functions + %% (Wait for an announcement from another evaluator) + await_start/0, await_start/1, + await_continue/3, await_continue/4, + await_ready/3, await_ready/4, + await_terminate/2, await_terminate/3, + await_termination/1, await_termination/2 + ]). + +%% Utility functions +-export([ + iprint/2, % Info printouts + eprint/2 % Error printouts + ]). + +-export_type([ + ev/0, + initial_evaluator_state/0, + evaluator_state/0, + command_fun/0, + command/0 + ]). + + +-include("socket_test_evaluator.hrl"). + +-type ev() :: #ev{}. +-type initial_evaluator_state() :: map(). +-type evaluator_state() :: term(). +-type command_fun() :: + fun((State :: evaluator_state()) -> ok) | + fun((State :: evaluator_state()) -> {ok, evaluator_state()}) | + fun((State :: evaluator_state()) -> {error, term()}). + +-type command() :: #{desc := string(), + cmd := command_fun()}. + + +%% ============================================================================ + +-define(LIB, socket_test_lib). + +-define(EXTRA_NOTHING, '$nothing'). +-define(ANNOUNCEMENT_START, '$start'). +-define(ANNOUNCEMENT_READY, '$ready'). +-define(ANNOUNCEMENT_CONTINUE, '$continue'). +-define(ANNOUNCEMENT_TERMINATE, '$terminate'). + +-define(START_NAME_NONE, '$no-name'). +-define(START_SLOGAN, ?ANNOUNCEMENT_START). +-define(TERMINATE_SLOGAN, ?ANNOUNCEMENT_TERMINATE). + + +%% ============================================================================ + +-spec start(Name, Seq, Init) -> ev() when + Name :: string(), + Seq :: [command()], + Init :: initial_evaluator_state(). + +start(Name, Seq, InitState) + when is_list(Name) andalso is_list(Seq) andalso (Seq =/= []) -> + %% Make sure 'parent' is not already used + case maps:find(parent, InitState) of + {ok, _} -> + erlang:error({already_used, parent}); + error -> + InitState2 = InitState#{parent => self()}, + {Pid, MRef} = erlang:spawn_monitor( + fun() -> init(Name, Seq, InitState2) end), + #ev{name = Name, pid = Pid, mref = MRef} + end. + +init(Name, Seq, Init) -> + put(sname, Name), + loop(1, Seq, Init). + +loop(_ID, [], FinalState) -> + exit(FinalState); +loop(ID, [#{desc := Desc, + cmd := Cmd}|Cmds], State) when is_function(Cmd, 1) -> + iprint("evaluate command ~2w: ~s", [ID, Desc]), + try Cmd(State) of + ok -> + loop(ID + 1, Cmds, State); + {ok, NewState} -> + loop(ID + 1, Cmds, NewState); + {error, Reason} -> + eprint("command ~w failed: " + "~n Reason: ~p", [ID, Reason]), + exit({command_failed, ID, Reason, State}) + catch + C:E:S -> + eprint("command ~w crashed: " + "~n Class: ~p" + "~n Error: ~p" + "~n Call Stack: ~p", [ID, C, E, S]), + exit({command_crashed, ID, {C,E,S}, State}) + end. + + +%% ============================================================================ + +-spec await_finish(Evs) -> term() when + Evs :: [ev()]. + +await_finish(Evs) -> + await_finish(Evs, []). + +await_finish([], []) -> + ok; +await_finish([], Fails) -> + Fails; +await_finish(Evs, Fails) -> + receive + {'DOWN', _MRef, process, Pid, normal} -> + case lists:keysearch(Pid, #ev.pid, Evs) of + {value, #ev{name = Name}} -> + iprint("evaluator '~s' (~p) success", [Name, Pid]), + NewEvs = lists:keydelete(Pid, #ev.pid, Evs), + await_finish(NewEvs, Fails); + false -> + iprint("unknown process ~p died (normal)", [Pid]), + await_finish(Evs, Fails) + end; + {'DOWN', _MRef, process, Pid, Reason} -> + case lists:keysearch(Pid, #ev.pid, Evs) of + {value, #ev{name = Name}} -> + iprint("evaluator '~s' (~p) failed", [Name, Pid]), + NewEvs = lists:keydelete(Pid, #ev.pid, Evs), + await_finish(NewEvs, [{Pid, Reason}|Fails]); + false -> + iprint("unknown process ~p died: " + "~n ~p", [Pid, Reason]), + await_finish(Evs, Fails) + end + end. + + +%% ============================================================================ + +-spec announce_start(To) -> ok when + To :: pid(). + +announce_start(To) -> + announce(To, ?ANNOUNCEMENT_START, ?START_SLOGAN). + +-spec announce_start(To, Extra) -> ok when + To :: pid(), + Extra :: term(). + +announce_start(To, Extra) -> + announce(To, ?ANNOUNCEMENT_START, ?START_SLOGAN, Extra). + + +%% ============================================================================ + +-spec announce_continue(To, Slogan) -> ok when + To :: pid(), + Slogan :: atom(). + +announce_continue(To, Slogan) -> + announce_continue(To, Slogan, ?EXTRA_NOTHING). + +-spec announce_continue(To, Slogan, Extra) -> ok when + To :: pid(), + Slogan :: atom(), + Extra :: term(). + +announce_continue(To, Slogan, Extra) -> + announce(To, ?ANNOUNCEMENT_CONTINUE, Slogan, Extra). + + +%% ============================================================================ + +-spec announce_ready(To, Slogan) -> ok when + To :: pid(), + Slogan :: atom(). + +announce_ready(To, Slogan) -> + announce_ready(To, Slogan, ?EXTRA_NOTHING). + +-spec announce_ready(To, Slogan, Extra) -> ok when + To :: pid(), + Slogan :: atom(), + Extra :: term(). + +announce_ready(To, Slogan, Extra) -> + announce(To, ?ANNOUNCEMENT_READY, Slogan, Extra). + + +%% ============================================================================ + +-spec announce_terminate(To) -> ok when + To :: pid(). + +announce_terminate(To) -> + announce(To, ?ANNOUNCEMENT_TERMINATE, ?TERMINATE_SLOGAN). + + +%% ============================================================================ + +-spec announce(To, Announcement, Slogan) -> ok when + To :: pid(), + Announcement :: atom(), + Slogan :: atom(). + +announce(To, Announcement, Slogan) -> + announce(To, Announcement, Slogan, ?EXTRA_NOTHING). + +-spec announce(To, Announcement, Slogan, Extra) -> ok when + To :: pid(), + Announcement :: atom(), + Slogan :: atom(), + Extra :: term(). + +announce(To, Announcement, Slogan, Extra) + when is_pid(To) andalso + is_atom(Announcement) andalso + is_atom(Slogan) -> + To ! {Announcement, self(), Slogan, Extra}, + ok. + + + +%% ============================================================================ + +-spec await_start() -> Pid | {Pid, Extra} when + Pid :: pid(), + Extra :: term(). + +await_start() -> + await_start(any). + +-spec await_start(Pid) -> Pid | {Pid, Extra} when + Pid :: pid(), + Extra :: term(). + +await_start(P) when is_pid(P) orelse (P =:= any) -> + case await(P, ?START_NAME_NONE, ?ANNOUNCEMENT_START, ?START_SLOGAN, []) of + {ok, Any} when is_pid(P) -> + Any; + {ok, Pid} when is_pid(Pid) andalso (P =:= any) -> + Pid; + {ok, {Pid, _} = OK} when is_pid(Pid) andalso (P =:= any) -> + OK + end. + + +%% ============================================================================ + +-spec await_continue(From, Name, Slogan) -> ok | {ok, Extra} | {error, Reason} when + From :: pid(), + Name :: atom(), + Slogan :: atom(), + Extra :: term(), + Reason :: term(). + +await_continue(From, Name, Slogan) -> + await_continue(From, Name, Slogan, []). + +-spec await_continue(From, Name, Slogan, OtherPids) -> + ok | {ok, Extra} | {error, Reason} when + From :: pid(), + Name :: atom(), + Slogan :: atom(), + OtherPids :: [{pid(), atom()}], + Extra :: term(), + Reason :: term(). + +await_continue(From, Name, Slogan, OtherPids) + when is_pid(From) andalso + is_atom(Name) andalso + is_atom(Slogan) andalso + is_list(OtherPids) -> + await(From, Name, ?ANNOUNCEMENT_CONTINUE, Slogan, OtherPids). + + + +%% ============================================================================ + +-spec await_ready(From, Name, Slogan) -> ok | {ok, Extra} | {error, Reason} when + From :: pid(), + Name :: atom(), + Slogan :: atom(), + Extra :: term(), + Reason :: term(). + +await_ready(From, Name, Slogan) -> + await_ready(From, Name, Slogan, []). + +-spec await_ready(From, Name, Slogan, OtherPids) -> + ok | {ok, Extra} | {error, Reason} when + From :: pid(), + Name :: atom(), + Slogan :: atom(), + OtherPids :: [{pid(), atom()}], + Extra :: term(), + Reason :: term(). + +await_ready(From, Name, Slogan, OtherPids) + when is_pid(From) andalso + is_atom(Name) andalso + is_atom(Slogan) andalso + is_list(OtherPids) -> + await(From, Name, ?ANNOUNCEMENT_READY, Slogan, OtherPids). + + + +%% ============================================================================ + +-spec await_terminate(Pid, Name) -> ok | {error, Reason} when + Pid :: pid(), + Name :: atom(), + Reason :: term(). + +await_terminate(Pid, Name) when is_pid(Pid) andalso is_atom(Name) -> + await_terminate(Pid, Name, []). + +-spec await_terminate(Pid, Name, OtherPids) -> ok | {error, Reason} when + Pid :: pid(), + Name :: atom(), + OtherPids :: [{pid(), atom()}], + Reason :: term(). + +await_terminate(Pid, Name, OtherPids) -> + await(Pid, Name, ?ANNOUNCEMENT_TERMINATE, ?TERMINATE_SLOGAN, OtherPids). + + +%% ============================================================================ + +-spec await_termination(Pid) -> ok | {error, Reason} when + Pid :: pid(), + Reason :: term(). + +await_termination(Pid) when is_pid(Pid) -> + await_termination(Pid, any). + +-spec await_termination(Pid, ExpReason) -> ok | {error, Reason} when + Pid :: pid(), + ExpReason :: term(), + Reason :: term(). + +await_termination(Pid, ExpReason) -> + receive + {'DOWN', _, process, Pid, _} when (ExpReason =:= any) -> + ok; + {'DOWN', _, process, Pid, Reason} when (ExpReason =:= Reason) -> + ok; + {'DOWN', _, process, Pid, Reason} -> + {error, {unexpected_exit, ExpReason, Reason}} + end. + + +%% ============================================================================ + +%% We expect a message (announcement) from Pid, but we also watch for DOWN from +%% both Pid and OtherPids, in which case the test has failed! + +-spec await(ExpPid, Name, Announcement, Slogan, OtherPids) -> + ok | {ok, Extra} | {error, Reason} when + ExpPid :: any | pid(), + Name :: atom(), + Announcement :: atom(), + Slogan :: atom(), + OtherPids :: [{pid(), atom()}], + Extra :: term(), + Reason :: term(). + +await(ExpPid, Name, Announcement, Slogan, OtherPids) + when (is_pid(ExpPid) orelse (ExpPid =:= any)) andalso + is_atom(Name) andalso + is_atom(Announcement) andalso + is_atom(Slogan) andalso + is_list(OtherPids) -> + receive + {Announcement, Pid, Slogan, ?EXTRA_NOTHING} when (ExpPid =:= any) -> + {ok, Pid}; + {Announcement, Pid, Slogan, Extra} when (ExpPid =:= any) -> + {ok, {Pid, Extra}}; + {Announcement, Pid, Slogan, ?EXTRA_NOTHING} when (Pid =:= ExpPid) -> + ok; + {Announcement, Pid, Slogan, Extra} when (Pid =:= ExpPid) -> + {ok, Extra}; + {'DOWN', _, process, Pid, Reason} when (Pid =:= ExpPid) -> + eprint("Unexpected DOWN regarding ~w ~p: " + "~n ~p", [Name, Pid, Reason]), + {error, {unexpected_exit, Name}}; + {'DOWN', _, process, OtherPid, Reason} -> + case check_down(OtherPid, Reason, OtherPids) of + ok -> + iprint("DOWN from unknown process ~p: " + "~n ~p", [OtherPid, Reason]), + await(ExpPid, Name, Announcement, Slogan, OtherPids); + {error, _} = ERROR -> + ERROR + end + after infinity -> % For easy debugging, just change to some valid time (5000) + iprint("await -> timeout for msg from ~p (~w): " + "~n Announcement: ~p" + "~n Slogan: ~p" + "~nwhen" + "~n Messages: ~p", + [ExpPid, Name, Announcement, Slogan, pi(messages)]), + await(ExpPid, Name, Announcement, Slogan, OtherPids) + end. + +pi(Item) -> + pi(self(), Item). + +pi(Pid, Item) -> + {Item, Info} = process_info(Pid, Item), + Info. + +check_down(Pid, DownReason, Pids) -> + case lists:keymember(Pid, 1, Pids) of + {value, {_, Name}} -> + eprint("Unexpected DOWN regarding ~w ~p: " + "~n ~p", [Name, Pid, DownReason]), + {error, {unexpected_exit, Name}}; + false -> + ok + end. + + +%% ============================================================================ + +f(F, A) -> + lists:flatten(io_lib:format(F, A)). + + +iprint(F, A) -> + print("", F, A). + +eprint(F, A) -> + print("<ERROR> ", F, A). + +print(Prefix, F, A) -> + %% The two prints is to get the output both in the shell (for when + %% "personal" testing is going on) and in the logs. + IDStr = + case get(sname) of + undefined -> + %% This means its not an evaluator, + %% or a named process. Instead its + %% most likely the test case itself, + %% so skip the name and the pid. + ""; + SName -> + f("[~s][~p]", [SName, self()]) + end, + FStr = f("[~s]~s ~s" ++ F, [?LIB:formated_timestamp(), IDStr, Prefix | A]), + io:format(user, FStr ++ "~n", []), + io:format(FStr, []). diff --git a/erts/emulator/test/socket_test_evaluator.hrl b/erts/emulator/test/socket_test_evaluator.hrl new file mode 100644 index 0000000000..5be49dc022 --- /dev/null +++ b/erts/emulator/test/socket_test_evaluator.hrl @@ -0,0 +1,68 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2018-2018. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-ifndef(socket_test_evaluator). +-define(socket_test_evaluator, true). + +-record(ev, {name :: string(), + pid :: pid(), + mref :: reference()}). + +-define(SEV, socket_test_evaluator). + +-define(SEV_START(N, S, IS), ?SEV:start(N, S, IS)). +-define(SEV_AWAIT_FINISH(Evs), ?SEV:await_finish(Evs)). + +-define(SEV_ANNOUNCE_START(To), ?SEV:announce_start(To)). +-define(SEV_ANNOUNCE_START(To, Ex), ?SEV:announce_start(To, Ex)). +-define(SEV_ANNOUNCE_CONTINUE(To, S), ?SEV:announce_continue(To, S)). +-define(SEV_ANNOUNCE_CONTINUE(To, S, Ex), ?SEV:announce_continue(To, S, Ex)). +-define(SEV_ANNOUNCE_READY(To, S), ?SEV:announce_ready(To, S)). +-define(SEV_ANNOUNCE_READY(To, S, Ex), ?SEV:announce_ready(To, S, Ex)). +-define(SEV_ANNOUNCE_TERMINATE(To), ?SEV:announce_terminate(To)). + +-define(SEV_AWAIT_START(), ?SEV:await_start()). +-define(SEV_AWAIT_START(P), ?SEV:await_start(P)). +-define(SEV_AWAIT_CONTINUE(F, N, S), ?SEV:await_continue(F, N, S)). +-define(SEV_AWAIT_CONTINUE(F, N, S, Ps), ?SEV:await_continue(F, N, S, Ps)). +-define(SEV_AWAIT_READY(F, N, S), ?SEV:await_ready(F, N, S)). +-define(SEV_AWAIT_READY(F, N, S, Ps), ?SEV:await_ready(F, N, S, Ps)). +-define(SEV_AWAIT_TERMINATE(F, N), ?SEV:await_terminate(F, N)). +-define(SEV_AWAIT_TERMINATE(F, N, Ps), ?SEV:await_terminate(F, N, Ps)). +-define(SEV_AWAIT_TERMINATION(P), ?SEV:await_termination(P)). +-define(SEV_AWAIT_TERMINATION(P, R), ?SEV:await_termination(P, R)). + +-define(SEV_IPRINT(F, A), ?SEV:iprint(F, A)). +-define(SEV_IPRINT(F), ?SEV_IPRINT(F, [])). +-define(SEV_EPRINT(F, A), ?SEV:eprint(F, A)). +-define(SEV_EPRINT(F), ?SEV_EPRINT(F, [])). + +-define(SEV_SLEEP(T), #{desc => "sleep", + cmd => fun(_) -> + ?SLEEP(T), + ok + end}). +-define(SEV_FINISH_NORMAL, #{desc => "finish", + cmd => fun(_) -> + {ok, normal} + end}). + +-endif. % -ifdef(socket_test_evaluator). + diff --git a/erts/emulator/test/socket_test_lib.erl b/erts/emulator/test/socket_test_lib.erl new file mode 100644 index 0000000000..c36cc4fbfa --- /dev/null +++ b/erts/emulator/test/socket_test_lib.erl @@ -0,0 +1,72 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2018-2018. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-module(socket_test_lib). + +-export([ + %% Time stuff + timestamp/0, + tdiff/2, + formated_timestamp/0, + format_timestamp/1, + + %% Skipping + not_yet_implemented/0, + skip/1 + ]). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +timestamp() -> + os:timestamp(). + + +tdiff({A1, B1, C1} = _T1x, {A2, B2, C2} = _T2x) -> + T1 = A1*1000000000+B1*1000+(C1 div 1000), + T2 = A2*1000000000+B2*1000+(C2 div 1000), + T2 - T1. + + +formated_timestamp() -> + format_timestamp(os:timestamp()). + +format_timestamp({_N1, _N2, _N3} = TS) -> + {_Date, Time} = calendar:now_to_local_time(TS), + %% {YYYY,MM,DD} = Date, + {Hour,Min,Sec} = Time, + %% FormatTS = + %% io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w.~w", + %% [YYYY, MM, DD, Hour, Min, Sec, N3]), + FormatTS = io_lib:format("~.2.0w:~.2.0w:~.2.0w", [Hour, Min, Sec]), + lists:flatten(FormatTS). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +not_yet_implemented() -> + skip("not yet implemented"). + +skip(Reason) -> + throw({skip, Reason}). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |