test: add more test for cluster_rpc_handler/api_configs/api_trace

This commit is contained in:
Zhongwen Deng 2022-03-09 15:55:29 +08:00
parent 414d29c413
commit 0ec8c528a0
6 changed files with 159 additions and 11 deletions

View File

@ -38,6 +38,7 @@ start_link(MaxHistory, CleanupMs) ->
%%%=================================================================== %%%===================================================================
init([State]) -> init([State]) ->
erlang:process_flag(trap_exit, true),
{ok, ensure_timer(State)}. {ok, ensure_timer(State)}.
handle_call(Req, _From, State) -> handle_call(Req, _From, State) ->

View File

@ -225,6 +225,16 @@ t_fast_forward_commit(_Config) ->
tnx_ids(List2)), tnx_ids(List2)),
ok. ok.
t_handler_unexpected_msg(_Config) ->
Handler = emqx_cluster_rpc_handler,
OldPid = erlang:whereis(Handler),
ok = gen_server:cast(Handler, unexpected_cast_msg),
ignore = gen_server:call(Handler, unexpected_cast_msg),
erlang:send(Handler, unexpected_info_msg),
NewPid = erlang:whereis(Handler),
?assertEqual(OldPid, NewPid),
ok.
tnx_ids(Status) -> tnx_ids(Status) ->
lists:sort(lists:map(fun(#{tnx_id := TnxId, node := Node}) -> lists:sort(lists:map(fun(#{tnx_id := TnxId, node := Node}) ->
{Node, TnxId} end, Status)). {Node, TnxId} end, Status)).
@ -234,6 +244,7 @@ start() ->
{ok, Pid2} = emqx_cluster_rpc:start_link({node(), ?NODE2}, ?NODE2, 500), {ok, Pid2} = emqx_cluster_rpc:start_link({node(), ?NODE2}, ?NODE2, 500),
{ok, Pid3} = emqx_cluster_rpc:start_link({node(), ?NODE3}, ?NODE3, 500), {ok, Pid3} = emqx_cluster_rpc:start_link({node(), ?NODE3}, ?NODE3, 500),
{ok, Pid4} = emqx_cluster_rpc_handler:start_link(100, 500), {ok, Pid4} = emqx_cluster_rpc_handler:start_link(100, 500),
true = erlang:register(emqx_cluster_rpc_handler, Pid4),
{ok, [Pid1, Pid2, Pid3, Pid4]}. {ok, [Pid1, Pid2, Pid3, Pid4]}.
stop() -> stop() ->
@ -243,7 +254,8 @@ stop() ->
P -> P ->
erlang:unlink(P), erlang:unlink(P),
erlang:exit(P, kill) erlang:exit(P, kill)
end end || N <- [?NODE1, ?NODE2, ?NODE3]]. end end || N <- [?NODE1, ?NODE2, ?NODE3]],
gen_server:stop(emqx_cluster_rpc_handler, normal, 5000).
receive_msg(0, _Msg) -> ok; receive_msg(0, _Msg) -> ok;
receive_msg(Count, Msg) when Count > 0 -> receive_msg(Count, Msg) when Count > 0 ->

View File

