From 306a732e5e6ee9d9dfaf59ac3d6cc7ce5c14c8d2 Mon Sep 17 00:00:00 2001 From: Thales Macedo Garitezi Date: Mon, 8 May 2023 14:00:23 -0300 Subject: [PATCH] test: perform sanity checks when starting apps These are checks to detect inter-suite or inter-testcase flakiness early. One suite might forget one application running and stop others, and then the `application:start/2' callback is never called again for this application. One example of this was that: i) `emqx_rule_engine` was left running by one suite; ii) `emqx` app was stopped, taking `emqx_config_handler` down with it and losing the rule engine handler; iii) another suite that uses rule engine "started" it (a no-op) and then the config handler was never installed again. --- apps/emqx/test/emqx_common_test_helpers.erl | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/apps/emqx/test/emqx_common_test_helpers.erl b/apps/emqx/test/emqx_common_test_helpers.erl index 61373f638..c8ef40925 100644 --- a/apps/emqx/test/emqx_common_test_helpers.erl +++ b/apps/emqx/test/emqx_common_test_helpers.erl @@ -251,6 +251,7 @@ start_app(App, SpecAppConfig, Opts) -> {ok, _} -> ok = ensure_dashboard_listeners_started(App), ok = wait_for_app_processes(App), + ok = perform_sanity_checks(App), ok; {error, Reason} -> error({failed_to_start_app, App, Reason}) @@ -264,6 +265,27 @@ wait_for_app_processes(emqx_conf) -> wait_for_app_processes(_) -> ok. +%% These are checks to detect inter-suite or inter-testcase flakiness +%% early. For example, one suite might forget one application running +%% and stop others, and then the `application:start/2' callback is +%% never called again for this application. +perform_sanity_checks(emqx_rule_engine) -> + ensure_config_handler(emqx_rule_engine, [rule_engine, rules]), + ok; +perform_sanity_checks(emqx_bridge) -> + ensure_config_handler(emqx_bridge, [bridges]), + ok; +perform_sanity_checks(_App) -> + ok. + +ensure_config_handler(Module, ConfigPath) -> + #{handlers := Handlers} = sys:get_state(emqx_config_handler), + case emqx_utils_maps:deep_get(ConfigPath, Handlers, not_found) of + #{{mod} := Module} -> ok; + _NotFound -> error({config_handler_missing, ConfigPath, Module}) + end, + ok. + app_conf_file(emqx_conf) -> "emqx.conf.all"; app_conf_file(App) -> atom_to_list(App) ++ ".conf".