diff --git a/src/emqx_mqtt_caps.erl b/src/emqx_mqtt_caps.erl index d9ad79e0a..27b8ad7bc 100644 --- a/src/emqx_mqtt_caps.erl +++ b/src/emqx_mqtt_caps.erl @@ -62,7 +62,7 @@ do_check_pub(Props = #{qos := QoS}, [{max_qos_allowed, MaxQoS}|Caps]) -> end; do_check_pub(#{retain := true}, [{mqtt_retain_available, false}|_Caps]) -> {error, ?RC_RETAIN_NOT_SUPPORTED}; -do_check_pub(Props, [{mqtt_retain_available, true}|Caps]) -> +do_check_pub(Props, [{mqtt_retain_available, _}|Caps]) -> do_check_pub(Props, Caps). -spec(check_sub(zone(), mqtt_topic_filters()) -> {ok | error, mqtt_topic_filters()}). diff --git a/test/emqx_cm_SUITE.erl b/test/emqx_cm_SUITE.erl index 4cb4fa8a4..440b2788b 100644 --- a/test/emqx_cm_SUITE.erl +++ b/test/emqx_cm_SUITE.erl @@ -21,19 +21,19 @@ -include("emqx_mqtt.hrl"). -all() -> [t_register_unregister_client]. +all() -> [t_register_unregister_connection]. -t_register_unregister_client(_) -> +t_register_unregister_connection(_) -> {ok, _} = emqx_cm_sup:start_link(), Pid = self(), - emqx_cm:register_client(<<0, 0, 1>>), - emqx_cm:register_client({<<0, 0, 2>>, Pid}, [{port, 8080}, {ip, "192.168.0.1"}]), + emqx_cm:register_connection(<<"conn1">>), + emqx_cm:register_connection({<<"conn2">>, Pid}, [{port, 8080}, {ip, "192.168.0.1"}]), timer:sleep(2000), - [{<<0, 0, 1>>, Pid}] = emqx_cm:lookup_client(<<0, 0, 1>>), - [{<<0, 0, 2>>, Pid}] = emqx_cm:lookup_client(<<0, 0, 2>>), - Pid = emqx_cm:lookup_client_pid(<<0, 0, 1>>), - emqx_cm:unregister_client(<<0, 0, 1>>), - [] = emqx_cm:lookup_client(<<0, 0, 1>>), - [{port, 8080}, {ip, "192.168.0.1"}] = emqx_cm:get_client_attrs({<<0, 0, 2>>, Pid}), - emqx_cm:set_client_stats(<<0, 0, 2>>, [[{count, 1}, {max, 2}]]), - [[{count, 1}, {max, 2}]] = emqx_cm:get_client_stats({<<0, 0, 2>>, Pid}). \ No newline at end of file + [{<<"conn1">>, Pid}] = emqx_cm:lookup_connection(<<"conn1">>), + [{<<"conn2">>, Pid}] = emqx_cm:lookup_connection(<<"conn2">>), + Pid = emqx_cm:lookup_conn_pid(<<"conn1">>), + emqx_cm:unregister_connection(<<"conn1">>), + [] = emqx_cm:lookup_connection(<<"conn1">>), + [{port, 8080}, {ip, "192.168.0.1"}] = emqx_cm:get_conn_attrs({<<"conn2">>, Pid}), + emqx_cm:set_conn_stats(<<"conn2">>, [[{count, 1}, {max, 2}]]), + [[{count, 1}, {max, 2}]] = emqx_cm:get_conn_stats({<<"conn2">>, Pid}). \ No newline at end of file diff --git a/test/emqx_inflight_SUITE.erl b/test/emqx_inflight_SUITE.erl index de3accc06..25f4cd7da 100644 --- a/test/emqx_inflight_SUITE.erl +++ b/test/emqx_inflight_SUITE.erl @@ -1,62 +1,43 @@ -%%%=================================================================== -%%% Copyright (c) 2013-2018 EMQ Inc. All rights reserved. -%%% -%%% Licensed under the Apache License, Version 2.0 (the "License"); -%%% you may not use this file except in compliance with the License. -%%% You may obtain a copy of the License at -%%% -%%% http://www.apache.org/licenses/LICENSE-2.0 -%%% -%%% Unless required by applicable law or agreed to in writing, software -%%% distributed under the License is distributed on an "AS IS" BASIS, -%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%%% See the License for the specific language governing permissions and -%%% limitations under the License. -%%%=================================================================== +%%-------------------------------------------------------------------- +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- -module(emqx_inflight_SUITE). --include_lib("eunit/include/eunit.hrl"). - -compile(export_all). -compile(nowarn_export_all). --import(emqx_inflight, [new/1, contain/2, insert/3, lookup/2, update/3, - delete/2, is_empty/1, is_full/1]). - -all() -> - [t_contain, t_lookup, t_insert, t_update, t_delete, t_window, - t_is_full, t_is_empty]. - -t_contain(_) -> - ?assertNot(contain(k, new(0))), - ?assert(contain(k, insert(k, v, new(0)))). - -t_lookup(_) -> - Inflight = insert(k, v, new(0)), - ?assertEqual({value, v}, lookup(k, Inflight)), - ?assertEqual(none, lookup(x, Inflight)). - -t_insert(_) -> - Inflight = insert(k2, v2, insert(k1, v1, new(0))), - ?assertEqual({value, v1}, lookup(k1, Inflight)), - ?assertEqual({value, v2}, lookup(k2, Inflight)). - -t_update(_) -> - Inflight = update(k, v2, insert(k, v1, new(0))), - ?assertEqual({value, v2}, lookup(k, Inflight)). - -t_delete(_) -> - ?assert(is_empty(delete(k, insert(k, v1, new(0))))). - -t_window(_) -> - ?assertEqual([], emqx_inflight:window(new(10))), - Inflight = insert(2, 2, insert(1, 1, new(0))), - ?assertEqual([1, 2], emqx_inflight:window(Inflight)). - -t_is_full(_) -> - ?assert(is_full(insert(k, v1, new(1)))). - -t_is_empty(_) -> - ?assertNot(is_empty(insert(k, v1, new(1)))). +all() -> [t_inflight_all]. +t_inflight_all(_) -> + Empty = emqx_inflight:new(2), + true = emqx_inflight:is_empty(Empty), + 2 = emqx_inflight:max_size(Empty), + false = emqx_inflight:contain(a, Empty), + none = emqx_inflight:lookup(a, Empty), + try emqx_inflight:update(a, 1, Empty) catch + error:Reason -> io:format("Reason: ~w~n", [Reason]) + end, + 0 = emqx_inflight:size(Empty), + Inflight1 = emqx_inflight:insert(a, 1, Empty), + Inflight2 = emqx_inflight:insert(b, 2, Inflight1), + 2 = emqx_inflight:size(Inflight2), + true = emqx_inflight:is_full(Inflight2), + {value, 1} = emqx_inflight:lookup(a, Inflight1), + {value, 2} = emqx_inflight:lookup(a, emqx_inflight:update(a, 2, Inflight1)), + false = emqx_inflight:contain(a, emqx_inflight:delete(a, Inflight1)), + [1, 2] = emqx_inflight:values(Inflight2), + [{a, 1}, {b ,2}] = emqx_inflight:to_list(Inflight2), + [a, b] = emqx_inflight:window(Inflight2). \ No newline at end of file diff --git a/test/emqx_json_SUITE.erl b/test/emqx_json_SUITE.erl new file mode 100644 index 000000000..9d8b6e697 --- /dev/null +++ b/test/emqx_json_SUITE.erl @@ -0,0 +1,39 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +-module(emqx_json_SUITE). + +-compile(export_all). +-compile(nowarn_export_all). + +all() -> [t_decode_encode, t_safe_decode_encode]. + +t_decode_encode(_) -> + JsonText = <<"{\"library\": \"jsx\", \"awesome\": true}">>, + JsonTerm = emqx_json:decode(JsonText), + JsonMaps = #{library => <<"jsx">>, awesome => true}, + JsonMaps = emqx_json:decode(JsonText, [{labels, atom}, return_maps]), + JsonText = emqx_json:encode(JsonTerm, [{space, 1}]). + +t_safe_decode_encode(_) -> + JsonText = <<"{\"library\": \"jsx\", \"awesome\": true}">>, + {ok, JsonTerm} = emqx_json:safe_decode(JsonText), + JsonMaps = #{library => <<"jsx">>, awesome => true}, + {ok, JsonMaps} = emqx_json:safe_decode(JsonText, [{labels, atom}, return_maps]), + {ok, JsonText} = emqx_json:safe_encode(JsonTerm, [{space, 1}]), + BadJsonText = <<"{\"library\", \"awesome\": true}">>, + {error, _} = emqx_json:safe_decode(BadJsonText), + {error, _} = emqx_json:safe_encode({a, {b ,1}}). \ No newline at end of file diff --git a/test/emqx_mqtt_caps_SUITE.erl b/test/emqx_mqtt_caps_SUITE.erl index 3fbb422d5..f2f50a296 100644 --- a/test/emqx_mqtt_caps_SUITE.erl +++ b/test/emqx_mqtt_caps_SUITE.erl @@ -16,11 +16,100 @@ -include_lib("eunit/include/eunit.hrl"). +-include("emqx.hrl"). +-include("emqx_mqtt.hrl"). + %% CT -compile(export_all). -compile(nowarn_export_all). -all() -> - []. +all() -> [t_get_set_caps, t_check_pub, t_check_sub]. + +t_get_set_caps(_) -> + {ok, _} = emqx_zone:start_link(), + Caps = #{ + max_packet_size => ?MAX_PACKET_SIZE, + max_clientid_len => ?MAX_CLIENTID_LEN, + max_topic_alias => 0, + max_topic_levels => 0, + max_qos_allowed => ?QOS_2, + mqtt_retain_available => true, + mqtt_shared_subscription => true, + mqtt_wildcard_subscription => true + }, + Caps = emqx_mqtt_caps:get_caps(zone), + PubCaps = #{ + max_qos_allowed => ?QOS_2, + mqtt_retain_available => true + }, + PubCaps = emqx_mqtt_caps:get_caps(zone, publish), + NewPubCaps = PubCaps#{max_qos_allowed => ?QOS_1}, + emqx_zone:set_env(zone, '$mqtt_pub_caps', NewPubCaps), + timer:sleep(100), + NewPubCaps = emqx_mqtt_caps:get_caps(zone, publish), + SubCaps = #{ + max_topic_levels => 0, + max_qos_allowed => ?QOS_2, + mqtt_shared_subscription => true, + mqtt_wildcard_subscription => true + }, + SubCaps = emqx_mqtt_caps:get_caps(zone, subscribe). + +t_check_pub(_) -> + {ok, _} = emqx_zone:start_link(), + PubCaps = #{ + max_qos_allowed => ?QOS_1, + mqtt_retain_available => false + }, + emqx_zone:set_env(zone, '$mqtt_pub_caps', PubCaps), + timer:sleep(100), + BadPubProps1 = #{ + qos => ?QOS_2, + retain => false + }, + {error, ?RC_QOS_NOT_SUPPORTED} = emqx_mqtt_caps:check_pub(zone, BadPubProps1), + BadPubProps2 = #{ + qos => ?QOS_1, + retain => true + }, + {error, ?RC_RETAIN_NOT_SUPPORTED} = emqx_mqtt_caps:check_pub(zone, BadPubProps2), + PubProps = #{ + qos => ?QOS_1, + retain => false + }, + ok = emqx_mqtt_caps:check_pub(zone, PubProps). + +t_check_sub(_) -> + {ok, _} = emqx_zone:start_link(), + + Opts = #{qos => ?QOS_2, share => true, rc => 0}, + Caps = #{ + max_topic_levels => 0, + max_qos_allowed => ?QOS_2, + mqtt_shared_subscription => true, + mqtt_wildcard_subscription => true + }, + + ok = do_check_sub([{<<"client/stat">>, Opts}], [{<<"client/stat">>, Opts}]), + ok = do_check_sub(Caps#{max_qos_allowed => ?QOS_1}, [{<<"client/stat">>, Opts}], [{<<"client/stat">>, Opts#{qos => ?QOS_1}}]), + ok = do_check_sub(Caps#{max_topic_levels => 1}, + [{<<"client/stat">>, Opts}], + [{<<"client/stat">>, Opts#{rc => ?RC_TOPIC_FILTER_INVALID}}]), + ok = do_check_sub(Caps#{mqtt_shared_subscription => false}, + [{<<"client/stat">>, Opts}], + [{<<"client/stat">>, Opts#{rc => ?RC_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED}}]), + ok = do_check_sub(Caps#{mqtt_wildcard_subscription => false}, + [{<<"vlient/+/dsofi">>, Opts}], + [{<<"vlient/+/dsofi">>, Opts#{rc => ?RC_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED}}]). + + +do_check_sub(TopicFilters, Topics) -> + {ok, Topics} = emqx_mqtt_caps:check_sub(zone, TopicFilters), + ok. +do_check_sub(Caps, TopicFilters, Topics) -> + emqx_zone:set_env(zone, '$mqtt_sub_caps', Caps), + timer:sleep(100), + {_, Topics} = emqx_mqtt_caps:check_sub(zone, TopicFilters), + ok. diff --git a/test/emqx_mqtt_properties_SUITE.erl b/test/emqx_mqtt_properties_SUITE.erl new file mode 100644 index 000000000..7fe78433c --- /dev/null +++ b/test/emqx_mqtt_properties_SUITE.erl @@ -0,0 +1,29 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +-module(emqx_mqtt_properties_SUITE). + +-compile(export_all). +-compile(nowarn_export_all). + +-include("emqx_mqtt.hrl"). + +all() -> [t_mqtt_properties_all]. + +t_mqtt_properties_all(_) -> + Props = emqx_mqtt_properties:filter(?CONNECT, #{'Session-Expiry-Interval' => 1, 'Maximum-Packet-Size' => 255}), + ok = emqx_mqtt_properties:validate(Props), + #{} = emqx_mqtt_properties:filter(?CONNECT, #{'Maximum-QoS' => ?QOS_2}). \ No newline at end of file diff --git a/test/emqx_tables_SUITE.erl b/test/emqx_tables_SUITE.erl new file mode 100644 index 000000000..618e83597 --- /dev/null +++ b/test/emqx_tables_SUITE.erl @@ -0,0 +1,28 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +-module(emqx_tables_SUITE). + +-compile(export_all). +-compile(nowarn_export_all). + +all() -> [t_new]. + +t_new(_) -> + TId = emqx_tables:new(test_table, [{read_concurrency, true}]), + ets:insert(TId, {loss, 100}), + TId = emqx_tables:new(test_table, [{read_concurrency, true}]), + 100 = ets:lookup_element(TId, loss, 2). diff --git a/test/emqx_zone_SUITE.erl b/test/emqx_zone_SUITE.erl new file mode 100644 index 000000000..deca884d8 --- /dev/null +++ b/test/emqx_zone_SUITE.erl @@ -0,0 +1,33 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +-module(emqx_zone_SUITE). + +-compile(export_all). +-compile(nowarn_export_all). + +-include("emqx_mqtt.hrl"). + +all() -> [t_set_get_env]. + +t_set_get_env(_) -> + {ok, _} = emqx_zone:start_link(), + ok = emqx_zone:set_env(china, language, chinese), + timer:sleep(100), % make sure set_env/3 is okay + chinese = emqx_zone:get_env(china, language), + cn470 = emqx_zone:get_env(china, ism_band, cn470), + undefined = emqx_zone:get_env(undefined, delay), + 500 = emqx_zone:get_env(undefined, delay, 500).