chore(gw): add cli testcases
This commit is contained in:
parent
d781dc73a5
commit
fca5a3bc21
|
@ -532,7 +532,21 @@ params_client_searching_in_qs() ->
|
||||||
, {lte_connected_at,
|
, {lte_connected_at,
|
||||||
mk(binary(),
|
mk(binary(),
|
||||||
M#{desc => <<"Match the client socket connected datatime less than "
|
M#{desc => <<"Match the client socket connected datatime less than "
|
||||||
" a certain value">>})}
|
"a certain value">>})}
|
||||||
|
, {endpoint_name,
|
||||||
|
mk(binary(),
|
||||||
|
M#{desc => <<"Match the lwm2m client's endpoint name">>})}
|
||||||
|
, {like_endpoint_name,
|
||||||
|
mk(binary(),
|
||||||
|
M#{desc => <<"Use sub-string to match lwm2m client's endpoint name">>})}
|
||||||
|
, {gte_lifetime,
|
||||||
|
mk(binary(),
|
||||||
|
M#{desc => <<"Match the lwm2m client registered lifetime greater "
|
||||||
|
"than a certain value">>})}
|
||||||
|
, {lte_lifetime,
|
||||||
|
mk(binary(),
|
||||||
|
M#{desc => <<"Match the lwm2m client registered lifetime less than "
|
||||||
|
"a certain value">>})}
|
||||||
].
|
].
|
||||||
|
|
||||||
params_paging() ->
|
params_paging() ->
|
||||||
|
|
|
@ -50,18 +50,24 @@ is_cmd(Fun) ->
|
||||||
%% Cmds
|
%% Cmds
|
||||||
|
|
||||||
gateway(["list"]) ->
|
gateway(["list"]) ->
|
||||||
lists:foreach(fun(#{name := Name} = Gateway) ->
|
lists:foreach(
|
||||||
%% TODO: More infos: listeners?, connected?
|
fun (#{name := Name, status := unloaded}) ->
|
||||||
Status = maps:get(status, Gateway, stopped),
|
print("Gateway(name=~ts, status=unloaded)\n", [Name]);
|
||||||
print("Gateway(name=~ts, status=~ts)~n", [Name, Status])
|
(#{name := Name, status := stopped, stopped_at := StoppedAt}) ->
|
||||||
end, emqx_gateway:list());
|
print("Gateway(name=~ts, status=stopped, stopped_at=~ts)\n",
|
||||||
|
[Name, StoppedAt]);
|
||||||
|
(#{name := Name, status := running, current_connections := ConnCnt,
|
||||||
|
started_at := StartedAt}) ->
|
||||||
|
print("Gateway(name=~ts, status=running, clients=~w, started_at=~ts)\n",
|
||||||
|
[Name, ConnCnt, StartedAt])
|
||||||
|
end, emqx_gateway_http:gateways(all));
|
||||||
|
|
||||||
gateway(["lookup", Name]) ->
|
gateway(["lookup", Name]) ->
|
||||||
case emqx_gateway:lookup(atom(Name)) of
|
case emqx_gateway:lookup(atom(Name)) of
|
||||||
undefined ->
|
undefined ->
|
||||||
print("undefined~n");
|
print("undefined\n");
|
||||||
Info ->
|
Info ->
|
||||||
print("~p~n", [Info])
|
print("~p\n", [Info])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
gateway(["load", Name, Conf]) ->
|
gateway(["load", Name, Conf]) ->
|
||||||
|
@ -70,17 +76,17 @@ gateway(["load", Name, Conf]) ->
|
||||||
emqx_json:decode(Conf, [return_maps])
|
emqx_json:decode(Conf, [return_maps])
|
||||||
) of
|
) of
|
||||||
{ok, _} ->
|
{ok, _} ->
|
||||||
print("ok~n");
|
print("ok\n");
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
print("Error: ~p~n", [Reason])
|
print("Error: ~p\n", [Reason])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
gateway(["unload", Name]) ->
|
gateway(["unload", Name]) ->
|
||||||
case emqx_gateway_conf:unload_gateway(bin(Name)) of
|
case emqx_gateway_conf:unload_gateway(bin(Name)) of
|
||||||
ok ->
|
ok ->
|
||||||
print("ok~n");
|
print("ok\n");
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
print("Error: ~p~n", [Reason])
|
print("Error: ~p\n", [Reason])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
gateway(["stop", Name]) ->
|
gateway(["stop", Name]) ->
|
||||||
|
@ -89,9 +95,9 @@ gateway(["stop", Name]) ->
|
||||||
#{<<"enable">> => <<"false">>}
|
#{<<"enable">> => <<"false">>}
|
||||||
) of
|
) of
|
||||||
{ok, _} ->
|
{ok, _} ->
|
||||||
print("ok~n");
|
print("ok\n");
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
print("Error: ~p~n", [Reason])
|
print("Error: ~p\n", [Reason])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
gateway(["start", Name]) ->
|
gateway(["start", Name]) ->
|
||||||
|
@ -100,9 +106,9 @@ gateway(["start", Name]) ->
|
||||||
#{<<"enable">> => <<"true">>}
|
#{<<"enable">> => <<"true">>}
|
||||||
) of
|
) of
|
||||||
{ok, _} ->
|
{ok, _} ->
|
||||||
print("ok~n");
|
print("ok\n");
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
print("Error: ~p~n", [Reason])
|
print("Error: ~p\n", [Reason])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
gateway(_) ->
|
gateway(_) ->
|
||||||
|
@ -123,7 +129,7 @@ gateway(_) ->
|
||||||
'gateway-registry'(["list"]) ->
|
'gateway-registry'(["list"]) ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({Name, #{cbkmod := CbMod}}) ->
|
fun({Name, #{cbkmod := CbMod}}) ->
|
||||||
print("Registered Name: ~ts, Callback Module: ~ts~n", [Name, CbMod])
|
print("Registered Name: ~ts, Callback Module: ~ts\n", [Name, CbMod])
|
||||||
end,
|
end,
|
||||||
emqx_gateway_registry:list());
|
emqx_gateway_registry:list());
|
||||||
|
|
||||||
|
@ -137,7 +143,7 @@ gateway(_) ->
|
||||||
InfoTab = emqx_gateway_cm:tabname(info, Name),
|
InfoTab = emqx_gateway_cm:tabname(info, Name),
|
||||||
case ets:info(InfoTab) of
|
case ets:info(InfoTab) of
|
||||||
undefined ->
|
undefined ->
|
||||||
print("Bad Gateway Name.~n");
|
print("Bad Gateway Name.\n");
|
||||||
_ ->
|
_ ->
|
||||||
dump(InfoTab, client)
|
dump(InfoTab, client)
|
||||||
end;
|
end;
|
||||||
|
@ -145,7 +151,7 @@ gateway(_) ->
|
||||||
'gateway-clients'(["lookup", Name, ClientId]) ->
|
'gateway-clients'(["lookup", Name, ClientId]) ->
|
||||||
ChanTab = emqx_gateway_cm:tabname(chan, Name),
|
ChanTab = emqx_gateway_cm:tabname(chan, Name),
|
||||||
case ets:lookup(ChanTab, bin(ClientId)) of
|
case ets:lookup(ChanTab, bin(ClientId)) of
|
||||||
[] -> print("Not Found.~n");
|
[] -> print("Not Found.\n");
|
||||||
[Chann] ->
|
[Chann] ->
|
||||||
InfoTab = emqx_gateway_cm:tabname(info, Name),
|
InfoTab = emqx_gateway_cm:tabname(info, Name),
|
||||||
[ChannInfo] = ets:lookup(InfoTab, Chann),
|
[ChannInfo] = ets:lookup(InfoTab, Chann),
|
||||||
|
@ -154,8 +160,8 @@ gateway(_) ->
|
||||||
|
|
||||||
'gateway-clients'(["kick", Name, ClientId]) ->
|
'gateway-clients'(["kick", Name, ClientId]) ->
|
||||||
case emqx_gateway_cm:kick_session(Name, bin(ClientId)) of
|
case emqx_gateway_cm:kick_session(Name, bin(ClientId)) of
|
||||||
ok -> print("ok~n");
|
ok -> print("ok\n");
|
||||||
_ -> print("Not Found.~n")
|
_ -> print("Not Found.\n")
|
||||||
end;
|
end;
|
||||||
|
|
||||||
'gateway-clients'(_) ->
|
'gateway-clients'(_) ->
|
||||||
|
@ -171,11 +177,11 @@ gateway(_) ->
|
||||||
Tab = emqx_gateway_metrics:tabname(Name),
|
Tab = emqx_gateway_metrics:tabname(Name),
|
||||||
case ets:info(Tab) of
|
case ets:info(Tab) of
|
||||||
undefined ->
|
undefined ->
|
||||||
print("Bad Gateway Name.~n");
|
print("Bad Gateway Name.\n");
|
||||||
_ ->
|
_ ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({K, V}) ->
|
fun({K, V}) ->
|
||||||
print("~-30s: ~w~n", [K, V])
|
print("~-30s: ~w\n", [K, V])
|
||||||
end, lists:sort(ets:tab2list(Tab)))
|
end, lists:sort(ets:tab2list(Tab)))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -232,7 +238,7 @@ print_record({client, {_, Infos, Stats}}) ->
|
||||||
print("Client(~ts, username=~ts, peername=~ts, "
|
print("Client(~ts, username=~ts, peername=~ts, "
|
||||||
"clean_start=~ts, keepalive=~w, "
|
"clean_start=~ts, keepalive=~w, "
|
||||||
"subscriptions=~w, delivered_msgs=~w, "
|
"subscriptions=~w, delivered_msgs=~w, "
|
||||||
"connected=~ts, created_at=~w, connected_at=~w)~n",
|
"connected=~ts, created_at=~w, connected_at=~w)\n",
|
||||||
[format(K, maps:get(K, Info)) || K <- InfoKeys]).
|
[format(K, maps:get(K, Info)) || K <- InfoKeys]).
|
||||||
|
|
||||||
print(S) -> emqx_ctl:print(S).
|
print(S) -> emqx_ctl:print(S).
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2021 EMQ Technologies Co., Ltd. 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.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_gateway_cli_SUITE).
|
||||||
|
|
||||||
|
-compile(export_all).
|
||||||
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
-define(GP(S), begin S, receive {fmt, P} -> P; O -> O end end).
|
||||||
|
|
||||||
|
%% this parses to #{}, will not cause config cleanup
|
||||||
|
%% so we will need call emqx_config:erase
|
||||||
|
-define(CONF_DEFAULT, <<"
|
||||||
|
gateway {}
|
||||||
|
">>).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Setup
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
all() -> emqx_common_test_helpers:all(?MODULE).
|
||||||
|
|
||||||
|
init_per_suite(Conf) ->
|
||||||
|
emqx_config:erase(gateway),
|
||||||
|
emqx_config:init_load(emqx_gateway_schema, ?CONF_DEFAULT),
|
||||||
|
emqx_mgmt_api_test_util:init_suite([emqx_conf, emqx_authn, emqx_gateway]),
|
||||||
|
Conf.
|
||||||
|
|
||||||
|
end_per_suite(Conf) ->
|
||||||
|
emqx_mgmt_api_test_util:end_suite([emqx_gateway, emqx_authn, emqx_conf]),
|
||||||
|
Conf.
|
||||||
|
|
||||||
|
init_per_testcase(_, Conf) ->
|
||||||
|
Self = self(),
|
||||||
|
ok = meck:new(emqx_ctl, [passthrough, no_history, no_link]),
|
||||||
|
ok = meck:expect(emqx_ctl, usage,
|
||||||
|
fun(L) -> emqx_ctl:format_usage(L) end),
|
||||||
|
ok = meck:expect(emqx_ctl, print,
|
||||||
|
fun(Fmt) ->
|
||||||
|
Self ! {fmt, emqx_ctl:format(Fmt)}
|
||||||
|
end),
|
||||||
|
ok = meck:expect(emqx_ctl, print,
|
||||||
|
fun(Fmt, Args) ->
|
||||||
|
Self ! {fmt, emqx_ctl:format(Fmt, Args)}
|
||||||
|
end),
|
||||||
|
Conf.
|
||||||
|
|
||||||
|
end_per_testcase(_, _) ->
|
||||||
|
meck:unload([emqx_ctl]),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Cases
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% TODO:
|
||||||
|
|
||||||
|
t_load_unload(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_gateway_registry_usage(_) ->
|
||||||
|
?assertEqual(
|
||||||
|
["gateway-registry list # List all registered gateways\n"],
|
||||||
|
emqx_gateway_cli:'gateway-registry'(usage)).
|
||||||
|
|
||||||
|
t_gateway_registry_list(_) ->
|
||||||
|
emqx_gateway_cli:'gateway-registry'(["list"]),
|
||||||
|
?assertEqual(
|
||||||
|
"Registered Name: coap, Callback Module: emqx_coap_impl\n"
|
||||||
|
"Registered Name: exproto, Callback Module: emqx_exproto_impl\n"
|
||||||
|
"Registered Name: lwm2m, Callback Module: emqx_lwm2m_impl\n"
|
||||||
|
"Registered Name: mqttsn, Callback Module: emqx_sn_impl\n"
|
||||||
|
"Registered Name: stomp, Callback Module: emqx_stomp_impl\n"
|
||||||
|
, acc_print()).
|
||||||
|
|
||||||
|
t_gateway_usage(_) ->
|
||||||
|
?assertEqual(
|
||||||
|
["gateway list # List all gateway\n",
|
||||||
|
"gateway lookup <Name> # Lookup a gateway detailed informations\n",
|
||||||
|
"gateway load <Name> <JsonConf> # Load a gateway with config\n",
|
||||||
|
"gateway unload <Name> # Unload the gateway\n",
|
||||||
|
"gateway stop <Name> # Stop the gateway\n",
|
||||||
|
"gateway start <Name> # Start the gateway\n"],
|
||||||
|
emqx_gateway_cli:gateway(usage)
|
||||||
|
).
|
||||||
|
|
||||||
|
t_gateway_list(_) ->
|
||||||
|
emqx_gateway_cli:gateway(["list"]),
|
||||||
|
?assertEqual(
|
||||||
|
"Gateway(name=coap, status=unloaded)\n"
|
||||||
|
"Gateway(name=exproto, status=unloaded)\n"
|
||||||
|
"Gateway(name=lwm2m, status=unloaded)\n"
|
||||||
|
"Gateway(name=mqttsn, status=unloaded)\n"
|
||||||
|
"Gateway(name=stomp, status=unloaded)\n"
|
||||||
|
, acc_print()).
|
||||||
|
|
||||||
|
t_gateway_load(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_gateway_unload(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_gateway_start(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_gateway_stop(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_gateway_clients_usage(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_gateway_clients_list(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_gateway_clients_lookup(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_gateway_clients_kick(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_gateway_metrcis_usage(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_gateway_metrcis(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
acc_print() ->
|
||||||
|
lists:concat(lists:reverse(acc_print([]))).
|
||||||
|
|
||||||
|
acc_print(Acc) ->
|
||||||
|
receive
|
||||||
|
{fmt, S} -> acc_print([S|Acc])
|
||||||
|
after 200 ->
|
||||||
|
Acc
|
||||||
|
end.
|
Loading…
Reference in New Issue