emqx_postgresql_SUITE.erl 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. % %%--------------------------------------------------------------------
  2. % %% Copyright (c) 2020-2024 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. % %% http://www.apache.org/licenses/LICENSE-2.0
  8. % %%
  9. % %% Unless required by applicable law or agreed to in writing, software
  10. % %% distributed under the License is distributed on an "AS IS" BASIS,
  11. % %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. % %% See the License for the specific language governing permissions and
  13. % %% limitations under the License.
  14. % %%--------------------------------------------------------------------
  15. -module(emqx_postgresql_SUITE).
  16. -compile(nowarn_export_all).
  17. -compile(export_all).
  18. -include("../../emqx_connector/include/emqx_connector.hrl").
  19. -include_lib("emqx_postgresql/include/emqx_postgresql.hrl").
  20. -include_lib("eunit/include/eunit.hrl").
  21. -include_lib("common_test/include/ct.hrl").
  22. -include_lib("emqx/include/emqx.hrl").
  23. -include_lib("stdlib/include/assert.hrl").
  24. -define(PGSQL_HOST, "pgsql").
  25. -define(PGSQL_RESOURCE_MOD, emqx_postgresql).
  26. all() ->
  27. emqx_common_test_helpers:all(?MODULE).
  28. groups() ->
  29. [].
  30. init_per_suite(Config) ->
  31. case emqx_common_test_helpers:is_tcp_server_available(?PGSQL_HOST, ?PGSQL_DEFAULT_PORT) of
  32. true ->
  33. Apps = emqx_cth_suite:start(
  34. [emqx_conf, emqx_connector],
  35. #{work_dir => emqx_cth_suite:work_dir(Config)}
  36. ),
  37. [{apps, Apps} | Config];
  38. false ->
  39. {skip, no_pgsql}
  40. end.
  41. end_per_suite(Config) ->
  42. Apps = ?config(apps, Config),
  43. emqx_cth_suite:stop(Apps),
  44. ok.
  45. init_per_testcase(_, Config) ->
  46. Config.
  47. end_per_testcase(_, _Config) ->
  48. ok.
  49. % %%------------------------------------------------------------------------------
  50. % %% Testcases
  51. % %%------------------------------------------------------------------------------
  52. t_lifecycle(_Config) ->
  53. perform_lifecycle_check(
  54. <<"emqx_postgresql_SUITE">>,
  55. pgsql_config()
  56. ).
  57. perform_lifecycle_check(ResourceId, InitialConfig) ->
  58. {ok, #{config := CheckedConfig}} =
  59. emqx_resource:check_config(?PGSQL_RESOURCE_MOD, InitialConfig),
  60. {ok, #{
  61. state := #{pool_name := PoolName} = State,
  62. status := InitialStatus
  63. }} =
  64. emqx_resource:create_local(
  65. ResourceId,
  66. ?CONNECTOR_RESOURCE_GROUP,
  67. ?PGSQL_RESOURCE_MOD,
  68. CheckedConfig,
  69. #{}
  70. ),
  71. ?assertEqual(InitialStatus, connected),
  72. % Instance should match the state and status of the just started resource
  73. {ok, ?CONNECTOR_RESOURCE_GROUP, #{
  74. state := State,
  75. status := InitialStatus
  76. }} =
  77. emqx_resource:get_instance(ResourceId),
  78. ?assertEqual({ok, connected}, emqx_resource:health_check(ResourceId)),
  79. % % Perform query as further check that the resource is working as expected
  80. ?assertMatch({ok, _, [{1}]}, emqx_resource:query(ResourceId, test_query_no_params())),
  81. ?assertMatch({ok, _, [{1}]}, emqx_resource:query(ResourceId, test_query_with_params())),
  82. ?assertEqual(ok, emqx_resource:stop(ResourceId)),
  83. % Resource will be listed still, but state will be changed and healthcheck will fail
  84. % as the worker no longer exists.
  85. {ok, ?CONNECTOR_RESOURCE_GROUP, #{
  86. state := State,
  87. status := StoppedStatus
  88. }} =
  89. emqx_resource:get_instance(ResourceId),
  90. ?assertEqual(stopped, StoppedStatus),
  91. ?assertEqual({error, resource_is_stopped}, emqx_resource:health_check(ResourceId)),
  92. % Resource healthcheck shortcuts things by checking ets. Go deeper by checking pool itself.
  93. ?assertEqual({error, not_found}, ecpool:stop_sup_pool(PoolName)),
  94. % Can call stop/1 again on an already stopped instance
  95. ?assertEqual(ok, emqx_resource:stop(ResourceId)),
  96. % Make sure it can be restarted and the healthchecks and queries work properly
  97. ?assertEqual(ok, emqx_resource:restart(ResourceId)),
  98. % async restart, need to wait resource
  99. timer:sleep(500),
  100. {ok, ?CONNECTOR_RESOURCE_GROUP, #{status := InitialStatus}} =
  101. emqx_resource:get_instance(ResourceId),
  102. ?assertEqual({ok, connected}, emqx_resource:health_check(ResourceId)),
  103. ?assertMatch({ok, _, [{1}]}, emqx_resource:query(ResourceId, test_query_no_params())),
  104. ?assertMatch({ok, _, [{1}]}, emqx_resource:query(ResourceId, test_query_with_params())),
  105. % Stop and remove the resource in one go.
  106. ?assertEqual(ok, emqx_resource:remove_local(ResourceId)),
  107. ?assertEqual({error, not_found}, ecpool:stop_sup_pool(PoolName)),
  108. % Should not even be able to get the resource data out of ets now unlike just stopping.
  109. ?assertEqual({error, not_found}, emqx_resource:get_instance(ResourceId)).
  110. % %%------------------------------------------------------------------------------
  111. % %% Helpers
  112. % %%------------------------------------------------------------------------------
  113. pgsql_config() ->
  114. RawConfig = list_to_binary(
  115. io_lib:format(
  116. ""
  117. "\n"
  118. " auto_reconnect = true\n"
  119. " database = mqtt\n"
  120. " username= root\n"
  121. " password = public\n"
  122. " pool_size = 8\n"
  123. " server = \"~s:~b\"\n"
  124. " "
  125. "",
  126. [?PGSQL_HOST, ?PGSQL_DEFAULT_PORT]
  127. )
  128. ),
  129. {ok, Config} = hocon:binary(RawConfig),
  130. #{<<"config">> => Config}.
  131. test_query_no_params() ->
  132. {query, <<"SELECT 1">>}.
  133. test_query_with_params() ->
  134. {query, <<"SELECT $1::integer">>, [1]}.