234 lines
7.5 KiB
Erlang
234 lines
7.5 KiB
Erlang
%%--------------------------------------------------------------------
|
|
%% Copyright (c) 2020-2024 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_prometheus_SUITE).
|
|
|
|
-include_lib("stdlib/include/assert.hrl").
|
|
-include_lib("common_test/include/ct.hrl").
|
|
|
|
-compile(nowarn_export_all).
|
|
-compile(export_all).
|
|
|
|
-define(CLUSTER_RPC_SHARD, emqx_cluster_rpc_shard).
|
|
%% erlfmt-ignore
|
|
-define(LEGACY_CONF_DEFAULT, <<"
|
|
prometheus {
|
|
push_gateway_server = \"http://127.0.0.1:9091\"
|
|
interval = \"1s\"
|
|
headers = { Authorization = \"some-authz-tokens\"}
|
|
job_name = \"${name}~${host}\"
|
|
enable = true
|
|
vm_dist_collector = disabled
|
|
mnesia_collector = disabled
|
|
vm_statistics_collector = disabled
|
|
vm_system_info_collector = disabled
|
|
vm_memory_collector = disabled
|
|
vm_msacc_collector = disabled
|
|
}
|
|
">>).
|
|
|
|
-define(CONF_DEFAULT, #{
|
|
<<"prometheus">> =>
|
|
#{
|
|
<<"enable_basic_auth">> => false,
|
|
<<"collectors">> =>
|
|
#{
|
|
<<"mnesia">> => <<"disabled">>,
|
|
<<"vm_dist">> => <<"disabled">>,
|
|
<<"vm_memory">> => <<"disabled">>,
|
|
<<"vm_msacc">> => <<"disabled">>,
|
|
<<"vm_statistics">> => <<"disabled">>,
|
|
<<"vm_system_info">> => <<"disabled">>
|
|
},
|
|
<<"push_gateway">> =>
|
|
#{
|
|
<<"enable">> => true,
|
|
<<"headers">> => #{<<"Authorization">> => <<"some-authz-tokens">>},
|
|
<<"interval">> => <<"1s">>,
|
|
<<"job_name">> => <<"${name}~${host}">>,
|
|
<<"url">> => <<"http://127.0.0.1:9091">>
|
|
}
|
|
}
|
|
}).
|
|
|
|
%%--------------------------------------------------------------------
|
|
%% Setups
|
|
%%--------------------------------------------------------------------
|
|
all() ->
|
|
[
|
|
{group, new_config},
|
|
{group, legacy_config}
|
|
].
|
|
|
|
groups() ->
|
|
[
|
|
{new_config, [sequence], common_tests()},
|
|
{legacy_config, [sequence], common_tests()}
|
|
].
|
|
|
|
suite() ->
|
|
[{timetrap, {seconds, 60}}].
|
|
|
|
common_tests() ->
|
|
emqx_common_test_helpers:all(?MODULE).
|
|
|
|
init_per_group(new_config, Config) ->
|
|
Apps = emqx_cth_suite:start(
|
|
[
|
|
%% coverage olp metrics
|
|
{emqx, "overload_protection.enable = true"},
|
|
{emqx_license, "license.key = default"},
|
|
{emqx_prometheus, #{config => config(default)}}
|
|
],
|
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
|
),
|
|
[{suite_apps, Apps} | Config];
|
|
init_per_group(legacy_config, Config) ->
|
|
Apps = emqx_cth_suite:start(
|
|
[
|
|
{emqx, "overload_protection.enable = false"},
|
|
{emqx_license, "license.key = default"},
|
|
{emqx_prometheus, #{config => config(legacy)}}
|
|
],
|
|
#{work_dir => emqx_cth_suite:work_dir(Config)}
|
|
),
|
|
[{suite_apps, Apps} | Config].
|
|
|
|
end_per_group(_Group, Config) ->
|
|
ok = emqx_cth_suite:stop(?config(suite_apps, Config)).
|
|
|
|
init_per_testcase(t_assert_push, Config) ->
|
|
meck:new(httpc, [passthrough]),
|
|
Config;
|
|
init_per_testcase(t_push_gateway, Config) ->
|
|
start_mock_pushgateway(9091),
|
|
Config;
|
|
init_per_testcase(_Testcase, Config) ->
|
|
Config.
|
|
|
|
end_per_testcase(t_push_gateway, Config) ->
|
|
stop_mock_pushgateway(),
|
|
Config;
|
|
end_per_testcase(t_assert_push, _Config) ->
|
|
meck:unload(httpc),
|
|
ok;
|
|
end_per_testcase(_Testcase, _Config) ->
|
|
ok.
|
|
|
|
config(default) ->
|
|
?CONF_DEFAULT;
|
|
config(legacy) ->
|
|
?LEGACY_CONF_DEFAULT.
|
|
|
|
conf_default() ->
|
|
?CONF_DEFAULT.
|
|
|
|
legacy_conf_default() ->
|
|
?LEGACY_CONF_DEFAULT.
|
|
|
|
-if(?EMQX_RELEASE_EDITION == ee).
|
|
maybe_meck_license() ->
|
|
meck:new(emqx_license_checker, [non_strict, passthrough, no_link]),
|
|
meck:expect(emqx_license_checker, expiry_epoch, fun() -> 1859673600 end).
|
|
maybe_unmeck_license() ->
|
|
meck:unload(emqx_license_checker).
|
|
-else.
|
|
maybe_meck_license() -> ok.
|
|
maybe_unmeck_license() -> ok.
|
|
-endif.
|
|
%%--------------------------------------------------------------------
|
|
%% Test cases
|
|
%%--------------------------------------------------------------------
|
|
|
|
t_start_stop(_) ->
|
|
App = emqx_prometheus,
|
|
Conf = emqx_prometheus_config:conf(),
|
|
?assertMatch(ok, emqx_prometheus_sup:start_child(App, Conf)),
|
|
%% start twice return ok.
|
|
?assertMatch(ok, emqx_prometheus_sup:start_child(App, Conf)),
|
|
ok = gen_server:call(emqx_prometheus, dump, 1000),
|
|
ok = gen_server:cast(emqx_prometheus, dump),
|
|
dump = erlang:send(emqx_prometheus, dump),
|
|
?assertMatch(ok, emqx_prometheus_sup:stop_child(App)),
|
|
%% stop twice return ok.
|
|
?assertMatch(ok, emqx_prometheus_sup:stop_child(App)),
|
|
%% wait the interval timer trigger
|
|
timer:sleep(2000).
|
|
|
|
t_collector_no_crash_test(_) ->
|
|
prometheus_text_format:format(),
|
|
ok.
|
|
|
|
t_assert_push(_) ->
|
|
Self = self(),
|
|
AssertPush = fun(Method, Req = {Url, Headers, ContentType, _Data}, HttpOpts, Opts) ->
|
|
?assertEqual(post, Method),
|
|
?assertMatch("http://127.0.0.1:9091/metrics/job/test~127.0.0.1", Url),
|
|
?assertEqual([{"Authorization", "some-authz-tokens"}], Headers),
|
|
?assertEqual("text/plain", ContentType),
|
|
Self ! pass,
|
|
meck:passthrough([Method, Req, HttpOpts, Opts])
|
|
end,
|
|
meck:expect(httpc, request, AssertPush),
|
|
Conf = emqx_prometheus_config:conf(),
|
|
?assertMatch(ok, emqx_prometheus_sup:start_child(emqx_prometheus, Conf)),
|
|
receive
|
|
pass -> ok
|
|
after 2000 ->
|
|
ct:fail(assert_push_request_failed)
|
|
end.
|
|
|
|
t_push_gateway(_) ->
|
|
Conf = emqx_prometheus_config:conf(),
|
|
?assertMatch(ok, emqx_prometheus_sup:stop_child(emqx_prometheus)),
|
|
?assertMatch(ok, emqx_prometheus_sup:start_child(emqx_prometheus, Conf)),
|
|
?assertMatch(#{ok := 0, failed := 0}, emqx_prometheus:info()),
|
|
timer:sleep(1100),
|
|
?assertMatch(#{ok := 1, failed := 0}, emqx_prometheus:info()),
|
|
ok = emqx_prometheus_sup:update_child(emqx_prometheus, Conf),
|
|
?assertMatch(#{ok := 0, failed := 0}, emqx_prometheus:info()),
|
|
|
|
ok.
|
|
|
|
start_mock_pushgateway(Port) ->
|
|
application:ensure_all_started(cowboy),
|
|
Dispatch = cowboy_router:compile([{'_', [{'_', ?MODULE, []}]}]),
|
|
{ok, _} = cowboy:start_clear(
|
|
mock_pushgateway_listener,
|
|
[{port, Port}],
|
|
#{env => #{dispatch => Dispatch}}
|
|
).
|
|
|
|
stop_mock_pushgateway() ->
|
|
cowboy:stop_listener(mock_pushgateway_listener).
|
|
|
|
init(Req0, Opts) ->
|
|
Method = cowboy_req:method(Req0),
|
|
Headers = cowboy_req:headers(Req0),
|
|
?assertEqual(<<"POST">>, Method),
|
|
?assertMatch(
|
|
#{
|
|
<<"authorization">> := <<"some-authz-tokens">>,
|
|
<<"content-length">> := _,
|
|
<<"content-type">> := <<"text/plain">>,
|
|
<<"host">> := <<"127.0.0.1:9091">>
|
|
},
|
|
Headers
|
|
),
|
|
RespHeader = #{<<"content-type">> => <<"text/plain; charset=utf-8">>},
|
|
Req = cowboy_req:reply(200, RespHeader, <<"OK">>, Req0),
|
|
{ok, Req, Opts}.
|