Merge pull request #7306 from mononym/EMQX-3917-add-test-cases-for-connectors-mongo-db

refactor: refactor mongo connector test suite
This commit is contained in:
Chris Hicks 2022-03-23 14:01:26 +01:00 committed by GitHub
commit e659748153
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 72 additions and 73 deletions

View File

@ -24,7 +24,7 @@
-include_lib("stdlib/include/assert.hrl"). -include_lib("stdlib/include/assert.hrl").
-define(MONGO_HOST, "mongo"). -define(MONGO_HOST, "mongo").
-define(MONGO_CLIENT, 'emqx_connector_mongo_SUITE_client'). -define(MONGO_RESOURCE_MOD, emqx_connector_mongo).
all() -> all() ->
emqx_common_test_helpers:all(?MODULE). emqx_common_test_helpers:all(?MODULE).
@ -35,99 +35,98 @@ groups() ->
init_per_suite(Config) -> init_per_suite(Config) ->
case emqx_common_test_helpers:is_tcp_server_available(?MONGO_HOST, ?MONGO_DEFAULT_PORT) of case emqx_common_test_helpers:is_tcp_server_available(?MONGO_HOST, ?MONGO_DEFAULT_PORT) of
true -> true ->
ok = emqx_connector_test_helpers:start_apps([ecpool, mongodb]), ok = emqx_common_test_helpers:start_apps([emqx_conf]),
ok = emqx_connector_test_helpers:start_apps([emqx_resource, emqx_connector]),
Config; Config;
false -> false ->
{skip, no_mongo} {skip, no_mongo}
end. end.
end_per_suite(_Config) -> end_per_suite(_Config) ->
ok = emqx_connector_test_helpers:stop_apps([ecpool, mongodb]). ok = emqx_common_test_helpers:stop_apps([emqx_conf]),
ok = emqx_connector_test_helpers:stop_apps([emqx_resource, emqx_connector]).
init_per_testcase(_, Config) -> init_per_testcase(_, Config) ->
?assertEqual(
{ok, #{poolname => emqx_connector_mongo, type => single}},
emqx_connector_mongo:on_start(<<"emqx_connector_mongo">>, mongo_config())
),
Config. Config.
end_per_testcase(_, _Config) -> end_per_testcase(_, _Config) ->
?assertEqual( ok.
ok,
emqx_connector_mongo:on_stop(<<"emqx_connector_mongo">>, #{poolname => emqx_connector_mongo})
).
% %%------------------------------------------------------------------------------ % %%------------------------------------------------------------------------------
% %% Testcases % %% Testcases
% %%------------------------------------------------------------------------------ % %%------------------------------------------------------------------------------
% Simple test to make sure the proper reference to the module is returned. t_lifecycle(_Config) ->
t_roots(_Config) -> perform_lifecycle_check(
ExpectedRoots = [ <<"emqx_connector_mongo_SUITE">>,
{config, #{ mongo_config()
type =>
{union, [
{ref, emqx_connector_mongo, single},
{ref, emqx_connector_mongo, rs},
{ref, emqx_connector_mongo, sharded}
]}
}}
],
ActualRoots = emqx_connector_mongo:roots(),
?assertEqual(ExpectedRoots, ActualRoots).
% Not sure if this level of testing is appropriate for this function.
% Checking the actual values/types of the returned term starts getting
% into checking the emqx_connector_schema_lib.erl returns and the shape
% of expected data elsewhere.
t_fields(_Config) ->
AllFieldTypes = [single, rs, sharded, topology],
lists:foreach(
fun(FieldType) ->
Fields = emqx_connector_mongo:fields(FieldType),
lists:foreach(fun emqx_connector_test_helpers:check_fields/1, Fields)
end,
AllFieldTypes
). ).
% Execute a minimal query to validate connection. perform_lifecycle_check(PoolName, InitialConfig) ->
t_basic_query(_Config) -> {ok, #{config := CheckedConfig}} =
?assertMatch( emqx_resource:check_config(?MONGO_RESOURCE_MOD, InitialConfig),
[], {ok, #{state := #{poolname := ReturnedPoolName} = State,
emqx_connector_mongo:on_query( status := InitialStatus}}
<<"emqx_connector_mongo">>, {find, <<"connector">>, #{}, #{}}, undefined, #{ = emqx_resource:create_local(
poolname => emqx_connector_mongo PoolName,
} ?CONNECTOR_RESOURCE_GROUP,
) ?MONGO_RESOURCE_MOD,
). CheckedConfig,
#{}
% Perform health check. ),
t_do_healthcheck(_Config) -> ?assertEqual(InitialStatus, connected),
?assertEqual( % Instance should match the state and status of the just started resource
{ok, #{poolname => emqx_connector_mongo}}, {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State,
emqx_connector_mongo:on_health_check(<<"emqx_connector_mongo">>, #{ status := InitialStatus}}
poolname => emqx_connector_mongo = 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([], emqx_resource:query(PoolName, test_query_find())),
% Perform healthcheck on a connector that does not exist. ?assertMatch(undefined, emqx_resource:query(PoolName, test_query_find_one())),
t_healthceck_when_connector_does_not_exist(_Config) -> ?assertEqual(ok, emqx_resource:stop(PoolName)),
?assertEqual( % Resource will be listed still, but state will be changed and healthcheck will fail
{error, health_check_failed, #{poolname => emqx_connector_mongo_does_not_exist}}, % as the worker no longer exists.
emqx_connector_mongo:on_health_check(<<"emqx_connector_mongo_does_not_exist">>, #{ {ok, ?CONNECTOR_RESOURCE_GROUP, #{state := State,
poolname => emqx_connector_mongo_does_not_exist 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.
?assertEqual({error, not_found}, ecpool:stop_sup_pool(ReturnedPoolName)),
% 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)),
% 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([], emqx_resource:query(PoolName, test_query_find())),
?assertMatch(undefined, emqx_resource:query(PoolName, test_query_find_one())),
% Stop and remove the resource in one go.
?assertEqual(ok, emqx_resource:remove_local(PoolName)),
?assertEqual({error, not_found}, ecpool:stop_sup_pool(ReturnedPoolName)),
% Should not even be able to get the resource data out of ets now unlike just stopping.
?assertEqual({error, not_found}, emqx_resource:get_instance(PoolName)).
% %%------------------------------------------------------------------------------ % %%------------------------------------------------------------------------------
% %% Helpers % %% Helpers
% %%------------------------------------------------------------------------------ % %%------------------------------------------------------------------------------
mongo_config() -> mongo_config() ->
#{ RawConfig = list_to_binary(io_lib:format("""
mongo_type => single, mongo_type = single
pool_size => 8, database = mqtt
ssl => #{enable => false}, pool_size = 8
srv_record => false, server = \"~s:~b\"
server => {<<?MONGO_HOST>>, ?MONGO_DEFAULT_PORT} """, [?MONGO_HOST, ?MONGO_DEFAULT_PORT])),
}.
{ok, Config} = hocon:binary(RawConfig),
#{<<"config">> => Config}.
test_query_find() ->
{find, <<"foo">>, #{}, #{}}.
test_query_find_one() ->
{find_one, <<"foo">>, #{}, #{}}.