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