@ -145,13 +145,8 @@ fields(Field) -> emqx_conf_schema:fields(Field).
%% HTTP API Callbacks %% HTTP API Callbacks
config(get, _Params, Req) -> config(get, _Params, Req) ->
Path = conf_path(Req), Path = conf_path(Req),
case emqx_map_lib:deep_find(Path, get_full_config()) of {ok, Conf} = emqx_map_lib:deep_find(Path, get_full_config()),
{ok, Conf} -> {200, Conf};
{200, Conf};
{not_found, _, _} ->
{404, #{code => 'NOT_FOUND',
message => <<(list_to_binary(Path))/binary, " not found">>}}
end;
config(put, #{body := Body}, Req) -> config(put, #{body := Body}, Req) ->
Path = conf_path(Req), Path = conf_path(Req),
@ -195,7 +190,9 @@ conf_path_reset(Req) ->
string:lexemes(Path, "/ "). string:lexemes(Path, "/ ").
get_full_config() -> get_full_config() ->
emqx_config:fill_defaults(emqx:get_raw_config([])). emqx_config:fill_defaults(
maps:without(?EXCLUDES,
emqx:get_raw_config([]))).
conf_path_from_querystr(Req) -> conf_path_from_querystr(Req) ->
case proplists:get_value(<<"conf_path">>, cowboy_req:parse_qs(Req)) of case proplists:get_value(<<"conf_path">>, cowboy_req:parse_qs(Req)) of

View File

@ -67,7 +67,10 @@ schema("/trace") ->
description => "Create new trace", description => "Create new trace",
'requestBody' => delete([status, log_size], fields(trace)), 'requestBody' => delete([status, log_size], fields(trace)),
responses => #{ responses => #{
200 => hoconsc:ref(trace) 200 => hoconsc:ref(trace),
400 => emqx_dashboard_swagger:error_codes(['ALREADY_EXISTS',
'DUPLICATE_CONDITION', 'INVALID_PARAMS'],
<<"trace name already exists">>)
} }
}, },
delete => #{ delete => #{
@ -274,7 +277,7 @@ trace(post, #{body := Param}) ->
}}; }};
{error, Reason} -> {error, Reason} ->
{400, #{ {400, #{
code => 'INCORRECT_PARAMS', code => 'INVALID_PARAMS',
message => ?TO_BIN(Reason) message => ?TO_BIN(Reason)
}} }}
end; end;

View File

