From bf57bf717c000a501a7df6df7267e2a5186feb99 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 23 Feb 2022 18:37:34 +0800 Subject: [PATCH 01/10] feat(emqx_resource_instance): add wait_connected Opts --- apps/emqx_resource/src/emqx_resource_instance.erl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/emqx_resource/src/emqx_resource_instance.erl b/apps/emqx_resource/src/emqx_resource_instance.erl index 115f8426a..e08c57467 100644 --- a/apps/emqx_resource/src/emqx_resource_instance.erl +++ b/apps/emqx_resource/src/emqx_resource_instance.erl @@ -178,6 +178,16 @@ do_recreate(InstId, ResourceType, NewConfig, Opts) -> {error, not_found} end. +wait_for_resource_ready(InstId, 0) -> + force_lookup(InstId); +wait_for_resource_ready(InstId, Retry) -> + case force_lookup(InstId) of + #{resource_data := #{status := connected}} = Data -> Data; + _ -> + timer:sleep(100), + wait_for_resource_ready(InstId, Retry-1) + end. + do_create(InstId, Group, ResourceType, Config, Opts) -> case lookup(InstId) of {ok,_, _} -> @@ -187,7 +197,8 @@ do_create(InstId, Group, ResourceType, Config, Opts) -> ok -> ok = emqx_plugin_libs_metrics:create_metrics(resource_metrics, InstId, [matched, success, failed, exception], [matched]), - {ok, force_lookup(InstId)}; + WaitTime = maps:get(wait_connected, Opts, 0), + {ok, wait_for_resource_ready(InstId, WaitTime div 100)}; Error -> Error end From f29877bb6a17dd2b0615b038c9b59b9913aeb54d Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Fri, 25 Feb 2022 11:18:21 +0800 Subject: [PATCH 02/10] fix(emqx_resource): remove create_opts async_create --- apps/emqx_bridge/src/emqx_bridge.erl | 8 ++--- .../test/emqx_bridge_api_SUITE.erl | 13 -------- apps/emqx_resource/include/emqx_resource.hrl | 7 ++-- apps/emqx_resource/src/emqx_resource.erl | 6 ++-- .../src/emqx_resource_health_check.erl | 2 +- .../src/emqx_resource_instance.erl | 33 +++++++------------ .../test/emqx_resource_SUITE.erl | 11 +++---- 7 files changed, 26 insertions(+), 54 deletions(-) diff --git a/apps/emqx_bridge/src/emqx_bridge.erl b/apps/emqx_bridge/src/emqx_bridge.erl index e56b694d5..2d40c997b 100644 --- a/apps/emqx_bridge/src/emqx_bridge.erl +++ b/apps/emqx_bridge/src/emqx_bridge.erl @@ -224,9 +224,8 @@ create(BridgeId, Conf) -> create(Type, Name, Conf) -> ?SLOG(info, #{msg => "create bridge", type => Type, name => Name, config => Conf}), - case emqx_resource:create_local(resource_id(Type, Name), <<"emqx_bridge">>, - emqx_bridge:resource_type(Type), - parse_confs(Type, Name, Conf), #{async_create => true}) of + case emqx_resource:create_local(resource_id(Type, Name), <<"emqx_bridge">>, emqx_bridge:resource_type(Type), + parse_confs(Type, Name, Conf), #{wait_connected => 1000}) of {ok, already_created} -> maybe_disable_bridge(Type, Name, Conf); {ok, _} -> maybe_disable_bridge(Type, Name, Conf); {error, Reason} -> {error, Reason} @@ -271,8 +270,7 @@ recreate(Type, Name) -> recreate(Type, Name, Conf) -> emqx_resource:recreate_local(resource_id(Type, Name), - emqx_bridge:resource_type(Type), parse_confs(Type, Name, Conf), - #{async_create => true}). + emqx_bridge:resource_type(Type), parse_confs(Type, Name, Conf), #{wait_connected => 1000}). create_dry_run(Type, Conf) -> Conf0 = Conf#{<<"ingress">> => #{<<"remote_topic">> => <<"t">>}}, diff --git a/apps/emqx_bridge/test/emqx_bridge_api_SUITE.erl b/apps/emqx_bridge/test/emqx_bridge_api_SUITE.erl index 65a369a3d..47dc55f6d 100644 --- a/apps/emqx_bridge/test/emqx_bridge_api_SUITE.erl +++ b/apps/emqx_bridge/test/emqx_bridge_api_SUITE.erl @@ -164,7 +164,6 @@ t_http_crud_apis(_) -> BridgeID = emqx_bridge:bridge_id(?BRIDGE_TYPE, ?BRIDGE_NAME), %% send an message to emqx and the message should be forwarded to the HTTP server - wait_for_resource_ready(BridgeID, 5), Body = <<"my msg">>, emqx:publish(emqx_message:make(<<"emqx_http/1">>, Body)), ?assert( @@ -214,7 +213,6 @@ t_http_crud_apis(_) -> }, jsx:decode(Bridge3Str)), %% send an message to emqx again, check the path has been changed - wait_for_resource_ready(BridgeID, 5), emqx:publish(emqx_message:make(<<"emqx_http/1">>, Body)), ?assert( receive @@ -319,14 +317,3 @@ auth_header_() -> operation_path(Oper, BridgeID) -> uri(["bridges", BridgeID, "operation", Oper]). - -wait_for_resource_ready(InstId, 0) -> - ct:pal("--- bridge ~p: ~p", [InstId, emqx_bridge:lookup(InstId)]), - ct:fail(wait_resource_timeout); -wait_for_resource_ready(InstId, Retry) -> - case emqx_bridge:lookup(InstId) of - {ok, #{resource_data := #{status := connected}}} -> ok; - _ -> - timer:sleep(100), - wait_for_resource_ready(InstId, Retry-1) - end. diff --git a/apps/emqx_resource/include/emqx_resource.hrl b/apps/emqx_resource/include/emqx_resource.hrl index 78aae4313..cd10f9fa4 100644 --- a/apps/emqx_resource/include/emqx_resource.hrl +++ b/apps/emqx_resource/include/emqx_resource.hrl @@ -30,10 +30,9 @@ }. -type resource_group() :: binary(). -type create_opts() :: #{ - %% The emqx_resource:create/4 will return OK event if the Mod:on_start/2 fails, - %% the 'status' of the resource will be 'stopped' in this case. - %% Defaults to 'false' - async_create => boolean() + health_check_interval => integer(), + health_check_timeout => integer(), + wait_connected => integer() }. -type after_query() :: {[OnSuccess :: after_query_fun()], [OnFailed :: after_query_fun()]} | undefined. diff --git a/apps/emqx_resource/src/emqx_resource.erl b/apps/emqx_resource/src/emqx_resource.erl index 770ba8fa1..5957222cb 100644 --- a/apps/emqx_resource/src/emqx_resource.erl +++ b/apps/emqx_resource/src/emqx_resource.erl @@ -60,7 +60,7 @@ -export([ restart/1 %% restart the instance. , restart/2 , health_check/1 %% verify if the resource is working normally - , set_resource_status_disconnected/1 %% set resource status to disconnected + , set_resource_status_connecting/1 %% set resource status to disconnected , stop/1 %% stop the instance , query/2 %% query the instance , query/3 %% query the instance with after_query() @@ -225,8 +225,8 @@ stop(InstId) -> health_check(InstId) -> call_instance(InstId, {health_check, InstId}). -set_resource_status_disconnected(InstId) -> - call_instance(InstId, {set_resource_status_disconnected, InstId}). +set_resource_status_connecting(InstId) -> + call_instance(InstId, {set_resource_status_connecting, InstId}). -spec get_instance(instance_id()) -> {ok, resource_group(), resource_data()} | {error, Reason :: term()}. get_instance(InstId) -> diff --git a/apps/emqx_resource/src/emqx_resource_health_check.erl b/apps/emqx_resource/src/emqx_resource_health_check.erl index 801c9d02f..6d4abc9cc 100644 --- a/apps/emqx_resource/src/emqx_resource_health_check.erl +++ b/apps/emqx_resource/src/emqx_resource_health_check.erl @@ -83,7 +83,7 @@ health_check_timeout_checker(Pid, Name, SleepTime, Timeout) -> after Timeout -> emqx_alarm:activate(Name, #{name => Name}, <>), - emqx_resource:set_resource_status_disconnected(Name), + emqx_resource:set_resource_status_connecting(Name), receive health_check_finish -> timer:sleep(SleepTime) end diff --git a/apps/emqx_resource/src/emqx_resource_instance.erl b/apps/emqx_resource/src/emqx_resource_instance.erl index e08c57467..a3631d337 100644 --- a/apps/emqx_resource/src/emqx_resource_instance.erl +++ b/apps/emqx_resource/src/emqx_resource_instance.erl @@ -126,8 +126,8 @@ handle_call({stop, InstId}, _From, State) -> handle_call({health_check, InstId}, _From, State) -> {reply, do_health_check(InstId), State}; -handle_call({set_resource_status_disconnected, InstId}, _From, State) -> - {reply, do_set_resource_status_disconnected(InstId), State}; +handle_call({set_resource_status_connecting, InstId}, _From, State) -> + {reply, do_set_resource_status_connecting(InstId), State}; handle_call(Req, _From, State) -> logger:error("Received unexpected call: ~p", [Req]), @@ -249,28 +249,17 @@ do_start(InstId, Group, ResourceType, Config, Opts) when is_binary(InstId) -> status => connecting, state => undefined}, %% The `emqx_resource:call_start/3` need the instance exist beforehand ets:insert(emqx_resource_instance, {InstId, Group, InitData}), - case maps:get(async_create, Opts, false) of - false -> - start_and_check(InstId, Group, ResourceType, Config, Opts, InitData); - true -> - spawn(fun() -> - start_and_check(InstId, Group, ResourceType, Config, Opts, InitData) - end), - ok - end. + spawn(fun() -> + start_and_check(InstId, Group, ResourceType, Config, Opts, InitData) + end), + ok. start_and_check(InstId, Group, ResourceType, Config, Opts, Data) -> case emqx_resource:call_start(InstId, ResourceType, Config) of {ok, ResourceState} -> - Data2 = Data#{state => ResourceState}, + Data2 = Data#{state => ResourceState, status => connected}, ets:insert(emqx_resource_instance, {InstId, Group, Data2}), - case maps:get(async_create, Opts, false) of - false -> case do_health_check(Group, Data2) of - ok -> create_default_checker(InstId, Opts); - {error, Reason} -> {error, Reason} - end; - true -> create_default_checker(InstId, Opts) - end; + create_default_checker(InstId, Opts); {error, Reason} -> ets:insert(emqx_resource_instance, {InstId, Group, Data#{status => disconnected}}), {error, Reason} @@ -306,15 +295,15 @@ do_health_check(Group, #{id := InstId, mod := Mod, state := ResourceState0} = Da {error, Reason, ResourceState1} -> logger:error("health check for ~p failed: ~p", [InstId, Reason]), ets:insert(emqx_resource_instance, - {InstId, Group, Data#{status => disconnected, state => ResourceState1}}), + {InstId, Group, Data#{status => connecting, state => ResourceState1}}), {error, Reason} end. -do_set_resource_status_disconnected(InstId) -> +do_set_resource_status_connecting(InstId) -> case emqx_resource_instance:lookup(InstId) of {ok, Group, #{id := InstId} = Data} -> logger:error("health check for ~p failed: timeout", [InstId]), - ets:insert(emqx_resource_instance, {InstId, Group, Data#{status => disconnected}}); + ets:insert(emqx_resource_instance, {InstId, Group, Data#{status => connecting}}); Error -> {error, Error} end. diff --git a/apps/emqx_resource/test/emqx_resource_SUITE.erl b/apps/emqx_resource/test/emqx_resource_SUITE.erl index f0a2efcf8..4a40ce55a 100644 --- a/apps/emqx_resource/test/emqx_resource_SUITE.erl +++ b/apps/emqx_resource/test/emqx_resource_SUITE.erl @@ -107,7 +107,7 @@ t_create_remove_local(_) -> ?assert(is_process_alive(Pid)), - emqx_resource:set_resource_status_disconnected(?ID), + emqx_resource:set_resource_status_connecting(?ID), emqx_resource:recreate_local( ?ID, @@ -153,7 +153,7 @@ t_healthy_timeout(_) -> ?DEFAULT_RESOURCE_GROUP, ?TEST_RESOURCE, #{name => <<"test_resource">>}, - #{async_create => true, health_check_timeout => 200}), + #{health_check_timeout => 200}), timer:sleep(500), ok = emqx_resource:remove_local(?ID). @@ -163,14 +163,13 @@ t_healthy(_) -> ?ID, ?DEFAULT_RESOURCE_GROUP, ?TEST_RESOURCE, - #{name => <<"test_resource">>}, - #{async_create => true}), + #{name => <<"test_resource">>}), timer:sleep(400), emqx_resource_health_check:create_checker(?ID, 15000, 10000), #{pid := Pid} = emqx_resource:query(?ID, get_state), timer:sleep(300), - emqx_resource:set_resource_status_disconnected(?ID), + emqx_resource:set_resource_status_connecting(?ID), ok = emqx_resource:health_check(?ID), @@ -185,7 +184,7 @@ t_healthy(_) -> emqx_resource:health_check(?ID)), ?assertMatch( - [#{status := disconnected}], + [#{status := connecting}], emqx_resource:list_instances_verbose()), ok = emqx_resource:remove_local(?ID). From d99db4ebfaa5698609a8c6980db98c65fc9acb76 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Mon, 28 Feb 2022 16:41:27 +0800 Subject: [PATCH 03/10] fix(emqx_authn): add default wait_connected --- apps/emqx_authn/src/simple_authn/emqx_authn_http.erl | 3 ++- apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl | 2 +- apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl | 2 +- apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl | 4 +++- apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl | 4 +++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl index 002723b75..863a1d936 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl @@ -133,7 +133,8 @@ create(#{method := Method, ?RESOURCE_GROUP, emqx_connector_http, Config#{base_url => maps:remove(query, URIMap), - pool_type => random}) of + pool_type => random}, + #{wait_connected => 1000}) of {ok, already_created} -> {ok, State}; {ok, _} -> diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl index 683429908..10e5d370c 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl @@ -112,7 +112,7 @@ create(#{selector := Selector} = Config) -> NState = State#{ selector_template => SelectorTemplate, resource_id => ResourceId}, - case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_mongo, Config) of + case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_mongo, Config, #{wait_connected => 1000}) of {ok, already_created} -> {ok, NState}; {ok, _} -> diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl index 087b153f7..62ff83b1e 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl @@ -81,7 +81,7 @@ create(#{password_hash_algorithm := Algorithm, placeholders => PlaceHolders, query_timeout => QueryTimeout, resource_id => ResourceId}, - case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_mysql, Config) of + case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_mysql, Config, #{wait_connected => 1000}) of {ok, already_created} -> {ok, State}; {ok, _} -> diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl index 620bf2b9b..550a6cfe1 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl @@ -79,7 +79,9 @@ create(#{query := Query0, State = #{placeholders => PlaceHolders, password_hash_algorithm => Algorithm, resource_id => ResourceId}, - case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_pgsql, Config#{named_queries => #{ResourceId => Query}}) of + case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_pgsql, + Config#{named_queries => #{ResourceId => Query}}, + #{wait_connected => 1000}) of {ok, already_created} -> {ok, State}; {ok, _} -> diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl index 11fcdac84..389def83d 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl @@ -91,7 +91,9 @@ create(#{cmd := Cmd, NState = State#{ cmd => NCmd, resource_id => ResourceId}, - case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_redis, Config) of + case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, + emqx_connector_redis, Config, + #{wait_connected => 1000}) of {ok, already_created} -> {ok, NState}; {ok, _} -> From db97ed5163bb2e87f42fc759683ca9c8757caf08 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Mon, 28 Feb 2022 16:55:24 +0800 Subject: [PATCH 04/10] fix(emqx_authz): add default wait_connected --- apps/emqx_authz/src/emqx_authz_utils.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/emqx_authz/src/emqx_authz_utils.erl b/apps/emqx_authz/src/emqx_authz_utils.erl index c0a8206c6..cef16b99b 100644 --- a/apps/emqx_authz/src/emqx_authz_utils.erl +++ b/apps/emqx_authz/src/emqx_authz_utils.erl @@ -35,7 +35,10 @@ create_resource(Module, Config) -> ResourceID = make_resource_id(Module), - case emqx_resource:create_local(ResourceID, ?RESOURCE_GROUP, Module, Config) of + case emqx_resource:create_local(ResourceID, + ?RESOURCE_GROUP, + Module, Config, + #{wait_connected => 1000}) of {ok, already_created} -> {ok, ResourceID}; {ok, _} -> {ok, ResourceID}; {error, Reason} -> {error, Reason} From db0e9e33588fb780431fc842648960fbc0bde13e Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Mon, 28 Feb 2022 18:18:57 +0800 Subject: [PATCH 05/10] fix(emqx_resource_instance): fix dialyzer warning --- apps/emqx_resource/src/emqx_resource_instance.erl | 2 +- apps/emqx_resource/test/emqx_resource_SUITE.erl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/emqx_resource/src/emqx_resource_instance.erl b/apps/emqx_resource/src/emqx_resource_instance.erl index a3631d337..ea88b24bd 100644 --- a/apps/emqx_resource/src/emqx_resource_instance.erl +++ b/apps/emqx_resource/src/emqx_resource_instance.erl @@ -182,7 +182,7 @@ wait_for_resource_ready(InstId, 0) -> force_lookup(InstId); wait_for_resource_ready(InstId, Retry) -> case force_lookup(InstId) of - #{resource_data := #{status := connected}} = Data -> Data; + #{status := connected} = Data -> Data; _ -> timer:sleep(100), wait_for_resource_ready(InstId, Retry-1) diff --git a/apps/emqx_resource/test/emqx_resource_SUITE.erl b/apps/emqx_resource/test/emqx_resource_SUITE.erl index 4a40ce55a..4019f983e 100644 --- a/apps/emqx_resource/test/emqx_resource_SUITE.erl +++ b/apps/emqx_resource/test/emqx_resource_SUITE.erl @@ -221,6 +221,8 @@ t_stop_start(_) -> ok = emqx_resource:restart(?ID), + timer:sleep(300), + #{pid := Pid1} = emqx_resource:query(?ID, get_state), ?assert(is_process_alive(Pid1)). From 62d3aecc0985e94eac3047f08ff40a4f6229e136 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Tue, 1 Mar 2022 14:20:04 +0800 Subject: [PATCH 06/10] fix(emqx_connector): add default Opts: '#{wait_connected => 1000}' --- apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl | 3 ++- apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl | 3 ++- apps/emqx_connector/test/emqx_connector_redis_SUITE.erl | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl b/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl index b38cee3eb..6c5932b97 100644 --- a/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl +++ b/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl @@ -68,7 +68,8 @@ perform_lifecycle_check(PoolName, InitialConfig) -> PoolName, ?CONNECTOR_RESOURCE_GROUP, ?MYSQL_RESOURCE_MOD, - CheckedConfig + CheckedConfig, + #{wait_connected => 1000} ), ?assertEqual(InitialStatus, connected), % Instance should match the state and status of the just started resource diff --git a/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl b/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl index 331283c59..25bf6bb06 100644 --- a/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl +++ b/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl @@ -68,7 +68,8 @@ perform_lifecycle_check(PoolName, InitialConfig) -> PoolName, ?CONNECTOR_RESOURCE_GROUP, ?PGSQL_RESOURCE_MOD, - CheckedConfig + CheckedConfig, + #{wait_connected => 1000} ), ?assertEqual(InitialStatus, connected), % Instance should match the state and status of the just started resource diff --git a/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl b/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl index 45fc17d9a..787872d3c 100644 --- a/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl +++ b/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl @@ -83,7 +83,8 @@ perform_lifecycle_check(PoolName, InitialConfig, RedisCommand) -> PoolName, ?CONNECTOR_RESOURCE_GROUP, ?REDIS_RESOURCE_MOD, - CheckedConfig + CheckedConfig, + #{wait_connected => 1000} ), ?assertEqual(InitialStatus, connected), % Instance should match the state and status of the just started resource From 57adbab5eadf89828e0a312e91f8a1048f8d4044 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Tue, 1 Mar 2022 14:47:57 +0800 Subject: [PATCH 07/10] fix(emqx_authn): fix authn suite status --- apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl | 6 +++++- apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl | 6 +++--- apps/emqx_authn/test/emqx_authn_mysql_SUITE.erl | 2 +- apps/emqx_authn/test/emqx_authn_mysql_tls_SUITE.erl | 6 +++--- apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl | 3 ++- apps/emqx_authn/test/emqx_authn_pgsql_tls_SUITE.erl | 6 +++--- apps/emqx_authn/test/emqx_authn_redis_SUITE.erl | 2 +- apps/emqx_authn/test/emqx_authn_redis_tls_SUITE.erl | 6 +++--- 8 files changed, 21 insertions(+), 16 deletions(-) diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl index 10e5d370c..fc444d6f2 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl @@ -112,7 +112,11 @@ create(#{selector := Selector} = Config) -> NState = State#{ selector_template => SelectorTemplate, resource_id => ResourceId}, - case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_mongo, Config, #{wait_connected => 1000}) of + case emqx_resource:create_local(ResourceId, + ?RESOURCE_GROUP, + emqx_connector_mongo, + Config, + #{wait_connected => 1000}) of {ok, already_created} -> {ok, NState}; {ok, _} -> diff --git a/apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl b/apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl index 0e36d125c..c471c1f8b 100644 --- a/apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl @@ -91,7 +91,7 @@ t_create_invalid_server_name(_Config) -> create_mongo_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server-unknown-host">>, <<"verify">> => <<"verify_peer">>}), - fun({error, _}, Trace) -> + fun({ok, _}, Trace) -> ?assertEqual( [failed], ?projection( @@ -109,7 +109,7 @@ t_create_invalid_version(_Config) -> #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, <<"versions">> => [<<"tlsv1.1">>]}), - fun({error, _}, Trace) -> + fun({ok, _}, Trace) -> ?assertEqual( [failed], ?projection( @@ -128,7 +128,7 @@ t_invalid_ciphers(_Config) -> <<"verify">> => <<"verify_peer">>, <<"versions">> => [<<"tlsv1.2">>], <<"ciphers">> => [<<"DHE-RSA-AES256-GCM-SHA384">>]}), - fun({error, _}, Trace) -> + fun({ok, _}, Trace) -> ?assertEqual( [failed], ?projection( diff --git a/apps/emqx_authn/test/emqx_authn_mysql_SUITE.erl b/apps/emqx_authn/test/emqx_authn_mysql_SUITE.erl index 56e1b491e..b2a69b4c8 100644 --- a/apps/emqx_authn/test/emqx_authn_mysql_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_mysql_SUITE.erl @@ -101,7 +101,7 @@ t_create_invalid(_Config) -> lists:foreach( fun(Config) -> - {error, _} = emqx:update_config( + {ok, _} = emqx:update_config( ?PATH, {create_authenticator, ?GLOBAL, Config}), diff --git a/apps/emqx_authn/test/emqx_authn_mysql_tls_SUITE.erl b/apps/emqx_authn/test/emqx_authn_mysql_tls_SUITE.erl index a919c91c9..ce9e04577 100644 --- a/apps/emqx_authn/test/emqx_authn_mysql_tls_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_mysql_tls_SUITE.erl @@ -80,14 +80,14 @@ t_create_invalid(_Config) -> %% invalid server_name ?assertMatch( - {error, _}, + {ok, _}, create_mysql_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server-unknown-host">>, <<"verify">> => <<"verify_peer">>})), %% incompatible versions ?assertMatch( - {error, _}, + {ok, _}, create_mysql_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, @@ -95,7 +95,7 @@ t_create_invalid(_Config) -> %% incompatible ciphers ?assertMatch( - {error, _}, + {ok, _}, create_mysql_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, diff --git a/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl b/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl index 3bf93dc09..fecd3d6a4 100644 --- a/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl @@ -62,7 +62,8 @@ init_per_suite(Config) -> ?PGSQL_RESOURCE, ?RESOURCE_GROUP, emqx_connector_pgsql, - pgsql_config()), + pgsql_config(), + #{wait_connected => 1000}), Config; false -> {skip, no_pgsql} diff --git a/apps/emqx_authn/test/emqx_authn_pgsql_tls_SUITE.erl b/apps/emqx_authn/test/emqx_authn_pgsql_tls_SUITE.erl index 72c4a3126..0c21badc9 100644 --- a/apps/emqx_authn/test/emqx_authn_pgsql_tls_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_pgsql_tls_SUITE.erl @@ -80,14 +80,14 @@ t_create_invalid(_Config) -> %% invalid server_name ?assertMatch( - {error, _}, + {ok, _}, create_pgsql_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server-unknown-host">>, <<"verify">> => <<"verify_peer">>})), %% incompatible versions ?assertMatch( - {error, _}, + {ok, _}, create_pgsql_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, @@ -95,7 +95,7 @@ t_create_invalid(_Config) -> %% incompatible ciphers ?assertMatch( - {error, _}, + {ok, _}, create_pgsql_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, diff --git a/apps/emqx_authn/test/emqx_authn_redis_SUITE.erl b/apps/emqx_authn/test/emqx_authn_redis_SUITE.erl index 0645bfd7d..7aad87b6a 100644 --- a/apps/emqx_authn/test/emqx_authn_redis_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_redis_SUITE.erl @@ -108,7 +108,7 @@ t_create_invalid(_Config) -> lists:foreach( fun(Config) -> - {error, _} = emqx:update_config( + {ok, _} = emqx:update_config( ?PATH, {create_authenticator, ?GLOBAL, Config}), diff --git a/apps/emqx_authn/test/emqx_authn_redis_tls_SUITE.erl b/apps/emqx_authn/test/emqx_authn_redis_tls_SUITE.erl index b3f456622..d6249e328 100644 --- a/apps/emqx_authn/test/emqx_authn_redis_tls_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_redis_tls_SUITE.erl @@ -77,7 +77,7 @@ t_create(_Config) -> t_create_invalid(_Config) -> %% invalid server_name ?assertMatch( - {error, _}, + {ok, _}, create_redis_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server-unknown-host">>, <<"verify">> => <<"verify_peer">>, @@ -86,7 +86,7 @@ t_create_invalid(_Config) -> %% incompatible versions ?assertMatch( - {error, _}, + {ok, _}, create_redis_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, @@ -94,7 +94,7 @@ t_create_invalid(_Config) -> %% incompatible ciphers ?assertMatch( - {error, _}, + {ok, _}, create_redis_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, From ca7a43986a99d08b3e54f0e688ef86131c851d6b Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Tue, 1 Mar 2022 17:31:23 +0800 Subject: [PATCH 08/10] fix(emqx_connector): restart with default wait_connected --- apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl | 2 +- apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl | 2 +- apps/emqx_connector/test/emqx_connector_redis_SUITE.erl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl b/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl index 6c5932b97..3eec37af1 100644 --- a/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl +++ b/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl @@ -90,7 +90,7 @@ perform_lifecycle_check(PoolName, InitialConfig) -> % Can call stop/1 again on an already stopped instance ?assertEqual(ok, emqx_resource:stop(PoolName)), % Make sure it can be restarted and the healthchecks and queries work properly - ?assertEqual(ok, emqx_resource:restart(PoolName)), + ?assertEqual(ok, emqx_resource:restart(PoolName, #{wait_connected => 1000})), {ok, ?CONNECTOR_RESOURCE_GROUP, #{status := InitialStatus}} = emqx_resource:get_instance(PoolName), ?assertEqual(ok, emqx_resource:health_check(PoolName)), ?assertMatch({ok, _, [[1]]}, emqx_resource:query(PoolName, test_query_no_params())), diff --git a/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl b/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl index 25bf6bb06..b8b3980ac 100644 --- a/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl +++ b/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl @@ -89,7 +89,7 @@ perform_lifecycle_check(PoolName, InitialConfig) -> % Can call stop/1 again on an already stopped instance ?assertEqual(ok, emqx_resource:stop(PoolName)), % Make sure it can be restarted and the healthchecks and queries work properly - ?assertEqual(ok, emqx_resource:restart(PoolName)), + ?assertEqual(ok, emqx_resource:restart(PoolName, #{wait_connected => 1000})), {ok, ?CONNECTOR_RESOURCE_GROUP, #{status := InitialStatus}} = emqx_resource:get_instance(PoolName), ?assertEqual(ok, emqx_resource:health_check(PoolName)), ?assertMatch({ok, _, [{1}]}, emqx_resource:query(PoolName, test_query_no_params())), diff --git a/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl b/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl index 787872d3c..2b8495dac 100644 --- a/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl +++ b/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl @@ -103,7 +103,7 @@ perform_lifecycle_check(PoolName, InitialConfig, RedisCommand) -> % Can call stop/1 again on an already stopped instance ?assertEqual(ok, emqx_resource:stop(PoolName)), % Make sure it can be restarted and the healthchecks and queries work properly - ?assertEqual(ok, emqx_resource:restart(PoolName)), + ?assertEqual(ok, emqx_resource:restart(PoolName, #{wait_connected => 1000})), {ok, ?CONNECTOR_RESOURCE_GROUP, #{status := InitialStatus}} = emqx_resource:get_instance(PoolName), ?assertEqual(ok, emqx_resource:health_check(PoolName)), ?assertEqual({ok, <<"PONG">>}, emqx_resource:query(PoolName, {cmd, RedisCommand})), From 583624fb8d426418102cd982a4a3147016e2ddcf Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 2 Mar 2022 10:49:50 +0800 Subject: [PATCH 09/10] fix(emqx_authn): fix test suite --- .../src/simple_authn/emqx_authn_http.erl | 2 +- .../src/simple_authn/emqx_authn_mongodb.erl | 2 +- .../src/simple_authn/emqx_authn_mysql.erl | 6 ++- .../src/simple_authn/emqx_authn_pgsql.erl | 2 +- .../src/simple_authn/emqx_authn_redis.erl | 2 +- .../test/emqx_authn_mongo_tls_SUITE.erl | 22 +++++----- .../test/emqx_authn_mysql_SUITE.erl | 11 +++-- .../test/emqx_authn_mysql_tls_SUITE.erl | 5 ++- .../test/emqx_authn_pgsql_SUITE.erl | 10 +++-- .../test/emqx_authn_pgsql_tls_SUITE.erl | 5 ++- .../test/emqx_authn_redis_SUITE.erl | 42 +++++++++++++------ .../test/emqx_authn_redis_tls_SUITE.erl | 4 +- apps/emqx_authz/src/emqx_authz_postgresql.erl | 3 +- apps/emqx_authz/src/emqx_authz_utils.erl | 2 +- apps/emqx_authz/test/emqx_authz_SUITE.erl | 4 ++ .../test/emqx_authz_api_settings_SUITE.erl | 4 ++ .../test/emqx_authz_mysql_SUITE.erl | 7 ++-- .../test/emqx_authz_postgresql_SUITE.erl | 7 ++-- .../test/emqx_authz_redis_SUITE.erl | 7 ++-- apps/emqx_bridge/src/emqx_bridge.erl | 11 +++-- .../test/emqx_connector_mysql_SUITE.erl | 29 +++++++++---- .../test/emqx_connector_pgsql_SUITE.erl | 24 +++++++---- .../test/emqx_connector_redis_SUITE.erl | 23 ++++++---- apps/emqx_resource/include/emqx_resource.hrl | 2 +- apps/emqx_resource/src/emqx_resource.erl | 40 ++++++++++++++---- .../src/emqx_resource_health_check.erl | 2 +- .../src/emqx_resource_instance.erl | 6 +-- apps/emqx_retainer/src/emqx_retainer.erl | 3 +- 28 files changed, 195 insertions(+), 92 deletions(-) diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl index 863a1d936..9308bbe95 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl @@ -134,7 +134,7 @@ create(#{method := Method, emqx_connector_http, Config#{base_url => maps:remove(query, URIMap), pool_type => random}, - #{wait_connected => 1000}) of + #{waiting_connect_complete => 5000}) of {ok, already_created} -> {ok, State}; {ok, _} -> diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl index fc444d6f2..158306a87 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl @@ -116,7 +116,7 @@ create(#{selector := Selector} = Config) -> ?RESOURCE_GROUP, emqx_connector_mongo, Config, - #{wait_connected => 1000}) of + #{waiting_connect_complete => 5000}) of {ok, already_created} -> {ok, NState}; {ok, _} -> diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl index 62ff83b1e..b347ff30c 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl @@ -81,7 +81,11 @@ create(#{password_hash_algorithm := Algorithm, placeholders => PlaceHolders, query_timeout => QueryTimeout, resource_id => ResourceId}, - case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_mysql, Config, #{wait_connected => 1000}) of + case emqx_resource:create_local(ResourceId, + ?RESOURCE_GROUP, + emqx_connector_mysql, + Config, + #{waiting_connect_complete => 5000}) of {ok, already_created} -> {ok, State}; {ok, _} -> diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl index 550a6cfe1..856271db3 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl @@ -81,7 +81,7 @@ create(#{query := Query0, resource_id => ResourceId}, case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_pgsql, Config#{named_queries => #{ResourceId => Query}}, - #{wait_connected => 1000}) of + #{waiting_connect_complete => 5000}) of {ok, already_created} -> {ok, State}; {ok, _} -> diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl index 389def83d..e604acfe3 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl @@ -93,7 +93,7 @@ create(#{cmd := Cmd, resource_id => ResourceId}, case emqx_resource:create_local(ResourceId, ?RESOURCE_GROUP, emqx_connector_redis, Config, - #{wait_connected => 1000}) of + #{waiting_connect_complete => 5000}) of {ok, already_created} -> {ok, NState}; {ok, _} -> diff --git a/apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl b/apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl index c471c1f8b..8ad0caa6d 100644 --- a/apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_mongo_tls_SUITE.erl @@ -91,9 +91,9 @@ t_create_invalid_server_name(_Config) -> create_mongo_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server-unknown-host">>, <<"verify">> => <<"verify_peer">>}), - fun({ok, _}, Trace) -> - ?assertEqual( - [failed], + fun(_, Trace) -> + ?assertNotEqual( + [ok], ?projection( status, ?of_kind(emqx_connector_mongo_health_check, Trace))) @@ -109,9 +109,9 @@ t_create_invalid_version(_Config) -> #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, <<"versions">> => [<<"tlsv1.1">>]}), - fun({ok, _}, Trace) -> - ?assertEqual( - [failed], + fun(_, Trace) -> + ?assertNotEqual( + [ok], ?projection( status, ?of_kind(emqx_connector_mongo_health_check, Trace))) @@ -128,9 +128,9 @@ t_invalid_ciphers(_Config) -> <<"verify">> => <<"verify_peer">>, <<"versions">> => [<<"tlsv1.2">>], <<"ciphers">> => [<<"DHE-RSA-AES256-GCM-SHA384">>]}), - fun({ok, _}, Trace) -> - ?assertEqual( - [failed], + fun(_, Trace) -> + ?assertNotEqual( + [ok], ?projection( status, ?of_kind(emqx_connector_mongo_health_check, Trace))) @@ -142,7 +142,9 @@ t_invalid_ciphers(_Config) -> create_mongo_auth_with_ssl_opts(SpecificSSLOpts) -> AuthConfig = raw_mongo_auth_config(SpecificSSLOpts), - emqx:update_config(?PATH, {create_authenticator, ?GLOBAL, AuthConfig}). + Res = emqx:update_config(?PATH, {create_authenticator, ?GLOBAL, AuthConfig}), + timer:sleep(500), + Res. raw_mongo_auth_config(SpecificSSLOpts) -> SSLOpts = maps:merge( diff --git a/apps/emqx_authn/test/emqx_authn_mysql_SUITE.erl b/apps/emqx_authn/test/emqx_authn_mysql_SUITE.erl index b2a69b4c8..4199564c2 100644 --- a/apps/emqx_authn/test/emqx_authn_mysql_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_mysql_SUITE.erl @@ -28,6 +28,7 @@ -define(MYSQL_RESOURCE, <<"emqx_authn_mysql_SUITE">>). -define(PATH, [authentication]). +-define(ResourceID, <<"password-based:mysql">>). all() -> [{group, require_seeds}, t_create, t_create_invalid]. @@ -61,7 +62,8 @@ init_per_suite(Config) -> ?MYSQL_RESOURCE, ?RESOURCE_GROUP, emqx_connector_mysql, - mysql_config()), + mysql_config(), + #{waiting_connect_complete => 5000}), Config; false -> {skip, no_mysql} @@ -86,7 +88,8 @@ t_create(_Config) -> ?PATH, {create_authenticator, ?GLOBAL, AuthConfig}), - {ok, [#{provider := emqx_authn_mysql}]} = emqx_authentication:list_authenticators(?GLOBAL). + {ok, [#{provider := emqx_authn_mysql}]} = emqx_authentication:list_authenticators(?GLOBAL), + emqx_authn_test_lib:delete_config(?ResourceID). t_create_invalid(_Config) -> AuthConfig = raw_mysql_auth_config(), @@ -104,8 +107,8 @@ t_create_invalid(_Config) -> {ok, _} = emqx:update_config( ?PATH, {create_authenticator, ?GLOBAL, Config}), - - {ok, []} = emqx_authentication:list_authenticators(?GLOBAL) + emqx_authn_test_lib:delete_config(?ResourceID), + {ok, _} = emqx_authentication:list_authenticators(?GLOBAL) end, InvalidConfigs). diff --git a/apps/emqx_authn/test/emqx_authn_mysql_tls_SUITE.erl b/apps/emqx_authn/test/emqx_authn_mysql_tls_SUITE.erl index ce9e04577..51bf9d235 100644 --- a/apps/emqx_authn/test/emqx_authn_mysql_tls_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_mysql_tls_SUITE.erl @@ -27,6 +27,7 @@ -define(MYSQL_HOST, "mysql-tls"). -define(PATH, [authentication]). +-define(ResourceID, <<"password-based:mysql">>). all() -> emqx_common_test_helpers:all(?MODULE). @@ -84,7 +85,7 @@ t_create_invalid(_Config) -> create_mysql_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server-unknown-host">>, <<"verify">> => <<"verify_peer">>})), - + emqx_authn_test_lib:delete_config(?ResourceID), %% incompatible versions ?assertMatch( {ok, _}, @@ -92,7 +93,7 @@ t_create_invalid(_Config) -> #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, <<"versions">> => [<<"tlsv1.1">>]})), - + emqx_authn_test_lib:delete_config(?ResourceID), %% incompatible ciphers ?assertMatch( {ok, _}, diff --git a/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl b/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl index fecd3d6a4..a4d6f8c07 100644 --- a/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl @@ -27,6 +27,7 @@ -define(PGSQL_HOST, "pgsql"). -define(PGSQL_RESOURCE, <<"emqx_authn_pgsql_SUITE">>). +-define(ResourceID, <<"password-based:postgresql">>). -define(PATH, [authentication]). @@ -63,7 +64,7 @@ init_per_suite(Config) -> ?RESOURCE_GROUP, emqx_connector_pgsql, pgsql_config(), - #{wait_connected => 1000}), + #{waiting_connect_complete => 5000}), Config; false -> {skip, no_pgsql} @@ -88,7 +89,8 @@ t_create(_Config) -> ?PATH, {create_authenticator, ?GLOBAL, AuthConfig}), - {ok, [#{provider := emqx_authn_pgsql}]} = emqx_authentication:list_authenticators(?GLOBAL). + {ok, [#{provider := emqx_authn_pgsql}]} = emqx_authentication:list_authenticators(?GLOBAL), + emqx_authn_test_lib:delete_config(?ResourceID). t_create_invalid(_Config) -> AuthConfig = raw_pgsql_auth_config(), @@ -103,10 +105,10 @@ t_create_invalid(_Config) -> lists:foreach( fun(Config) -> - {error, _} = emqx:update_config( + {ok, _} = emqx:update_config( ?PATH, {create_authenticator, ?GLOBAL, Config}), - + emqx_authn_test_lib:delete_config(?ResourceID), {ok, []} = emqx_authentication:list_authenticators(?GLOBAL) end, InvalidConfigs). diff --git a/apps/emqx_authn/test/emqx_authn_pgsql_tls_SUITE.erl b/apps/emqx_authn/test/emqx_authn_pgsql_tls_SUITE.erl index 0c21badc9..591dd1eea 100644 --- a/apps/emqx_authn/test/emqx_authn_pgsql_tls_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_pgsql_tls_SUITE.erl @@ -27,6 +27,7 @@ -define(PGSQL_HOST, "pgsql-tls"). -define(PATH, [authentication]). +-define(ResourceID, <<"password-based:postgresql">>). all() -> emqx_common_test_helpers:all(?MODULE). @@ -84,7 +85,7 @@ t_create_invalid(_Config) -> create_pgsql_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server-unknown-host">>, <<"verify">> => <<"verify_peer">>})), - + emqx_authn_test_lib:delete_config(?ResourceID), %% incompatible versions ?assertMatch( {ok, _}, @@ -92,7 +93,7 @@ t_create_invalid(_Config) -> #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, <<"versions">> => [<<"tlsv1.1">>]})), - + emqx_authn_test_lib:delete_config(?ResourceID), %% incompatible ciphers ?assertMatch( {ok, _}, diff --git a/apps/emqx_authn/test/emqx_authn_redis_SUITE.erl b/apps/emqx_authn/test/emqx_authn_redis_SUITE.erl index 7aad87b6a..c02830ab7 100644 --- a/apps/emqx_authn/test/emqx_authn_redis_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_redis_SUITE.erl @@ -28,6 +28,7 @@ -define(REDIS_RESOURCE, <<"emqx_authn_redis_SUITE">>). -define(PATH, [authentication]). +-define(ResourceID, <<"password-based:redis">>). all() -> [{group, require_seeds}, t_create, t_create_invalid]. @@ -61,7 +62,8 @@ init_per_suite(Config) -> ?REDIS_RESOURCE, ?RESOURCE_GROUP, emqx_connector_redis, - redis_config()), + redis_config(), + #{waiting_connect_complete => 5000}), Config; false -> {skip, no_redis} @@ -91,13 +93,8 @@ t_create(_Config) -> t_create_invalid(_Config) -> AuthConfig = raw_redis_auth_config(), - InvalidConfigs = [ - maps:without([server], AuthConfig), - AuthConfig#{server => <<"unknownhost:3333">>}, - AuthConfig#{password => <<"wrongpass">>}, - AuthConfig#{database => <<"5678">>}, AuthConfig#{ cmd => <<"MGET password_hash:${username} salt:${username}">>}, AuthConfig#{ @@ -105,16 +102,33 @@ t_create_invalid(_Config) -> AuthConfig#{ cmd => <<"HMGET mqtt_user:${username} salt is_superuser">>} ], + lists:foreach( + fun(Config) -> + {error, _} = emqx:update_config( + ?PATH, + {create_authenticator, ?GLOBAL, Config}), + + {ok, []} = emqx_authentication:list_authenticators(?GLOBAL) + end, + InvalidConfigs), + + InvalidConfigs1 = + [ + maps:without([server], AuthConfig), + AuthConfig#{server => <<"unknownhost:3333">>}, + AuthConfig#{password => <<"wrongpass">>}, + AuthConfig#{database => <<"5678">>} + ], lists:foreach( fun(Config) -> {ok, _} = emqx:update_config( ?PATH, {create_authenticator, ?GLOBAL, Config}), - + emqx_authn_test_lib:delete_config(?ResourceID), {ok, []} = emqx_authentication:list_authenticators(?GLOBAL) end, - InvalidConfigs). + InvalidConfigs1). t_authenticate(_Config) -> ok = lists:foreach( @@ -270,7 +284,8 @@ user_seeds() -> }, #{data => #{ - password_hash => <<"$2b$12$wtY3h20mUjjmeaClpqZVveDWGlHzCGsvuThMlneGHA7wVeFYyns2u">>, + password_hash => + <<"$2b$12$wtY3h20mUjjmeaClpqZVveDWGlHzCGsvuThMlneGHA7wVeFYyns2u">>, salt => <<"$2b$12$wtY3h20mUjjmeaClpqZVve">>, is_superuser => <<"0">> }, @@ -303,7 +318,8 @@ user_seeds() -> result => {ok,#{is_superuser => false}} }, #{data => #{ - password_hash => <<"$2b$12$wtY3h20mUjjmeaClpqZVveDWGlHzCGsvuThMlneGHA7wVeFYyns2u">>, + password_hash => + <<"$2b$12$wtY3h20mUjjmeaClpqZVveDWGlHzCGsvuThMlneGHA7wVeFYyns2u">>, salt => <<"$2b$12$wtY3h20mUjjmeaClpqZVve">>, is_superuser => <<"0">> }, @@ -321,7 +337,8 @@ user_seeds() -> }, #{data => #{ - password_hash => <<"$2b$12$wtY3h20mUjjmeaClpqZVveDWGlHzCGsvuThMlneGHA7wVeFYyns2u">>, + password_hash => + <<"$2b$12$wtY3h20mUjjmeaClpqZVveDWGlHzCGsvuThMlneGHA7wVeFYyns2u">>, salt => <<"$2b$12$wtY3h20mUjjmeaClpqZVve">>, is_superuser => <<"0">> }, @@ -339,7 +356,8 @@ user_seeds() -> }, #{data => #{ - password_hash => <<"$2b$12$wtY3h20mUjjmeaClpqZVveDWGlHzCGsvuThMlneGHA7wVeFYyns2u">>, + password_hash => + <<"$2b$12$wtY3h20mUjjmeaClpqZVveDWGlHzCGsvuThMlneGHA7wVeFYyns2u">>, salt => <<"$2b$12$wtY3h20mUjjmeaClpqZVve">>, is_superuser => <<"0">> }, diff --git a/apps/emqx_authn/test/emqx_authn_redis_tls_SUITE.erl b/apps/emqx_authn/test/emqx_authn_redis_tls_SUITE.erl index d6249e328..670088e08 100644 --- a/apps/emqx_authn/test/emqx_authn_redis_tls_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_redis_tls_SUITE.erl @@ -86,7 +86,7 @@ t_create_invalid(_Config) -> %% incompatible versions ?assertMatch( - {ok, _}, + {error, _}, create_redis_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, @@ -94,7 +94,7 @@ t_create_invalid(_Config) -> %% incompatible ciphers ?assertMatch( - {ok, _}, + {error, _}, create_redis_auth_with_ssl_opts( #{<<"server_name_indication">> => <<"authn-server">>, <<"verify">> => <<"verify_peer">>, diff --git a/apps/emqx_authz/src/emqx_authz_postgresql.erl b/apps/emqx_authz/src/emqx_authz_postgresql.erl index 936cfc7e6..a127a9c2b 100644 --- a/apps/emqx_authz/src/emqx_authz_postgresql.erl +++ b/apps/emqx_authz/src/emqx_authz_postgresql.erl @@ -55,7 +55,8 @@ init(#{query := SQL0} = Source) -> ResourceID, ?RESOURCE_GROUP, emqx_connector_pgsql, - Source#{named_queries => #{ResourceID => SQL}}) of + Source#{named_queries => #{ResourceID => SQL}}, + #{waiting_connect_complete => 5000}) of {ok, _} -> Source#{annotations => #{id => ResourceID, diff --git a/apps/emqx_authz/src/emqx_authz_utils.erl b/apps/emqx_authz/src/emqx_authz_utils.erl index cef16b99b..73e387d81 100644 --- a/apps/emqx_authz/src/emqx_authz_utils.erl +++ b/apps/emqx_authz/src/emqx_authz_utils.erl @@ -38,7 +38,7 @@ create_resource(Module, Config) -> case emqx_resource:create_local(ResourceID, ?RESOURCE_GROUP, Module, Config, - #{wait_connected => 1000}) of + #{waiting_connect_complete => 5000}) of {ok, already_created} -> {ok, ResourceID}; {ok, _} -> {ok, ResourceID}; {error, Reason} -> {error, Reason} diff --git a/apps/emqx_authz/test/emqx_authz_SUITE.erl b/apps/emqx_authz/test/emqx_authz_SUITE.erl index 638da1416..e62be0aa2 100644 --- a/apps/emqx_authz/test/emqx_authz_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_SUITE.erl @@ -46,6 +46,7 @@ end_per_suite(_Config) -> #{<<"no_match">> => <<"allow">>, <<"cache">> => #{<<"enable">> => <<"true">>}, <<"sources">> => []}), + ok = stop_apps([emqx_resource]), emqx_common_test_helpers:stop_apps([emqx_authz, emqx_conf]), meck:unload(emqx_resource), ok. @@ -222,3 +223,6 @@ t_move_source(_) -> ], emqx_authz:lookup()), ok. + +stop_apps(Apps) -> + lists:foreach(fun application:stop/1, Apps). diff --git a/apps/emqx_authz/test/emqx_authz_api_settings_SUITE.erl b/apps/emqx_authz/test/emqx_authz_api_settings_SUITE.erl index 6a48fee4d..e4b48c740 100644 --- a/apps/emqx_authz/test/emqx_authz_api_settings_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_api_settings_SUITE.erl @@ -44,6 +44,7 @@ end_per_suite(_Config) -> #{<<"no_match">> => <<"allow">>, <<"cache">> => #{<<"enable">> => <<"true">>}, <<"sources">> => []}), + ok = stop_apps([emqx_resource, emqx_connector]), emqx_common_test_helpers:stop_apps([emqx_dashboard, emqx_authz, emqx_conf]), ok. @@ -131,3 +132,6 @@ auth_header_() -> Password = <<"public">>, {ok, Token} = emqx_dashboard_admin:sign_token(Username, Password), {"Authorization", "Bearer " ++ binary_to_list(Token)}. + +stop_apps(Apps) -> + lists:foreach(fun application:stop/1, Apps). diff --git a/apps/emqx_authz/test/emqx_authz_mysql_SUITE.erl b/apps/emqx_authz/test/emqx_authz_mysql_SUITE.erl index 9e435267d..1bdff9455 100644 --- a/apps/emqx_authz/test/emqx_authz_mysql_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_mysql_SUITE.erl @@ -44,7 +44,8 @@ init_per_suite(Config) -> ?MYSQL_RESOURCE, ?RESOURCE_GROUP, emqx_connector_mysql, - mysql_config()), + mysql_config(), + #{waiting_connect_complete => 5000}), Config; false -> {skip, no_mysql} @@ -179,9 +180,9 @@ t_create_invalid(_Config) -> BadConfig = maps:merge( raw_mysql_authz_config(), #{<<"server">> => <<"255.255.255.255:33333">>}), - {error, _} = emqx_authz:update(?CMD_REPLACE, [BadConfig]), + {ok, _} = emqx_authz:update(?CMD_REPLACE, [BadConfig]), - [] = emqx_authz:lookup(). + [_] = emqx_authz:lookup(). t_nonbinary_values(_Config) -> ClientInfo = #{clientid => clientid, diff --git a/apps/emqx_authz/test/emqx_authz_postgresql_SUITE.erl b/apps/emqx_authz/test/emqx_authz_postgresql_SUITE.erl index 8e4d25434..5f8c914fe 100644 --- a/apps/emqx_authz/test/emqx_authz_postgresql_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_postgresql_SUITE.erl @@ -44,7 +44,8 @@ init_per_suite(Config) -> ?PGSQL_RESOURCE, ?RESOURCE_GROUP, emqx_connector_pgsql, - pgsql_config()), + pgsql_config(), + #{waiting_connect_complete => 5000}), Config; false -> {skip, no_pgsql} @@ -180,9 +181,9 @@ t_create_invalid(_Config) -> BadConfig = maps:merge( raw_pgsql_authz_config(), #{<<"server">> => <<"255.255.255.255:33333">>}), - {error, _} = emqx_authz:update(?CMD_REPLACE, [BadConfig]), + {ok, _} = emqx_authz:update(?CMD_REPLACE, [BadConfig]), - [] = emqx_authz:lookup(). + [_] = emqx_authz:lookup(). t_nonbinary_values(_Config) -> ClientInfo = #{clientid => clientid, diff --git a/apps/emqx_authz/test/emqx_authz_redis_SUITE.erl b/apps/emqx_authz/test/emqx_authz_redis_SUITE.erl index 32b62ac35..519973ebe 100644 --- a/apps/emqx_authz/test/emqx_authz_redis_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_redis_SUITE.erl @@ -45,7 +45,8 @@ init_per_suite(Config) -> ?REDIS_RESOURCE, ?RESOURCE_GROUP, emqx_connector_redis, - redis_config()), + redis_config(), + #{waiting_connect_complete => 5000}), Config; false -> {skip, no_redis} @@ -151,8 +152,8 @@ t_create_invalid(_Config) -> lists:foreach( fun(Config) -> - {error, _} = emqx_authz:update(?CMD_REPLACE, [Config]), - [] = emqx_authz:lookup() + {ok, _} = emqx_authz:update(?CMD_REPLACE, [Config]), + [_] = emqx_authz:lookup() end, InvalidConfigs). diff --git a/apps/emqx_bridge/src/emqx_bridge.erl b/apps/emqx_bridge/src/emqx_bridge.erl index 2d40c997b..67e9286bf 100644 --- a/apps/emqx_bridge/src/emqx_bridge.erl +++ b/apps/emqx_bridge/src/emqx_bridge.erl @@ -224,8 +224,11 @@ create(BridgeId, Conf) -> create(Type, Name, Conf) -> ?SLOG(info, #{msg => "create bridge", type => Type, name => Name, config => Conf}), - case emqx_resource:create_local(resource_id(Type, Name), <<"emqx_bridge">>, emqx_bridge:resource_type(Type), - parse_confs(Type, Name, Conf), #{wait_connected => 1000}) of + case emqx_resource:create_local(resource_id(Type, Name), + <<"emqx_bridge">>, + emqx_bridge:resource_type(Type), + parse_confs(Type, Name, Conf), + #{waiting_connect_complete => 5000}) of {ok, already_created} -> maybe_disable_bridge(Type, Name, Conf); {ok, _} -> maybe_disable_bridge(Type, Name, Conf); {error, Reason} -> {error, Reason} @@ -270,7 +273,9 @@ recreate(Type, Name) -> recreate(Type, Name, Conf) -> emqx_resource:recreate_local(resource_id(Type, Name), - emqx_bridge:resource_type(Type), parse_confs(Type, Name, Conf), #{wait_connected => 1000}). + emqx_bridge:resource_type(Type), + parse_confs(Type, Name, Conf), + #{waiting_connect_complete => 5000}). create_dry_run(Type, Conf) -> Conf0 = Conf#{<<"ingress">> => #{<<"remote_topic">> => <<"t">>}}, diff --git a/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl b/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl index 3eec37af1..47d8f31c8 100644 --- a/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl +++ b/apps/emqx_connector/test/emqx_connector_mysql_SUITE.erl @@ -63,26 +63,33 @@ t_lifecycle(_Config) -> ). perform_lifecycle_check(PoolName, InitialConfig) -> - {ok, #{config := CheckedConfig}} = emqx_resource:check_config(?MYSQL_RESOURCE_MOD, InitialConfig), - {ok, #{state := #{poolname := ReturnedPoolName} = State, status := InitialStatus}} = emqx_resource:create_local( + {ok, #{config := CheckedConfig}} = + emqx_resource:check_config(?MYSQL_RESOURCE_MOD, InitialConfig), + {ok, #{state := #{poolname := ReturnedPoolName} = State, + status := InitialStatus}} = emqx_resource:create_local( PoolName, ?CONNECTOR_RESOURCE_GROUP, ?MYSQL_RESOURCE_MOD, CheckedConfig, - #{wait_connected => 1000} + #{waiting_connect_complete => 5000} ), ?assertEqual(InitialStatus, connected), % Instance should match the state and status of the just started resource - {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, status := InitialStatus}} = emqx_resource:get_instance(PoolName), + {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, + status := InitialStatus}} + = emqx_resource:get_instance(PoolName), ?assertEqual(ok, emqx_resource:health_check(PoolName)), % % Perform query as further check that the resource is working as expected ?assertMatch({ok, _, [[1]]}, emqx_resource:query(PoolName, test_query_no_params())), ?assertMatch({ok, _, [[1]]}, emqx_resource:query(PoolName, test_query_with_params())), - ?assertMatch({ok, _, [[1]]}, emqx_resource:query(PoolName, test_query_with_params_and_timeout())), + ?assertMatch({ok, _, [[1]]}, emqx_resource:query(PoolName, + test_query_with_params_and_timeout())), ?assertEqual(ok, emqx_resource:stop(PoolName)), % Resource will be listed still, but state will be changed and healthcheck will fail % as the worker no longer exists. - {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, status := StoppedStatus}} = emqx_resource:get_instance(PoolName), + {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, + status := StoppedStatus}} + = emqx_resource:get_instance(PoolName), ?assertEqual(StoppedStatus, disconnected), ?assertEqual({error,health_check_failed}, emqx_resource:health_check(PoolName)), % Resource healthcheck shortcuts things by checking ets. Go deeper by checking pool itself. @@ -90,12 +97,16 @@ perform_lifecycle_check(PoolName, InitialConfig) -> % Can call stop/1 again on an already stopped instance ?assertEqual(ok, emqx_resource:stop(PoolName)), % Make sure it can be restarted and the healthchecks and queries work properly - ?assertEqual(ok, emqx_resource:restart(PoolName, #{wait_connected => 1000})), - {ok, ?CONNECTOR_RESOURCE_GROUP, #{status := InitialStatus}} = emqx_resource:get_instance(PoolName), + ?assertEqual(ok, emqx_resource:restart(PoolName)), + % async restart, need to wait resource + timer:sleep(500), + {ok, ?CONNECTOR_RESOURCE_GROUP, #{status := InitialStatus}} = + emqx_resource:get_instance(PoolName), ?assertEqual(ok, emqx_resource:health_check(PoolName)), ?assertMatch({ok, _, [[1]]}, emqx_resource:query(PoolName, test_query_no_params())), ?assertMatch({ok, _, [[1]]}, emqx_resource:query(PoolName, test_query_with_params())), - ?assertMatch({ok, _, [[1]]}, emqx_resource:query(PoolName, test_query_with_params_and_timeout())), + ?assertMatch({ok, _, [[1]]}, emqx_resource:query(PoolName, + test_query_with_params_and_timeout())), % Stop and remove the resource in one go. ?assertEqual(ok, emqx_resource:remove_local(PoolName)), ?assertEqual({error, not_found}, ecpool:stop_sup_pool(ReturnedPoolName)), diff --git a/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl b/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl index b8b3980ac..bc7b2eb4d 100644 --- a/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl +++ b/apps/emqx_connector/test/emqx_connector_pgsql_SUITE.erl @@ -63,17 +63,22 @@ t_lifecycle(_Config) -> ). perform_lifecycle_check(PoolName, InitialConfig) -> - {ok, #{config := CheckedConfig}} = emqx_resource:check_config(?PGSQL_RESOURCE_MOD, InitialConfig), - {ok, #{state := #{poolname := ReturnedPoolName} = State, status := InitialStatus}} = emqx_resource:create_local( + {ok, #{config := CheckedConfig}} = + emqx_resource:check_config(?PGSQL_RESOURCE_MOD, InitialConfig), + {ok, #{state := #{poolname := ReturnedPoolName} = State, + status := InitialStatus}} + = emqx_resource:create_local( PoolName, ?CONNECTOR_RESOURCE_GROUP, ?PGSQL_RESOURCE_MOD, CheckedConfig, - #{wait_connected => 1000} + #{waiting_connect_complete => 5000} ), ?assertEqual(InitialStatus, connected), % Instance should match the state and status of the just started resource - {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, status := InitialStatus}} = emqx_resource:get_instance(PoolName), + {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, + status := InitialStatus}} + = emqx_resource:get_instance(PoolName), ?assertEqual(ok, emqx_resource:health_check(PoolName)), % % Perform query as further check that the resource is working as expected ?assertMatch({ok, _, [{1}]}, emqx_resource:query(PoolName, test_query_no_params())), @@ -81,7 +86,9 @@ perform_lifecycle_check(PoolName, InitialConfig) -> ?assertEqual(ok, emqx_resource:stop(PoolName)), % Resource will be listed still, but state will be changed and healthcheck will fail % as the worker no longer exists. - {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, status := StoppedStatus}} = emqx_resource:get_instance(PoolName), + {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, + status := StoppedStatus}} + = emqx_resource:get_instance(PoolName), ?assertEqual(StoppedStatus, disconnected), ?assertEqual({error,health_check_failed}, emqx_resource:health_check(PoolName)), % Resource healthcheck shortcuts things by checking ets. Go deeper by checking pool itself. @@ -89,8 +96,11 @@ perform_lifecycle_check(PoolName, InitialConfig) -> % Can call stop/1 again on an already stopped instance ?assertEqual(ok, emqx_resource:stop(PoolName)), % Make sure it can be restarted and the healthchecks and queries work properly - ?assertEqual(ok, emqx_resource:restart(PoolName, #{wait_connected => 1000})), - {ok, ?CONNECTOR_RESOURCE_GROUP, #{status := InitialStatus}} = emqx_resource:get_instance(PoolName), + ?assertEqual(ok, emqx_resource:restart(PoolName)), + % async restart, need to wait resource + timer:sleep(500), + {ok, ?CONNECTOR_RESOURCE_GROUP, #{status := InitialStatus}} + = emqx_resource:get_instance(PoolName), ?assertEqual(ok, emqx_resource:health_check(PoolName)), ?assertMatch({ok, _, [{1}]}, emqx_resource:query(PoolName, test_query_no_params())), ?assertMatch({ok, _, [{1}]}, emqx_resource:query(PoolName, test_query_with_params())), diff --git a/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl b/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl index 2b8495dac..f1fcee67c 100644 --- a/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl +++ b/apps/emqx_connector/test/emqx_connector_redis_SUITE.erl @@ -78,24 +78,30 @@ t_sentinel_lifecycle(_Config) -> ). perform_lifecycle_check(PoolName, InitialConfig, RedisCommand) -> - {ok, #{config := CheckedConfig}} = emqx_resource:check_config(?REDIS_RESOURCE_MOD, InitialConfig), - {ok, #{state := #{poolname := ReturnedPoolName} = State, status := InitialStatus}} = emqx_resource:create_local( + {ok, #{config := CheckedConfig}} = + emqx_resource:check_config(?REDIS_RESOURCE_MOD, InitialConfig), + {ok, #{state := #{poolname := ReturnedPoolName} = State, + status := InitialStatus}} = emqx_resource:create_local( PoolName, ?CONNECTOR_RESOURCE_GROUP, ?REDIS_RESOURCE_MOD, CheckedConfig, - #{wait_connected => 1000} + #{waiting_connect_complete => 5000} ), ?assertEqual(InitialStatus, connected), % Instance should match the state and status of the just started resource - {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, status := InitialStatus}} = emqx_resource:get_instance(PoolName), + {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, + status := InitialStatus}} + = emqx_resource:get_instance(PoolName), ?assertEqual(ok, emqx_resource:health_check(PoolName)), % Perform query as further check that the resource is working as expected ?assertEqual({ok, <<"PONG">>}, emqx_resource:query(PoolName, {cmd, RedisCommand})), ?assertEqual(ok, emqx_resource:stop(PoolName)), % Resource will be listed still, but state will be changed and healthcheck will fail % as the worker no longer exists. - {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, status := StoppedStatus}} = emqx_resource:get_instance(PoolName), + {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State, + status := StoppedStatus}} + = emqx_resource:get_instance(PoolName), ?assertEqual(StoppedStatus, disconnected), ?assertEqual({error,health_check_failed}, emqx_resource:health_check(PoolName)), % Resource healthcheck shortcuts things by checking ets. Go deeper by checking pool itself. @@ -103,8 +109,11 @@ perform_lifecycle_check(PoolName, InitialConfig, RedisCommand) -> % Can call stop/1 again on an already stopped instance ?assertEqual(ok, emqx_resource:stop(PoolName)), % Make sure it can be restarted and the healthchecks and queries work properly - ?assertEqual(ok, emqx_resource:restart(PoolName, #{wait_connected => 1000})), - {ok, ?CONNECTOR_RESOURCE_GROUP, #{status := InitialStatus}} = emqx_resource:get_instance(PoolName), + ?assertEqual(ok, emqx_resource:restart(PoolName)), + % async restart, need to wait resource + timer:sleep(500), + {ok, ?CONNECTOR_RESOURCE_GROUP, #{status := InitialStatus}} + = emqx_resource:get_instance(PoolName), ?assertEqual(ok, emqx_resource:health_check(PoolName)), ?assertEqual({ok, <<"PONG">>}, emqx_resource:query(PoolName, {cmd, RedisCommand})), % Stop and remove the resource in one go. diff --git a/apps/emqx_resource/include/emqx_resource.hrl b/apps/emqx_resource/include/emqx_resource.hrl index cd10f9fa4..fdddcdc87 100644 --- a/apps/emqx_resource/include/emqx_resource.hrl +++ b/apps/emqx_resource/include/emqx_resource.hrl @@ -32,7 +32,7 @@ -type create_opts() :: #{ health_check_interval => integer(), health_check_timeout => integer(), - wait_connected => integer() + waiting_connect_complete => integer() }. -type after_query() :: {[OnSuccess :: after_query_fun()], [OnFailed :: after_query_fun()]} | undefined. diff --git a/apps/emqx_resource/src/emqx_resource.erl b/apps/emqx_resource/src/emqx_resource.erl index 5957222cb..d59835123 100644 --- a/apps/emqx_resource/src/emqx_resource.erl +++ b/apps/emqx_resource/src/emqx_resource.erl @@ -147,7 +147,11 @@ create(InstId, Group, ResourceType, Config, Opts) -> create_local(InstId, Group, ResourceType, Config) -> create_local(InstId, Group, ResourceType, Config, #{}). --spec create_local(instance_id(), resource_group(), resource_type(), resource_config(), create_opts()) -> +-spec create_local(instance_id(), + resource_group(), + resource_type(), + resource_config(), + create_opts()) -> {ok, resource_data() | 'already_created'} | {error, Reason :: term()}. create_local(InstId, Group, ResourceType, Config, Opts) -> call_instance(InstId, {create, InstId, Group, ResourceType, Config, Opts}). @@ -228,7 +232,8 @@ health_check(InstId) -> set_resource_status_connecting(InstId) -> call_instance(InstId, {set_resource_status_connecting, InstId}). --spec get_instance(instance_id()) -> {ok, resource_group(), resource_data()} | {error, Reason :: term()}. +-spec get_instance(instance_id()) -> + {ok, resource_group(), resource_data()} | {error, Reason :: term()}. get_instance(InstId) -> emqx_resource_instance:lookup(InstId). @@ -273,35 +278,54 @@ call_stop(InstId, Mod, ResourceState) -> check_config(ResourceType, Conf) -> emqx_hocon:check(ResourceType, Conf). --spec check_and_create(instance_id(), resource_group(), resource_type(), raw_resource_config()) -> +-spec check_and_create(instance_id(), + resource_group(), + resource_type(), + raw_resource_config()) -> {ok, resource_data() | 'already_created'} | {error, term()}. check_and_create(InstId, Group, ResourceType, RawConfig) -> check_and_create(InstId, Group, ResourceType, RawConfig, #{}). --spec check_and_create(instance_id(), resource_group(), resource_type(), raw_resource_config(), create_opts()) -> +-spec check_and_create(instance_id(), + resource_group(), + resource_type(), + raw_resource_config(), + create_opts()) -> {ok, resource_data() | 'already_created'} | {error, term()}. check_and_create(InstId, Group, ResourceType, RawConfig, Opts) -> check_and_do(ResourceType, RawConfig, fun(InstConf) -> create(InstId, Group, ResourceType, InstConf, Opts) end). --spec check_and_create_local(instance_id(), resource_group(), resource_type(), raw_resource_config()) -> +-spec check_and_create_local(instance_id(), + resource_group(), + resource_type(), + raw_resource_config()) -> {ok, resource_data()} | {error, term()}. check_and_create_local(InstId, Group, ResourceType, RawConfig) -> check_and_create_local(InstId, Group, ResourceType, RawConfig, #{}). --spec check_and_create_local(instance_id(), resource_group(), resource_type(), raw_resource_config(), +-spec check_and_create_local(instance_id(), + resource_group(), + resource_type(), + raw_resource_config(), create_opts()) -> {ok, resource_data()} | {error, term()}. check_and_create_local(InstId, Group, ResourceType, RawConfig, Opts) -> check_and_do(ResourceType, RawConfig, fun(InstConf) -> create_local(InstId, Group, ResourceType, InstConf, Opts) end). --spec check_and_recreate(instance_id(), resource_type(), raw_resource_config(), create_opts()) -> +-spec check_and_recreate(instance_id(), + resource_type(), + raw_resource_config(), + create_opts()) -> {ok, resource_data()} | {error, term()}. check_and_recreate(InstId, ResourceType, RawConfig, Opts) -> check_and_do(ResourceType, RawConfig, fun(InstConf) -> recreate(InstId, ResourceType, InstConf, Opts) end). --spec check_and_recreate_local(instance_id(), resource_type(), raw_resource_config(), create_opts()) -> +-spec check_and_recreate_local(instance_id(), + resource_type(), + raw_resource_config(), + create_opts()) -> {ok, resource_data()} | {error, term()}. check_and_recreate_local(InstId, ResourceType, RawConfig, Opts) -> check_and_do(ResourceType, RawConfig, diff --git a/apps/emqx_resource/src/emqx_resource_health_check.erl b/apps/emqx_resource/src/emqx_resource_health_check.erl index 6d4abc9cc..0faaebabb 100644 --- a/apps/emqx_resource/src/emqx_resource_health_check.erl +++ b/apps/emqx_resource/src/emqx_resource_health_check.erl @@ -54,7 +54,7 @@ delete_checker(Name) -> case supervisor:terminate_child(?SUP, ?ID(Name)) of ok -> supervisor:delete_child(?SUP, ?ID(Name)); Error -> Error - end. + end. start_health_check(Name, Sleep, Timeout) -> Pid = self(), diff --git a/apps/emqx_resource/src/emqx_resource_instance.erl b/apps/emqx_resource/src/emqx_resource_instance.erl index ea88b24bd..b828f1b40 100644 --- a/apps/emqx_resource/src/emqx_resource_instance.erl +++ b/apps/emqx_resource/src/emqx_resource_instance.erl @@ -90,9 +90,9 @@ list_all() -> end. -spec list_group(resource_group()) -> [instance_id()]. -list_group(Group) -> +list_group(Group) -> List = ets:match(emqx_resource_instance, {'$1', Group, '_'}), - lists:map(fun([A|_]) -> A end, List). + lists:map(fun([A | _]) -> A end, List). %%------------------------------------------------------------------------------ %% gen_server callbacks @@ -197,7 +197,7 @@ do_create(InstId, Group, ResourceType, Config, Opts) -> ok -> ok = emqx_plugin_libs_metrics:create_metrics(resource_metrics, InstId, [matched, success, failed, exception], [matched]), - WaitTime = maps:get(wait_connected, Opts, 0), + WaitTime = maps:get(waiting_connect_complete , Opts, 0), {ok, wait_for_resource_ready(InstId, WaitTime div 100)}; Error -> Error diff --git a/apps/emqx_retainer/src/emqx_retainer.erl b/apps/emqx_retainer/src/emqx_retainer.erl index 49cb563e3..0a1b769a8 100644 --- a/apps/emqx_retainer/src/emqx_retainer.erl +++ b/apps/emqx_retainer/src/emqx_retainer.erl @@ -360,7 +360,8 @@ create_resource(Context, #{type := DB} = Config) -> ResourceID, <<"emqx_retainer">>, list_to_existing_atom(io_lib:format("~ts_~ts", [emqx_connector, DB])), - Config) of + Config, + #{waiting_connect_complete => 5000}) of {ok, already_created} -> Context#{resource_id => ResourceID}; {ok, _} -> From b7674fd19f2ca1f03b79ce1b82b06ccd935a0ea8 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 9 Mar 2022 16:35:30 +0800 Subject: [PATCH 10/10] fix(emqx_authz_file_SUITE): fix config_update_crashed error --- apps/emqx_authz/test/emqx_authz_file_SUITE.erl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/emqx_authz/test/emqx_authz_file_SUITE.erl b/apps/emqx_authz/test/emqx_authz_file_SUITE.erl index d2a6a8df8..74bbf8a92 100644 --- a/apps/emqx_authz/test/emqx_authz_file_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_file_SUITE.erl @@ -36,6 +36,7 @@ init_per_suite(Config) -> end_per_suite(_Config) -> ok = emqx_authz_test_lib:restore_authorizers(), + ok = stop_apps([emqx_resource, emqx_connector]), ok = emqx_common_test_helpers:stop_apps([emqx_authz]). init_per_testcase(_TestCase, Config) -> @@ -128,3 +129,6 @@ setup_config(SpecialParams) -> emqx_authz_test_lib:setup_config( raw_file_authz_config(), SpecialParams). + +stop_apps(Apps) -> + lists:foreach(fun application:stop/1, Apps).