emqx_mongodb_tests.erl 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2022-2023 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(emqx_mongodb_tests).
  17. -include_lib("eunit/include/eunit.hrl").
  18. srv_record_test() ->
  19. with_dns_mock(
  20. fun normal_dns_resolution_mock/2,
  21. fun() ->
  22. Single = single_config(),
  23. Rs = simple_rs_config(),
  24. Hosts = [
  25. <<"cluster0-shard-00-02.zkemc.mongodb.net:27017">>,
  26. <<"cluster0-shard-00-01.zkemc.mongodb.net:27017">>,
  27. <<"cluster0-shard-00-00.zkemc.mongodb.net:27017">>
  28. ],
  29. ?assertMatch(
  30. #{
  31. hosts := Hosts,
  32. auth_source := <<"admin">>
  33. },
  34. resolve(Single)
  35. ),
  36. ?assertMatch(
  37. #{
  38. hosts := Hosts,
  39. auth_source := <<"admin">>,
  40. replica_set_name := <<"atlas-wrnled-shard-0">>
  41. },
  42. resolve(Rs)
  43. ),
  44. ok
  45. end
  46. ).
  47. empty_srv_record_test() ->
  48. with_dns_mock(
  49. bad_srv_record_mock(_DnsResolution = []),
  50. fun() ->
  51. ?assertThrow(#{reason := "failed_to_resolve_srv_record"}, resolve(simple_rs_config()))
  52. end
  53. ).
  54. empty_txt_record_test() ->
  55. with_dns_mock(
  56. bad_txt_record_mock(_DnsResolution = []),
  57. fun() ->
  58. Config = resolve(single_config()),
  59. ?assertNot(maps:is_key(auth_source, Config)),
  60. ?assertNot(maps:is_key(replica_set_name, Config)),
  61. ok
  62. end
  63. ).
  64. multiple_txt_records_test() ->
  65. with_dns_mock(
  66. bad_txt_record_mock(_DnsResolution = [1, 2]),
  67. fun() ->
  68. ?assertThrow(#{reason := "multiple_txt_records"}, resolve(simple_rs_config()))
  69. end
  70. ).
  71. bad_query_string_test() ->
  72. with_dns_mock(
  73. bad_txt_record_mock(_DnsResolution = [["%-111"]]),
  74. fun() ->
  75. ?assertThrow(#{reason := "bad_txt_record_resolution"}, resolve(simple_rs_config()))
  76. end
  77. ).
  78. resolve(Config) ->
  79. emqx_mongodb:maybe_resolve_srv_and_txt_records(Config).
  80. checked_config(Hocon) ->
  81. {ok, Config} = hocon:binary(Hocon),
  82. hocon_tconf:check_plain(
  83. emqx_mongodb,
  84. #{<<"config">> => Config},
  85. #{atom_key => true}
  86. ).
  87. simple_rs_config() ->
  88. #{config := Rs} = checked_config(
  89. "mongo_type = rs\n"
  90. "servers = \"cluster0.zkemc.mongodb.net:27017\"\n"
  91. "srv_record = true\n"
  92. "database = foobar\n"
  93. "replica_set_name = configured_replicaset_name\n"
  94. ),
  95. Rs.
  96. single_config() ->
  97. #{config := Single} = checked_config(
  98. "mongo_type = single\n"
  99. "server = \"cluster0.zkemc.mongodb.net:27017,cluster0.zkemc.mongodb.net:27017\"\n"
  100. "srv_record = true\n"
  101. "database = foobar\n"
  102. ),
  103. Single.
  104. normal_srv_resolution() ->
  105. [
  106. {0, 0, 27017, "cluster0-shard-00-02.zkemc.mongodb.net"},
  107. {0, 0, 27017, "cluster0-shard-00-01.zkemc.mongodb.net"},
  108. {0, 0, 27017, "cluster0-shard-00-00.zkemc.mongodb.net"}
  109. ].
  110. normal_txt_resolution() ->
  111. [["authSource=admin&replicaSet=atlas-wrnled-shard-0"]].
  112. normal_dns_resolution_mock("_mongodb._tcp.cluster0.zkemc.mongodb.net", srv) ->
  113. normal_srv_resolution();
  114. normal_dns_resolution_mock("cluster0.zkemc.mongodb.net", txt) ->
  115. normal_txt_resolution().
  116. bad_srv_record_mock(DnsResolution) ->
  117. fun("_mongodb._tcp.cluster0.zkemc.mongodb.net", srv) ->
  118. DnsResolution
  119. end.
  120. bad_txt_record_mock(DnsResolution) ->
  121. fun
  122. ("_mongodb._tcp.cluster0.zkemc.mongodb.net", srv) ->
  123. normal_srv_resolution();
  124. ("cluster0.zkemc.mongodb.net", txt) ->
  125. DnsResolution
  126. end.
  127. with_dns_mock(MockFn, TestFn) ->
  128. meck:new(emqx_connector_lib, [non_strict, passthrough, no_history, no_link]),
  129. meck:expect(emqx_connector_lib, resolve_dns, MockFn),
  130. try
  131. TestFn()
  132. after
  133. meck:unload(emqx_connector_lib)
  134. end,
  135. ok.