diff options
Diffstat (limited to 'lib/snmp/test/snmp_agent_mibs_SUITE.erl')
-rw-r--r-- | lib/snmp/test/snmp_agent_mibs_SUITE.erl | 299 |
1 files changed, 254 insertions, 45 deletions
diff --git a/lib/snmp/test/snmp_agent_mibs_SUITE.erl b/lib/snmp/test/snmp_agent_mibs_SUITE.erl index 39946ba7d1..ce6ec80322 100644 --- a/lib/snmp/test/snmp_agent_mibs_SUITE.erl +++ b/lib/snmp/test/snmp_agent_mibs_SUITE.erl @@ -189,7 +189,7 @@ init_per_testcase2(size_check_mnesia, Config) when is_list(Config) -> Config; init_per_testcase2(cache_test, Config) when is_list(Config) -> Factor = ?config(snmp_factor, Config), - ct:timetrap(?MINS(5 + (Factor div 2))), + ct:timetrap(?MINS(10 + (Factor div 2))), Config; init_per_testcase2(_Case, Config) when is_list(Config) -> Factor = ?config(snmp_factor, Config), @@ -206,8 +206,6 @@ end_per_testcase1(size_check_mnesia, Config) when is_list(Config) -> mnesia_stop(), Config; end_per_testcase1(cache_test, Config) when is_list(Config) -> - Dog = ?config(watchdog, Config), - test_server:timetrap_cancel(Dog), Config; end_per_testcase1(_Case, Config) when is_list(Config) -> Config. @@ -552,9 +550,10 @@ cache_test(Config) when is_list(Config) -> fun() -> do_cache_test(Config) end). do_cache_test(Config) -> - ?DBG("do_cache_test -> start", []), + ?IPRINT("cache_test -> start"), Prio = normal, - Verbosity = trace, + %% Verbosity = trace, + Verbosity = info, MibStorage = [{module, snmpa_mib_storage_ets}], MibDir = ?config(data_dir, Config), StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/", @@ -565,77 +564,213 @@ do_cache_test(Config) -> "SNMP-MPD-MIB", "SNMP-NOTIFICATION-MIB", "SNMP-TARGET-MIB", - %% "SNMP-USER-BASED-SM-MIB", + "SNMP-USER-BASED-SM-MIB", "SNMP-VIEW-BASED-ACM-MIB", "SNMPv2-MIB", "SNMPv2-TC", "SNMPv2-TM"], - ?DBG("cache_test -> start symbolic store", []), - ?line sym_start(Prio, MibStorage, Verbosity), + ?IPRINT("cache_test -> start symbolic store"), + ?line sym_start(Prio, MibStorage, silence), % Verbosity), - ?DBG("cache_test -> start mib server", []), - GcLimit = 2, - Age = timer:seconds(10), - CacheOpts = [{autogc, false}, {age, Age}, {gclimit, GcLimit}], + ?IPRINT("cache_test -> start mib server"), + GcLimit = 3, + Age = timer:seconds(10), + CacheOpts = [{autogc, false}, + {age, Age}, + {gclimit, GcLimit}, + {gcverbose, true}], ?line MibsPid = mibs_start(Prio, MibStorage, [], Verbosity, CacheOpts), - ?DBG("cache_test -> load mibs", []), + ?NPRINT("Info before load mibs: " + "~n ~p", [snmpa_mib:info(MibsPid)]), + + ?IPRINT("cache_test -> load mibs"), ?line load_mibs(MibsPid, MibDir, Mibs), - ?DBG("cache_test -> load std mibs", []), + + ?NPRINT("Info before load std mibs: " + "~n ~p", [snmpa_mib:info(MibsPid)]), + + ?IPRINT("cache_test -> load std mibs"), ?line load_mibs(MibsPid, StdMibDir, StdMibs), - ?DBG("cache_test -> do a simple walk to populate the cache", []), - ?line ok = walk(MibsPid), - - {ok, Sz1} = snmpa_mib:which_cache_size(MibsPid), - ?DBG("cache_test -> Size1: ~p", [Sz1]), + ?NPRINT("Info (after mibs load but) before populate: " + "~n ~p", [snmpa_mib:info(MibsPid)]), + + ?IPRINT("cache_test -> populate the cache"), + ?line ok = populate(MibsPid), - ?DBG("cache_test -> sleep 5 secs", []), + ?NPRINT("Info after populate: " + "~n ~p", [snmpa_mib:info(MibsPid)]), + + Sz1 = cache_sz_verify(1, MibsPid, any), + + ?IPRINT("cache_test -> sleep 5 secs"), ?SLEEP(timer:seconds(5)), - ?DBG("cache_test -> perform gc, expect nothing", []), - {ok, 0} = snmpa_mib:gc_cache(MibsPid), + _ = cache_gc_verify(1, MibsPid), + + ?NPRINT("Info after 5 sec sleep: " + "~n ~p", [snmpa_mib:info(MibsPid)]), - ?DBG("cache_test -> sleep 10 secs", []), + ?IPRINT("cache_test -> sleep 10 secs"), ?SLEEP(timer:seconds(10)), - ?DBG("cache_test -> perform gc, expect GcLimit", []), - GcLimit1 = GcLimit + 1, - {ok, GcLimit1} = snmpa_mib:gc_cache(MibsPid, Age, GcLimit1), + ?NPRINT("Info after 10 sec sleep: " + "~n ~p", [snmpa_mib:info(MibsPid)]), + + GcLimit1 = cache_gc_verify(2, MibsPid, Age, GcLimit + 1), + + Sz2 = cache_sz_verify(2, MibsPid, Sz1 - GcLimit1), + - Sz2 = Sz1 - GcLimit1, - {ok, Sz2} = snmpa_mib:which_cache_size(MibsPid), - ?DBG("cache_test -> Size2: ~p", [Sz2]), + ?IPRINT("cache_test -> subscribe to GC events"), + ?line ok = snmpa_mib:subscribe_gc_events(MibsPid), - ?DBG("cache_test -> enable cache autogc", []), + ?IPRINT("cache_test -> enable cache autogc"), ?line ok = snmpa_mib:enable_cache_autogc(MibsPid), - ?DBG("cache_test -> wait 65 seconds to allow gc to happen", []), + ?IPRINT("cache_test -> wait 65 seconds to allow gc to happen"), ?SLEEP(timer:seconds(65)), - Sz3 = Sz2 - GcLimit, - {ok, Sz3} = snmpa_mib:which_cache_size(MibsPid), - ?DBG("cache_test -> Size3: ~p", [Sz3]), - ?DBG("cache_test -> " - "wait 2 minutes to allow gc to happen, expect empty cache", []), + ?NPRINT("Info after 65 sec sleep: " + "~n ~p", [snmpa_mib:info(MibsPid)]), + + ?IPRINT("cache_test -> [1] flush expected GC events"), + {NumEvents1, TotGC1} = cache_flush_gc_events(MibsPid), + ?IPRINT("cache_test -> GC events: " + "~n Number of Events: ~p" + "~n Total elements GCed: ~p", [NumEvents1, TotGC1]), + + _ = cache_sz_verify(3, MibsPid, Sz2 - GcLimit), + + ?IPRINT("cache_test -> " + "wait 2 minutes to allow gc to happen, expect empty cache"), ?SLEEP(timer:minutes(2)), - {ok, 0} = snmpa_mib:which_cache_size(MibsPid), - ?DBG("cache_test -> stop mib server", []), + ?NPRINT("Info after 2 min sleep: " + "~n ~p", [snmpa_mib:info(MibsPid)]), + + _ = cache_sz_verify(4, MibsPid, 0), + + + ?IPRINT("cache_test -> change gclimit to infinity"), + snmpa_mib:update_cache_gclimit(MibsPid, infinity), + + ?IPRINT("cache_test -> change age to ~w mins", [3]), + snmpa_mib:update_cache_age(MibsPid, ?MINS(3)), + + ?IPRINT("cache_test -> [2] flush expected GC events"), + {NumEvents2, TotGC2} = cache_flush_gc_events(MibsPid), + ?IPRINT("cache_test -> GC events: " + "~n Number of Events: ~p" + "~n Total elements GCed: ~p", [NumEvents2, TotGC2]), + + ?IPRINT("cache_test -> populate the cache again"), + populate(MibsPid), + + ?IPRINT("cache_test -> validate cache size"), + {ok, Sz4} = snmpa_mib:which_cache_size(MibsPid), + if (Sz4 > 0) -> + ?IPRINT("cache_test -> expected cache size: ~w > 0", [Sz4]); + true -> + ?EPRINT("cache_test -> cache *not* populated"), + ?FAIL(cache_not_populated) + end, + + ?NPRINT("Info after poulated: " + "~n ~p", [snmpa_mib:info(MibsPid)]), + + ?IPRINT("cache_test -> wait 2 mins - before tuching some entries"), + ?SLEEP(?MINS(2)), + + %% There should not be anything GC:ed + + receive + {MibsPid, gc_result, {ok, NGC1}} -> + ?EPRINT("cache_test -> unexpected GC of ~w elements", [NGC1]), + exit({unexpected_gc_result, NGC1}) + after 0 -> + ok + end, + + ?IPRINT("cache_test -> touch some elements again (update the cache)"), + populate_lookup(MibsPid), + + ?IPRINT("cache_test -> await partial GC"), + NumGC2 = + receive + {MibsPid, gc_result, {ok, NGC2}} + when (NGC2 > 0) andalso (Sz4 > NGC2) -> + ?NPRINT("cache_test -> " + "received partial GC result of ~w elements", [NGC2]), + NGC2 + end, + + ?NPRINT("Info after partial GC: " + "~n ~p", [snmpa_mib:info(MibsPid)]), + + + ?IPRINT("cache_test -> await final GC"), + receive + {MibsPid, gc_result, {ok, NGC3}} + when (NGC3 > 0) andalso ((Sz4 - NumGC2) =:= NGC3) -> + ?NPRINT("cache_test -> " + "received final GC result of ~w elements", [NGC3]), + NGC3; + Any -> + ?EPRINT("cache_test -> unexpected message: " + "~n ~p", [Any]), + ?FAIL({unexpected, Any}) + end, + + ?NPRINT("Info after final GC: " + "~n ~p", [snmpa_mib:info(MibsPid)]), + + ?IPRINT("cache_test -> validate cache size (expect empty)"), + {ok, Sz5} = snmpa_mib:which_cache_size(MibsPid), + if (Sz5 =:= 0) -> + ?IPRINT("cache_test -> expected cache size: 0"); + true -> + ?EPRINT("cache_test -> cache *not* empty (~w)", [Sz5]), + ?FAIL({cache_populated, Sz5}) + end, + + + ?IPRINT("cache_test -> stop mib server"), ?line mibs_stop(MibsPid), - ?DBG("cache_test -> stop symbolic store", []), + ?IPRINT("cache_test -> stop symbolic store"), ?line sym_stop(), + + ?IPRINT("cache_test -> end"), ok. -walk(MibsPid) -> +populate(MibsPid) -> + %% Make some lookups + populate_lookup(MibsPid), + %% Make some walk's + populate_walk(MibsPid). + +populate_lookup(MibsPid) -> + {variable, _} = snmpa_mib:lookup(MibsPid, ?snmpTrapCommunity_instance), + {variable, _} = snmpa_mib:lookup(MibsPid, ?vacmViewSpinLock_instance), + {variable, _} = snmpa_mib:lookup(MibsPid, ?usmStatsNotInTimeWindows_instance), + {variable, _} = snmpa_mib:lookup(MibsPid, ?tDescr_instance), + ok. + +populate_walk(MibsPid) -> MibView = snmpa_acm:get_root_mib_view(), - do_walk(MibsPid, ?snmpTrapCommunity_instance, MibView), - do_walk(MibsPid, ?vacmViewSpinLock_instance, MibView), - do_walk(MibsPid, ?usmStatsNotInTimeWindows_instance, MibView), - do_walk(MibsPid, ?tDescr_instance, MibView). - + walk(MibsPid, ?snmpTrapCommunity_instance, MibView), + walk(MibsPid, ?vacmViewSpinLock_instance, MibView), + walk(MibsPid, ?usmStatsNotInTimeWindows_instance, MibView), + walk(MibsPid, ?tDescr_instance, MibView), + ok. + +walk(MibsPid, Oid, MibView) -> + ?IPRINT("walk -> entry with" + "~n Oid: ~p", [Oid]), + do_walk(MibsPid, Oid, MibView). do_walk(MibsPid, Oid, MibView) -> ?IPRINT("do_walk -> entry with" @@ -646,15 +781,89 @@ do_walk(MibsPid, Oid, MibView) -> ?IPRINT("do_walk -> done for table (~p)", [Oid]), ok; {table, _, _, #me{oid = Next}} -> + ?IPRINT("do_walk -> table next ~p", [Next]), do_walk(MibsPid, Next, MibView); {variable, #me{oid = Oid}, _} -> ?IPRINT("do_walk -> done for variable (~p)", [Oid]), ok; {variable, #me{oid = Next}, _} -> + ?IPRINT("do_walk -> variable next ~p", [Next]), do_walk(MibsPid, Next, MibView) end. +cache_gc_verify(ID, MibsPid) -> + GC = fun() -> snmpa_mib:gc_cache(MibsPid) end, + cache_gc_verify(ID, GC, 0). + +cache_gc_verify(ID, MibsPid, Age, ExpectedGcLimit) -> + GC = fun() -> snmpa_mib:gc_cache(MibsPid, Age, ExpectedGcLimit) end, + cache_gc_verify(ID, GC, ExpectedGcLimit). + +cache_gc_verify(ID, GC, ExpectedGc) -> + ?IPRINT("cache_gc_verify -> [~w] perform gc, expect ~w", [ID, ExpectedGc]), + case GC() of + {ok, ExpectedGc} -> + ?IPRINT("cache_gc_verify -> [~w] gc => ok", [ID]), + ExpectedGc; + {ok, OtherGc} -> + ?IPRINT("cache_gc_verify -> [~w] invalid GC limit: " + "~n Expected: ~p" + "~n Got: ~p" + "~n ~p", + [ID, 0, OtherGc]), + exit({ID, invalid_gc_limit, {ExpectedGc, OtherGc}}); + Unexpected -> + ?IPRINT("cache_gc_verify -> [~w] unexpected: " + "~n ~p", + [ID, Unexpected]), + exit({ID, unexpected, Unexpected}) + end. + + +cache_sz_verify(ID, MibsPid, ExpectedSz) -> + ?IPRINT("cache_sz_verify -> [~w] expect size ~w", [ID, ExpectedSz]), + case snmpa_mib:which_cache_size(MibsPid) of + {ok, ExpectedSz} -> + ?IPRINT("cache_sz_verify -> [~w] sz => ok", [ID]), + ExpectedSz; + {ok, UnexpectedSz} when (ExpectedSz =:= any) -> + ?IPRINT("cache_sz_verify -> [~w] sz => ok (~w)", [ID, UnexpectedSz]), + UnexpectedSz; + {ok, UnexpectedSz} -> + ?IPRINT("cache_sz_verify -> [~w] invalid size: " + "~n Expected: ~p" + "~n Got: ~p", + [ID, ExpectedSz, UnexpectedSz]), + exit({ID, invalid_size, {ExpectedSz, UnexpectedSz}}); + Unexpected -> + ?IPRINT("cache_sz_verify -> [~w] unexpected: " + "~n ~p", + [ID, Unexpected]), + exit({ID, unexpected, Unexpected}) + end. + + +cache_flush_gc_events(MibServer) -> + cache_flush_gc_events(MibServer, 0, 0). + +cache_flush_gc_events(MibServer, NumEvents, TotGC) -> + receive + {MibServer, gc_result, {ok, NumGC}} -> + ?IPRINT("cache_flush_gc_events -> GC event ~w (~w)", + [NumGC, NumEvents]), + cache_flush_gc_events(MibServer, NumEvents+1, TotGC+NumGC) + after 0 -> + if + (NumEvents =:= 0) andalso (TotGC =:= 0) -> + ?IPRINT("cache_flush_gc_events -> no GC events"), + exit(no_gc_events); + true -> + {NumEvents, TotGC} + end + end. + + %%====================================================================== %% Internal functions %%====================================================================== |