diff options
Diffstat (limited to 'lib/snmp')
28 files changed, 656 insertions, 391 deletions
diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl index 9fd7b30f9f..984b0bcee1 100644 --- a/lib/snmp/src/agent/snmp_community_mib.erl +++ b/lib/snmp/src/agent/snmp_community_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2016. All Rights Reserved. +%% Copyright Ericsson AB 1999-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. @@ -206,10 +206,10 @@ do_add_community(Community) -> {error, create_failed} end catch - {error, Reason} -> - {error, Reason}; - Class:Reason -> - {error, {Class, Reason, erlang:get_stacktrace()}} + throw:{error, _} = ERROR -> + ERROR; + C:E:S -> + {error, {C, E, S}} end. %% FIXME: does not work with mnesia diff --git a/lib/snmp/src/agent/snmp_generic.erl b/lib/snmp/src/agent/snmp_generic.erl index e67a1b3c80..26a0dd0648 100644 --- a/lib/snmp/src/agent/snmp_generic.erl +++ b/lib/snmp/src/agent/snmp_generic.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2017. 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. @@ -421,12 +421,12 @@ table_check_status(NameDb, Col, ?'RowStatus_createAndGo', RowIndex, Cols) -> _Found -> {inconsistentValue, Col} end catch - _:_Reason -> + _:_E:_S -> ?vtrace( "failed construct row (createAndGo): " - " n Reason: ~p" - " n Stack: ~p", - [_Reason, erlang:get_stacktrace()]), + " n Error: ~p" + " n Stack: ~p", + [_E, _S]), {noCreation, Col} % Bad RowIndex end; true -> {inconsistentValue, Col} @@ -441,12 +441,12 @@ table_check_status(NameDb, Col, ?'RowStatus_createAndWait', RowIndex, Cols) -> _Row -> {noError, 0} catch - _:_Reason -> + _:_E:_S -> ?vtrace( "failed construct row (createAndWait): " - " n Reason: ~p" - " n Stack: ~p", - [_Reason, erlang:get_stacktrace()]), + " n Error: ~p" + " n Stack: ~p", + [_E, _S]), {noCreation, Col} % Bad RowIndex end; true -> {inconsistentValue, Col} diff --git a/lib/snmp/src/agent/snmp_standard_mib.erl b/lib/snmp/src/agent/snmp_standard_mib.erl index bfe471178d..679d2657c6 100644 --- a/lib/snmp/src/agent/snmp_standard_mib.erl +++ b/lib/snmp/src/agent/snmp_standard_mib.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. @@ -27,6 +27,7 @@ -include("snmp_types.hrl"). -include("STANDARD-MIB.hrl"). +-include("snmpa_internal.hrl"). -define(VMODULE,"STANDARD-MIB"). -include("snmp_verbosity.hrl"). @@ -547,10 +548,12 @@ dummy(_Op) -> ok. %%----------------------------------------------------------------- snmp_set_serial_no(new) -> snmp_generic:variable_func(new, {snmpSetSerialNo, volatile}), - random:seed(erlang:phash2([node()]), - erlang:monotonic_time(), - erlang:unique_integer()), - Val = random:uniform(2147483648) - 1, + ?SNMP_RAND_SEED(), + %% rand:seed(exrop, + %% {erlang:phash2([node()]), + %% erlang:monotonic_time(), + %% erlang:unique_integer()}), + Val = rand:uniform(2147483648) - 1, snmp_generic:variable_func(set, Val, {snmpSetSerialNo, volatile}); snmp_set_serial_no(delete) -> diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index e65fa7f340..22fd3acb84 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2015. All Rights Reserved. +%% Copyright Ericsson AB 1998-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. @@ -42,6 +42,7 @@ -define(VMODULE,"TARGET-MIB"). -include("snmp_verbosity.hrl"). +-include("snmpa_internal.hrl"). %% Column not accessible via SNMP - needed when the agent sends informs @@ -673,10 +674,12 @@ snmpTargetSpinLock(print) -> snmpTargetSpinLock(new) -> snmp_generic:variable_func(new, {snmpTargetSpinLock, volatile}), - random:seed(erlang:phash2([node()]), - erlang:monotonic_time(), - erlang:unique_integer()), - Val = random:uniform(2147483648) - 1, + ?SNMP_RAND_SEED(), + %% rand:seed(exrop, + %% {erlang:phash2([node()]), + %% erlang:monotonic_time(), + %% erlang:unique_integer()}), + Val = rand:uniform(2147483648) - 1, snmp_generic:variable_func(set, Val, {snmpTargetSpinLock, volatile}); snmpTargetSpinLock(delete) -> diff --git a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl index f6e4fd3951..4842669fa4 100644 --- a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl +++ b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2015. All Rights Reserved. +%% Copyright Ericsson AB 1999-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. @@ -440,10 +440,12 @@ usmUserSpinLock(print) -> usmUserSpinLock(new) -> snmp_generic:variable_func(new, {usmUserSpinLock, volatile}), - random:seed(erlang:phash2([node()]), - erlang:monotonic_time(), - erlang:unique_integer()), - Val = random:uniform(2147483648) - 1, + ?SNMP_RAND_SEED(), + %% rand:seed(exrop, + %% {erlang:phash2([node()]), + %% erlang:monotonic_time(), + %% erlang:unique_integer()}), + Val = rand:uniform(2147483648) - 1, snmp_generic:variable_func(set, Val, {usmUserSpinLock, volatile}); usmUserSpinLock(delete) -> diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl index c6eeb7cea2..56b5d96142 100644 --- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl +++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl @@ -48,6 +48,7 @@ -include("SNMPv2-TC.hrl"). -include("SNMP-VIEW-BASED-ACM-MIB.hrl"). -include("snmpa_vacm.hrl"). +-include("snmpa_internal.hrl"). -define(VMODULE,"VACM-MIB"). @@ -860,10 +861,12 @@ vacmViewSpinLock(print) -> vacmViewSpinLock(new) -> snmp_generic:variable_func(new, volatile_db(vacmViewSpinLock)), - random:seed(erlang:phash2([node()]), - erlang:monotonic_time(), - erlang:unique_integer()), - Val = random:uniform(2147483648) - 1, + ?SNMP_RAND_SEED(), + %% rand:seed(exrop, + %% {erlang:phash2([node()]), + %% erlang:monotonic_time(), + %% erlang:unique_integer()}), + Val = rand:uniform(2147483648) - 1, snmp_generic:variable_func(set, Val, volatile_db(vacmViewSpinLock)); vacmViewSpinLock(delete) -> diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index b440d57d03..2ec5dcb5e6 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2015. All Rights Reserved. +%% Copyright Ericsson AB 1997-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. @@ -76,11 +76,9 @@ init(Vsns) -> ?vlog("init -> entry with" "~n Vsns: ~p", [Vsns]), - random:seed(erlang:phash2([node()]), - erlang:monotonic_time(), - erlang:unique_integer()), - ets:insert(snmp_agent_table, {msg_id, random:uniform(2147483647)}), - ets:insert(snmp_agent_table, {req_id, random:uniform(2147483647)}), + ?SNMP_RAND_SEED(), + ets:insert(snmp_agent_table, {msg_id, rand:uniform(2147483647)}), + ets:insert(snmp_agent_table, {req_id, rand:uniform(2147483647)}), init_counters(), init_versions(Vsns, #state{}). diff --git a/lib/snmp/src/agent/snmpa_set.erl b/lib/snmp/src/agent/snmpa_set.erl index 9833d6fdcc..b3a3bf0ab0 100644 --- a/lib/snmp/src/agent/snmpa_set.erl +++ b/lib/snmp/src/agent/snmpa_set.erl @@ -163,10 +163,14 @@ set_phase_two(MyVarbinds, SubagentVarbinds) -> [MyVarbinds, SubagentVarbinds]), case snmpa_set_lib:try_set(MyVarbinds) of {noError, 0} -> + ?vtrace("set phase two: (local) varbinds set ok", []), set_phase_two_subagents(SubagentVarbinds); - {ErrorStatus, Index} -> + {ErrorStatus, ErrorIndex} -> + ?vlog("set phase two: (local) varbinds set failed" + "~n ErrorStatus: ~p" + "~n ErrorIndex: ~p", [ErrorStatus, ErrorIndex]), set_phase_two_undo_subagents(SubagentVarbinds), - {ErrorStatus, Index} + {ErrorStatus, ErrorIndex} end. %%----------------------------------------------------------------- @@ -188,6 +192,7 @@ set_phase_two_subagents([{SubAgentPid, SAVbs} | SubagentVarbinds]) -> {_SAOids, Vbs} = sa_split(SAVbs), case catch snmpa_agent:subagent_set(SubAgentPid, [phase_two, set, Vbs]) of {noError, 0} -> + ?vtrace("set phase two: subagent ~p varbinds set ok", [SubAgentPid]), set_phase_two_subagents(SubagentVarbinds); {'EXIT', Reason} -> user_err("Lost contact with subagent (set)~n~w. Using genErr", @@ -195,10 +200,14 @@ set_phase_two_subagents([{SubAgentPid, SAVbs} | SubagentVarbinds]) -> set_phase_two_undo_subagents(SubagentVarbinds), {genErr, 0}; {ErrorStatus, ErrorIndex} -> + ?vlog("set phase two: subagent ~p varbinds set failed" + "~n ErrorStatus: ~p" + "~n ErrorIndex: ~p", [SubAgentPid, ErrorStatus, ErrorIndex]), set_phase_two_undo_subagents(SubagentVarbinds), {ErrorStatus, ErrorIndex} end; set_phase_two_subagents([]) -> + ?vtrace("set phase two: subagent(s) set ok", []), {noError, 0}. %%----------------------------------------------------------------- diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index d04b6a206e..f741c3aaa9 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.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. @@ -364,13 +364,14 @@ send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, LocalEngineID, ExtraInfo, NetIf) end catch - T:E -> - Info = [{args, [TrapRec, NotifyName, ContextName, - Recv, Vbs, LocalEngineID, ExtraInfo, NetIf]}, - {tag, T}, - {err, E}, - {stacktrace, erlang:get_stacktrace()}], - ?vlog("snmpa_trap:send_trap exception: ~p", [Info]), + C:E:S -> + Info = [{args, [TrapRec, NotifyName, ContextName, + Recv, Vbs, LocalEngineID, ExtraInfo, NetIf]}, + {class, C}, + {err, E}, + {stacktrace, S}], + ?vlog("snmpa_trap:send_trap exception: " + "~n ~p", [Info]), {error, {failed_sending_trap, Info}} end. diff --git a/lib/snmp/src/agent/snmpa_usm.erl b/lib/snmp/src/agent/snmpa_usm.erl index fb616cd9ef..1debceae98 100644 --- a/lib/snmp/src/agent/snmpa_usm.erl +++ b/lib/snmp/src/agent/snmpa_usm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2015. All Rights Reserved. +%% Copyright Ericsson AB 1999-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. @@ -646,10 +646,12 @@ get_des_salt() -> ets:insert(snmp_agent_table, {usm_des_salt, 0}), 0; _ -> % it doesn't exist, initialize - random:seed(erlang:phash2([node()]), - erlang:monotonic_time(), - erlang:unique_integer()), - R = random:uniform(4294967295), + ?SNMP_RAND_SEED(), + %% rand:seed(exrop, + %% {erlang:phash2([node()]), + %% erlang:monotonic_time(), + %% erlang:unique_integer()}), + R = rand:uniform(4294967295), ets:insert(snmp_agent_table, {usm_des_salt, R}), R end, @@ -679,10 +681,12 @@ get_aes_salt() -> ets:insert(snmp_agent_table, {usm_aes_salt, 0}), 0; _ -> % it doesn't exist, initialize - random:seed(erlang:phash2([node()]), - erlang:monotonic_time(), - erlang:unique_integer()), - R = random:uniform(36893488147419103231), + ?SNMP_RAND_SEED(), + %% rand:seed(exrop, + %% {erlang:phash2([node()]), + %% erlang:monotonic_time(), + %% erlang:unique_integer()}), + R = rand:uniform(36893488147419103231), ets:insert(snmp_agent_table, {usm_aes_salt, R}), R end, diff --git a/lib/snmp/src/app/snmp_internal.hrl b/lib/snmp/src/app/snmp_internal.hrl index 374767df15..f9a758ab7b 100644 --- a/lib/snmp/src/app/snmp_internal.hrl +++ b/lib/snmp/src/app/snmp_internal.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2016. All Rights Reserved. +%% Copyright Ericsson AB 2006-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. @@ -25,7 +25,12 @@ -define(APPLICATION, snmp). -endif. --define(STACK(), erlang:get_stacktrace()). + +-define(SNMP_RAND_SEED_ALG, exrop). +-define(SNMP_RAND_SEED(), rand:seed(?SNMP_RAND_SEED_ALG, + {erlang:phash2([node()]), + erlang:monotonic_time(), + erlang:unique_integer()})). -define(snmp_info(C, F, A), ?snmp_msg(info_msg, C, F, A)). -define(snmp_warning(C, F, A), ?snmp_msg(warning_msg, C, F, A)). @@ -39,5 +44,3 @@ -endif. % -ifdef(snmp_internal). - - diff --git a/lib/snmp/src/compile/Makefile b/lib/snmp/src/compile/Makefile index 4093ffa9ca..d9678669a5 100644 --- a/lib/snmp/src/compile/Makefile +++ b/lib/snmp/src/compile/Makefile @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2016. All Rights Reserved. +# Copyright Ericsson AB 1997-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. @@ -59,6 +59,8 @@ PARSER_TARGET = $(PARSER_MODULE).$(EMULATOR) # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- +ERL_COMPILE_FLAGS += -pa $(ERL_TOP)/lib/snmp/ebin + ifeq ($(WARN_UNUSED_VARS),true) ERL_COMPILE_FLAGS += +warn_unused_vars endif diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl index c810bfcd41..4249799195 100644 --- a/lib/snmp/src/compile/snmpc.erl +++ b/lib/snmp/src/compile/snmpc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2018. All Rights Reserved. +%% Copyright Ericsson AB 1997-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. @@ -31,6 +31,7 @@ -export([init/3]). -include_lib("stdlib/include/erl_compile.hrl"). +-include_lib("snmp/src/app/snmp_internal.hrl"). -include("snmp_types.hrl"). -include("snmpc.hrl"). -include("snmpc_lib.hrl"). @@ -413,9 +414,11 @@ get_verbosity(Options) -> %%---------------------------------------------------------------------- init(From, MibFileName, Options) -> - 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()}), put(options, Options), put(verbosity, get_verbosity(Options)), put(description, get_description(Options)), diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index 118cdcd1df..cd9fecd4d4 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.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. @@ -479,10 +479,7 @@ agent_info(Domain, Address, Item) when is_atom(Domain) -> NAddress -> do_agent_info(Domain, NAddress, Item) catch - _Thrown -> - %% p(?MODULE_STRING":agent_info(~p, ~p, ~p) throwed ~p at.~n" - %% " ~p", - %% [Domain, Address, Item, _Thrown, erlang:get_stacktrace()]), + _C:_E:_S -> {error, not_found} end; agent_info(Ip, Port, Item) when is_integer(Port) -> @@ -493,10 +490,7 @@ agent_info(Ip, Port, Item) when is_integer(Port) -> Address -> do_agent_info(Domain, Address, Item) catch - _Thrown -> - %% p(?MODULE_STRING":agent_info(~p, ~p, ~p) throwed ~p at.~n" - %% " ~p", - %% [Ip, Port, Item, _Thrown, erlang:get_stacktrace()]), + _C:_E:_S -> {error, not_found} end. @@ -1688,9 +1682,10 @@ read_agents_config_file(Dir) -> Check = fun check_agent_config/2, try read_file(Dir, "agents.conf", Order, Check, []) catch - throw:Error -> - ?vlog("agent config error: ~p", [Error]), - erlang:raise(throw, Error, erlang:get_stacktrace()) + throw:E:S -> + ?vlog("agent config error: " + "~n ~p", [E]), + erlang:raise(throw, E, S) end. check_agent_config(Agent, State) -> @@ -1935,9 +1930,10 @@ read_users_config_file(Dir) -> Check = fun (User, State) -> {check_user_config(User), State} end, try read_file(Dir, "users.conf", Order, Check, []) catch - throw:Error -> - ?vlog("failure reading users config file: ~n ~p", [Error]), - erlang:raise(throw, Error, erlang:get_stacktrace()) + throw:E:S -> + ?vlog("failure reading users config file: " + "~n ~p", [E]), + erlang:raise(throw, E, S) end. check_user_config({Id, Mod, Data}) -> @@ -2351,10 +2347,11 @@ read_file(Dir, FileName, Order, Check, Default) -> read_file(Dir, FileName, Order, Check) -> try snmp_conf:read(filename:join(Dir, FileName), Order, Check) catch - throw:{error, Reason} = Error + throw:{error, Reason} = E:S when element(1, Reason) =:= failed_open -> - error_msg("failed reading config from ~s: ~p", [FileName, Reason]), - erlang:raise(throw, Error, erlang:get_stacktrace()) + error_msg("failed reading config from ~s: " + "~n ~p", [FileName, Reason]), + erlang:raise(throw, E, S) end. %%-------------------------------------------------------------------- diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl index 191dc2c281..8d0a7918a6 100644 --- a/lib/snmp/src/manager/snmpm_mpd.erl +++ b/lib/snmp/src/manager/snmpm_mpd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2015. 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. @@ -68,11 +68,13 @@ %%%----------------------------------------------------------------- init(Vsns) -> ?vdebug("init -> entry with ~p", [Vsns]), - random:seed(erlang:phash2([node()]), - erlang:monotonic_time(), - erlang:unique_integer()), - snmpm_config:cre_counter(msg_id, random:uniform(2147483647)), - snmpm_config:cre_counter(req_id, random:uniform(2147483647)), + ?SNMP_RAND_SEED(), + %% rand:seed(exrop, + %% {erlang:phash2([node()]), + %% erlang:monotonic_time(), + %% erlang:unique_integer()}), + snmpm_config:cre_counter(msg_id, rand:uniform(2147483647)), + snmpm_config:cre_counter(req_id, rand:uniform(2147483647)), init_counters(), State = init_versions(Vsns, #state{}), init_usm(State#state.v3), diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl index 29216f9d6a..184f782860 100644 --- a/lib/snmp/src/manager/snmpm_net_if.erl +++ b/lib/snmp/src/manager/snmpm_net_if.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2017. 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. @@ -182,11 +182,9 @@ worker(Worker, Failer, #state{log = Log} = State) -> %% Winds up in handle_info {'DOWN', ...} erlang:exit({net_if_worker, Result}) catch - Class:Reason -> + C:E:S -> %% Winds up in handle_info {'DOWN', ...} - erlang:exit( - {net_if_worker, Failer, - Class, Reason, erlang:get_stacktrace()}) + erlang:exit({net_if_worker, Failer, C, E, S}) end end, [monitor]). @@ -983,11 +981,10 @@ udp_send(Sock, To, Msg) -> error_msg("failed sending message to ~p:~p:~n" " ~p",[IpAddr, IpPort, Reason]) catch - error:Error -> - error_msg("failed sending message to ~p:~p:~n" - " error:~p~n" - " ~p", - [IpAddr, IpPort, Error, erlang:get_stacktrace()]) + error:E:S -> + error_msg("failed sending message to ~p:~p:" + "~n ~p" + "~n ~p", [IpAddr, IpPort, E, S]) end. sz(B) when is_binary(B) -> diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl index c8d7fa1e8b..a6ca2b2b14 100644 --- a/lib/snmp/src/manager/snmpm_server.erl +++ b/lib/snmp/src/manager/snmpm_server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2015. 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. @@ -1755,9 +1755,10 @@ handle_error(_UserId, Mod, Reason, ReqId, Data, _State) -> Mod:handle_error(ReqId, Reason, Data) end catch - T:E -> + C:E:S -> CallbackArgs = [ReqId, Reason, Data], - handle_invalid_result(handle_error, CallbackArgs, T, E) + handle_invalid_result(handle_error, CallbackArgs, + C, E, S) end end, handle_callback(F), @@ -1948,9 +1949,10 @@ handle_pdu( Mod:handle_pdu(TargetName, ReqId, SnmpResponse, Data) end catch - T:E -> + C:E:S -> CallbackArgs = [TargetName, ReqId, SnmpResponse, Data], - handle_invalid_result(handle_pdu, CallbackArgs, T, E) + handle_invalid_result(handle_pdu, CallbackArgs, + C, E, S) end end, handle_callback(F), @@ -2119,10 +2121,10 @@ do_handle_agent(DefUserId, DefMod, "<~p,~p>: ~n~w", [Type, Domain, Addr, SnmpInfo]) end; - T:E -> + C:E:S -> CallbackArgs = [Domain_or_Ip, Addr_or_Port, Type, SnmpInfo, DefData], - handle_invalid_result(handle_agent, CallbackArgs, T, E) + handle_invalid_result(handle_agent, CallbackArgs, C, E, S) end. @@ -2331,8 +2333,8 @@ do_handle_trap( handle_invalid_result(handle_trap, CallbackArgs, InvalidResult) catch - T:E -> - handle_invalid_result(handle_trap, CallbackArgs, T, E) + C:E:S -> + handle_invalid_result(handle_trap, CallbackArgs, C, E, S) end. @@ -2523,8 +2525,8 @@ do_handle_inform( reply catch - T:E -> - handle_invalid_result(handle_inform, CallbackArgs, T, E), + C:E:S -> + handle_invalid_result(handle_inform, CallbackArgs, C, E, S), reply end, @@ -2837,8 +2839,8 @@ do_handle_report( reply catch - T:E -> - handle_invalid_result(handle_report, CallbackArgs, T, E), + C:E:S -> + handle_invalid_result(handle_report, CallbackArgs, C, E, S), reply end. @@ -2855,15 +2857,14 @@ handle_callback(F) -> -handle_invalid_result(Func, Args, T, E) -> - Stacktrace = ?STACK(), +handle_invalid_result(Func, Args, C, E, S) -> error_msg("Callback function failed: " "~n Function: ~p" "~n Args: ~p" - "~n Error Type: ~p" + "~n Class: ~p" "~n Error: ~p" "~n Stacktrace: ~p", - [Func, Args, T, E, Stacktrace]). + [Func, Args, C, E, S]). handle_invalid_result(Func, Args, InvalidResult) -> error_msg("Callback function returned invalid result: " diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 513616a285..d73291764d 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.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. @@ -236,15 +236,16 @@ read_check(File, Check, [{StartLine, Row, EndLine}|Lines], State, Res) -> " NewRow: ~p~n", [NewRow]), read_check(File, Check, Lines, NewState, [NewRow | Res]) catch - {error, Reason} -> - ?vtrace("read_check -> error:~n" - " Reason: ~p", [Reason]), + throw:{error, Reason} -> + ?vtrace("read_check -> error:" + "~n Reason: ~p", [Reason]), error({failed_check, File, StartLine, EndLine, Reason}); - Class:Reason -> - Error = {Class,Reason,erlang:get_stacktrace()}, - ?vtrace("read_check -> failure:~n" - " Error: ~p", [Error]), - error({failed_check, File, StartLine, EndLine, Error}) + C:E:S -> + ?vtrace("read_check -> failure:" + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + error({failed_check, File, StartLine, EndLine, {C, E, S}}) end. open_file(File) -> diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 45661b71a7..26e85897f4 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.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. @@ -2573,15 +2573,17 @@ write_config_file(Dir, FileName, Order, Check, Write, Entries) Error end catch - Error -> - S = erlang:get_stacktrace(), - d("File write of ~s throwed: ~p~n ~p~n", - [FileName, Error, S]), - Error; - C:E -> - S = erlang:get_stacktrace(), - d("File write of ~s exception: ~p:~p~n ~p~n", - [FileName,C,E,S]), + throw:E:S -> + d("File write of ~s throwed: " + "~n ~p" + "~n ~p" + "~n", [FileName, E, S]), + E; + C:E:S -> + d("File write of ~s exception: " + "~n ~p:~p" + "~n ~p" + "~n", [FileName, C, E, S]), {error, {failed_write, Dir, FileName, {C, E, S}}} end. @@ -2590,16 +2592,18 @@ write_config_file(Dir, FileName, Write, Entries, Fd) -> ok -> close_config_file(Dir, FileName, Fd) catch - Error -> - S = erlang:get_stacktrace(), - d("File write of ~s throwed: ~p~n ~p~n", - [FileName, Error, S]), + throw:E:S -> + d("File write of ~s throwed: " + "~n ~p" + "~n ~p" + "~n", [FileName, E, S]), close_config_file(Dir, FileName, Fd), - Error; - C:E -> - S = erlang:get_stacktrace(), - d("File write of ~s exception: ~p:~p~n ~p~n", - [FileName,C,E,S]), + E; + C:E:S -> + d("File write of ~s exception: " + "~n ~p:~p" + "~n ~p" + "~n", [FileName, C, E, S]), close_config_file(Dir, FileName, Fd), {error, {failed_write, Dir, FileName, {C, E, S}}} end. @@ -2661,16 +2665,18 @@ append_config_file(Dir, FileName, Order, Check, Write, Entries, Fd) -> ok -> close_config_file(Dir, FileName, Fd) catch - Error -> - S = erlang:get_stacktrace(), - d("File append of ~s throwed: ~p~n ~p~n", - [FileName, Error, S]), + throw:E:S -> + d("File append of ~s throwed: " + "~n ~p" + "~n ~p" + "~n", [FileName, E, S]), close_config_file(Dir, FileName, Fd), - Error; - C:E -> - S = erlang:get_stacktrace(), - d("File append of ~s exception: ~p:~p~n ~p~n", - [FileName,C,E,S]), + E; + C:E:S -> + d("File append of ~s exception: " + "~n ~p:~p" + "~n ~p" + "~n", [FileName, C, E, S]), close_config_file(Dir, FileName, Fd), {error, {failed_append, Dir, FileName, {C, E, S}}} end. @@ -2702,16 +2708,18 @@ read_config_file(Dir, FileName, Order, Check) SortedLines = sort_lines(Lines, Order), {ok, verify_lines(SortedLines, Check, undefined, [])} catch - Error -> - S = erlang:get_stacktrace(), - d("File read of ~s throwed: ~p~n ~p~n", - [FileName, Error, S]), - {error, Error}; - T:E -> - S = erlang:get_stacktrace(), - d("File read of ~s exception: ~p:~p~n ~p~n", - [FileName,T,E,S]), - {error, {failed_read, Dir, FileName, {T, E, S}}} + throw:E:S -> + d("File read of ~s throwed: " + "~n ~p" + "~n ~p" + "~n", [FileName, E, S]), + {error, E}; + C:E:S -> + d("File read of ~s exception: " + "~n ~p:~p" + "~n ~p" + "~n", [FileName, C, E, S]), + {error, {failed_read, Dir, FileName, {C, E, S}}} after file:close(Fd) end; @@ -2760,11 +2768,10 @@ verify_lines( {{ok, NewTerm}, NewState} -> verify_lines(Lines, Check, NewState, [NewTerm|Acc]) catch - {error, Reason} -> + throw:{error, Reason}:_ -> throw({failed_check, StartLine, EndLine, Reason}); - C:R -> - S = erlang:get_stacktrace(), - throw({failed_check, StartLine, EndLine, {C, R, S}}) + C:E:S -> + throw({failed_check, StartLine, EndLine, {C, E, S}}) end. diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 71e3fa3b9a..860ca17cdb 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -667,22 +667,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) -> diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index 6defdadb5a..1128fc8a8c 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,36 +276,94 @@ 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]), + exit({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 -> + 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} -> + ?EPRINT2("TC runner failed: " + "~n ~p~n", [Reason]), + exit({tx_runner_failed, 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); @@ -314,49 +372,66 @@ call(N,M,F,A) -> 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)}, + exit(Res). + +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}, @@ -377,23 +452,23 @@ run(Mod, Func, Args, Opts) -> {ok, _Pid} -> case (catch apply(Mod, Func, Args)) of {'EXIT', Reason} -> - catch snmp_test_mgr:stop(), + (catch snmp_test_mgr:stop()), ?FAIL({apply_failed, {Mod, Func, Args}, Reason}); 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. 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..d959d9e09b 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -619,38 +619,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). diff --git a/lib/snmp/test/snmp_test_lib.erl b/lib/snmp/test/snmp_test_lib.erl index a483690653..42f710e4cd 100644 --- a/lib/snmp/test/snmp_test_lib.erl +++ b/lib/snmp/test/snmp_test_lib.erl @@ -25,7 +25,9 @@ -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, @@ -52,11 +54,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 +81,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} -> @@ -207,53 +212,108 @@ non_pc_tc_maybe_skip(Config, Condition, File, Line) 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. %% ---------------------------------------------------------------- diff --git a/lib/snmp/test/snmp_test_lib.hrl b/lib/snmp/test/snmp_test_lib.hrl index 335f3fff3c..c66602b779 100644 --- a/lib/snmp/test/snmp_test_lib.hrl +++ b/lib/snmp/test/snmp_test_lib.hrl @@ -49,8 +49,12 @@ 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 - @@ -150,8 +154,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_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}; |