1: -module(keystore_SUITE). 2: -include_lib("eunit/include/eunit.hrl"). 3: -compile([export_all, nowarn_export_all]). 4: -import(config_parser_helper, [default_mod_config/1, mod_config/2]). 5: 6: -define(ae(Expected, Actual), ?assertEqual(Expected, Actual)). 7: 8: all() -> 9: [ 10: module_startup_no_opts, 11: module_startup_read_key_from_file, 12: module_startup_create_ram_key, 13: module_startup_create_ram_key_of_given_size, 14: module_startup_for_multiple_domains, 15: multiple_domains_one_stopped 16: ]. 17: 18: init_per_suite(C) -> 19: {ok, _} = application:ensure_all_started(jid), 20: ok = mnesia:create_schema([node()]), 21: ok = mnesia:start(), 22: C. 23: 24: end_per_suite(C) -> 25: mnesia:stop(), 26: mnesia:delete_schema([node()]), 27: C. 28: 29: init_per_testcase(_, Config) -> 30: mock_mongoose_metrics(), 31: async_helper:start(Config, gen_hook, start_link, []). 32: 33: end_per_testcase(module_startup_non_unique_key_ids, C) -> 34: clean_after_testcase(C); 35: end_per_testcase(module_startup_for_multiple_domains, C) -> 36: mod_keystore:stop(<<"first.com">>), 37: mod_keystore:stop(<<"second.com">>), 38: clean_after_testcase(C); 39: end_per_testcase(multiple_domains_one_stopped, C) -> 40: mod_keystore:stop(<<"second.com">>), 41: clean_after_testcase(C); 42: end_per_testcase(_CaseName, C) -> 43: mod_keystore:stop(<<"localhost">>), 44: clean_after_testcase(C). 45: 46: clean_after_testcase(C) -> 47: meck:unload(mongoose_metrics), 48: async_helper:stop_all(C), 49: mnesia:delete_table(key), 50: C. 51: 52: %% 53: %% Tests 54: %% 55: 56: module_startup_no_opts(_) -> 57: ok = mod_keystore:start(<<"localhost">>, default_mod_config(mod_keystore)). 58: 59: module_startup_read_key_from_file(_) -> 60: %% given 61: RawKey = <<"qwe123">>, 62: {ok, KeyFile} = key_at("/tmp/key-from-file", RawKey), 63: %% when 64: ok = mod_keystore:start(<<"localhost">>, key_from_file(KeyFile)), 65: %% then 66: ?ae([{{key_from_file, <<"localhost">>}, RawKey}], 67: get_key(<<"localhost">>, key_from_file)). 68: 69: module_startup_create_ram_key(Config) -> 70: module_startup_create_ram_key(Config, ram_key()), 71: %% then we can access the key 72: [{{ram_key, <<"localhost">>}, Key}] = get_key(<<"localhost">>, ram_key), 73: true = is_binary(Key). 74: 75: module_startup_create_ram_key_of_given_size(Config) -> 76: KeySize = 4, 77: module_startup_create_ram_key(Config, sized_ram_key(KeySize)), 78: %% then 79: [{{ram_key, <<"localhost">>}, Key}] = get_key(<<"localhost">>, ram_key), 80: true = is_binary(Key), 81: KeySize = byte_size(Key). 82: 83: module_startup_create_ram_key(_, ModKeystoreOpts) -> 84: %% given no key 85: [] = get_key(<<"localhost">>, ram_key), 86: %% when keystore starts with config to generate a memory-only key 87: ok = mod_keystore:start(<<"localhost">>, ModKeystoreOpts). 88: 89: module_startup_for_multiple_domains(_Config) -> 90: %% given 91: [] = get_key(<<"first.com">>, key_from_file), 92: [] = get_key(<<"second.com">>, key_from_file), 93: FirstKey = <<"random-first.com-key-content">>, 94: SecondKey = <<"random-second.com-key-content">>, 95: {ok, FirstKeyFile} = key_at("/tmp/first.com", FirstKey), 96: {ok, SecondKeyFile} = key_at("/tmp/second.com", SecondKey), 97: %% when 98: ok = mod_keystore:start(<<"first.com">>, key_from_file(FirstKeyFile)), 99: ok = mod_keystore:start(<<"second.com">>, key_from_file(SecondKeyFile)), 100: %% then 101: ?ae([{{key_from_file, <<"first.com">>}, FirstKey}], 102: get_key(<<"first.com">>, key_from_file)), 103: ?ae([{{key_from_file, <<"second.com">>}, SecondKey}], 104: get_key(<<"second.com">>, key_from_file)). 105: 106: multiple_domains_one_stopped(_Config) -> 107: % given 108: [] = get_key(<<"first.com">>, key_from_file), 109: [] = get_key(<<"second.com">>, key_from_file), 110: FirstKey = <<"random-first.com-key-content">>, 111: SecondKey = <<"random-second.com-key-content">>, 112: {ok, FirstKeyFile} = key_at("/tmp/first.com", FirstKey), 113: {ok, SecondKeyFile} = key_at("/tmp/second.com", SecondKey), 114: % when 115: ok = mod_keystore:start(<<"first.com">>, key_from_file(FirstKeyFile)), 116: ok = mod_keystore:start(<<"second.com">>, key_from_file(SecondKeyFile)), 117: ok = mod_keystore:stop(<<"first.com">>), 118: % then 119: ?ae([{{key_from_file, <<"second.com">>}, SecondKey}], 120: get_key(<<"second.com">>, key_from_file)). 121: 122: %% 123: %% Helpers 124: %% 125: 126: key_at(Path, Data) -> 127: ok = file:write_file(Path, Data), 128: {ok, Path}. 129: 130: key_from_file(KeyFile) -> 131: mod_config(mod_keystore, #{keys => #{key_from_file => {file, KeyFile}}}). 132: 133: ram_key() -> 134: mod_config(mod_keystore, #{keys => #{ram_key => ram}}). 135: 136: sized_ram_key(Size) -> 137: mod_config(mod_keystore, #{keys => #{ram_key => ram}, 138: ram_key_size => Size}). 139: 140: mock_mongoose_metrics() -> 141: meck:new(mongoose_metrics, []), 142: meck:expect(mongoose_metrics, create_generic_hook_metric, fun (_, _) -> ok end), 143: meck:expect(mongoose_metrics, increment_generic_hook_metric, fun (_, _) -> ok end), 144: ok. 145: 146: %% Use a function like this in your module which is a client of mod_keystore. 147: -spec get_key(HostType, KeyName) -> Result when 148: HostType :: mongooseim:host_type(), 149: KeyName :: mod_keystore:key_name(), 150: Result :: mod_keystore:key_list(). 151: get_key(HostType, KeyName) -> 152: mongoose_hooks:get_key(HostType, KeyName).