1: -module(mongoose_domain_core_SUITE). 2: 3: -compile([export_all, nowarn_export_all]). 4: 5: -include_lib("eunit/include/eunit.hrl"). 6: 7: -define(STATIC_PAIRS, [{<<"example.cfg">>, <<"type #1">>}, 8: {<<"erlang-solutions.com">>, <<"type #2">>}, 9: {<<"erlang-solutions.local">>, <<"static type">>}, %% not allowed type 10: {<<"example.org">>, <<"type #2">>}]). 11: -define(ALLOWED_TYPES, [<<"type #1">>, <<"type #2">>, <<"type #3">>]). 12: 13: -define(assertEqualLists(L1, L2), ?assertEqual(lists:sort(L1), lists:sort(L2))). 14: 15: all() -> 16: [can_get_init_arguments, 17: lookup_works, 18: double_insert_double_remove_works, 19: static_domain_check, 20: cannot_delete_static, 21: cannot_insert_static_domain, 22: cannot_insert_if_host_type_not_configured, 23: get_all_static, 24: get_domains_by_host_type, 25: host_type_check, 26: can_get_outdated_domains, 27: run_for_each_domain]. 28: 29: init_per_suite(Config) -> 30: meck:new(mongoose_lazy_routing, [no_link]), 31: meck:new(mongoose_subdomain_core, [no_link]), 32: [meck:expect(M, F, fun remove_domain_mock_fn/2) 33: || {M, F} <- [{mongoose_lazy_routing, maybe_remove_domain}, 34: {mongoose_subdomain_core, remove_domain}]], 35: meck:expect(mongoose_subdomain_core, add_domain, fun add_domain_mock_fn/2), 36: Config. 37: 38: end_per_suite(Config) -> 39: meck:unload(), 40: Config. 41: 42: init_per_testcase(_, Config) -> 43: {ok, _} = mongoose_domain_core:start_link(?STATIC_PAIRS, ?ALLOWED_TYPES), 44: [meck:reset(M) || M <- [mongoose_lazy_routing, mongoose_subdomain_core]], 45: Config. 46: 47: end_per_testcase(_, Config) -> 48: Config. 49: 50: can_get_init_arguments(_) -> 51: [?STATIC_PAIRS, ?ALLOWED_TYPES] = mongoose_domain_core:get_start_args(). 52: 53: lookup_works(_) -> 54: {ok, <<"type #1">>} = mongoose_domain_core:get_host_type(<<"example.cfg">>), 55: {ok, <<"static type">>} = mongoose_domain_core:get_host_type(<<"erlang-solutions.local">>), 56: {error, not_found} = mongoose_domain_core:get_host_type(<<"some.domain">>), 57: ok = mongoose_domain_core:insert(<<"some.domain">>, <<"type #3">>, dummy_src), 58: add_domain_mock_is_executed_only_one_time(<<"type #3">>, <<"some.domain">>), 59: {ok, <<"type #3">>} = mongoose_domain_core:get_host_type(<<"some.domain">>), 60: ok = mongoose_domain_core:delete(<<"some.domain">>), 61: {error, not_found} = mongoose_domain_core:get_host_type(<<"some.domain">>), 62: remove_domain_mocks_are_executed_only_one_time(<<"type #3">>, <<"some.domain">>). 63: 64: double_insert_double_remove_works(_) -> 65: {error, not_found} = mongoose_domain_core:get_host_type(<<"some.domain">>), 66: ok = mongoose_domain_core:insert(<<"some.domain">>, <<"type #3">>, dummy_src), 67: ok = mongoose_domain_core:insert(<<"some.domain">>, <<"type #3">>, dummy_src), 68: {ok, <<"type #3">>} = mongoose_domain_core:get_host_type(<<"some.domain">>), 69: add_domain_mock_is_executed_only_one_time(<<"type #3">>, <<"some.domain">>), 70: ok = mongoose_domain_core:delete(<<"some.domain">>), 71: ok = mongoose_domain_core:delete(<<"some.domain">>), 72: {error, not_found} = mongoose_domain_core:get_host_type(<<"some.domain">>), 73: remove_domain_mocks_are_executed_only_one_time(<<"type #3">>, <<"some.domain">>). 74: 75: static_domain_check(_) -> 76: true = mongoose_domain_core:is_static(<<"example.cfg">>), 77: false = mongoose_domain_core:is_static(<<"some.domain">>), %% not configured yet 78: ok = mongoose_domain_core:insert(<<"some.domain">>, <<"type #1">>, dummy_src), 79: false = mongoose_domain_core:is_static(<<"some.domain">>). 80: 81: cannot_delete_static(_) -> 82: {error, static} = mongoose_domain_core:delete(<<"example.cfg">>), 83: {error, static} = mongoose_domain_core:delete(<<"erlang-solutions.local">>), 84: remove_domain_mocks_are_not_executed(). 85: 86: cannot_insert_static_domain(_) -> 87: {error, static} = mongoose_domain_core:insert(<<"example.cfg">>, <<"type #1">>, dummy_src), 88: {error, static} = mongoose_domain_core:insert(<<"erlang-solutions.local">>, <<"type #3">>, 89: dummy_src), 90: add_domain_mock_is_not_executed(). 91: 92: 93: cannot_insert_if_host_type_not_configured(_) -> 94: {ok, StaticHostType} = mongoose_domain_core:get_host_type(<<"erlang-solutions.local">>), 95: {error, unknown_host_type} = mongoose_domain_core:insert(<<"erlang-solutions.local">>, 96: StaticHostType, dummy_src), 97: {error, unknown_host_type} = mongoose_domain_core:insert(<<"erlang-solutions.local">>, 98: <<"invalid type">>, dummy_src), 99: add_domain_mock_is_not_executed(). 100: 101: %% See also db_get_all_static 102: get_all_static(_) -> 103: ok = mongoose_domain_core:insert(<<"some.domain">>, <<"type #1">>, dummy_src), 104: ?assertEqualLists(?STATIC_PAIRS, mongoose_domain_core:get_all_static()). 105: 106: get_domains_by_host_type(_) -> 107: ?assertEqualLists([<<"erlang-solutions.com">>, <<"example.org">>], 108: lists:sort(mongoose_domain_core:get_domains_by_host_type(<<"type #2">>))), 109: [<<"example.cfg">>] = mongoose_domain_core:get_domains_by_host_type(<<"type #1">>), 110: [<<"erlang-solutions.local">>] = mongoose_domain_core:get_domains_by_host_type(<<"static type">>), 111: [] = mongoose_domain_core:get_domains_by_host_type(<<"invalid type">>), 112: %% just no configured domains for this host type 113: [] = mongoose_domain_core:get_domains_by_host_type(<<"type #3">>), 114: ok = mongoose_domain_core:insert(<<"some.domain">>, <<"type #3">>, dummy_src), 115: [<<"some.domain">>] = mongoose_domain_core:get_domains_by_host_type(<<"type #3">>). 116: 117: host_type_check(_) -> 118: {ok, StaticHostType} = mongoose_domain_core:get_host_type(<<"erlang-solutions.local">>), 119: false = mongoose_domain_core:is_host_type_allowed(StaticHostType), 120: true = mongoose_domain_core:is_host_type_allowed(<<"type #1">>), 121: true = mongoose_domain_core:is_host_type_allowed(<<"type #3">>), 122: false = mongoose_domain_core:is_host_type_allowed(<<"invalid_type">>). 123: 124: can_get_outdated_domains(_) -> 125: [] = mongoose_domain_core:get_all_outdated(dummy_src), 126: [] = mongoose_domain_core:get_all_outdated(another_dummy_src), 127: ok = mongoose_domain_core:insert(<<"some.domain">>, <<"type #3">>, dummy_src), 128: ok = mongoose_domain_core:insert(<<"another.domain">>, <<"type #3">>, dummy_src), 129: [] = mongoose_domain_core:get_all_outdated(dummy_src), 130: ?assertEqualLists([{<<"some.domain">>, <<"type #3">>}, {<<"another.domain">>, <<"type #3">>}], 131: mongoose_domain_core:get_all_outdated(another_dummy_src)), 132: %% reinserting record with another source 133: ok = mongoose_domain_core:insert(<<"another.domain">>, <<"type #3">>, another_dummy_src), 134: [{<<"another.domain">>, <<"type #3">>}] = mongoose_domain_core:get_all_outdated(dummy_src), 135: [{<<"some.domain">>, <<"type #3">>}] = mongoose_domain_core:get_all_outdated(another_dummy_src), 136: ok = mongoose_domain_core:insert(<<"some.domain">>, <<"type #3">>, another_dummy_src), 137: [] = mongoose_domain_core:get_all_outdated(another_dummy_src), 138: ?assertEqualLists([{<<"some.domain">>, <<"type #3">>}, {<<"another.domain">>, <<"type #3">>}], 139: mongoose_domain_core:get_all_outdated(dummy_src)), 140: %% try to remove domains 141: ok = mongoose_domain_core:delete(<<"some.domain">>), 142: [{<<"another.domain">>, <<"type #3">>}] = mongoose_domain_core:get_all_outdated(dummy_src), 143: [] = mongoose_domain_core:get_all_outdated(another_dummy_src), 144: ok = mongoose_domain_core:delete(<<"another.domain">>), 145: [] = mongoose_domain_core:get_all_outdated(dummy_src), 146: [] = mongoose_domain_core:get_all_outdated(another_dummy_src). 147: 148: run_for_each_domain(_) -> 149: %% NumOfDomains is just some big non-round number to ensure that more than 2 ets 150: %% selections are done during the call to mongoose_domain_core:for_each_domain/2. 151: %% currently max selection size is 100 domains. 152: NumOfDomains = 1234, 153: NewDomains = [<<"dummy_domain_", (integer_to_binary(N))/binary, ".localhost">> 154: || N <- lists:seq(1, NumOfDomains)], 155: [mongoose_domain_core:insert(Domain, <<"type #3">>, dummy_src) || Domain <- NewDomains], 156: meck:new(dummy_module, [non_strict]), 157: meck:expect(dummy_module, for_each_callback, fun(_, _) -> ok end), 158: mongoose_domain_core:for_each_domain(<<"type #3">>, fun dummy_module:for_each_callback/2), 159: NumOfDomains = meck:num_calls(dummy_module, for_each_callback, 2), 160: [meck:wait(dummy_module, for_each_callback, [<<"type #3">>, Domain], 0) 161: || Domain <- NewDomains], 162: meck:unload(dummy_module). 163: 164: add_domain_mock_is_executed_only_one_time(HostType, Domain) -> 165: 1 = meck:num_calls(mongoose_subdomain_core, add_domain, [HostType, Domain]). 166: 167: remove_domain_mocks_are_executed_only_one_time(HostType, Domain) -> 168: 1 = meck:num_calls(mongoose_subdomain_core, remove_domain, [HostType, Domain]), 169: 1 = meck:num_calls(mongoose_lazy_routing, maybe_remove_domain, [HostType, Domain]). 170: 171: remove_domain_mocks_are_not_executed() -> 172: 0 = meck:num_calls(mongoose_subdomain_core, remove_domain, 2), 173: 0 = meck:num_calls(mongoose_lazy_routing, maybe_remove_domain, 2). 174: 175: add_domain_mock_is_not_executed() -> 176: 0 = meck:num_calls(mongoose_subdomain_core, add_domain, 2). 177: 178: remove_domain_mock_fn(_HostType, Domain) -> 179: %% ensure that domain is removed from ETS table 180: %% before other modules notified about it 181: {error, not_found} = mongoose_domain_core:get_host_type(Domain), 182: true = self() =:= whereis(mongoose_domain_core), 183: ok. 184: 185: add_domain_mock_fn(HostType, Domain) -> 186: %% ensure that domain is added to ETS table before 187: %% mongoose_subdomain_core module notified about it 188: {ok, HostType} = mongoose_domain_core:get_host_type(Domain), 189: true = self() =:= whereis(mongoose_domain_core), 190: ok.