1: %%==============================================================================
    2: %% Copyright 2018 Erlang Solutions Ltd.
    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: 
   17: -module(gen_mod_SUITE).
   18: -compile([export_all, nowarn_export_all]).
   19: -author('bartlomiej.gorny@erlang-solutions.com').
   20: 
   21: -include_lib("eunit/include/eunit.hrl").
   22: 
   23: %%--------------------------------------------------------------------
   24: %% Suite configuration
   25: %%--------------------------------------------------------------------
   26: 
   27: all() ->
   28:     [start_and_stop,
   29:      start_error,
   30:      start_with_service_deps,
   31:      stop_error,
   32:      loaded_modules,
   33:      loaded_modules_with_opts,
   34:      get_module_opt,
   35:      lookup_module_opt,
   36:      hosts_with_module,
   37:      hosts_and_opts_with_module].
   38: 
   39: init_per_testcase(_, Config) ->
   40:     mongoose_config:set_opts(opts()),
   41:     [setup_meck(Module) || Module <- [a_module, b_module]],
   42:     Config.
   43: 
   44: end_per_testcase(_, Config) ->
   45:     mongoose_config:erase_opts(),
   46:     [meck:unload(Module) || Module <- [a_module, b_module]],
   47:     Config.
   48: 
   49: start_and_stop(_Config) ->
   50:     ?assertEqual({ok, ok}, gen_mod:start_module(host(a), a_module, #{})),
   51:     ?assertError(#{what := module_not_loaded}, gen_mod:start_module(host(a), b_module, #{k => v})),
   52:     ?assertError(#{what := module_not_loaded}, gen_mod:start_module(host(b), a_module, #{})),
   53:     ?assertEqual({ok, ok}, gen_mod:start_module(host(b), b_module, #{k => v})),
   54:     ?assertEqual(ok, gen_mod:stop_module(host(a), a_module)),
   55:     ?assertError(#{what := module_not_loaded}, gen_mod:stop_module(host(a), b_module)),
   56:     ?assertError(#{what := module_not_loaded}, gen_mod:stop_module(host(b), a_module)),
   57:     ?assertEqual(ok, gen_mod:stop_module(host(b), b_module)).
   58: 
   59: start_error(_Config) ->
   60:     meck:expect(a_module, start, fun(_, _) -> error(bad_weather) end),
   61:     ?assertError(bad_weather, gen_mod:start_module(host(a), a_module, #{})).
   62: 
   63: start_with_service_deps(_Config) ->
   64:     meck:expect(a_module, deps, fun(_, _) -> [{service, a_service}] end),
   65:     ?assertError(#{what := service_not_loaded}, gen_mod:start_module(host(a), a_module, #{})),
   66:     mongoose_config:set_opt(services, #{a_service => #{}}),
   67:     ?assertEqual({ok, ok}, gen_mod:start_module(host(a), a_module, #{})).
   68: 
   69: stop_error(_Config) ->
   70:     meck:expect(a_module, stop, fun(_) -> error(bad_mood) end),
   71:     ?assertError(bad_mood, gen_mod:stop_module(host(a), a_module)).
   72: 
   73: loaded_modules(_Config) ->
   74:     ?assertEqual([a_module], gen_mod:loaded_modules(host(a))),
   75:     ?assertEqual([b_module], gen_mod:loaded_modules(host(b))),
   76:     ?assertEqual([a_module, b_module], gen_mod:loaded_modules()).
   77: 
   78: loaded_modules_with_opts(_Config) ->
   79:     MA = #{a_module => #{}},
   80:     MB = #{b_module => #{k => v}},
   81:     ?assertEqual(MA, gen_mod:loaded_modules_with_opts(host(a))),
   82:     ?assertEqual(MB, gen_mod:loaded_modules_with_opts(host(b))),
   83:     ?assertEqual(#{host(a) => MA, host(b) => MB}, gen_mod:loaded_modules_with_opts()).
   84: 
   85: get_module_opt(_Config) ->
   86:     ?assertEqual(v, gen_mod:get_module_opt(host(b), b_module, k)),
   87:     ?assertError({badkey, k}, gen_mod:get_module_opt(host(a), a_module, k)),
   88:     ?assertError({badkey, b_module}, gen_mod:get_module_opt(host(a), b_module, k)),
   89:     ?assertEqual(default, gen_mod:get_module_opt(host(a), a_module, k, default)),
   90:     ?assertEqual(default, gen_mod:get_module_opt(host(a), b_module, k, default)).
   91: 
   92: lookup_module_opt(_Config) ->
   93:     ?assertEqual({ok, v}, gen_mod:lookup_module_opt(host(b), b_module, k)),
   94:     ?assertEqual({error, not_found}, gen_mod:lookup_module_opt(host(a), a_module, k)),
   95:     ?assertEqual({error, not_found}, gen_mod:lookup_module_opt(host(a), b_module, k)).
   96: 
   97: hosts_with_module(_Config) ->
   98:     ?assertEqual([host(a)], gen_mod:hosts_with_module(a_module)),
   99:     ?assertEqual([host(b)], gen_mod:hosts_with_module(b_module)).
  100: 
  101: hosts_and_opts_with_module(_Config) ->
  102:     ?assertEqual(#{host(a) => #{}}, gen_mod:hosts_and_opts_with_module(a_module)),
  103:     ?assertEqual(#{host(b) => #{k => v}}, gen_mod:hosts_and_opts_with_module(b_module)).
  104: 
  105: host(a) ->
  106:     <<"localhost">>;
  107: host(b) ->
  108:     <<"localhost.bis">>.
  109: 
  110: setup_meck(Module) ->
  111:     meck:new(Module, [non_strict]),
  112:     meck:expect(Module, start, fun(_, _) -> ok end),
  113:     meck:expect(Module, stop, fun(_) -> ok end).
  114: 
  115: opts() ->
  116:     #{hosts => [host(a), host(b)],
  117:       host_types => [],
  118:       services => #{},
  119:       {modules, host(a)} => #{a_module => #{}},
  120:       {modules, host(b)} => #{b_module => #{k => v}}}.