diff options
author | kjnilsson <knilsson@pivotal.io> | 2020-07-09 14:41:00 +0100 |
---|---|---|
committer | kjnilsson <knilsson@pivotal.io> | 2020-07-09 14:41:00 +0100 |
commit | 3cf84a19b24cb57e110e3179d712ca680181118d (patch) | |
tree | 56592f6d27cf18bf1f318d799b99f1a17ebad4f6 | |
parent | 378b6719e4d84044c85d950c17eeb6f287bf3eee (diff) | |
download | rabbitmq-server-git-3cf84a19b24cb57e110e3179d712ca680181118d.tar.gz |
Fix mqtt_machine crash bug
When a client performs repeated requests the state machine would crash
with a match exception.
Add unit test suite for mqtt_machine.
-rw-r--r-- | deps/rabbitmq_mqtt/src/mqtt_machine.erl | 2 | ||||
-rw-r--r-- | deps/rabbitmq_mqtt/test/mqtt_machine_SUITE.erl | 73 |
2 files changed, 74 insertions, 1 deletions
diff --git a/deps/rabbitmq_mqtt/src/mqtt_machine.erl b/deps/rabbitmq_mqtt/src/mqtt_machine.erl index 2084ab908b..2809c6e86e 100644 --- a/deps/rabbitmq_mqtt/src/mqtt_machine.erl +++ b/deps/rabbitmq_mqtt/src/mqtt_machine.erl @@ -48,7 +48,7 @@ apply(_Meta, {register, ClientId, Pid}, #machine_state{client_ids = Ids} = State {monitor, process, Pid}, {mod_call, ?MODULE, notify_connection, [OldPid, duplicate_id]}], {Effects0, maps:remove(ClientId, Ids)}; - error -> + _ -> Effects0 = [{monitor, process, Pid}], {Effects0, Ids} end, diff --git a/deps/rabbitmq_mqtt/test/mqtt_machine_SUITE.erl b/deps/rabbitmq_mqtt/test/mqtt_machine_SUITE.erl new file mode 100644 index 0000000000..abdc3506dc --- /dev/null +++ b/deps/rabbitmq_mqtt/test/mqtt_machine_SUITE.erl @@ -0,0 +1,73 @@ +-module(mqtt_machine_SUITE). + +-compile(export_all). + +-export([ + ]). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). +-include("mqtt_machine.hrl"). + +%%%=================================================================== +%%% Common Test callbacks +%%%=================================================================== + +all() -> + [ + {group, tests} + ]. + + +all_tests() -> + [ + basics + ]. + +groups() -> + [ + {tests, [], all_tests()} + ]. + +init_per_suite(Config) -> + Config. + +end_per_suite(_Config) -> + ok. + +init_per_group(_Group, Config) -> + Config. + +end_per_group(_Group, _Config) -> + ok. + +init_per_testcase(_TestCase, Config) -> + Config. + +end_per_testcase(_TestCase, _Config) -> + ok. + +%%%=================================================================== +%%% Test cases +%%%=================================================================== + +basics(_Config) -> + S0 = mqtt_machine:init(#{}), + ClientId = <<"id1">>, + {S1, ok, _} = mqtt_machine:apply(meta(1), {register, ClientId, self()}, S0), + ?assertMatch(#machine_state{client_ids = Ids} when map_size(Ids) == 1, S1), + {S2, ok, _} = mqtt_machine:apply(meta(2), {register, ClientId, self()}, S1), + ?assertMatch(#machine_state{client_ids = Ids} when map_size(Ids) == 1, S2), + {S3, ok, _} = mqtt_machine:apply(meta(3), {down, self(), noproc}, S2), + ?assertMatch(#machine_state{client_ids = Ids} when map_size(Ids) == 0, S3), + {S4, ok, _} = mqtt_machine:apply(meta(3), {unregister, ClientId, self()}, S2), + ?assertMatch(#machine_state{client_ids = Ids} when map_size(Ids) == 0, S4), + + ok. + +%% Utility + +meta(Idx) -> + #{index => Idx, + term => 1, + ts => erlang:system_time(millisecond)}. |