summaryrefslogtreecommitdiff
path: root/lib/stdlib/test/gen_server_SUITE.erl
diff options
context:
space:
mode:
authorDan Gudmundsson <dgud@erlang.org>2020-01-08 12:24:54 +0100
committerDan Gudmundsson <dgud@erlang.org>2020-01-08 12:24:54 +0100
commit83c68a5e9cebdd00d00bbf8e5de20ce928e0172f (patch)
tree9de04112356d46abf5b9a4f9cef77208b59c8b4a /lib/stdlib/test/gen_server_SUITE.erl
parent52412c598ad67786032d17762e8655ad3d6771b5 (diff)
parentb092f750bd736d4eccf889eba52a5ea6658ffea9 (diff)
downloaderlang-83c68a5e9cebdd00d00bbf8e5de20ce928e0172f.tar.gz
Merge branch 'dgud/stdlib/gen-async-call'
* dgud/stdlib/gen-async-call: Add tag to response message stdlib: Add 'send_request' and 'wait_response' to generic behaviors
Diffstat (limited to 'lib/stdlib/test/gen_server_SUITE.erl')
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl91
1 files changed, 88 insertions, 3 deletions
diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl
index d2b2fcea65..c14d283e73 100644
--- a/lib/stdlib/test/gen_server_SUITE.erl
+++ b/lib/stdlib/test/gen_server_SUITE.erl
@@ -26,7 +26,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
--export([start/1, crash/1, call/1, cast/1, cast_fast/1,
+-export([start/1, crash/1, call/1, send_request/1, cast/1, cast_fast/1,
continue/1, info/1, abcast/1, multicall/1, multicall_down/1,
call_remote1/1, call_remote2/1, call_remote3/1,
call_remote_n1/1, call_remote_n2/1, call_remote_n3/1, spec_init/1,
@@ -63,7 +63,7 @@ suite() ->
{timetrap,{minutes,1}}].
all() ->
- [start, {group,stop}, crash, call, cast, cast_fast, info, abcast,
+ [start, {group,stop}, crash, call, send_request, cast, cast_fast, info, abcast,
continue, multicall, multicall_down, call_remote1, call_remote2,
call_remote3, call_remote_n1, call_remote_n2,
call_remote_n3, spec_init,
@@ -107,7 +107,8 @@ init_per_testcase(Case, Config) when Case == call_remote1;
Case == call_remote3;
Case == call_remote_n1;
Case == call_remote_n2;
- Case == call_remote_n3 ->
+ Case == call_remote_n3;
+ Case == send_request ->
{ok,N} = start_node(hubba),
[{node,N} | Config];
@@ -462,6 +463,90 @@ call(Config) when is_list(Config) ->
ok.
%% --------------------------------------
+%% Test gen_server:send_request.
+%% --------------------------------------
+
+send_request(Config) when is_list(Config) ->
+ OldFl = process_flag(trap_exit, true),
+
+ {ok, Pid} = gen_server:start_link({local, my_test_name},
+ gen_server_SUITE, [], []),
+
+ Async = fun(Process, Req) ->
+ try
+ Promise = gen_server:send_request(Process, Req),
+ gen_server:wait_response(Promise, infinity)
+ catch _:Reason:ST ->
+ {'did_exit', Reason, ST}
+ end
+ end,
+ {reply,ok} = Async(my_test_name, started_p),
+
+ {reply,delayed} = Async(Pid, {delayed_answer,1}),
+
+ %% two requests within a specified time.
+ Promise1 = gen_server:send_request(my_test_name, {call_within, 1000}),
+ Promise2 = gen_server:send_request(my_test_name, next_call),
+ {reply, ok} = gen_server:wait_response(Promise1, infinity),
+ {reply, ok} = gen_server:wait_response(Promise2, infinity),
+
+ Promise3 = gen_server:send_request(my_test_name, {call_within, 1000}),
+ no_reply = gen_server:check_response({foo, bar}, Promise3),
+ receive {{'$gen_request_id',Ref},_} = Msg when is_reference(Ref) ->
+ {reply, ok} = gen_server:check_response(Msg, Promise3)
+ after 1000 ->
+ %% Format not yet doumented so it might be ok
+ %% This test is just to make you aware that you have changed it
+ exit(message_format_changed)
+ end,
+ timer:sleep(1500),
+
+ {reply, false} = Async(my_test_name, next_call),
+
+ %% timeout
+ Promise5 = gen_server:send_request(my_test_name, {delayed_answer,50}),
+ timeout = gen_server:wait_response(Promise5, 0),
+ {reply, delayed} = gen_server:wait_response(Promise5, infinity),
+
+ %% bad return value in the gen_server loop from handle_call.
+ {error,{{bad_return_value, badreturn},_}} = Async(my_test_name, badreturn),
+
+ %% Test other error cases
+ {error, {noproc,_}} = Async(Pid, started_p),
+ {error, {noproc,_}} = Async(my_test_name, started_p),
+ {error, {noconnection, _}} = Async({my_test_name, foo@node}, started_p),
+
+ {error, {noproc,_}} = Async({global, non_existing}, started_p),
+ catch exit(whereis(dummy_via), foo),
+ {'EXIT', {badarg,_}} =
+ (catch gen_server:send_request({via, dummy_via, non_existing}, started_p)),
+
+ %% Remote nodes
+ Via = dummy_via:reset(),
+ Remote = proplists:get_value(node,Config),
+ {ok, RPid} = rpc:call(Remote, gen_server, start, [{global, remote}, ?MODULE, [], []]),
+ dummy_via:register_name(remote, RPid),
+ {reply, ok} = Async(RPid, started_p),
+ {reply, ok} = Async({global, remote}, started_p),
+ {reply, ok} = Async({via, dummy_via, remote}, started_p),
+ {error, {shutdown, _}} = Async({global, remote}, stop_shutdown),
+ {error, {noproc, _}} = Async({global, remote}, started_p),
+ {error, {noproc, _}} = Async({via, dummy_via, remote}, started_p),
+ {error, {noproc, _}} = Async({via, dummy_via, non_existing}, started_p),
+
+ {ok, _} = rpc:call(Remote, gen_server, start, [{local, remote}, ?MODULE, [], []]),
+ {reply, ok} = Async({remote, Remote}, started_p),
+ {error, {shutdown, _}} = Async({remote, Remote}, stop_shutdown),
+ {error, {noproc, _}} = Async({remote, Remote}, started_p),
+
+ %% Cleanup
+ catch exit(Via, foo2),
+ receive {'EXIT', Via, foo2} -> ok end,
+ process_flag(trap_exit, OldFl),
+ ok.
+
+
+%% --------------------------------------
%% Test handle_continue.
%% --------------------------------------