File 3477-snmp-agent-test-Add-transport-kind-test-case-s.patch of Package erlang
From 9d24525a4bf347201a993df89e5f505cbe83356c Mon Sep 17 00:00:00 2001
From: Micael Karlberg <bmk@erlang.org>
Date: Fri, 11 Sep 2020 16:50:54 +0200
Subject: [PATCH 07/21] [snmp|agent|test] Add transport kind test case(s)
Add transport kind test case(s).
*Reqests* sent from the manager to the agent (which sends a reply)
and *traps* sent from the agent to the manager. Both handled on the
respective transports.
Also adjusted the info test case (net-if info has been change).
OTP-16649
---
lib/snmp/test/modules.mk | 1 +
lib/snmp/test/snmp_agent_SUITE.erl | 592 +++++++++++++++++++++++++-
lib/snmp/test/snmp_agent_test_lib.erl | 68 ++-
lib/snmp/test/snmp_otp16649_user.erl | 93 ++++
lib/snmp/test/snmp_test_mgr.erl | 3 +
lib/snmp/test/snmp_test_mgr_misc.erl | 84 +++-
6 files changed, 789 insertions(+), 52 deletions(-)
create mode 100644 lib/snmp/test/snmp_otp16649_user.erl
diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk
index ba0aea21dd..66cfa07f3b 100644
--- a/lib/snmp/test/modules.mk
+++ b/lib/snmp/test/modules.mk
@@ -38,6 +38,7 @@ TEST_UTIL_MODULES = \
snmp_test_lib \
snmp_agent_test_lib \
snmp_agent_test_get \
+ snmp_otp16649_user \
snmp_manager_user \
snmp_manager_user_old \
snmp_manager_user_test_lib \
diff --git a/lib/snmp/test/snmp_agent_SUITE.erl b/lib/snmp/test/snmp_agent_SUITE.erl
index c676bc487e..36e52ce207 100644
--- a/lib/snmp/test/snmp_agent_SUITE.erl
+++ b/lib/snmp/test/snmp_agent_SUITE.erl
@@ -303,7 +303,14 @@
%% tickets2
otp8395/1,
- otp9884/1
+ otp9884/1,
+ otp16649_1/1,
+ otp16649_2/1,
+ otp16649_3/1,
+ otp16649_4/1,
+ otp16649_5/1,
+ otp16649_6/1,
+ otp16649_7/1
]).
%% Internal exports
@@ -420,6 +427,9 @@
mnesia_start/0,
mnesia_stop/0,
start_standalone_agent/1,
+ stop_standalone_agent/1,
+ start_standalone_manager/1,
+ stop_standalone_manager/1,
do_info/1
]).
@@ -441,6 +451,9 @@
-define(sa, [1,3,6,1,4,1,193,2]).
-define(system, [1,3,6,1,2,1,1]).
-define(snmp, [1,3,6,1,2,1,11]).
+-define(sysDescr_instance, [1,3,6,1,2,1,1,1,0]).
+-define(sysObjectID_instance, [1,3,6,1,2,1,1,2,0]).
+-define(sysUpTime_instance, [1,3,6,1,2,1,1,3,0]).
-define(snmpTraps, [1,3,6,1,6,3,1,1,5]).
-define(ericsson, [1,3,6,1,4,1,193]).
-define(testTrap, [1,3,6,1,2,1,15,0]).
@@ -456,6 +469,11 @@
-define(TRAP_UDP, 5000).
+-define(MGR_PORT, 5000).
+-define(MGR_MMS, 1024).
+-define(MGR_ENGINE_ID, "mgrEngine").
+
+
-define(tooBigStr, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").
-define(str(X), snmp_pdus:bits_to_str(X)).
@@ -552,7 +570,8 @@ groups() ->
{tickets2, [], tickets2_cases()},
{otp4394, [], [otp_4394]},
{otp7157, [], [otp_7157]},
- {otp16092, [], otp16092_cases()}
+ {otp16092, [], otp16092_cases()},
+ {otp16649, [], otp16649_cases()}
].
@@ -858,6 +877,41 @@ init_per_testcase1(otp9884 = Case, Config) when is_list(Config) ->
"~n Case: ~p"
"~n Config: ~p", [Case, Config]),
otp9884({init, init_per_testcase2(Case, Config)});
+init_per_testcase1(otp16649_1 = Case, Config) when is_list(Config) ->
+ ?DBG("init_per_testcase1 -> entry with"
+ "~n Case: ~p"
+ "~n Config: ~p", [Case, Config]),
+ otp16649_1_init(init_per_testcase2(Case, Config));
+init_per_testcase1(otp16649_2 = Case, Config) when is_list(Config) ->
+ ?DBG("init_per_testcase1 -> entry with"
+ "~n Case: ~p"
+ "~n Config: ~p", [Case, Config]),
+ otp16649_2_init(init_per_testcase2(Case, Config));
+init_per_testcase1(otp16649_3 = Case, Config) when is_list(Config) ->
+ ?DBG("init_per_testcase1 -> entry with"
+ "~n Case: ~p"
+ "~n Config: ~p", [Case, Config]),
+ otp16649_3_init(init_per_testcase2(Case, Config));
+init_per_testcase1(otp16649_4 = Case, Config) when is_list(Config) ->
+ ?DBG("init_per_testcase1 -> entry with"
+ "~n Case: ~p"
+ "~n Config: ~p", [Case, Config]),
+ otp16649_4_init(init_per_testcase2(Case, Config));
+init_per_testcase1(otp16649_5 = Case, Config) when is_list(Config) ->
+ ?DBG("init_per_testcase1 -> entry with"
+ "~n Case: ~p"
+ "~n Config: ~p", [Case, Config]),
+ otp16649_5_init(init_per_testcase2(Case, Config));
+init_per_testcase1(otp16649_6 = Case, Config) when is_list(Config) ->
+ ?DBG("init_per_testcase1 -> entry with"
+ "~n Case: ~p"
+ "~n Config: ~p", [Case, Config]),
+ otp16649_6_init(init_per_testcase2(Case, Config));
+init_per_testcase1(otp16649_7 = Case, Config) when is_list(Config) ->
+ ?DBG("init_per_testcase1 -> entry with"
+ "~n Case: ~p"
+ "~n Config: ~p", [Case, Config]),
+ otp16649_7_init(init_per_testcase2(Case, Config));
init_per_testcase1(otp_7157 = _Case, Config) when is_list(Config) ->
?DBG("init_per_testcase1 -> entry with"
"~n Case: ~p"
@@ -976,6 +1030,20 @@ end_per_testcase1(otp8395, Config) when is_list(Config) ->
otp8395({fin, Config});
end_per_testcase1(otp9884, Config) when is_list(Config) ->
otp9884({fin, Config});
+end_per_testcase1(otp16649_1, Config) when is_list(Config) ->
+ otp16649_1_fin(Config);
+end_per_testcase1(otp16649_2, Config) when is_list(Config) ->
+ otp16649_2_fin(Config);
+end_per_testcase1(otp16649_3, Config) when is_list(Config) ->
+ otp16649_3_fin(Config);
+end_per_testcase1(otp16649_4, Config) when is_list(Config) ->
+ otp16649_4_fin(Config);
+end_per_testcase1(otp16649_5, Config) when is_list(Config) ->
+ otp16649_5_fin(Config);
+end_per_testcase1(otp16649_6, Config) when is_list(Config) ->
+ otp16649_6_fin(Config);
+end_per_testcase1(otp16649_7, Config) when is_list(Config) ->
+ otp16649_7_fin(Config);
end_per_testcase1(_Case, Config) when is_list(Config) ->
?DBG("end_per_testcase1 -> entry with"
"~n Case: ~p"
@@ -4399,7 +4467,7 @@ sa_mib() ->
ok.
ma_trap1(MA) ->
- ok = snmpa:send_trap(MA, testTrap2, "standard trap"),
+ ok = snmpa:send_trap(MA, testTrap2, "standard trap"),
?line ?expect5(trap, [system], 6, 1, [{[system, [4,0]],
"{mbj,eklas}@erlang.ericsson.se"}]),
ok = snmpa:send_trap(MA, testTrap1, "standard trap"),
@@ -7032,12 +7100,12 @@ otp16092_try_start_and_stop_agent(Node, Opts, Expected) ->
?IPRINT("try start snmp (agent) supervisor (on ~p) - expect ~p",
[Node, Expected]),
case start_standalone_agent(Node, Opts) of
- Pid when is_pid(Pid) andalso (Expected =:= success) ->
+ {ok, Pid} when is_pid(Pid) andalso (Expected =:= success) ->
?IPRINT("Expected success starting snmp (agent) supervisor"),
?SLEEP(1000),
stop_standalone_agent(Pid),
ok;
- Pid when is_pid(Pid) andalso (Expected =:= failure) ->
+ {ok, Pid} when is_pid(Pid) andalso (Expected =:= failure) ->
?EPRINT("Unexpected success starting snmp (agent) supervisor: (~p)",
[Pid]),
?SLEEP(1000),
@@ -7094,7 +7162,6 @@ otp16092_try_start_and_stop_agent(Node, Opts, Expected) ->
end,
ok.
-
%%-----------------------------------------------------------------
@@ -7105,17 +7172,29 @@ otp16092_try_start_and_stop_agent(Node, Opts, Expected) ->
tickets2_cases() ->
[
otp8395,
- otp9884
+ otp9884,
+ {group, otp16649}
].
+otp16649_cases() ->
+ [
+ otp16649_1,
+ otp16649_2,
+ otp16649_3,
+ otp16649_4,
+ otp16649_5,
+ otp16649_6,
+ otp16649_7
+ ].
+
otp8395({init, Config}) when is_list(Config) ->
?DBG("otp8395(init) -> entry with"
"~n Config: ~p", [Config]),
- %% --
+ %% --
%% Start nodes
- %%
+ %%
{ok, AgentNode} = start_node(agent),
{ok, ManagerNode} = start_node(manager),
@@ -7369,6 +7448,468 @@ otp9884_await_backup_completion(First, Second) ->
throw({error, {bad_completion, First, Second}}).
+%%-----------------------------------------------------------------
+
+otp16649_1_init(Config) ->
+ AgentPreTransports = [{4000, req_responder},
+ {4001, trap_sender}],
+ otp16649_init(1, AgentPreTransports, Config).
+
+otp16649_1_fin(Config) ->
+ otp16649_fin(1, Config).
+
+otp16649_1(doc) ->
+ "OTP-16649 - Multiple transports.";
+otp16649_1(Config) when is_list(Config) ->
+ otp16649(1, Config).
+
+
+otp16649_2_init(Config) ->
+ AgentPreTransports = [{4000, req_responder},
+ {system, trap_sender}],
+ otp16649_init(2, AgentPreTransports, Config).
+
+otp16649_2_fin(Config) ->
+ otp16649_fin(2, Config).
+
+otp16649_2(doc) ->
+ "OTP-16649 - Multiple transports.";
+otp16649_2(Config) when is_list(Config) ->
+ otp16649(2, Config).
+
+
+otp16649_3_init(Config) ->
+ AgentPreTransports = [{4000, req_responder},
+ {0, trap_sender}],
+ otp16649_init(3, AgentPreTransports, Config).
+
+otp16649_3_fin(Config) ->
+ otp16649_fin(3, Config).
+
+otp16649_3(doc) ->
+ "OTP-16649 - Multiple transports.";
+otp16649_3(Config) when is_list(Config) ->
+ otp16649(3, Config).
+
+
+otp16649_4_init(Config) ->
+ AgentPreTransports = [{4000, req_responder},
+ {{4000,4010}, trap_sender, [{no_reuse, true}]}],
+ otp16649_init(4, AgentPreTransports, Config).
+
+otp16649_4_fin(Config) ->
+ otp16649_fin(4, Config).
+
+otp16649_4(doc) ->
+ "OTP-16649 - Multiple transports.";
+otp16649_4(Config) when is_list(Config) ->
+ otp16649(4, Config).
+
+
+otp16649_5_init(Config) ->
+ AgentPreTransports = [{4000, req_responder},
+ {[{4000,4010}], trap_sender, [{no_reuse, true}]}],
+ otp16649_init(5, AgentPreTransports, Config).
+
+otp16649_5_fin(Config) ->
+ otp16649_fin(5, Config).
+
+otp16649_5(doc) ->
+ "OTP-16649 - Multiple transports.";
+otp16649_5(Config) when is_list(Config) ->
+ otp16649(5, Config).
+
+
+otp16649_6_init(Config) ->
+ AgentPreTransports = [{4000, req_responder},
+ {[4000,4001,4002], trap_sender, [{no_reuse, true}]}],
+ otp16649_init(6, AgentPreTransports, Config).
+
+otp16649_6_fin(Config) ->
+ otp16649_fin(5, Config).
+
+otp16649_6(doc) ->
+ "OTP-16649 - Multiple transports.";
+otp16649_6(Config) when is_list(Config) ->
+ otp16649(6, Config).
+
+
+otp16649_7_init(Config) ->
+ AgentPreTransports = [{4000, req_responder},
+ {[4000,{5100,5110}], trap_sender,
+ [{no_reuse, true}]}],
+ otp16649_init(7, AgentPreTransports, Config).
+
+otp16649_7_fin(Config) ->
+ otp16649_fin(7, Config).
+
+otp16649_7(doc) ->
+ "OTP-16649 - Multiple transports.";
+otp16649_7(Config) when is_list(Config) ->
+ otp16649(7, Config).
+
+
+otp16649(N, Config) ->
+ ?IPRINT("otp16649 -> entry with"
+ "~n N: ~w"
+ "~n Config: ~p", [N, Config]),
+
+ AgentNode = ?config(agent_node, Config),
+ ManagerNode = ?config(manager_node, Config),
+
+ ?line AInfo = rpc:call(AgentNode, snmpa, info, []),
+
+ ?IPRINT("Agent Info: "
+ "~n ~p", [AInfo]),
+
+ {value, {_, AgentRawTransports}} =
+ lists:keysearch(agent_raw_transports, 1, Config),
+ {value, {_, NetIF}} =
+ lists:keysearch(net_if, 1, AInfo),
+ {value, {_, TIs}} =
+ lists:keysearch(transport_info, 1, NetIF),
+
+ if (length(AgentRawTransports) =:= length(TIs)) ->
+ ok;
+ true ->
+ ?IPRINT("Invalid transports: "
+ "~n Number of raw transports: ~w"
+ "~n Number of transports: ~w",
+ [length(AgentRawTransports), length(TIs)]),
+ exit({invalid_num_transports,
+ length(AgentRawTransports), length(TIs)})
+ end,
+
+ ?IPRINT("validate transports"),
+ otp16649_validate_transports(AgentRawTransports, TIs),
+
+ ?IPRINT("which req-responder port-no"),
+ AgentReqPortNo = otp16649_which_req_port_no(TIs),
+
+ ?IPRINT("which trap-sender port-no"),
+ AgentTrapPortNo = otp16649_which_trap_port_no(TIs),
+
+ ?IPRINT("(mgr) register user"),
+ ?line ok = otp16649_mgr_reg_user(ManagerNode),
+
+ ?IPRINT("(mgr) register agent"),
+ TargetBase = "otp16649-agent-",
+ ReqTarget = TargetBase ++ "req",
+ TrapTarget = TargetBase ++ "trap",
+
+ ?line ok = otp16649_mgr_reg_agent(ManagerNode, ReqTarget, AgentReqPortNo),
+ ?line ok = otp16649_mgr_reg_agent(ManagerNode, TrapTarget, AgentTrapPortNo),
+
+ ?IPRINT("(mgr) simple (sync) get request"),
+ Oids = [?sysObjectID_instance, ?sysDescr_instance, ?sysUpTime_instance],
+ ?line ok = case otp16649_mgr_get_req(ManagerNode, Oids) of
+ {ok, {noError, 0, ReplyOids}, _} ->
+ ?IPRINT("(mgr) simple (sync) successful reply: "
+ "~n ~p", [ReplyOids]),
+ ok;
+ {ok, InvalidReply, _} ->
+ ?IPRINT("(mgr) simple (sync) invalid reply: "
+ "~n ~p", [InvalidReply]),
+ ok;
+ {error, Reason} ->
+ ?IPRINT("(mgr) simple (sync) error: "
+ "~n ~p", [Reason]),
+ error
+ end,
+
+ ?IPRINT("load TestTrap..."),
+ MibDir = ?config(mib_dir, Config),
+ ?line ok = otp16649_agent_load_mib(AgentNode, MibDir, "TestTrap"),
+
+ ?IPRINT("(agent) send trap"),
+ ?line ok = otp16649_agent_send_trap(AgentNode, testTrap2),
+
+ receive
+ {handle_trap, From, TrapTarget,
+ {?system, 6, 1, _, Vbs}} when is_pid(From) andalso
+ is_list(Vbs) ->
+ ?IPRINT("received expected handle trap callback message"),
+ ok
+
+ after 10000 ->
+ ?IPRINT("TIMEOUT"),
+ ?line exit(timeout)
+ end,
+
+ ?IPRINT("done"),
+ ok.
+
+
+otp16649_init(N, AgentPreTransports, Config) ->
+ ?IPRINT("otp16649_init -> entry with"
+ "~n N: ~w"
+ "~n AgentPreTransports: ~w"
+ "~n Config: ~p", [N, AgentPreTransports, Config]),
+
+ %% --
+ %% Start nodes
+ %%
+
+ ?IPRINT("start (agent and mansger) nodes"),
+
+ {ok, AgentNode} = start_node(otp16649_mk_name(N, agent)),
+ {ok, ManagerNode} = start_node(otp16649_mk_name(N, manager)),
+
+ %% --
+ %% Misc
+ %%
+
+ AgentHost = ?HOSTNAME(AgentNode),
+ ManagerHost = ?HOSTNAME(ManagerNode),
+
+ ?IPRINT("otp16649_init -> "
+ "~n AgentHost: ~p"
+ "~n ManagerHost: ~p",
+ [AgentHost, ManagerHost]),
+
+ IpFamily = inet,
+ Host = snmp_test_lib:hostname(),
+ Ip = ?LOCALHOST(),
+ {ok, AgentIP} = snmp_misc:ip(AgentHost),
+ {ok, ManagerIP0} = snmp_misc:ip(ManagerHost),
+ ManagerIP = tuple_to_list(ManagerIP0),
+ ?IPRINT("otp16649_init -> "
+ "~n Host: ~p"
+ "~n Ip: ~p"
+ "~n AgentIP: ~p"
+ "~n ManagerIP0: ~p"
+ "~n ManagerIP: ~p",
+ [Host, Ip, AgentIP, ManagerIP0, ManagerIP]),
+
+
+ %% --
+ %% Write agent config
+ %%
+
+ AgentConfDir = ?config(agent_conf_dir, Config),
+ Vsns = [v1,v2],
+ TransportDomain = transportDomainUdpIpv4,
+ F = fun({PortInfo, Kind}) ->
+ #{addr => {AgentIP, PortInfo}, kind => Kind};
+ ({PortInfo, Kind, Opts}) ->
+ #{addr => {AgentIP, PortInfo}, kind => Kind, opts => Opts}
+ end,
+ AgentPreTransports2 = [F(T) || T <- AgentPreTransports],
+
+ ?IPRINT("write agent config files"),
+ ?line ok = snmp_config:write_agent_snmp_files(
+ AgentConfDir, Vsns,
+ TransportDomain, {ManagerIP, ?MGR_PORT}, AgentPreTransports2,
+ "test"),
+
+ ?IPRINT("start agent"),
+ Config2 = start_agent([{host, Host},
+ {ip, Ip},
+ {ipfamily, IpFamily},
+ {agent_node, AgentNode},
+ {agent_host, AgentHost},
+ {agent_ip, AgentIP},
+ {manager_node, ManagerNode},
+ {manager_host, ManagerHost},
+ {manager_ip, ManagerIP}|Config]),
+
+
+
+ %% --
+ %% Write manager config
+ %%
+
+ ?IPRINT("create manager dirs"),
+ MgrTopDir = ?config(manager_top_dir, Config),
+ MgrDbDir = filename:join(MgrTopDir, "db/"),
+ MgrConfDir = filename:join(MgrTopDir, "conf/"),
+ ?line ok = file:make_dir(MgrConfDir),
+ MgrDbDir = filename:join(MgrTopDir, "db/"),
+ ?line ok = file:make_dir(MgrDbDir),
+ MgrLogDir = filename:join(MgrTopDir, "log/"),
+ ?line ok = file:make_dir(MgrLogDir),
+
+ ?IPRINT("write manager config files"),
+ MgrTransports = [{TransportDomain, {ManagerIP0, ?MGR_PORT}}],
+ ?line ok = snmp_config:write_manager_snmp_files(
+ MgrConfDir,
+ MgrTransports,
+ ?MGR_MMS, ?MGR_ENGINE_ID),
+
+ Config3 = [{manager_db_dir, MgrDbDir},
+ {manager_conf_dir, MgrConfDir},
+ {manager_log_dir, MgrLogDir} | Config2],
+
+ ?IPRINT("start manager"),
+ ?line ok = start_manager(Config3),
+
+ ?DBG("otp16649_init -> done when"
+ "~n Config2: ~p", [Config3]),
+ [{agent_raw_transports, AgentPreTransports} | Config3].
+
+otp16649_mk_name(N, Post) when is_integer(N) andalso is_atom(Post) ->
+ list_to_atom(?F("otp16649_~w_~w", [N, Post])).
+
+
+otp16649_fin(N, Config) when is_integer(N) ->
+ ?IPRINT("otp16649_fin -> entry with"
+ "~n N: ~p"
+ "~n Config: ~p", [N, Config]),
+
+ ManagerNode = ?config(manager_node, Config),
+ AgentNode = ?config(agent_node, Config),
+
+ %% -
+ %% Stop agent (this is the nice way to do it,
+ %% so logs and files can be closed in the proper way).
+ %%
+
+ ?line AgentTopSup = ?config(agent_sup, Config),
+ stop_standalone_agent(AgentTopSup),
+
+
+ %% -
+ %% Stop manager
+ %%
+
+ stop_standalone_manager(ManagerNode),
+
+
+ %%
+ %% Stop the manager node
+ %%
+
+ ?DBG("otp16649_fin -> stop manager node", []),
+ stop_node(ManagerNode),
+
+
+ %%
+ %% Stop the agent node
+ %%
+
+ ?DBG("otp16649_fin -> stop agent node", []),
+ stop_node(AgentNode),
+
+ ?DBG("otp16649_fin -> done", []),
+ Config1 = lists:keydelete(manager_node, 1, Config),
+ lists:keydelete(agent_node, 1, Config1).
+
+
+otp16649_validate_transports([], []) ->
+ ok;
+otp16649_validate_transports([AgentRawTransport|AgentRawTransports],
+ [TI|TIs]) ->
+ otp16649_validate_transport(AgentRawTransport, TI),
+ otp16649_validate_transports(AgentRawTransports, TIs).
+
+otp16649_validate_transport({PortInfo, Kind}, {PortNo, Kind, _}) ->
+ ?IPRINT("validate ~w transport:"
+ "~n PortNo: ~w"
+ "~n PortInfo: ~p", [Kind, PortNo, PortInfo]),
+ otp16649_validate_port(PortInfo, PortNo);
+otp16649_validate_transport({_, ConfKind}, {PortNo, ActualKind, _}) ->
+ exit({invalid_transport_kind, {PortNo, ConfKind, ActualKind}});
+otp16649_validate_transport({PortInfo, Kind, _}, {PortNo, Kind, _}) ->
+ ?IPRINT("validate ~w transport:"
+ "~n PortNo: ~w"
+ "~n PortInfo: ~p", [Kind, PortNo, PortInfo]),
+ otp16649_validate_port(PortInfo, PortNo);
+otp16649_validate_transport({_, ConfKind, _}, {PortNo, ActualKind, _}) ->
+ exit({invalid_transport_kind, {PortNo, ConfKind, ActualKind}}).
+
+otp16649_validate_port(PortNo, PortNo) when is_integer(PortNo) ->
+ ok;
+otp16649_validate_port(0, PortNo) when is_integer(PortNo) ->
+ ok;
+otp16649_validate_port(system, PortNo) when is_integer(PortNo) ->
+ ok;
+otp16649_validate_port(Range, PortNo) when is_tuple(Range) ->
+ case otp16649_validate_port_range(Range, PortNo) of
+ ok ->
+ ok;
+ error ->
+ exit({invalid_transport_port_no, {Range, PortNo}})
+ end;
+otp16649_validate_port(Ranges, PortNo) when is_list(Ranges) ->
+ case otp16649_validate_port_ranges(Ranges, PortNo) of
+ ok ->
+ ok;
+ error ->
+ exit({invalid_transport_port_no, {Ranges, PortNo}})
+ end.
+
+
+otp16649_validate_port_range({Min, Max}, PortNo)
+ when is_integer(Min) andalso
+ is_integer(Max) andalso
+ is_integer(PortNo) andalso
+ (Min =< PortNo) andalso
+ (PortNo =< Max) ->
+ ok;
+otp16649_validate_port_range(_Range, _PortNo) ->
+ error.
+
+otp16649_validate_port_ranges([], _PortNo) ->
+ error;
+otp16649_validate_port_ranges([PortNo|_], PortNo) when is_integer(PortNo) ->
+ ok;
+otp16649_validate_port_ranges([Range|Ranges], PortNo) when is_tuple(Range) ->
+ case otp16649_validate_port_range(Range, PortNo) of
+ ok ->
+ ok;
+ error ->
+ otp16649_validate_port_ranges(Ranges, PortNo)
+ end;
+otp16649_validate_port_ranges([_|Ranges], PortNo) ->
+ otp16649_validate_port_ranges(Ranges, PortNo).
+
+
+otp16649_which_req_port_no(TIs) ->
+ ?IPRINT("otp16649_which_req_port_no -> entry with"
+ "~n TIs: ~p", [TIs]),
+ otp16649_which_port_no(TIs, req_responder).
+
+otp16649_which_trap_port_no(TIs) ->
+ ?IPRINT("otp16649_which_trap_port_no -> entry with"
+ "~n TIs: ~p", [TIs]),
+ otp16649_which_port_no(TIs, trap_sender).
+
+otp16649_which_port_no([], Kind) ->
+ exit({no_transport_port_no, Kind});
+otp16649_which_port_no([{PortNo, Kind, _}|_], Kind) ->
+ PortNo;
+otp16649_which_port_no([_|TIs], Kind) ->
+ otp16649_which_port_no(TIs, Kind).
+
+
+otp16649_mgr_reg_user(Node) ->
+ rpc:call(Node, snmpm, register_user,
+ [otp16649, snmp_otp16649_user, self()]).
+
+otp16649_mgr_reg_agent(Node, Target, PortNo) ->
+ Localhost = snmp_test_lib:localhost(),
+ Config = [{address, Localhost},
+ {port, PortNo},
+ {version, v1},
+ {tdomain, transportDomainUdpIpv4},
+ {engine_id, "agentEngine"}],
+ rpc:call(Node, snmpm, register_agent,
+ [otp16649, Target, Config]).
+
+otp16649_mgr_get_req(Node, Oids) ->
+ TargetName = "otp16649-agent-req",
+ rpc:call(Node, snmpm, sync_get2, [otp16649, TargetName, Oids]).
+
+otp16649_agent_load_mib(Node, MibDir, Mib) ->
+ rpc:call(Node, snmpa, unload_mib, [snmp_master_agent, Mib]), % For safety
+ MibPath = join(MibDir, Mib),
+ rpc:call(Node, snmpa, load_mib, [snmp_master_agent, MibPath]).
+
+otp16649_agent_send_trap(Node, testTrap2 = Trap) ->
+ rpc:call(Node, snmpa, send_trap,
+ [snmp_master_agent, Trap, "standard trap"]).
+
+
%%-----------------------------------------------------------------
agent_log_validation(Node) ->
@@ -7421,7 +7962,7 @@ start_agent(Config, Opts) ->
process_flag(trap_exit, true),
- AgentTopSup = start_standalone_agent(AgentNode, AgentConfig),
+ ?line {ok, AgentTopSup} = start_standalone_agent(AgentNode, AgentConfig),
[{agent_sup, AgentTopSup} | Config].
@@ -7473,9 +8014,9 @@ start_standalone_agent(Config) ->
case snmpa_supervisor:start_link(normal, Config) of
{ok, AgentTopSup} ->
unlink(AgentTopSup),
- AgentTopSup;
+ {ok, AgentTopSup};
{error, {already_started, AgentTopSup}} ->
- AgentTopSup;
+ {ok, AgentTopSup};
{error, _} = ERROR ->
ERROR
end.
@@ -7499,6 +8040,31 @@ stop_standalone_agent(Pid) ->
nkill(Pid, kill).
+start_manager(Config) ->
+ Node = ?config(manager_node, Config),
+ ConfDir = ?config(manager_conf_dir, Config),
+ DbDir = ?config(manager_db_dir, Config),
+
+ Opts = [{server, [{verbosity, trace}]},
+ {net_if, [{verbosity, trace}]},
+ {note_store, [{verbosity, trace}]},
+ {config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
+ ?line ok = start_standalone_manager(Node, Opts).
+
+
+start_standalone_manager(Node, Config) ->
+ rpc:call(Node, ?MODULE, start_standalone_manager, [Config]).
+
+start_standalone_manager(Config) ->
+ snmpm:start(Config).
+
+
+stop_standalone_manager(Node) when (Node =/= node()) ->
+ rpc:call(Node, snmpm, stop, []);
+stop_standalone_manager(_) ->
+ snmpm:stop().
+
+
nkill(Pid, Reason) ->
nkill(Pid, Reason, 10).
@@ -7536,7 +8102,7 @@ do_info(MaNode) ->
Keys = [vsns,
stats_counters,
{agent, [process_memory, db_memory]},
- {net_if, [process_memory, port_info, reqs]},
+ {net_if, [process_memory, transport_info, reqs]},
{note_store, [process_memory, db_memory]},
{symbolic_store, [process_memory, db_memory]},
{local_db, [process_memory, db_memory]},
diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl
index 629ec49db4..ce75e34649 100644
--- a/lib/snmp/test/snmp_agent_test_lib.erl
+++ b/lib/snmp/test/snmp_agent_test_lib.erl
@@ -475,22 +475,28 @@ tc_run(Mod, Func, Args, Opts) ->
"~n StdM: ~p"
"~n", [M,Vsn,Dir,User,SecLevel,EngineID,CtxEngineID,Community,StdM]),
case snmp_test_mgr:start_link([%% {agent, snmp_test_lib:hostname()},
- {packet_server_debug, true},
- {debug, false},
- {agent, get(master_host)},
- {ipfamily, get(ipfamily)},
- {agent_udp, 4000},
- {trap_udp, 5000},
- {recbuf, 65535},
- quiet,
- Vsn,
- {community, Community},
- {user, User},
- {sec_level, SecLevel},
- {engine_id, EngineID},
- {context_engine_id, CtxEngineID},
- {dir, Dir},
- {mibs, mibs(StdM, M)}]) of
+ {packet_server_debug, true},
+ {debug, false},
+ {agent, get(master_host)},
+ {ipfamily, get(ipfamily)},
+ {agent_udp, 4000},
+ %% <SEP-TRANSPORTS>
+ %% First port is used to request replies
+ %% Second port is used for traps sent
+ %% by the agent.
+ %% {agent_udp, {4000, 4001}},
+ %% </SEP-TRANSPORTS>
+ {trap_udp, 5000},
+ {recbuf, 65535},
+ quiet,
+ Vsn,
+ {community, Community},
+ {user, User},
+ {sec_level, SecLevel},
+ {engine_id, EngineID},
+ {context_engine_id, CtxEngineID},
+ {dir, Dir},
+ {mibs, mibs(StdM, M)}]) of
{ok, _Pid} ->
try apply(Mod, Func, Args) of
Res ->
@@ -1584,14 +1590,28 @@ config(Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily) ->
?line {Domain, ManagerAddr} =
case IpFamily of
inet6 ->
- Ipv6Domain = transportDomainUdpIpv6,
- AgentIpv6Addr = {AIp, 4000},
- ManagerIpv6Addr = {MIp, ?TRAP_UDP},
+ TransportDomain6 = transportDomainUdpIpv6,
+ AgentAddr6 = {AIp, 4000},
+ ManagerAddr6 = {MIp, ?TRAP_UDP},
?line ok =
snmp_config:write_agent_snmp_files(
AgentConfDir, Vsns,
- Ipv6Domain, ManagerIpv6Addr, AgentIpv6Addr, "test"),
- {Ipv6Domain, ManagerIpv6Addr};
+ TransportDomain6, ManagerAddr6, AgentAddr6, "test"),
+ {TransportDomain6, ManagerAddr6};
+ inet ->
+ TransportDomain4 = transportDomainUdpIpv4,
+ AIp2 = maybe_fix_addr(AIp),
+ ManagerAddr4 = {MIp, ?TRAP_UDP},
+ %% AgentPreTransport =
+ %% [#{addr => {AIp2, 4000}, kind => req_responder},
+ %% #{addr => {AIp2, 4001}, kind => trap_sender}],
+ AgentPreTransport = [#{addr => {AIp2, 4000}}],
+ ?line ok =
+ snmp_config:write_agent_snmp_files(
+ AgentConfDir, Vsns,
+ TransportDomain4, ManagerAddr4, AgentPreTransport,
+ "test"),
+ {TransportDomain4, ManagerAddr4};
_ ->
?line ok =
snmp_config:write_agent_snmp_files(
@@ -1614,6 +1634,12 @@ config(Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily) ->
?line write_notify_conf(AgentConfDir),
ok.
+maybe_fix_addr(Addr) when is_list(Addr) ->
+ list_to_tuple(Addr);
+maybe_fix_addr(Addr) when is_tuple(Addr) ->
+ Addr.
+
+
delete_files(Config) ->
AgentDir = ?config(agent_dir, Config),
delete_files(AgentDir, [db, conf]).
diff --git a/lib/snmp/test/snmp_otp16649_user.erl b/lib/snmp/test/snmp_otp16649_user.erl
new file mode 100644
index 0000000000..260099a999
--- /dev/null
+++ b/lib/snmp/test/snmp_otp16649_user.erl
@@ -0,0 +1,93 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2020-2020. 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%
+%%
+
+%%----------------------------------------------------------------------
+%% Purpose: Utility functions for the (snmp manager) user test(s).
+%%----------------------------------------------------------------------
+
+-module(snmp_otp16649_user).
+
+-behaviour(snmpm_user).
+
+
+%%----------------------------------------------------------------------
+%% Include files
+%%----------------------------------------------------------------------
+-include_lib("common_test/include/ct.hrl").
+-include("snmp_test_lib.hrl").
+
+
+%%----------------------------------------------------------------------
+%% External exports
+%%----------------------------------------------------------------------
+-export([
+ ]).
+
+
+%%----------------------------------------------------------------------
+%% Internal exports
+%%----------------------------------------------------------------------
+
+-export([
+ handle_error/3,
+ handle_agent/5,
+ handle_pdu/4,
+ handle_trap/3,
+ handle_inform/3,
+ handle_report/3
+ ]).
+
+
+%%----------------------------------------------------------------------
+%% User callback functions:
+%%----------------------------------------------------------------------
+
+handle_error(ReqId, Reason, UserPid) ->
+ UserPid ! {handle_error, self(), ReqId, Reason},
+ ignore.
+
+
+handle_agent(Addr, Port, SnmpInfo, UserPid, UserData) ->
+ UserPid ! {handle_agent, self(), Addr, Port, SnmpInfo, UserData},
+ ignore.
+
+
+handle_pdu(TargetName, ReqId, SnmpResponse, UserPid) ->
+ UserPid ! {handle_pdu, self(), TargetName, ReqId, SnmpResponse},
+ ignore.
+
+handle_trap(TargetName, SnmpTrap, UserPid) ->
+ UserPid ! {handle_trap, self(), TargetName, SnmpTrap},
+ ignore.
+
+handle_inform(TargetName, SnmpInform, UserPid) ->
+ UserPid ! {handle_inform, self(), TargetName, SnmpInform},
+ receive
+ {handle_inform_no_response, TargetName} ->
+ no_reply;
+ {handle_inform_response, TargetName} ->
+ ignore
+ end.
+
+handle_report(TargetName, SnmpReport, UserPid) ->
+ UserPid ! {handle_report, self(), TargetName, SnmpReport},
+ ignore.
+
+
diff --git a/lib/snmp/test/snmp_test_mgr.erl b/lib/snmp/test/snmp_test_mgr.erl
index f8eb85734e..e4b5eb0083 100644
--- a/lib/snmp/test/snmp_test_mgr.erl
+++ b/lib/snmp/test/snmp_test_mgr.erl
@@ -312,6 +312,9 @@ is_options_ok([{ipfamily,IpFamily}|Opts])
is_options_ok(Opts);
is_options_ok([{agent_udp,Int}|Opts]) when is_integer(Int) ->
is_options_ok(Opts);
+is_options_ok([{agent_udp, {IntR, IntT}}|Opts]) when is_integer(IntR) andalso
+ is_integer(IntT) ->
+ is_options_ok(Opts);
is_options_ok([{trap_udp,Int}|Opts]) when is_integer(Int) ->
is_options_ok(Opts);
is_options_ok([{community,List}|Opts]) when is_list(List) ->
diff --git a/lib/snmp/test/snmp_test_mgr_misc.erl b/lib/snmp/test/snmp_test_mgr_misc.erl
index b1b1b8040b..2bfd44002f 100644
--- a/lib/snmp/test/snmp_test_mgr_misc.erl
+++ b/lib/snmp/test/snmp_test_mgr_misc.erl
@@ -62,9 +62,29 @@ start_link_packet(
start_link_packet(
InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz,
Dbg, IpFamily) when is_integer(UdpPort) ->
+ do_start_link_packet(InHandler,
+ AgentIp, UdpPort, TrapUdp,
+ VsnHdr, Version, Dir, BufSz,
+ Dbg, IpFamily);
+start_link_packet(InHandler,
+ AgentIp, {AReqPort, ATrapPort} = UdpPorts, TrapUdp,
+ VsnHdr, Version, Dir, BufSz,
+ Dbg, IpFamily) when is_integer(AReqPort) andalso
+ is_integer(ATrapPort) ->
+ do_start_link_packet(InHandler,
+ AgentIp, UdpPorts, TrapUdp,
+ VsnHdr, Version, Dir, BufSz,
+ Dbg, IpFamily).
+
+do_start_link_packet(InHandler,
+ AgentIp, UdpPorts, TrapUdp,
+ VsnHdr, Version, Dir, BufSz,
+ Dbg, IpFamily) ->
Args =
[self(),
- InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz,
+ InHandler,
+ AgentIp, UdpPorts, TrapUdp,
+ VsnHdr, Version, Dir, BufSz,
Dbg, IpFamily],
proc_lib:start_link(?MODULE, init_packet, Args).
@@ -100,7 +120,7 @@ send_bytes(Bytes, PacketPid) ->
%%--------------------------------------------------
init_packet(
Parent,
- SnmpMgr, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz,
+ SnmpMgr, AgentIp, UdpPorts, TrapUdp, VsnHdr, Version, Dir, BufSz,
DbgOptions, IpFamily) ->
%% This causes "verbosity printouts" to print (from the
%% specified level) in the modules we "borrow" from the
@@ -117,7 +137,7 @@ init_packet(
init_usm(Version, Dir),
proc_lib:init_ack(Parent, self()),
?IPRINT("started"),
- packet_loop(SnmpMgr, UdpId, AgentIp, UdpPort, VsnHdr, Version, []).
+ packet_loop(SnmpMgr, UdpId, AgentIp, UdpPorts, VsnHdr, Version, []).
init_debug(Dbg) when is_atom(Dbg) ->
put(debug,Dbg),
@@ -139,7 +159,7 @@ init_debug(DbgOptions) when is_list(DbgOptions) ->
ok.
-packet_loop(SnmpMgr, UdpId, AgentIp, UdpPort, VsnHdr, Version, MsgData) ->
+packet_loop(SnmpMgr, UdpId, AgentIp, UdpPorts, VsnHdr, Version, MsgData) ->
receive
{send_discovery_pdu, From, Pdu} ->
d("packet_loop -> received send_discovery_pdu with"
@@ -151,9 +171,10 @@ packet_loop(SnmpMgr, UdpId, AgentIp, UdpPort, VsnHdr, Version, MsgData) ->
{M, B} when is_list(B) ->
put(discovery, {M, From}),
display_outgoing_message(M),
- udp_send(UdpId, AgentIp, UdpPort, B)
+ Port = select_request_port(UdpPorts),
+ udp_send(UdpId, AgentIp, Port, B)
end,
- packet_loop(SnmpMgr, UdpId, AgentIp, UdpPort, VsnHdr, Version, []);
+ packet_loop(SnmpMgr, UdpId, AgentIp, UdpPorts, VsnHdr, Version, []);
{send_pdu, Pdu} ->
d("packet_loop -> received send_pdu with"
@@ -161,10 +182,11 @@ packet_loop(SnmpMgr, UdpId, AgentIp, UdpPort, VsnHdr, Version, MsgData) ->
case mk_msg(Version, Pdu, VsnHdr, MsgData) of
error ->
ok;
- B when is_list(B) ->
- udp_send(UdpId, AgentIp, UdpPort, B)
+ B when is_list(B) ->
+ Port = select_request_port(UdpPorts),
+ udp_send(UdpId, AgentIp, Port, B)
end,
- packet_loop(SnmpMgr,UdpId,AgentIp,UdpPort,VsnHdr,Version,[]);
+ packet_loop(SnmpMgr, UdpId, AgentIp, UdpPorts, VsnHdr, Version, []);
{send_msg, Msg, Ip, Udp} ->
d("packet_loop -> received send_msg with"
@@ -179,38 +201,64 @@ packet_loop(SnmpMgr, UdpId, AgentIp, UdpPort, VsnHdr, Version, MsgData) ->
B when is_list(B) ->
udp_send(UdpId, Ip, Udp, B)
end,
- packet_loop(SnmpMgr,UdpId,AgentIp,UdpPort,VsnHdr,Version,[]);
- {udp, UdpId, Ip, UdpPort, Bytes} ->
+ packet_loop(SnmpMgr, UdpId, AgentIp, UdpPorts, VsnHdr, Version, []);
+
+ {udp, UdpId, Ip, Port, Bytes} ->
d("packet_loop -> received udp with"
"~n UdpId: ~p"
"~n Ip: ~p"
- "~n UdpPort: ~p"
- "~n sz(Bytes): ~p", [UdpId, Ip, UdpPort, sz(Bytes)]),
+ "~n Port: ~p (~p)"
+ "~n sz(Bytes): ~p", [UdpId, Ip, Port, UdpPorts, sz(Bytes)]),
+ case UdpPorts of
+ Port ->
+ ok;
+ {Port, _} -> % Should be a (request) response
+ ok;
+ {_, Port} -> % Should be a trap
+ ok;
+ _ ->
+ d("packet_loop -> received packet from unknown port"
+ "~n ~p", [Port]),
+ exit({snmp_packet_from_unknown_port, Port, UdpPorts})
+ end,
MsgData3 = handle_udp_packet(Version, erase(discovery),
- UdpId, Ip, UdpPort, Bytes,
+ UdpId, Ip, Port, Bytes,
SnmpMgr, AgentIp),
- packet_loop(SnmpMgr,UdpId,AgentIp,UdpPort,VsnHdr,Version,
+ packet_loop(SnmpMgr, UdpId, AgentIp, UdpPorts, VsnHdr, Version,
MsgData3);
+
{udp_error, UdpId, Reason} ->
gen_udp:close(UdpId),
exit({udp_error, Reason});
{send_bytes, B} ->
d("packet_loop -> received send_bytes with"
- "~n sz(B): ~p", [sz(B)]),
- udp_send(UdpId, AgentIp, UdpPort, B),
- packet_loop(SnmpMgr,UdpId,AgentIp,UdpPort,VsnHdr,Version,[]);
+ "~n sz(B): ~p", [sz(B)]),
+ Port = select_request_port(UdpPorts),
+ udp_send(UdpId, AgentIp, Port, B),
+ packet_loop(SnmpMgr, UdpId, AgentIp, UdpPorts, VsnHdr, Version, []);
+
{stop, Pid} ->
d("packet_loop -> received stop from ~p", [Pid]),
gen_udp:close(UdpId),
Pid ! {self(), stopped},
exit(normal);
+
Other ->
d("packet_loop -> received unknown"
"~n ~p", [Other]),
exit({snmp_packet_got_other, Other})
end.
+select_request_port({Port, _}) when is_integer(Port) ->
+ Port;
+select_request_port(Port) when is_integer(Port) ->
+ Port.
+
+%% select_trap_port({_, Port}) when is_integer(Port) ->
+%% Port;
+%% select_trap_port(Port) when is_integer(Port) ->
+%% Port.
handle_udp_packet(_V, undefined,
UdpId, Ip, UdpPort,
--
2.26.2