emqx/apps/emqx_web_hook/test/props/prop_webhook_confs.erl

147 lines
5.0 KiB
Erlang

%%--------------------------------------------------------------------
%% Copyright (c) 2020-2023 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(prop_webhook_confs).
-include_lib("proper/include/proper.hrl").
-import(emqx_ct_proper_types,
[ url/0
, nof/1
]).
-define(ALL(Vars, Types, Exprs),
?SETUP(fun() ->
State = do_setup(),
fun() -> do_teardown(State) end
end, ?FORALL(Vars, Types, Exprs))).
%%--------------------------------------------------------------------
%% Properties
%%--------------------------------------------------------------------
prop_confs() ->
Schema = cuttlefish_schema:files(filelib:wildcard(code:priv_dir(emqx_web_hook) ++ "/*.schema")),
?ALL({Url, Confs0}, {url(), confs()},
begin
Confs = [{"web.hook.url", Url}|Confs0],
Envs = cuttlefish_generator:map(Schema, cuttlefish_conf_file(Confs)),
assert_confs(Confs, Envs),
set_application_envs(Envs),
{ok, _} = application:ensure_all_started(emqx_web_hook),
application:stop(emqx_web_hook),
unset_application_envs(Envs),
true
end).
%%--------------------------------------------------------------------
%% Helpers
%%--------------------------------------------------------------------
do_setup() ->
logger:set_primary_config(#{level => warning}),
emqx_ct_helpers:start_apps([], fun set_special_cfgs/1),
ok.
do_teardown(_) ->
emqx_ct_helpers:stop_apps([]),
logger:set_primary_config(#{level => info}),
ok.
set_special_cfgs(_) ->
application:set_env(emqx, plugins_loaded_file, undefined),
application:set_env(emqx, modules_loaded_file, undefined),
ok.
assert_confs([{"web.hook.url", Url}|More], Envs) ->
%% Assert!
Url = deep_get_env("emqx_web_hook.url", Envs),
assert_confs(More, Envs);
assert_confs([{"web.hook.rule." ++ HookName0, Spec}|More], Envs) ->
HookName = re:replace(HookName0, "\\.[0-9]", "", [{return, list}]),
Rules = deep_get_env("emqx_web_hook.rules", Envs),
%% Assert!
Spec = proplists:get_value(HookName, Rules),
assert_confs(More, Envs);
assert_confs([_|More], Envs) ->
assert_confs(More, Envs);
assert_confs([], _) ->
true.
deep_get_env(Path, Envs) ->
lists:foldl(
fun(_K, undefiend) -> undefiend;
(K, Acc) -> proplists:get_value(binary_to_atom(K, utf8), Acc)
end, Envs, re:split(Path, "\\.")).
set_application_envs(Envs) ->
application:set_env(Envs).
unset_application_envs(Envs) ->
lists:foreach(fun({App, Es}) ->
lists:foreach(fun({K, _}) ->
application:unset_env(App, K)
end, Es) end, Envs).
cuttlefish_conf_file(Ls) when is_list(Ls) ->
[cuttlefish_conf_option(K,V) || {K, V} <- Ls].
cuttlefish_conf_option(K, V)
when is_list(K) ->
{re:split(K, "[.]", [{return, list}]), V}.
%%--------------------------------------------------------------------
%% Generators
%%--------------------------------------------------------------------
confs() ->
nof([{"web.hook.headers.content-type",
oneof(["application/json"])},
{"web.hook.body.encoding_of_payload_field",
oneof(["plain", "base64", "base62"])},
{"web.hook.rule.client.connect.1", rule_spec()},
{"web.hook.rule.client.connack.1", rule_spec()},
{"web.hook.rule.client.connected.1", rule_spec()},
{"web.hook.rule.client.disconnected.1", rule_spec()},
{"web.hook.rule.client.subscribe.1", rule_spec()},
{"web.hook.rule.client.unsubscribe.1", rule_spec()},
{"web.hook.rule.session.subscribed.1", rule_spec()},
{"web.hook.rule.session.unsubscribed.1", rule_spec()},
{"web.hook.rule.session.terminated.1", rule_spec()},
{"web.hook.rule.message.publish.1", rule_spec()},
{"web.hook.rule.message.delivered.1", rule_spec()},
{"web.hook.rule.message.acked.1", rule_spec()}
]).
rule_spec() ->
?LET(Action, action_names(),
begin
binary_to_list(emqx_json:encode(#{action => Action}))
end).
action_names() ->
oneof([on_client_connect, on_client_connack, on_client_connected,
on_client_connected, on_client_disconnected, on_client_subscribe, on_client_unsubscribe,
on_session_subscribed, on_session_unsubscribed, on_session_terminated,
on_message_publish, on_message_delivered, on_message_acked]).