1: %%============================================================================== 2: %% Copyright 2017 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: -module(monitored_map_SUITE). 17: 18: -compile([export_all, nowarn_export_all]). 19: 20: -include_lib("common_test/include/ct.hrl"). 21: -include_lib("eunit/include/eunit.hrl"). 22: 23: %%-------------------------------------------------------------------- 24: %% Suite configuration 25: %%-------------------------------------------------------------------- 26: 27: all() -> 28: [ 29: no_key_test, 30: put_monitors_test, 31: get_test, 32: remove_test, 33: expire_entries_on_process_death_test, 34: overwrite_entry_test, 35: overwrite_entry_same_pid_test, 36: find_test, 37: get_default_test, 38: remove_nonexistent_element_test, 39: ignore_nonrelevant_info_test 40: ]. 41: 42: %%-------------------------------------------------------------------- 43: %% Tests 44: %%-------------------------------------------------------------------- 45: 46: no_key_test(_Config) -> 47: Map = monitored_map:new(), 48: ?assertError(_, monitored_map:get(key, Map)). 49: 50: put_monitors_test(_Config) -> 51: Map0 = monitored_map:new(), 52: Pid = new_process(), 53: _Map1 = monitored_map:put(key, value, Pid, Map0), 54: assert_monitors([Pid]). 55: 56: get_test(_Config) -> 57: Map0 = monitored_map:new(), 58: Map1 = monitored_map:put(key, value, self(), Map0), 59: ?assertEqual(value, monitored_map:get(key, Map1)). 60: 61: remove_test(_Config) -> 62: Map0 = monitored_map:new(), 63: Map1 = monitored_map:put(key, value, self(), Map0), 64: Map2 = monitored_map:remove(key, Map1), 65: ?assertError(_, monitored_map:get(key, Map2)), 66: assert_monitors([]). 67: 68: expire_entries_on_process_death_test(_Config) -> 69: Map0 = monitored_map:new(), 70: Pid1 = spawn(fun() -> ok end), 71: Pid2 = spawn(fun() -> ok end), 72: Pid3 = new_process(), 73: 74: Map1 = lists:foldl(fun({Key, Value, Pid}, M) -> monitored_map:put(Key, Value, Pid, M) end, 75: Map0, [{key1, value1, Pid1}, {key2, value2, Pid1}, 76: {key3, value3, Pid2}, {key4, value4, Pid3}]), 77: 78: %% Receive 3 expiration messages: two from first process, one from second 79: Map2 = lists:foldl( 80: fun(_, Map) -> receive DownMsg1 -> monitored_map:handle_info(DownMsg1, Map) end end, 81: Map1, lists:seq(1, 3)), 82: 83: ?assertError(_, monitored_map:get(key1, Map2)), 84: ?assertError(_, monitored_map:get(key2, Map2)), 85: ?assertError(_, monitored_map:get(key3, Map2)), 86: ?assertEqual(value4, monitored_map:get(key4, Map2)), 87: assert_monitors([Pid3]). 88: 89: overwrite_entry_test(_Config) -> 90: Map0 = monitored_map:new(), 91: Pid = new_process(), 92: Map1 = monitored_map:put(key, value1, self(), Map0), 93: Map2 = monitored_map:put(key, value2, Pid, Map1), 94: ?assertEqual(value2, monitored_map:get(key, Map2)), 95: assert_monitors([Pid]). 96: 97: overwrite_entry_same_pid_test(_Config) -> 98: Map0 = monitored_map:new(), 99: Map1 = monitored_map:put(key, value1, self(), Map0), 100: Map2 = monitored_map:put(key, value2, self(), Map1), 101: ?assertEqual(value2, monitored_map:get(key, Map2)). 102: 103: find_test(_Config) -> 104: Map0 = monitored_map:new(), 105: Map1 = monitored_map:put(key, value, self(), Map0), 106: ?assertEqual({ok, value}, monitored_map:find(key, Map1)), 107: ?assertEqual(error, monitored_map:find(key2, Map1)). 108: 109: get_default_test(_Config) -> 110: Map0 = monitored_map:new(), 111: Map1 = monitored_map:put(key, value, self(), Map0), 112: ?assertEqual(value, monitored_map:get(key, Map1, default_value)), 113: ?assertEqual(default_value, monitored_map:get(key2, Map1, default_value)). 114: 115: remove_nonexistent_element_test(_Config) -> 116: Map = monitored_map:new(), 117: ?assertEqual(Map, monitored_map:remove(key, Map)). 118: 119: ignore_nonrelevant_info_test(_Config) -> 120: Map0 = monitored_map:new(), 121: Map1 = monitored_map:put(key, value, self(), Map0), 122: DownMsg = {'DOWN', make_ref(), process, self(), error}, 123: ?assertEqual(Map1, monitored_map:handle_info(DownMsg, Map1)), 124: ?assertEqual(Map1, monitored_map:handle_info(any_other_msg, Map1)). 125: 126: %%-------------------------------------------------------------------- 127: %% Test helpers 128: %%-------------------------------------------------------------------- 129: 130: assert_monitors(Expected) -> 131: {monitors, All} = process_info(self(), monitors), 132: MonitoredPids = [Pid || {process, Pid} <- All], 133: ?assertEqual(ordsets:from_list(Expected), ordsets:from_list(MonitoredPids)). 134: 135: new_process() -> 136: spawn_link(fun() -> receive Anything -> Anything end end).