summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkjnilsson <knilsson@pivotal.io>2020-07-09 14:41:00 +0100
committerkjnilsson <knilsson@pivotal.io>2020-07-09 14:41:00 +0100
commit3cf84a19b24cb57e110e3179d712ca680181118d (patch)
tree56592f6d27cf18bf1f318d799b99f1a17ebad4f6
parent378b6719e4d84044c85d950c17eeb6f287bf3eee (diff)
downloadrabbitmq-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.erl2
-rw-r--r--deps/rabbitmq_mqtt/test/mqtt_machine_SUITE.erl73
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)}.