emqx_plugins_tests.erl 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2019-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. %%
  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_plugins_tests).
  17. -include("emqx_plugins.hrl").
  18. -include_lib("eunit/include/eunit.hrl").
  19. -compile(nowarn_export_all).
  20. -compile(export_all).
  21. ensure_configured_test_todo() ->
  22. meck_emqx(),
  23. try
  24. test_ensure_configured()
  25. after
  26. emqx_plugins:put_configured([])
  27. end,
  28. unmeck_emqx().
  29. test_ensure_configured() ->
  30. ok = emqx_plugins:put_configured([]),
  31. P1 = #{name_vsn => "p-1", enable => true},
  32. P2 = #{name_vsn => "p-2", enable => true},
  33. P3 = #{name_vsn => "p-3", enable => false},
  34. emqx_plugins:ensure_configured(P1, front, local),
  35. emqx_plugins:ensure_configured(P2, {before, <<"p-1">>}, local),
  36. emqx_plugins:ensure_configured(P3, {before, <<"p-1">>}, local),
  37. ?assertEqual([P2, P3, P1], emqx_plugins:configured()),
  38. ?assertThrow(
  39. #{error := "position_anchor_plugin_not_configured"},
  40. emqx_plugins:ensure_configured(P3, {before, <<"unknown-x">>}, local)
  41. ).
  42. read_plugin_test() ->
  43. meck_emqx(),
  44. with_rand_install_dir(
  45. fun(_Dir) ->
  46. NameVsn = "bar-5",
  47. InfoFile = emqx_plugins:info_file_path(NameVsn),
  48. FakeInfo =
  49. "name=bar, rel_vsn=\"5\", rel_apps=[justname_no_vsn],"
  50. "description=\"desc bar\"",
  51. try
  52. ok = write_file(InfoFile, FakeInfo),
  53. ?assertMatch(
  54. {error, #{error_msg := "bad_rel_apps"}},
  55. emqx_plugins:read_plugin_info(NameVsn, #{})
  56. )
  57. after
  58. emqx_plugins:purge(NameVsn)
  59. end
  60. end
  61. ),
  62. unmeck_emqx().
  63. with_rand_install_dir(F) ->
  64. N = rand:uniform(10000000),
  65. TmpDir = integer_to_list(N),
  66. OriginalInstallDir = emqx_plugins:install_dir(),
  67. ok = filelib:ensure_dir(filename:join([TmpDir, "foo"])),
  68. ok = emqx_plugins:put_config_internal(install_dir, TmpDir),
  69. try
  70. F(TmpDir)
  71. after
  72. file:del_dir_r(TmpDir),
  73. ok = emqx_plugins:put_config_internal(install_dir, OriginalInstallDir)
  74. end.
  75. write_file(Path, Content) ->
  76. ok = filelib:ensure_dir(Path),
  77. file:write_file(Path, Content).
  78. %% delete package should mostly work and return ok
  79. %% but it may fail in case the path is a directory
  80. %% or if the file is read-only
  81. delete_package_test() ->
  82. meck_emqx(),
  83. with_rand_install_dir(
  84. fun(_Dir) ->
  85. File = emqx_plugins:pkg_file_path("a-1"),
  86. ok = write_file(File, "a"),
  87. ok = emqx_plugins:delete_package("a-1"),
  88. %% delete again should be ok
  89. ok = emqx_plugins:delete_package("a-1"),
  90. Dir = File,
  91. ok = filelib:ensure_dir(filename:join([Dir, "foo"])),
  92. ?assertMatch({error, _}, emqx_plugins:delete_package("a-1"))
  93. end
  94. ),
  95. unmeck_emqx().
  96. %% purge plugin's install dir should mostly work and return ok
  97. %% but it may fail in case the dir is read-only
  98. purge_test() ->
  99. meck_emqx(),
  100. with_rand_install_dir(
  101. fun(_Dir) ->
  102. File = emqx_plugins:info_file_path("a-1"),
  103. Dir = emqx_plugins:plugin_dir("a-1"),
  104. ok = filelib:ensure_dir(File),
  105. ?assertMatch({ok, _}, file:read_file_info(Dir)),
  106. ?assertEqual(ok, emqx_plugins:purge("a-1")),
  107. %% assert the dir is gone
  108. ?assertMatch({error, enoent}, file:read_file_info(Dir)),
  109. %% write a file for the dir path
  110. ok = file:write_file(Dir, "a"),
  111. ?assertEqual(ok, emqx_plugins:purge("a-1"))
  112. end
  113. ),
  114. unmeck_emqx().
  115. meck_emqx() ->
  116. meck:new(emqx, [unstick, passthrough]),
  117. meck:new(emqx_plugins_serde),
  118. meck:expect(
  119. emqx,
  120. update_config,
  121. fun(Path, Values, _Opts) ->
  122. emqx_config:put(Path, Values)
  123. end
  124. ),
  125. meck:expect(
  126. emqx_plugins_serde,
  127. delete_schema,
  128. fun(_NameVsn) -> ok end
  129. ),
  130. ok.
  131. unmeck_emqx() ->
  132. meck:unload(emqx),
  133. meck:unload(emqx_plugins_serde),
  134. ok.