diff options
Diffstat (limited to 'lib/snmp/test')
-rw-r--r-- | lib/snmp/test/Makefile | 2 | ||||
-rw-r--r-- | lib/snmp/test/modules.mk | 3 | ||||
-rw-r--r-- | lib/snmp/test/snmp_agent_test.erl | 174 | ||||
-rw-r--r-- | lib/snmp/test/snmp_agent_test_get.erl | 58 | ||||
-rw-r--r-- | lib/snmp/test/snmp_agent_test_lib.erl | 678 | ||||
-rw-r--r-- | lib/snmp/test/snmp_compiler_test.erl | 33 | ||||
-rw-r--r-- | lib/snmp/test/snmp_manager_config_test.erl | 13 | ||||
-rw-r--r-- | lib/snmp/test/snmp_manager_test.erl | 1691 | ||||
-rw-r--r-- | lib/snmp/test/snmp_test_global_sys_monitor.erl | 214 | ||||
-rw-r--r-- | lib/snmp/test/snmp_test_lib.erl | 372 | ||||
-rw-r--r-- | lib/snmp/test/snmp_test_lib.hrl | 46 | ||||
-rw-r--r-- | lib/snmp/test/snmp_test_mgr.erl | 425 | ||||
-rw-r--r-- | lib/snmp/test/snmp_test_mgr_misc.erl | 294 | ||||
-rw-r--r-- | lib/snmp/test/snmp_test_server.erl | 4 | ||||
-rw-r--r-- | lib/snmp/test/snmp_test_sys_monitor.erl | 86 | ||||
-rw-r--r-- | lib/snmp/test/snmp_to_snmpnet_SUITE.erl | 143 | ||||
-rw-r--r-- | lib/snmp/test/test-mibs/ALARM-MIB.mib | 2 | ||||
-rw-r--r-- | lib/snmp/test/test-mibs/SNMPv2-TC.mib | 4 |
18 files changed, 2315 insertions, 1927 deletions
diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile index a9142d911d..d9b01536ea 100644 --- a/lib/snmp/test/Makefile +++ b/lib/snmp/test/Makefile @@ -180,7 +180,7 @@ emakebuild: $(EMAKEFILE) targets: mib $(EMAKEFILE) erl -make -old_targets: $(TARGET_FILES) $(TEST_SERVER_TARGETS) +old_targets: mib $(TARGET_FILES) $(TEST_SERVER_TARGETS) $(EMAKEFILE): Makefile $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' > $(EMAKEFILE) diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk index 0f54e67c65..ec3870dbd8 100644 --- a/lib/snmp/test/modules.mk +++ b/lib/snmp/test/modules.mk @@ -31,6 +31,7 @@ SUITE_MODULES = \ snmp_agent_mibs_test \ snmp_agent_nfilter_test \ snmp_agent_test \ + snmp_agent_test_get \ snmp_agent_conf_test \ snmp_agent_test_lib \ snmp_manager_config_test \ @@ -41,6 +42,8 @@ SUITE_MODULES = \ snmp_manager_test TEST_UTIL_MODULES = \ + snmp_test_global_sys_monitor \ + snmp_test_sys_monitor \ snmp_test_lib \ snmp_test_manager \ snmp_test_mgr \ diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index f9c18af6ea..f6416ee2f9 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2018. All Rights Reserved. +%% Copyright Ericsson AB 2003-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -557,6 +557,8 @@ init_per_suite(Config0) when is_list(Config0) -> Config3 = [{mib_dir, MibDir}, {std_mib_dir, StdMibDir} | Config2], + snmp_test_global_sys_monitor:start(), + snmp_test_sys_monitor:start(), % We need one on this node also snmp_test_mgr_counter_server:start(), p("init_per_suite -> end when" @@ -580,6 +582,8 @@ end_per_suite(Config) when is_list(Config) -> p("end_per_suite -> failed stopping counter server" "~n Reason: ~p", [Reason]) end, + snmp_test_sys_monitor:stop(), + snmp_test_global_sys_monitor:stop(), p("end_per_suite -> end when" "~n Nodes: ~p", [erlang:nodes()]), @@ -667,22 +671,39 @@ init_per_group(GroupName, Config) -> snmp_test_lib:init_group_top_dir(GroupName, Config). init_per_group_ipv6(GroupName, Config, Init) -> - {ok, Hostname0} = inet:gethostname(), - case ct:require(ipv6_hosts) of - ok -> - case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of - true -> - Init( - snmp_test_lib:init_group_top_dir( - GroupName, - [{ipfamily, inet6}, - {ip, ?LOCALHOST(inet6)} - | lists:keydelete(ip, 1, Config)])); - false -> - {skip, "Host does not support IPV6"} - end; - _ -> - {skip, "Test config ipv6_hosts is missing"} + %% <OS-CONDITIONAL-SKIP> + %% This is a higly questionable test. + %% But until we have time to figure out what IPv6 issues + %% are actually causing the failures... + OSSkipable = [{unix, + [ + {darwin, fun(V) when (V > {9, 8, 0}) -> + %% This version is OK: No Skip + false; + (_) -> + %% This version is *not* ok: Skip + true + end} + ] + }], + %% </OS-CONDITIONAL-SKIP> + case ?OS_BASED_SKIP(OSSkipable) of + true -> + {skip, "Host *may* not *properly* support IPV6"}; + false -> + %% Even if this host supports IPv6 we don't use it unless its + %% one of the configured/supported IPv6 hosts... + case (?HAS_SUPPORT_IPV6() andalso ?IS_IPV6_HOST()) of + true -> + Init( + snmp_test_lib:init_group_top_dir( + GroupName, + [{ipfamily, inet6}, + {ip, ?LOCALHOST(inet6)} + | lists:keydelete(ip, 1, Config)])); + false -> + {skip, "Host does not support IPv6"} + end end. end_per_group(all_tcs, Config) -> @@ -751,6 +772,8 @@ init_per_testcase(Case, Config) when is_list(Config) -> Result = init_per_testcase1(Case, Config), + snmp_test_global_sys_monitor:reset_events(), + p("init_per_testcase -> done when" "~n Result: ~p" "~n Nodes: ~p", [Result, erlang:nodes()]), @@ -800,6 +823,9 @@ end_per_testcase(Case, Config) when is_list(Config) -> "~n Nodes: ~p", [Config, erlang:nodes()]), display_log(Config), + + p("system events during test: " + "~n ~p", [snmp_test_global_sys_monitor:events()]), Result = end_per_testcase1(Case, Config), @@ -1116,15 +1142,15 @@ init_ms(Config, Opts) when is_list(Config) -> Opts1 = [MasterAgentVerbosity, MibsVerbosity, SymStoreVerbosity | Opts], [{vsn, v1} | start_v1_agent(Config, Opts1)]. -init_size_check_mse(Config) when is_list(Config) -> - MibStorage = {mib_storage, [{module, snmpa_mib_storage_ets}]}, - init_size_check_ms(Config, [MibStorage]). +%% init_size_check_mse(Config) when is_list(Config) -> +%% MibStorage = {mib_storage, [{module, snmpa_mib_storage_ets}]}, +%% init_size_check_ms(Config, [MibStorage]). -init_size_check_msd(Config) when is_list(Config) -> - AgentDbDir = ?GCONF(agent_db_dir, Config), - MibStorage = {mib_storage, [{module, snmpa_mib_storage_dets}, - {options, [{dir, AgentDbDir}]}]}, - init_size_check_ms(Config, [MibStorage]). +%% init_size_check_msd(Config) when is_list(Config) -> +%% AgentDbDir = ?GCONF(agent_db_dir, Config), +%% MibStorage = {mib_storage, [{module, snmpa_mib_storage_dets}, +%% {options, [{dir, AgentDbDir}]}]}, +%% init_size_check_ms(Config, [MibStorage]). init_size_check_msm(Config) when is_list(Config) -> ?line AgentNode = ?GCONF(snmp_master, Config), @@ -1637,7 +1663,7 @@ create_local_db_dir(Config) when is_list(Config) -> Name = list_to_atom(atom_to_list(create_local_db_dir) ++"-"++As++"-"++Bs++"-"++Cs), Pa = filename:dirname(code:which(?MODULE)), - {ok,Node} = ?t:start_node(Name, slave, [{args, "-pa "++Pa}]), + {ok,Node} = ?t:start_node(Name, slave, [{args, "-pa " ++ Pa}]), %% first start with a nonexisting DbDir Fun1 = fun() -> @@ -3524,7 +3550,8 @@ table_test() -> ?line ?expect1([{NewKeyc5, ?destroy}]), s([{NewKeyc3, 3}]), ?line ?expect3(?v1_2(noSuchName, inconsistentName), 1, [{NewKeyc3, 3}]), - otp_1128_test(). + otp_1128_test(), + ok. %% Req. system group simple_standard_test() -> @@ -5004,7 +5031,8 @@ snmpv2_mib_2(Config) when is_list(Config) -> "then disable auth traps",[]), try_test(snmpv2_mib_test_finish, [], [{community, "bad community"}]), - ?LOG("snmpv2_mib_2 -> done",[]). + ?LOG("snmpv2_mib_2 -> done", []), + ok. standard_mibs3_cases() -> @@ -5100,7 +5128,8 @@ snmpv2_mib_a() -> ?line ?expect3(inconsistentValue, 2, [{[sysLocation, 0], "val3"}, {[snmpSetSerialNo,0], SetSerial}]), - ?line ["val2"] = get_req(5, [[sysLocation,0]]). + ?line ["val2"] = get_req(5, [[sysLocation,0]]), + ok. %%----------------------------------------------------------------- @@ -5123,6 +5152,7 @@ snmp_community_mib_test() -> ?INF("NOT YET IMPLEMENTED", []), nyi. + %%----------------------------------------------------------------- %% o Test engine boots / time %%----------------------------------------------------------------- @@ -5146,12 +5176,21 @@ snmp_framework_mib_3(Config) when is_list(Config) -> %% Req. SNMP-FRAMEWORK-MIB snmp_framework_mib_test() -> ?line ["agentEngine"] = get_req(1, [[snmpEngineID,0]]), + T1 = snmp_misc:now(ms), ?line [EngineTime] = get_req(2, [[snmpEngineTime,0]]), + T2 = snmp_misc:now(ms), ?SLEEP(5000), + T3 = snmp_misc:now(ms), ?line [EngineTime2] = get_req(3, [[snmpEngineTime,0]]), - ?DBG("snmp_framework_mib -> time(s): " - "~n EngineTime 1 = ~p" - "~n EngineTime 2 = ~p", [EngineTime, EngineTime2]), + T4 = snmp_misc:now(ms), + ?PRINT2("snmp_framework_mib -> time(s): " + "~n EngineTime 1: ~p" + "~n Time to acquire: ~w ms" + "~n EngineTime 2: ~p" + "~n Time to acquire: ~w ms" + "~n => (5 sec sleep between get(snmpEngineTime))" + "~n Total time to acquire: ~w ms", + [EngineTime, T2-T1, EngineTime2, T4-T3, T4-T1]), if (EngineTime+7) < EngineTime2 -> ?line ?FAIL({too_large_diff, EngineTime, EngineTime2}); @@ -5160,11 +5199,18 @@ snmp_framework_mib_test() -> true -> ok end, + T5 = snmp_misc:now(ms), ?line case get_req(4, [[snmpEngineBoots,0]]) of [Boots] when is_integer(Boots) -> + T6 = snmp_misc:now(ms), + ?PRINT2("snmp_framework_mib -> " + "~n boots: ~p" + "~n Time to acquire: ~w ms", [Boots, T6-T5]), ok; Else -> - ?FAIL(Else) + ?PRINT2("snmp_framework_mib -> failed get proper boots:" + "~n ~p", [Else]), + ?FAIL({invalid_boots, Else}) end, ok. @@ -5235,7 +5281,8 @@ snmp_mpd_mib_b() -> snmp_mpd_mib_c(UnknownPDUHs) -> ?line [UnknownPDUHs2] = get_req(1, [[snmpUnknownPDUHandlers, 0]]), - ?line UnknownPDUHs2 = UnknownPDUHs + 1. + ?line UnknownPDUHs2 = UnknownPDUHs + 1, + ok. snmp_target_mib(suite) -> []; @@ -5272,6 +5319,7 @@ snmp_notification_mib_test() -> ?INF("NOT YET IMPLEMENTED", []), nyi. + %%----------------------------------------------------------------- %% o add/delete views and try them %% o try boundaries @@ -5619,7 +5667,8 @@ usm_key_change3(OldShaKey, OldDesKey, ShaKey, DesKey) -> Vbs3 = [{[usmUserAuthKeyChange, NewRowIndex], ShaKeyChange}, {[usmUserPrivKeyChange, NewRowIndex], DesKeyChange}], s(Vbs3), - ?line ?expect1(Vbs3). + ?line ?expect1(Vbs3), + ok. usm_read() -> NewRowIndex = [11,"agentEngine", 7, "newUser"], @@ -5737,7 +5786,8 @@ loop_mib_1(Config) when is_list(Config) -> ?line unload_master("SNMP-VIEW-BASED-ACM-MIB"), %% snmpa:verbosity(master_agent,log), %% snmpa:verbosity(mib_server,silence), - ?LOG("loop_mib_1 -> done",[]). + ?LOG("loop_mib_1 -> done",[]), + ok. loop_mib_2(suite) -> []; @@ -5766,7 +5816,8 @@ loop_mib_2(Config) when is_list(Config) -> ?line unload_master("SNMP-NOTIFICATION-MIB"), ?line unload_master("SNMP-FRAMEWORK-MIB"), ?line unload_master("SNMP-VIEW-BASED-ACM-MIB"), - ?LOG("loop_mib_2 -> done",[]). + ?LOG("loop_mib_2 -> done",[]), + ok. loop_mib_3(suite) -> []; @@ -5791,7 +5842,8 @@ loop_mib_3(Config) when is_list(Config) -> ?line unload_master("SNMP-NOTIFICATION-MIB"), ?line unload_master("SNMP-VIEW-BASED-ACM-MIB"), ?line unload_master("SNMP-USER-BASED-SM-MIB"), - ?LOG("loop_mib_3 -> done",[]). + ?LOG("loop_mib_3 -> done",[]), + ok. %% Req. As many mibs all possible @@ -6001,7 +6053,8 @@ otp_1128(Config) when is_list(Config) -> ?line load_master("OLD-SNMPEA-MIB"), ?line init_old(), try_test(otp_1128_test), - ?line unload_master("OLD-SNMPEA-MIB"). + ?line unload_master("OLD-SNMPEA-MIB"), + ok. otp_1128_2(X) -> ?P(otp_1128_2), otp_1128(X). @@ -6023,7 +6076,8 @@ otp_1128_test() -> g([NewKeyc5]), ?line ?expect1([{NewKeyc5, ?active}]), s([{NewKeyc5, ?destroy}]), - ?line ?expect1([{NewKeyc5, ?destroy}]). + ?line ?expect1([{NewKeyc5, ?destroy}]), + ok. %%----------------------------------------------------------------- @@ -6036,7 +6090,8 @@ otp_1129(Config) when is_list(Config) -> init_case(Config), ?line load_master("Klas3"), try_test(otp_1129_i, [node()]), - ?line unload_master("Klas3"). + ?line unload_master("Klas3"), + ok. otp_1129_2(X) -> ?P(otp_1129_2), otp_1129(X). @@ -6107,7 +6162,8 @@ otp_1131_test() -> io:format("Testing bug reported in ticket OTP-1131...~n"), s([{[friendsEntry, [2, 3, 1]], s, "kompis3"}, {[friendsEntry, [3, 3, 1]], i, ?createAndGo}]), - ?line ?expect3(?v1_2(noSuchName, noCreation), 2, any). + ?line ?expect3(?v1_2(noSuchName, noCreation), 2, any), + ok. %%----------------------------------------------------------------- @@ -6128,7 +6184,8 @@ otp_1162_3(X) -> ?P(otp_1162_3), otp_1162(X). otp_1162_test() -> s([{[sa, [2,0]], 6}]), % wrongValue (i is_set_ok) - ?line ?expect3(?v1_2(badValue, wrongValue), 1, any). + ?line ?expect3(?v1_2(badValue, wrongValue), 1, any), + ok. %%----------------------------------------------------------------- @@ -6143,7 +6200,8 @@ otp_1222(Config) when is_list(Config) -> ?line load_master("Klas4"), try_test(otp_1222_test), ?line unload_master("Klas3"), - ?line unload_master("Klas4"). + ?line unload_master("Klas4"), + ok. otp_1222_2(X) -> ?P(otp_1222_2), otp_1222(X). @@ -6154,7 +6212,8 @@ otp_1222_test() -> s([{[fStatus4,1], 4}, {[fName4,1], 1}]), ?line ?expect3(genErr, 0, any), s([{[fStatus4,2], 4}, {[fName4,2], 1}]), - ?line ?expect3(genErr, 0, any). + ?line ?expect3(genErr, 0, any), + ok. %%----------------------------------------------------------------- @@ -6168,7 +6227,8 @@ otp_1298(Config) when is_list(Config) -> ?line load_master("Klas2"), try_test(otp_1298_test), - ?line unload_master("Klas2"). + ?line unload_master("Klas2"), + ok. otp_1298_2(X) -> ?P(otp_1298_2), otp_1298(X). @@ -6177,7 +6237,8 @@ otp_1298_3(X) -> ?P(otp_1298_3), otp_1298(X). otp_1298_test() -> io:format("Testing bug reported in ticket OTP-1298...~n"), s([{[fint,0], -1}]), - ?line ?expect1([{[fint,0], -1}]). + ?line ?expect1([{[fint,0], -1}]), + ok. %%----------------------------------------------------------------- @@ -6191,7 +6252,8 @@ otp_1331(Config) when is_list(Config) -> ?line load_master("OLD-SNMPEA-MIB"), ?line init_old(), try_test(otp_1331_test), - ?line unload_master("OLD-SNMPEA-MIB"). + ?line unload_master("OLD-SNMPEA-MIB"), + ok. otp_1331_2(X) -> ?P(otp_1331_2), otp_1331(X). @@ -6200,7 +6262,8 @@ otp_1331_3(X) -> ?P(otp_1331_3), otp_1331(X). otp_1331_test() -> NewKeyc5 = [intCommunityStatus,[127,32,0,0],is("test")], s([{NewKeyc5, ?destroy}]), - ?line ?expect1([{NewKeyc5, ?destroy}]). + ?line ?expect1([{NewKeyc5, ?destroy}]), + ok. %%----------------------------------------------------------------- @@ -6238,7 +6301,8 @@ otp_1342(Config) when is_list(Config) -> init_case(Config), ?line load_master("Klas4"), try_test(otp_1342_test), - ?line unload_master("Klas4"). + ?line unload_master("Klas4"), + ok. otp_1342_2(X) -> ?P(otp_1342_2), otp_1342(X). @@ -6248,7 +6312,8 @@ otp_1342_test() -> s([{[fIndex5, 1], i, 1}, {[fName5, 1], i, 3}, {[fStatus5, 1], i, ?createAndGo}]), - ?line ?expect3(?v1_2(noSuchName, noCreation), 3, any). + ?line ?expect3(?v1_2(noSuchName, noCreation), 3, any), + ok. %%----------------------------------------------------------------- @@ -6264,7 +6329,8 @@ otp_1366(Config) when is_list(Config) -> ?line load_master("OLD-SNMPEA-MIB"), ?line init_old(), try_test(otp_1366_test), - ?line unload_master("OLD-SNMPEA-MIB"). + ?line unload_master("OLD-SNMPEA-MIB"), + ok. otp_1366_2(X) -> ?P(otp_1366_2), otp_1366(X). @@ -6362,7 +6428,8 @@ otp_2979_3(X) -> ?P(otp_2979_3), otp_2979(X). otp_2979_test() -> gn([[sparseDescr], [sparseStatus]]), ?line ?expect1([{[sparseStr,0], "slut"}, - {[sparseStr,0], "slut"}]). + {[sparseStr,0], "slut"}]), + ok. %%----------------------------------------------------------------- @@ -6551,7 +6618,6 @@ otp_4394_test() -> gn([[1,1]]), Res = case snmp_test_mgr:expect(1, [{[sysDescr,0], "Erlang SNMP agent"}]) of - %% {error, 1, {"?",[]}, {"~w",[timeout]}} {error, 1, _, {_, [timeout]}} -> ?DBG("otp_4394_test -> expected result: timeout", []), ok; diff --git a/lib/snmp/test/snmp_agent_test_get.erl b/lib/snmp/test/snmp_agent_test_get.erl new file mode 100644 index 0000000000..517c71507a --- /dev/null +++ b/lib/snmp/test/snmp_agent_test_get.erl @@ -0,0 +1,58 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2019-2019. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-module(snmp_agent_test_get). + +-behaviour(snmpa_get_mechanism). + + +%%%----------------------------------------------------------------- +%%% snmpa_get_mechanism exports +%%%----------------------------------------------------------------- + +-export([ + do_get/3, do_get/4, + do_get_next/3, + do_get_bulk/7 + ]). + + + +do_get(UnsortedVarbinds, IsNotification, Extra) -> + snmpa_get:do_get(UnsortedVarbinds, IsNotification, Extra). + + + +do_get(MibView, UnsortedVarbinds, IsNotification, Extra) -> + snmpa_get:do_get(MibView, UnsortedVarbinds, IsNotification, Extra). + + + +do_get_next(MibView, UnsortedVBs, Extra) -> + snmpa_get:do_get_next(MibView, UnsortedVBs, Extra). + + + + +do_get_bulk(MibView, NonRepeaters, MaxRepetitions, + PduMS, Varbinds, GbMaxVBs, Extra) -> + snmpa_get:do_get_bulk(MibView, NonRepeaters, MaxRepetitions, + PduMS, Varbinds, GbMaxVBs, + Extra). diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index 66211d7105..c0da47dc4c 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2016. All Rights Reserved. +%% Copyright Ericsson AB 2005-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -66,7 +66,7 @@ ]). %% Internal exports --export([wait/5, run/4]). +-export([tc_wait/5, tc_run/4]). -include_lib("kernel/include/file.hrl"). -include_lib("common_test/include/ct.hrl"). @@ -276,117 +276,256 @@ init_case(Config) when is_list(Config) -> %%% configuration. %%%-------------------------------------------------- -try_test(Mod, Func) -> - call(get(mgr_node), ?MODULE, run, [Mod, Func, [], []]). - -try_test(Mod, Func, A) -> - call(get(mgr_node), ?MODULE, run, [Mod, Func, A, []]). - -try_test(Mod, Func, A, Opts) -> - call(get(mgr_node), ?MODULE, run, [Mod, Func, A, Opts]). - -call(N,M,F,A) -> - ?DBG("call -> entry with~n" - " N: ~p~n" - " M: ~p~n" - " F: ~p~n" - " A: ~p~n" - " when~n" - " get(): ~p", - [N,M,F,A,get()]), - spawn(N, ?MODULE, wait, [self(),get(),M,F,A]), +try_test(TcRunMod, TcRunFunc) -> + try_test(TcRunMod, TcRunFunc, []). + +try_test(TcRunMod, TcRunFunc, TcRunArgs) -> + try_test(TcRunMod, TcRunFunc, TcRunArgs, []). + +try_test(TcRunMod, TcRunFunc, TcRunArgs, TcRunOpts) -> + Node = get(mgr_node), + Mod = ?MODULE, + Func = tc_run, + Args = [TcRunMod, TcRunFunc, TcRunArgs, TcRunOpts], + tc_try(Node, Mod, Func, Args). + +%% We spawn a test case runner process on the manager node. +%% The assumption is that the manager shall do something, but +%% not all test cases have the manager perform actions. +%% In some cases we make a rpc call back to the agent node directly +%% and call something in the agent... (for example the info_test +%% test case). +%% We should use link (instead of monitor) in order for the test case +%% timeout cleanup (kills) should have effect on the test case runner +%% process as well. + +tc_try(N, M, F, A) -> + ?PRINT2("tc_try -> entry with" + "~n N: ~p" + "~n M: ~p" + "~n F: ~p" + "~n A: ~p" + "~n when" + "~n get(): ~p" + "~n", [N, + M, F, A, + get()]), + case net_adm:ping(N) of + pong -> + ?PRINT2("tc_try -> ~p still running - start runner~n", [N]), + OldFlag = trap_exit(true), % Make sure we catch it + Runner = spawn_link(N, ?MODULE, tc_wait, [self(), get(), M, F, A]), + await_tc_runner_started(Runner, OldFlag), + await_tc_runner_done(Runner, OldFlag); + pang -> + ?EPRINT2("tc_try -> ~p *not* running~n", [N]), + skip({node_not_running, N}) + end. + +await_tc_runner_started(Runner, OldFlag) -> + ?PRINT2("await tc-runner (~p) start ack~n", [Runner]), + receive + {'EXIT', Runner, Reason} -> + ?EPRINT2("TC runner start failed: " + "~n ~p~n", [Reason]), + exit({tx_runner_start_failed, Reason}); + {tc_runner_started, Runner} -> + ?PRINT2("TC runner start acknowledged~n"), + ok + after 10000 -> %% We should *really* not have to wait this long, but... + trap_exit(OldFlag), + unlink_and_flush_exit(Runner), + RunnerInfo = process_info(Runner), + ?EPRINT2("TC runner start timeout: " + "~n ~p", [RunnerInfo]), + %% If we don't get a start ack within 10 seconds, we are f*ed + exit(Runner, kill), + exit({tc_runner_start, timeout, RunnerInfo}) + end. + +await_tc_runner_done(Runner, OldFlag) -> receive - {done, {'EXIT', Rn}, Loc} -> - ?DBG("call -> done with exit: " - "~n Rn: ~p" - "~n Loc: ~p", [Rn, Loc]), + {'EXIT', Runner, Reason} -> + %% This is not a normal (tc) failure (that is the clause below). + %% Instead the tc runner process crashed, for some reason. So + %% check if have got any system events, and if so, skip. + SysEvs = snmp_test_global_sys_monitor:events(), + if + (SysEvs =:= []) -> + ?EPRINT2("TC runner failed: " + "~n ~p~n", [Reason]), + exit({tx_runner_failed, Reason}); + true -> + ?EPRINT2("TC runner failed when we got system events: " + "~n Reason: ~p" + "~n Sys Events: ~p" + "~n", [Reason, SysEvs]), + skip([{reason, Reason}, {system_events, SysEvs}]) + end; + {tc_runner_done, Runner, {'EXIT', {skip, Reason}}, Loc} -> + ?PRINT2("call -> done with skip: " + "~n Reason: ~p" + "~n Loc: ~p" + "~n", [Reason, Loc]), + trap_exit(OldFlag), + unlink_and_flush_exit(Runner), + put(test_server_loc, Loc), + skip(Reason); + {tc_runner_done, Runner, {'EXIT', Rn}, Loc} -> + ?PRINT2("call -> done with exit: " + "~n Rn: ~p" + "~n Loc: ~p" + "~n", [Rn, Loc]), + trap_exit(OldFlag), + unlink_and_flush_exit(Runner), put(test_server_loc, Loc), exit(Rn); - {done, Ret, _Zed} -> + {tc_runner_done, Runner, Ret, _Zed} -> ?DBG("call -> done:" "~n Ret: ~p" "~n Zed: ~p", [Ret, _Zed]), + trap_exit(OldFlag), + unlink_and_flush_exit(Runner), case Ret of {error, Reason} -> exit(Reason); + {skip, Reason} -> + skip(Reason); OK -> OK end end. -wait(From, Env, M, F, A) -> - ?DBG("wait -> entry with" - "~n From: ~p" - "~n Env: ~p" - "~n M: ~p" - "~n F: ~p" - "~n A: ~p", [From, Env, M, F, A]), +trap_exit(Flag) when is_boolean(Flag) -> + erlang:process_flag(trap_exit, Flag). + +unlink_and_flush_exit(Pid) -> + unlink(Pid), + receive + {'EXIT', Pid, _} -> + ok + after 0 -> + ok + end. + +tc_wait(From, Env, M, F, A) -> + ?PRINT2("tc_wait -> entry with" + "~n From: ~p" + "~n Env: ~p" + "~n M: ~p" + "~n F: ~p" + "~n A: ~p", [From, Env, M, F, A]), + From ! {tc_runner_started, self()}, lists:foreach(fun({K,V}) -> put(K,V) end, Env), - Rn = (catch apply(M, F, A)), - ?DBG("wait -> Rn: ~n~p", [Rn]), - From ! {done, Rn, get(test_server_loc)}, - exit(Rn). - -run(Mod, Func, Args, Opts) -> - ?DBG("run -> entry with" - "~n Mod: ~p" - "~n Func: ~p" - "~n Args: ~p" - "~n Opts: ~p", [Mod, Func, Args, Opts]), - M = get(mib_dir), - Dir = get(mgr_dir), - User = snmp_misc:get_option(user, Opts, "all-rights"), - SecLevel = snmp_misc:get_option(sec_level, Opts, noAuthNoPriv), - EngineID = snmp_misc:get_option(engine_id, Opts, "agentEngine"), + ?PRINT2("tc_wait -> env set - now run tc~n"), + Res = (catch apply(M, F, A)), + ?PRINT2("tc_wait -> tc run done: " + "~n ~p" + "~n", [Res]), + From ! {tc_runner_done, self(), Res, get(test_server_loc)}, + %% The point of this is that in some cases we have seen that the + %% exit signal having been "passed on" to the CT, which consider any + %% exit a fail (even if its {'EXIT', ok}). + %% So, just to be on the safe side, convert an 'ok' to a 'normal'. + case Res of + ok -> + exit(normal); + {ok, _} -> + exit(normal); + _ -> + exit(Res) + end. + +tc_run(Mod, Func, Args, Opts) -> + ?PRINT2("tc_run -> entry with" + "~n Mod: ~p" + "~n Func: ~p" + "~n Args: ~p" + "~n Opts: ~p" + "~n", [Mod, Func, Args, Opts]), + (catch snmp_test_mgr:stop()), % If we had a running mgr from a failed case + M = get(mib_dir), + Dir = get(mgr_dir), + User = snmp_misc:get_option(user, Opts, "all-rights"), + SecLevel = snmp_misc:get_option(sec_level, Opts, noAuthNoPriv), + EngineID = snmp_misc:get_option(engine_id, Opts, "agentEngine"), CtxEngineID = snmp_misc:get_option(context_engine_id, Opts, EngineID), - Community = snmp_misc:get_option(community, Opts, "all-rights"), - ?DBG("run -> start crypto app",[]), - _CryptoRes = ?CRYPTO_START(), - ?DBG("run -> Crypto: ~p", [_CryptoRes]), - catch snmp_test_mgr:stop(), % If we had a running mgr from a failed case - StdM = join(code:priv_dir(snmp), "mibs") ++ "/", - Vsn = get(vsn), - ?DBG("run -> config:" - "~n M: ~p" - "~n Vsn: ~p" - "~n Dir: ~p" - "~n User: ~p" - "~n SecLevel: ~p" - "~n EngineID: ~p" - "~n CtxEngineID: ~p" - "~n Community: ~p" - "~n StdM: ~p", - [M,Vsn,Dir,User,SecLevel,EngineID,CtxEngineID,Community,StdM]), + Community = snmp_misc:get_option(community, Opts, "all-rights"), + ?DBG("tc_run -> start crypto app",[]), + _CryptoRes = ?CRYPTO_START(), + ?DBG("tc_run -> Crypto: ~p", [_CryptoRes]), + StdM = join(code:priv_dir(snmp), "mibs") ++ "/", + Vsn = get(vsn), + ?PRINT2("tc_run -> config:" + "~n M: ~p" + "~n Vsn: ~p" + "~n Dir: ~p" + "~n User: ~p" + "~n SecLevel: ~p" + "~n EngineID: ~p" + "~n CtxEngineID: ~p" + "~n Community: ~p" + "~n StdM: ~p" + "~n", [M,Vsn,Dir,User,SecLevel,EngineID,CtxEngineID,Community,StdM]), case snmp_test_mgr:start([%% {agent, snmp_test_lib:hostname()}, - {packet_server_debug,true}, - {debug,true}, - {agent, get(master_host)}, - {ipfamily, get(ipfamily)}, - {agent_udp, 4000}, - {trap_udp, 5000}, - {recbuf,65535}, + {packet_server_debug, true}, + {debug, true}, + {agent, get(master_host)}, + {ipfamily, get(ipfamily)}, + {agent_udp, 4000}, + {trap_udp, 5000}, + {recbuf, 65535}, quiet, Vsn, - {community, Community}, - {user, User}, - {sec_level, SecLevel}, - {engine_id, EngineID}, - {context_engine_id, CtxEngineID}, - {dir, Dir}, - {mibs, mibs(StdM, M)}]) of + {community, Community}, + {user, User}, + {sec_level, SecLevel}, + {engine_id, EngineID}, + {context_engine_id, CtxEngineID}, + {dir, Dir}, + {mibs, mibs(StdM, M)}]) of {ok, _Pid} -> case (catch apply(Mod, Func, Args)) of + {'EXIT', {skip, Reason}} -> + ?EPRINT2("apply skip detected: " + "~n ~p", [Reason]), + (catch snmp_test_mgr:stop()), + ?SKIP(Reason); {'EXIT', Reason} -> - catch snmp_test_mgr:stop(), - ?FAIL({apply_failed, {Mod, Func, Args}, Reason}); + %% We have hosts (mostly *very* slooow VMs) that + %% can timeout anything. Since we are basically + %% testing communication, we therefor must check + %% for system events at every failure. Grrr! + SysEvs = snmp_test_global_sys_monitor:events(), + (catch snmp_test_mgr:stop()), + if + (SysEvs =:= []) -> + ?EPRINT2("TC runner failed: " + "~n ~p~n", [Reason]), + ?FAIL({apply_failed, {Mod, Func, Args}, Reason}); + true -> + ?EPRINT2("apply exit catched when we got system events: " + "~n Reason: ~p" + "~n Sys Events: ~p" + "~n", [Reason, SysEvs]), + ?SKIP([{reason, Reason}, {system_events, SysEvs}]) + end; Res -> - catch snmp_test_mgr:stop(), + (catch snmp_test_mgr:stop()), Res end; + + {error, Reason} -> + ?EPRINT2("Failed starting (test) manager: " + "~n ~p", [Reason]), + (catch snmp_test_mgr:stop()), + ?line ?FAIL({mgr_start_error, Reason}); + Err -> - io:format("Error starting manager: ~p\n", [Err]), - catch snmp_test_mgr:stop(), - ?line ?FAIL({mgr_start, Err}) + ?EPRINT2("Failed starting (test) manager: " + "~n ~p", [Err]), + (catch snmp_test_mgr:stop()), + ?line ?FAIL({mgr_start_failure, Err}) end. @@ -445,6 +584,7 @@ start_agent(Config, Vsns, Opts) -> [{versions, Vsns}, {agent_type, master}, {agent_verbosity, trace}, + {get_mechanism, snmp_agent_test_get}, {db_dir, AgentDbDir}, {audit_trail_log, [{type, read_write}, {dir, AgentLogDir}, @@ -463,20 +603,24 @@ start_agent(Config, Vsns, Opts) -> process_flag(trap_exit,true), + ?PRINT2("start_agent -> try start snmp app supervisor", []), {ok, AppSup} = snmp_app_sup:start_link(), unlink(AppSup), ?DBG("start_agent -> snmp app supervisor: ~p", [AppSup]), - ?DBG("start_agent -> start master agent",[]), + ?PRINT2("start_agent -> try start master agent",[]), ?line Sup = start_sup(Env), - - ?DBG("start_agent -> unlink from supervisor", []), ?line unlink(Sup), + ?DBG("start_agent -> snmp supervisor: ~p", [Sup]), + + ?PRINT2("start_agent -> try (rpc) start sub agent on ~p", [SaNode]), ?line SaDir = ?config(sa_dir, Config), - ?DBG("start_agent -> (rpc) start sub on ~p", [SaNode]), ?line {ok, Sub} = start_sub_sup(SaNode, SaDir), - ?DBG("start_agent -> done",[]), - ?line [{snmp_sup, {Sup, self()}}, {snmp_sub, Sub} | Config]. + ?DBG("start_agent -> done", []), + + ?line [{snmp_app_sup, AppSup}, + {snmp_sup, {Sup, self()}}, + {snmp_sub, Sub} | Config]. app_agent_env_init(Env0, Opts) -> @@ -669,35 +813,52 @@ merge_agent_options([{Key, _Value} = Opt|Opts], Options) -> stop_agent(Config) when is_list(Config) -> - ?LOG("stop_agent -> entry with" - "~n Config: ~p",[Config]), - - {Sup, Par} = ?config(snmp_sup, Config), - ?DBG("stop_agent -> attempt to stop (sup) ~p" - "~n Sup: ~p" - "~n Par: ~p", - [Sup, - (catch process_info(Sup)), - (catch process_info(Par))]), - - _Info = agent_info(Sup), - ?DBG("stop_agent -> Agent info: " - "~n ~p", [_Info]), - - stop_sup(Sup, Par), - - {Sup2, Par2} = ?config(snmp_sub, Config), - ?DBG("stop_agent -> attempt to stop (sub) ~p" - "~n Sup2: ~p" - "~n Par2: ~p", - [Sup2, - (catch process_info(Sup2)), - (catch process_info(Par2))]), - stop_sup(Sup2, Par2), - - ?DBG("stop_agent -> done - now cleanup config", []), - C1 = lists:keydelete(snmp_sup, 1, Config), - lists:keydelete(snmp_sub, 1, C1). + ?PRINT2("stop_agent -> entry with" + "~n Config: ~p",[Config]), + + + %% Stop the sub-agent (the agent supervisor) + {SubSup, SubPar} = ?config(snmp_sub, Config), + ?PRINT2("stop_agent -> attempt to stop sub agent (~p)" + "~n Sub Sup info: " + "~n ~p" + "~n Sub Par info: " + "~n ~p", + [SubSup, + (catch process_info(SubSup)), + (catch process_info(SubPar))]), + stop_sup(SubSup, SubPar), + Config2 = lists:keydelete(snmp_sub, 1, Config), + + + %% Stop the master-agent (the top agent supervisor) + {MasterSup, MasterPar} = ?config(snmp_sup, Config), + ?PRINT2("stop_agent -> attempt to stop master agent (~p)" + "~n Master Sup: " + "~n ~p" + "~n Master Par: " + "~n ~p" + "~n Agent Info: " + "~n ~p", + [MasterSup, + (catch process_info(MasterSup)), + (catch process_info(MasterPar)), + agent_info(MasterSup)]), + stop_sup(MasterSup, MasterPar), + Config3 = lists:keydelete(snmp_sup, 1, Config2), + + + %% Stop the top supervisor (of the snmp app) + AppSup = ?config(snmp_app_sup, Config), + ?PRINT2("stop_agent -> attempt to app sup ~p" + "~n App Sup: ~p", + [AppSup, + (catch process_info(AppSup))]), + Config4 = lists:keydelete(snmp_app_sup, 1, Config3), + + + ?PRINT2("stop_agent -> done", []), + Config4. start_sup(Env) -> @@ -727,7 +888,6 @@ stop_sup(Pid, _) -> ?LOG("stop_sup -> attempt to stop ~p", [Pid]), Ref = erlang:monitor(process, Pid), ?LOG("stop_sup -> Ref: ~p", [Ref]), - %% Pid ! {'EXIT', Parent, shutdown}, % usch exit(Pid, kill), await_stopped(Pid, Ref). @@ -863,23 +1023,37 @@ expect(Mod, Line, Type, Enterp, Generic, Specific, ExpVBs) -> expect2(Mod, Line, Fun). expect2(Mod, Line, F) -> - io:format("EXPECT for ~w:~w~n", [Mod, Line]), + io_format_expect("for ~w:~w", [Mod, Line]), case F() of {error, Reason} -> - io:format("EXPECT failed at ~w:~w => ~n~p~n", [Mod, Line, Reason]), + io_format_expect("failed at ~w:~w => " + "~n ~p", [Mod, Line, Reason]), throw({error, {expect, Mod, Line, Reason}}); Else -> - io:format("EXPECT result for ~w:~w => ~n~p~n", [Mod, Line, Else]), + io_format_expect("result for ~w:~w => " + "~n ~p", [Mod, Line, Else]), Else end. %% ---------------------------------------------------------------------- -get_timeout() -> - get_timeout(os:type()). +-define(BASE_REQ_TIMEOUT, 3500). -get_timeout(_) -> 3500. +get_timeout() -> + %% Try to figure out how "fast" a machine is. + %% We assume that the number of schedulers + %% (which depends on the number of core:s) + %% effect the performance of the host... + %% This is obviously not enough. The network + %% also matterns, clock freq or the CPU, ... + %% But its better than what we had before... + case erlang:system_info(schedulers) of + N when is_integer(N) -> + ?BASE_REQ_TIMEOUT + timer:seconds(10 div N); + _ -> + ?BASE_REQ_TIMEOUT + end. receive_pdu(To) -> receive @@ -898,20 +1072,27 @@ receive_trap(To) -> end. +io_format_expect(F) -> + io_format_expect(F, []). + +io_format_expect(F, A) -> + ?PRINT2("EXPECT " ++ F, A). + + do_expect(Expect) when is_atom(Expect) -> do_expect({Expect, get_timeout()}); do_expect({any_pdu, To}) when is_integer(To) orelse (To =:= infinity) -> - io:format("EXPECT any PDU~n", []), + io_format_expect("any PDU"), receive_pdu(To); do_expect({any_trap, To}) -> - io:format("EXPECT any TRAP within ~w~n", [To]), + io_format_expect("any TRAP within ~w", [To]), receive_trap(To); do_expect({timeout, To}) -> - io:format("EXPECT nothing within ~w~n", [To]), + io_format_expect("nothing within ~w", [To]), receive X -> {error, {unexpected, X}} @@ -923,16 +1104,16 @@ do_expect({timeout, To}) -> do_expect({Err, To}) when (is_atom(Err) andalso ((is_integer(To) andalso To > 0) orelse (To =:= infinity))) -> - io:format("EXPECT error ~w within ~w~n", [Err, To]), + io_format_expect("error ~w within ~w", [Err, To]), do_expect({{error, Err}, To}); do_expect({error, Err}) when is_atom(Err) -> Check = fun(_, R) -> R end, - io:format("EXPECT error ~w~n", [Err]), + io_format_expect("error ~w", [Err]), do_expect2(Check, any, Err, any, any, get_timeout()); do_expect({{error, Err}, To}) -> Check = fun(_, R) -> R end, - io:format("EXPECT error ~w within ~w~n", [Err, To]), + io_format_expect("error ~w within ~w", [Err, To]), do_expect2(Check, any, Err, any, any, To); %% exp_varbinds() -> [exp_varbind()] @@ -942,25 +1123,23 @@ do_expect({{error, Err}, To}) -> %% ExpVBs -> exp_varbinds() | {VbsCondition, exp_varbinds()} do_expect(ExpVBs) -> Check = fun(_, R) -> R end, - io:format("EXPECT 'get-response'" - "~n with" - "~n Varbinds: ~p~n", [ExpVBs]), + io_format_expect("'get-response'" + "~n with" + "~n Varbinds: ~p", [ExpVBs]), do_expect2(Check, 'get-response', noError, 0, ExpVBs, get_timeout()). do_expect(v2trap, ExpVBs) -> Check = fun(_, R) -> R end, - io:format("EXPECT 'snmpv2-trap'" - "~n with" - "~n Varbinds: ~p~n", [ExpVBs]), + io_format_expect("'snmpv2-trap' with" + "~n Varbinds: ~p", [ExpVBs]), do_expect2(Check, 'snmpv2-trap', noError, 0, ExpVBs, get_timeout()); do_expect(report, ExpVBs) -> Check = fun(_, R) -> R end, - io:format("EXPECT 'report'" - "~n with" - "~n Varbinds: ~p~n", [ExpVBs]), + io_format_expect("'report' with" + "~n Varbinds: ~p", [ExpVBs]), do_expect2(Check, 'report', noError, 0, ExpVBs, get_timeout()); @@ -969,9 +1148,8 @@ do_expect(inform, ExpVBs) -> do_expect({inform, false}, ExpVBs) -> Check = fun(_, R) -> R end, - io:format("EXPECT 'inform-request' (false)" - "~n with" - "~n Varbinds: ~p~n", [ExpVBs]), + io_format_expect("'inform-request' (false) with" + "~n Varbinds: ~p", [ExpVBs]), do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()); do_expect({inform, true}, ExpVBs) -> @@ -985,9 +1163,8 @@ do_expect({inform, true}, ExpVBs) -> (_, Err) -> Err end, - io:format("EXPECT 'inform-request' (true)" - "~n with" - "~n Varbinds: ~p~n", [ExpVBs]), + io_format_expect("'inform-request' (true) with" + "~n Varbinds: ~p", [ExpVBs]), do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()); do_expect({inform, {error, EStat, EIdx}}, ExpVBs) @@ -1002,11 +1179,10 @@ do_expect({inform, {error, EStat, EIdx}}, ExpVBs) (_, Err) -> Err end, - io:format("EXPECT 'inform-request' (error)" - "~n with" - "~n Error Status: ~p" - "~n Error Index: ~p" - "~n Varbinds: ~p~n", [EStat, EIdx, ExpVBs]), + io_format_expect("'inform-request' (error) with" + "~n Error Status: ~p" + "~n Error Index: ~p" + "~n Varbinds: ~p", [EStat, EIdx, ExpVBs]), do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()). @@ -1017,26 +1193,23 @@ do_expect(Err, Idx, ExpVBs, To) when is_atom(Err) andalso (is_integer(Idx) orelse is_list(Idx) orelse (Idx == any)) -> Check = fun(_, R) -> R end, - io:format("EXPECT 'get-response'" - "~n with" - "~n Error: ~p" - "~n Index: ~p" - "~n Varbinds: ~p" - "~n within ~w~n", [Err, Idx, ExpVBs, To]), + io_format_expect("'get-response' withing ~w ms with" + "~n Error: ~p" + "~n Index: ~p" + "~n Varbinds: ~p", [To, Err, Idx, ExpVBs]), do_expect2(Check, 'get-response', Err, Idx, ExpVBs, To). do_expect(Type, Enterp, Generic, Specific, ExpVBs) -> - do_expect(Type, Enterp, Generic, Specific, ExpVBs, 3500). + do_expect(Type, Enterp, Generic, Specific, ExpVBs, get_timeout()). do_expect(trap, Enterp, Generic, Specific, ExpVBs, To) -> - io:format("EXPECT trap" - "~n with" - "~n Enterp: ~w" - "~n Generic: ~w" - "~n Specific: ~w" - "~n Varbinds: ~w" - "~n within ~w~n", [Enterp, Generic, Specific, ExpVBs, To]), + io_format_expect("trap within ~w ms with" + "~n Enterp: ~w" + "~n Generic: ~w" + "~n Specific: ~w" + "~n Varbinds: ~w", + [To, Enterp, Generic, Specific, ExpVBs]), PureE = purify_oid(Enterp), case receive_trap(To) of #trappdu{enterprise = PureE, @@ -1053,6 +1226,18 @@ do_expect(trap, Enterp, Generic, Specific, ExpVBs, To) -> {PureE, Generic, Specific, ExpVBs}, {Ent2, G2, Spec2, VBs}}}; + {error, timeout} = Error -> + SysEvs = snmp_test_global_sys_monitor:events(), + io_format_expect("[expecting trap] got timeout when system events:" + "~n ~p", [SysEvs]), + if + (SysEvs =:= []) -> + Error; + true -> + skip({system_events, SysEvs}) + end; + + Error -> Error end. @@ -1071,46 +1256,46 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) #pdu{type = Type, error_status = Err, error_index = Idx} when ExpVBs =:= any -> - io:format("EXPECT received expected pdu (1)~n", []), + io_format_expect("received expected pdu (1)"), ok; #pdu{type = Type, request_id = ReqId, error_status = Err2, error_index = Idx} when ExpVBs =:= any -> - io:format("EXPECT received expected pdu with " - "unexpected error status (2): " - "~n Error Status: ~p~n", [Err2]), + io_format_expect("received expected pdu with " + "unexpected error status (2): " + "~n Error Status: ~p", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; #pdu{error_status = Err} when (Type =:= any) andalso (Idx =:= any) andalso (ExpVBs =:= any) -> - io:format("EXPECT received expected pdu (3)~n", []), + io_format_expect("received expected pdu (3)"), ok; #pdu{request_id = ReqId, error_status = Err2} when (Type =:= any) andalso (Idx =:= any) andalso (ExpVBs =:= any) -> - io:format("EXPECT received expected pdu with " - "unexpected error status (4): " - "~n Error Status: ~p~n", [Err2]), + io_format_expect("received expected pdu with " + "unexpected error status (4): " + "~n Error Status: ~p", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; #pdu{type = Type, error_status = Err} when (Idx =:= any) andalso (ExpVBs =:= any) -> - io:format("EXPECT received expected pdu (5)~n", []), + io_format_expect("received expected pdu (5)", []), ok; #pdu{type = Type, request_id = ReqId, error_status = Err2} when (Idx =:= any) andalso (ExpVBs =:= any) -> - io:format("EXPECT received expected pdu with " - "unexpected error status (6): " - "~n Error Status: ~p~n", [Err2]), + io_format_expect("received expected pdu with " + "unexpected error status (6): " + "~n Error Status: ~p", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; #pdu{type = Type, @@ -1119,13 +1304,13 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_index = EI} when is_list(Idx) andalso (ExpVBs =:= any) -> case lists:member(EI, Idx) of true -> - io:format("EXPECT received expected pdu with " - "expected error index (7)~n", []), + io_format_expect("received expected pdu with " + "expected error index (7)"), ok; false -> - io:format("EXPECT received expected pdu with " - "unexpected error index (8): " - "~n Error Index: ~p~n", [EI]), + io_format_expect("received expected pdu with " + "unexpected error index (8): " + "~n Error Index: ~p", [EI]), {error, {unexpected_error_index, EI, Idx, ReqId}} end; @@ -1135,15 +1320,15 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_index = EI} when is_list(Idx) andalso (ExpVBs =:= any) -> case lists:member(EI, Idx) of true -> - io:format("EXPECT received expected pdu with " - "unexpected error status (9): " - "~n Error Status: ~p~n", [Err2]), + io_format_expect("received expected pdu with " + "unexpected error status (9): " + "~n Error Status: ~p", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; false -> - io:format("EXPECT received expected pdu with " - "unexpected error (10): " - "~n Error Status: ~p" - "~n Error index: ~p~n", [Err2, EI]), + io_format_expect("received expected pdu with " + "unexpected error (10): " + "~n Error Status: ~p" + "~n Error index: ~p", [Err2, EI]), {error, {unexpected_error, {Err, Idx}, {Err2, EI}, ReqId}} end; @@ -1151,12 +1336,12 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) request_id = ReqId, error_status = Err2, error_index = Idx2} when ExpVBs =:= any -> - io:format("EXPECT received unexpected pdu with (11) " - "~n Type: ~p" - "~n ReqId: ~p" - "~n Errot status: ~p" - "~n Error index: ~p" - "~n", [Type2, ReqId, Err2, Idx2]), + io_format_expect("received unexpected pdu with (11) " + "~n Type: ~p" + "~n ReqId: ~p" + "~n Error status: ~p" + "~n Error index: ~p", + [Type2, ReqId, Err2, Idx2]), {error, {unexpected_pdu, {Type, Err, Idx}, {Type2, Err2, Idx2}, ReqId}}; @@ -1165,26 +1350,26 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_status = Err, error_index = Idx, varbinds = VBs} = PDU -> - io:format("EXPECT received pdu (12): " - "~n [exp] Type: ~p" - "~n [exp] Error Status: ~p" - "~n [exp] Error Index: ~p" - "~n VBs: ~p" - "~nwhen" - "~n ExpVBs: ~p" - "~n", [Type, Err, Idx, VBs, ExpVBs]), + io_format_expect("received pdu (12): " + "~n [exp] Type: ~p" + "~n [exp] Error Status: ~p" + "~n [exp] Error Index: ~p" + "~n VBs: ~p" + "~nwhen" + "~n ExpVBs: ~p", + [Type, Err, Idx, VBs, ExpVBs]), Check(PDU, check_vbs(purify_oids(ExpVBs), VBs)); #pdu{type = Type, error_status = Err, varbinds = VBs} = PDU when Idx =:= any -> - io:format("EXPECT received pdu (13): " - "~n [exp] Type: ~p" - "~n [exp] Error Status: ~p" - "~n VBs: ~p" - "~nwhen" - "~n ExpVBs: ~p" - "~n", [Type, Err, VBs, ExpVBs]), + io_format_expect("received pdu (13): " + "~n [exp] Type: ~p" + "~n [exp] Error Status: ~p" + "~n VBs: ~p" + "~nwhen" + "~n ExpVBs: ~p", + [Type, Err, VBs, ExpVBs]), Check(PDU, check_vbs(purify_oids(ExpVBs), VBs)); #pdu{type = Type, @@ -1192,15 +1377,15 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_status = Err, error_index = EI, varbinds = VBs} = PDU when is_list(Idx) -> - io:format("EXPECT received pdu (14): " - "~n [exp] Type: ~p" - "~n ReqId: ~p" - "~n [exp] Error Status: ~p" - "~n [exp] Error Index: ~p" - "~n VBs: ~p" - "~nwhen" - "~n ExpVBs: ~p" - "~n", [Type, ReqId, Err, EI, VBs, ExpVBs]), + io_format_expect("received pdu (14): " + "~n [exp] Type: ~p" + "~n ReqId: ~p" + "~n [exp] Error Status: ~p" + "~n [exp] Error Index: ~p" + "~n VBs: ~p" + "~nwhen" + "~n ExpVBs: ~p", + [Type, ReqId, Err, EI, VBs, ExpVBs]), PureVBs = purify_oids(ExpVBs), case lists:member(EI, Idx) of true -> @@ -1214,24 +1399,36 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_status = Err2, error_index = Idx2, varbinds = VBs2} -> - io:format("EXPECT received unexpected pdu with (15) " - "~n Type: ~p" - "~n ReqId: ~p" - "~n Errot status: ~p" - "~n Error index: ~p" - "~n Varbinds: ~p" - "~n", [Type2, ReqId, Err2, Idx2, VBs2]), + io_format_expect("received unexpected pdu with (15) " + "~n Type: ~p" + "~n ReqId: ~p" + "~n Error status: ~p" + "~n Error index: ~p" + "~n Varbinds: ~p", + [Type2, ReqId, Err2, Idx2, VBs2]), {error, {unexpected_pdu, {Type, Err, Idx, purify_oids(ExpVBs)}, {Type2, Err2, Idx2, VBs2}, ReqId}}; - Error -> - io:format("EXPECT received error (16): " - "~n Error: ~p" - "~n", [Error]), - Error + + {error, timeout} = Error -> + SysEvs = snmp_test_global_sys_monitor:events(), + io_format_expect("got timeout (16) when system events:" + "~n ~p", [SysEvs]), + if + (SysEvs =:= []) -> + Error; + true -> + skip({system_events, SysEvs}) + end; + + + Error -> + io_format_expect("received error (17): " + "~n Error: ~p", [Error]), + Error end. @@ -1349,12 +1546,15 @@ start_node(Name) -> "" end, %% Do not use start_link!!! (the proc that calls this one is tmp) - ?DBG("start_node -> Args: ~p~n",[Args]), - A = Args ++ " -pa " ++ Pa, + ?DBG("start_node -> Args: ~p~n", [Args]), + A = Args ++ " -pa " ++ Pa ++ + " -s " ++ atom_to_list(snmp_test_sys_monitor) ++ " start" ++ + " -s global sync", case (catch ?START_NODE(Name, A)) of {ok, Node} -> %% Tell the test_server to not clean up things it never started. ?DBG("start_node -> Node: ~p",[Node]), + global:sync(), {ok, Node}; Else -> ?ERR("start_node -> failed with(other): Else: ~p",[Else]), @@ -1672,6 +1872,10 @@ rpc(Node, F, A) -> join(Dir, File) -> filename:join(Dir, File). + +skip(R) -> + exit({skip, R}). + %% await_pdu(To) -> %% await_response(To, pdu). %% diff --git a/lib/snmp/test/snmp_compiler_test.erl b/lib/snmp/test/snmp_compiler_test.erl index 0a7b729d1f..a28f925a22 100644 --- a/lib/snmp/test/snmp_compiler_test.erl +++ b/lib/snmp/test/snmp_compiler_test.erl @@ -226,22 +226,20 @@ agent_capabilities(Config) when is_list(Config) -> put(tname,agent_capabilities), p("starting with Config: ~p~n", [Config]), - SnmpPrivDir = code:priv_dir(snmp), + SnmpPrivDir = which_priv_dir(snmp), SnmpMibsDir = join(SnmpPrivDir, "mibs"), - OtpMibsPrivDir = code:priv_dir(otp_mibs), - OtpMibsMibsDir = join(OtpMibsPrivDir, "mibs"), Dir = ?config(mib_dir, Config), AcMib = join(Dir,"AC-TEST-MIB.mib"), ?line {ok, MibFile1} = snmpc:compile(AcMib, [options, version, - {i, [SnmpMibsDir, OtpMibsMibsDir]}, + {i, [SnmpMibsDir]}, {outdir, Dir}, {verbosity, trace}]), ?line {ok, Mib1} = snmp_misc:read_mib(MibFile1), ?line {ok, MibFile2} = snmpc:compile(AcMib, [options, version, agent_capabilities, - {i, [SnmpMibsDir, OtpMibsMibsDir]}, + {i, [SnmpMibsDir]}, {outdir, Dir}, {verbosity, trace}]), ?line {ok, Mib2} = snmp_misc:read_mib(MibFile2), @@ -269,28 +267,26 @@ module_compliance(Config) when is_list(Config) -> put(tname,module_compliance), p("starting with Config: ~p~n", [Config]), - SnmpPrivDir = code:priv_dir(snmp), - SnmpMibsDir = join(SnmpPrivDir, "mibs"), - OtpMibsPrivDir = code:priv_dir(otp_mibs), - OtpMibsMibsDir = join(OtpMibsPrivDir, "mibs"), - Dir = ?config(mib_dir, Config), - AcMib = join(Dir,"MC-TEST-MIB.mib"), + SnmpPrivDir = which_priv_dir(snmp), + SnmpMibsDir = join(SnmpPrivDir, "mibs"), + Dir = ?config(mib_dir, Config), + AcMib = join(Dir,"MC-TEST-MIB.mib"), ?line {ok, MibFile1} = snmpc:compile(AcMib, [options, version, - {i, [SnmpMibsDir, OtpMibsMibsDir]}, + {i, [SnmpMibsDir]}, {outdir, Dir}, {verbosity, trace}]), ?line {ok, Mib1} = snmp_misc:read_mib(MibFile1), ?line {ok, MibFile2} = snmpc:compile(AcMib, [options, version, module_compliance, - {i, [SnmpMibsDir, OtpMibsMibsDir]}, + {i, [SnmpMibsDir]}, {outdir, Dir}, {verbosity, trace}]), ?line {ok, Mib2} = snmp_misc:read_mib(MibFile2), MEDiff = Mib2#mib.mes -- Mib1#mib.mes, %% This is a rather pathetic test, but it is somthing... - io:format("agent_capabilities -> " + io:format("module_compliance -> " "~n MEDiff: ~p" "~n Mib1: ~p" "~n Mib2: ~p" @@ -731,6 +727,15 @@ check_desc(Desc1, Desc2) -> exit({'description not equal', Desc1, Desc2}). +which_priv_dir(App) -> + case code:priv_dir(App) of + Dir when is_list(Dir) -> + Dir; + {error, Reason} -> + exit({App, priv_dir_not_found, Reason}) + end. + + %% join(Comp) -> %% filename:join(Comp). diff --git a/lib/snmp/test/snmp_manager_config_test.erl b/lib/snmp/test/snmp_manager_config_test.erl index 64d3134055..ccbdd77629 100644 --- a/lib/snmp/test/snmp_manager_config_test.erl +++ b/lib/snmp/test/snmp_manager_config_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ -include_lib("common_test/include/ct.hrl"). -include("snmp_test_lib.hrl"). -include_lib("snmp/src/manager/snmpm_usm.hrl"). +-include_lib("snmp/src/app/snmp_internal.hrl"). %%---------------------------------------------------------------------- @@ -2259,11 +2260,13 @@ create_and_increment(Conf) when is_list(Conf) -> ?line {ok, _Pid} = snmpm_config:start_link(Opts), %% Random init - random:seed(erlang:phash2([node()]), - erlang:monotonic_time(), - erlang:unique_integer()), + ?SNMP_RAND_SEED(), + %% rand:seed(exrop, + %% {erlang:phash2([node()]), + %% erlang:monotonic_time(), + %% erlang:unique_integer()}), - StartVal = random:uniform(2147483647), + StartVal = rand:uniform(2147483647), IncVal = 42, EndVal = StartVal + IncVal, diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 6ced55f0cc..e2356bd70a 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -62,41 +62,32 @@ register_user1/1, - register_agent1/1, + register_agent_old/1, register_agent2/1, register_agent3/1, info/1, - simple_sync_get1/1, simple_sync_get2/1, simple_sync_get3/1, - simple_async_get1/1, simple_async_get2/1, simple_async_get3/1, - simple_sync_get_next1/1, simple_sync_get_next2/1, simple_sync_get_next3/1, - simple_async_get_next1/1, simple_async_get_next2/1, simple_async_get_next3/1, - simple_sync_set1/1, simple_sync_set2/1, simple_sync_set3/1, - simple_async_set1/1, simple_async_set2/1, simple_async_set3/1, - simple_sync_get_bulk1/1, simple_sync_get_bulk2/1, simple_sync_get_bulk3/1, - simple_async_get_bulk1/1, simple_async_get_bulk2/1, simple_async_get_bulk3/1, - misc_async1/1, misc_async2/1, discovery/1, @@ -163,6 +154,10 @@ init_per_suite(Config0) when is_list(Config0) -> %% until we have a more important reason to fix this. case snmp_test_lib:crypto_start() of ok -> + + snmp_test_global_sys_monitor:start(), + snmp_test_sys_monitor:start(), % We need one on this node also + Config1 = snmp_test_lib:init_suite_top_dir(?MODULE, Config0), Config2 = snmp_test_lib:fix_data_dir(Config1), %% Mib-dirs @@ -181,33 +176,33 @@ end_per_suite(Config) when is_list(Config) -> ?DBG("end_per_suite -> entry with" "~n Config: ~p", [Config]), + snmp_test_sys_monitor:stop(), + snmp_test_global_sys_monitor:stop(), + Config. init_per_testcase(Case, Config) when is_list(Config) -> - io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE, Case]), p(Case, "init_per_testcase begin when" "~n Nodes: ~p~n~n", [erlang:nodes()]), %% This version of the API, based on Addr and Port, has been deprecated DeprecatedApiCases = [ - simple_sync_get1, - simple_async_get1, - simple_sync_get_next1, - simple_async_get_next1, - simple_sync_set1, - simple_async_set1, - simple_sync_get_bulk1, - simple_async_get_bulk1, - misc_async1 ], Result = case lists:member(Case, DeprecatedApiCases) of true -> - %% ?SKIP(api_no_longer_supported); - {skip, api_no_longer_supported}; + {skip, "API no longer supported"}; false -> - init_per_testcase2(Case, Config) + try init_per_testcase2(Case, Config) + catch + C:{skip, _} = E:_ when ((C =:= throw) orelse + (C =:= exit)) -> + E; + C:E:_ when ((C =:= throw) orelse + (C =:= exit)) -> + {skip, {catched, C, E}} + end end, p(Case, "init_per_testcase end when" "~n Nodes: ~p" @@ -326,9 +321,25 @@ init_per_testcase3(Case, Config) -> true -> Config end, + %% We don't need to try catch this (init_agent) + %% since we have a try catch "higher up"... Conf2 = init_agent(Conf1), - Conf3 = init_manager(AutoInform, Conf2), - Conf4 = init_mgr_user(Conf3), + Conf3 = try init_manager(AutoInform, Conf2) + catch AC:AE:_ -> + %% Ouch we need to clean up: + %% The init_agent starts an agent node! + init_per_testcase_fail_agent_cleanup(Conf2), + throw({skip, {manager_init_failed, AC, AE}}) + end, + Conf4 = try init_mgr_user(Conf3) + catch MC:ME:_ -> + %% Ouch we need to clean up: + %% The init_agent starts an agent node! + %% The init_magager starts an manager node! + init_per_testcase_fail_manager_cleanup(Conf3), + init_per_testcase_fail_agent_cleanup(Conf3), + throw({skip, {manager_user_init_failed, MC, ME}}) + end, case lists:member(Case, ApiCases02 ++ ApiCases03) of true -> init_mgr_user_data2(Conf4); @@ -339,6 +350,12 @@ init_per_testcase3(Case, Config) -> Config end. +init_per_testcase_fail_manager_cleanup(Conf) -> + (catch fin_manager(Conf)). + +init_per_testcase_fail_agent_cleanup(Conf) -> + (catch fin_agent(Conf)). + end_per_testcase(Case, Config) when is_list(Config) -> p(Case, "end_per_testcase begin when" "~n Nodes: ~p~n~n", [erlang:nodes()]), @@ -452,7 +469,7 @@ groups() -> }, {agent_tests, [], [ - register_agent1, + register_agent_old, register_agent2, register_agent3 ] @@ -477,47 +494,38 @@ groups() -> }, {get_tests, [], [ - simple_sync_get1, simple_sync_get2, simple_sync_get3, - simple_async_get1, simple_async_get2, simple_async_get3 ] }, {get_next_tests, [], [ - simple_sync_get_next1, simple_sync_get_next2, simple_sync_get_next3, - simple_async_get_next1, simple_async_get_next2, simple_async_get_next3 ] }, {set_tests, [], [ - simple_sync_set1, simple_sync_set2, simple_sync_set3, - simple_async_set1, simple_async_set2, simple_async_set3 ] }, {bulk_tests, [], [ - simple_sync_get_bulk1, simple_sync_get_bulk2, simple_sync_get_bulk3, - simple_async_get_bulk1, simple_async_get_bulk2, simple_async_get_bulk3 ] }, {misc_request_tests, [], [ - misc_async1, misc_async2 ] }, @@ -568,7 +576,7 @@ groups() -> ipv6_tests() -> [ - register_agent1, + register_agent_old, simple_sync_get_next3, simple_async_get2, simple_sync_get3, @@ -592,38 +600,47 @@ init_per_group(event_tests_mt = GroupName, Config) -> GroupName, [{manager_net_if_module, snmpm_net_if_mt} | Config]); init_per_group(ipv6_mt = GroupName, Config) -> - {ok, Hostname0} = inet:gethostname(), - case ct:require(ipv6_hosts) of - ok -> - case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of - true -> - ipv6_init( - snmp_test_lib:init_group_top_dir( - GroupName, - [{manager_net_if_module, snmpm_net_if_mt} - | Config])); - false -> - {skip, "Host does not support IPv6"} - end; - _ -> - {skip, "Test config ipv6_hosts is missing"} - end; + init_per_group_ipv6(GroupName, + [{manager_net_if_module, snmpm_net_if_mt} | Config]); init_per_group(ipv6 = GroupName, Config) -> - {ok, Hostname0} = inet:gethostname(), - case ct:require(ipv6_hosts) of - ok -> - case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of - true -> - ipv6_init(snmp_test_lib:init_group_top_dir(GroupName, Config)); - false -> - {skip, "Host does not support IPv6"} - end; - _ -> - {skip, "Test config ipv6_hosts is missing"} - end; + init_per_group_ipv6(GroupName, Config); init_per_group(GroupName, Config) -> snmp_test_lib:init_group_top_dir(GroupName, Config). + +init_per_group_ipv6(GroupName, Config) -> + %% <OS-CONDITIONAL-SKIP> + OSSkipable = [{unix, + [ + {darwin, fun(V) when (V > {9, 8, 0}) -> + %% This version is OK: No Skip + false; + (_) -> + %% This version is *not* ok: Skip + %% We need a fully qualified hostname + %% to get a proper IPv6 address (in this + %% version), but its just to messy, so + %% instead we skip this **OLD** darwin... + true + end} + ] + }], + %% </OS-CONDITIONAL-SKIP> + case ?OS_BASED_SKIP(OSSkipable) of + true -> + {skip, "Host *may* not *properly* support IPV6"}; + false -> + %% Even if this host supports IPv6 we don't use it unless its + %% one of the configures/supported IPv6 hosts... + case (?HAS_SUPPORT_IPV6() andalso ?IS_IPV6_HOST()) of + true -> + ipv6_init(snmp_test_lib:init_group_top_dir(GroupName, Config)); + false -> + {skip, "Host does not support IPv6"} + end + end. + + end_per_group(_GroupName, Config) -> %% Do we really need to do this? lists:keydelete(snmp_group_top_dir, 1, Config). @@ -635,11 +652,11 @@ end_per_group(_GroupName, Config) -> simple_start_and_stop1(suite) -> []; simple_start_and_stop1(Config) when is_list(Config) -> - %% ?SKIP(not_yet_implemented), - process_flag(trap_exit, true), - put(tname,ssas1), - p("starting with Config: ~n~p", [Config]), + ?TC_TRY(simple_start_and_stop1, + fun() -> do_simple_start_and_stop1(Config) end). +do_simple_start_and_stop1(Config) -> + p("starting with Config: ~n~p", [Config]), ConfDir = ?config(manager_conf_dir, Config), DbDir = ?config(manager_db_dir, Config), @@ -660,7 +677,6 @@ simple_start_and_stop1(Config) when is_list(Config) -> ?SLEEP(1000), - p("end"), ok. @@ -668,9 +684,10 @@ simple_start_and_stop1(Config) when is_list(Config) -> simple_start_and_stop2(suite) -> []; simple_start_and_stop2(Config) when is_list(Config) -> - %% ?SKIP(not_yet_implemented), - process_flag(trap_exit, true), - put(tname,ssas2), + ?TC_TRY(simple_start_and_stop2, + fun() -> do_simple_start_and_stop2(Config) end). + +do_simple_start_and_stop2(Config) -> p("starting with Config: ~p~n", [Config]), ManagerNode = start_manager_node(), @@ -708,7 +725,6 @@ simple_start_and_stop2(Config) when is_list(Config) -> ?SLEEP(1000), - p("end"), ok. @@ -716,8 +732,10 @@ simple_start_and_stop2(Config) when is_list(Config) -> simple_start_and_monitor_crash1(suite) -> []; simple_start_and_monitor_crash1(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,ssamc1), + ?TC_TRY(simple_start_and_monitor_crash1, + fun() -> do_simple_start_and_monitor_crash1(Config) end). + +do_simple_start_and_monitor_crash1(Config) -> p("starting with Config: ~n~p", [Config]), ConfDir = ?config(manager_conf_dir, Config), @@ -761,7 +779,6 @@ simple_start_and_monitor_crash1(Config) when is_list(Config) -> ?FAIL(timeout) end, - p("end"), ok. @@ -769,8 +786,10 @@ simple_start_and_monitor_crash1(Config) when is_list(Config) -> simple_start_and_monitor_crash2(suite) -> []; simple_start_and_monitor_crash2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,ssamc2), + ?TC_TRY(simple_start_and_monitor_crash2, + fun() -> do_simple_start_and_monitor_crash2(Config) end). + +do_simple_start_and_monitor_crash2(Config) -> p("starting with Config: ~n~p", [Config]), ConfDir = ?config(manager_conf_dir, Config), @@ -815,7 +834,6 @@ simple_start_and_monitor_crash2(Config) when is_list(Config) -> ?FAIL(timeout) end, - p("end"), ok. @@ -861,8 +879,10 @@ simulate_crash(NumKills, _) -> notify_started01(suite) -> []; notify_started01(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,ns01), + ?TC_TRY(notify_started01, + fun() -> do_notify_started01(Config) end). + +do_notify_started01(Config) -> p("starting with Config: ~n~p", [Config]), ConfDir = ?config(manager_conf_dir, Config), @@ -949,37 +969,34 @@ snmpm_starter(Opts, To) -> notify_started02(suite) -> []; notify_started02(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,ns02), + ?TC_TRY(notify_started02, + fun() -> notify_started02_cond(Config) end, + fun() -> do_notify_started02(Config) end). - %% <CONDITIONAL-SKIP> - %% The point of this is to catch machines running - %% SLES9 (2.6.5) +notify_started02_cond(Config) -> LinuxVersionVerify = fun() -> case os:cmd("uname -m") of "i686" ++ _ -> -%% io:format("found an i686 machine, " -%% "now check version~n", []), case os:version() of {2, 6, Rev} when Rev >= 16 -> - true; + false; {2, Min, _} when Min > 6 -> - true; + false; {Maj, _, _} when Maj > 2 -> - true; + false; _ -> - false + true end; _ -> - true + false end end, Skippable = [{unix, [{linux, LinuxVersionVerify}]}], Condition = fun() -> ?OS_BASED_SKIP(Skippable) end, - ?NON_PC_TC_MAYBE_SKIP(Config, Condition), - %% </CONDITIONAL-SKIP> - + ?NON_PC_TC_MAYBE_SKIP(Config, Condition). + +do_notify_started02(Config) -> p("starting with Config: ~n~p", [Config]), ConfDir = ?config(manager_conf_dir, Config), @@ -987,24 +1004,52 @@ notify_started02(Config) when is_list(Config) -> write_manager_conf(ConfDir), - Opts = [{server, [{verbosity, log}]}, - {net_if, [{verbosity, silence}]}, + Opts = [{server, [{verbosity, log}]}, + {net_if, [{verbosity, silence}]}, {note_store, [{verbosity, silence}]}, - {config, [{verbosity, log}, {dir, ConfDir}, {db_dir, DbDir}]}], + {config, [{verbosity, debug}, {dir, ConfDir}, {db_dir, DbDir}]}], p("start snmpm client process"), - Pid1 = ns02_loop1_start(), + NumIterations = 5, + Pid1 = ns02_client_start(NumIterations), + + p("start snmpm ctrl (starter) process"), + Pid2 = ns02_ctrl_start(Opts, NumIterations), + + %% On a reasonably fast machine, one iteration takes approx 4 seconds. + %% We measure the first iteration, and then we wait for the remaining + %% ones (4 in this case). + ApproxStartTime = + case ns02_client_await_approx_runtime(Pid1) of + {ok, T} -> + T; + {error, Reason} -> + %% Attempt cleanup just in case + exit(Pid1, kill), + exit(Pid2, kill), + ?FAIL(Reason); + {skip, Reason} -> + %% Attempt cleanup just in case + exit(Pid1, kill), + exit(Pid2, kill), + ?SKIP(Reason) + end, - p("start snmpm starter process"), - Pid2 = ns02_loop2_start(Opts), - - p("await snmpm client process exit"), + p("await snmpm client process exit (max ~p+10000 msec)", [ApproxStartTime]), receive + %% We take this opportunity to check if we got a skip from + %% the ctrl process. + {'EXIT', Pid2, {skip, SkipReason1}} -> + ?SKIP(SkipReason1); {'EXIT', Pid1, normal} -> ok; + {'EXIT', Pid1, {suite_failed, Reason1}} -> + ?FAIL({client, Reason1}); {'EXIT', Pid1, Reason1} -> - ?FAIL(Reason1) - after 25000 -> + ?FAIL({client, Reason1}) + after ApproxStartTime + 10000 -> + exit(Pid1, kill), + exit(Pid2, kill), ?FAIL(timeout) end, @@ -1012,9 +1057,13 @@ notify_started02(Config) when is_list(Config) -> receive {'EXIT', Pid2, normal} -> ok; + {'EXIT', Pid2, {skip, SkipReason2}} -> + %% In case of a race + ?SKIP(SkipReason2); {'EXIT', Pid2, Reason2} -> - ?FAIL(Reason2) + ?FAIL({ctrl, Reason2}) after 5000 -> + exit(Pid2, kill), ?FAIL(timeout) end, @@ -1022,26 +1071,63 @@ notify_started02(Config) when is_list(Config) -> ok. -ns02_loop1_start() -> - spawn_link(fun() -> ns02_loop1() end). +ns02_client_start(N) -> + Self = self(), + spawn_link(fun() -> ns02_client(Self, N) end). + +ns02_client_await_approx_runtime(Pid) -> + receive + {?MODULE, client_time, Time} -> + {ok, Time}; + {'EXIT', Pid, Reason} -> + p("client (~p) failed: " + "~n ~p", [Pid, Reason]), + {error, Reason} + + after 30000 -> + %% Either something is *really* wrong or this machine + %% is dog slow. Either way, this is a skip-reason... + {skip, approx_runtime_timeout} + end. + -ns02_loop1() -> - put(tname,ns02_loop1), +ns02_client(Parent, N) when is_pid(Parent) -> + put(tname, ns02_client), p("starting"), - ns02_loop1(dummy, snmpm:notify_started(?NS_TIMEOUT), 5). + ns02_client_loop(Parent, + dummy, snmpm:notify_started(?NS_TIMEOUT), + snmp_misc:now(ms), undefined, + N). -ns02_loop1(_Ref, _Pid, 0) -> - p("done"), +ns02_client_loop(_Parent, _Ref, _Pid, _Begin, _End, 0) -> + %% p("loop -> done"), exit(normal); -ns02_loop1(Ref, Pid, N) -> - p("entry when" - "~n Ref: ~p" - "~n Pid: ~p" - "~n N: ~p", [Ref, Pid, N]), +ns02_client_loop(Parent, Ref, Pid, Begin, End, N) + when is_pid(Parent) andalso is_integer(Begin) andalso is_integer(End) -> + %% p("loop -> [~w] inform parent: ~w, ~w => ~w", [N, Begin, End, End-Begin]), + Parent ! {?MODULE, client_time, N*(End-Begin)}, + ns02_client_loop(undefined, Ref, Pid, snmp_misc:now(ms), undefined, N); +ns02_client_loop(Parent, Ref, Pid, Begin, End, N) + when is_integer(Begin) andalso is_integer(End) -> + %% p("loop -> [~w] entry when" + %% "~n Ref: ~p" + %% "~n Pid: ~p" + %% "~n Begin: ~p" + %% "~n End: ~p", [N, Ref, Pid, Begin, End]), + ns02_client_loop(Parent, Ref, Pid, snmp_misc:now(ms), undefined, N); +ns02_client_loop(Parent, Ref, Pid, Begin, End, N) -> + %% p("loop(await message) -> [~w] entry when" + %% "~n Ref: ~p" + %% "~n Pid: ~p" + %% "~n Begin: ~p" + %% "~n End: ~p", [N, Ref, Pid, Begin, End]), receive {snmpm_started, Pid} -> p("received expected started message (~w)", [N]), - ns02_loop1(snmpm:monitor(), dummy, N); + ns02_client_loop(Parent, + snmpm:monitor(), dummy, + Begin, End, + N); {snmpm_start_timeout, Pid} -> p("unexpected timout"), ?FAIL({unexpected_start_timeout, Pid}); @@ -1049,40 +1135,72 @@ ns02_loop1(Ref, Pid, N) -> p("received expected DOWN message (~w) with" "~n Obj: ~p" "~n Reason: ~p", [N, Obj, Reason]), - ns02_loop1(dummy, snmpm:notify_started(?NS_TIMEOUT), N-1) - after 10000 -> - ?FAIL(timeout) + ns02_client_loop(Parent, + dummy, snmpm:notify_started(?NS_TIMEOUT), + Begin, snmp_misc:now(ms), + N-1) end. - -ns02_loop2_start(Opts) -> - spawn_link(fun() -> ns02_loop2(Opts) end). +ns02_ctrl_start(Opts, N) -> + spawn_link(fun() -> ns02_ctrl(Opts, N) end). -ns02_loop2(Opts) -> - put(tname,ns02_loop2), +ns02_ctrl(Opts, N) -> + put(tname, ns02_ctrl), p("starting"), - ns02_loop2(Opts, 5). + ns02_ctrl_loop(Opts, N). + -ns02_loop2(_Opts, 0) -> +%% We have seen that some times it takes unreasonably long time to +%% start the manager (it got "stuck" in snmpm_config). But since +%% we did not have enough verbosity, we do not know how far it got. +%% So, we try to monitor each start attempt. We allow 5 sec (just +%% to give slow boxes a chance). +ns02_ctrl_loop(_Opts, 0) -> p("done"), exit(normal); -ns02_loop2(Opts, N) -> +ns02_ctrl_loop(Opts, N) -> p("entry when N: ~p", [N]), ?SLEEP(2000), p("start manager"), - snmpm:start(Opts), + TS1 = erlang:system_time(millisecond), + {StarterPid, StarterMRef} = + erlang:spawn_monitor(fun() -> exit(snmpm:start(Opts)) end), + receive + {'DOWN', StarterMRef, process, StarterPid, ok} -> + TS2 = erlang:system_time(millisecond), + p("manager started: ~w ms", [TS2-TS1]), + ok + after 5000 -> + p("manager (~p) start timeout - kill", [StarterPid]), + exit(StarterPid, kill), + exit({skip, start_timeout}) + end, ?SLEEP(2000), p("stop manager"), - snmpm:stop(), - ns02_loop2(Opts, N-1). + ?SLEEP(100), % Give the verbosity to take effect... + TS3 = erlang:system_time(millisecond), + case snmpm:stop(5000) of + ok -> + TS4 = erlang:system_time(millisecond), + p("manager stopped: ~p ms", [TS4-TS3]), + ok; + {error, timeout} -> + p("manager stop timeout - kill (cleanup) and skip"), + exit(whereis(snmpm_supervisor), kill), + exit({skip, stop_timeout}) + end, + ns02_ctrl_loop(Opts, N-1). + %%====================================================================== info(suite) -> []; info(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,info), + ?TC_TRY(info, + fun() -> do_info(Config) end). + +do_info(Config) -> p("starting with Config: ~n~p", [Config]), ConfDir = ?config(manager_conf_dir, Config), @@ -1110,7 +1228,6 @@ info(Config) when is_list(Config) -> ?SLEEP(1000), - p("end"), ok. verify_info(Info) when is_list(Info) -> @@ -1150,9 +1267,10 @@ verify_info([{Key, SubKeys}|Keys], Info) -> register_user1(suite) -> []; register_user1(Config) when is_list(Config) -> - %% ?SKIP(not_yet_implemented). - process_flag(trap_exit, true), - put(tname,ru1), + ?TC_TRY(register_user1, + fun() -> do_register_user1(Config) end). + +do_register_user1(Config) -> p("starting with Config: ~p~n", [Config]), ManagerNode = start_manager_node(), @@ -1226,7 +1344,6 @@ register_user1(Config) when is_list(Config) -> ?SLEEP(1000), - p("end"), ok. verify_users([], []) -> @@ -1244,14 +1361,15 @@ verify_users(ActualUsers0, [User|RegUsers]) -> %%====================================================================== -register_agent1(doc) -> +register_agent_old(doc) -> ["Test registration of agents with the OLD interface functions"]; -register_agent1(suite) -> +register_agent_old(suite) -> []; -register_agent1(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,ra1), - +register_agent_old(Config) when is_list(Config) -> + ?TC_TRY(register_agent_old, + fun() -> do_register_agent_old(Config) end). + +do_register_agent_old(Config) -> p("starting with Config: ~p~n", [Config]), ManagerNode = start_manager_node(), @@ -1366,7 +1484,6 @@ register_agent1(Config) when is_list(Config) -> ?SLEEP(1000), - p("end"), ok. @@ -1377,8 +1494,10 @@ register_agent2(doc) -> register_agent2(suite) -> []; register_agent2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, ra2), + ?TC_TRY(register_agent2, + fun() -> do_register_agent2(Config) end). + +do_register_agent2(Config) -> p("starting with Config: ~p~n", [Config]), ManagerNode = start_manager_node(), @@ -1511,7 +1630,6 @@ register_agent2(Config) when is_list(Config) -> ?SLEEP(1000), - p("end"), ok. @@ -1523,8 +1641,10 @@ register_agent3(doc) -> register_agent3(suite) -> []; register_agent3(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, ra3), + ?TC_TRY(register_agent3, + fun() -> do_register_agent3(Config) end). + +do_register_agent3(Config) -> p("starting with Config: ~p~n", [Config]), ManagerNode = start_manager_node(), @@ -1661,89 +1781,27 @@ register_agent3(Config) when is_list(Config) -> ?SLEEP(1000), - p("end"), ok. %%====================================================================== -simple_sync_get1(doc) -> ["Simple sync get-request - Old style (Addr & Port)"]; -simple_sync_get1(suite) -> []; -simple_sync_get1(Config) when is_list(Config) -> - ?SKIP(api_no_longer_supported), - - process_flag(trap_exit, true), - put(tname, ssg1), - p("starting with Config: ~p~n", [Config]), - - Node = ?config(manager_node, Config), - Addr = ?config(manager_agent_target_name, Config), - Port = ?AGENT_PORT, - - p("issue get-request without loading the mib"), - Oids1 = [?sysObjectID_instance, ?sysDescr_instance, ?sysUpTime_instance], - ?line ok = do_simple_sync_get(Node, Addr, Port, Oids1), - - p("issue get-request after first loading the mibs"), - ?line ok = mgr_user_load_mib(Node, std_mib()), - Oids2 = [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]], - ?line ok = do_simple_sync_get(Node, Addr, Port, Oids2), - - p("Display log"), - display_log(Config), - - p("done"), - ok. - -do_simple_sync_get(Node, Addr, Port, Oids) -> - ?line {ok, Reply, _Rem} = mgr_user_sync_get(Node, Addr, Port, Oids), - - ?DBG("~n Reply: ~p" - "~n Rem: ~w", [Reply, _Rem]), - - %% verify that the operation actually worked: - %% The order should be the same, so no need to seach - ?line ok = case Reply of - {noError, 0, [#varbind{oid = ?sysObjectID_instance, - value = SysObjectID}, - #varbind{oid = ?sysDescr_instance, - value = SysDescr}, - #varbind{oid = ?sysUpTime_instance, - value = SysUpTime}]} -> - p("expected result from get: " - "~n SysObjectID: ~p" - "~n SysDescr: ~s" - "~n SysUpTime: ~w", - [SysObjectID, SysDescr, SysUpTime]), - ok; - {noError, 0, Vbs} -> - p("unexpected varbinds: ~n~p", [Vbs]), - {error, {unexpected_vbs, Vbs}}; - Else -> - p("unexpected reply: ~n~p", [Else]), - {error, {unexpected_response, Else}} - end, - ok. - - -%%====================================================================== - simple_sync_get2(doc) -> ["Simple sync get-request - Version 2 API (TargetName)"]; simple_sync_get2(suite) -> []; simple_sync_get2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, ssg2), - do_simple_sync_get2(Config), - display_log(Config), - ok. + ?TC_TRY(simple_sync_get2, + fun() -> do_simple_sync_get2(Config) end). do_simple_sync_get2(Config) -> + p("starting with Config: ~n~p", [Config]), Get = fun(Node, TargetName, Oids) -> mgr_user_sync_get(Node, TargetName, Oids) end, PostVerify = fun() -> ok end, - do_simple_sync_get2(Config, Get, PostVerify). + do_simple_sync_get2(Config, Get, PostVerify), + display_log(Config), + ok. do_simple_sync_get2(Config, Get, PostVerify) -> p("starting with Config: ~p~n", [Config]), @@ -1799,13 +1857,11 @@ simple_sync_get3(doc) -> ["Simple sync get-request - Version 3 API (TargetName and send-opts)"]; simple_sync_get3(suite) -> []; simple_sync_get3(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, ssg3), - do_simple_sync_get3(Config), - display_log(Config), - ok. + ?TC_TRY(simple_sync_get3, + fun() -> do_simple_sync_get3(Config) end). do_simple_sync_get3(Config) -> + p("starting with Config: ~n~p", [Config]), Self = self(), Msg = simple_sync_get3, Fun = fun() -> Self ! Msg end, @@ -1824,81 +1880,14 @@ do_simple_sync_get3(Config) -> ok end end, - do_simple_sync_get2(Config, Get, PostVerify). - - -%%====================================================================== - -simple_async_get1(doc) -> - ["Simple (async) get-request - Old style (Addr & Port)"]; -simple_async_get1(suite) -> []; -simple_async_get1(Config) when is_list(Config) -> - ?SKIP(api_no_longer_supported), - - process_flag(trap_exit, true), - put(tname, sag1), - p("starting with Config: ~p~n", [Config]), - - MgrNode = ?config(manager_node, Config), - AgentNode = ?config(agent_node, Config), - Addr = ?config(ip, Config), - Port = ?AGENT_PORT, - - ?line ok = mgr_user_load_mib(MgrNode, std_mib()), - Test2Mib = test2_mib(Config), - ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), - ?line ok = agent_load_mib(AgentNode, Test2Mib), - - Exec = fun(Data) -> - async_g_exec1(MgrNode, Addr, Port, Data) - end, - - Requests = - [ - { 1, - [?sysObjectID_instance], - Exec, - fun(X) -> sag_verify(X, [?sysObjectID_instance]) end }, - { 2, - [?sysDescr_instance, ?sysUpTime_instance], - Exec, - fun(X) -> - sag_verify(X, [?sysObjectID_instance, - ?sysUpTime_instance]) - end }, - { 3, - [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]], - Exec, - fun(X) -> - sag_verify(X, [?sysObjectID_instance, - ?sysDescr_instance, - ?sysUpTime_instance]) - end }, - { 4, - [?sysObjectID_instance, - ?sysDescr_instance, - ?sysUpTime_instance], - Exec, - fun(X) -> - sag_verify(X, [?sysObjectID_instance, - ?sysDescr_instance, - ?sysUpTime_instance]) - end } - ], - - p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when starting test: ~n~p", [agent_info(AgentNode)]), + do_simple_sync_get2(Config, Get, PostVerify), + display_log(Config), + ok. - ?line ok = async_exec(Requests, []), - p("manager info when ending test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when ending test: ~n~p", [agent_info(AgentNode)]), - display_log(Config), - ok. -async_g_exec1(Node, Addr, Port, Oids) -> - mgr_user_async_get(Node, Addr, Port, Oids). +%%====================================================================== sag_verify({noError, 0, _Vbs}, any) -> p("verified [any]"), @@ -1937,8 +1926,10 @@ simple_async_get2(doc) -> ["Simple (async) get-request - Version 2 API (TargetName)"]; simple_async_get2(suite) -> []; simple_async_get2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, sag2), + ?TC_TRY(simple_async_get2, + fun() -> do_simple_async_get2(Config) end). + +do_simple_async_get2(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), AgentNode = ?config(agent_node, Config), @@ -2018,8 +2009,10 @@ simple_async_get3(doc) -> ["Simple (async) get-request - Version 3 API (TargetName and send-opts)"]; simple_async_get3(suite) -> []; simple_async_get3(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, sag3), + ?TC_TRY(simple_async_get3, + fun() -> do_simple_async_get3(Config) end). + +do_simple_async_get3(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), AgentNode = ?config(agent_node, Config), @@ -2046,113 +2039,6 @@ async_g_exec3(Node, TargetName, Oids, SendOpts) -> %%====================================================================== -simple_sync_get_next1(doc) -> ["Simple (sync) get_next-request - " - "Old style (Addr & Port)"]; -simple_sync_get_next1(suite) -> []; -simple_sync_get_next1(Config) when is_list(Config) -> - ?SKIP(api_no_longer_supported), - - process_flag(trap_exit, true), - put(tname, ssgn1), - p("starting with Config: ~p~n", [Config]), - - MgrNode = ?config(manager_node, Config), - AgentNode = ?config(agent_node, Config), - Addr = ?config(ip, Config), - Port = ?AGENT_PORT, - - %% -- 1 -- - Oids01 = [[1,3,7,1]], - VF01 = fun(X) -> verify_ssgn_reply1(X, [{[1,3,7,1],endOfMibView}]) end, - ?line ok = do_simple_get_next(1, - MgrNode, Addr, Port, Oids01, VF01), - - ?line ok = mgr_user_load_mib(MgrNode, std_mib()), - - %% -- 2 -- - Oids02 = [[sysDescr], [1,3,7,1]], - VF02 = fun(X) -> - verify_ssgn_reply1(X, [?sysDescr_instance, endOfMibView]) - end, - ?line ok = do_simple_get_next(2, - MgrNode, Addr, Port, Oids02, VF02), - - Test2Mib = test2_mib(Config), - ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), - ?line ok = agent_load_mib(AgentNode, Test2Mib), - - %% -- 3 -- - ?line {ok, [TCnt2|_]} = mgr_user_name_to_oid(MgrNode, tCnt2), - Oids03 = [[TCnt2, 1]], - VF03 = fun(X) -> - verify_ssgn_reply1(X, [{fl([TCnt2,2]), 100}]) - end, - ?line ok = do_simple_get_next(3, - MgrNode, Addr, Port, Oids03, VF03), - - %% -- 4 -- - Oids04 = [[TCnt2, 2]], - VF04 = fun(X) -> - verify_ssgn_reply1(X, [{fl([TCnt2,2]), endOfMibView}]) - end, - ?line ok = do_simple_get_next(4, - MgrNode, Addr, Port, Oids04, VF04), - - %% -- 5 -- - ?line {ok, [TGenErr1|_]} = mgr_user_name_to_oid(MgrNode, tGenErr1), - Oids05 = [TGenErr1], - VF05 = fun(X) -> - verify_ssgn_reply2(X, {genErr, 1, [TGenErr1]}) - end, - ?line ok = do_simple_get_next(5, - MgrNode, Addr, Port, Oids05, VF05), - - %% -- 6 -- - ?line {ok, [TGenErr2|_]} = mgr_user_name_to_oid(MgrNode, tGenErr2), - Oids06 = [TGenErr2], - VF06 = fun(X) -> - verify_ssgn_reply2(X, {genErr, 1, [TGenErr2]}) - end, - ?line ok = do_simple_get_next(6, - MgrNode, Addr, Port, Oids06, VF06), - - %% -- 7 -- - ?line {ok, [TGenErr3|_]} = mgr_user_name_to_oid(MgrNode, tGenErr3), - Oids07 = [[sysDescr], TGenErr3], - VF07 = fun(X) -> - verify_ssgn_reply2(X, {genErr, 2, - [?sysDescr, TGenErr3]}) - end, - ?line ok = do_simple_get_next(7, - MgrNode, Addr, Port, Oids07, VF07), - - %% -- 8 -- - ?line {ok, [TTooBig|_]} = mgr_user_name_to_oid(MgrNode, tTooBig), - Oids08 = [TTooBig], - VF08 = fun(X) -> - verify_ssgn_reply2(X, {tooBig, 0, []}) - end, - ?line ok = do_simple_get_next(8, - MgrNode, Addr, Port, Oids08, VF08), - - display_log(Config), - ok. - - -do_simple_get_next(N, Node, Addr, Port, Oids, Verify) -> - p("issue get-next command ~w", [N]), - case mgr_user_sync_get_next(Node, Addr, Port, Oids) of - {ok, Reply, _Rem} -> - ?DBG("get-next ok:" - "~n Reply: ~p" - "~n Rem: ~w", [Reply, _Rem]), - Verify(Reply); - - Error -> - {error, {unexpected_reply, Error}} - end. - - verify_ssgn_reply1({noError, 0, _Vbs}, any) -> ok; verify_ssgn_reply1({noError, 0, Vbs}, Expected) -> @@ -2191,8 +2077,10 @@ simple_sync_get_next2(doc) -> ["Simple (sync) get_next-request - Version 2 API (TargetName)"]; simple_sync_get_next2(suite) -> []; simple_sync_get_next2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, ssgn2), + ?TC_TRY(simple_sync_get_next2, + fun() -> do_simple_sync_get_next2(Config) end). + +do_simple_sync_get_next2(Config) -> p("starting with Config: ~p~n", [Config]), GetNext = fun(Node, TargetName, Oids) -> @@ -2340,112 +2228,14 @@ simple_sync_get_next3(Config) when is_list(Config) -> %%====================================================================== -simple_async_get_next1(doc) -> ["Simple (async) get_next-request - " - "Old style (Addr & Port)"]; -simple_async_get_next1(suite) -> []; -simple_async_get_next1(Config) when is_list(Config) -> - ?SKIP(api_no_longer_supported), - - process_flag(trap_exit, true), - put(tname, ssgn1), - p("starting with Config: ~p~n", [Config]), - - MgrNode = ?config(manager_node, Config), - AgentNode = ?config(agent_node, Config), - Addr = ?config(ip, Config), - Port = ?AGENT_PORT, - - ?line ok = mgr_user_load_mib(MgrNode, std_mib()), - Test2Mib = test2_mib(Config), - ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), - ?line ok = agent_load_mib(AgentNode, Test2Mib), - - Exec = fun(X) -> - async_gn_exec1(MgrNode, Addr, Port, X) - end, - - ?line {ok, [TCnt2|_]} = mgr_user_name_to_oid(MgrNode, tCnt2), - ?line {ok, [TGenErr1|_]} = mgr_user_name_to_oid(MgrNode, tGenErr1), - ?line {ok, [TGenErr2|_]} = mgr_user_name_to_oid(MgrNode, tGenErr2), - ?line {ok, [TGenErr3|_]} = mgr_user_name_to_oid(MgrNode, tGenErr3), - ?line {ok, [TTooBig|_]} = mgr_user_name_to_oid(MgrNode, tTooBig), - - Requests = - [ - {1, - [[1,3,7,1]], - Exec, - fun(X) -> - verify_ssgn_reply1(X, [{[1,3,7,1], endOfMibView}]) - end}, - {2, - [[sysDescr], [1,3,7,1]], - Exec, - fun(X) -> - verify_ssgn_reply1(X, [?sysDescr_instance, endOfMibView]) - end}, - {3, - [[TCnt2, 1]], - Exec, - fun(X) -> - verify_ssgn_reply1(X, [{fl([TCnt2,2]), 100}]) - end}, - {4, - [[TCnt2, 2]], - Exec, - fun(X) -> - verify_ssgn_reply1(X, [{fl([TCnt2,2]), endOfMibView}]) - end}, - {5, - [TGenErr1], - Exec, - fun(X) -> - verify_ssgn_reply2(X, {genErr, 1, [TGenErr1]}) - end}, - {6, - [TGenErr2], - Exec, - fun(X) -> - verify_ssgn_reply2(X, {genErr, 1, [TGenErr2]}) - end}, - {7, - [[sysDescr], TGenErr3], - Exec, - fun(X) -> - verify_ssgn_reply2(X, {genErr, 2, [TGenErr3]}) - end}, - {8, - [TTooBig], - Exec, - fun(X) -> - verify_ssgn_reply2(X, {tooBig, 0, []}) - end} - ], - - p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when starting test: ~n~p", [agent_info(AgentNode)]), - - ?line ok = async_exec(Requests, []), - - p("manager info when ending test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when ending test: ~n~p", [agent_info(AgentNode)]), - - display_log(Config), - ok. - - -async_gn_exec1(Node, Addr, Port, Oids) -> - mgr_user_async_get_next(Node, Addr, Port, Oids). - - -%%====================================================================== - simple_async_get_next2(doc) -> ["Simple (async) get_next-request - Version 2 API (TargetName)"]; simple_async_get_next2(suite) -> []; simple_async_get_next2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, ssgn2), + ?TC_TRY(simple_async_get_next2, + fun() -> do_simple_async_get_next2(Config) end). + +do_simple_async_get_next2(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -2555,8 +2345,10 @@ simple_async_get_next3(doc) -> "Version 3 API (TargetName with send-opts)"]; simple_async_get_next3(suite) -> []; simple_async_get_next3(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, ssgn2), + ?TC_TRY(simple_async_get_next3, + fun() -> do_simple_async_get_next3(Config) end). + +do_simple_async_get_next3(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -2594,66 +2386,6 @@ async_gn_exec3(Node, TargetName, Oids, SendOpts) -> %%====================================================================== -simple_sync_set1(doc) -> ["Simple (sync) set-request - " - "Old style (Addr & Port)"]; -simple_sync_set1(suite) -> []; -simple_sync_set1(Config) when is_list(Config) -> - ?SKIP(api_no_longer_supported), - - process_flag(trap_exit, true), - put(tname, sss1), - p("starting with Config: ~p~n", [Config]), - - Node = ?config(manager_node, Config), - Addr = ?config(ip, Config), - Port = ?AGENT_PORT, - - p("issue set-request without loading the mib"), - Val11 = "Arne Anka", - Val12 = "Stockholm", - VAVs1 = [ - {?sysName_instance, s, Val11}, - {?sysLocation_instance, s, Val12} - ], - ?line ok = do_simple_set1(Node, Addr, Port, VAVs1), - - p("issue set-request after first loading the mibs"), - ?line ok = mgr_user_load_mib(Node, std_mib()), - Val21 = "Sune Anka", - Val22 = "Gothenburg", - VAVs2 = [ - {[sysName, 0], Val21}, - {[sysLocation, 0], Val22} - ], - ?line ok = do_simple_set1(Node, Addr, Port, VAVs2), - - display_log(Config), - ok. - -do_simple_set1(Node, Addr, Port, VAVs) -> - [SysName, SysLoc] = value_of_vavs(VAVs), - ?line {ok, Reply, _Rem} = mgr_user_sync_set(Node, Addr, Port, VAVs), - - ?DBG("~n Reply: ~p" - "~n Rem: ~w", [Reply, _Rem]), - - %% verify that the operation actually worked: - %% The order should be the same, so no need to seach - %% The value we get should be exactly the same as we sent - ?line ok = case Reply of - {noError, 0, [#varbind{oid = ?sysName_instance, - value = SysName}, - #varbind{oid = ?sysLocation_instance, - value = SysLoc}]} -> - ok; - {noError, 0, Vbs} -> - {error, {unexpected_vbs, Vbs}}; - Else -> - p("unexpected reply: ~n~p", [Else]), - {error, {unexpected_response, Else}} - end, - ok. - value_of_vavs(VAVs) -> value_of_vavs(VAVs, []). @@ -2671,8 +2403,10 @@ simple_sync_set2(doc) -> ["Simple (sync) set-request - Version 2 API (TargetName)"]; simple_sync_set2(suite) -> []; simple_sync_set2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, sss2), + ?TC_TRY(simple_sync_set2, + fun() -> do_simple_sync_set2(Config) end). + +do_simple_sync_set2(Config) -> p("starting with Config: ~p~n", [Config]), Set = fun(Node, TargetName, VAVs) -> @@ -2741,8 +2475,10 @@ simple_sync_set3(doc) -> ["Simple (sync) set-request - Version 3 API (TargetName with send-opts)"]; simple_sync_set3(suite) -> []; simple_sync_set3(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, sss3), + ?TC_TRY(simple_sync_set3, + fun() -> do_simple_sync_set3(Config) end). + +do_simple_sync_set3(Config) -> p("starting with Config: ~p~n", [Config]), Self = self(), @@ -2766,69 +2502,6 @@ simple_sync_set3(Config) when is_list(Config) -> %%====================================================================== -simple_async_set1(doc) -> ["Simple (async) set-request - " - "Old style (Addr & Port)"]; -simple_async_set1(suite) -> []; -simple_async_set1(Config) when is_list(Config) -> - ?SKIP(api_no_longer_supported), - - process_flag(trap_exit, true), - put(tname, sas1), - p("starting with Config: ~p~n", [Config]), - - MgrNode = ?config(manager_node, Config), - AgentNode = ?config(agent_node, Config), - Addr = ?config(ip, Config), - Port = ?AGENT_PORT, - - ?line ok = mgr_user_load_mib(MgrNode, std_mib()), - Test2Mib = test2_mib(Config), - ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), - ?line ok = agent_load_mib(AgentNode, Test2Mib), - - Exec = fun(X) -> - async_s_exec1(MgrNode, Addr, Port, X) - end, - - Requests = - [ - {1, - [{?sysName_instance, s, "Arne Anka"}], - Exec, - fun(X) -> - sas_verify(X, [?sysName_instance]) - end}, - {2, - [{?sysLocation_instance, s, "Stockholm"}, - {?sysName_instance, s, "Arne Anka"}], - Exec, - fun(X) -> - sas_verify(X, [?sysLocation_instance, ?sysName_instance]) - end}, - {3, - [{[sysName, 0], "Gothenburg"}, - {[sysLocation, 0], "Sune Anka"}], - Exec, - fun(X) -> - sas_verify(X, [?sysName_instance, ?sysLocation_instance]) - end} - ], - - p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when starting test: ~n~p", [agent_info(AgentNode)]), - - ?line ok = async_exec(Requests, []), - - p("manager info when ending test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when ending test: ~n~p", [agent_info(AgentNode)]), - - display_log(Config), - ok. - - -async_s_exec1(Node, Addr, Port, VAVs) -> - mgr_user_async_set(Node, Addr, Port, VAVs). - sas_verify({noError, 0, _Vbs}, any) -> p("verified [any]"), ok; @@ -2865,8 +2538,10 @@ simple_async_set2(doc) -> ["Simple (async) set-request - Version 2 API (TargetName)"]; simple_async_set2(suite) -> []; simple_async_set2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, sas2), + ?TC_TRY(simple_async_set2, + fun() -> do_simple_async_set2(Config) end). + +do_simple_async_set2(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -2938,8 +2613,10 @@ simple_async_set3(doc) -> ["Simple (async) set-request - Version 3 API (TargetName with send-opts)"]; simple_async_set3(suite) -> []; simple_async_set3(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, sas3), + ?TC_TRY(simple_async_set3, + fun() -> do_simple_async_set3(Config) end). + +do_simple_async_set3(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -2978,145 +2655,9 @@ async_s_exec3(Node, TargetName, VAVs, SendOpts) -> %%====================================================================== -simple_sync_get_bulk1(doc) -> ["Simple (sync) get_bulk-request - " - "Old style (Addr & Port)"]; -simple_sync_get_bulk1(suite) -> []; -simple_sync_get_bulk1(Config) when is_list(Config) -> - ?SKIP(api_no_longer_supported), - - process_flag(trap_exit, true), - put(tname, ssgb1), - p("starting with Config: ~p~n", [Config]), - - MgrNode = ?config(manager_node, Config), - AgentNode = ?config(agent_node, Config), - Addr = ?config(ip, Config), - Port = ?AGENT_PORT, - - %% -- 1 -- - ?line ok = do_simple_get_bulk1(1, - MgrNode, Addr, Port, 1, 1, [], - fun verify_ssgb_reply1/1), - - %% -- 2 -- - ?line ok = do_simple_get_bulk1(2, - MgrNode, Addr, Port, -1, 1, [], - fun verify_ssgb_reply1/1), - - %% -- 3 -- - ?line ok = do_simple_get_bulk1(3, - MgrNode, Addr, Port, -1, -1, [], - fun verify_ssgb_reply1/1), - - ?line ok = mgr_user_load_mib(MgrNode, std_mib()), - %% -- 4 -- - VF04 = fun(X) -> - verify_ssgb_reply2(X, [?sysDescr_instance, endOfMibView]) - end, - ?line ok = do_simple_get_bulk1(4, - MgrNode, Addr, Port, - 2, 0, [[sysDescr],[1,3,7,1]], VF04), - - %% -- 5 -- - ?line ok = do_simple_get_bulk1(5, - MgrNode, Addr, Port, - 1, 2, [[sysDescr],[1,3,7,1]], VF04), - - %% -- 6 -- - VF06 = fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, endOfMibView, - ?sysObjectID_instance, endOfMibView]) - end, - ?line ok = do_simple_get_bulk1(6, - MgrNode, Addr, Port, - 0, 2, [[sysDescr],[1,3,7,1]], VF06), - - %% -- 7 -- - VF07 = fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, endOfMibView, - ?sysDescr_instance, endOfMibView, - ?sysObjectID_instance, endOfMibView]) - end, - ?line ok = do_simple_get_bulk1(7, - MgrNode, Addr, Port, - 2, 2, - [[sysDescr],[1,3,7,1],[sysDescr],[1,3,7,1]], - VF07), - - Test2Mib = test2_mib(Config), - ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), - ?line ok = agent_load_mib(AgentNode, Test2Mib), - - %% -- 8 -- - VF08 = fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, - ?sysDescr_instance]) - end, - ?line ok = do_simple_get_bulk1(8, - MgrNode, Addr, Port, - 1, 2, - [[sysDescr],[sysDescr],[tTooBig]], - VF08), - - %% -- 9 -- - ?line ok = do_simple_get_bulk1(9, - MgrNode, Addr, Port, - 1, 12, - [[tDescr2], [sysDescr]], - fun verify_ssgb_reply1/1), - - %% -- 10 -- - VF10 = fun(X) -> - verify_ssgb_reply3(X, - [{?sysDescr, 'NULL'}, - {?sysObjectID, 'NULL'}, - {?tGenErr1, 'NULL'}, - {?sysDescr, 'NULL'}]) - end, - ?line ok = do_simple_get_bulk1(10, - MgrNode, Addr, Port, - 2, 2, - [[sysDescr], - [sysObjectID], - [tGenErr1], - [sysDescr]], - VF10), - - %% -- 11 -- - ?line {ok, [TCnt2|_]} = mgr_user_name_to_oid(MgrNode, tCnt2), - p("TCnt2: ~p", [TCnt2]), - VF11 = fun(X) -> - verify_ssgb_reply2(X, - [{fl([TCnt2,2]), 100}, - {fl([TCnt2,2]), endOfMibView}]) - end, - ?line ok = do_simple_get_bulk1(11, - MgrNode, Addr, Port, - 0, 2, - [[TCnt2, 1]], VF11), - - display_log(Config), - ok. - fl(L) -> lists:flatten(L). -do_simple_get_bulk1(N, Node, Addr, Port, NonRep, MaxRep, Oids, Verify) -> - p("issue get-bulk command ~w", [N]), - case mgr_user_sync_get_bulk(Node, Addr, Port, NonRep, MaxRep, Oids) of - {ok, Reply, _Rem} -> - ?DBG("get-bulk ok:" - "~n Reply: ~p" - "~n Rem: ~w", [Reply, _Rem]), - Verify(Reply); - - Error -> - {error, {unexpected_reply, Error}} - end. - verify_ssgb_reply1({noError, 0, []}) -> ok; verify_ssgb_reply1(X) -> @@ -3149,15 +2690,16 @@ check_ssgb_vbs([#varbind{oid = Oid, value = Value}|R], check_ssgb_vbs([R|_], [E|_]) -> {error, {unexpected_vb, R, E}}. - %%====================================================================== simple_sync_get_bulk2(doc) -> ["Simple (sync) get_bulk-request - Version 2 API (TargetName)"]; simple_sync_get_bulk2(suite) -> []; simple_sync_get_bulk2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, ssgb2), + ?TC_TRY(simple_sync_get_bulk2, + fun() -> do_simple_sync_get_bulk2(Config) end). + +do_simple_sync_get_bulk2(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -3312,8 +2854,10 @@ simple_sync_get_bulk3(doc) -> "Version 3 API (TargetName with send-opts)"]; simple_sync_get_bulk3(suite) -> []; simple_sync_get_bulk3(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, ssgb3), + ?TC_TRY(simple_sync_get_bulk3, + fun() -> do_simple_sync_get_bulk3(Config) end). + +do_simple_sync_get_bulk3(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -3345,158 +2889,14 @@ simple_sync_get_bulk3(Config) when is_list(Config) -> %%====================================================================== -simple_async_get_bulk1(doc) -> ["Simple (async) get_bulk-request - " - "Old style (Addr & Port)"]; -simple_async_get_bulk1(suite) -> []; -simple_async_get_bulk1(Config) when is_list(Config) -> - ?SKIP(api_no_longer_supported), - - process_flag(trap_exit, true), - put(tname, sagb1), - p("starting with Config: ~p~n", [Config]), - - MgrNode = ?config(manager_node, Config), - AgentNode = ?config(agent_node, Config), - Addr = ?config(ip, Config), - Port = ?AGENT_PORT, - - ?line ok = mgr_user_load_mib(MgrNode, std_mib()), - Test2Mib = test2_mib(Config), - ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), - ?line ok = agent_load_mib(AgentNode, Test2Mib), - - Exec = fun(Data) -> - async_gb_exec1(MgrNode, Addr, Port, Data) - end, - - %% We re-use the verification functions from the ssgb test-case - VF04 = fun(X) -> - verify_ssgb_reply2(X, [?sysDescr_instance, endOfMibView]) - end, - VF06 = fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, endOfMibView, - ?sysObjectID_instance, endOfMibView]) - end, - VF07 = fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, endOfMibView, - ?sysDescr_instance, endOfMibView, - ?sysObjectID_instance, endOfMibView]) - end, - VF08 = fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, - ?sysDescr_instance]) - end, - VF10 = fun(X) -> - verify_ssgb_reply3(X, - [{?sysDescr, 'NULL'}, - {?sysObjectID, 'NULL'}, - {?tGenErr1, 'NULL'}, - {?sysDescr, 'NULL'}]) - end, - ?line {ok, [TCnt2|_]} = mgr_user_name_to_oid(MgrNode, tCnt2), - VF11 = fun(X) -> - verify_ssgb_reply2(X, - [{fl([TCnt2,2]), 100}, - {fl([TCnt2,2]), endOfMibView}]) - end, - Requests = [ - { 1, - {1, 1, []}, - Exec, - fun verify_ssgb_reply1/1}, - { 2, - {-1, 1, []}, - Exec, - fun verify_ssgb_reply1/1}, - { 3, - {-1, -1, []}, - Exec, - fun verify_ssgb_reply1/1}, - { 4, - {2, 0, [[sysDescr],[1,3,7,1]]}, - Exec, - VF04}, - { 5, - {1, 2, [[sysDescr],[1,3,7,1]]}, - Exec, - VF04}, - { 6, - {0, 2, [[sysDescr],[1,3,7,1]]}, - Exec, - VF06}, - { 7, - {2, 2, [[sysDescr],[1,3,7,1],[sysDescr],[1,3,7,1]]}, - Exec, - VF07}, - { 8, - {1, 2, [[sysDescr],[sysDescr],[tTooBig]]}, - Exec, - VF08}, - { 9, - {1, 12, [[tDescr2], [sysDescr]]}, - Exec, - fun verify_ssgb_reply1/1}, - {10, - {2, 2, [[sysDescr],[sysObjectID], [tGenErr1],[sysDescr]]}, - Exec, - VF10}, - {11, - {0, 2, [[TCnt2, 1]]}, - Exec, - VF11}, - {12, - {2, 0, [[sysDescr],[1,3,7,1]]}, - Exec, - VF04}, - {13, - {1, 12, [[tDescr2], [sysDescr]]}, - Exec, - fun verify_ssgb_reply1/1}, - {14, - {2, 2, [[sysDescr],[sysObjectID],[tGenErr1],[sysDescr]]}, - Exec, - VF10}, - {15, - {0, 2, [[TCnt2, 1]]}, - Exec, - VF11}, - {16, - {2, 2, [[sysDescr],[1,3,7,1],[sysDescr],[1,3,7,1]]}, - Exec, - VF07}, - {17, - {2, 2, [[sysDescr],[sysObjectID], [tGenErr1],[sysDescr]]}, - Exec, - VF10} - ], - - p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when starting test: ~n~p", [agent_info(AgentNode)]), - - ?line ok = async_exec(Requests, []), - - p("manager info when ending test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when ending test: ~n~p", [agent_info(AgentNode)]), - - display_log(Config), - ok. - - -async_gb_exec1(Node, Addr, Port, {NR, MR, Oids}) -> - mgr_user_async_get_bulk(Node, Addr, Port, NR, MR, Oids). - - -%%====================================================================== - simple_async_get_bulk2(doc) -> ["Simple (async) get_bulk-request - Version 2 API (TargetName)"]; simple_async_get_bulk2(suite) -> []; simple_async_get_bulk2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, sagb2), + ?TC_TRY(simple_async_get_bulk2, + fun() -> do_simple_async_get_bulk2(Config) end). + +do_simple_async_get_bulk2(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -3651,8 +3051,10 @@ simple_async_get_bulk3(doc) -> "Version 3 API (TargetName with send-opts)"]; simple_async_get_bulk3(suite) -> []; simple_async_get_bulk3(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, sagb3), + ?TC_TRY(simple_async_get_bulk3, + fun() -> do_simple_async_get_bulk3(Config) end). + +do_simple_async_get_bulk3(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -3691,204 +3093,14 @@ async_gb_exec3(Node, TargetName, {NR, MR, Oids}, SendOpts) -> %%====================================================================== -misc_async1(doc) -> ["Misc (async) request(s) - " - "Old style (Addr & Port)"]; -misc_async1(suite) -> []; -misc_async1(Config) when is_list(Config) -> - ?SKIP(api_no_longer_supported), - - process_flag(trap_exit, true), - put(tname, ms1), - p("starting with Config: ~p~n", [Config]), - - MgrNode = ?config(manager_node, Config), - AgentNode = ?config(agent_node, Config), - Addr = ?config(ip, Config), - Port = ?AGENT_PORT, - - ?line ok = mgr_user_load_mib(MgrNode, std_mib()), - Test2Mib = test2_mib(Config), - ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), - ?line ok = agent_load_mib(AgentNode, Test2Mib), - - ExecG = fun(Data) -> - async_g_exec1(MgrNode, Addr, Port, Data) - end, - - ExecGN = fun(Data) -> - async_gn_exec1(MgrNode, Addr, Port, Data) - end, - - ExecS = fun(Data) -> - async_s_exec1(MgrNode, Addr, Port, Data) - end, - - ExecGB = fun(Data) -> - async_gb_exec1(MgrNode, Addr, Port, Data) - end, - - ?line {ok, [TCnt2|_]} = mgr_user_name_to_oid(MgrNode, tCnt2), - ?line {ok, [TGenErr1|_]} = mgr_user_name_to_oid(MgrNode, tGenErr1), - ?line {ok, [TGenErr2|_]} = mgr_user_name_to_oid(MgrNode, tGenErr2), - ?line {ok, [TGenErr3|_]} = mgr_user_name_to_oid(MgrNode, tGenErr3), - ?line {ok, [TTooBig|_]} = mgr_user_name_to_oid(MgrNode, tTooBig), - - Requests = - [ - { 1, - [?sysObjectID_instance], - ExecG, - fun(X) -> - sag_verify(X, [?sysObjectID_instance]) - end - }, - { 2, - {1, 1, []}, - ExecGB, - fun verify_ssgb_reply1/1}, - { 3, - {-1, 1, []}, - ExecGB, - fun verify_ssgb_reply1/1}, - { 4, - [{?sysLocation_instance, s, "Stockholm"}, - {?sysName_instance, s, "Arne Anka"}], - ExecS, - fun(X) -> - sas_verify(X, [?sysLocation_instance, ?sysName_instance]) - end}, - { 5, - [[sysDescr], [1,3,7,1]], - ExecGN, - fun(X) -> - verify_ssgn_reply1(X, [?sysDescr_instance, endOfMibView]) - end}, - { 6, - [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]], - ExecG, - fun(X) -> - sag_verify(X, [?sysObjectID_instance, - ?sysDescr_instance, - ?sysUpTime_instance]) - end}, - { 7, - [TGenErr2], - ExecGN, - fun(X) -> - verify_ssgn_reply2(X, {genErr, 1, [TGenErr2]}) - end}, - { 8, - {2, 0, [[sysDescr],[1,3,7,1]]}, - ExecGB, - fun(X) -> - verify_ssgb_reply2(X, [?sysDescr_instance, endOfMibView]) - end}, - { 9, - {1, 2, [[sysDescr],[1,3,7,1]]}, - ExecGB, - fun(X) -> - verify_ssgb_reply2(X, [?sysDescr_instance, endOfMibView]) - end}, - {10, - [TGenErr1], - ExecGN, - fun(X) -> - verify_ssgn_reply2(X, {genErr, 1, [TGenErr1]}) - end}, - {11, - {0, 2, [[sysDescr],[1,3,7,1]]}, - ExecGB, - fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, endOfMibView, - ?sysObjectID_instance, endOfMibView]) - end}, - {12, - [{[sysName, 0], "Gothenburg"}, - {[sysLocation, 0], "Sune Anka"}], - ExecS, - fun(X) -> - sas_verify(X, [?sysName_instance, ?sysLocation_instance]) - end}, - {13, - {2, 2, [[sysDescr],[1,3,7,1],[sysDescr],[1,3,7,1]]}, - ExecGB, - fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, endOfMibView, - ?sysDescr_instance, endOfMibView, - ?sysObjectID_instance, endOfMibView]) - end}, - {14, - {1, 2, [[sysDescr],[sysDescr],[tTooBig]]}, - ExecGB, - fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, - ?sysDescr_instance]) - end}, - {15, - {1, 12, [[tDescr2], [sysDescr]]}, - ExecGB, - fun verify_ssgb_reply1/1}, - {16, - {2, 2, [[sysDescr],[sysObjectID], [tGenErr1],[sysDescr]]}, - ExecGB, - fun(X) -> - verify_ssgb_reply3(X, - [{?sysDescr, 'NULL'}, - {?sysObjectID, 'NULL'}, - {?tGenErr1, 'NULL'}, - {?sysDescr, 'NULL'}]) - end}, - {17, - [[sysDescr], TGenErr3], - ExecGN, - fun(X) -> - verify_ssgn_reply2(X, {genErr, 2, [TGenErr3]}) - end}, - {18, - {0, 2, [[TCnt2, 1]]}, - ExecGB, - fun(X) -> - verify_ssgb_reply2(X, - [{fl([TCnt2,2]), 100}, - {fl([TCnt2,2]), endOfMibView}]) - end}, - {19, - [TTooBig], - ExecGN, - fun(X) -> - verify_ssgn_reply2(X, {tooBig, 0, []}) - end}, - {20, - [TTooBig], - ExecGN, - fun(X) -> - verify_ssgn_reply2(X, {tooBig, 0, []}) - end} - ], - - p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when starting test: ~n~p", [agent_info(AgentNode)]), - - ?line ok = async_exec(Requests, []), - - p("manager info when ending test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when ending test: ~n~p", [agent_info(AgentNode)]), - - display_log(Config), - ok. - - -%%====================================================================== - misc_async2(doc) -> ["Misc (async) request(s) - Version 2 API (TargetName)"]; misc_async2(suite) -> []; misc_async2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, ms2), + ?TC_TRY(misc_async2, + fun() -> do_misc_async2(Config) end). + +do_misc_async2(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -4137,8 +3349,10 @@ verify_trap(Trap, [{Id, Verifier}|Verifiers]) -> trap1(suite) -> []; trap1(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,t1), + ?TC_TRY(trap1, + fun() -> do_trap1(Config) end). + +do_trap1(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -4290,8 +3504,10 @@ trap1(Config) when is_list(Config) -> trap2(suite) -> []; trap2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,t2), + ?TC_TRY(trap2, + fun() -> do_trap2(Config) end). + +do_trap2(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -4483,8 +3699,10 @@ trap2(Config) when is_list(Config) -> inform1(suite) -> []; inform1(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,i1), + ?TC_TRY(inform1, + fun() -> do_inform1(Config) end). + +do_inform1(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -4610,8 +3828,10 @@ inform1(Config) when is_list(Config) -> inform2(suite) -> []; inform2(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, i2), + ?TC_TRY(inform2, + fun() -> do_inform2(Config) end). + +do_inform2(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -4745,7 +3965,7 @@ inform2(Config) when is_list(Config) -> "~n ~p", [Addr]), ok; {snmp_notification, inform2_tag1, {no_response, Addr}} -> - p("<ERROR> received expected \"no response\" " + e("Received unexpected \"no response\" " "notification from: " "~n ~p", [Addr]), {error, no_response} @@ -4782,8 +4002,10 @@ inform2(Config) when is_list(Config) -> inform3(suite) -> []; inform3(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,i3), + ?TC_TRY(inform3, + fun() -> do_inform3(Config) end). + +do_inform3(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -4879,7 +4101,7 @@ inform3(Config) when is_list(Config) -> "~n ~p", [Addr]), ok; {snmp_notification, inform3_tag1, {got_response, Addr}} -> - p("<ERROR> received unexpected \"got response\" " + e("Received unexpected \"got response\" " "notification from: " "~n ~p", [Addr]), @@ -4918,8 +4140,10 @@ inform3(Config) when is_list(Config) -> inform4(suite) -> []; inform4(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname,i4), + ?TC_TRY(inform4, + fun() -> do_inform4(Config) end). + +do_inform4(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -5038,8 +4262,10 @@ inform4(Config) when is_list(Config) -> inform_swarm(suite) -> []; inform_swarm(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, is), + ?TC_TRY(inform_swarm, + fun() -> do_inform_swarm(Config) end). + +do_inform_swarm(Config) -> p("starting with Config: ~p~n", [Config]), MgrNode = ?config(manager_node, Config), @@ -5166,7 +4392,7 @@ inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, Timeout) -> inform_swarm_collector(N, SentAckCnt, RecvCnt+1, RespCnt, Timeout); {Err, Idx, VBs} -> - p("<ERROR> unexpected error status: " + e("Unexpected error status: " "~n Err: ~p" "~n Idx: ~p" "~n VBs: ~p", [Err, Idx, VBs]), @@ -5185,7 +4411,7 @@ inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, Timeout) -> %% The agent did not received ack from the manager in time {snmp_notification, inform2_tag1, {no_response, Addr}} -> - p("<ERROR> received expected \"no response\" notification " + e("Received expected \"no response\" notification " "from: " "~n ~p", [Addr]), Reason = {no_response, Addr, {N, SentAckCnt, RecvCnt, RespCnt}}, @@ -5210,8 +4436,10 @@ report(Config) when is_list(Config) -> otp8015_1(doc) -> ["OTP-8015:1 - testing the new api-function."]; otp8015_1(suite) -> []; otp8015_1(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, otp8015_1), + ?TC_TRY(otp8015_1, + fun() -> do_otp8015_1(Config) end). + +do_otp8015_1(Config) -> p("starting with Config: ~p~n", [Config]), ConfDir = ?config(manager_conf_dir, Config), @@ -5258,8 +4486,10 @@ otp8015_1(Config) when is_list(Config) -> otp8395_1(doc) -> ["OTP-8395:1 - simple get with ATL sequence numbering."]; otp8395_1(suite) -> []; otp8395_1(Config) when is_list(Config) -> - process_flag(trap_exit, true), - put(tname, otp8395_1), + ?TC_TRY(otp8395_1, + fun() -> do_otp8395_1(Config) end). + +do_otp8395_1(Config) -> do_simple_sync_get2(Config). @@ -5362,10 +4592,10 @@ command_handler([{No, Desc, Cmd}|Cmds]) -> p("command_handler -> ~w: ok",[No]), command_handler(Cmds); {error, Reason} -> - p("<ERROR> command_handler -> ~w error: ~n~p",[No, Reason]), + e("Command_handler -> ~w error: ~n~p",[No, Reason]), ?line ?FAIL({command_failed, No, Reason}); Error -> - p("<ERROR> command_handler -> ~w unexpected: ~n~p",[No, Error]), + e("Command_handler -> ~w unexpected: ~n~p",[No, Error]), ?line ?FAIL({unexpected_command_result, No, Error}) end. @@ -5416,15 +4646,14 @@ init_manager(AutoInform, Config) -> start_manager(Node, Vsns, Conf) end catch - T:E -> - StackTrace = ?STACK(), + C:E:S -> p("Failure during manager start: " - "~n Error Type: ~p" - "~n Error: ~p" - "~n StackTrace: ~p", [T, E, StackTrace]), + "~n Error Class: ~p" + "~n Error: ~p" + "~n StackTrace: ~p", [C, E, S]), %% And now, *try* to cleanup (catch stop_node(Node)), - ?FAIL({failed_starting_manager, T, E, StackTrace}) + ?FAIL({failed_starting_manager, C, E, S}) end. fin_manager(Config) -> @@ -5432,7 +4661,7 @@ fin_manager(Config) -> StopMgrRes = stop_manager(Node), StopCryptoRes = fin_crypto(Node), StopNode = stop_node(Node), - p("fin_agent -> stop apps and (mgr node ~p) node results: " + p("fin_manager -> stop apps and (mgr node ~p) node results: " "~n SNMP Mgr: ~p" "~n Crypto: ~p" "~n Node: ~p", @@ -5498,15 +4727,14 @@ init_agent(Config) -> start_agent(Node, Vsns, Conf) end catch - T:E -> - StackTrace = ?STACK(), + C:E:S -> p("Failure during agent start: " - "~n Error Type: ~p" - "~n Error: ~p" - "~n StackTrace: ~p", [T, E, StackTrace]), + "~n Error Class: ~p" + "~n Error: ~p" + "~n StackTrace: ~p", [C, E, S]), %% And now, *try* to cleanup (catch stop_node(Node)), - ?FAIL({failed_starting_agent, T, E, StackTrace}) + ?FAIL({failed_starting_agent, C, E, S}) end. @@ -5922,40 +5150,21 @@ mgr_user_stop(Node) -> mgr_user_register_agent(Node, TargetName, Conf) when is_list(TargetName) andalso is_list(Conf) -> rcall(Node, snmp_manager_user, register_agent, [TargetName, Conf]). -%% <REMOVED-IN-R16B> -%% mgr_user_register_agent(Node, Addr, Port) -> -%% mgr_user_register_agent(Node, Addr, Port, []). -%% mgr_user_register_agent(Node, Addr, Port, Conf) -> -%% rcall(Node, snmp_manager_user, register_agent, [Addr, Port, Conf]). -%% </REMOVED-IN-R16B> %% mgr_user_unregister_agent(Node) -> %% mgr_user_unregister_agent(Node, ?LOCALHOST(), ?AGENT_PORT). mgr_user_unregister_agent(Node, TargetName) when is_list(TargetName) -> rcall(Node, snmp_manager_user, unregister_agent, [TargetName]). -%% <REMOVED-IN-R16B> -%% mgr_user_unregister_agent(Node, Addr, Port) -> -%% rcall(Node, snmp_manager_user, unregister_agent, [Addr, Port]). -%% </REMOVED-IN-R16B> mgr_user_agent_info(Node, TargetName, Item) when is_list(TargetName) andalso is_atom(Item) -> rcall(Node, snmp_manager_user, agent_info, [TargetName, Item]). -%% <REMOVED-IN-R16B> -%% mgr_user_agent_info(Node, Addr, Port, Item) when is_atom(Item) -> -%% rcall(Node, snmp_manager_user, agent_info, [Addr, Port, Item]). -%% </REMOVED-IN-R16B> %% mgr_user_update_agent_info(Node, Item, Val) when atom(Item) -> %% mgr_user_update_agent_info(Node, ?LOCALHOST(), ?AGENT_PORT, Item, Val). mgr_user_update_agent_info(Node, TargetName, Item, Val) when is_list(TargetName) andalso is_atom(Item) -> rcall(Node, snmp_manager_user, update_agent_info, [TargetName, Item, Val]). -%% <REMOVED-IN-R16B> -%% mgr_user_update_agent_info(Node, Addr, Port, Item, Val) when is_atom(Item) -> -%% rcall(Node, snmp_manager_user, update_agent_info, -%% [Addr, Port, Item, Val]). -%% </REMOVED-IN-R16B> %% mgr_user_which_all_agents(Node) -> %% rcall(Node, snmp_manager_user, which_all_agents, []). @@ -5970,10 +5179,6 @@ mgr_user_load_mib(Node, Mib) -> %% mgr_user_sync_get(Node, ?LOCALHOST(), ?AGENT_PORT, Oids). mgr_user_sync_get(Node, TargetName, Oids) when is_list(TargetName) -> rcall(Node, snmp_manager_user, sync_get, [TargetName, Oids]). -%% <REMOVED-IN-R16B> -mgr_user_sync_get(Node, Addr, Port, Oids) -> - rcall(Node, snmp_manager_user, sync_get, [Addr, Port, Oids]). -%% </REMOVED-IN-R16B> mgr_user_sync_get2(Node, TargetName, Oids, SendOpts) when is_list(TargetName) -> rcall(Node, snmp_manager_user, sync_get2, [TargetName, Oids, SendOpts]). @@ -5982,10 +5187,6 @@ mgr_user_sync_get2(Node, TargetName, Oids, SendOpts) when is_list(TargetName) -> %% mgr_user_async_get(Node, ?LOCALHOST(), ?AGENT_PORT, Oids). mgr_user_async_get(Node, TargetName, Oids) when is_list(TargetName) -> rcall(Node, snmp_manager_user, async_get, [TargetName, Oids]). -%% <REMOVED-IN-R16B> -mgr_user_async_get(Node, Addr, Port, Oids) -> - rcall(Node, snmp_manager_user, async_get, [Addr, Port, Oids]). -%% </REMOVED-IN-R16B> mgr_user_async_get2(Node, TargetName, Oids, SendOpts) when is_list(TargetName) -> @@ -5995,10 +5196,6 @@ mgr_user_async_get2(Node, TargetName, Oids, SendOpts) %% mgr_user_sync_get_next(Node, ?LOCALHOST(), ?AGENT_PORT, Oids). mgr_user_sync_get_next(Node, TargetName, Oids) when is_list(TargetName) -> rcall(Node, snmp_manager_user, sync_get_next, [TargetName, Oids]). -%% <REMOVED-IN-R16B> -mgr_user_sync_get_next(Node, Addr, Port, Oids) -> - rcall(Node, snmp_manager_user, sync_get_next, [Addr, Port, Oids]). -%% </REMOVED-IN-R16B> mgr_user_sync_get_next2(Node, TargetName, Oids, SendOpts) when is_list(TargetName) -> @@ -6008,10 +5205,6 @@ mgr_user_sync_get_next2(Node, TargetName, Oids, SendOpts) %% mgr_user_async_get_next(Node, ?LOCALHOST(), ?AGENT_PORT, Oids). mgr_user_async_get_next(Node, TargetName, Oids) when is_list(TargetName) -> rcall(Node, snmp_manager_user, async_get_next, [TargetName, Oids]). -%% <REMOVED-IN-R16B> -mgr_user_async_get_next(Node, Addr, Port, Oids) -> - rcall(Node, snmp_manager_user, async_get_next, [Addr, Port, Oids]). -%% </REMOVED-IN-R16B> mgr_user_async_get_next2(Node, TargetName, Oids, SendOpts) when is_list(TargetName) -> @@ -6021,10 +5214,6 @@ mgr_user_async_get_next2(Node, TargetName, Oids, SendOpts) %% mgr_user_sync_set(Node, ?LOCALHOST(), ?AGENT_PORT, VAV). mgr_user_sync_set(Node, TargetName, VAV) when is_list(TargetName) -> rcall(Node, snmp_manager_user, sync_set, [TargetName, VAV]). -%% <REMOVED-IN-R16B> -mgr_user_sync_set(Node, Addr, Port, VAV) -> - rcall(Node, snmp_manager_user, sync_set, [Addr, Port, VAV]). -%% </REMOVED-IN-R16B> mgr_user_sync_set2(Node, TargetName, VAV, SendOpts) when is_list(TargetName) -> rcall(Node, snmp_manager_user, sync_set2, [TargetName, VAV, SendOpts]). @@ -6033,10 +5222,6 @@ mgr_user_sync_set2(Node, TargetName, VAV, SendOpts) when is_list(TargetName) -> %% mgr_user_async_set(Node, ?LOCALHOST(), ?AGENT_PORT, VAV). mgr_user_async_set(Node, TargetName, VAV) when is_list(TargetName) -> rcall(Node, snmp_manager_user, async_set, [TargetName, VAV]). -%% <REMOVED-IN-R16B> -mgr_user_async_set(Node, Addr, Port, VAV) -> - rcall(Node, snmp_manager_user, async_set, [Addr, Port, VAV]). -%% </REMOVED-IN-R16B> mgr_user_async_set2(Node, TargetName, VAV, SendOpts) when is_list(TargetName) -> rcall(Node, snmp_manager_user, async_set2, [TargetName, VAV, SendOpts]). @@ -6048,11 +5233,6 @@ mgr_user_sync_get_bulk(Node, TargetName, NonRep, MaxRep, Oids) when is_list(TargetName) -> rcall(Node, snmp_manager_user, sync_get_bulk, [TargetName, NonRep, MaxRep, Oids]). -%% <REMOVED-IN-R16B> -mgr_user_sync_get_bulk(Node, Addr, Port, NonRep, MaxRep, Oids) -> - rcall(Node, snmp_manager_user, sync_get_bulk, - [Addr, Port, NonRep, MaxRep, Oids]). -%% </REMOVED-IN-R16B> mgr_user_sync_get_bulk2(Node, TargetName, NonRep, MaxRep, Oids, SendOpts) when is_list(TargetName) -> @@ -6066,11 +5246,6 @@ mgr_user_async_get_bulk(Node, TargetName, NonRep, MaxRep, Oids) when is_list(TargetName) -> rcall(Node, snmp_manager_user, async_get_bulk, [TargetName, NonRep, MaxRep, Oids]). -%% <REMOVED-IN-R16B> -mgr_user_async_get_bulk(Node, Addr, Port, NonRep, MaxRep, Oids) -> - rcall(Node, snmp_manager_user, async_get_bulk, - [Addr, Port, NonRep, MaxRep, Oids]). -%% </REMOVED-IN-R16B> mgr_user_async_get_bulk2(Node, TargetName, NonRep, MaxRep, Oids, SendOpts) when is_list(TargetName) -> @@ -6179,7 +5354,12 @@ start_agent(Node, Vsns, Conf0, _Opts) -> {mib_server, [{verbosity, MSV}]}, {note_store, [{verbosity, NSV}]}, {stymbolic_store, [{verbosity, SSV}]}, - {net_if, [{verbosity, NIV}]}, + {net_if, [{verbosity, NIV}, + %% On some linux "they" add a 127.0.1.1 or somthing + %% similar, so if we don't specify bind_to + %% we don't know which address will be selected + %% (which will cause problems for some test cases). + {options, [{bind_to, true}]}]}, {multi_threaded, true}], ?line ok = set_agent_env(Node, Env), @@ -6228,6 +5408,8 @@ start_manager_node() -> start_node(snmp_manager). start_node(Name) -> + start_node(Name, true). +start_node(Name, Retry) -> Pa = filename:dirname(code:which(?MODULE)), Args = case init:get_argument('CC_TEST') of {ok, [[]]} -> @@ -6237,31 +5419,51 @@ start_node(Name) -> error -> "" end, - A = Args ++ " -pa " ++ Pa, - case (catch ?START_NODE(Name, A)) of + A = Args ++ " -pa " ++ Pa ++ + " -s " ++ atom_to_list(snmp_test_sys_monitor) ++ " start" ++ + " -s global sync", + try ?START_NODE(Name, A) of {ok, Node} -> + global:sync(), Node; - Else -> - ?line ?FAIL(Else) + {error, timeout} -> + e("Failed starting node ~p: timeout", [Name]), + ?line ?FAIL({error_starting_node, Name, timeout}); + {error, {already_running, Node}} when (Retry =:= true) -> + %% Ouch + %% Either we previously failed to (properly) stop the node + %% or it was a failed start, that reported failure (for instance + %% timeout) but actually succeeded. Regardless, we don't know + %% the state of this node, so (try) stop it and then (re-) try + %% start again. + e("Failed starting node ~p: Already Running - try stop", [Node]), + case ?STOP_NODE(Node) of + true -> + p("Successfully stopped old node ~p", [Node]), + start_node(Name, false); + false -> + e("Failed stop old node ~p", [Node]), + ?line ?FAIL({error_starting_node, Node, Retry, already_running}) + end; + {error, {already_running, Node}} -> + e("Failed starting node ~p: Already Running", [Node]), + ?line ?FAIL({error_starting_node, Node, Retry, already_running}); + {error, Reason} -> + e("Failed starting node ~p: ~p", [Name, Reason]), + ?line ?FAIL({error_starting_node, Name, Reason}) + catch + exit:{suite_failed, Reason} -> + e("(suite) Failed starting node ~p: ~p", [Name, Reason]), + ?line ?FAIL({failed_starting_node, Name, Reason}) end. -stop_node(Node) -> - rpc:cast(Node, erlang, halt, []), - await_stopped(Node, 5). -await_stopped(Node, 0) -> - p("await_stopped -> ~p still exist: giving up", [Node]), - ok; -await_stopped(Node, N) -> - Nodes = erlang:nodes(), - case lists:member(Node, Nodes) of - true -> - p("await_stopped -> ~p still exist: ~w", [Node, N]), - ?SLEEP(1000), - await_stopped(Node, N-1); - false -> - p("await_stopped -> ~p gone: ~w", [Node, N]), - ok +stop_node(Node) -> + case ?STOP_NODE(Node) of + true -> + ok; + false -> + ?line ?FAIL({failed_stop_node, Node}) end. @@ -6506,12 +5708,15 @@ rcall(Node, Mod, Func, Args) -> %% ------ +e(F, A) -> + p("<ERROR> " ++ F, A). + p(F) -> p(F, []). p(F, A) -> p(get(tname), F, A). - + p(TName, F, A) -> io:format("*** [~w][~s] ***" "~n " ++ F ++ "~n", [TName, formated_timestamp()|A]). diff --git a/lib/snmp/test/snmp_test_global_sys_monitor.erl b/lib/snmp/test/snmp_test_global_sys_monitor.erl new file mode 100644 index 0000000000..eafb96621a --- /dev/null +++ b/lib/snmp/test/snmp_test_global_sys_monitor.erl @@ -0,0 +1,214 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2019-2019. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-module(snmp_test_global_sys_monitor). + +-export([start/0, stop/0, + reset_events/0, + events/0, + log/1]). +-export([init/1]). + +-define(NAME, ?MODULE). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +start() -> + Parent = self(), + proc_lib:start(?MODULE, init, [Parent]). + +stop() -> + cast(stop). + +%% This does not reset the global counter but the "collector" +%% See events for more info. +reset_events() -> + cast(reset_events). + +events() -> + call(events). + +log(Event) -> + cast({node(), Event}). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +init(Parent) -> + process_flag(priority, high), + case global:register_name(?NAME, self()) of + yes -> + info_msg("Starting", []), + proc_lib:init_ack(Parent, {ok, self()}), + loop(#{parent => Parent, ev_cnt => 0, evs => []}); + no -> + warning_msg("Already started", []), + proc_lib:init_ack(Parent, {error, already_started}), + exit(normal) + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +loop(State) -> + receive + {?MODULE, stop} -> + warning_msg("Stopping with ~w events counted", + [maps:get(ev_cnt, State)]), + exit(normal); + + {?MODULE, reset_events} -> + loop(State#{evs => []}); + + {?MODULE, Ref, From, events} -> + Evs = maps:get(evs, State), + From ! {?MODULE, Ref, lists:reverse(Evs)}, + loop(State); + + {?MODULE, {Node, Event}} -> + State2 = process_event(State, Node, Event), + loop(State2); + + {nodedown = Event, Node} -> + State2 = process_event(State, Node, Event), + loop(State2); + + _ -> + loop(State) + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +process_event(State, Node, {Pid, TS, Tag, Info}) -> + process_system_event(State, Node, Pid, TS, Tag, Info); + +process_event(State, Node, {TS, starting}) -> + FTS = snmp_misc:format_timestamp(TS), + info_msg("System Monitor on node ~p starting at ~s", [Node, FTS]), + if + (Node =/= node()) -> + erlang:monitor_node(Node, true); + true -> + ok + end, + State; + +process_event(State, Node, {TS, already_started}) -> + FTS = snmp_misc:format_timestamp(TS), + info_msg("System Monitor on node ~p already started", [Node, FTS]), + State; + +process_event(State, Node, nodedown) -> + info_msg("Node ~p down", [Node]), + State; + +process_event(State, Node, Event) -> + warning_msg("Received unknown event from node ~p:" + "~n ~p", [Node, Event]), + State. + + +%% System Monitor events +%% We only *count* system events +process_system_event(#{ev_cnt := Cnt, evs := Evs} = State, + Node, Pid, TS, long_gc = Ev, Info) -> + print_system_event("Long GC", Node, Pid, TS, Info), + State#{ev_cnt => Cnt + 1, evs => [{Node, Ev} | Evs]}; +process_system_event(#{ev_cnt := Cnt, evs := Evs} = State, + Node, Pid, TS, long_schedule = Ev, Info) -> + print_system_event("Long Schedule", Node, Pid, TS, Info), + State#{ev_cnt => Cnt + 1, evs => [{Node, Ev} | Evs]}; +process_system_event(#{ev_cnt := Cnt, evs := Evs} = State, + Node, Pid, TS, large_heap = Ev, Info) -> + print_system_event("Large Heap", Node, Pid, TS, Info), + State#{ev_cnt => Cnt + 1, evs => [{Node, Ev} | Evs]}; +process_system_event(#{ev_cnt := Cnt, evs := Evs} = State, + Node, Pid, TS, busy_port = Ev, Info) -> + print_system_event("Busy port", Node, Pid, TS, Info), + State#{ev_cnt => Cnt + 1, evs => [{Node, Ev} | Evs]}; +process_system_event(#{ev_cnt := Cnt, evs := Evs} = State, + Node, Pid, TS, busy_dist_port = Ev, Info) -> + print_system_event("Busy dist port", Node, Pid, TS, Info), + State#{ev_cnt => Cnt + 1, evs => [{Node, Ev} | Evs]}; + +%% And everything else +process_system_event(State, Node, Pid, TS, Tag, Info) -> + Pre = f("Unknown Event '~p'", [Tag]), + print_system_event(Pre, Node, Pid, TS, Info), + State. + + +print_system_event(Pre, Node, Pid, TS, Info) -> + FTS = snmp_misc:format_timestamp(TS), + warning_msg("~s from ~p (~p) at ~s:" + "~n ~p", [Pre, Node, Pid, FTS, Info]). + +f(F, A) -> + lists:flatten(io_lib:format(F, A)). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +cast(Msg) -> + try global:send(?NAME, {?MODULE, Msg}) of + Pid when is_pid(Pid) -> + ok + catch + C:E:_ -> + {error, {catched, C, E}} + end. + +call(Req) -> + call(Req, infinity). + +call(Req, Timeout) -> + Ref = make_ref(), + try global:send(?NAME, {?MODULE, Ref, self(), Req}) of + Pid when is_pid(Pid) -> + receive + {?MODULE, Ref, Rep} -> + Rep + after Timeout -> + {error, timeout} + end + catch + C:E:_ -> + {error, {catched, C, E}} + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +info_msg(F, A) -> + error_logger:info_msg(format_msg(F, A), []). + +warning_msg(F, A) -> + error_logger:warning_msg(format_msg(F, A), []). + + +format_msg(F, A) -> + f("~n" ++ + "****** SNMP TEST GLOBAL SYSTEM MONITOR ******~n~n" ++ + F ++ + "~n~n", + A). + diff --git a/lib/snmp/test/snmp_test_lib.erl b/lib/snmp/test/snmp_test_lib.erl index 290f1bc31a..a040c4f39c 100644 --- a/lib/snmp/test/snmp_test_lib.erl +++ b/lib/snmp/test/snmp_test_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2015. All Rights Reserved. +%% Copyright Ericsson AB 2002-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -23,9 +23,12 @@ -include_lib("kernel/include/file.hrl"). +-export([tc_try/2, tc_try/3]). -export([hostname/0, hostname/1, localhost/0, localhost/1, os_type/0, sz/1, display_suite_info/1]). --export([non_pc_tc_maybe_skip/4, os_based_skip/1]). +-export([non_pc_tc_maybe_skip/4, os_based_skip/1, + has_support_ipv6/0, has_support_ipv6/1, + is_ipv6_host/0, is_ipv6_host/1]). -export([fix_data_dir/1, init_suite_top_dir/2, init_group_top_dir/2, init_testcase_top_dir/2, lookup/2, @@ -34,17 +37,134 @@ -export([hours/1, minutes/1, seconds/1, sleep/1]). -export([flush_mqueue/0, trap_exit/0, trap_exit/1]). -export([ping/1, local_nodes/0, nodes_on/1]). --export([start_node/2]). +-export([start_node/2, stop_node/1]). -export([is_app_running/1, is_crypto_running/0, is_mnesia_running/0, is_snmp_running/0]). -export([crypto_start/0, crypto_support/0]). -export([watchdog/3, watchdog_start/1, watchdog_start/2, watchdog_stop/1]). -export([del_dir/1]). -export([cover/1]). --export([p/2, print/5, formated_timestamp/0]). +-export([f/2, p/2, print1/2, print2/2, print/5, formated_timestamp/0]). %% ---------------------------------------------------------------------- +%% Run test-case +%% + +%% *** tc_try/2,3 *** +%% Case: Basically the test case name +%% TCCondFun: A fun that is evaluated before the actual test case +%% The point of this is that it can performs checks to +%% see if we shall run the test case at all. +%% For instance, the test case may only work in specific +%% conditions. +%% FCFun: The test case fun +tc_try(Case, TCFun) -> + tc_try(Case, fun() -> ok end, TCFun). + +tc_try(Case, TCCondFun, TCFun) + when is_atom(Case) andalso + is_function(TCCondFun, 0) andalso + is_function(TCFun, 0) -> + tc_begin(Case), + try TCCondFun() of + ok -> + try + begin + TCFun(), + sleep(seconds(1)), + tc_end("ok") + end + catch + C:{skip, _} = SKIP when ((C =:= throw) orelse (C =:= exit)) -> + tc_end( f("skipping(catched,~w,tc)", [C]) ), + SKIP; + C:E:S -> + %% We always check the system events before we accept a failure + case snmp_test_global_sys_monitor:events() of + [] -> + tc_end( f("failed(catched,~w,tc)", [C]) ), + erlang:raise(C, E, S); + SysEvs -> + tc_print("System Events received: " + "~n ~p", [SysEvs], "", ""), + tc_end( f("skipping(catched-sysevs,~w,tc)", [C]) ), + SKIP = {skip, "TC failure with system events"}, + SKIP + end + end; + {skip, _} = SKIP -> + tc_end("skipping(cond)"), + SKIP; + {error, Reason} -> + tc_end("failed(cond)"), + exit({tc_cond_failed, Reason}) + catch + C:{skip, _} = SKIP when ((C =:= throw) orelse (C =:= exit)) -> + tc_end( f("skipping(catched,~w,cond)", [C]) ), + SKIP; + C:E:S -> + %% We always check the system events before we accept a failure + case snmp_test_global_sys_monitor:events() of + [] -> + tc_end( f("failed(catched,~w,cond)", [C]) ), + erlang:raise(C, E, S); + SysEvs -> + tc_print("System Events received: " + "~n ~p", [SysEvs], "", ""), + tc_end( f("skipping(catched-sysevs,~w,cond)", [C]) ), + SKIP = {skip, "TC cond failure with system events"}, + SKIP + end + end. + + +tc_set_name(N) when is_atom(N) -> + tc_set_name(atom_to_list(N)); +tc_set_name(N) when is_list(N) -> + put(tc_name, N). + +tc_get_name() -> + get(tc_name). + +tc_begin(TC) -> + OldVal = process_flag(trap_exit, true), + put(old_trap_exit, OldVal), + tc_set_name(TC), + tc_print("begin ***", + "~n----------------------------------------------------~n", ""). + +tc_end(Result) when is_list(Result) -> + OldVal = erase(old_trap_exit), + process_flag(trap_exit, OldVal), + tc_print("done: ~s", [Result], + "", "----------------------------------------------------~n~n"), + ok. + +tc_print(F, Before, After) -> + tc_print(F, [], Before, After). + +tc_print(F, A, Before, After) -> + Name = tc_which_name(), + FStr = f("*** [~s][~s][~p] " ++ F ++ "~n", + [formated_timestamp(),Name,self()|A]), + io:format(user, Before ++ FStr ++ After, []). + +tc_which_name() -> + case tc_get_name() of + undefined -> + case get(sname) of + undefined -> + ""; + SName when is_list(SName) -> + SName + end; + Name when is_list(Name) -> + Name + end. + + +%% ---------------------------------------------------------------------- %% Misc functions %% @@ -52,18 +172,76 @@ hostname() -> hostname(node()). hostname(Node) -> - from($@, atom_to_list(Node)). + case string:tokens(atom_to_list(Node), [$@]) of + [_, Host] -> + Host; + _ -> + [] + end. -from(H, [H | T]) -> T; -from(H, [_ | T]) -> from(H, T); -from(_H, []) -> []. +%% localhost() -> +%% {ok, Ip} = snmp_misc:ip(net_adm:localhost()), +%% Ip. +%% localhost(Family) -> +%% {ok, Ip} = snmp_misc:ip(net_adm:localhost(), Family), +%% Ip. localhost() -> - {ok, Ip} = snmp_misc:ip(net_adm:localhost()), - Ip. + localhost(inet). + localhost(Family) -> - {ok, Ip} = snmp_misc:ip(net_adm:localhost(), Family), - Ip. + case inet:getaddr(net_adm:localhost(), Family) of + {ok, {127, _, _, _}} when (Family =:= inet) -> + %% Ouch, we need to use something else + case inet:getifaddrs() of + {ok, IfList} -> + which_addr(Family, IfList); + {error, Reason1} -> + fail({getifaddrs, Reason1}, ?MODULE, ?LINE) + end; + {ok, {A1, _, _, _, _, _, _, _}} when (Family =:= inet6) andalso + ((A1 =:= 0) orelse + (A1 =:= 16#fe80)) -> + %% Ouch, we need to use something else + case inet:getifaddrs() of + {ok, IfList} -> + which_addr(Family, IfList); + {error, Reason1} -> + fail({getifaddrs, Reason1}, ?MODULE, ?LINE) + end; + {ok, Addr} -> + Addr; + {error, Reason2} -> + fail({getaddr, Reason2}, ?MODULE, ?LINE) + end. + +which_addr(_Family, []) -> + fail(no_valid_addr, ?MODULE, ?LINE); +which_addr(Family, [{"lo", _} | IfList]) -> + which_addr(Family, IfList); +which_addr(Family, [{"docker" ++ _, _} | IfList]) -> + which_addr(Family, IfList); +which_addr(Family, [{"br-" ++ _, _} | IfList]) -> + which_addr(Family, IfList); +which_addr(Family, [{_Name, IfOpts} | IfList]) -> + case which_addr2(Family, IfOpts) of + {ok, Addr} -> + Addr; + {error, _} -> + which_addr(Family, IfList) + end. + +which_addr2(_Family, []) -> + {error, not_found}; +which_addr2(Family, [{addr, Addr}|_]) + when (Family =:= inet) andalso (size(Addr) =:= 4) -> + {ok, Addr}; +which_addr2(Family, [{addr, Addr}|_]) + when (Family =:= inet6) andalso (size(Addr) =:= 8) -> + {ok, Addr}; +which_addr2(Family, [_|IfOpts]) -> + which_addr2(Family, IfOpts). + sz(L) when is_list(L) -> length(L); @@ -142,63 +320,121 @@ non_pc_tc_maybe_skip(Config, Condition, File, Line) %% test-server... ok; _ -> - case Condition() of + try Condition() of true -> skip(non_pc_testcase, File, Line); false -> ok + catch + C:E:S -> + skip({condition, C, E, S}, File, Line) end end end. +%% The type and spec'ing is just to increase readability +-type os_family() :: win32 | unix. +-type os_name() :: atom(). +-type os_version() :: string() | {non_neg_integer(), + non_neg_integer(), + non_neg_integer()}. +-type os_skip_check() :: fun(() -> boolean()) | + fun((os_version()) -> boolean()). +-type skippable() :: any | [os_family() | + {os_family(), os_name() | + [os_name() | {os_name(), + os_skip_check()}]}]. + +-spec os_based_skip(skippable()) -> boolean(). + os_based_skip(any) -> - io:format("os_based_skip(any) -> entry" - "~n", []), true; os_based_skip(Skippable) when is_list(Skippable) -> - io:format("os_based_skip -> entry with" - "~n Skippable: ~p" - "~n", [Skippable]), - {OsFam, OsName} = - case os:type() of - {_Fam, _Name} = FamAndName -> - FamAndName; - Fam -> - {Fam, undefined} - end, - io:format("os_based_skip -> os-type: " - "~n OsFam: ~p" - "~n OsName: ~p" - "~n", [OsFam, OsName]), + os_base_skip(Skippable, os:type()); +os_based_skip(_Crap) -> + false. + +os_base_skip(Skippable, {OsFam, OsName}) -> + os_base_skip(Skippable, OsFam, OsName); +os_base_skip(Skippable, OsFam) -> + os_base_skip(Skippable, OsFam, undefined). + +os_base_skip(Skippable, OsFam, OsName) -> + %% Check if the entire family is to be skipped + %% Example: [win32, unix] case lists:member(OsFam, Skippable) of true -> true; false -> - case lists:keysearch(OsFam, 1, Skippable) of - {value, {OsFam, OsName}} -> - true; - {value, {OsFam, OsNames}} when is_list(OsNames) -> + %% Example: [{unix, freebsd}] | [{unix, [freebsd, darwin]}] + case lists:keysearch(OsFam, 1, Skippable) of + {value, {OsFam, OsName}} -> + true; + {value, {OsFam, OsNames}} when is_list(OsNames) -> + %% OsNames is a list of: + %% [atom()|{atom(), function/0 | function/1}] case lists:member(OsName, OsNames) of true -> true; false -> - case lists:keymember(OsName, 1, OsNames) of - {value, {OsName, Check}} when is_function(Check) -> - Check(); - _ -> - false - end + os_based_skip_check(OsName, OsNames) end; - _ -> - false - end - end; -os_based_skip(_Crap) -> - io:format("os_based_skip -> entry with" - "~n _Crap: ~p" - "~n", [_Crap]), - false. + _ -> + false + end + end. + +%% Performs a check via a provided fun with arity 0 or 1. +%% The argument is the result of os:version(). +os_based_skip_check(OsName, OsNames) -> + case lists:keysearch(OsName, 1, OsNames) of + {value, {OsName, Check}} when is_function(Check, 0) -> + Check(); + {value, {OsName, Check}} when is_function(Check, 1) -> + Check(os:version()); + _ -> + false + end. + + +%% A basic test to check if current host supports IPv6 +has_support_ipv6() -> + case inet:gethostname() of + {ok, Hostname} -> + has_support_ipv6(Hostname); + _ -> + false + end. + +has_support_ipv6(Hostname) -> + case inet:getaddr(Hostname, inet6) of + {ok, Addr} when (size(Addr) =:= 8) andalso + (element(1, Addr) =/= 0) andalso + (element(1, Addr) =/= 16#fe80) -> + true; + {ok, _} -> + false; + {error, _} -> + false + end. + + +is_ipv6_host() -> + case inet:gethostname() of + {ok, Hostname} -> + is_ipv6_host(Hostname); + {error, _} -> + false + end. + +is_ipv6_host(Hostname) -> + case ct:require(ipv6_hosts) of + ok -> + lists:member(list_to_atom(Hostname), ct:get_config(ipv6_hosts)); + _ -> + false + end. %% ---------------------------------------------------------------- @@ -397,10 +633,14 @@ nodes_on(Host) when is_list(Host) -> start_node(Name, Args) -> - Opts = [{cleanup,false}, {args,Args}], + Opts = [{cleanup, false}, {args, Args}], test_server:start_node(Name, slave, Opts). +stop_node(Node) -> + test_server:stop_node(Node). + + %% ---------------------------------------------------------------- %% Application and Crypto utility functions %% @@ -593,6 +833,9 @@ cover([Suite, Case] = Args) when is_atom(Suite) andalso is_atom(Case) -> %% (debug) Print functions %% +f(F, A) -> + lists:flatten(io_lib:format(F, A)). + p(Mod, Case) when is_atom(Mod) andalso is_atom(Case) -> case get(test_case) of undefined -> @@ -605,19 +848,30 @@ p(Mod, Case) when is_atom(Mod) andalso is_atom(Case) -> p(F, A) when is_list(F) andalso is_list(A) -> io:format(user, F ++ "~n", A). +%% This is just a bog standard printout, with a (formatted) timestamp +%% prefix and a newline after. +%% print1 - prints to both standard_io and user. +%% print2 - prints to just standard_io. + +print_format(F, A) -> + FTS = snmp_test_lib:formated_timestamp(), + io_lib:format("[~s] " ++ F ++ "~n", [FTS | A]). + +print1(F, A) -> + S = print_format(F, A), + io:format("~s", [S]), + io:format(user, "~s", [S]). + +print2(F, A) -> + S = print_format(F, A), + io:format("~s", [S]). + + print(Prefix, Module, Line, Format, Args) -> io:format("*** [~s] ~s ~p ~p ~p:~p *** " ++ Format ++ "~n", [formated_timestamp(), Prefix, node(), self(), Module, Line|Args]). formated_timestamp() -> - format_timestamp(os:timestamp()). - -format_timestamp({_N1, _N2, N3} = Now) -> - {Date, Time} = calendar:now_to_datetime(Now), - {YYYY,MM,DD} = Date, - {Hour,Min,Sec} = Time, - FormatDate = - io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w ~w", - [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), - lists:flatten(FormatDate). + snmp_misc:formated_timestamp(). + diff --git a/lib/snmp/test/snmp_test_lib.hrl b/lib/snmp/test/snmp_test_lib.hrl index 7acebee1f1..f077f15d3e 100644 --- a/lib/snmp/test/snmp_test_lib.hrl +++ b/lib/snmp/test/snmp_test_lib.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2015. All Rights Reserved. +%% Copyright Ericsson AB 2002-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,15 +18,11 @@ %% The Initial Developer of the Original Code is Ericsson AB. %% %CopyrightEnd% %% + %%---------------------------------------------------------------------- -%% Purpose: Define common macros for testing +%% Purpose: Define common macros for (the snmp) testing %%---------------------------------------------------------------------- -%% - (some of the) Macros stolen from the test server - - -%% -define(line,put(test_server_loc,{?MODULE,?LINE}),). - - %% - Misc macros - -ifndef(APPLICATION). @@ -45,12 +41,18 @@ %% - Test case macros - +-define(TC_TRY(C, TC), snmp_test_lib:tc_try(C, TC)). +-define(TC_TRY(C, TCCond, TC), snmp_test_lib:tc_try(C, TCCond, TC)). -define(OS_BASED_SKIP(Skippable), snmp_test_lib:os_based_skip(Skippable)). -define(NON_PC_TC_MAYBE_SKIP(Config, Condition), snmp_test_lib:non_pc_tc_maybe_skip(Config, Condition, ?MODULE, ?LINE)). --define(SKIP(Reason), snmp_test_lib:skip(Reason, ?MODULE, ?LINE)). --define(FAIL(Reason), snmp_test_lib:fail(Reason, ?MODULE, ?LINE)). +-define(SKIP(Reason), snmp_test_lib:skip(Reason, ?MODULE, ?LINE)). +-define(FAIL(Reason), snmp_test_lib:fail(Reason, ?MODULE, ?LINE)). +-define(IS_IPV6_HOST(), snmp_test_lib:is_ipv6_host()). +-define(IS_IPV6_HOST(H), snmp_test_lib:is_ipv6_host(H)). +-define(HAS_SUPPORT_IPV6(), snmp_test_lib:has_support_ipv6()). +-define(HAS_SUPPORT_IPV6(H), snmp_test_lib:has_support_ipv6(H)). %% - Time macros - @@ -88,6 +90,7 @@ -define(LNODES(), snmp_test_lib:local_nodes()). -define(NODES(H), snmp_test_lib:nodes_on(H)). -define(START_NODE(N,A), snmp_test_lib:start_node(N,A)). +-define(STOP_NODE(N), snmp_test_lib:stop_node(N)). %% - Application and Crypto utility macros - @@ -127,24 +130,33 @@ -endif. -ifdef(snmp_debug). --define(DBG(F,A),?PRINT("DBG",F,A)). +-define(DBG(F,A), ?PRINT("DBG", F, A)). -else. --define(DBG(F,A),ok). +-define(DBG(F,A), ok). -endif. -ifdef(snmp_log). --define(LOG(F,A),?PRINT("LOG",F,A)). +-define(LOG(F,A), ?PRINT("LOG", F, A)). -else. --define(LOG(F,A),ok). +-define(LOG(F,A), ok). -endif. -ifdef(snmp_error). --define(ERR(F,A),?PRINT("ERR",F,A)). +-define(ERR(F,A), ?PRINT("ERR", F, A)). -else. --define(ERR(F,A),ok). +-define(ERR(F,A), ok). -endif. --define(INF(F,A),?PRINT("INF",F,A)). +-define(INF(F,A), ?PRINT("INF", F, A)). -define(PRINT(P,F,A), - snmp_test_lib:print(P,?MODULE,?LINE,F,A)). + snmp_test_lib:print(P, ?MODULE, ?LINE, F, A)). + +-define(PRINT1(F, A), snmp_test_lib:print1(F, A)). +-define(PRINT1(F), ?PRINT1(F, [])). +-define(EPRINT1(F, A), ?PRINT1("<ERROR> " ++ F, A)). + +-define(PRINT2(F, A), snmp_test_lib:print2(F, A)). +-define(PRINT2(F), ?PRINT2(F, [])). +-define(EPRINT2(F, A), ?PRINT2("<ERROR> " ++ F, A)). + diff --git a/lib/snmp/test/snmp_test_mgr.erl b/lib/snmp/test/snmp_test_mgr.erl index 36637d5cf4..f50147a852 100644 --- a/lib/snmp/test/snmp_test_mgr.erl +++ b/lib/snmp/test/snmp_test_mgr.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2015. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -20,8 +20,10 @@ -module(snmp_test_mgr). + %%---------------------------------------------------------------------- -%% This module implements a simple SNMP manager for Erlang. +%% This module implements a simple SNMP manager for Erlang. Its used +%% during by the agent test suite. %%---------------------------------------------------------------------- %% c(snmp_test_mgr). @@ -49,16 +51,18 @@ -include_lib("snmp/include/snmp_types.hrl"). -include_lib("snmp/include/STANDARD-MIB.hrl"). - --record(state,{dbg = true, - quiet, - parent, - timeout = 3500, - print_traps = true, - mini_mib, - packet_server, - last_sent_pdu, - last_received_pdu}). +-include("snmp_test_lib.hrl"). +-include_lib("snmp/src/app/snmp_internal.hrl"). + +-record(state, {dbg = true, + quiet, + parent, + timeout = 3500, + print_traps = true, + mini_mib, + packet_server, + last_sent_pdu, + last_received_pdu}). -define(SERVER, ?MODULE). -define(PACK_SERV, snmp_test_mgr_misc). @@ -189,35 +193,38 @@ receive_trap(Timeout) -> init({Options, CallerPid}) -> put(sname, mgr), put(verbosity, debug), - random:seed(erlang:phash2([node()]), - erlang:monotonic_time(), - erlang:unique_integer()), + ?SNMP_RAND_SEED(), + %% rand:seed(exrop, + %% {erlang:phash2([node()]), + %% erlang:monotonic_time(), + %% erlang:unique_integer()}), case (catch is_options_ok(Options)) of true -> put(debug, get_value(debug, Options, false)), d("init -> (~p) extract options",[self()]), PacksDbg = get_value(packet_server_debug, Options, false), - io:format("[~w] ~p -> PacksDbg: ~p~n", [?MODULE, self(), PacksDbg]), + print("[~w] ~p -> PacksDbg: ~p~n", [?MODULE, self(), PacksDbg]), RecBufSz = get_value(recbuf, Options, 1024), - io:format("[~w] ~p -> RecBufSz: ~p~n", [?MODULE, self(), RecBufSz]), + print("[~w] ~p -> RecBufSz: ~p~n", [?MODULE, self(), RecBufSz]), Mibs = get_value(mibs, Options, []), - io:format("[~w] ~p -> Mibs: ~p~n", [?MODULE, self(), Mibs]), + print("[~w] ~p -> Mibs: ~p~n", [?MODULE, self(), Mibs]), Udp = get_value(agent_udp, Options, 4000), - io:format("[~w] ~p -> Udp: ~p~n", [?MODULE, self(), Udp]), + print("[~w] ~p -> Udp: ~p~n", [?MODULE, self(), Udp]), User = get_value(user, Options, "initial"), - io:format("[~w] ~p -> User: ~p~n", [?MODULE, self(), User]), + print("[~w] ~p -> User: ~p~n", [?MODULE, self(), User]), EngineId = get_value(engine_id, Options, "agentEngine"), - io:format("[~w] ~p -> EngineId: ~p~n", [?MODULE, self(), EngineId]), + print("[~w] ~p -> EngineId: ~p~n", [?MODULE, self(), EngineId]), CtxEngineId = get_value(context_engine_id, Options, EngineId), - io:format("[~w] ~p -> CtxEngineId: ~p~n", [?MODULE, self(), CtxEngineId]), + print("[~w] ~p -> CtxEngineId: ~p~n", [?MODULE, self(), CtxEngineId]), TrapUdp = get_value(trap_udp, Options, 5000), - io:format("[~w] ~p -> TrapUdp: ~p~n", [?MODULE, self(), TrapUdp]), + print("[~w] ~p -> TrapUdp: ~p~n", [?MODULE, self(), TrapUdp]), Dir = get_value(dir, Options, "."), - io:format("[~w] ~p -> Dir: ~p~n", [?MODULE, self(), Dir]), + print("[~w] ~p -> Dir: ~p~n", [?MODULE, self(), Dir]), SecLevel = get_value(sec_level, Options, noAuthNoPriv), - io:format("[~w] ~p -> SecLevel: ~p~n", [?MODULE, self(), SecLevel]), + print("[~w] ~p -> SecLevel: ~p~n", [?MODULE, self(), SecLevel]), MiniMIB = snmp_mini_mib:create(Mibs), - io:format("[~w] ~p -> MiniMIB: ~p~n", [?MODULE, self(), MiniMIB]), + d("[~w] ~p -> MiniMIB: " + "~n ~p", [?MODULE, self(), MiniMIB]), Version = case lists:member(v2, Options) of true -> 'version-2'; false -> @@ -226,30 +233,41 @@ init({Options, CallerPid}) -> false -> 'version-1' end end, - io:format("[~w] ~p -> Version: ~p~n", [?MODULE, self(), Version]), + print("[~w] ~p -> Version: ~p~n", [?MODULE, self(), Version]), Com = case Version of 'version-3' -> get_value(context, Options, ""); _ -> get_value(community, Options, "public") end, - io:format("[~w] ~p -> Com: ~p~n", [?MODULE, self(), Com]), + print("[~w] ~p -> Com: ~p~n", [?MODULE, self(), Com]), VsnHdrD = {Com, User, EngineId, CtxEngineId, mk_seclevel(SecLevel)}, - io:format("[~w] ~p -> VsnHdrD: ~p~n", [?MODULE, self(), VsnHdrD]), + print("[~w] ~p -> VsnHdrD: ~p~n", [?MODULE, self(), VsnHdrD]), IpFamily = get_value(ipfamily, Options, inet), - io:format("[~w] ~p -> IpFamily: ~p~n", [?MODULE, self(), IpFamily]), + print("[~w] ~p -> IpFamily: ~p~n", [?MODULE, self(), IpFamily]), AgIp = case snmp_misc:assq(agent, Options) of - {value, Tuple4} when is_tuple(Tuple4) andalso - (size(Tuple4) =:= 4) -> - Tuple4; + {value, Addr} when is_tuple(Addr) andalso + (size(Addr) =:= 4) andalso + (IpFamily =:= inet) -> + print("[~w] ~p -> Addr: ~p~n", + [?MODULE, self(), Addr]), + Addr; + {value, Addr} when is_tuple(Addr) andalso + (size(Addr) =:= 8) andalso + (IpFamily =:= inet6) -> + print("[~w] ~p -> Addr: ~p~n", + [?MODULE, self(), Addr]), + Addr; {value, Host} when is_list(Host) -> + print("[~w] ~p -> Host: ~p~n", + [?MODULE, self(), Host]), {ok, Ip} = snmp_misc:ip(Host, IpFamily), Ip end, - io:format("[~w] ~p -> AgIp: ~p~n", [?MODULE, self(), AgIp]), + print("[~w] ~p -> AgIp: ~p~n", [?MODULE, self(), AgIp]), Quiet = lists:member(quiet, Options), - io:format("[~w] ~p -> Quiet: ~p~n", [?MODULE, self(), Quiet]), + print("[~w] ~p -> Quiet: ~p~n", [?MODULE, self(), Quiet]), PackServ = start_packet_server( Quiet, Options, CallerPid, AgIp, Udp, TrapUdp, @@ -443,7 +461,8 @@ handle_cast({bulk, Args}, State) -> {noreply, execute_request(bulk, Args, State)}; handle_cast({response, RespPdu}, State) -> - d("handle_cast -> response request with ~p", [RespPdu]), + d("handle_cast -> response request with " + "~n ~p", [RespPdu]), ?PACK_SERV:send_pdu(RespPdu, State#state.packet_server), {noreply, State}; @@ -663,7 +682,6 @@ make_vb(Oid) -> #varbind{oid = Oid, variabletype = 'NULL', value = 'NULL'}. make_request_id() -> - %% random:uniform(16#FFFFFFF-1). snmp_test_mgr_counter_server:increment(mgr_request_id, 1, 1, 2147483647). echo_pdu(PDU, MiniMIB) -> @@ -682,18 +700,30 @@ echo_errors({error, Id, {ExpectedFormat, ExpectedData}, {Format, Data}})-> echo_errors(ok) -> ok; echo_errors({ok, Val}) -> {ok, Val}. -get_response_impl(Id, Vars) -> +get_response_impl(Id, ExpVars) -> + ?PRINT2("await response ~w with" + "~n Expected Varbinds: ~p", + [Id, ExpVars]), + PureVars = find_pure_oids2(ExpVars), case receive_response() of #pdu{type = 'get-response', error_status = noError, error_index = 0, varbinds = VBs} -> - match_vars(Id, find_pure_oids2(Vars), VBs, []); + ?PRINT2("received expected response pdu (~w) - match vars" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Id, PureVars, VBs]), + match_vars(Id, PureVars, VBs, []); #pdu{type = Type2, request_id = ReqId, error_status = Err2, error_index = Index2} -> + ?EPRINT2("received unexpected response pdu: ~w, ~w, ~w" + "~n Received Error: ~p" + "~n Received Index: ~p", + [Type2, Id, ReqId, Err2, Index2]), {error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w", @@ -702,6 +732,8 @@ get_response_impl(Id, Vars) -> [Type2, Err2, Index2]}}; {error, Reason} -> + ?EPRINT2("unexpected receive pdu error: ~w" + "~n ~p", [Id, Reason]), format_reason(Id, Reason) end. @@ -711,171 +743,208 @@ get_response_impl(Id, Vars) -> %% Returns: ok | {error, Id, {ExpectedFormat, ExpectedData}, {Format, Data}} %%---------------------------------------------------------------------- expect_impl(Id, any) -> - io:format("expect_impl(~w, any) -> entry ~n", [Id]), + ?PRINT2("await ~w pdu (any)", [Id]), case receive_response() of - PDU when is_record(PDU, pdu) -> ok; - {error, Reason} -> format_reason(Id, Reason) + PDU when is_record(PDU, pdu) -> + ?PRINT2("received expected pdu (~w)", [Id]), + ok; + {error, Reason} -> + ?EPRINT1("unexpected receive error: ~w" + "~n ~p", [Id, Reason]), + format_reason(Id, Reason) end; expect_impl(Id, return) -> - io:format("expect_impl(~w, return) -> entry ~n", [Id]), + ?PRINT2("await ~w pdu", [Id]), case receive_response() of - PDU when is_record(PDU, pdu) -> {ok, PDU}; - {error, Reason} -> format_reason(Id, Reason) + PDU when is_record(PDU, pdu) -> + ?PRINT2("received expected pdu (~w)", [Id]), + {ok, PDU}; + {error, Reason} -> + ?EPRINT1("unexpected receive error: ~w" + "~n ~p", [Id, Reason]), + format_reason(Id, Reason) end; expect_impl(Id, trap) -> - io:format("expect_impl(~w, trap) -> entry ~n", [Id]), + ?PRINT2("await ~w trap", [Id]), case receive_trap(3500) of - PDU when is_record(PDU, trappdu) -> ok; - {error, Reason} -> format_reason(Id, Reason) + PDU when is_record(PDU, trappdu) -> + ?PRINT2("received expected trap (~w)", [Id]), + ok; + {error, Reason} -> + ?EPRINT1("unexpected receive error: ~w" + "~n ~p", [Id, Reason]), + format_reason(Id, Reason) end; expect_impl(Id, timeout) -> - io:format("expect_impl(~w, timeout) -> entry ~n", [Id]), + ?PRINT2("await ~w nothing", [Id]), receive X -> - io:format("expect_impl(~w, timeout) -> " - "received unexpected message: ~n~p~n", [Id, X]), + ?EPRINT1("received unexpected message: ~w" + "~n ~p", + [Id, X]), {error, Id, {"Timeout", []}, {"Message ~w", [X]}} after 3500 -> ok end; expect_impl(Id, Err) when is_atom(Err) -> - io:format("expect_impl(~w, ~w) -> entry ~n", [Id, Err]), + ?PRINT2("await ~w with" + "~n Err: ~p", + [Id, Err]), case receive_response() of #pdu{error_status = Err} -> + ?PRINT2("received pdu with expected error status (~w, ~w)", + [Id, Err]), ok; - #pdu{request_id = ReqId, - error_status = OtherErr} -> - io:format("expect_impl(~w, ~w) -> " - "received pdu (~w) with unexpected error-status: " - "~n~p~n", [Id, Err, ReqId, OtherErr]), + #pdu{type = Type2, + request_id = ReqId, + error_status = Err2} -> + ?EPRINT1("received pdu with unexpected error status: ~w, ~w, ~w" + "~n Expected Error: ~p" + "~n Received Error: ~p", + [Type2, Id, ReqId, Err, Err2]), {error, Id, {"ErrorStatus: ~w, RequestId: ~w", [Err,ReqId]}, - {"ErrorStatus: ~w", [OtherErr]}}; + {"ErrorStatus: ~w", [Err2]}}; {error, Reason} -> + ?EPRINT1("unexpected receive error: ~w" + "~n ~p", [Id, Reason]), format_reason(Id, Reason) end; expect_impl(Id, ExpectedVarbinds) when is_list(ExpectedVarbinds) -> - io:format("expect_impl(~w) -> entry with" - "~n ExpectedVarbinds: ~p~n", [Id, ExpectedVarbinds]), + ?PRINT2("await ~w with" + "~n ExpectedVarbinds: ~p", + [Id, ExpectedVarbinds]), + PureVars = find_pure_oids(ExpectedVarbinds), case receive_response() of #pdu{type = 'get-response', error_status = noError, error_index = 0, varbinds = VBs} -> - io:format("expect_impl(~w) -> received pdu with" - "~n VBs: ~p~n", [Id, VBs]), - check_vars(Id, find_pure_oids(ExpectedVarbinds), VBs); + ?PRINT2("received expected response pdu (~w) - check varbinds" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Id, PureVars, VBs]), + check_vars(Id, PureVars, VBs); #pdu{type = Type2, request_id = ReqId, error_status = Err2, error_index = Index2} -> - io:format("expect_impl(~w) -> received unexpected pdu with" - "~n Type2: ~p" - "~n ReqId: ~p" - "~n Err2: ~p" - "~n Index2: ~p" - "~n", [Id, Type2, ReqId, Err2, Index2]), + ?EPRINT1("received unexpected pdu: ~w, ~w, ~w" + "~n Received Error: ~p" + "~n Received Index: ~p", + [Type2, Id, ReqId, Err2, Index2]), {error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w", ['get-response', noError, 0, ReqId]}, {"Type: ~w, ErrStat: ~w, Idx: ~w", [Type2, Err2, Index2]}}; {error, Reason} -> + ?EPRINT1("unexpected receive error: ~w" + "~n ~p", [Id, Reason]), format_reason(Id, Reason) end. expect_impl(Id, v2trap, ExpectedVarbinds) when is_list(ExpectedVarbinds) -> - io:format("expect_impl(~w, v2trap) -> entry with" - "~n ExpectedVarbinds: ~p~n", [Id, ExpectedVarbinds]), + ?PRINT2("await v2 trap ~w with" + "~n ExpectedVarbinds: ~p", + [Id, ExpectedVarbinds]), + PureVars = find_pure_oids(ExpectedVarbinds), case receive_response() of #pdu{type = 'snmpv2-trap', error_status = noError, error_index = 0, varbinds = VBs} -> - io:format("expect_impl(~w, v2trap) -> received pdu with" - "~n VBs: ~p~n", [Id, VBs]), - check_vars(Id, find_pure_oids(ExpectedVarbinds), VBs); + ?PRINT2("received expected v2 trap (~w) - check varbinds" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Id, PureVars, VBs]), + check_vars(Id, PureVars, VBs); #pdu{type = Type2, request_id = ReqId, error_status = Err2, error_index = Index2} -> - io:format("expect_impl(~w, v2trap) -> received unexpected pdu with" - "~n Type2: ~p" - "~n ReqId: ~p" - "~n Err2: ~p" - "~n Index2: ~p" - "~n", [Id, Type2, ReqId, Err2, Index2]), + ?EPRINT1("received unexpected pdu: ~w, ~w, ~w" + "~n Received Error: ~p" + "~n Received Index: ~p", + [Type2, Id, ReqId, Err2, Index2]), {error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w", ['snmpv2-trap', noError, 0, ReqId]}, {"Type: ~w, ErrStat: ~w, Idx: ~w", [Type2, Err2, Index2]}}; {error, Reason} -> + ?EPRINT1("unexpected receive error: ~w" + "~n ~p", [Id, Reason]), format_reason(Id, Reason) end; expect_impl(Id, report, ExpectedVarbinds) when is_list(ExpectedVarbinds) -> - io:format("expect_impl(~w, report) -> entry with" - "~n ExpectedVarbinds: ~p~n", [Id, ExpectedVarbinds]), + ?PRINT2("await report ~w with" + "~n ExpectedVarbinds: ~p", + [Id, ExpectedVarbinds]), + PureVBs = find_pure_oids(ExpectedVarbinds), case receive_response() of #pdu{type = 'report', error_status = noError, error_index = 0, varbinds = VBs} -> - io:format("expect_impl(~w, report) -> received pdu with" - "~n VBs: ~p~n", [Id, VBs]), - check_vars(Id, find_pure_oids(ExpectedVarbinds), VBs); + ?PRINT2("received expected report (~w) - check varbinds" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Id, PureVBs, VBs]), + check_vars(Id, PureVBs, VBs); #pdu{type = Type2, request_id = ReqId, error_status = Err2, error_index = Index2} -> - io:format("expect_impl(~w, report) -> received unexpected pdu with" - "~n Type2: ~p" - "~n ReqId: ~p" - "~n Err2: ~p" - "~n Index2: ~p" - "~n", [Id, Type2, ReqId, Err2, Index2]), + ?EPRINT1("received unexpected pdu: ~w, ~w, ~w" + "~n Received Error: ~p" + "~n Received Index: ~p", + [Type2, Id, ReqId, Err2, Index2]), {error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w", [report, noError, 0, ReqId]}, {"Type: ~w, ErrStat: ~w, Idx: ~w", [Type2, Err2, Index2]}}; {error, Reason} -> + ?EPRINT1("unexpected receive error: ~w" + "~n ~p", [Id, Reason]), format_reason(Id, Reason) end; expect_impl(Id, {inform, Reply}, ExpectedVarbinds) when is_list(ExpectedVarbinds) -> - io:format("expect_impl(~w, inform) -> entry with" - "~n Reply: ~p" - "~n ExpectedVarbinds: ~p" - "~n", [Id, Reply, ExpectedVarbinds]), - Resp = receive_response(), + ?PRINT2("await inform ~w with" + "~n Reply: ~p" + "~n ExpectedVarbinds: ~p", + [Id, Reply, ExpectedVarbinds]), + PureVBs = find_pure_oids(ExpectedVarbinds), + Resp = receive_response(), case Resp of #pdu{type = 'inform-request', error_status = noError, error_index = 0, varbinds = VBs} -> - io:format("expect_impl(~w, inform) -> received pdu with" - "~n VBs: ~p~n", [Id, VBs]), - case check_vars(Id, find_pure_oids(ExpectedVarbinds), VBs) of + ?PRINT2("received inform (~w) - check varbinds" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Id, PureVBs, VBs]), + case check_vars(Id, PureVBs, VBs) of ok when (Reply == true) -> - io:format("expect_impl(~w, inform) -> send ok response" - "~n", [Id]), + ?PRINT2("varbinds ok (~w) - send ok inform response", [Id]), RespPDU = Resp#pdu{type = 'get-response', error_status = noError, error_index = 0}, ?MODULE:rpl(RespPDU), ok; ok when (element(1, Reply) == error) -> - io:format("expect_impl(~w, inform) -> send error response" - "~n", [Id]), + ?PRINT2("varbinds ok (~w) - send error inform response", [Id]), {error, Status, Index} = Reply, RespPDU = Resp#pdu{type = 'get-response', error_status = Status, @@ -883,10 +952,10 @@ expect_impl(Id, {inform, Reply}, ExpectedVarbinds) ?MODULE:rpl(RespPDU), ok; ok when (Reply == false) -> - io:format("expect_impl(~w, inform) -> no response sent" - "~n", [Id]), + ?PRINT2("varbinds ok (~w) - don't send inform response", [Id]), ok; Else -> + ?EPRINT1("unexpected varbinds (~w)", [Id]), io:format("expect_impl(~w, inform) -> " "~n Else: ~p" "~n", [Id, Else]), @@ -897,54 +966,54 @@ expect_impl(Id, {inform, Reply}, ExpectedVarbinds) request_id = ReqId, error_status = Err2, error_index = Index2} -> - io:format("expect_impl(~w, inform) -> received unexpected pdu with" - "~n Type2: ~p" - "~n ReqId: ~p" - "~n Err2: ~p" - "~n Index2: ~p" - "~n", [Id, Type2, ReqId, Err2, Index2]), + ?EPRINT1("received unexpected pdu: ~w, ~w, ~w" + "~n Received Error: ~p" + "~n Received Index: ~p", + [Type2, Id, ReqId, Err2, Index2]), {error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w", ['inform-request', noError, 0, ReqId]}, {"Type: ~w, ErrStat: ~w, Idx: ~w", [Type2, Err2, Index2]}}; {error, Reason} -> - io:format("expect_impl(~w, inform) -> receive failed" - "~n Reason: ~p" - "~n", [Id, Reason]), + ?EPRINT1("unexpected receive error: ~w" + "~n ~p", [Id, Reason]), format_reason(Id, Reason) end. -expect_impl(Id, Err, Index, any) -> - io:format("expect_impl(~w, any) -> entry with" - "~n Err: ~p" - "~n Index: ~p" - "~n", [Id, Err, Index]), +expect_impl(Id, Err, Index, any = _ExpectedVarbinds) -> + ?PRINT2("await response ~w with" + "~n Err: ~p" + "~n Index: ~p" + "~n ExpectedVarbinds: ~p", + [Id, Err, Index, _ExpectedVarbinds]), case receive_response() of #pdu{type = 'get-response', error_status = Err, error_index = Index} -> - io:format("expect_impl(~w, any) -> received expected pdu" - "~n", [Id]), + ?PRINT2("received expected response pdu (~w, ~w, ~w)", + [Id, Err, Index]), ok; - #pdu{type = 'get-response', error_status = Err} when (Index == any) -> - io:format("expect_impl(~w, any) -> received expected pdu (any)" - "~n", [Id]), + #pdu{type = 'get-response', + error_status = Err} when (Index == any) -> + ?PRINT2("received expected response pdu (~w, ~w)", + [Id, Err]), ok; #pdu{type = 'get-response', request_id = ReqId, error_status = Err, error_index = Idx} when is_list(Index) -> - io:format("expect_impl(~w, any) -> received pdu: " - "~n ReqId: ~p" - "~n Err: ~p" - "~n Idx: ~p" - "~n", [Id, ReqId, Err, Idx]), case lists:member(Idx, Index) of true -> + ?PRINT2("received expected response pdu (~w, ~w, ~w)", + [Id, Err, Idx]), ok; false -> + ?EPRINT1("received response pdu with unexpected index (~w, ~w):" + "~n Expected Index: ~p" + "~n Received Index: ~p", + [Id, Err, Index, Idx]), {error, Id, {"ErrStat: ~w, Idx: ~w, RequestId: ~w", [Err, Index, ReqId]}, {"ErrStat: ~w, Idx: ~w", [Err, Idx]}} @@ -954,12 +1023,12 @@ expect_impl(Id, Err, Index, any) -> request_id = ReqId, error_status = Err2, error_index = Index2} -> - io:format("expect_impl(~w, any) -> received unexpected pdu: " - "~n Type2: ~p" - "~n ReqId: ~p" - "~n Err2: ~p" - "~n Index2: ~p" - "~n", [Id, Type2, ReqId, Err2, Index2]), + ?EPRINT1("received unexpected response pdu: ~w, ~w, ~w" + "~n Expected Error: ~p" + "~n Received Error: ~p" + "~n Expected Index: ~p" + "~n Received Index: ~p", + [Type2, Id, ReqId, Err, Err2, Index, Index2]), {error, Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, RequestId: ~w", ['get-response', Err, Index, ReqId]}, {"Type: ~w, ErrStat: ~w, Idx: ~w", [Type2, Err2, Index2]}}; @@ -969,22 +1038,30 @@ expect_impl(Id, Err, Index, any) -> end; expect_impl(Id, Err, Index, ExpectedVarbinds) -> - io:format("expect_impl(~w) -> entry with" - "~n Err: ~p" - "~n Index: ~p" - "~n ExpectedVarbinds: ~p" - "~n", [Id, Err, Index, ExpectedVarbinds]), + ?PRINT2("await response ~w with" + "~n Err: ~p" + "~n Index: ~p" + "~n ExpectedVarbinds: ~p", + [Id, Err, Index, ExpectedVarbinds]), PureVBs = find_pure_oids(ExpectedVarbinds), case receive_response() of #pdu{type = 'get-response', error_status = Err, error_index = Index, varbinds = VBs} -> + ?PRINT2("received expected response pdu (~w, ~w, ~w) - check varbinds" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Id, Err, Index, PureVBs, VBs]), check_vars(Id, PureVBs, VBs); #pdu{type = 'get-response', error_status = Err, varbinds = VBs} when (Index == any) -> + ?PRINT2("received expected response pdu (~w, ~w) - check varbinds" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Id, Err, PureVBs, VBs]), check_vars(Id, PureVBs, VBs); #pdu{type = 'get-response', @@ -994,8 +1071,18 @@ expect_impl(Id, Err, Index, ExpectedVarbinds) -> varbinds = VBs} when is_list(Index) -> case lists:member(Idx, Index) of true -> + ?PRINT2("received expected pdu (~w, ~w, ~w) - check varbinds" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Id, Err, Idx, PureVBs, VBs]), check_vars(Id, PureVBs, VBs); false -> + ?EPRINT1("received response pdu with unexpected index (~w, ~w):" + "~n Expected Index: ~p" + "~n Received Index: ~p" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Id, Err, Index, Idx, PureVBs, VBs]), {error,Id, {"ErrStat: ~w, Idx: ~w, Varbinds: ~w, RequestId: ~w", [Err,Index,PureVBs,ReqId]}, @@ -1008,29 +1095,65 @@ expect_impl(Id, Err, Index, ExpectedVarbinds) -> error_status = Err2, error_index = Index2, varbinds = VBs} -> + ?EPRINT1("received unexpected response pdu: ~w, ~w, ~w" + "~n Expected Error: ~p" + "~n Received Error: ~p" + "~n Expected Index: ~p" + "~n Received Index: ~p" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Type2, Id, ReqId, + Err, Err2, Index, Index2, PureVBs, VBs]), {error,Id, {"Type: ~w, ErrStat: ~w, Idx: ~w, Varbinds: ~w, RequestId: ~w", ['get-response',Err,Index,PureVBs,ReqId]}, {"Type: ~w, ErrStat: ~w Idx: ~w Varbinds: ~w", [Type2,Err2,Index2,VBs]}}; - {error, Reason} -> + {error, Reason} -> + ?EPRINT1("unexpected receive pdu error: ~w" + "~n ~p", [Id, Reason]), format_reason(Id, Reason) end. expect_impl(Id, trap, Enterp, Generic, Specific, ExpectedVarbinds) -> - PureE = find_pure_oid(Enterp), + ?PRINT2("await trap pdu ~w with" + "~n Enterprise: ~p" + "~n Generic: ~p" + "~n Specific: ~p" + "~n ExpectedVarbinds: ~p", + [Id, Enterp, Generic, Specific, ExpectedVarbinds]), + PureE = find_pure_oid(Enterp), + PureVBs = find_pure_oids(ExpectedVarbinds), case receive_trap(3500) of #trappdu{enterprise = PureE, generic_trap = Generic, specific_trap = Specific, varbinds = VBs} -> - check_vars(Id, find_pure_oids(ExpectedVarbinds), VBs); + ?PRINT2("received expected trap pdu - check varbinds" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [PureVBs, VBs]), + check_vars(Id, PureVBs, VBs); #trappdu{enterprise = Ent2, generic_trap = G2, specific_trap = Spec2, varbinds = VBs} -> + ?EPRINT1("received unexpected trap pdu: ~w" + "~n Expected Enterprise: ~p" + "~n Received Enterprise: ~p" + "~n Expected Generic: ~p" + "~n Received Generic: ~p" + "~n Expected Specific: ~p" + "~n Received Specific: ~p" + "~n Expected VBs: ~p" + "~n Received VBs: ~p", + [Id, + PureE, Ent2, + Generic, G2, + Specific, Spec2, + PureVBs, VBs]), {error, Id, {"Enterprise: ~w, Generic: ~w, Specific: ~w, Varbinds: ~w", [PureE, Generic, Specific, ExpectedVarbinds]}, @@ -1038,12 +1161,15 @@ expect_impl(Id, trap, Enterp, Generic, Specific, ExpectedVarbinds) -> [Ent2, G2, Spec2, VBs]}}; {error, Reason} -> + ?EPRINT1("unexpected receive trap pdu error: ~w" + "~n ~p", [Id, Reason]), format_reason(Id, Reason) end. format_reason(Id, Reason) -> {error, Id, {"?", []}, {"~w", [Reason]}}. + %%---------------------------------------------------------------------- %% Args: Id, ExpectedVarbinds, GotVarbinds %% Returns: ok @@ -1126,14 +1252,15 @@ sizeOf(L) when is_list(L) -> sizeOf(B) when is_binary(B) -> size(B). -d(F,A) -> d(get(debug),F,A). +d(F, A) -> d(get(debug), F, A). -d(true,F,A) -> - io:format("*** [~s] MGR_DBG *** " ++ F ++ "~n", - [formated_timestamp()|A]); +d(true, F, A) -> + print(F, A); d(_,_F,_A) -> ok. +print(F, A) -> + ?PRINT2("MGR " ++ F, A). -formated_timestamp() -> - snmp_test_lib:formated_timestamp(). +%% formated_timestamp() -> +%% snmp_test_lib:formated_timestamp(). diff --git a/lib/snmp/test/snmp_test_mgr_misc.erl b/lib/snmp/test/snmp_test_mgr_misc.erl index 274fb5be26..6608a88c00 100644 --- a/lib/snmp/test/snmp_test_mgr_misc.erl +++ b/lib/snmp/test/snmp_test_mgr_misc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2016. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -38,11 +38,14 @@ -define(SNMP_USE_V3, true). -include_lib("snmp/include/snmp_types.hrl"). +-include_lib("snmp/src/misc/snmp_verbosity.hrl"). +-include("snmp_test_lib.hrl"). %%---------------------------------------------------------------------- %% The InHandler process will receive messages on the form {snmp_pdu, Pdu}. %%---------------------------------------------------------------------- + start_link_packet( InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz) -> start_link_packet( @@ -101,11 +104,11 @@ init_packet( DbgOptions, IpFamily) -> put(sname, mgr_misc), init_debug(DbgOptions), - {ok, UdpId} = - gen_udp:open(TrapUdp, [{recbuf,BufSz}, {reuseaddr, true}, IpFamily]), + UdpOpts = [{recbuf,BufSz}, {reuseaddr, true}, IpFamily], + {ok, UdpId} = gen_udp:open(TrapUdp, UdpOpts), put(msg_id, 1), - proc_lib:init_ack(Parent, self()), init_usm(Version, Dir), + proc_lib:init_ack(Parent, self()), packet_loop(SnmpMgr, UdpId, AgentIp, UdpPort, VsnHdr, Version, []). init_debug(Dbg) when is_atom(Dbg) -> @@ -200,86 +203,24 @@ packet_loop(SnmpMgr, UdpId, AgentIp, UdpPort, VsnHdr, Version, MsgData) -> handle_udp_packet(_V, undefined, UdpId, Ip, UdpPort, Bytes, SnmpMgr, AgentIp) -> - M = (catch snmp_pdus:dec_message_only(Bytes)), - MsgData3 = - case M of - Message when Message#message.version =:= 'version-3' -> - d("handle_udp_packet -> version 3"), - case catch handle_v3_msg(Bytes, Message) of - {ok, NewData, MsgData2} -> - Msg = Message#message{data = NewData}, - case SnmpMgr of - {pdu, Pid} -> - Pdu = get_pdu(Msg), - d("packet_loop -> " - "send pdu to manager (~w): ~p", [Pid, Pdu]), - Pid ! {snmp_pdu, Pdu}; - {msg, Pid} -> - d("packet_loop -> " - "send msg to manager (~w): ~p", [Pid, Msg]), - Pid ! {snmp_msg, Msg, Ip, UdpPort} - end, - MsgData2; - {error, Reason, B} -> - udp_send(UdpId, AgentIp, UdpPort, B), - error("Decoding error. Auto-sending Report.\n" - "Reason: ~w " - "(UDPport: ~w, Ip: ~w)", - [Reason, UdpPort, Ip]), - []; - {error, Reason} -> - error("Decoding error. " - "Bytes: ~w ~n Reason: ~w " - "(UDPport: ~w, Ip: ~w)", - [Bytes, Reason, UdpPort, Ip]), - [] - end; - Message when is_record(Message, message) -> - %% v1 or v2c - d("handle_udp_packet -> version v1 or v2c"), - case catch snmp_pdus:dec_pdu(Message#message.data) of - Pdu when is_record(Pdu, pdu) -> - case SnmpMgr of - {pdu, Pid} -> - d("handle_udp_packet -> " - "send pdu to manager (~w): ~p", - [Pid, Pdu]), - Pid ! {snmp_pdu, Pdu}; - {msg, Pid} -> - d("handle_udp_packet -> " - "send pdu-msg to manager (~w): ~p", - [Pid, Pdu]), - Msg = Message#message{data = Pdu}, - Pid ! {snmp_msg, Msg, Ip, UdpPort} - end; - Pdu when is_record(Pdu, trappdu) -> - case SnmpMgr of - {pdu, Pid} -> - d("handle_udp_packet -> " - "send trap to manager (~w): ~p", - [Pid, Pdu]), - Pid ! {snmp_pdu, Pdu}; - {msg, Pid} -> - d("handle_udp_packet -> " - "send trap-msg to manager (~w): ~p", - [Pid, Pdu]), - Msg = Message#message{data = Pdu}, - Pid ! {snmp_msg, Msg, Ip, UdpPort} - end; - Reason -> - error("Decoding error. " - "Bytes: ~w ~n Reason: ~w " - "(UDPport: ~w, Ip: ~w)", - [Bytes, Reason, UdpPort, Ip]) - end, - []; - Reason -> - error("Decoding error. Bytes: ~w ~n Reason: ~w " - "(UDPport: ~w, Ip: ~w)", - [Bytes, Reason, UdpPort, Ip]), - [] - end, - MsgData3; + try snmp_pdus:dec_message_only(Bytes) of + Message when Message#message.version =:= 'version-3' -> + d("handle_udp_packet -> version 3"), + handle_v3_message(SnmpMgr, UdpId, Ip, UdpPort, AgentIp, + Bytes, Message); + + Message when is_record(Message, message) -> + d("handle_udp_packet -> version 1 or 2"), + handle_v1_or_v2_message(SnmpMgr, UdpId, Ip, UdpPort, AgentIp, + Bytes, Message) + + catch + Class:Error:_ -> + error("Decoding error (~w). Bytes: ~w ~n Error: ~w " + "(UDPport: ~w, Ip: ~w)", + [Class, Bytes, Error, UdpPort, Ip]), + [] + end; handle_udp_packet(V, {DiscoReqMsg, From}, _UdpId, _Ip, _UdpPort, Bytes, _, _AgentIp) -> DiscoRspMsg = (catch snmp_pdus:dec_message(Bytes)), @@ -297,6 +238,88 @@ handle_udp_packet(V, {DiscoReqMsg, From}, _UdpId, _Ip, _UdpPort, [] end. +handle_v3_message(Mgr, UdpId, Ip, UdpPort, AgentIp, + Bytes, Message) -> + try handle_v3_msg(Bytes, Message) of + {ok, NewData, MsgData} -> + Msg = Message#message{data = NewData}, + case Mgr of + {pdu, Pid} -> + Pdu = get_pdu(Msg), + d("handle_v3_message -> send pdu to manager (~p): " + "~n ~p", [Pid, Pdu]), + Pid ! {snmp_pdu, Pdu}; + {msg, Pid} -> + d("handle_v3_message -> send msg to manager (~p): " + "~n ~p", [Pid, Msg]), + Pid ! {snmp_msg, Msg, Ip, UdpPort} + end, + MsgData + + catch + throw:{error, Reason, B}:_ -> + udp_send(UdpId, AgentIp, UdpPort, B), + error("Decoding (v3) error. Auto-sending Report.\n" + "~n Reason: ~w " + "(UDPport: ~w, Ip: ~w)", + [Reason, UdpPort, Ip]), + []; + + throw:{error, Reason}:_ -> + error("Decoding (v3) error. " + "~n Bytes: ~w" + "~n Reason: ~w " + "(UDPport: ~w, Ip: ~w)", + [Bytes, Reason, UdpPort, Ip]), + []; + + Class:Error:_ -> + error("Decoding (v3) error (~w). " + "~n Bytes: ~w" + "~n Error: ~w " + "(UDPport: ~w, Ip: ~w)", + [Class, Bytes, Error, UdpPort, Ip]), + [] + + end. + +handle_v1_or_v2_message(Mgr, _UdpId, Ip, UdpPort, _AgentIp, + Bytes, Message) -> + try snmp_pdus:dec_pdu(Message#message.data) of + Pdu when is_record(Pdu, pdu) -> + case Mgr of + {pdu, Pid} -> + d("handle_v1_or_v2_message -> send pdu to manager (~p): " + "~n ~p", [Pid, Pdu]), + Pid ! {snmp_pdu, Pdu}; + {msg, Pid} -> + d("handle_v1_or_v2_message -> send msg to manager (~p): " + "~n ~p", [Pid, Pdu]), + Msg = Message#message{data = Pdu}, + Pid ! {snmp_msg, Msg, Ip, UdpPort} + end; + Pdu when is_record(Pdu, trappdu) -> + case Mgr of + {pdu, Pid} -> + d("handle_v1_or_v2_message -> send trap-pdu to manager (~p): " + "~n ~p", [Pid, Pdu]), + Pid ! {snmp_pdu, Pdu}; + {msg, Pid} -> + d("handle_v1_or_v2_message -> send trap-msg to manager (~p): " + "~n ~p", [Pid, Pdu]), + Msg = Message#message{data = Pdu}, + Pid ! {snmp_msg, Msg, Ip, UdpPort} + end + + catch + Class:Error:_ -> + error("Decoding (v1 or v2) error (~w): " + "~n Bytes: ~w" + "~n Error: ~w " + "(UDPport: ~w, Ip: ~w)", + [Class, Bytes, Error, UdpPort, Ip]) + end. + %% This function assumes that the agent and the manager (thats us) %% has the same version. @@ -553,6 +576,7 @@ vsn('version-2') -> v2c. udp_send(UdpId, AgentIp, UdpPort, B) -> + ?vlog("attempt send message (~w bytes) to ~p", [sz(B), {AgentIp, UdpPort}]), case (catch gen_udp:send(UdpId, AgentIp, UdpPort, B)) of {error,ErrorReason} -> error("failed (error) sending message to ~p:~p: " @@ -578,18 +602,100 @@ set_pdu(Msg, RePdu) -> init_usm('version-3', Dir) -> + ?vlog("init_usm -> create (and init) fake \"agent\" table", []), ets:new(snmp_agent_table, [set, public, named_table]), ets:insert(snmp_agent_table, {agent_mib_storage, persistent}), - snmpa_local_db:start_link(normal, Dir, [{verbosity,trace}]), + %% The local-db process may *still* be running (from a previous + %% test case), on the way down, but not yet dead. + %% Either way, before we start it, make sure its dead and *gone*! + %% How do we do that without getting hung up? Calling the stop + %% function, will not do since it uses Timeout=infinity. + ?vlog("init_usm -> ensure (old) fake local-db is dead", []), + ensure_local_db_dead(), + ?vlog("init_usm -> try start fake local-db", []), + case snmpa_local_db:start_link(normal, Dir, + [{sname, "MGR-LOCAL-DB"}, + {verbosity, trace}]) of + {ok, Pid} -> + ?vlog("started: ~p" + "~n ~p", [Pid, process_info(Pid)]); + {error, {already_started, Pid}} -> + LDBInfo = process_info(Pid), + ?vlog("already started: ~p" + "~n ~p", [Pid, LDBInfo]), + ?FAIL({still_running, snmpa_local_db, LDBInfo}); + {error, Reason} -> + ?FAIL({failed_starting, snmpa_local_db, Reason}) + end, NameDb = snmpa_agent:db(snmpEngineID), + ?vlog("init_usm -> try set manager engine-id", []), R = snmp_generic:variable_set(NameDb, "mgrEngine"), - io:format("~w:init_usm -> engine-id set result: ~p~n", [?MODULE,R]), + snmp_verbosity:print(info, info, "init_usm -> engine-id set result: ~p", [R]), + ?vlog("init_usm -> try set engine boots (framework-mib)", []), snmp_framework_mib:set_engine_boots(1), + ?vlog("init_usm -> try set engine time (framework-mib)", []), snmp_framework_mib:set_engine_time(1), - snmp_user_based_sm_mib:reconfigure(Dir); + ?vlog("init_usm -> try usm (mib) reconfigure", []), + snmp_user_based_sm_mib:reconfigure(Dir), + ?vlog("init_usm -> done", []), + ok; init_usm(_Vsn, _Dir) -> ok. +ensure_local_db_dead() -> + ensure_dead(whereis(snmpa_local_db), 2000). + +ensure_dead(Pid, Timeout) when is_pid(Pid) -> + MRef = erlang:monitor(process, Pid), + try + begin + ensure_dead_wait(Pid, MRef, Timeout), + ensure_dead_stop(Pid, MRef, Timeout), + ensure_dead_kill(Pid, MRef, Timeout), + exit(failed_stop_local_db) + end + catch + throw:ok -> + ok + end; +ensure_dead(_, _) -> + ?vlog("ensure_dead -> already dead", []), + ok. + +ensure_dead_wait(Pid, MRef, Timeout) -> + receive + {'DOWN', MRef, process, Pid, _Info} -> + ?vlog("ensure_dead_wait -> died peacefully", []), + throw(ok) + after Timeout -> + ?vlog("ensure_dead_wait -> giving up", []), + ok + end. + +ensure_dead_stop(Pid, MRef, Timeout) -> + StopPid = spawn(fun() -> snmpa_local_db:stop() end), + receive + {'DOWN', MRef, process, Pid, _Info} -> + ?vlog("ensure_dead -> dead (stopped)", []), + throw(ok) + after Timeout -> + ?vlog("ensure_dead_stop -> giving up", []), + exit(StopPid, kill), + ok + end. + +ensure_dead_kill(Pid, MRef, Timeout) -> + exit(Pid, kill), + receive + {'DOWN', MRef, process, Pid, _Info} -> + ?vlog("ensure_dead -> dead (killed)", []), + throw(ok) + after Timeout -> + ?vlog("ensure_dead_kill -> giving up", []), + ok + end. + + display_incomming_message(M) -> display_message("Incomming",M). @@ -775,20 +881,20 @@ display_prop_hdr(S) -> %%---------------------------------------------------------------------- sz(L) when is_list(L) -> - length(lists:flatten(L)); + iolist_size(L); sz(B) when is_binary(B) -> size(B); sz(O) -> {unknown_size, O}. d(F) -> d(F, []). -d(F,A) -> d(get(debug),F,A). +d(F,A) -> d(get(debug), F, A). -d(true,F,A) -> - io:format("*** [~s] MGR_PS_DBG *** " ++ F ++ "~n", - [formated_timestamp()|A]); +d(true, F, A) -> + print(F, A); d(_,_F,_A) -> ok. -formated_timestamp() -> - snmp_test_lib:formated_timestamp(). +print(F, A) -> + ?PRINT2("MGR_PS " ++ F, A). + diff --git a/lib/snmp/test/snmp_test_server.erl b/lib/snmp/test/snmp_test_server.erl index a77bdc142c..ab7dbbbaa0 100644 --- a/lib/snmp/test/snmp_test_server.erl +++ b/lib/snmp/test/snmp_test_server.erl @@ -207,7 +207,7 @@ do_subcases(Mod, Fun, [{conf, Init, Cases, Finish}|SubCases], Config, Acc) [{failed, {Mod, Fun}, Error}] end, do_subcases(Mod, Fun, SubCases, Config, [R|Acc]); -do_subcases(Mod, Fun, [SubCase|SubCases], Config, Acc) when atom(SubCase) -> +do_subcases(Mod, Fun, [SubCase|SubCases], Config, Acc) when is_atom(SubCase) -> R = do_case(Mod, SubCase, Config), do_subcases(Mod, Fun, SubCases,Config, [R|Acc]). @@ -407,7 +407,7 @@ d(_, _, _, _) -> ok. timestamp() -> - {Date, Time} = calendar:now_to_datetime( now() ), + {Date, Time} = calendar:now_to_datetime( erlang:timestamp() ), {YYYY, MM, DD} = Date, {Hour, Min, Sec} = Time, FormatDate = diff --git a/lib/snmp/test/snmp_test_sys_monitor.erl b/lib/snmp/test/snmp_test_sys_monitor.erl new file mode 100644 index 0000000000..2291c6ca97 --- /dev/null +++ b/lib/snmp/test/snmp_test_sys_monitor.erl @@ -0,0 +1,86 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2019-2019. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-module(snmp_test_sys_monitor). + +-export([start/0, stop/0, + init/1]). + +-define(NAME, ?MODULE). +-define(GSM, snmp_test_global_sys_monitor). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +start() -> + Parent = self(), + proc_lib:start(?MODULE, init, [Parent]). + +stop() -> + case whereis(?NAME) of + Pid when is_pid(Pid) -> + Pid ! {?MODULE, stop}, + ok; + _ -> + ok + end. + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +init(Parent) -> + process_flag(priority, high), + try register(?NAME, self()) of + true -> + global:sync(), + MonSettings = [ + busy_port, + busy_dist_port, + {long_gc, 1000}, + {long_schedule, 1000}, + {large_heap, 8*1024*1024} % 8 MB + ], + erlang:system_monitor(self(), MonSettings), + ?GSM:log({erlang:timestamp(), starting}), + proc_lib:init_ack(Parent, {ok, self()}), + loop(#{parent => Parent}) + catch + _:_:_ -> + ?GSM:log({erlang:timestamp(), already_started}), + proc_lib:init_ack(Parent, {error, already_started}), + exit(normal) + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +loop(State) -> + receive + {monitor, Pid, Tag, Info} -> + ?GSM:log({Pid, erlang:timestamp(), Tag, Info}), + loop(State); + + _ -> + loop(State) + end. + + + diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl index b83c7461d1..b8bdb30271 100644 --- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -247,9 +247,17 @@ erlang_agent_netsnmp_get(Config) when is_list(Config) -> start_agent(Config), Oid = ?sysDescr_instance, Expected = expected(Oid, get), - [Expected = snmpget(Oid, Transport, Config) - || Transport <- Transports], - ok. + try + begin + [Expected = snmpget(Oid, Transport, Config) + || Transport <- Transports], + ok + end + catch + throw:{skip, _} = SKIP -> + SKIP + end. + %%-------------------------------------------------------------------- erlang_manager_netsnmp_get() -> @@ -260,29 +268,34 @@ erlang_manager_netsnmp_get(Config) when is_list(Config) -> SysDescr = "Net-SNMP agent", TargetName = "Target Net-SNMP agent", Transports = ?config(transports, Config), - ProgHandle = start_snmpd(Community, SysDescr, Config), - start_manager(Config), - snmp_manager_user:start_link(self(), test_user), - [snmp_manager_user:register_agent( - TargetName++domain_suffix(Domain), - [{reg_type, target_name}, - {tdomain, Domain}, {taddress, Addr}, - {community, Community}, {engine_id, "EngineId"}, - {version, v2}, {sec_model, v2c}, {sec_level, noAuthNoPriv}]) - || {Domain, Addr} <- Transports], - Results = - [snmp_manager_user:sync_get( - TargetName++domain_suffix(Domain), - [?sysDescr_instance]) - || {Domain, _} <- Transports], - ct:pal("sync_get -> ~p", [Results]), - snmp_manager_user:stop(), - stop_program(ProgHandle), - [{ok, - {noError, 0, - [{varbind, ?sysDescr_instance, 'OCTET STRING', SysDescr,1}] }, - _} = R || R <- Results], - ok. + case start_snmpd(Community, SysDescr, Config) of + {skip, _} = SKIP -> + SKIP; + ProgHandle -> + start_manager(Config), + snmp_manager_user:start_link(self(), test_user), + [snmp_manager_user:register_agent( + TargetName++domain_suffix(Domain), + [{reg_type, target_name}, + {tdomain, Domain}, {taddress, Addr}, + {community, Community}, {engine_id, "EngineId"}, + {version, v2}, {sec_model, v2c}, {sec_level, noAuthNoPriv}]) + || {Domain, Addr} <- Transports], + Results = + [snmp_manager_user:sync_get( + TargetName++domain_suffix(Domain), + [?sysDescr_instance]) + || {Domain, _} <- Transports], + ct:pal("sync_get -> ~p", [Results]), + snmp_manager_user:stop(), + stop_program(ProgHandle), + [{ok, + {noError, 0, + [{varbind, ?sysDescr_instance, 'OCTET STRING', SysDescr,1}] }, + _} = R || R <- Results], + ok + end. + %%-------------------------------------------------------------------- erlang_agent_netsnmp_inform(Config) when is_list(Config) -> @@ -292,17 +305,19 @@ erlang_agent_netsnmp_inform(Config) when is_list(Config) -> start_agent(Config), ok = snmpa:load_mib(snmp_master_agent, filename:join(DataDir, Mib)), - ProgHandle = start_snmptrapd(Mib, Config), - - snmpa:send_notification( - snmp_master_agent, testTrapv22, {erlang_agent_test, self()}), - - receive - {snmp_targets, erlang_agent_test, Addresses} -> - ct:pal("Notification sent to: ~p~n", [Addresses]), - erlang_agent_netsnmp_inform_responses(Addresses) - end, - stop_program(ProgHandle). + case start_snmptrapd(Mib, Config) of + {skip, _} = SKIP -> + SKIP; + ProgHandle -> + snmpa:send_notification( + snmp_master_agent, testTrapv22, {erlang_agent_test, self()}), + receive + {snmp_targets, erlang_agent_test, Addresses} -> + ct:pal("Notification sent to: ~p~n", [Addresses]), + erlang_agent_netsnmp_inform_responses(Addresses) + end, + stop_program(ProgHandle) + end. erlang_agent_netsnmp_inform_responses([]) -> receive @@ -326,6 +341,7 @@ erlang_agent_netsnmp_inform_responses([Address | Addresses]) -> %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- + snmpget(Oid, Transport, Config) -> Versions = ?config(snmp_versions, Config), @@ -335,10 +351,14 @@ snmpget(Oid, Transport, Config) -> "-Cf", net_snmp_addr_str(Transport), oid_str(Oid)], - ProgHandle = start_program(snmpget, Args, none, Config), - {_, line, Line} = get_program_output(ProgHandle), - stop_program(ProgHandle), - Line. + case start_program(snmpget, Args, none, Config) of + {skip, _} = SKIP -> + throw(SKIP); + ProgHandle -> + {_, line, Line} = get_program_output(ProgHandle), + stop_program(ProgHandle), + Line + end. start_snmptrapd(Mibs, Config) -> DataDir = ?config(data_dir, Config), @@ -382,12 +402,13 @@ start_program(Prog, Args, StartCheckMP, Config) -> DataDir = ?config(data_dir, Config), StartWrapper = filename:join(DataDir, "start_stop_wrapper"), Parent = self(), - Pid = - spawn_link( + %% process_flag(trap_exit, true), + {Pid, Mon} = + spawn_monitor( fun () -> run_program(Parent, StartWrapper, [Path | Args]) end), - start_check(Pid, erlang:monitor(process, Pid), StartCheckMP). + start_check(Pid, Mon, StartCheckMP). start_check(Pid, Mon, none) -> {Pid, Mon}; @@ -400,6 +421,10 @@ start_check(Pid, Mon, StartCheckMP) -> nomatch -> start_check(Pid, Mon, StartCheckMP) end; + {'DOWN', Mon, _, _Pid, {skip, Reason} = SKIP} -> + ct:pal("Received DOWN from ~p" + "~n Skip Reason: ~p", [_Pid, Reason]), + SKIP; {'DOWN', Mon, _, _, Reason} -> ct:fail("Prog ~p start failed: ~p", [Pid, Reason]) end. @@ -446,14 +471,34 @@ run_program_loop(Parent, Port, Buf) -> {Port, {data, {Flag, Data}}} -> case Flag of eol -> - Line = iolist_to_binary(lists:reverse(Buf, Data)), - ct:pal("Prog ~p output: ~s", [Port, Line]), - Parent ! {self(), line, Line}, - run_program_loop(Parent, Port, []); + Line = iolist_to_binary(lists:reverse(Buf, Data)), + ct:pal("Prog ~p output: ~s", [Port, Line]), + %% There are potentially many different fail outputs, + %% but for now we test for just this one: illegal option + IOpt = "illegal option", + case string:find(binary_to_list(Line), IOpt) of + nomatch -> + Parent ! {self(), line, Line}, + run_program_loop(Parent, Port, []); + Line2 -> + %% Try to extract the actual illegal option string + IOpt2 = + case string:take( + string:prefix(Line2, IOpt), [$-, $ ]) of + {_, Str} when length(Str) > 0 -> + Str; + _X -> + Line2 + end, + ct:pal("Force program ~p stop", [Port]), + true = port_command(Port, <<"stop\n">>), + (catch port_close(Port)), + exit({skip, {illegal_option, IOpt2}}) + end; noeol -> run_program_loop(Parent, Port, [Data | Buf]) end; - {Port, {exit_status,ExitStatus}} -> + {Port, {exit_status, ExitStatus}} -> ct:pal("Prog ~p exit: ~p", [Port, ExitStatus]), catch port_close(Port), Parent ! {self(), exit, ExitStatus}; diff --git a/lib/snmp/test/test-mibs/ALARM-MIB.mib b/lib/snmp/test/test-mibs/ALARM-MIB.mib index 18e43d4b4b..10d2adbff9 100644 --- a/lib/snmp/test/test-mibs/ALARM-MIB.mib +++ b/lib/snmp/test/test-mibs/ALARM-MIB.mib @@ -330,7 +330,7 @@ alarmModelRowStatus OBJECT-TYPE cannot be used as an alarm suppression mechanism. Entries that are notInService will disappear as described in RFC2579. - This row can not be modified while it is being + This row cannot be modified while it is being referenced by a value of alarmActiveModelPointer. In these cases, an error of `inconsistentValue' will be returned to the manager. diff --git a/lib/snmp/test/test-mibs/SNMPv2-TC.mib b/lib/snmp/test/test-mibs/SNMPv2-TC.mib index fd6a728ab5..1d75c4bbd8 100644 --- a/lib/snmp/test/test-mibs/SNMPv2-TC.mib +++ b/lib/snmp/test/test-mibs/SNMPv2-TC.mib @@ -454,7 +454,7 @@ value | | see 1| ->C| ->D associated with this column or that there is no conceptual row for which this column would be accessible in the MIB view used by the retrieval. As - such, the management station can not issue any + such, the management station cannot issue any management protocol set operations to create an instance of this column. @@ -576,7 +576,7 @@ value | | see 1| ->C| ->D associated with this column or that there is no conceptual row for which this column would be accessible in the MIB view used by the retrieval. As - such, the management station can not issue any + such, the management station cannot issue any management protocol set operations to create an instance of this column. |