aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/test/snmp_test_manager.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/snmp/test/snmp_test_manager.erl')
-rw-r--r--lib/snmp/test/snmp_test_manager.erl388
1 files changed, 388 insertions, 0 deletions
diff --git a/lib/snmp/test/snmp_test_manager.erl b/lib/snmp/test/snmp_test_manager.erl
new file mode 100644
index 0000000000..9d9c52ef8d
--- /dev/null
+++ b/lib/snmp/test/snmp_test_manager.erl
@@ -0,0 +1,388 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%----------------------------------------------------------------------
+%% This module implements an SNMP manager used in the test suite
+%%----------------------------------------------------------------------
+%%
+
+-module(snmp_test_manager).
+
+-behaviour(gen_server).
+-behaviour(snmpm_user).
+
+
+%% External exports
+-export([
+ start_link/0, start_link/1,
+ stop/0,
+
+ sync_get/1, sync_get/2,
+ sync_get_next/1, sync_get_next/2,
+ sync_get_bulk/3,
+ sync_set/1, sync_set/2
+ ]).
+
+
+%% Manager callback API:
+-export([
+ handle_error/3,
+ handle_agent/4,
+ handle_pdu/4,
+ handle_trap/3,
+ handle_inform/3,
+ handle_report/3
+ ]).
+
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ code_change/3, terminate/2]).
+
+-record(state, {mgr, parent, req, agent_target_name}).
+
+-define(SERVER, ?MODULE).
+-define(USER, ?MODULE).
+
+
+%%%-------------------------------------------------------------------
+%%% API
+%%%-------------------------------------------------------------------
+
+start_link() ->
+ start_link([]).
+
+start_link(Opts) ->
+ gen_server:start_link({local, ?SERVER}, ?MODULE, [self(), Opts], []).
+
+stop() ->
+ call(stop).
+
+
+sync_get(Oids) ->
+ sync_get(Oids, fun(X) -> {ok, X} end).
+
+sync_get(Oids, Verify) when is_list(Oids) and is_function(Verify) ->
+ Verify(call({sync_get, Oids})).
+
+
+sync_get_next(Oids) ->
+ sync_get_next(Oids, fun(X) -> {ok, X} end).
+
+sync_get_next(Oids, Verify) when is_list(Oids) and is_function(Verify) ->
+ Verify(call({sync_get_next, Oids})).
+
+
+sync_get_bulk(NR, MR, Oids) ->
+ sync_get_bulk(NR, MR, Oids, fun(X) -> {ok, X} end).
+
+sync_get_bulk(NR, MR, Oids, Verify)
+ when is_integer(NR) and is_integer(MR) and
+ is_list(Oids) and is_function(Verify) ->
+ Verify(call({sync_get_bulk, NR, MR, Oids})).
+
+
+sync_set(VarsAndVals) ->
+ sync_set(VarsAndVals, fun(X) -> {ok, X} end).
+
+sync_set(VarsAndVals, Verify)
+ when is_list(VarsAndVals) and is_function(Verify) ->
+ Verify(call({sync_set, VarsAndVals})).
+
+
+%%%-------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%-------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%--------------------------------------------------------------------
+init([Parent, Opts]) ->
+ process_flag(trap_exit, true),
+ case (catch do_init(Opts)) of
+ {ok, State} ->
+ {ok, State#state{parent = Parent}};
+ {error, Reason} ->
+ {stop, Reason}
+ end.
+
+do_init(Opts) ->
+ {MgrDir, MgrConf, MgrOpts, AgentTargetName, AgentConf} = parse_opts(Opts),
+ ok = snmp_config:write_manager_config(MgrDir, "", MgrConf),
+ {ok, Pid} = snmpm:start_link(MgrOpts),
+ ok = snmpm:register_user(?USER, ?MODULE, self()),
+ ok = snmpm:register_agent(?USER, AgentTargetName, AgentConf),
+ {ok, #state{mgr = Pid, agent_target_name = AgentTargetName}}.
+
+
+parse_opts(Opts) ->
+ %% Manager config (written to the manager.conf file)
+ %% Addr = get_opt(addr, Opts, ?HOSTNAME()),
+ Port = get_opt(port, Opts, 5000),
+ EngineId = get_opt(engine_id, Opts, "mgrEngine"),
+ MMS = get_opt(max_message_size, Opts, 484),
+
+ MgrConf = [%% {address, Addr},
+ {port, Port},
+ {engine_id, EngineId},
+ {max_message_size, MMS}],
+
+
+ %% Manager options
+ MgrOpts = get_opt(options, Opts),
+ MgrDir = get_opt(dir, get_opt(config, MgrOpts, [])),
+
+
+ %% Retreive the agent configuration
+ AgentConf = get_opt(agent_config, Opts),
+ AgentTarget = get_opt(agent_target, Opts),
+ {MgrDir, MgrConf, MgrOpts, AgentTarget, AgentConf}.
+
+
+get_opt(Key, Opts) ->
+ case lists:keysearch(Key, 1, Opts) of
+ {value, {Key, Val}} ->
+ Val;
+ false ->
+ throw({error, {missing_mandatory, Key}})
+ end.
+
+get_opt(Key, Opts, Def) ->
+ case lists:keysearch(Key, 1, Opts) of
+ {value, {Key, Val}} ->
+ Val;
+ false ->
+ Def
+ end.
+
+
+%%--------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%--------------------------------------------------------------------
+handle_call(stop, _From, S) ->
+ (catch snmpm:stop()),
+ {stop, normal, S};
+
+handle_call({sync_get, Oids}, _From,
+ #state{agent_target_name = TargetName} = S) ->
+ Reply = (catch snmpm:sync_get(?USER, TargetName, Oids)),
+ {reply, Reply, S};
+
+handle_call({sync_get_next, Oids}, _From,
+ #state{agent_target_name = TargetName} = S) ->
+ Reply = (catch snmpm:sync_get_next(?USER, TargetName, Oids)),
+ {reply, Reply, S};
+
+handle_call({sync_get_bulk, NR, MR, Oids}, _From,
+ #state{agent_target_name = TargetName} = S) ->
+ Reply = (catch snmpm:sync_get_bulk(?USER, TargetName, NR, MR, Oids)),
+ {reply, Reply, S};
+
+handle_call({sync_set, VarsAndVals}, _From,
+ #state{agent_target_name = TargetName} = S) ->
+ Reply = (catch snmpm:sync_set(?USER, TargetName, VarsAndVals)),
+ {reply, Reply, S};
+
+handle_call(Req, From, State) ->
+ error_msg("received unknown request ~n~p~nFrom ~p", [Req, From]),
+ {reply, {error, unknown_request}, State}.
+
+
+%%--------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%--------------------------------------------------------------------
+handle_cast(Msg, State) ->
+ error_msg("received unknown message ~n~p", [Msg]),
+ {noreply, State}.
+
+
+%%--------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%--------------------------------------------------------------------
+handle_info({snmp_error, ReqId, Reason},
+ #state{parent = P} = State) ->
+ info_msg("received snmp error: "
+ "~n ReqId: ~w"
+ "~n Reason: ~p", [ReqId, Reason]),
+ P ! {snmp_error, ReqId, Reason},
+ {noreply, State};
+
+handle_info({snmp_agent, Addr, Port, Info, Pid},
+ #state{parent = P} = State) ->
+ error_msg("detected new agent: "
+ "~n Addr: ~w"
+ "~n Port: ~p"
+ "~n Info: ~p", [Addr, Port, Info]),
+ Pid ! {snmp_agent_reply, ignore, self()},
+ P ! {snmp_agent, Addr, Port, Info},
+ {noreply, State};
+
+handle_info({snmp_pdu, TargetName, ReqId, Resp},
+ #state{parent = P} = State) ->
+ info_msg("received snmp pdu: "
+ "~n TargetName: ~p"
+ "~n ReqId: ~w"
+ "~n Resp: ~p", [TargetName, ReqId, Resp]),
+ P ! {snmp_pdu, TargetName, ReqId, Resp},
+ {noreply, State};
+
+handle_info({snmp_trap, TargetName, Info, Pid},
+ #state{parent = P} = State) ->
+ info_msg("received snmp trap: "
+ "~n TargetName: ~p"
+ "~n Info: ~p", [TargetName, Info]),
+ Pid ! {snmp_trap_reply, ignore, self()},
+ P ! {snmp_trap, TargetName, Info},
+ {noreply, State};
+
+handle_info({snmp_inform, TargetName, Info, Pid},
+ #state{parent = P} = State) ->
+ info_msg("received snmp inform: "
+ "~n TargetName: ~p"
+ "~n Info: ~p", [TargetName, Info]),
+ Pid ! {snmp_inform_reply, ignore, self()},
+ P ! {snmp_inform, TargetName, Info},
+ {noreply, State};
+
+handle_info({snmp_report, TargetName, Info, Pid},
+ #state{parent = P} = State) ->
+ info_msg("received snmp report: "
+ "~n TargetName: ~p"
+ "~n Info: ~p", [TargetName, Info]),
+ Pid ! {snmp_report_reply, ignore, self()},
+ P ! {snmp_report, TargetName, Info},
+ {noreply, State};
+
+handle_info(Info, State) ->
+ error_msg("received unknown info: "
+ "~n Info: ~p", [Info]),
+ {noreply, State}.
+
+
+%%--------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%--------------------------------------------------------------------
+terminate(_Reason, _State) ->
+ ok.
+
+
+code_change({down, _Vsn}, State, _Extra) ->
+ {ok, State};
+
+% upgrade
+code_change(_Vsn, State, _Extra) ->
+ {ok, State}.
+
+
+%%%-------------------------------------------------------------------
+%%% Internal functions
+%%%-------------------------------------------------------------------
+
+
+
+
+%% --------------------------------------------------------------------------
+%%
+%% SNMP manager callback functions
+%%
+%% --------------------------------------------------------------------------
+
+handle_error(ReqId, Reason, Pid) ->
+ Pid ! {snmp_error, ReqId, Reason},
+ ignore.
+
+
+handle_agent(Addr, Port, SnmpInfo, Pid) ->
+ Pid ! {snmp_agent, Addr, Port, SnmpInfo, self()},
+ receive
+ {snmp_agent_reply, Reply, Pid} ->
+ Reply
+ after 10000 ->
+ ignore
+ end.
+
+
+handle_pdu(TargetName, ReqId, SnmpResponse, Pid) ->
+ Pid ! {snmp_pdu, TargetName, ReqId, SnmpResponse},
+ ignore.
+
+
+handle_trap(TargetName, SnmpTrapInfo, Pid) ->
+ Pid ! {snmp_trap, TargetName, SnmpTrapInfo, self()},
+ receive
+ {snmp_trap_reply, Reply, Pid} ->
+ Reply
+ after 10000 ->
+ ignore
+ end.
+
+
+handle_inform(TargetName, SnmpInfo, Pid) ->
+ Pid ! {snmp_inform, TargetName, SnmpInfo, self()},
+ receive
+ {snmp_inform_reply, Reply, Pid} ->
+ Reply
+ after 10000 ->
+ ignore
+ end.
+
+
+handle_report(TargetName, SnmpInfo, Pid) ->
+ Pid ! {snmp_report, TargetName, SnmpInfo, self()},
+ receive
+ {snmp_report_reply, Reply, Pid} ->
+ Reply
+ after 10000 ->
+ ignore
+ end.
+
+
+%%----------------------------------------------------------------------
+
+call(Req) ->
+ gen_server:call(?SERVER, Req, infinity).
+
+% cast(Msg) ->
+% gen_server:cast(?SERVER, Msg).
+
+info_msg(F, A) ->
+ catch error_logger:info_msg("*** TEST-MANAGER: " ++ F ++ "~n", A).
+
+error_msg(F, A) ->
+ catch error_logger:error_msg("*** TEST-MANAGER: " ++ F ++ "~n", A).
+
+