|
|
@@ -23,7 +23,7 @@
|
|
|
emqx_gateway_test_utils,
|
|
|
[
|
|
|
assert_confs/2,
|
|
|
- assert_feilds_apperence/2,
|
|
|
+ assert_fields_exist/2,
|
|
|
request/2,
|
|
|
request/3,
|
|
|
ssl_server_opts/0,
|
|
|
@@ -32,6 +32,7 @@
|
|
|
).
|
|
|
|
|
|
-include_lib("eunit/include/eunit.hrl").
|
|
|
+-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
|
|
|
|
|
%% this parses to #{}, will not cause config cleanup
|
|
|
%% so we will need call emqx_config:erase
|
|
|
@@ -55,32 +56,68 @@ end_per_suite(Conf) ->
|
|
|
emqx_mgmt_api_test_util:end_suite([emqx_gateway, emqx_authn, emqx_conf]),
|
|
|
Conf.
|
|
|
|
|
|
+init_per_testcase(t_gateway_fail, Config) ->
|
|
|
+ meck:expect(
|
|
|
+ emqx_gateway_conf,
|
|
|
+ update_gateway,
|
|
|
+ fun
|
|
|
+ (stomp, V) -> {error, {badconf, #{key => gw, value => V, reason => test_error}}};
|
|
|
+ (coap, V) -> error({badconf, #{key => gw, value => V, reason => test_crash}})
|
|
|
+ end
|
|
|
+ ),
|
|
|
+ Config;
|
|
|
+init_per_testcase(_, Config) ->
|
|
|
+ Config.
|
|
|
+
|
|
|
+end_per_testcase(TestCase, Config) ->
|
|
|
+ case TestCase of
|
|
|
+ t_gateway_fail -> meck:unload(emqx_gateway_conf);
|
|
|
+ _ -> ok
|
|
|
+ end,
|
|
|
+ [emqx_gateway_conf:unload_gateway(GwName) || GwName <- [stomp, mqttsn, coap, lwm2m, exproto]],
|
|
|
+ Config.
|
|
|
+
|
|
|
%%--------------------------------------------------------------------
|
|
|
%% Cases
|
|
|
%%--------------------------------------------------------------------
|
|
|
|
|
|
-t_gateway(_) ->
|
|
|
+t_gateways(_) ->
|
|
|
{200, Gateways} = request(get, "/gateways"),
|
|
|
lists:foreach(fun assert_gw_unloaded/1, Gateways),
|
|
|
{200, UnloadedGateways} = request(get, "/gateways?status=unloaded"),
|
|
|
lists:foreach(fun assert_gw_unloaded/1, UnloadedGateways),
|
|
|
{200, NoRunningGateways} = request(get, "/gateways?status=running"),
|
|
|
?assertEqual([], NoRunningGateways),
|
|
|
- {404, GwNotFoundReq} = request(get, "/gateways/unknown_gateway"),
|
|
|
- assert_not_found(GwNotFoundReq),
|
|
|
{400, BadReqInvalidStatus} = request(get, "/gateways?status=invalid_status"),
|
|
|
assert_bad_request(BadReqInvalidStatus),
|
|
|
{400, BadReqUCStatus} = request(get, "/gateways?status=UNLOADED"),
|
|
|
assert_bad_request(BadReqUCStatus),
|
|
|
- {201, _} = request(post, "/gateways", #{name => <<"stomp">>}),
|
|
|
- {200, StompGw1} = request(get, "/gateways/stomp"),
|
|
|
- assert_feilds_apperence(
|
|
|
+ ok.
|
|
|
+
|
|
|
+t_gateway(_) ->
|
|
|
+ {404, GwNotFoundReq1} = request(get, "/gateways/not_a_known_atom"),
|
|
|
+ assert_not_found(GwNotFoundReq1),
|
|
|
+ {404, GwNotFoundReq2} = request(get, "/gateways/undefined"),
|
|
|
+ assert_not_found(GwNotFoundReq2),
|
|
|
+ {204, _} = request(put, "/gateways/stomp", #{}),
|
|
|
+ {200, StompGw} = request(get, "/gateways/stomp"),
|
|
|
+ assert_fields_exist(
|
|
|
[name, status, enable, created_at, started_at],
|
|
|
- StompGw1
|
|
|
+ StompGw
|
|
|
),
|
|
|
- {204, _} = request(delete, "/gateways/stomp"),
|
|
|
- {200, StompGw2} = request(get, "/gateways/stomp"),
|
|
|
- assert_gw_unloaded(StompGw2),
|
|
|
+ {204, _} = request(put, "/gateways/stomp", #{enable => true}),
|
|
|
+ {200, #{enable := true}} = request(get, "/gateway/stomp"),
|
|
|
+ {204, _} = request(put, "/gateways/stomp", #{enable => false}),
|
|
|
+ {200, #{enable := false}} = request(get, "/gateway/stomp"),
|
|
|
+ {404, _} = request(put, "/gateways/undefined", #{}),
|
|
|
+ {400, _} = request(put, "/gateways/stomp", #{bad_key => "foo"}),
|
|
|
+ ok.
|
|
|
+
|
|
|
+t_gateway_fail(_) ->
|
|
|
+ {204, _} = request(put, "/gateways/stomp", #{}),
|
|
|
+ {400, _} = request(put, "/gateways/stomp", #{}),
|
|
|
+ {204, _} = request(put, "/gateways/coap", #{}),
|
|
|
+ {400, _} = request(put, "/gateways/coap", #{}),
|
|
|
ok.
|
|
|
|
|
|
t_deprecated_gateway(_) ->
|
|
|
@@ -88,21 +125,30 @@ t_deprecated_gateway(_) ->
|
|
|
lists:foreach(fun assert_gw_unloaded/1, Gateways),
|
|
|
{404, NotFoundReq} = request(get, "/gateway/uname_gateway"),
|
|
|
assert_not_found(NotFoundReq),
|
|
|
- {201, _} = request(post, "/gateway", #{name => <<"stomp">>}),
|
|
|
- {200, StompGw1} = request(get, "/gateway/stomp"),
|
|
|
- assert_feilds_apperence(
|
|
|
+ {204, _} = request(put, "/gateway/stomp", #{}),
|
|
|
+ {200, StompGw} = request(get, "/gateway/stomp"),
|
|
|
+ assert_fields_exist(
|
|
|
[name, status, enable, created_at, started_at],
|
|
|
- StompGw1
|
|
|
+ StompGw
|
|
|
),
|
|
|
- {204, _} = request(delete, "/gateway/stomp"),
|
|
|
- {200, StompGw2} = request(get, "/gateway/stomp"),
|
|
|
- assert_gw_unloaded(StompGw2),
|
|
|
+ ok.
|
|
|
+
|
|
|
+t_gateway_enable(_) ->
|
|
|
+ {204, _} = request(put, "/gateways/stomp", #{}),
|
|
|
+ {200, #{enable := Enable}} = request(get, "/gateway/stomp"),
|
|
|
+ NotEnable = not Enable,
|
|
|
+ {204, _} = request(put, "/gateways/stomp/enable/" ++ atom_to_list(NotEnable), undefined),
|
|
|
+ {200, #{enable := NotEnable}} = request(get, "/gateway/stomp"),
|
|
|
+ {204, _} = request(put, "/gateways/stomp/enable/" ++ atom_to_list(Enable), undefined),
|
|
|
+ {200, #{enable := Enable}} = request(get, "/gateway/stomp"),
|
|
|
+ {404, _} = request(put, "/gateways/undefined/enable/true", undefined),
|
|
|
+ {404, _} = request(put, "/gateways/not_a_known_atom/enable/true", undefined),
|
|
|
+ {404, _} = request(put, "/gateways/coap/enable/true", undefined),
|
|
|
ok.
|
|
|
|
|
|
t_gateway_stomp(_) ->
|
|
|
{200, Gw} = request(get, "/gateways/stomp"),
|
|
|
assert_gw_unloaded(Gw),
|
|
|
- %% post
|
|
|
GwConf = #{
|
|
|
name => <<"stomp">>,
|
|
|
frame => #{
|
|
|
@@ -114,20 +160,18 @@ t_gateway_stomp(_) ->
|
|
|
#{name => <<"def">>, type => <<"tcp">>, bind => <<"61613">>}
|
|
|
]
|
|
|
},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
+ {204, _} = request(put, "/gateways/stomp", GwConf),
|
|
|
{200, ConfResp} = request(get, "/gateways/stomp"),
|
|
|
assert_confs(GwConf, ConfResp),
|
|
|
- %% put
|
|
|
GwConf2 = emqx_map_lib:deep_merge(GwConf, #{frame => #{max_headers => 10}}),
|
|
|
- {200, _} = request(put, "/gateways/stomp", maps:without([name, listeners], GwConf2)),
|
|
|
+ {204, _} = request(put, "/gateways/stomp", maps:without([name, listeners], GwConf2)),
|
|
|
{200, ConfResp2} = request(get, "/gateways/stomp"),
|
|
|
assert_confs(GwConf2, ConfResp2),
|
|
|
- {204, _} = request(delete, "/gateways/stomp").
|
|
|
+ ok.
|
|
|
|
|
|
t_gateway_mqttsn(_) ->
|
|
|
{200, Gw} = request(get, "/gateways/mqttsn"),
|
|
|
assert_gw_unloaded(Gw),
|
|
|
- %% post
|
|
|
GwConf = #{
|
|
|
name => <<"mqttsn">>,
|
|
|
gateway_id => 1,
|
|
|
@@ -138,20 +182,18 @@ t_gateway_mqttsn(_) ->
|
|
|
#{name => <<"def">>, type => <<"udp">>, bind => <<"1884">>}
|
|
|
]
|
|
|
},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
+ {204, _} = request(put, "/gateways/mqttsn", GwConf),
|
|
|
{200, ConfResp} = request(get, "/gateways/mqttsn"),
|
|
|
assert_confs(GwConf, ConfResp),
|
|
|
- %% put
|
|
|
GwConf2 = emqx_map_lib:deep_merge(GwConf, #{predefined => []}),
|
|
|
- {200, _} = request(put, "/gateways/mqttsn", maps:without([name, listeners], GwConf2)),
|
|
|
+ {204, _} = request(put, "/gateways/mqttsn", maps:without([name, listeners], GwConf2)),
|
|
|
{200, ConfResp2} = request(get, "/gateways/mqttsn"),
|
|
|
assert_confs(GwConf2, ConfResp2),
|
|
|
- {204, _} = request(delete, "/gateways/mqttsn").
|
|
|
+ ok.
|
|
|
|
|
|
t_gateway_coap(_) ->
|
|
|
{200, Gw} = request(get, "/gateways/coap"),
|
|
|
assert_gw_unloaded(Gw),
|
|
|
- %% post
|
|
|
GwConf = #{
|
|
|
name => <<"coap">>,
|
|
|
heartbeat => <<"60s">>,
|
|
|
@@ -160,20 +202,18 @@ t_gateway_coap(_) ->
|
|
|
#{name => <<"def">>, type => <<"udp">>, bind => <<"5683">>}
|
|
|
]
|
|
|
},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
+ {204, _} = request(put, "/gateways/coap", GwConf),
|
|
|
{200, ConfResp} = request(get, "/gateways/coap"),
|
|
|
assert_confs(GwConf, ConfResp),
|
|
|
- %% put
|
|
|
GwConf2 = emqx_map_lib:deep_merge(GwConf, #{heartbeat => <<"10s">>}),
|
|
|
- {200, _} = request(put, "/gateways/coap", maps:without([name, listeners], GwConf2)),
|
|
|
+ {204, _} = request(put, "/gateways/coap", maps:without([name, listeners], GwConf2)),
|
|
|
{200, ConfResp2} = request(get, "/gateways/coap"),
|
|
|
assert_confs(GwConf2, ConfResp2),
|
|
|
- {204, _} = request(delete, "/gateways/coap").
|
|
|
+ ok.
|
|
|
|
|
|
t_gateway_lwm2m(_) ->
|
|
|
{200, Gw} = request(get, "/gateways/lwm2m"),
|
|
|
assert_gw_unloaded(Gw),
|
|
|
- %% post
|
|
|
GwConf = #{
|
|
|
name => <<"lwm2m">>,
|
|
|
xml_dir => <<"../../lib/emqx_gateway/src/lwm2m/lwm2m_xml">>,
|
|
|
@@ -192,20 +232,18 @@ t_gateway_lwm2m(_) ->
|
|
|
#{name => <<"def">>, type => <<"udp">>, bind => <<"5783">>}
|
|
|
]
|
|
|
},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
+ {204, _} = request(put, "/gateways/lwm2m", GwConf),
|
|
|
{200, ConfResp} = request(get, "/gateways/lwm2m"),
|
|
|
assert_confs(GwConf, ConfResp),
|
|
|
- %% put
|
|
|
GwConf2 = emqx_map_lib:deep_merge(GwConf, #{qmode_time_window => <<"10s">>}),
|
|
|
- {200, _} = request(put, "/gateways/lwm2m", maps:without([name, listeners], GwConf2)),
|
|
|
+ {204, _} = request(put, "/gateways/lwm2m", maps:without([name, listeners], GwConf2)),
|
|
|
{200, ConfResp2} = request(get, "/gateways/lwm2m"),
|
|
|
assert_confs(GwConf2, ConfResp2),
|
|
|
- {204, _} = request(delete, "/gateways/lwm2m").
|
|
|
+ ok.
|
|
|
|
|
|
t_gateway_exproto(_) ->
|
|
|
{200, Gw} = request(get, "/gateways/exproto"),
|
|
|
assert_gw_unloaded(Gw),
|
|
|
- %% post
|
|
|
GwConf = #{
|
|
|
name => <<"exproto">>,
|
|
|
server => #{bind => <<"9100">>},
|
|
|
@@ -214,15 +252,14 @@ t_gateway_exproto(_) ->
|
|
|
#{name => <<"def">>, type => <<"tcp">>, bind => <<"7993">>}
|
|
|
]
|
|
|
},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
+ {204, _} = request(put, "/gateways/exproto", GwConf),
|
|
|
{200, ConfResp} = request(get, "/gateways/exproto"),
|
|
|
assert_confs(GwConf, ConfResp),
|
|
|
- %% put
|
|
|
GwConf2 = emqx_map_lib:deep_merge(GwConf, #{server => #{bind => <<"9200">>}}),
|
|
|
- {200, _} = request(put, "/gateways/exproto", maps:without([name, listeners], GwConf2)),
|
|
|
+ {204, _} = request(put, "/gateways/exproto", maps:without([name, listeners], GwConf2)),
|
|
|
{200, ConfResp2} = request(get, "/gateways/exproto"),
|
|
|
assert_confs(GwConf2, ConfResp2),
|
|
|
- {204, _} = request(delete, "/gateways/exproto").
|
|
|
+ ok.
|
|
|
|
|
|
t_gateway_exproto_with_ssl(_) ->
|
|
|
{200, Gw} = request(get, "/gateways/exproto"),
|
|
|
@@ -230,7 +267,6 @@ t_gateway_exproto_with_ssl(_) ->
|
|
|
|
|
|
SslSvrOpts = ssl_server_opts(),
|
|
|
SslCliOpts = ssl_client_opts(),
|
|
|
- %% post
|
|
|
GwConf = #{
|
|
|
name => <<"exproto">>,
|
|
|
server => #{
|
|
|
@@ -245,27 +281,22 @@ t_gateway_exproto_with_ssl(_) ->
|
|
|
#{name => <<"def">>, type => <<"tcp">>, bind => <<"7993">>}
|
|
|
]
|
|
|
},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
+ {204, _} = request(put, "/gateways/exproto", GwConf),
|
|
|
{200, ConfResp} = request(get, "/gateways/exproto"),
|
|
|
assert_confs(GwConf, ConfResp),
|
|
|
- %% put
|
|
|
GwConf2 = emqx_map_lib:deep_merge(GwConf, #{
|
|
|
server => #{
|
|
|
bind => <<"9200">>,
|
|
|
ssl_options => SslCliOpts
|
|
|
}
|
|
|
}),
|
|
|
- {200, _} = request(put, "/gateways/exproto", maps:without([name, listeners], GwConf2)),
|
|
|
+ {204, _} = request(put, "/gateways/exproto", maps:without([name, listeners], GwConf2)),
|
|
|
{200, ConfResp2} = request(get, "/gateways/exproto"),
|
|
|
assert_confs(GwConf2, ConfResp2),
|
|
|
- {204, _} = request(delete, "/gateways/exproto").
|
|
|
+ ok.
|
|
|
|
|
|
t_authn(_) ->
|
|
|
- GwConf = #{name => <<"stomp">>},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
- ct:sleep(500),
|
|
|
- {204, _} = request(get, "/gateways/stomp/authentication"),
|
|
|
-
|
|
|
+ init_gw("stomp"),
|
|
|
AuthConf = #{
|
|
|
mechanism => <<"password_based">>,
|
|
|
backend => <<"built_in_database">>,
|
|
|
@@ -283,22 +314,18 @@ t_authn(_) ->
|
|
|
|
|
|
{204, _} = request(delete, "/gateways/stomp/authentication"),
|
|
|
{204, _} = request(get, "/gateways/stomp/authentication"),
|
|
|
- {204, _} = request(delete, "/gateways/stomp").
|
|
|
+ ok.
|
|
|
|
|
|
t_authn_data_mgmt(_) ->
|
|
|
- GwConf = #{name => <<"stomp">>},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
- ct:sleep(500),
|
|
|
- {204, _} = request(get, "/gateways/stomp/authentication"),
|
|
|
-
|
|
|
+ init_gw("stomp"),
|
|
|
AuthConf = #{
|
|
|
mechanism => <<"password_based">>,
|
|
|
backend => <<"built_in_database">>,
|
|
|
user_id_type => <<"clientid">>
|
|
|
},
|
|
|
{201, _} = request(post, "/gateways/stomp/authentication", AuthConf),
|
|
|
- ct:sleep(500),
|
|
|
- {200, ConfResp} = request(get, "/gateways/stomp/authentication"),
|
|
|
+ {200, ConfResp} =
|
|
|
+ ?retry(10, 10, {200, _} = request(get, "/gateways/stomp/authentication")),
|
|
|
assert_confs(AuthConf, ConfResp),
|
|
|
|
|
|
User1 = #{
|
|
|
@@ -358,11 +385,10 @@ t_authn_data_mgmt(_) ->
|
|
|
|
|
|
{204, _} = request(delete, "/gateways/stomp/authentication"),
|
|
|
{204, _} = request(get, "/gateways/stomp/authentication"),
|
|
|
- {204, _} = request(delete, "/gateways/stomp").
|
|
|
+ ok.
|
|
|
|
|
|
t_listeners_tcp(_) ->
|
|
|
- GwConf = #{name => <<"stomp">>},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
+ {204, _} = request(put, "/gateways/stomp", #{}),
|
|
|
{404, _} = request(get, "/gateways/stomp/listeners"),
|
|
|
LisConf = #{
|
|
|
name => <<"def">>,
|
|
|
@@ -387,7 +413,7 @@ t_listeners_tcp(_) ->
|
|
|
|
|
|
{204, _} = request(delete, "/gateways/stomp/listeners/stomp:tcp:def"),
|
|
|
{404, _} = request(get, "/gateways/stomp/listeners/stomp:tcp:def"),
|
|
|
- {204, _} = request(delete, "/gateways/stomp").
|
|
|
+ ok.
|
|
|
|
|
|
t_listeners_authn(_) ->
|
|
|
GwConf = #{
|
|
|
@@ -400,9 +426,7 @@ t_listeners_authn(_) ->
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
- ct:sleep(500),
|
|
|
- {200, ConfResp} = request(get, "/gateways/stomp"),
|
|
|
+ ConfResp = init_gw("stomp", GwConf),
|
|
|
assert_confs(GwConf, ConfResp),
|
|
|
|
|
|
AuthConf = #{
|
|
|
@@ -424,7 +448,7 @@ t_listeners_authn(_) ->
|
|
|
{204, _} = request(delete, Path),
|
|
|
%% FIXME: 204?
|
|
|
{204, _} = request(get, Path),
|
|
|
- {204, _} = request(delete, "/gateways/stomp").
|
|
|
+ ok.
|
|
|
|
|
|
t_listeners_authn_data_mgmt(_) ->
|
|
|
GwConf = #{
|
|
|
@@ -437,7 +461,7 @@ t_listeners_authn_data_mgmt(_) ->
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
+ {204, _} = request(put, "/gateways/stomp", GwConf),
|
|
|
{200, ConfResp} = request(get, "/gateways/stomp"),
|
|
|
assert_confs(GwConf, ConfResp),
|
|
|
|
|
|
@@ -514,13 +538,10 @@ t_listeners_authn_data_mgmt(_) ->
|
|
|
{filename, "user-credentials.csv", CSVData}
|
|
|
]),
|
|
|
|
|
|
- {204, _} = request(delete, "/gateways/stomp").
|
|
|
+ ok.
|
|
|
|
|
|
t_authn_fuzzy_search(_) ->
|
|
|
- GwConf = #{name => <<"stomp">>},
|
|
|
- {201, _} = request(post, "/gateways", GwConf),
|
|
|
- {204, _} = request(get, "/gateways/stomp/authentication"),
|
|
|
-
|
|
|
+ init_gw("stomp"),
|
|
|
AuthConf = #{
|
|
|
mechanism => <<"password_based">>,
|
|
|
backend => <<"built_in_database">>,
|
|
|
@@ -561,7 +582,25 @@ t_authn_fuzzy_search(_) ->
|
|
|
|
|
|
{204, _} = request(delete, "/gateways/stomp/authentication"),
|
|
|
{204, _} = request(get, "/gateways/stomp/authentication"),
|
|
|
- {204, _} = request(delete, "/gateways/stomp").
|
|
|
+ ok.
|
|
|
+
|
|
|
+%%--------------------------------------------------------------------
|
|
|
+%% Helpers
|
|
|
+
|
|
|
+init_gw(GwName) ->
|
|
|
+ init_gw(GwName, #{}).
|
|
|
+
|
|
|
+init_gw(GwName, GwConf) ->
|
|
|
+ {204, _} = request(put, "/gateways/" ++ GwName, GwConf),
|
|
|
+ ?retry(
|
|
|
+ 10,
|
|
|
+ 10,
|
|
|
+ begin
|
|
|
+ {200, #{status := Status} = RespConf} = request(get, "/gateways/" ++ GwName),
|
|
|
+ false = (Status == <<"unloaded">>),
|
|
|
+ RespConf
|
|
|
+ end
|
|
|
+ ).
|
|
|
|
|
|
%%--------------------------------------------------------------------
|
|
|
%% Asserts
|