diff options
| author | Simon MacMullen <simon@rabbitmq.com> | 2014-06-02 16:58:49 +0100 |
|---|---|---|
| committer | Simon MacMullen <simon@rabbitmq.com> | 2014-06-02 16:58:49 +0100 |
| commit | 5978e68936e0106de436964e65ee2957c6be2ad6 (patch) | |
| tree | 42288d7addac182aa7d4e61fc55990dd327aeffa /src | |
| parent | 5272fae5383a912a72342b28d78c28f417448e0e (diff) | |
| download | rabbitmq-server-git-5978e68936e0106de436964e65ee2957c6be2ad6.tar.gz | |
Don't expect message delivery until we have had the joined callback invoked.
Diffstat (limited to 'src')
| -rw-r--r-- | src/gm_qc.erl | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/src/gm_qc.erl b/src/gm_qc.erl index a7dc1ede2b..42d2c07b6f 100644 --- a/src/gm_qc.erl +++ b/src/gm_qc.erl @@ -38,7 +38,7 @@ %% For insertion into gm -export([call/3, cast/2]). --record(state, {seq, instrumented, outstanding}). +-record(state, {seq, instrumented, outstanding, to_join}). prop_gm_test() -> case ?INSTR_MOD of @@ -88,7 +88,8 @@ await_death(MRef, P) -> {'EXIT', _, normal} -> await_death(MRef, P); {'EXIT', _, Reason} -> exit(Reason); {instrumented, From, To, Thing} -> process_msg(From, To, Thing), - await_death(MRef, P) + await_death(MRef, P); + {joined, _GM} -> await_death(MRef, P) end. %% --------------------------------------------------------------------------- @@ -97,7 +98,8 @@ await_death(MRef, P) -> initial_state() -> #state{seq = 1, outstanding = dict:new(), - instrumented = dict:new()}. + instrumented = dict:new(), + to_join = sets:new()}. command(S = #state{outstanding = Outstanding}) -> case dict:size(Outstanding) of @@ -147,10 +149,8 @@ postcondition(S = #state{outstanding = Outstanding}, postcondition(S = #state{}, {call, _M, _F, _A}, _Res) -> assert(S). -next_state(S = #state{outstanding = Outstanding}, GM, - {call, ?MODULE, do_join, []}) -> - S#state{outstanding = dict:store(GM, {gb_trees:empty(), gb_sets:empty()}, - Outstanding)}; +next_state(S = #state{to_join = Set}, GM, {call, ?MODULE, do_join, []}) -> + S#state{to_join = sets:add_element(GM, Set)}; next_state(S = #state{outstanding = Outstanding}, _Res, {call, ?MODULE, do_leave, [GM]}) -> @@ -186,7 +186,8 @@ next_state(S = #state{instrumented = Msgs}, _Res, %% GM %% --------------------------------------------------------------------------- -joined(_Pid, _Members) -> ok. +joined(Pid, _Members) -> Pid ! {joined, self()}, + ok. members_changed(_Pid, _Bs, _Ds) -> %%[Pid ! {birth, self(), B} || B <- Bs], %%[Pid ! {death, self(), D} || D <- Ds], ok. @@ -201,11 +202,6 @@ terminate(_Pid, _Reason) -> ok. do_join() -> {ok, GM} = gm:start_link(?GROUP, ?MODULE, self(), fun rabbit_misc:execute_mnesia_transaction/1), - %% TODO do we need to test the joined callback? What is the joined - %% callback actually for? - %% receive - %% {joined, GM} -> ok - %% end, GM. do_leave(GM) -> @@ -272,6 +268,11 @@ handle_msg({instrumented, From, To, Thing}, S = #state{instrumented = Msgs}) -> error -> queue:from_list([Thing]) end, S#state{instrumented = dict:store({From, To}, Q1, Msgs)}; +handle_msg({joined, GM}, S = #state{outstanding = Outstanding, + to_join = ToJoin}) -> + S#state{outstanding = dict:store(GM, {gb_trees:empty(), gb_sets:empty()}, + Outstanding), + to_join = sets:del_element(GM, ToJoin)}; handle_msg({'EXIT', _From, normal}, S) -> S; handle_msg({'EXIT', _From, Reason}, _S) -> @@ -300,7 +301,7 @@ assert(S = #state{outstanding = Outstanding}) -> true. ensure_outstanding_msgs_received(S) -> - case outstanding_msgs(S) of + case outstanding_joiners(S) orelse outstanding_msgs(S) of false -> S; true -> timer:sleep(100), S2 = drain_proceeding(S), @@ -308,6 +309,9 @@ ensure_outstanding_msgs_received(S) -> ensure_outstanding_msgs_received(S2) end. +outstanding_joiners(#state{to_join = ToJoin}) -> + sets:size(ToJoin) > 0. + outstanding_msgs(#state{outstanding = Outstanding}) -> dict:fold(fun (_GM, {_Tree, Set}, false) -> not gb_sets:is_empty(Set); (_GM, {_Tree, _Set}, true) -> true |
