summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMichael Klishin <michael@clojurewerkz.org>2018-09-15 01:57:07 +0200
committerMichael Klishin <michael@clojurewerkz.org>2018-09-15 01:57:07 +0200
commitdc894579c8497c645f55ab925e77c5b8824f8425 (patch)
treece9eb8fd7557ff5e7fe7be9e8d96ea00966bfbb9 /test
parent3d08081d8f4b0ef8220bceadc7f3db2e6d8a7b03 (diff)
downloadrabbitmq-server-git-dc894579c8497c645f55ab925e77c5b8824f8425.tar.gz
Make pg_local:member_died/2 more resilient
See #1699 for background. [#160530707]
Diffstat (limited to 'test')
-rw-r--r--test/unit_SUITE.erl61
1 files changed, 57 insertions, 4 deletions
diff --git a/test/unit_SUITE.erl b/test/unit_SUITE.erl
index 06288ac1b6..be9c8d8698 100644
--- a/test/unit_SUITE.erl
+++ b/test/unit_SUITE.erl
@@ -17,6 +17,7 @@
-module(unit_SUITE).
-include_lib("common_test/include/ct.hrl").
+-include_lib("eunit/include/eunit.hrl").
-include_lib("rabbit_common/include/rabbit.hrl").
-include_lib("rabbit_common/include/rabbit_framing.hrl").
@@ -44,7 +45,6 @@ groups() ->
decrypt_config,
listing_plugins_from_multiple_directories,
rabbitmqctl_encode,
- pg_local,
pmerge,
plmerge,
priority_queue,
@@ -68,6 +68,9 @@ groups() ->
]}
]},
{sequential_tests, [], [
+ pg_local,
+ pg_local_with_unexpected_deaths1,
+ pg_local_with_unexpected_deaths2,
decrypt_start_app,
decrypt_start_app_file,
decrypt_start_app_undefined,
@@ -377,29 +380,79 @@ rabbit_direct_extract_extra_auth_props(_Config) ->
%% -------------------------------------------------------------------
pg_local(_Config) ->
- [P, Q] = [spawn(fun () -> receive X -> X end end) || _ <- [x, x]],
+ [P, Q] = [spawn(fun () -> receive X -> X end end) || _ <- lists:seq(0, 1)],
check_pg_local(ok, [], []),
+ %% P joins group a, then b, then a again
check_pg_local(pg_local:join(a, P), [P], []),
check_pg_local(pg_local:join(b, P), [P], [P]),
check_pg_local(pg_local:join(a, P), [P, P], [P]),
+ %% Q joins group a, then b, then b again
check_pg_local(pg_local:join(a, Q), [P, P, Q], [P]),
check_pg_local(pg_local:join(b, Q), [P, P, Q], [P, Q]),
check_pg_local(pg_local:join(b, Q), [P, P, Q], [P, Q, Q]),
+ %% P leaves groups a and a
check_pg_local(pg_local:leave(a, P), [P, Q], [P, Q, Q]),
check_pg_local(pg_local:leave(b, P), [P, Q], [Q, Q]),
+ %% leave/2 is idempotent
check_pg_local(pg_local:leave(a, P), [Q], [Q, Q]),
check_pg_local(pg_local:leave(a, P), [Q], [Q, Q]),
+ %% clean up all processes
[begin X ! done,
Ref = erlang:monitor(process, X),
receive {'DOWN', Ref, process, X, _Info} -> ok end
end || X <- [P, Q]],
+ %% ensure the groups are empty
+ check_pg_local(ok, [], []),
+ passed.
+
+pg_local_with_unexpected_deaths1(_Config) ->
+ [A, B] = [spawn(fun () -> receive X -> X end end) || _ <- lists:seq(0, 1)],
check_pg_local(ok, [], []),
+ %% A joins groups a and b
+ check_pg_local(pg_local:join(a, A), [A], []),
+ check_pg_local(pg_local:join(b, A), [A], [A]),
+ %% B joins group b
+ check_pg_local(pg_local:join(b, B), [A], [A, B]),
+
+ [begin erlang:exit(X, sleep_now_in_a_fire),
+ Ref = erlang:monitor(process, X),
+ receive {'DOWN', Ref, process, X, _Info} -> ok end
+ end || X <- [A, B]],
+ %% ensure the groups are empty
+ check_pg_local(ok, [], []),
+ ?assertNot(erlang:is_process_alive(A)),
+ ?assertNot(erlang:is_process_alive(B)),
+
+ passed.
+
+pg_local_with_unexpected_deaths2(_Config) ->
+ [A, B] = [spawn(fun () -> receive X -> X end end) || _ <- lists:seq(0, 1)],
+ check_pg_local(ok, [], []),
+ %% A joins groups a and b
+ check_pg_local(pg_local:join(a, A), [A], []),
+ check_pg_local(pg_local:join(b, A), [A], [A]),
+ %% B joins group b
+ check_pg_local(pg_local:join(b, B), [A], [A, B]),
+
+ %% something else yanks a record (or all of them) from the pg_local
+ %% bookkeeping table
+ ok = pg_local:clear(),
+
+ [begin erlang:exit(X, sleep_now_in_a_fire),
+ Ref = erlang:monitor(process, X),
+ receive {'DOWN', Ref, process, X, _Info} -> ok end
+ end || X <- [A, B]],
+ %% ensure the groups are empty
+ check_pg_local(ok, [], []),
+ ?assertNot(erlang:is_process_alive(A)),
+ ?assertNot(erlang:is_process_alive(B)),
+
passed.
check_pg_local(ok, APids, BPids) ->
ok = pg_local:sync(),
- [true, true] = [lists:sort(Pids) == lists:sort(pg_local:get_members(Key)) ||
- {Key, Pids} <- [{a, APids}, {b, BPids}]].
+ ?assertEqual([true, true], [lists:sort(Pids) == lists:sort(pg_local:get_members(Key)) ||
+ {Key, Pids} <- [{a, APids}, {b, BPids}]]).
%% -------------------------------------------------------------------
%% priority_queue.