prop_webhook_confs.erl 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. -module(prop_webhook_confs).
  17. -include_lib("proper/include/proper.hrl").
  18. -import(emqx_ct_proper_types,
  19. [ url/0
  20. , nof/1
  21. ]).
  22. -define(ALL(Vars, Types, Exprs),
  23. ?SETUP(fun() ->
  24. State = do_setup(),
  25. fun() -> do_teardown(State) end
  26. end, ?FORALL(Vars, Types, Exprs))).
  27. %%--------------------------------------------------------------------
  28. %% Properties
  29. %%--------------------------------------------------------------------
  30. prop_confs() ->
  31. Schema = cuttlefish_schema:files(filelib:wildcard(code:priv_dir(emqx_web_hook) ++ "/*.schema")),
  32. ?ALL({Url, Confs0}, {url(), confs()},
  33. begin
  34. Confs = [{"web.hook.url", Url}|Confs0],
  35. Envs = cuttlefish_generator:map(Schema, cuttlefish_conf_file(Confs)),
  36. assert_confs(Confs, Envs),
  37. set_application_envs(Envs),
  38. {ok, _} = application:ensure_all_started(emqx_web_hook),
  39. application:stop(emqx_web_hook),
  40. unset_application_envs(Envs),
  41. true
  42. end).
  43. %%--------------------------------------------------------------------
  44. %% Helpers
  45. %%--------------------------------------------------------------------
  46. do_setup() ->
  47. logger:set_primary_config(#{level => warning}),
  48. emqx_ct_helpers:start_apps([], fun set_special_cfgs/1),
  49. ok.
  50. do_teardown(_) ->
  51. emqx_ct_helpers:stop_apps([]),
  52. logger:set_primary_config(#{level => info}),
  53. ok.
  54. set_special_cfgs(_) ->
  55. application:set_env(emqx, plugins_loaded_file, undefined),
  56. application:set_env(emqx, modules_loaded_file, undefined),
  57. ok.
  58. assert_confs([{"web.hook.url", Url}|More], Envs) ->
  59. %% Assert!
  60. Url = deep_get_env("emqx_web_hook.url", Envs),
  61. assert_confs(More, Envs);
  62. assert_confs([{"web.hook.rule." ++ HookName0, Spec}|More], Envs) ->
  63. HookName = re:replace(HookName0, "\\.[0-9]", "", [{return, list}]),
  64. Rules = deep_get_env("emqx_web_hook.rules", Envs),
  65. %% Assert!
  66. Spec = proplists:get_value(HookName, Rules),
  67. assert_confs(More, Envs);
  68. assert_confs([_|More], Envs) ->
  69. assert_confs(More, Envs);
  70. assert_confs([], _) ->
  71. true.
  72. deep_get_env(Path, Envs) ->
  73. lists:foldl(
  74. fun(_K, undefiend) -> undefiend;
  75. (K, Acc) -> proplists:get_value(binary_to_atom(K, utf8), Acc)
  76. end, Envs, re:split(Path, "\\.")).
  77. set_application_envs(Envs) ->
  78. application:set_env(Envs).
  79. unset_application_envs(Envs) ->
  80. lists:foreach(fun({App, Es}) ->
  81. lists:foreach(fun({K, _}) ->
  82. application:unset_env(App, K)
  83. end, Es) end, Envs).
  84. cuttlefish_conf_file(Ls) when is_list(Ls) ->
  85. [cuttlefish_conf_option(K,V) || {K, V} <- Ls].
  86. cuttlefish_conf_option(K, V)
  87. when is_list(K) ->
  88. {re:split(K, "[.]", [{return, list}]), V}.
  89. %%--------------------------------------------------------------------
  90. %% Generators
  91. %%--------------------------------------------------------------------
  92. confs() ->
  93. nof([{"web.hook.headers.content-type",
  94. oneof(["application/json"])},
  95. {"web.hook.body.encoding_of_payload_field",
  96. oneof(["plain", "base64", "base62"])},
  97. {"web.hook.rule.client.connect.1", rule_spec()},
  98. {"web.hook.rule.client.connack.1", rule_spec()},
  99. {"web.hook.rule.client.connected.1", rule_spec()},
  100. {"web.hook.rule.client.disconnected.1", rule_spec()},
  101. {"web.hook.rule.client.subscribe.1", rule_spec()},
  102. {"web.hook.rule.client.unsubscribe.1", rule_spec()},
  103. {"web.hook.rule.session.subscribed.1", rule_spec()},
  104. {"web.hook.rule.session.unsubscribed.1", rule_spec()},
  105. {"web.hook.rule.session.terminated.1", rule_spec()},
  106. {"web.hook.rule.message.publish.1", rule_spec()},
  107. {"web.hook.rule.message.delivered.1", rule_spec()},
  108. {"web.hook.rule.message.acked.1", rule_spec()}
  109. ]).
  110. rule_spec() ->
  111. ?LET(Action, action_names(),
  112. begin
  113. binary_to_list(emqx_json:encode(#{action => Action}))
  114. end).
  115. action_names() ->
  116. oneof([on_client_connect, on_client_connack, on_client_connected,
  117. on_client_connected, on_client_disconnected, on_client_subscribe, on_client_unsubscribe,
  118. on_session_subscribed, on_session_unsubscribed, on_session_terminated,
  119. on_message_publish, on_message_delivered, on_message_acked]).