@ -0,0 +1,100 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020-2022 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_mgmt_api_configs_SUITE).
-compile(export_all).
-compile(nowarn_export_all).
-include_lib("eunit/include/eunit.hrl").
all() ->
emqx_common_test_helpers:all(?MODULE).
init_per_suite(Config) ->
emqx_mgmt_api_test_util:init_suite(),
Config.
end_per_suite(_) ->
emqx_mgmt_api_test_util:end_suite().
t_get(_Config) ->
{ok, Configs} = get_configs(),
maps:map(fun(Name, Value) ->
{ok, Config} = get_config(Name),
?assertEqual(Value, Config)
end, Configs),
ok.
t_update(_Config) ->
%% update ok
{ok, SysMon} = get_config(<<"sysmon">>),
#{<<"vm">> := #{<<"busy_port">> := BusyPort}} = SysMon,
NewSysMon = emqx_map_lib:deep_put([<<"vm">>, <<"busy_port">>], SysMon, not BusyPort),
{ok, #{}} = update_config(<<"sysmon">>, NewSysMon),
{ok, SysMon1} = get_config(<<"sysmon">>),
#{<<"vm">> := #{<<"busy_port">> := BusyPort1}} = SysMon1,
?assertEqual(BusyPort, not BusyPort1),
%% update failed
ErrorSysMon = emqx_map_lib:deep_put([<<"vm">>, <<"busy_port">>], SysMon, "123"),
?assertMatch({error, {"HTTP/1.1", 400, _}},
update_config(<<"sysmon">>, ErrorSysMon)),
{ok, SysMon2} = get_config(<<"sysmon">>),
?assertEqual(SysMon1, SysMon2),
%% reset specific config
ok = reset_config(<<"sysmon">>, "conf_path=vm.busy_port"),
{ok, SysMon3} = get_config(<<"sysmon">>),
?assertMatch(#{<<"vm">> := #{<<"busy_port">> := true}}, SysMon3),
%% reset no_default_value config
NewSysMon1 = emqx_map_lib:deep_put([<<"vm">>, <<"busy_port">>], SysMon, false),
{ok, #{}} = update_config(<<"sysmon">>, NewSysMon1),
?assertMatch({error, {"HTTP/1.1", 400, _}}, reset_config(<<"sysmon">>, "")),
{ok, SysMon4} = get_config(<<"sysmon">>),
?assertMatch(#{<<"vm">> := #{<<"busy_port">> := false}}, SysMon4),
ok.
get_config(Name) ->
Path = emqx_mgmt_api_test_util:api_path(["configs", Name]),
case emqx_mgmt_api_test_util:request_api(get, Path) of
{ok, Res} ->
{ok, emqx_json:decode(Res, [return_maps])};
Error -> Error
end.
get_configs() ->
Path = emqx_mgmt_api_test_util:api_path(["configs"]),
case emqx_mgmt_api_test_util:request_api(get, Path) of
{ok, Res} -> {ok, emqx_json:decode(Res, [return_maps])};
Error -> Error
end.
update_config(Name, Change) ->
AuthHeader = emqx_mgmt_api_test_util:auth_header_(),
UpdatePath = emqx_mgmt_api_test_util:api_path(["configs", Name]),
case emqx_mgmt_api_test_util:request_api(put, UpdatePath, "", AuthHeader, Change) of
{ok, Update} -> {ok, emqx_json:decode(Update, [return_maps])};
Error -> Error
end.
reset_config(Name, Key) ->
AuthHeader = emqx_mgmt_api_test_util:auth_header_(),
Path = binary_to_list(iolist_to_binary(emqx_mgmt_api_test_util:api_path(["configs_reset", Name]))),
case emqx_mgmt_api_test_util:request_api(post, Path, Key, AuthHeader, []) of
{ok, []} -> ok;
Error -> Error
end.

View File

@ -80,6 +80,8 @@ t_http_test(_Config) ->
?assertEqual(#{<<"enable">> => false, ?assertEqual(#{<<"enable">> => false,
<<"name">> => <<"test-name">>}, json(Update)), <<"name">> => <<"test-name">>}, json(Update)),
?assertMatch({error, {"HTTP/1.1", 404, _}, _},
request_api(put, api_path("trace/test-name-not-found/stop"), Header, #{})),
{ok, List1} = request_api(get, api_path("trace"), Header), {ok, List1} = request_api(get, api_path("trace"), Header),
[Data1] = json(List1), [Data1] = json(List1),
Node = atom_to_binary(node()), Node = atom_to_binary(node()),
@ -115,6 +117,39 @@ t_http_test(_Config) ->
unload(), unload(),
ok. ok.
t_create_failed(_Config) ->
load(),
Header = auth_header_(),
Trace = [{<<"type">>, <<"topic">>}, {<<"topic">>, <<"/x/y/z">>}],
BadName1 = {<<"name">>, <<"test/bad">>},
?assertMatch({error, {"HTTP/1.1", 400, _}, _},
request_api(post, api_path("trace"), Header, [BadName1 | Trace])),
BadName2 = {<<"name">>, list_to_binary(lists:duplicate(257, "t"))},
?assertMatch({error, {"HTTP/1.1", 400, _}, _},
request_api(post, api_path("trace"), Header, [BadName2 | Trace])),
%% already_exist
GoodName = {<<"name">>, <<"test-name-0">>},
{ok, Create} = request_api(post, api_path("trace"), Header, [GoodName | Trace]),
?assertMatch(#{<<"name">> := <<"test-name-0">>}, json(Create)),
?assertMatch({error, {"HTTP/1.1", 400, _}, _},
request_api(post, api_path("trace"), Header, [GoodName | Trace])),
%% MAX Limited
lists:map(fun(Seq) ->
Name0 = list_to_binary("name" ++ integer_to_list(Seq)),
Trace0 = [{name, Name0}, {type, topic},
{topic, list_to_binary("/x/y/" ++ integer_to_list(Seq))}],
{ok, _} = emqx_trace:create(Trace0)
end, lists:seq(1, 30 - ets:info(emqx_trace, size))),
GoodName1 = {<<"name">>, <<"test-name-1">>},
?assertMatch({error, {"HTTP/1.1", 400, _}, _},
request_api(post, api_path("trace"), Header, [GoodName1 | Trace])),
unload(),
emqx_trace:clear(),
ok.
t_download_log(_Config) -> t_download_log(_Config) ->
ClientId = <<"client-test-download">>, ClientId = <<"client-test-download">>,
Now = erlang:system_time(second), Now = erlang:system_time(second),