aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/snmp/test')
-rw-r--r--lib/snmp/test/Makefile2
-rw-r--r--lib/snmp/test/modules.mk2
-rw-r--r--lib/snmp/test/snmp_agent_test.erl61
-rw-r--r--lib/snmp/test/snmp_agent_test_lib.erl337
-rw-r--r--lib/snmp/test/snmp_manager_config_test.erl13
-rw-r--r--lib/snmp/test/snmp_manager_test.erl539
-rw-r--r--lib/snmp/test/snmp_test_global_sys_monitor.erl214
-rw-r--r--lib/snmp/test/snmp_test_lib.erl260
-rw-r--r--lib/snmp/test/snmp_test_lib.hrl21
-rw-r--r--lib/snmp/test/snmp_test_mgr.erl31
-rw-r--r--lib/snmp/test/snmp_test_mgr_misc.erl3
-rw-r--r--lib/snmp/test/snmp_test_server.erl4
-rw-r--r--lib/snmp/test/snmp_test_sys_monitor.erl86
-rw-r--r--lib/snmp/test/snmp_to_snmpnet_SUITE.erl143
14 files changed, 1291 insertions, 425 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 8b6547f9a9..ec3870dbd8 100644
--- a/lib/snmp/test/modules.mk
+++ b/lib/snmp/test/modules.mk
@@ -42,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 71e3fa3b9a..a45cfa9e98 100644
--- a/lib/snmp/test/snmp_agent_test.erl
+++ b/lib/snmp/test/snmp_agent_test.erl
@@ -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),
@@ -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() ->
@@ -6567,7 +6593,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_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl
index 6defdadb5a..c0da47dc4c 100644
--- a/lib/snmp/test/snmp_agent_test_lib.erl
+++ b/lib/snmp/test/snmp_agent_test_lib.erl
@@ -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,87 +276,197 @@ 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
- {done, {'EXIT', Rn}, Loc} ->
- ?DBG("call -> done with exit: "
- "~n Rn: ~p"
- "~n Loc: ~p", [Rn, Loc]),
+ {'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
+ {'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},
@@ -376,24 +486,45 @@ run(Mod, Func, Args, Opts) ->
{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(),
+ (catch snmp_test_mgr:stop()),
?line ?FAIL({mgr_start_error, Reason});
Err ->
?EPRINT2("Failed starting (test) manager: "
"~n ~p", [Err]),
- catch snmp_test_mgr:stop(),
+ (catch snmp_test_mgr:stop()),
?line ?FAIL({mgr_start_failure, Err})
end.
@@ -907,10 +1038,22 @@ expect2(Mod, Line, F) ->
%% ----------------------------------------------------------------------
-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
@@ -1083,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.
@@ -1184,7 +1339,7 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
io_format_expect("received unexpected pdu with (11) "
"~n Type: ~p"
"~n ReqId: ~p"
- "~n Errot status: ~p"
+ "~n Error status: ~p"
"~n Error index: ~p",
[Type2, ReqId, Err2, Idx2]),
{error,
@@ -1247,7 +1402,7 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
io_format_expect("received unexpected pdu with (15) "
"~n Type: ~p"
"~n ReqId: ~p"
- "~n Errot status: ~p"
+ "~n Error status: ~p"
"~n Error index: ~p"
"~n Varbinds: ~p",
[Type2, ReqId, Err2, Idx2, VBs2]),
@@ -1257,10 +1412,23 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To)
{Type2, Err2, Idx2, VBs2},
ReqId}};
- Error ->
- io_format_expect("received error (16): "
+
+ {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
+ Error
end.
@@ -1378,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]),
@@ -1701,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_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 5b0ebf8647..c31bb92e1f 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,7 +62,7 @@
register_user1/1,
- register_agent1/1,
+ register_agent_old/1,
register_agent2/1,
register_agent3/1,
@@ -185,7 +185,6 @@ end_per_suite(Config) when is_list(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
@@ -204,13 +203,15 @@ init_per_testcase(Case, Config) when is_list(Config) ->
Result =
case lists:member(Case, DeprecatedApiCases) of
true ->
- {skip, api_no_longer_supported};
+ {skip, "API no longer supported"};
false ->
try init_per_testcase2(Case, Config)
catch
- C:{skip, _} = E:_ when ((C =:= throw) orelse (C =:= exit)) ->
+ C:{skip, _} = E:_ when ((C =:= throw) orelse
+ (C =:= exit)) ->
E;
- C:E:_ when ((C =:= throw) orelse (C =:= exit)) ->
+ C:E:_ when ((C =:= throw) orelse
+ (C =:= exit)) ->
{skip, {catched, C, E}}
end
end,
@@ -479,7 +480,7 @@ groups() ->
},
{agent_tests, [],
[
- register_agent1,
+ register_agent_old,
register_agent2,
register_agent3
]
@@ -595,7 +596,7 @@ groups() ->
ipv6_tests() ->
[
- register_agent1,
+ register_agent_old,
simple_sync_get_next3,
simple_async_get2,
simple_sync_get3,
@@ -619,38 +620,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).
@@ -662,11 +672,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),
@@ -687,7 +697,6 @@ simple_start_and_stop1(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
@@ -695,9 +704,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(),
@@ -735,7 +745,6 @@ simple_start_and_stop2(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
@@ -743,8 +752,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),
@@ -788,7 +799,6 @@ simple_start_and_monitor_crash1(Config) when is_list(Config) ->
?FAIL(timeout)
end,
- p("end"),
ok.
@@ -796,8 +806,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),
@@ -842,7 +854,6 @@ simple_start_and_monitor_crash2(Config) when is_list(Config) ->
?FAIL(timeout)
end,
- p("end"),
ok.
@@ -888,8 +899,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),
@@ -976,37 +989,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),
@@ -1014,10 +1024,10 @@ 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"),
NumIterations = 5,
@@ -1047,8 +1057,14 @@ notify_started02(Config) when is_list(Config) ->
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({client, Reason1})
after ApproxStartTime + 10000 ->
@@ -1061,6 +1077,9 @@ 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({ctrl, Reason2})
after 5000 ->
@@ -1085,7 +1104,7 @@ ns02_client_await_approx_runtime(Pid) ->
"~n ~p", [Pid, Reason]),
{error, Reason}
- after 15000 ->
+ after 30000 ->
%% Either something is *really* wrong or this machine
%% is dog slow. Either way, this is a skip-reason...
{skip, approx_runtime_timeout}
@@ -1150,6 +1169,12 @@ ns02_ctrl(Opts, N) ->
p("starting"),
ns02_ctrl_loop(Opts, N).
+
+%% 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);
@@ -1157,19 +1182,45 @@ 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(),
+ ?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),
@@ -1197,7 +1248,6 @@ info(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
verify_info(Info) when is_list(Info) ->
@@ -1237,9 +1287,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(),
@@ -1313,7 +1364,6 @@ register_user1(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
verify_users([], []) ->
@@ -1331,14 +1381,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(),
@@ -1453,7 +1504,6 @@ register_agent1(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
@@ -1464,8 +1514,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(),
@@ -1598,7 +1650,6 @@ register_agent2(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
@@ -1610,8 +1661,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(),
@@ -1748,7 +1801,6 @@ register_agent3(Config) when is_list(Config) ->
?SLEEP(1000),
- p("end"),
ok.
@@ -1757,10 +1809,11 @@ register_agent3(Config) when is_list(Config) ->
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),
+ ?TC_TRY(simple_sync_get1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_sync_get1(Config) end).
- process_flag(trap_exit, true),
- put(tname, ssg1),
+do_simple_sync_get1(Config) ->
p("starting with Config: ~p~n", [Config]),
Node = ?config(manager_node, Config),
@@ -1819,18 +1872,18 @@ 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]),
@@ -1886,13 +1939,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,
@@ -1911,7 +1962,9 @@ do_simple_sync_get3(Config) ->
ok
end
end,
- do_simple_sync_get2(Config, Get, PostVerify).
+ do_simple_sync_get2(Config, Get, PostVerify),
+ display_log(Config),
+ ok.
%%======================================================================
@@ -1920,10 +1973,11 @@ 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),
+ ?TC_TRY(simple_async_get1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_async_get1(Config) end).
- process_flag(trap_exit, true),
- put(tname, sag1),
+do_simple_async_get1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -2024,8 +2078,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),
@@ -2105,8 +2161,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),
@@ -2137,10 +2195,11 @@ 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),
+ ?TC_TRY(simple_sync_get_next1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_sync_get_next1(Config) end).
- process_flag(trap_exit, true),
- put(tname, ssgn1),
+do_simple_sync_get_next1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -2278,8 +2337,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) ->
@@ -2431,10 +2492,11 @@ 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),
+ ?TC_TRY(simple_async_get_next1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_async_get_next1(Config) end).
- process_flag(trap_exit, true),
- put(tname, ssgn1),
+do_simple_async_get_next1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -2531,8 +2593,10 @@ 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),
@@ -2642,8 +2706,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),
@@ -2685,10 +2751,11 @@ 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),
+ ?TC_TRY(simple_sync_set1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_sync_set1(Config) end).
- process_flag(trap_exit, true),
- put(tname, sss1),
+do_simple_sync_set1(Config) ->
p("starting with Config: ~p~n", [Config]),
Node = ?config(manager_node, Config),
@@ -2758,8 +2825,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) ->
@@ -2828,8 +2897,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(),
@@ -2857,10 +2928,11 @@ 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),
+ ?TC_TRY(simple_async_set1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_async_set1(Config) end).
- process_flag(trap_exit, true),
- put(tname, sas1),
+do_simple_async_set1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -2952,8 +3024,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),
@@ -3025,8 +3099,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),
@@ -3069,10 +3145,11 @@ 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),
+ ?TC_TRY(simple_sync_get_bulk1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_sync_get_bulk1(Config) end).
- process_flag(trap_exit, true),
- put(tname, ssgb1),
+do_simple_sync_get_bulk1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3243,8 +3320,10 @@ 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),
@@ -3399,8 +3478,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),
@@ -3436,10 +3517,11 @@ 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),
+ ?TC_TRY(simple_async_get_bulk1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_simple_async_get_bulk1(Config) end).
- process_flag(trap_exit, true),
- put(tname, sagb1),
+do_simple_async_get_bulk1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3582,8 +3664,10 @@ 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),
@@ -3738,8 +3822,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),
@@ -3782,10 +3868,11 @@ 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),
+ ?TC_TRY(misc_async1,
+ fun() -> {skip, "API no longer supported"} end,
+ fun() -> do_misc_async1(Config) end).
- process_flag(trap_exit, true),
- put(tname, ms1),
+do_misc_async1(Config) ->
p("starting with Config: ~p~n", [Config]),
MgrNode = ?config(manager_node, Config),
@@ -3974,8 +4061,10 @@ 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),
@@ -4224,8 +4313,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),
@@ -4377,8 +4468,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),
@@ -4570,8 +4663,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),
@@ -4697,8 +4792,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),
@@ -4832,7 +4929,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}
@@ -4869,8 +4966,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),
@@ -4966,7 +5065,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]),
@@ -5005,8 +5104,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),
@@ -5125,8 +5226,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),
@@ -5253,7 +5356,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]),
@@ -5272,7 +5375,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}},
@@ -5297,8 +5400,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),
@@ -5345,8 +5450,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).
@@ -5449,10 +5556,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.
@@ -6318,6 +6425,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, [[]]} ->
@@ -6328,30 +6437,47 @@ start_node(Name) ->
""
end,
A = Args ++ " -pa " ++ Pa,
- case (catch ?START_NODE(Name, A)) of
+ try ?START_NODE(Name, A) of
{ok, Node} ->
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.
@@ -6596,12 +6722,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 a483690653..26b68501e2 100644
--- a/lib/snmp/test/snmp_test_lib.erl
+++ b/lib/snmp/test/snmp_test_lib.erl
@@ -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,114 @@
-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, print1/2, print2/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 ->
+ tc_end( f("failed(catched,~w,tc)", [C]) ),
+ erlang:raise(C, E, S)
+ end;
+ {skip, _} = SKIP ->
+ tc_end("skipping(tc)"),
+ SKIP;
+ {error, Reason} ->
+ tc_end("failed(tc)"),
+ 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 ->
+ tc_end( f("failed(catched,~w,cond)", [C]) ),
+ erlang:raise(C, E, S)
+ 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,11 +152,12 @@ hostname() ->
hostname(node()).
hostname(Node) ->
- from($@, atom_to_list(Node)).
-
-from(H, [H | T]) -> T;
-from(H, [_ | T]) -> from(H, T);
-from(_H, []) -> [].
+ case string:tokens(atom_to_list(Node), [$@]) of
+ [_, Host] ->
+ Host;
+ _ ->
+ []
+ end.
%% localhost() ->
%% {ok, Ip} = snmp_misc:ip(net_adm:localhost()),
@@ -78,7 +179,9 @@ localhost(Family) ->
{error, Reason1} ->
fail({getifaddrs, Reason1}, ?MODULE, ?LINE)
end;
- {ok, {0, _, _, _, _, _, _, _}} when (Family =:= inet6) ->
+ {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} ->
@@ -197,63 +300,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.
%% ----------------------------------------------------------------
@@ -452,10 +613,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
%%
@@ -648,6 +813,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 ->
diff --git a/lib/snmp/test/snmp_test_lib.hrl b/lib/snmp/test/snmp_test_lib.hrl
index 335f3fff3c..f077f15d3e 100644
--- a/lib/snmp/test/snmp_test_lib.hrl
+++ b/lib/snmp/test/snmp_test_lib.hrl
@@ -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 -
@@ -150,8 +153,10 @@
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 73a4d56084..9d6be65088 100644
--- a/lib/snmp/test/snmp_test_mgr.erl
+++ b/lib/snmp/test/snmp_test_mgr.erl
@@ -52,6 +52,7 @@
-include_lib("snmp/include/snmp_types.hrl").
-include_lib("snmp/include/STANDARD-MIB.hrl").
-include("snmp_test_lib.hrl").
+-include_lib("snmp/src/app/snmp_internal.hrl").
-record(state, {dbg = true,
quiet,
@@ -192,9 +193,11 @@ 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)),
@@ -244,10 +247,21 @@ init({Options, CallerPid}) ->
IpFamily = get_value(ipfamily, Options, inet),
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,
@@ -668,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) ->
@@ -1141,5 +1154,5 @@ d(_,_F,_A) ->
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 315e3ebd9e..6608a88c00 100644
--- a/lib/snmp/test/snmp_test_mgr_misc.erl
+++ b/lib/snmp/test/snmp_test_mgr_misc.erl
@@ -576,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: "
@@ -880,7 +881,7 @@ 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) ->
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};