1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2004-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%%---------------------------------------------------------------------- 22%% Purpose: Utility functions for the (snmp manager) user test(s). 23%%---------------------------------------------------------------------- 24 25-module(snmp_manager_user_test_lib). 26 27-behaviour(snmpm_user). 28 29 30%%---------------------------------------------------------------------- 31%% Include files 32%%---------------------------------------------------------------------- 33-include_lib("common_test/include/ct.hrl"). 34-include("snmp_test_lib.hrl"). 35 36 37%%---------------------------------------------------------------------- 38%% External exports 39%%---------------------------------------------------------------------- 40-export([ 41 start_link/0, stop/1, 42 simulate_crash/2, 43 register/2, register/3, 44 register_monitor/2, register_monitor/3, 45 unregister/1, unregister/2, 46 register_agent/4 47 ]). 48 49%%---------------------------------------------------------------------- 50%% Internal exports 51%%---------------------------------------------------------------------- 52-export([ 53 user/1 54 ]). 55 56-export([ 57 handle_error/3, 58 handle_agent/5, 59 handle_agent/4, % For backwards compatibillity 60 handle_pdu/4, 61 handle_pdu/5, % For backwards compatibillity 62 handle_trap/3, 63 handle_trap/4, % For backwards compatibillity 64 handle_inform/3, 65 handle_inform/4, % For backwards compatibillity 66 handle_report/3, 67 handle_report/4 % For backwards compatibillity 68 ]). 69 70 71-record(state, {parent, ids = []}). 72 73 74%%---------------------------------------------------------------------- 75%% The user simulation API 76%%---------------------------------------------------------------------- 77 78start_link() -> 79 S = #state{parent = self()}, 80 proc_lib:start_link(?MODULE, user, [S]). 81 82stop(Pid) -> 83 cast(Pid, stop). 84 85simulate_crash(Pid, Reason) -> 86 call(Pid, {simulate_crash, Reason}). 87 88%% For backwards compatibillity 89register(Pid, Id) -> 90 call(Pid, {register, Id}). 91 92register(Pid, Id, DefaultAgentConfig) -> 93 call(Pid, {register, Id, DefaultAgentConfig}). 94 95%% For backwards compatibillity 96register_monitor(Pid, Id) -> 97 call(Pid, {register_monitor, Id}). 98 99register_monitor(Pid, Id, DefaultAgentConfig) -> 100 call(Pid, {register_monitor, Id, DefaultAgentConfig}). 101 102unregister(Pid) -> 103 call(Pid, unregister). 104 105unregister(Pid, Id) -> 106 call(Pid, {unregister, Id}). 107 108register_agent(Pid, Id, TargetName, AgentConfig) -> 109 call(Pid, {register_agent, Id, TargetName, AgentConfig}). 110 111user(#state{parent = Pid} = S) -> 112 proc_lib:init_ack(Pid, {ok, self()}), 113 user_loop(S). 114 115user_loop(#state{parent = Parent} = S) -> 116 receive 117 {stop, Parent} -> 118 exit(normal); 119 120 {{simulate_crash, Reason}, Parent, Ref} -> 121 reply(Parent, ok, Ref), 122 exit(Reason); 123 124 %% For backwards compatibillity 125 {{register, Id}, Parent, Ref} -> 126 IDs = S#state.ids, 127 case lists:member(Id, IDs) of 128 false -> 129 Res = snmpm:register_user(Id, ?MODULE, self()), 130 reply(Parent, Res, Ref), 131 user_loop(S#state{ids = [Id|IDs]}); 132 true -> 133 reply(Parent, {error, already_registered}, Ref), 134 user_loop(S) 135 end; 136 137 {{register, Id, DefaultAgentConf}, Parent, Ref} -> 138 IDs = S#state.ids, 139 case lists:member(Id, IDs) of 140 false -> 141 Res = snmpm:register_user(Id, ?MODULE, self(), 142 DefaultAgentConf), 143 reply(Parent, Res, Ref), 144 user_loop(S#state{ids = [Id|IDs]}); 145 true -> 146 reply(Parent, {error, already_registered}, Ref), 147 user_loop(S) 148 end; 149 150 %% For backwards compatibillity 151 {{register_monitor, Id}, Parent, Ref} -> 152 IDs = S#state.ids, 153 case lists:member(Id, IDs) of 154 false -> 155 Res = snmpm:register_user_monitor(Id, ?MODULE, self()), 156 reply(Parent, Res, Ref), 157 user_loop(S#state{ids = [Id|IDs]}); 158 true -> 159 reply(Parent, {error, already_registered}, Ref), 160 user_loop(S) 161 end; 162 163 {{register_monitor, Id, DefaultAgentConf}, Parent, Ref} -> 164 IDs = S#state.ids, 165 case lists:member(Id, IDs) of 166 false -> 167 Res = snmpm:register_user_monitor(Id, ?MODULE, self(), 168 DefaultAgentConf), 169 reply(Parent, Res, Ref), 170 user_loop(S#state{ids = [Id|IDs]}); 171 true -> 172 reply(Parent, {error, already_registered}, Ref), 173 user_loop(S) 174 end; 175 176 {unregister, Parent, Ref} -> 177 Res = [snmpm:unregister_user(Id) || Id <- S#state.ids], 178 reply(Parent, {ok, Res}, Ref), 179 user_loop(S); 180 181 {{unregister, Id}, Parent, Ref} -> 182 IDs = S#state.ids, 183 IDs2 = 184 case lists:member(Id, IDs) of 185 true -> 186 Res = snmpm:unregister_user(Id), 187 reply(Parent, Res, Ref), 188 lists:delete(Id, IDs); 189 false -> 190 reply(Parent, {error, not_registered}, Ref), 191 IDs 192 end, 193 user_loop(S#state{ids = IDs2}); 194 195 {{register_agent, Id, TargetName, Config}, Parent, Ref} -> 196 IDs = S#state.ids, 197 case lists:member(Id, IDs) of 198 true -> 199 Res = snmpm:register_agent(Id, TargetName, Config), 200 reply(Parent, Res, Ref), 201 user_loop(S); 202 false -> 203 reply(Parent, {error, {unknown_user, Id}}, Ref), 204 user_loop(S) 205 end; 206 207 208 209 %% SNMP manager callback messages (from our callback API): 210 211 {handle_error, Pid, ReqId, Reason} -> 212 do_handle_error(Pid, ReqId, Reason), 213 user_loop(S); 214 215 {handle_agent, Pid, Domain, Address, Type, SnmpInfo} -> 216 do_handle_agent(Pid, Domain, Address, Type, SnmpInfo), 217 user_loop(S); 218 219 {handle_agent, Pid, Addr, Port, SnmpInfo} -> 220 do_handle_agent(Pid, Addr, Port, SnmpInfo), 221 user_loop(S); 222 223 {handle_pdu, Pid, TargetName, ReqId, SnmpResponse} -> 224 do_handle_pdu(Pid, TargetName, ReqId, SnmpResponse), 225 user_loop(S); 226 227 {handle_pdu, Pid, Addr, Port, ReqId, SnmpResponse} -> 228 do_handle_pdu(Pid, Addr, Port, ReqId, SnmpResponse), 229 user_loop(S); 230 231 {handle_trap, Pid, TargetName, SnmpTrap} -> 232 do_handle_trap(Pid, TargetName, SnmpTrap), 233 user_loop(S); 234 235 {handle_trap, Pid, Addr, Port, SnmpTrap} -> 236 do_handle_trap(Pid, Addr, Port, SnmpTrap), 237 user_loop(S); 238 239 {handle_inform, Pid, TargetName, SnmpInform} -> 240 do_handle_inform(Pid, TargetName, SnmpInform), 241 user_loop(S); 242 243 {handle_inform, Pid, Addr, Port, SnmpInform} -> 244 do_handle_inform(Pid, Addr, Port, SnmpInform), 245 user_loop(S); 246 247 {handle_report, Pid, TargetName, SnmpReport} -> 248 do_handle_report(Pid, TargetName, SnmpReport), 249 user_loop(S); 250 251 {handle_report, Pid, Addr, Port, SnmpReport} -> 252 do_handle_report(Pid, Addr, Port, SnmpReport), 253 user_loop(S); 254 255 Unknown -> 256 info("received unknown message: ~n~p", [Unknown]), 257 user_loop(S) 258 end. 259 260 261%% ------------- 262 263do_handle_error(Pid, ReqId, Reason) -> 264 info("received error callback:" 265 "~n ReqId: ~p" 266 "~n Reason: ~p", [ReqId, Reason]), 267 Pid ! {ignore, self()}, 268 ok. 269 270 271do_handle_agent(Pid, Domain, Address, Type, SnmpInfo) -> 272 info("received agent callback:" 273 "~n Domain: ~p" 274 "~n Address: ~p" 275 "~n Type: ~p" 276 "~n SnmpInfo: ~p", [Domain, Address, Type, SnmpInfo]), 277 Pid ! {ignore, self()}, 278 ok. 279 280 281do_handle_agent(Pid, Addr, Port, SnmpInfo) -> 282 info("received agent callback:" 283 "~n Addr: ~p" 284 "~n Port: ~p" 285 "~n SnmpInfo: ~p", [Addr, Port, SnmpInfo]), 286 Pid ! {ignore, self()}, 287 ok. 288 289 290do_handle_pdu(Pid, TargetName, ReqId, SnmpResponse) -> 291 info("received pdu callback:" 292 "~n TargetName: ~p" 293 "~n ReqId: ~p" 294 "~n SnmpResponse: ~p", [TargetName, ReqId, SnmpResponse]), 295 Pid ! {ignore, self()}, 296 ok. 297 298%% For backwards compatibillity 299do_handle_pdu(Pid, Addr, Port, ReqId, SnmpResponse) -> 300 info("received pdu callback:" 301 "~n Addr: ~p" 302 "~n Port: ~p" 303 "~n ReqId: ~p" 304 "~n SnmpResponse: ~p", [Addr, Port, ReqId, SnmpResponse]), 305 Pid ! {ignore, self()}, 306 ok. 307 308 309do_handle_trap(Pid, TargetName, SnmpTrap) -> 310 info("received trap callback:" 311 "~n TargetName: ~p" 312 "~n SnmpTrap: ~p", [TargetName, SnmpTrap]), 313 Pid ! {ignore, self()}, 314 ok. 315 316%% For backwards compatibillity 317do_handle_trap(Pid, Addr, Port, SnmpTrap) -> 318 info("received trap callback:" 319 "~n Addr: ~p" 320 "~n Port: ~p" 321 "~n SnmpTrap: ~p", [Addr, Port, SnmpTrap]), 322 Pid ! {ignore, self()}, 323 ok. 324 325 326do_handle_inform(Pid, TargetName, SnmpInform) -> 327 info("received inform callback:" 328 "~n TargetName: ~p" 329 "~n SnmpInform: ~p", [TargetName, SnmpInform]), 330 Pid ! {ignore, self()}, 331 ok. 332 333%% For backwards compatibillity 334do_handle_inform(Pid, Addr, Port, SnmpInform) -> 335 info("received inform callback:" 336 "~n Addr: ~p" 337 "~n Port: ~p" 338 "~n SnmpInform: ~p", [Addr, Port, SnmpInform]), 339 Pid ! {ignore, self()}, 340 ok. 341 342 343do_handle_report(Pid, TargetName, SnmpReport) -> 344 info("received report callback:" 345 "~n TargetName: ~p" 346 "~n SnmpReport: ~p", [TargetName, SnmpReport]), 347 Pid ! {ignore, self()}, 348 ok. 349 350%% For backwards compatibillity 351do_handle_report(Pid, Addr, Port, SnmpReport) -> 352 info("received report callback:" 353 "~n Addr: ~p" 354 "~n Port: ~p" 355 "~n SnmpReport: ~p", [Addr, Port, SnmpReport]), 356 Pid ! {ignore, self()}, 357 ok. 358 359 360info(F, A) -> 361 error_logger:info_msg("USER SIMULATOR " ++ F ++ "~n", A). 362 363 364%% ------------- 365 366call(UserPid, Req) -> 367 call(UserPid, Req, 5000). 368 369call(UserPid, Req, To) -> 370 Ref = make_ref(), 371 UserPid ! {Req, self(), Ref}, 372 receive 373 {Reply, UserPid, Ref} -> 374 Reply 375 after To -> 376 {error, timeout} 377 end. 378 379reply(Pid, Reply, Ref) -> 380 Pid ! {Reply, self(), Ref}. 381 382cast(UserPid, Msg) -> 383 UserPid ! {Msg, self()}, 384 ok. 385 386 387%%---------------------------------------------------------------------- 388%% User callback functions: 389%%---------------------------------------------------------------------- 390 391handle_error(ReqId, Reason, UserPid) -> 392 UserPid ! {handle_error, self(), ReqId, Reason}, 393 ignore. 394 395 396handle_agent(Domain, Address, Type, SnmpInfo, UserPid) -> 397 UserPid ! {handle_agent, self(), Domain, Address, Type, SnmpInfo}, 398 ignore. 399 400 401%% For backwards compatibillity 402handle_agent(Addr, Port, SnmpInfo, UserPid) -> 403 UserPid ! {handle_agent, self(), Addr, Port, SnmpInfo}, 404 ignore. 405 406 407handle_pdu(TargetName, ReqId, SnmpResponse, UserPid) -> 408 UserPid ! {handle_pdu, self(), TargetName, ReqId, SnmpResponse}, 409 ignore. 410 411%% For backwards compatibillity 412handle_pdu(Addr, Port, ReqId, SnmpResponse, UserPid) -> 413 UserPid ! {handle_pdu, self(), Addr, Port, ReqId, SnmpResponse}, 414 ignore. 415 416 417handle_trap(TargetName, SnmpTrap, UserPid) -> 418 UserPid ! {handle_trap, self(), TargetName, SnmpTrap}, 419 ok. 420 421%% For backwards compatibillity 422handle_trap(Addr, Port, SnmpTrap, UserPid) -> 423 UserPid ! {handle_trap, self(), Addr, Port, SnmpTrap}, 424 ok. 425 426 427handle_inform(TargetName, SnmpInform, UserPid) -> 428 UserPid ! {handle_inform, self(), TargetName, SnmpInform}, 429 ok. 430 431%% For backwards compatibillity 432handle_inform(Addr, Port, SnmpInform, UserPid) -> 433 UserPid ! {handle_inform, self(), Addr, Port, SnmpInform}, 434 ok. 435 436 437handle_report(TargetName, SnmpReport, UserPid) -> 438 UserPid ! {handle_report, self(), TargetName, SnmpReport}, 439 ok. 440 441%% For backwards compatibillity 442handle_report(Addr, Port, SnmpReport, UserPid) -> 443 UserPid ! {handle_report, self(), Addr, Port, SnmpReport}, 444 ok. 445