rabbitmq-server/deps/rabbit/test/unit_gen_server2_SUITE.erl

152 lines
4.6 KiB
Erlang

%% This Source Code Form is subject to the terms of the Mozilla Public
%% License, v. 2.0. If a copy of the MPL was not distributed with this
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
%%
%% Copyright (c) 2007-2025 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
%%
-module(unit_gen_server2_SUITE).
-include_lib("eunit/include/eunit.hrl").
-compile(export_all).
all() ->
[
{group, sequential_tests}
].
groups() ->
[
{sequential_tests, [], [
gen_server2_with_state,
mcall
]}
].
%% -------------------------------------------------------------------
%% Testsuite setup/teardown
%% -------------------------------------------------------------------
init_per_suite(Config) ->
rabbit_ct_helpers:log_environment(),
rabbit_ct_helpers:run_setup_steps(Config).
end_per_suite(Config) ->
rabbit_ct_helpers:run_teardown_steps(Config).
init_per_group(Group, Config) ->
Config1 = rabbit_ct_helpers:set_config(Config, [
{rmq_nodename_suffix, Group},
{rmq_nodes_count, 1}
]),
rabbit_ct_helpers:run_steps(Config1,
rabbit_ct_broker_helpers:setup_steps() ++
rabbit_ct_client_helpers:setup_steps()).
end_per_group(_Group, Config) ->
rabbit_ct_helpers:run_steps(Config,
rabbit_ct_client_helpers:teardown_steps() ++
rabbit_ct_broker_helpers:teardown_steps()).
init_per_testcase(Testcase, Config) ->
rabbit_ct_helpers:testcase_started(Config, Testcase).
end_per_testcase(Testcase, Config) ->
rabbit_ct_helpers:testcase_finished(Config, Testcase).
%% -------------------------------------------------------------------
%% Test cases
%% -------------------------------------------------------------------
gen_server2_with_state(Config) ->
passed = rabbit_ct_broker_helpers:rpc(Config, 0,
?MODULE, gen_server2_with_state1, [Config]).
gen_server2_with_state1(_Config) ->
state = gen_server2:with_state(background_gc,
fun (S) -> element(1, S) end),
passed.
mcall(Config) ->
passed = rabbit_ct_broker_helpers:rpc(Config, 0,
?MODULE, mcall1, [Config]).
mcall1(_Config) ->
P1 = spawn(fun gs2_test_listener/0),
register(foo, P1),
global:register_name(gfoo, P1),
P2 = spawn(fun() -> exit(bang) end),
%% ensure P2 is dead (ignore the race setting up the monitor)
await_exit(P2),
P3 = spawn(fun gs2_test_crasher/0),
%% since P2 crashes almost immediately and P3 after receiving its first
%% message, we have to spawn a few more processes to handle the additional
%% cases we're interested in here
register(baz, spawn(fun gs2_test_crasher/0)),
register(bog, spawn(fun gs2_test_crasher/0)),
global:register_name(gbaz, spawn(fun gs2_test_crasher/0)),
NoNode = rabbit_nodes:make("nonode"),
Targets =
%% pids
[P1, P2, P3]
++
%% registered names
[foo, bar, baz]
++
%% {Name, Node} pairs
[{foo, node()}, {bar, node()}, {bog, node()}, {foo, NoNode}]
++
%% {global, Name}
[{global, gfoo}, {global, gbar}, {global, gbaz}],
GoodResults = [{D, goodbye} || D <- [P1, foo,
{foo, node()},
{global, gfoo}]],
BadResults = [{P2, noproc}, % died before use
{P3, boom}, % died on first use
{bar, noproc}, % never registered
{baz, boom}, % died on first use
{{bar, node()}, noproc}, % never registered
{{bog, node()}, boom}, % died on first use
{{foo, NoNode}, nodedown}, % invalid node
{{global, gbar}, noproc}, % never registered globally
{{global, gbaz}, boom}], % died on first use
{Replies, Errors} = gen_server2:mcall([{T, hello} || T <- Targets]),
true = lists:sort(Replies) == lists:sort(GoodResults),
true = lists:sort(Errors) == lists:sort(BadResults),
%% cleanup (ignore the race setting up the monitor)
P1 ! stop,
await_exit(P1),
passed.
await_exit(Pid) ->
MRef = erlang:monitor(process, Pid),
receive
{'DOWN', MRef, _, _, _} -> ok
end.
gs2_test_crasher() ->
receive
{'$gen_call', _From, hello} -> exit(boom)
end.
gs2_test_listener() ->
receive
{'$gen_call', From, hello} ->
gen_server2:reply(From, goodbye),
gs2_test_listener();
stop ->
ok
end.