1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2005-2020. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21-module(snmp_agent_test_lib). 22 23 24-export([ 25 start_v1_agent/1, start_v1_agent/2, 26 start_v2_agent/1, start_v2_agent/2, 27 start_v3_agent/1, start_v3_agent/2, 28 start_bilingual_agent/1, start_bilingual_agent/2, 29 start_mt_agent/1, start_mt_agent/2, start_mt_agent/3, 30 stop_agent/1, 31 32 %% start_sup/0, stop_sup/2, 33 start_subagent/3, stop_subagent/1, 34 start_sub_sup/1, start_sub_sup/2, 35 36 start_node/1, stop_node/1, 37 38 load_master/1, load_master_std/1, unload_master/1, 39 loaded_mibs/0, unload_mibs/1, 40 41 get_req/2, get_next_req/1, 42 43 config/5, config/6, 44 delete_files/1, 45 copy_file/2, 46 update_usm/2, 47 update_usm_mgr/2, rewrite_usm_mgr/3, reset_usm_mgr/1, 48 update_community/2, 49 update_vacm/2, 50 write_community_conf/2, 51 write_target_addr_conf/2, write_target_addr_conf/4, 52 rewrite_target_addr_conf/2, reset_target_addr_conf/1, 53 write_target_params_conf/2, rewrite_target_params_conf/3, 54 reset_target_params_conf/1, 55 write_notify_conf/1, write_view_conf/1, 56 57 display_memory_usage/0, 58 59 init_all/1, finish_all/1, 60 init_case/1, 61 try_test/2, try_test/3, try_test/4, 62 expect/3, expect/4, expect/5, expect/7, 63 64 regs/0, 65 rpc/3 66 ]). 67 68%% Internal exports 69-export([tc_wait/5, tc_run/4]). 70 71-include_lib("kernel/include/file.hrl"). 72-include_lib("common_test/include/ct.hrl"). 73-include("snmp_test_lib.hrl"). 74-define(SNMP_USE_V3, true). 75-include_lib("snmp/include/snmp_types.hrl"). 76 77-define(TRAP_UDP, 5000). 78 79-define(v1_2(V1,V2), 80 case get(vsn) of 81 v1 -> V1; 82 _ -> V2 83 end). 84 85-define(v1_2_3(V1,V2,V3), 86 case get(vsn) of 87 v1 -> V1; 88 v2 -> V2; 89 _ -> V3 90 end). 91 92 93%%%----------------------------------------------------------------- 94%%% The test case structure is as follows: 95%%% 96%%% init_all - starts mnesia, 97%%% 98%%% init_v1 - starts agent 99%%% simple 100%%% big - e.g. starts/stops subagent, load/unloads mibs 101%%% init_mul 102%%% mul_get 103%%% mul_set 104%%% <etc> 105%%% finish_mul 106%%% <etc> 107%%% finish_v1 108%%% 109%%% init_v2 - starts agent 110%%% finish_v2 111%%% 112%%% init_bilingual - starts agent 113%%% finish_bilingual 114%%% 115%%% finish_all 116%%% 117%%% There is still one problem with these testsuites. If one test 118%%% fails, it may not be possible to run some other cases, as it 119%%% may have e.g. created some row or loaded some table, that it 120%%% didn't undo (since it failed). 121%%%----------------------------------------------------------------- 122 123init_all(Config) when is_list(Config) -> 124 125 ?IPRINT("init_all -> entry with" 126 "~n Config: ~p",[Config]), 127 128 %% -- 129 %% Start nodes 130 %% 131 132 ?line {ok, SaNode} = start_node(snmp_sa), 133 ?line {ok, MgrNode} = start_node(snmp_mgr), 134 135 136 %% -- 137 %% Create necessary files ( and dirs ) 138 %% 139 140 SuiteTopDir = ?config(snmp_suite_top_dir, Config), 141 ?DBG("init_all -> SuiteTopDir ~p", [SuiteTopDir]), 142 143 AgentDir = join(SuiteTopDir, "agent/"), 144 ?line ok = file:make_dir(AgentDir), 145 ?DBG("init_all -> AgentDir ~p", [AgentDir]), 146 147 AgentDbDir = join(AgentDir, "db/"), 148 ?line ok = file:make_dir(AgentDbDir), 149 ?DBG("init_all -> AgentDbDir ~p", [AgentDbDir]), 150 151 AgentLogDir = join(AgentDir, "log/"), 152 ?line ok = file:make_dir(AgentLogDir), 153 ?DBG("init_all -> AgentLogDir ~p", [AgentLogDir]), 154 155 AgentConfDir = join(AgentDir, "conf/"), 156 ?line ok = file:make_dir(AgentConfDir), 157 ?DBG("init_all -> AgentConfDir ~p", [AgentConfDir]), 158 159 MgrDir = join(SuiteTopDir, "mgr/"), 160 ?line ok = file:make_dir(MgrDir), 161 ?DBG("init_all -> MgrDir ~p", [MgrDir]), 162 163 SaDir = join(SuiteTopDir, "sa/"), 164 ?line ok = file:make_dir(SaDir), 165 ?DBG("init_all -> SaDir ~p", [SaDir]), 166 167 SaDbDir = join(SaDir, "db/"), 168 ?line ok = file:make_dir(SaDbDir), 169 ?DBG("init_all -> SaDbDir ~p", [SaDbDir]), 170 171 %% MibDir = ?config(mib_dir, Config), 172 %% ?DBG("init_all -> MibDir ~p", [DataDir]), 173 174 175 %% -- 176 %% Start and initiate mnesia 177 %% 178 179 ?DBG("init_all -> load application mnesia", []), 180 ?line ok = application:load(mnesia), 181 182 ?DBG("init_all -> load application mnesia on node ~p", [SaNode]), 183 ?line ok = rpc:call(SaNode, application, load, [mnesia]), 184 185 ?DBG("init_all -> application mnesia: set_env dir",[]), 186 ?line application_controller:set_env(mnesia, dir, 187 join(AgentDbDir, "Mnesia1")), 188 189 ?DBG("init_all -> application mnesia: set_env dir on node ~p",[SaNode]), 190 ?line rpc:call(SaNode, application_controller, set_env, 191 [mnesia, dir, join(SaDir, "Mnesia2")]), 192 193 ?DBG("init_all -> create mnesia schema",[]), 194 ?line ok = mnesia:create_schema([SaNode, node()]), 195 196 ?DBG("init_all -> start application mnesia",[]), 197 ?line ok = application:start(mnesia), 198 199 ?DBG("init_all -> start application mnesia on ~p",[SaNode]), 200 ?line ok = rpc:call(SaNode, application, start, [mnesia]), 201 Ip = ?LOCALHOST(), 202 [{snmp_sa, SaNode}, 203 {snmp_mgr, MgrNode}, 204 {snmp_master, node()}, 205 {agent_dir, AgentDir ++ "/"}, 206 {agent_db_dir, AgentDbDir ++ "/"}, 207 {agent_log_dir, AgentLogDir ++ "/"}, 208 {agent_conf_dir, AgentConfDir ++ "/"}, 209 {sa_dir, SaDir ++ "/"}, 210 {sa_db_dir, SaDbDir ++ "/"}, 211 {mgr_dir, MgrDir ++ "/"}, 212 %% {mib_dir, DataDir}, 213 {ip, Ip} | 214 Config]. 215 216 217finish_all(Config) when is_list(Config) -> 218 SaNode = ?config(snmp_sa, Config), 219 MgrNode = ?config(snmp_mgr, Config), 220 stop_node(SaNode), 221 stop_node(MgrNode), 222 application:stop(mnesia). 223 224 225%% --- This one *must* be run first in each case --- 226 227init_case(Config) when is_list(Config) -> 228 229 ?DBG("init_case -> entry with" 230 "~n Config: ~p", [Config]), 231 232 SaNode = ?config(snmp_sa, Config), 233 MgrNode = ?config(snmp_mgr, Config), 234 MasterNode = ?config(snmp_master, Config), 235 %% MasterNode = node(), 236 IpFamily = proplists:get_value(ipfamily, Config, inet), 237 238 SaHost = ?HOSTNAME(SaNode), 239 MgrHost = ?HOSTNAME(MgrNode), 240 MasterHost = ?HOSTNAME(MasterNode), 241 {ok, MasterIP} = snmp_misc:ip(MasterHost, IpFamily), 242 {ok, MIP} = snmp_misc:ip(MgrHost, IpFamily), 243 {ok, SIP} = snmp_misc:ip(SaHost, IpFamily), 244 245 246 put(mgr_node, MgrNode), 247 put(sa_node, SaNode), 248 put(master_node, MasterNode), 249 put(sa_host, SaHost), 250 put(mgr_host, MgrHost), 251 put(master_host, MasterHost), 252 put(mip, tuple_to_list(MIP)), 253 put(masterip, tuple_to_list(MasterIP)), 254 put(sip, tuple_to_list(SIP)), 255 put(ipfamily, IpFamily), 256 257 MibDir = ?config(mib_dir, Config), 258 put(mib_dir, MibDir), 259 StdM = join(code:priv_dir(snmp), "mibs") ++ "/", 260 put(std_mib_dir, StdM), 261 262 MgrDir = ?config(mgr_dir, Config), 263 put(mgr_dir, MgrDir), 264 265 put(vsn, ?config(vsn, Config)), 266 ?DBG("init_case -> exit with" 267 "~n MasterNode: ~p" 268 "~n SaNode: ~p" 269 "~n MgrNode: ~p" 270 "~n MibDir: ~p", [MasterNode, SaNode, MgrNode, MibDir]), 271 {SaNode, MgrNode, MibDir}. 272 273 274%%%-------------------------------------------------- 275%%% Used to test the standard mib with our 276%%% configuration. 277%%%-------------------------------------------------- 278 279try_test(TcRunMod, TcRunFunc) -> 280 try_test(TcRunMod, TcRunFunc, []). 281 282try_test(TcRunMod, TcRunFunc, TcRunArgs) -> 283 try_test(TcRunMod, TcRunFunc, TcRunArgs, []). 284 285try_test(TcRunMod, TcRunFunc, TcRunArgs, TcRunOpts) -> 286 Node = get(mgr_node), 287 Mod = ?MODULE, 288 Func = tc_run, 289 Args = [TcRunMod, TcRunFunc, TcRunArgs, TcRunOpts], 290 tc_try(Node, Mod, Func, Args). 291 292%% We spawn a test case runner process on the manager node. 293%% The assumption is that the manager shall do something, but 294%% not all test cases have the manager perform actions. 295%% In some cases we make a rpc call back to the agent node directly 296%% and call something in the agent... (for example the info_test 297%% test case). 298%% We should use link (instead of monitor) in order for the test case 299%% timeout cleanup (kills) should have effect on the test case runner 300%% process as well. 301 302tc_try(N, M, F, A) -> 303 ?IPRINT("tc_try -> entry with" 304 "~n N: ~p" 305 "~n M: ~p" 306 "~n F: ~p" 307 "~n A: ~p" 308 "~n when" 309 "~n get(): ~p" 310 "~n", [N, 311 M, F, A, 312 get()]), 313 case net_adm:ping(N) of 314 pong -> 315 ?IPRINT("tc_try -> ~p still running - start runner~n", [N]), 316 OldFlag = trap_exit(true), % Make sure we catch it 317 Runner = spawn_link(N, ?MODULE, tc_wait, [self(), get(), M, F, A]), 318 await_tc_runner_started(Runner, OldFlag), 319 await_tc_runner_done(Runner, OldFlag); 320 pang -> 321 ?WPRINT("tc_try -> ~p *not* running~n", [N]), 322 skip({node_not_running, N}) 323 end. 324 325await_tc_runner_started(Runner, OldFlag) -> 326 ?IPRINT("await tc-runner (~p) start ack~n", [Runner]), 327 receive 328 {'EXIT', Runner, Reason} -> 329 ?EPRINT("TC runner start failed: " 330 "~n ~p~n", [Reason]), 331 exit({tx_runner_start_failed, Reason}); 332 {tc_runner_started, Runner} -> 333 ?IPRINT("TC runner start acknowledged~n"), 334 ok 335 after 10000 -> %% We should *really* not have to wait this long, but... 336 trap_exit(OldFlag), 337 unlink_and_flush_exit(Runner), 338 RunnerInfo = ?PINFO(Runner), 339 ?EPRINT("TC runner start timeout: " 340 "~n ~p", [RunnerInfo]), 341 %% If we don't get a start ack within 10 seconds, we are f*ed 342 exit(Runner, kill), 343 exit({tc_runner_start, timeout, RunnerInfo}) 344 end. 345 346await_tc_runner_done(Runner, OldFlag) -> 347 receive 348 {'EXIT', Runner, Reason} -> 349 %% This is not a normal (tc) failure (that is the clause below). 350 %% Instead the tc runner process crashed, for some reason. So 351 %% check if have got any system events, and if so, skip. 352 SysEvs = snmp_test_global_sys_monitor:events(), 353 if 354 (SysEvs =:= []) -> 355 ?EPRINT("TC runner failed: " 356 "~n ~p~n", [Reason]), 357 exit({tx_runner_failed, Reason}); 358 true -> 359 ?WPRINT("TC runner failed when we got system events: " 360 "~n Reason: ~p" 361 "~n Sys Events: ~p" 362 "~n", [Reason, SysEvs]), 363 skip([{reason, Reason}, {system_events, SysEvs}]) 364 end; 365 {tc_runner_done, Runner, {'EXIT', {skip, Reason}}, Loc} -> 366 ?WPRINT("call -> done with skip: " 367 "~n Reason: ~p" 368 "~n Loc: ~p" 369 "~n", [Reason, Loc]), 370 trap_exit(OldFlag), 371 unlink_and_flush_exit(Runner), 372 put(test_server_loc, Loc), 373 skip(Reason); 374 {tc_runner_done, Runner, {'EXIT', Rn}, Loc} -> 375 ?EPRINT("call -> done with exit: " 376 "~n Rn: ~p" 377 "~n Loc: ~p" 378 "~n", [Rn, Loc]), 379 trap_exit(OldFlag), 380 unlink_and_flush_exit(Runner), 381 put(test_server_loc, Loc), 382 exit(Rn); 383 {tc_runner_done, Runner, Ret, _Zed} -> 384 ?DBG("call -> done:" 385 "~n Ret: ~p" 386 "~n Zed: ~p", [Ret, _Zed]), 387 trap_exit(OldFlag), 388 unlink_and_flush_exit(Runner), 389 case Ret of 390 {error, Reason} -> 391 exit(Reason); 392 {skip, Reason} -> 393 skip(Reason); 394 OK -> 395 OK 396 end 397 end. 398 399trap_exit(Flag) when is_boolean(Flag) -> 400 erlang:process_flag(trap_exit, Flag). 401 402unlink_and_flush_exit(Pid) -> 403 unlink(Pid), 404 receive 405 {'EXIT', Pid, _} -> 406 ok 407 after 0 -> 408 ok 409 end. 410 411tc_wait(From, Env, M, F, A) -> 412 ?IPRINT("tc_wait -> entry with" 413 "~n From: ~p" 414 "~n Env: ~p" 415 "~n M: ~p" 416 "~n F: ~p" 417 "~n A: ~p", [From, Env, M, F, A]), 418 From ! {tc_runner_started, self()}, 419 lists:foreach(fun({K,V}) -> put(K,V) end, Env), 420 ?IPRINT("tc_wait -> env set - now run tc~n"), 421 Res = (catch apply(M, F, A)), 422 ?IPRINT("tc_wait -> tc run done: " 423 "~n ~p" 424 "~n", [Res]), 425 From ! {tc_runner_done, self(), Res, get(test_server_loc)}, 426 %% The point of this is that in some cases we have seen that the 427 %% exit signal having been "passed on" to the CT, which consider any 428 %% exit a fail (even if its {'EXIT', ok}). 429 %% So, just to be on the safe side, convert an 'ok' to a 'normal'. 430 case Res of 431 ok -> 432 exit(normal); 433 {ok, _} -> 434 exit(normal); 435 _ -> 436 exit(Res) 437 end. 438 439tc_run(Mod, Func, Args, Opts) -> 440 ?IPRINT("tc_run -> entry with" 441 "~n Mod: ~p" 442 "~n Func: ~p" 443 "~n Args: ~p" 444 "~n Opts: ~p" 445 "~n", [Mod, Func, Args, Opts]), 446 (catch snmp_test_mgr:stop()), % If we had a running mgr from a failed case 447 M = get(mib_dir), 448 Dir = get(mgr_dir), 449 User = snmp_misc:get_option(user, Opts, "all-rights"), 450 SecLevel = snmp_misc:get_option(sec_level, Opts, noAuthNoPriv), 451 EngineID = snmp_misc:get_option(engine_id, Opts, "agentEngine"), 452 CtxEngineID = snmp_misc:get_option(context_engine_id, Opts, EngineID), 453 Community = snmp_misc:get_option(community, Opts, "all-rights"), 454 ?DBG("tc_run -> start crypto app",[]), 455 _CryptoRes = ?CRYPTO_START(), 456 ?DBG("tc_run -> Crypto: ~p", [_CryptoRes]), 457 StdM = join(code:priv_dir(snmp), "mibs") ++ "/", 458 Vsn = get(vsn), 459 ?IPRINT("tc_run -> config:" 460 "~n M: ~p" 461 "~n Vsn: ~p" 462 "~n Dir: ~p" 463 "~n User: ~p" 464 "~n SecLevel: ~p" 465 "~n EngineID: ~p" 466 "~n CtxEngineID: ~p" 467 "~n Community: ~p" 468 "~n StdM: ~p" 469 "~n", [M,Vsn,Dir,User,SecLevel,EngineID,CtxEngineID,Community,StdM]), 470 case snmp_test_mgr:start([%% {agent, snmp_test_lib:hostname()}, 471 {packet_server_debug, true}, 472 {debug, false}, 473 {agent, get(master_host)}, 474 {ipfamily, get(ipfamily)}, 475 {agent_udp, 4000}, 476 {trap_udp, 5000}, 477 {recbuf, 65535}, 478 quiet, 479 Vsn, 480 {community, Community}, 481 {user, User}, 482 {sec_level, SecLevel}, 483 {engine_id, EngineID}, 484 {context_engine_id, CtxEngineID}, 485 {dir, Dir}, 486 {mibs, mibs(StdM, M)}]) of 487 {ok, _Pid} -> 488 case (catch apply(Mod, Func, Args)) of 489 {'EXIT', {skip, Reason}} -> 490 ?WPRINT("apply skip detected: " 491 "~n ~p", [Reason]), 492 (catch snmp_test_mgr:stop()), 493 ?SKIP(Reason); 494 {'EXIT', Reason} -> 495 %% We have hosts (mostly *very* slooow VMs) that 496 %% can timeout anything. Since we are basically 497 %% testing communication, we therefor must check 498 %% for system events at every failure. Grrr! 499 SysEvs = snmp_test_global_sys_monitor:events(), 500 (catch snmp_test_mgr:stop()), 501 if 502 (SysEvs =:= []) -> 503 ?EPRINT("TC runner failed: " 504 "~n ~p~n", [Reason]), 505 ?FAIL({apply_failed, {Mod, Func, Args}, Reason}); 506 true -> 507 ?WPRINT("apply exit catched when we got system events: " 508 "~n Reason: ~p" 509 "~n Sys Events: ~p" 510 "~n", [Reason, SysEvs]), 511 ?SKIP([{reason, Reason}, {system_events, SysEvs}]) 512 end; 513 Res -> 514 (catch snmp_test_mgr:stop()), 515 Res 516 end; 517 518 {error, Reason} -> 519 ?EPRINT("Failed starting (test) manager: " 520 "~n ~p", [Reason]), 521 (catch snmp_test_mgr:stop()), 522 ?line ?FAIL({mgr_start_error, Reason}); 523 524 Err -> 525 ?EPRINT("Failed starting (test) manager: " 526 "~n ~p", [Err]), 527 (catch snmp_test_mgr:stop()), 528 ?line ?FAIL({mgr_start_failure, Err}) 529 end. 530 531 532%% --------------------------------------------------------------- 533%% --- --- 534%% --- Start the agent --- 535%% --- --- 536%% --------------------------------------------------------------- 537 538start_v1_agent(Config) when is_list(Config) -> 539 start_agent(Config, [v1]). 540 541start_v1_agent(Config, Opts) when is_list(Config) andalso is_list(Opts) -> 542 start_agent(Config, [v1], Opts). 543 544start_v2_agent(Config) when is_list(Config) -> 545 start_agent(Config, [v2]). 546 547start_v2_agent(Config, Opts) when is_list(Config) andalso is_list(Opts) -> 548 start_agent(Config, [v2], Opts). 549 550start_v3_agent(Config) when is_list(Config) -> 551 start_agent(Config, [v3]). 552 553start_v3_agent(Config, Opts) when is_list(Config) andalso is_list(Opts) -> 554 start_agent(Config, [v3], Opts). 555 556start_bilingual_agent(Config) when is_list(Config) -> 557 start_agent(Config, [v1,v2]). 558 559start_bilingual_agent(Config, Opts) 560 when is_list(Config) andalso is_list(Opts) -> 561 start_agent(Config, [v1,v2], Opts). 562 563start_mt_agent(Config) -> 564 start_mt_agent(Config, true, []). 565 566start_mt_agent(Config, MT) -> 567 start_mt_agent(Config, MT, []). 568 569start_mt_agent(Config, MT, Opts) 570 when is_list(Config) andalso 571 ((MT =:= true) orelse (MT =:= extended)) andalso 572 is_list(Opts) -> 573 start_agent(Config, [v2], [{multi_threaded, MT} | Opts]). 574 575start_agent(Config, Vsns) -> 576 start_agent(Config, Vsns, []). 577start_agent(Config, Vsns, Opts) -> 578 579 ?IPRINT("start_agent -> entry (~p) with" 580 "~n Config: ~p" 581 "~n Vsns: ~p" 582 "~n Opts: ~p", [node(), Config, Vsns, Opts]), 583 584 ?line AgentLogDir = ?config(agent_log_dir, Config), 585 ?line AgentConfDir = ?config(agent_conf_dir, Config), 586 ?line AgentDbDir = ?config(agent_db_dir, Config), 587 ?line SaNode = ?config(snmp_sa, Config), 588 589 Env = app_agent_env_init( 590 [{versions, Vsns}, 591 {agent_type, master}, 592 {agent_verbosity, trace}, 593 {get_mechanism, snmp_agent_test_get}, 594 {db_dir, AgentDbDir}, 595 {audit_trail_log, [{type, read_write}, 596 {dir, AgentLogDir}, 597 {size, {10240, 10}}]}, 598 {config, [{dir, AgentConfDir}, 599 {force_load, false}, 600 {verbosity, trace}]}, 601 {local_db, [{repair, true}, 602 {verbosity, log}]}, 603 {mib_server, [{verbosity, log}]}, 604 {symbolic_store, [{verbosity, log}]}, 605 {note_store, [{verbosity, log}]}, 606 {net_if, [{verbosity, trace}]}], 607 Opts), 608 609 610 process_flag(trap_exit,true), 611 612 ?IPRINT("start_agent -> try start snmp app supervisor", []), 613 {ok, AppSup} = snmp_app_sup:start_link(), 614 unlink(AppSup), 615 ?DBG("start_agent -> snmp app supervisor: ~p", [AppSup]), 616 617 ?IPRINT("start_agent -> try start master agent",[]), 618 ?line Sup = start_sup(Env), 619 ?line unlink(Sup), 620 ?DBG("start_agent -> snmp supervisor: ~p", [Sup]), 621 622 ?IPRINT("start_agent -> try (rpc) start sub agent on ~p", [SaNode]), 623 ?line SaDir = ?config(sa_dir, Config), 624 ?line {ok, Sub} = start_sub_sup(SaNode, SaDir), 625 ?DBG("start_agent -> done", []), 626 627 ?line [{snmp_app_sup, AppSup}, 628 {snmp_sup, {Sup, self()}}, 629 {snmp_sub, Sub} | Config]. 630 631 632app_agent_env_init(Env0, Opts) -> 633 ?DBG("app_agent_env_init -> unload snmp",[]), 634 ?line application:unload(snmp), 635 636 ?DBG("app_agent_env_init -> load snmp",[]), 637 ?line application:load(snmp), 638 639 ?DBG("app_agent_env_init -> " 640 "merge or maybe replace (snmp agent) app env",[]), 641 Env = add_or_maybe_merge_agent_env(Opts, Env0), 642 ?DBG("app_agent_env_init -> merged env: " 643 "~n ~p", [Env]), 644 645 %% We put it into the app environment just as 646 %% a precaution, since when starting normally, 647 %% this is where the environment is extracted from. 648 app_agent_set_env(Env), 649 Env. 650 651app_agent_set_env(Value) -> 652 application_controller:set_env(snmp, agent, Value). 653 654add_or_maybe_merge_agent_env([], Env) -> 655 ?DBG("merging agent env -> merged", []), 656 lists:keysort(1, Env); 657add_or_maybe_merge_agent_env([{Key, Value1}|Opts], Env) -> 658 ?DBG("merging agent env -> add, replace or merge ~p", [Key]), 659 case lists:keysearch(Key, 1, Env) of 660 {value, {Key, Value1}} -> 661 %% Identical, move on 662 ?DBG("merging agent env -> " 663 "no need to merge ~p - identical - keep: " 664 "~n ~p", [Key, Value1]), 665 add_or_maybe_merge_agent_env(Opts, Env); 666 {value, {Key, Value2}} -> 667 %% Another value, merge or replace 668 NewValue = merge_or_replace_agent_env(Key, Value1, Value2), 669 Env2 = lists:keyreplace(Key, 1, Env, {Key, NewValue}), 670 add_or_maybe_merge_agent_env(Opts, Env2); 671 false -> 672 ?DBG("merging agent env -> no old ~p to merge with - add: " 673 "~n ~p", [Key, Value1]), 674 add_or_maybe_merge_agent_env(Opts, [{Key, Value1}|Env]) 675 end. 676 677merge_or_replace_agent_env(versions, NewVersions, _OldVersions) -> 678 ?DBG("merging agent env -> versions replaced: ~p -> ~p", 679 [NewVersions, _OldVersions]), 680 NewVersions; 681merge_or_replace_agent_env(agent_type, NewType, _OldType) -> 682 ?DBG("merging agent env -> agent type replaced: ~p -> ~p", 683 [NewType, _OldType]), 684 NewType; 685merge_or_replace_agent_env(agent_verbosity, NewVerbosity, _OldVerbosity) -> 686 ?DBG("merging agent env -> agent verbosity replaced: ~p -> ~p", 687 [NewVerbosity, _OldVerbosity]), 688 NewVerbosity; 689merge_or_replace_agent_env(db_dir, NewDbDir, _OldDbDir) -> 690 ?DBG("merging agent env -> db-dir replaced: ~p -> ~p", 691 [NewDbDir, _OldDbDir]), 692 NewDbDir; 693merge_or_replace_agent_env(audit_trail_log, NewATL, OldATL) -> 694 merge_or_replace_agent_env_atl(NewATL, OldATL); 695merge_or_replace_agent_env(config, NewConfig, OldConfig) -> 696 merge_or_replace_agent_env_config(NewConfig, OldConfig); 697merge_or_replace_agent_env(local_db, NewLdb, OldLdb) -> 698 merge_or_replace_agent_env_ldb(NewLdb, OldLdb); 699merge_or_replace_agent_env(mib_storage, NewMst, OldMst) -> 700 merge_or_replace_agent_env_mib_storage(NewMst, OldMst); 701merge_or_replace_agent_env(mib_server, NewMibs, OldMibs) -> 702 merge_or_replace_agent_env_mib_server(NewMibs, OldMibs); 703merge_or_replace_agent_env(symbolic_store, NewSymStore, OldSymStore) -> 704 merge_or_replace_agent_env_symbolic_store(NewSymStore, OldSymStore); 705merge_or_replace_agent_env(note_store, NewNoteStore, OldNoteStore) -> 706 merge_or_replace_agent_env_note_store(NewNoteStore, OldNoteStore); 707merge_or_replace_agent_env(net_if, NewNetIf, OldNetIf) -> 708 merge_or_replace_agent_env_net_if(NewNetIf, OldNetIf); 709merge_or_replace_agent_env(Key, NewValue, OldValue) -> 710 ?FAIL({not_implemented_merge_or_replace, 711 Key, NewValue, OldValue}). 712 713merge_or_replace_agent_env_atl(New, Old) -> 714 ATL = merge_agent_options(New, Old), 715 ?DBG("merging agent env -> audit-trail-log merged: " 716 "~n ~p | ~p -> ~p", [New, Old, ATL]), 717 ATL. 718 719merge_or_replace_agent_env_config(New, Old) -> 720 Config = merge_agent_options(New, Old), 721 case lists:keymember(dir, 1, Config) of 722 true -> 723 ?DBG("merging agent env -> config merged: " 724 "~n ~p | ~p -> ~p", [New, Old, Config]), 725 Config; 726 false -> 727 ?FAIL({missing_mandatory_option, {config, dir}}) 728 end. 729 730merge_or_replace_agent_env_ldb(New, Old) -> 731 LDB = merge_agent_options(New, Old), 732 ?DBG("merging agent env -> local-db merged: " 733 "~n ~p | ~p -> ~p", [New, Old, LDB]), 734 LDB. 735 736merge_or_replace_agent_env_mib_storage(NewMibStorage, OldMibStorage) -> 737 %% Shall we merge or replace? 738 %% module is mandatory. We will only merge if NewModule is 739 %% equal to OldModule. 740 NewModule = 741 case lists:keysearch(module, 1, NewMibStorage) of 742 {value, {module, M}} -> 743 M; 744 false -> 745 ?FAIL({missing_mandatory_option, {mib_storage, module}}) 746 end, 747 case lists:keysearch(module, 1, OldMibStorage) of 748 {value, {module, NewModule}} -> 749 %% Same module => merge 750 %% Non-ex new options => remove 751 %% Ex new options and non-ex old options => replace 752 %% Otherwise merge 753 case lists:keysearch(options, 1, NewMibStorage) of 754 false -> 755 ?DBG("merging agent env -> " 756 "no mib-storage ~p merge needed - " 757 "no new options (= remove old options)", [NewModule]), 758 NewMibStorage; 759 {value, {options, NewOptions}} -> 760 case lists:keysearch(options, 1, OldMibStorage) of 761 false -> 762 ?DBG("merging agent env -> " 763 "no mib-storage ~p merge needed - " 764 "no old options", [NewModule]), 765 NewMibStorage; 766 {value, {options, OldOptions}} -> 767 MergedOptions = 768 merge_agent_options(NewOptions, OldOptions), 769 ?DBG("merging agent env -> mib-storage ~p merged: " 770 "~n Options: ~p | ~p -> ~p", 771 [NewModule, 772 NewOptions, OldOptions, MergedOptions]), 773 [{module, NewModule}, 774 {options, MergedOptions}] 775 end 776 end; 777 _ -> 778 %% Diff module => replace 779 ?DBG("merging agent env -> " 780 "no mib-storage ~p merge needed - " 781 "new module", [NewModule]), 782 NewMibStorage 783 end. 784 785merge_or_replace_agent_env_mib_server(New, Old) -> 786 MibServer = merge_agent_options(New, Old), 787 ?DBG("merging agent env -> mib-server merged: " 788 "~n ~p | ~p -> ~p", [New, Old, MibServer]), 789 MibServer. 790 791merge_or_replace_agent_env_symbolic_store(New, Old) -> 792 SymbolicStore = merge_agent_options(New, Old), 793 ?DBG("merging agent env -> symbolic-store merged: " 794 "~n ~p | ~p -> ~p", [New, Old, SymbolicStore]), 795 SymbolicStore. 796 797merge_or_replace_agent_env_note_store(New, Old) -> 798 NoteStore = merge_agent_options(New, Old), 799 ?DBG("merging agent env -> note-store merged: " 800 "~n ~p | ~p -> ~p", [New, Old, NoteStore]), 801 NoteStore. 802 803merge_or_replace_agent_env_net_if(New, Old) -> 804 NetIf = merge_agent_options(New, Old), 805 ?DBG("merging agent env -> net-if merged: " 806 "~n ~p | ~p -> ~p", [New, Old, NetIf]), 807 NetIf. 808 809merge_agent_options([], Options) -> 810 lists:keysort(1, Options); 811merge_agent_options([{Key, _Value} = Opt|Opts], Options) -> 812 case lists:keysearch(Key, 1, Options) of 813 {value, _} -> 814 NewOptions = lists:keyreplace(Key, 1, Options, Opt), 815 merge_agent_options(Opts, NewOptions); 816 false -> 817 merge_agent_options(Opts, [Opt|Options]) 818 end. 819 820 821stop_agent(Config) when is_list(Config) -> 822 ?IPRINT("stop_agent -> entry with" 823 "~n Config: ~p",[Config]), 824 825 826 %% Stop the sub-agent (the agent supervisor) 827 {SubSup, SubPar} = ?config(snmp_sub, Config), 828 ?IPRINT("stop_agent -> attempt to stop sub agent (~p)" 829 "~n Sub Sup info: " 830 "~n ~p" 831 "~n Sub Par info: " 832 "~n ~p", 833 [SubSup, ?PINFO(SubSup), ?PINFO(SubPar)]), 834 stop_sup(SubSup, SubPar), 835 Config2 = lists:keydelete(snmp_sub, 1, Config), 836 837 838 %% Stop the master-agent (the top agent supervisor) 839 {MasterSup, MasterPar} = ?config(snmp_sup, Config), 840 ?IPRINT("stop_agent -> attempt to stop master agent (~p)" 841 "~n Master Sup: " 842 "~n ~p" 843 "~n Master Par: " 844 "~n ~p" 845 "~n Agent Info: " 846 "~n ~p", 847 [MasterSup, 848 ?PINFO(MasterSup), ?PINFO(MasterPar), 849 agent_info(MasterSup)]), 850 stop_sup(MasterSup, MasterPar), 851 Config3 = lists:keydelete(snmp_sup, 1, Config2), 852 853 854 %% Stop the top supervisor (of the snmp app) 855 AppSup = ?config(snmp_app_sup, Config), 856 ?IPRINT("stop_agent -> attempt to app sup ~p" 857 "~n App Sup: ~p", 858 [AppSup, ?PINFO(AppSup)]), 859 Config4 = lists:keydelete(snmp_app_sup, 1, Config3), 860 861 862 ?IPRINT("stop_agent -> done", []), 863 Config4. 864 865 866start_sup(Env) -> 867 case (catch snmp_app_sup:start_agent(normal, Env)) of 868 {ok, S} -> 869 ?DBG("start_agent -> started, Sup: ~p", [S]), 870 S; 871 872 Else -> 873 ?EPRINT("start_agent -> unknown result: ~n~p", [Else]), 874 %% Get info about the apps we depend on 875 ?FAIL({start_failed, Else, ?IS_MNESIA_RUNNING()}) 876 end. 877 878stop_sup(Pid, _) when (node(Pid) =:= node()) -> 879 case (catch process_info(Pid)) of 880 PI when is_list(PI) -> 881 ?IPRINT("stop_sup -> attempt to stop ~p", [Pid]), 882 Ref = erlang:monitor(process, Pid), 883 exit(Pid, kill), 884 await_stopped(Pid, Ref); 885 {'EXIT', _Reason} -> 886 ?IPRINT("stop_sup -> ~p not running", [Pid]), 887 ok 888 end; 889stop_sup(Pid, _) -> 890 ?IPRINT("stop_sup -> attempt to stop ~p", [Pid]), 891 Ref = erlang:monitor(process, Pid), 892 ?IPRINT("stop_sup -> Ref: ~p", [Ref]), 893 exit(Pid, kill), 894 await_stopped(Pid, Ref). 895 896await_stopped(Pid, Ref) -> 897 receive 898 {'DOWN', Ref, process, Pid, _Reason} -> 899 ?DBG("received down message for ~p", [Pid]), 900 ok 901 after 10000 -> 902 ?EPRINT("await_stopped -> timeout for ~p",[Pid]), 903 erlang:demonitor(Ref), 904 ?FAIL({failed_stop,Pid}) 905 end. 906 907 908%% --- start subagent supervisor --- 909 910start_sub_sup(Node, Dir) -> 911 rpc:call(Node, ?MODULE, start_sub_sup, [Dir]). 912 913start_sub_sup(Dir) -> 914 ?DBG("start_sub -> entry",[]), 915 Opts = [{db_dir, Dir}, 916 {supervisor, [{verbosity, trace}]}], 917 {ok, P} = snmpa_supervisor:start_sub_sup(Opts), 918 unlink(P), 919 {ok, {P, self()}}. 920 921 922%% --- start and stop subagents --- 923 924start_subagent(SaNode, RegTree, Mib) -> 925 ?DBG("start_subagent -> entry with" 926 "~n SaNode: ~p" 927 "~n RegTree: ~p" 928 "~n Mib: ~p", [SaNode, RegTree, Mib]), 929 MA = whereis(snmp_master_agent), 930 ?DBG("start_subagent -> MA: ~p", [MA]), 931 MibDir = get(mib_dir), 932 Mib1 = join(MibDir, Mib), 933 Mod = snmpa_supervisor, 934 Func = start_sub_agent, 935 Args = [MA, RegTree, [Mib1]], 936 case rpc:call(SaNode, Mod, Func, Args) of 937 {ok, SA} -> 938 ?DBG("start_subagent -> SA: ~p", [SA]), 939 {ok, SA}; 940 Error -> 941 ?FAIL({subagent_start_failed, SaNode, Error, [MA, RegTree, Mib1]}) 942 end. 943 944stop_subagent(SA) -> 945 ?DBG("stop_subagent -> entry with" 946 "~n SA: ~p", [SA]), 947 rpc:call(node(SA), snmpa_supervisor, stop_sub_agent, [SA]). 948 949 950mibs(StdMibDir,MibDir) -> 951 [join(StdMibDir, ?v1_2("STANDARD-MIB.bin", "SNMPv2-MIB.bin")), 952 join(MibDir, "OLD-SNMPEA-MIB.bin"), 953 join(StdMibDir, "SNMP-FRAMEWORK-MIB"), 954 join(StdMibDir, "SNMP-MPD-MIB"), 955 join(StdMibDir, "SNMP-VIEW-BASED-ACM-MIB"), 956 join(StdMibDir, "SNMP-USER-BASED-SM-MIB"), 957 join(StdMibDir, "SNMP-TARGET-MIB"), 958 join(StdMibDir, "SNMP-NOTIFICATION-MIB"), 959 join(MibDir, "Klas1.bin"), 960 join(MibDir, "Klas2.bin"), 961 join(MibDir, "Klas3.bin"), 962 join(MibDir, "Klas4.bin"), 963 join(MibDir, "SA-MIB.bin"), 964 join(MibDir, "TestTrap.bin"), 965 join(MibDir, "Test1.bin"), 966 join(MibDir, "Test2.bin"), 967 join(MibDir, "TestTrapv2.bin")]. 968 969 970%% --- various mib load/unload functions --- 971 972load_master(Mib) -> 973 ?DBG("load_master -> entry with" 974 "~n Mib: ~p", [Mib]), 975 snmpa:unload_mib(snmp_master_agent, Mib), % Unload for safety 976 ok = snmpa:load_mib(snmp_master_agent, join(get(mib_dir), Mib)). 977 978load_master_std(Mib) -> 979 ?DBG("load_master_std -> entry with" 980 "~n Mib: ~p", [Mib]), 981 snmpa:unload_mib(snmp_master_agent, Mib), % Unload for safety 982 ok = snmpa:load_mibs(snmp_master_agent, join(get(std_mib_dir), Mib)). 983 984unload_master(Mib) -> 985 ?DBG("unload_master -> entry with" 986 "~n Mib: ~p", [Mib]), 987 ok = snmpa:unload_mib(snmp_master_agent, Mib). 988 989loaded_mibs() -> 990 ?DBG("loaded_mibs -> entry",[]), 991 Info = snmpa:info(snmp_master_agent), 992 {value, {loaded_mibs, Mibs}} = lists:keysearch(loaded_mibs, 1, Info), 993 [atom_to_list(Mib) || {Mib,_,_} <- Mibs]. 994 995unload_mibs(Mibs) -> 996 ?DBG("unload_mibs -> entry with" 997 "~n Mibs: ~p", [Mibs]), 998 ok = snmpa:unload_mibs(snmp_master_agent, Mibs). 999 1000 1001agent_info(Sup) -> 1002 ?DBG("agent_info -> entry with" 1003 "~n Sup: ~p", [Sup]), 1004 rpc:call(node(Sup), snmpa, info, []). 1005 1006 1007%% --- 1008%% The first two arguments are simple to be able to find where in the 1009%% (test) code this call is made. 1010 1011expect(Mod, Line, What) -> 1012 Fun = fun() -> do_expect(What) end, 1013 expect2(Mod, Line, Fun). 1014 1015expect(Mod, Line, What, ExpVBs) -> 1016 Fun = fun() -> do_expect(What, ExpVBs) end, 1017 expect2(Mod, Line, Fun). 1018 1019expect(Mod, Line, Error, Index, ExpVBS) -> 1020 Fun = fun() -> do_expect(Error, Index, ExpVBS) end, 1021 expect2(Mod, Line, Fun). 1022 1023expect(Mod, Line, Type, Enterp, Generic, Specific, ExpVBs) -> 1024 Fun = fun() -> do_expect(Type, Enterp, Generic, Specific, ExpVBs) end, 1025 expect2(Mod, Line, Fun). 1026 1027expect2(Mod, Line, F) -> 1028 io_format_expect("for ~w:~w", [Mod, Line]), 1029 case F() of 1030 {error, Reason} -> 1031 io_format_expect("failed at ~w:~w => " 1032 "~n ~p", [Mod, Line, Reason]), 1033 throw({error, {expect, Mod, Line, Reason}}); 1034 Else -> 1035 io_format_expect("result for ~w:~w => " 1036 "~n ~p", [Mod, Line, Else]), 1037 Else 1038 end. 1039 1040 1041%% ---------------------------------------------------------------------- 1042 1043-define(BASE_REQ_TIMEOUT, 3500). 1044 1045get_timeout() -> 1046 %% Try to figure out how "fast" a machine is. 1047 %% We assume that the number of schedulers 1048 %% (which depends on the number of core:s) 1049 %% effect the performance of the host... 1050 %% This is obviously not enough. The network 1051 %% also matterns, clock freq or the CPU, ... 1052 %% But its better than what we had before... 1053 case erlang:system_info(schedulers) of 1054 N when is_integer(N) -> 1055 ?BASE_REQ_TIMEOUT + timer:seconds(10 div N); 1056 _ -> 1057 ?BASE_REQ_TIMEOUT 1058 end. 1059 1060receive_pdu(To) -> 1061 receive 1062 {snmp_pdu, PDU} when is_record(PDU, pdu) -> 1063 PDU 1064 after To -> 1065 {error, timeout} 1066 end. 1067 1068receive_trap(To) -> 1069 receive 1070 {snmp_pdu, PDU} when is_record(PDU, trappdu) -> 1071 PDU 1072 after To -> 1073 {error, timeout} 1074 end. 1075 1076 1077io_format_expect(F) -> 1078 io_format_expect(F, []). 1079 1080io_format_expect(F, A) -> 1081 ?IPRINT("EXPECT " ++ F, A). 1082 1083 1084do_expect(Expect) when is_atom(Expect) -> 1085 do_expect({Expect, get_timeout()}); 1086 1087do_expect({any_pdu, To}) 1088 when is_integer(To) orelse (To =:= infinity) -> 1089 io_format_expect("any PDU"), 1090 receive_pdu(To); 1091 1092do_expect({any_trap, To}) -> 1093 io_format_expect("any TRAP within ~w", [To]), 1094 receive_trap(To); 1095 1096do_expect({timeout, To}) -> 1097 io_format_expect("nothing within ~w", [To]), 1098 receive 1099 X -> 1100 {error, {unexpected, X}} 1101 after 1102 To -> 1103 ok 1104 end; 1105 1106do_expect({Err, To}) 1107 when (is_atom(Err) andalso 1108 ((is_integer(To) andalso To > 0) orelse (To =:= infinity))) -> 1109 io_format_expect("error ~w within ~w", [Err, To]), 1110 do_expect({{error, Err}, To}); 1111 1112do_expect({error, Err}) when is_atom(Err) -> 1113 Check = fun(_, R) -> R end, 1114 io_format_expect("error ~w", [Err]), 1115 do_expect2(Check, any, Err, any, any, get_timeout()); 1116do_expect({{error, Err}, To}) -> 1117 Check = fun(_, R) -> R end, 1118 io_format_expect("error ~w within ~w", [Err, To]), 1119 do_expect2(Check, any, Err, any, any, To); 1120 1121%% exp_varbinds() -> [exp_varbind()] 1122%% exp_varbind() -> any | {Oid, any} | {Oid, Value} 1123%% Oid -> [integer()] 1124%% Value -> term() 1125%% ExpVBs -> exp_varbinds() | {VbsCondition, exp_varbinds()} 1126do_expect(ExpVBs) -> 1127 Check = fun(_, R) -> R end, 1128 io_format_expect("'get-response'" 1129 "~n with" 1130 "~n Varbinds: ~p", [ExpVBs]), 1131 do_expect2(Check, 'get-response', noError, 0, ExpVBs, get_timeout()). 1132 1133 1134do_expect(v2trap, ExpVBs) -> 1135 Check = fun(_, R) -> R end, 1136 io_format_expect("'snmpv2-trap' with" 1137 "~n Varbinds: ~p", [ExpVBs]), 1138 do_expect2(Check, 'snmpv2-trap', noError, 0, ExpVBs, get_timeout()); 1139 1140 1141do_expect(report, ExpVBs) -> 1142 Check = fun(_, R) -> R end, 1143 io_format_expect("'report' with" 1144 "~n Varbinds: ~p", [ExpVBs]), 1145 do_expect2(Check, 'report', noError, 0, ExpVBs, get_timeout()); 1146 1147 1148do_expect(inform, ExpVBs) -> 1149 do_expect({inform, true}, ExpVBs); 1150 1151do_expect({inform, false}, ExpVBs) -> 1152 Check = fun(_, R) -> R end, 1153 io_format_expect("'inform-request' (false) with" 1154 "~n Varbinds: ~p", [ExpVBs]), 1155 do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()); 1156 1157do_expect({inform, true}, ExpVBs) -> 1158 Check = 1159 fun(PDU, ok) -> 1160 RespPDU = PDU#pdu{type = 'get-response', 1161 error_status = noError, 1162 error_index = 0}, 1163 snmp_test_mgr:rpl(RespPDU), 1164 ok; 1165 (_, Err) -> 1166 Err 1167 end, 1168 io_format_expect("'inform-request' (true) with" 1169 "~n Varbinds: ~p", [ExpVBs]), 1170 do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()); 1171 1172do_expect({inform, {error, EStat, EIdx}}, ExpVBs) 1173 when is_atom(EStat) andalso is_integer(EIdx) -> 1174 Check = 1175 fun(PDU, ok) -> 1176 RespPDU = PDU#pdu{type = 'get-response', 1177 error_status = EStat, 1178 error_index = EIdx}, 1179 snmp_test_mgr:rpl(RespPDU), 1180 ok; 1181 (_, Err) -> 1182 Err 1183 end, 1184 io_format_expect("'inform-request' (error) with" 1185 "~n Error Status: ~p" 1186 "~n Error Index: ~p" 1187 "~n Varbinds: ~p", [EStat, EIdx, ExpVBs]), 1188 do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()). 1189 1190 1191do_expect(Err, Idx, ExpVBs) -> 1192 do_expect(Err, Idx, ExpVBs, get_timeout()). 1193 1194do_expect(Err, Idx, ExpVBs, To) 1195 when is_atom(Err) andalso 1196 (is_integer(Idx) orelse is_list(Idx) orelse (Idx == any)) -> 1197 Check = fun(_, R) -> R end, 1198 io_format_expect("'get-response' withing ~w ms with" 1199 "~n Error: ~p" 1200 "~n Index: ~p" 1201 "~n Varbinds: ~p", [To, Err, Idx, ExpVBs]), 1202 do_expect2(Check, 'get-response', Err, Idx, ExpVBs, To). 1203 1204 1205do_expect(Type, Enterp, Generic, Specific, ExpVBs) -> 1206 do_expect(Type, Enterp, Generic, Specific, ExpVBs, get_timeout()). 1207 1208do_expect(trap, Enterp, Generic, Specific, ExpVBs, To) -> 1209 io_format_expect("trap within ~w ms with" 1210 "~n Enterp: ~w" 1211 "~n Generic: ~w" 1212 "~n Specific: ~w" 1213 "~n Varbinds: ~w", 1214 [To, Enterp, Generic, Specific, ExpVBs]), 1215 PureE = purify_oid(Enterp), 1216 case receive_trap(To) of 1217 #trappdu{enterprise = PureE, 1218 generic_trap = Generic, 1219 specific_trap = Specific, 1220 varbinds = VBs} -> 1221 check_vbs(purify_oids(ExpVBs), VBs); 1222 1223 #trappdu{enterprise = Ent2, 1224 generic_trap = G2, 1225 specific_trap = Spec2, 1226 varbinds = VBs} -> 1227 {error, {unexpected_trap, 1228 {PureE, Generic, Specific, ExpVBs}, 1229 {Ent2, G2, Spec2, VBs}}}; 1230 1231 {error, timeout} = Error -> 1232 SysEvs = snmp_test_global_sys_monitor:events(), 1233 io_format_expect("[expecting trap] got timeout when system events:" 1234 "~n ~p", [SysEvs]), 1235 if 1236 (SysEvs =:= []) -> 1237 Error; 1238 true -> 1239 skip({system_events, SysEvs}) 1240 end; 1241 1242 1243 Error -> 1244 Error 1245 end. 1246 1247 1248do_expect2(Check, Type, Err, Idx, ExpVBs, To) 1249 when is_function(Check) andalso 1250 is_atom(Type) andalso 1251 is_atom(Err) andalso 1252 (is_integer(Idx) orelse is_list(Idx) orelse (Idx =:= any)) andalso 1253 (is_list(ExpVBs) orelse (ExpVBs =:= any)) andalso 1254 (is_integer(To) orelse (To =:= infinity)) -> 1255 1256 case receive_pdu(To) of 1257 1258 #pdu{type = Type, 1259 error_status = Err, 1260 error_index = Idx} when ExpVBs =:= any -> 1261 io_format_expect("received expected pdu (1)"), 1262 ok; 1263 1264 #pdu{type = Type, 1265 request_id = ReqId, 1266 error_status = Err2, 1267 error_index = Idx} when ExpVBs =:= any -> 1268 io_format_expect("received expected pdu with " 1269 "unexpected error status (2): " 1270 "~n Error Status: ~p", [Err2]), 1271 {error, {unexpected_error_status, Err, Err2, ReqId}}; 1272 1273 #pdu{error_status = Err} when (Type =:= any) andalso 1274 (Idx =:= any) andalso 1275 (ExpVBs =:= any) -> 1276 io_format_expect("received expected pdu (3)"), 1277 ok; 1278 1279 #pdu{request_id = ReqId, 1280 error_status = Err2} when (Type =:= any) andalso 1281 (Idx =:= any) andalso 1282 (ExpVBs =:= any) -> 1283 io_format_expect("received expected pdu with " 1284 "unexpected error status (4): " 1285 "~n Error Status: ~p", [Err2]), 1286 {error, {unexpected_error_status, Err, Err2, ReqId}}; 1287 1288 #pdu{type = Type, 1289 error_status = Err} when (Idx =:= any) andalso 1290 (ExpVBs =:= any) -> 1291 io_format_expect("received expected pdu (5)", []), 1292 ok; 1293 1294 #pdu{type = Type, 1295 request_id = ReqId, 1296 error_status = Err2} when (Idx =:= any) andalso 1297 (ExpVBs =:= any) -> 1298 io_format_expect("received expected pdu with " 1299 "unexpected error status (6): " 1300 "~n Error Status: ~p", [Err2]), 1301 {error, {unexpected_error_status, Err, Err2, ReqId}}; 1302 1303 #pdu{type = Type, 1304 request_id = ReqId, 1305 error_status = Err, 1306 error_index = EI} when is_list(Idx) andalso (ExpVBs =:= any) -> 1307 case lists:member(EI, Idx) of 1308 true -> 1309 io_format_expect("received expected pdu with " 1310 "expected error index (7)"), 1311 ok; 1312 false -> 1313 io_format_expect("received expected pdu with " 1314 "unexpected error index (8): " 1315 "~n Error Index: ~p", [EI]), 1316 {error, {unexpected_error_index, EI, Idx, ReqId}} 1317 end; 1318 1319 #pdu{type = Type, 1320 request_id = ReqId, 1321 error_status = Err2, 1322 error_index = EI} when is_list(Idx) andalso (ExpVBs =:= any) -> 1323 case lists:member(EI, Idx) of 1324 true -> 1325 io_format_expect("received expected pdu with " 1326 "unexpected error status (9): " 1327 "~n Error Status: ~p", [Err2]), 1328 {error, {unexpected_error_status, Err, Err2, ReqId}}; 1329 false -> 1330 io_format_expect("received expected pdu with " 1331 "unexpected error (10): " 1332 "~n Error Status: ~p" 1333 "~n Error index: ~p", [Err2, EI]), 1334 {error, {unexpected_error, {Err, Idx}, {Err2, EI}, ReqId}} 1335 end; 1336 1337 #pdu{type = Type2, 1338 request_id = ReqId, 1339 error_status = Err2, 1340 error_index = Idx2} when ExpVBs =:= any -> 1341 io_format_expect("received unexpected pdu with (11) " 1342 "~n Type: ~p" 1343 "~n ReqId: ~p" 1344 "~n Error status: ~p" 1345 "~n Error index: ~p", 1346 [Type2, ReqId, Err2, Idx2]), 1347 {error, 1348 {unexpected_pdu, 1349 {Type, Err, Idx}, {Type2, Err2, Idx2}, ReqId}}; 1350 1351 #pdu{type = Type, 1352 error_status = Err, 1353 error_index = Idx, 1354 varbinds = VBs} = PDU -> 1355 io_format_expect("received pdu (12): " 1356 "~n [exp] Type: ~p" 1357 "~n [exp] Error Status: ~p" 1358 "~n [exp] Error Index: ~p" 1359 "~n VBs: ~p" 1360 "~nwhen" 1361 "~n ExpVBs: ~p", 1362 [Type, Err, Idx, VBs, ExpVBs]), 1363 Check(PDU, check_vbs(purify_oids(ExpVBs), VBs)); 1364 1365 #pdu{type = Type, 1366 error_status = Err, 1367 varbinds = VBs} = PDU when Idx =:= any -> 1368 io_format_expect("received pdu (13): " 1369 "~n [exp] Type: ~p" 1370 "~n [exp] Error Status: ~p" 1371 "~n VBs: ~p" 1372 "~nwhen" 1373 "~n ExpVBs: ~p", 1374 [Type, Err, VBs, ExpVBs]), 1375 Check(PDU, check_vbs(purify_oids(ExpVBs), VBs)); 1376 1377 #pdu{type = Type, 1378 request_id = ReqId, 1379 error_status = Err, 1380 error_index = EI, 1381 varbinds = VBs} = PDU when is_list(Idx) -> 1382 io_format_expect("received pdu (14): " 1383 "~n [exp] Type: ~p" 1384 "~n ReqId: ~p" 1385 "~n [exp] Error Status: ~p" 1386 "~n [exp] Error Index: ~p" 1387 "~n VBs: ~p" 1388 "~nwhen" 1389 "~n ExpVBs: ~p", 1390 [Type, ReqId, Err, EI, VBs, ExpVBs]), 1391 PureVBs = purify_oids(ExpVBs), 1392 case lists:member(EI, Idx) of 1393 true -> 1394 Check(PDU, check_vbs(PureVBs, VBs)); 1395 false -> 1396 {error, {unexpected_error_index, Idx, EI, ReqId}} 1397 end; 1398 1399 #pdu{type = Type2, 1400 request_id = ReqId, 1401 error_status = Err2, 1402 error_index = Idx2, 1403 varbinds = VBs2} -> 1404 io_format_expect("received unexpected pdu with (15) " 1405 "~n Type: ~p" 1406 "~n ReqId: ~p" 1407 "~n Error status: ~p" 1408 "~n Error index: ~p" 1409 "~n Varbinds: ~p", 1410 [Type2, ReqId, Err2, Idx2, VBs2]), 1411 {error, 1412 {unexpected_pdu, 1413 {Type, Err, Idx, purify_oids(ExpVBs)}, 1414 {Type2, Err2, Idx2, VBs2}, 1415 ReqId}}; 1416 1417 1418 {error, timeout} = Error -> 1419 SysEvs = snmp_test_global_sys_monitor:events(), 1420 io_format_expect("got timeout (16) when system events:" 1421 "~n ~p", [SysEvs]), 1422 if 1423 (SysEvs =:= []) -> 1424 Error; 1425 true -> 1426 skip({system_events, SysEvs}) 1427 end; 1428 1429 1430 Error -> 1431 io_format_expect("received error (17): " 1432 "~n Error: ~p", [Error]), 1433 Error 1434 end. 1435 1436 1437 1438check_vbs([], []) -> 1439 ok; 1440check_vbs(Exp, []) -> 1441 {error, {to_few_vbs, Exp}}; 1442check_vbs([], VBs) -> 1443 {error, {to_many_vbs, VBs}}; 1444check_vbs([any|Exp], [_|VBs]) -> 1445 check_vbs(Exp, VBs); 1446check_vbs([{Oid, any}|Exp], [#varbind{oid = Oid}|VBs]) -> 1447 check_vbs(Exp, VBs); 1448check_vbs([{Oid, Val}|Exp], [#varbind{oid = Oid, value = Val}|VBs]) -> 1449 check_vbs(Exp, VBs); 1450check_vbs([{Oid, Val1}|_], [#varbind{oid = Oid, value = Val2}|_]) -> 1451 {error, {unexpected_vb_value, Oid, Val1, Val2}}; 1452check_vbs([{Oid1, _}|_], [#varbind{oid = Oid2}|_]) -> 1453 {error, {unexpected_vb_oid, Oid1, Oid2}}. 1454 1455 1456purify_oids({VbsCondition, VBs}) 1457 when ((VbsCondition =:= true) orelse (VbsCondition =:= false)) andalso 1458 is_list(VBs) -> 1459 {VbsCondition, do_purify_oids(VBs)}; 1460purify_oids(VBs) when is_list(VBs) -> 1461 do_purify_oids(VBs). 1462 1463do_purify_oids([]) -> 1464 []; 1465do_purify_oids([{XOid, Q}|T]) -> 1466 [{purify_oid(XOid), Q} | do_purify_oids(T)]. 1467 1468 1469purify_oid(Oid) -> 1470 io:format("~w:purify_oid -> entry with" 1471 "~n Oid: ~w" 1472 "~n", 1473 [?MODULE, Oid]), 1474 case (catch snmp_test_mgr:purify_oid(Oid)) of 1475 {error, Reason} -> 1476 io:format("~w:purify_oid -> error: " 1477 "~n Reason: ~p" 1478 "~n", 1479 [?MODULE, Reason]), 1480 exit({malformed_oid, Reason}); 1481 {ok, Oid2} when is_list(Oid2) -> 1482 io:format("~w:purify_oid -> ok: " 1483 "~n Oid2: ~p" 1484 "~n", 1485 [?MODULE, Oid2]), 1486 Oid2; 1487 Error -> 1488 io:format("~w:purify_oid -> unexpected return value: " 1489 "~n Error: ~p" 1490 "~n", 1491 [?MODULE, Error]), 1492 exit({unexpected_purify_result, Error}) 1493 1494 end. 1495 1496 1497%% ---------------------------------------------------------------------- 1498 1499get_req(Id, Vars) -> 1500 ?DBG("get_req -> entry with" 1501 "~n Id: ~p" 1502 "~n Vars: ~p",[Id,Vars]), 1503 snmp_test_mgr:g(Vars), 1504 ?DBG("get_req -> await response",[]), 1505 case snmp_test_mgr:get_response(Id, Vars) of 1506 {ok, Val} -> 1507 ?DBG("get_req -> response: ~p",[Val]), 1508 Val; 1509 {error, _, {_ExpFmt, ExpArg}, {_ActFmt, ActArg}} -> 1510 ?DBG("get_req -> error for ~p: " 1511 "~n " ++ _ExpFmt ++ 1512 "~n " ++ _ActFmt, 1513 [Id] ++ ExpArg ++ ActArg), 1514 exit({unexpected_response, ExpArg, ActArg}); 1515 Error -> 1516 ?DBG("get_req -> error: ~n~p",[Error]), 1517 exit({unknown, Error}) 1518 end. 1519 1520 1521get_next_req(Vars) -> 1522 ?DBG("get_next_req -> entry with" 1523 "~n Vars: ~p", [Vars]), 1524 snmp_test_mgr:gn(Vars), 1525 ?DBG("get_next_req -> await response",[]), 1526 Response = snmp_test_mgr:receive_response(), 1527 ?DBG("get_next_req -> response: ~p",[Response]), 1528 Response. 1529 1530 1531%% --- start and stop nodes --- 1532 1533start_node(Name) -> 1534 ?IPRINT("start_node -> entry with" 1535 "~n Name: ~p" 1536 "~n when" 1537 "~n hostname of this node: ~p", 1538 [Name, list_to_atom(?HOSTNAME(node()))]), 1539 1540 Pa = filename:dirname(code:which(?MODULE)), 1541 ?DBG("start_node -> Pa: ~p", [Pa]), 1542 1543 A = " -pa " ++ Pa ++ 1544 " -s " ++ atom_to_list(snmp_test_sys_monitor) ++ " start" ++ 1545 " -s global sync", 1546 case ?START_NODE(Name, A) of 1547 {ok, Node} -> 1548 ?DBG("start_node -> Node: ~p", [Node]), 1549 global:sync(), 1550 {ok, Node}; 1551 {error, Reason} -> 1552 ?WPRINT("start_node -> failed starting node ~p:" 1553 "~n Reason: ~p", [Name, Reason]), 1554 ?line ?SKIP({failed_start_node, Reason}); 1555 Else -> 1556 ?EPRINT("start_node -> failed starting node ~p:" 1557 "~n ~p", [Name, Else]), 1558 ?line ?FAIL(Else) 1559 end. 1560 1561 1562stop_node(Node) -> 1563 ?IPRINT("stop_node -> Node: ~p", [Node]), 1564 ?STOP_NODE(Node). 1565 1566 1567%%%----------------------------------------------------------------- 1568%%% Configuration 1569%%%----------------------------------------------------------------- 1570 1571config(Vsns, MgrDir, AgentConfDir, MIp, AIp) -> 1572 config(Vsns, MgrDir, AgentConfDir, MIp, AIp, inet). 1573 1574config(Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily) -> 1575 ?IPRINT("config -> entry with" 1576 "~n Vsns: ~p" 1577 "~n MgrDir: ~p" 1578 "~n AgentConfDir: ~p" 1579 "~n MIp: ~p" 1580 "~n AIp: ~p" 1581 "~n IpFamily: ~p", 1582 [Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily]), 1583 ?line {Domain, ManagerAddr} = 1584 case IpFamily of 1585 inet6 -> 1586 Ipv6Domain = transportDomainUdpIpv6, 1587 AgentIpv6Addr = {AIp, 4000}, 1588 ManagerIpv6Addr = {MIp, ?TRAP_UDP}, 1589 ?line ok = 1590 snmp_config:write_agent_snmp_files( 1591 AgentConfDir, Vsns, 1592 Ipv6Domain, ManagerIpv6Addr, AgentIpv6Addr, "test"), 1593 {Ipv6Domain, ManagerIpv6Addr}; 1594 _ -> 1595 ?line ok = 1596 snmp_config:write_agent_snmp_files( 1597 AgentConfDir, Vsns, MIp, ?TRAP_UDP, AIp, 4000, "test"), 1598 {snmpUDPDomain, {MIp, ?TRAP_UDP}} 1599 end, 1600 1601 ?line case update_usm(Vsns, AgentConfDir) of 1602 true -> 1603 ?line copy_file(join(AgentConfDir, "usm.conf"), 1604 join(MgrDir, "usm.conf")), 1605 ?line update_usm_mgr(Vsns, MgrDir); 1606 false -> 1607 ?line ok 1608 end, 1609 ?line update_community(Vsns, AgentConfDir), 1610 ?line update_vacm(Vsns, AgentConfDir), 1611 ?line write_target_addr_conf(AgentConfDir, Domain, ManagerAddr, Vsns), 1612 ?line write_target_params_conf(AgentConfDir, Vsns), 1613 ?line write_notify_conf(AgentConfDir), 1614 ok. 1615 1616delete_files(Config) -> 1617 AgentDir = ?config(agent_dir, Config), 1618 delete_files(AgentDir, [db, conf]). 1619 1620delete_files(_AgentFiles, []) -> 1621 ok; 1622delete_files(AgentDir, [DirName|DirNames]) -> 1623 Dir = join(AgentDir, DirName), 1624 {ok, Files} = file:list_dir(Dir), 1625 lists:foreach(fun(FName) -> file:delete(join(Dir, FName)) end, 1626 Files), 1627 delete_files(AgentDir, DirNames). 1628 1629update_usm(Vsns, Dir) -> 1630 case lists:member(v3, Vsns) of 1631 true -> 1632 Conf = [{"agentEngine", "all-rights", "all-rights", zeroDotZero, 1633 usmNoAuthProtocol, "", "", 1634 usmNoPrivProtocol, "", "", "", "", ""}, 1635 1636 {"agentEngine", "no-rights", "no-rights", zeroDotZero, 1637 usmNoAuthProtocol, "", "", 1638 usmNoPrivProtocol, "", "", "", "", ""}, 1639 1640 {"agentEngine", "authMD5", "authMD5", zeroDotZero, 1641 usmHMACMD5AuthProtocol, "", "", 1642 usmNoPrivProtocol, "", "", "", "passwd_md5xxxxxx", ""}, 1643 1644 {"agentEngine", "authSHA", "authSHA", zeroDotZero, 1645 usmHMACSHAAuthProtocol, "", "", 1646 usmNoPrivProtocol, "", "", "", 1647 "passwd_shaxxxxxxxxxx", ""}, 1648 1649 {"agentEngine", "privDES", "privDES", zeroDotZero, 1650 usmHMACSHAAuthProtocol, "", "", 1651 usmDESPrivProtocol, "", "", "", 1652 "passwd_shaxxxxxxxxxx", "passwd_desxxxxxx"}, 1653 1654 {"mgrEngine", "all-rights", "all-rights", zeroDotZero, 1655 usmNoAuthProtocol, "", "", 1656 usmNoPrivProtocol, "", "", "", "", ""}, 1657 1658 {"mgrEngine", "no-rights", "no-rights", zeroDotZero, 1659 usmNoAuthProtocol, "", "", 1660 usmNoPrivProtocol, "", "", "", "", ""}, 1661 1662 {"mgrEngine", "authMD5", "authMD5", zeroDotZero, 1663 usmHMACMD5AuthProtocol, "", "", 1664 usmNoPrivProtocol, "", "", "", "passwd_md5xxxxxx", ""}, 1665 1666 {"mgrEngine", "authSHA", "authSHA", zeroDotZero, 1667 usmHMACSHAAuthProtocol, "", "", 1668 usmNoPrivProtocol, "", "", "", 1669 "passwd_shaxxxxxxxxxx", ""}, 1670 1671 {"mgrEngine", "privDES", "privDES", zeroDotZero, 1672 usmHMACSHAAuthProtocol, "", "", 1673 usmDESPrivProtocol, "", "", "", 1674 "passwd_shaxxxxxxxxxx", "passwd_desxxxxxx"}], 1675 ?line ok = snmp_config:update_agent_usm_config(Dir, Conf), 1676 true; 1677 false -> 1678 false 1679 end. 1680 1681update_usm_mgr(Vsns, Dir) -> 1682 case lists:member(v3, Vsns) of 1683 true -> 1684 Conf = [{"agentEngine", "newUser", "newUser", zeroDotZero, 1685 usmHMACSHAAuthProtocol, "", "", 1686 usmDESPrivProtocol, "", "", "", 1687 "passwd_shaxxxxxxxxxx", "passwd_desxxxxxx"}, 1688 1689 {"mgrEngine", "newUser", "newUser", zeroDotZero, 1690 usmHMACSHAAuthProtocol, "", "", 1691 usmDESPrivProtocol, "", "", "", 1692 "passwd_shaxxxxxxxxxx", "passwd_desxxxxxx"}], 1693 1694 ?line ok = snmp_config:update_agent_usm_config(Dir, Conf), 1695 true; 1696 false -> 1697 false 1698 end. 1699 1700rewrite_usm_mgr(Dir, ShaKey, DesKey) -> 1701 ?line ok = file:rename(join(Dir,"usm.conf"), 1702 join(Dir,"usm.old")), 1703 Conf = [{"agentEngine", "newUser", "newUser", zeroDotZero, 1704 usmHMACSHAAuthProtocol, "", "", 1705 usmDESPrivProtocol, "", "", "", ShaKey, DesKey}, 1706 {"mgrEngine", "newUser", "newUser", zeroDotZero, 1707 usmHMACSHAAuthProtocol, "", "", 1708 usmDESPrivProtocol, "", "", "", ShaKey, DesKey}], 1709 ?line ok = snmp_config:write_agent_usm_config(Dir, "", Conf). 1710 1711reset_usm_mgr(Dir) -> 1712 ?line ok = file:rename(join(Dir,"usm.old"), 1713 join(Dir,"usm.conf")). 1714 1715 1716update_community([v3], _Dir) -> 1717 ok; 1718update_community(_, Dir) -> 1719 Conf = [{"no-rights", "no-rights", "no-rights", "", ""}], 1720 ?line ok = snmp_config:update_agent_community_config(Dir, Conf). 1721 1722 1723-define(tDescr_instance, [1,3,6,1,2,1,16,1,0]). 1724update_vacm(_Vsn, Dir) -> 1725 Conf = [{vacmSecurityToGroup, usm, "authMD5", "initial"}, 1726 {vacmSecurityToGroup, usm, "authSHA", "initial"}, 1727 {vacmSecurityToGroup, usm, "privDES", "initial"}, 1728 {vacmSecurityToGroup, usm, "newUser", "initial"}, 1729 {vacmViewTreeFamily, "internet", ?tDescr_instance, 1730 excluded, null}], 1731 ?line ok = snmp_config:update_agent_vacm_config(Dir, Conf). 1732 1733 1734write_community_conf(Dir, Conf) -> 1735 ?line ok = snmp_config:write_agent_community_config(Dir, "", Conf). 1736 1737write_target_addr_conf(Dir, Conf) -> 1738 ?line ok = snmp_config:write_agent_target_addr_config(Dir, "", Conf). 1739 1740write_target_addr_conf(Dir, Ip_or_Domain, Port_or_Addr, Vsns) -> 1741 ?line ok = 1742 snmp_config:write_agent_snmp_target_addr_conf( 1743 Dir, Ip_or_Domain, Port_or_Addr, Vsns). 1744 1745rewrite_target_addr_conf(Dir, NewPort) -> 1746 ?DBG("rewrite_target_addr_conf -> entry with" 1747 "~n NewPort: ~p", [NewPort]), 1748 TAFile = join(Dir, "target_addr.conf"), 1749 case file:read_file_info(TAFile) of 1750 {ok, _} -> 1751 ok; 1752 {error, _R} -> 1753 ?WPRINT("failure reading file info of " 1754 "target address config file: ~p", [_R]), 1755 ok 1756 end, 1757 1758 ?line [TrapAddr|Addrs] = 1759 snmp_conf:read(TAFile, fun rewrite_target_addr_conf_check/1), 1760 1761 ?DBG("rewrite_target_addr_conf -> TrapAddr: ~p",[TrapAddr]), 1762 1763 NewAddrs = [rewrite_target_addr_conf2(NewPort,TrapAddr)|Addrs], 1764 1765 ?DBG("rewrite_target_addr_conf -> NewAddrs: ~p",[NewAddrs]), 1766 1767 ?line ok = file:rename(join(Dir,"target_addr.conf"), 1768 join(Dir,"target_addr.old")), 1769 1770 ?line ok = snmp_config:write_agent_target_addr_config(Dir, "", NewAddrs). 1771 1772rewrite_target_addr_conf_check(O) -> 1773 {ok,O}. 1774 1775rewrite_target_addr_conf2(NewPort, 1776 {Name, Ip, _Port, Timeout, Retry, 1777 "std_trap", EngineId}) -> 1778 ?IPRINT("rewrite_target_addr_conf2 -> entry with std_trap",[]), 1779 {Name,Ip,NewPort,Timeout,Retry,"std_trap",EngineId}; 1780rewrite_target_addr_conf2(_NewPort,O) -> 1781 ?IPRINT("rewrite_target_addr_conf2 -> entry with " 1782 "~n O: ~p",[O]), 1783 O. 1784 1785reset_target_addr_conf(Dir) -> 1786 ?line ok = file:rename(join(Dir, "target_addr.old"), 1787 join(Dir, "target_addr.conf")). 1788 1789write_target_params_conf(Dir, Vsns) -> 1790 F = fun(v1) -> {"target_v1", v1, v1, "all-rights", noAuthNoPriv}; 1791 (v2) -> {"target_v2", v2c, v2c, "all-rights", noAuthNoPriv}; 1792 (v3) -> {"target_v3", v3, usm, "all-rights", noAuthNoPriv} 1793 end, 1794 Conf = [F(Vsn) || Vsn <- Vsns], 1795 ?line ok = snmp_config:write_agent_target_params_config(Dir, "", Conf). 1796 1797rewrite_target_params_conf(Dir, SecName, SecLevel) 1798 when is_list(SecName) andalso is_atom(SecLevel) -> 1799 ?line ok = file:rename(join(Dir,"target_params.conf"), 1800 join(Dir,"target_params.old")), 1801 Conf = [{"target_v3", v3, usm, SecName, SecLevel}], 1802 ?line ok = snmp_config:write_agent_target_params_config(Dir, "", Conf). 1803 1804reset_target_params_conf(Dir) -> 1805 ?line ok = file:rename(join(Dir,"target_params.old"), 1806 join(Dir,"target_params.conf")). 1807 1808write_notify_conf(Dir) -> 1809 Conf = [{"standard trap", "std_trap", trap}, 1810 {"standard inform", "std_inform", inform}], 1811 ?line ok = snmp_config:write_agent_notify_config(Dir, "", Conf). 1812 1813write_view_conf(Dir) -> 1814 Conf = [{2, [1,3,6], included, null}, 1815 {2, ?tDescr_instance, excluded, null}], 1816 ?line ok = snmp_config:write_agent_view_config(Dir, "", Conf). 1817 1818 1819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1820 1821copy_file(From, To) -> 1822 {ok, Bin} = file:read_file(From), 1823 ok = file:write_file(To, Bin). 1824 1825 1826%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1827 1828display_memory_usage() -> 1829 Info = snmpa:info(snmp_master_agent), 1830 TreeSize = key1search(tree_size_bytes, Info), 1831 ProcMem = key1search(process_memory, Info), 1832 MibDbSize = key1search([db_memory,mib], Info), 1833 NodeDbSize = key1search([db_memory,node], Info), 1834 TreeDbSize = key1search([db_memory,tree], Info), 1835 ?IPRINT("Memory usage: " 1836 "~n Tree size: ~p" 1837 "~n Process memory size: ~p" 1838 "~n Mib db size: ~p" 1839 "~n Node db size: ~p" 1840 "~n Tree db size: ~p", 1841 [TreeSize, ProcMem, MibDbSize, NodeDbSize, TreeDbSize]). 1842 1843key1search([], Res) -> 1844 Res; 1845key1search([Key|Keys], List) when is_atom(Key) andalso is_list(List) -> 1846 case lists:keysearch(Key, 1, List) of 1847 {value, {Key, Val}} -> 1848 key1search(Keys, Val); 1849 false -> 1850 undefined 1851 end; 1852key1search(Key, List) when is_atom(Key) -> 1853 case lists:keysearch(Key, 1, List) of 1854 {value, {Key, Val}} -> 1855 Val; 1856 false -> 1857 undefined 1858 end. 1859 1860 1861regs() -> 1862 lists:sort(registered()). 1863 1864 1865rpc(Node, F, A) -> 1866 rpc:call(Node, snmpa, F, A). 1867 1868 1869join(Dir, File) -> 1870 filename:join(Dir, File). 1871 1872 1873skip(R) -> 1874 exit({skip, R}). 1875 1876