1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2003-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%%---------------------------------------------------------------------- 23%% Purpose: Verify the application specifics of the Megaco application 24%%---------------------------------------------------------------------- 25-module(megaco_mreq_SUITE). 26 27-export([ 28 suite/0, all/0, groups/0, 29 init_per_suite/1, end_per_suite/1, 30 init_per_group/2, end_per_group/2, 31 init_per_testcase/2, end_per_testcase/2, 32 33 req_and_rep/1, 34 req_and_pending/1, 35 req_and_cancel/1 36 37 ]). 38 39-include_lib("megaco/include/megaco.hrl"). 40-include_lib("megaco/include/megaco_message_v1.hrl"). 41-include("megaco_test_lib.hrl"). 42 43-define(TEST_VERBOSITY, debug). 44-define(MGC_VERBOSITY, debug). 45-define(MG_VERBOSITY, debug). 46 47-define(LOAD_COUNTER_START, 10). 48-define(A4444, ["11111111", "00000000", "00000000"]). 49-define(A4445, ["11111111", "00000000", "11111111"]). 50-define(A5555, ["11111111", "11111111", "00000000"]). 51-define(A5556, ["11111111", "11111111", "11111111"]). 52 53-define(MGC_START(Pid, Mid, ET, Verb), 54 megaco_test_mgc:start(Pid, Mid, ET, Verb)). 55-define(MGC_STOP(Pid), megaco_test_mgc:stop(Pid)). 56-define(MGC_GET_STATS(Pid, No), megaco_test_mgc:get_stats(Pid, No)). 57-define(MGC_RESET_STATS(Pid), megaco_test_mgc:reset_stats(Pid)). 58-define(MGC_REQ_DISC(Pid,To), megaco_test_mgc:request_discard(Pid,To)). 59-define(MGC_REQ_PEND(Pid,To), megaco_test_mgc:request_pending(Pid,To)). 60-define(MGC_REQ_HAND(Pid), megaco_test_mgc:request_handle(Pid)). 61 62-define(MG_START(Pid, Mid, Enc, Transp, Verb), 63 megaco_test_mg:start(Pid, Mid, Enc, Transp, Verb)). 64-define(MG_STOP(Pid), megaco_test_mg:stop(Pid)). 65-define(MG_GET_STATS(Pid), megaco_test_mg:get_stats(Pid)). 66-define(MG_RESET_STATS(Pid), megaco_test_mg:reset_stats(Pid)). 67-define(MG_SERV_CHANGE(Pid), megaco_test_mg:service_change(Pid)). 68-define(MG_NOTIF_RAR(Pid), megaco_test_mg:notify_request_and_reply(Pid)). 69-define(MG_NOTIF_REQ(Pid), megaco_test_mg:notify_request(Pid)). 70-define(MG_NOTIF_AR(Pid), megaco_test_mg:await_notify_reply(Pid)). 71-define(MG_CANCEL(Pid,R), megaco_test_mg:cancel_request(Pid,R)). 72-define(MG_APPLY_LOAD(Pid,CntStart), megaco_test_mg:apply_load(Pid,CntStart)). 73 74 75%%====================================================================== 76%% Common Test interface functions 77%%====================================================================== 78 79suite() -> 80 [{ct_hooks, [ts_install_cth]}]. 81 82all() -> 83 [ 84 req_and_rep, 85 req_and_pending, 86 req_and_cancel 87 ]. 88 89groups() -> 90 []. 91 92 93 94%% 95%% ----- 96%% 97 98init_per_suite(suite) -> 99 []; 100init_per_suite(doc) -> 101 []; 102init_per_suite(Config0) when is_list(Config0) -> 103 104 ?ANNOUNCE_SUITE_INIT(), 105 106 p("init_per_suite -> entry with" 107 "~n Config: ~p" 108 "~n Nodes: ~p", [Config0, erlang:nodes()]), 109 110 case ?LIB:init_per_suite(Config0) of 111 {skip, _} = SKIP -> 112 SKIP; 113 114 Config1 when is_list(Config1) -> 115 116 %% We need a (local) monitor on this node also 117 megaco_test_sys_monitor:start(), 118 119 p("init_per_suite -> end when" 120 "~n Config: ~p" 121 "~n Nodes: ~p", [Config1, erlang:nodes()]), 122 123 Config1 124 end. 125 126end_per_suite(suite) -> []; 127end_per_suite(doc) -> []; 128end_per_suite(Config0) when is_list(Config0) -> 129 130 p("end_per_suite -> entry with" 131 "~n Config: ~p" 132 "~n Nodes: ~p", [Config0, erlang:nodes()]), 133 134 megaco_test_sys_monitor:stop(), 135 Config1 = ?LIB:end_per_suite(Config0), 136 137 p("end_per_suite -> end when" 138 "~n Nodes: ~p", [erlang:nodes()]), 139 140 Config1. 141 142 143%% 144%% ----- 145%% 146 147init_per_group(_GroupName, Config) -> 148 Config. 149 150end_per_group(_GroupName, Config) -> 151 Config. 152 153 154 155init_per_testcase(Case, Config) -> 156 process_flag(trap_exit, true), 157 158 p("init_per_suite -> entry with" 159 "~n Config: ~p" 160 "~n Nodes: ~p", [Config, erlang:nodes()]), 161 162 megaco_test_global_sys_monitor:reset_events(), 163 megaco_test_lib:init_per_testcase(Case, Config). 164 165end_per_testcase(Case, Config) -> 166 process_flag(trap_exit, false), 167 168 p("end_per_suite -> entry with" 169 "~n Config: ~p" 170 "~n Nodes: ~p", [Config, erlang:nodes()]), 171 172 p("system events during test: " 173 "~n ~p", [megaco_test_global_sys_monitor:events()]), 174 175 megaco_test_lib:end_per_testcase(Case, Config). 176 177 178 179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 180 181req_and_rep(suite) -> 182 []; 183req_and_rep(doc) -> 184 []; 185req_and_rep(Config) when is_list(Config) -> 186 Pre = fun() -> 187 MgcNode = make_node_name(mgc), 188 Mg1Node = make_node_name(mg1), 189 Mg2Node = make_node_name(mg2), 190 Mg3Node = make_node_name(mg3), 191 Mg4Node = make_node_name(mg4), 192 d("try start nodes: " 193 "~n MgcNode: ~p" 194 "~n Mg1Node: ~p" 195 "~n Mg2Node: ~p" 196 "~n Mg3Node: ~p" 197 "~n Mg4Node: ~p", 198 [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]), 199 Nodes = [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node], 200 ok = ?START_NODES(Nodes), 201 Nodes 202 end, 203 Case = fun do_req_and_rep/1, 204 Post = fun(Nodes) -> 205 d("stop nodes (in the reverse order):" 206 "~n ~p", [Nodes]), 207 ?STOP_NODES(lists:reverse(Nodes)) 208 end, 209 try_tc(req_and_rep, Pre, Case, Post). 210 211do_req_and_rep([MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]) -> 212 %% Start the MGC and MGs 213 i("start the MGC"), 214 ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}], 215 {ok, Mgc} = 216 ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, ?MGC_VERBOSITY), 217 218 i("start and connect the MGs"), 219 MgConf0 = [{Mg1Node, "mg1", text, tcp, ?MG_VERBOSITY}, 220 {Mg2Node, "mg2", text, udp, ?MG_VERBOSITY}, 221 {Mg3Node, "mg3", binary, tcp, ?MG_VERBOSITY}, 222 {Mg4Node, "mg4", binary, udp, ?MG_VERBOSITY}], 223 MgConf = rar_connect_mg(MgConf0, []), 224 225 %% Collect the (initial) MGs statistics 226 Stats1 = rar_get_mg_stats(MgConf, []), 227 d("stats for the MGs: " 228 "~n ~p", [Stats1]), 229 230 %% Collect and check the MGC statistics 231 i("collect and check the MGC stats"), 232 {ok, MgcStats1} = ?MGC_GET_STATS(Mgc, 1), 233 d("stats (1) for Mgc: " 234 "~n ~p" 235 "~n", [MgcStats1]), 236 237 238 sleep(1000), 239 240 241 %% And apply some load 242 i("apply traffic load"), 243 ok = rar_apply_load(MgConf), 244 245 %% Await completion of load part and the collect traffic 246 i("await load completion"), 247 ok = rar_await_load_complete(MgConf), 248 249 250 sleep(1000), 251 252 253 i("collect the MGs statistics"), 254 Stats2 = rar_get_mg_stats(MgConf, []), 255 d("stats for MGs: " 256 "~n ~p", [Stats2]), 257 258 i("collect the MGC statistics"), 259 {ok, MgcStats2} = ?MGC_GET_STATS(Mgc, 1), 260 d("stats (1) for Mgc: " 261 "~n ~p" 262 "~n", [MgcStats2]), 263 264 265 sleep(1000), 266 267 268 %% Reset counters 269 i("reset the MGs statistics"), 270 rar_reset_mg_stats(MgConf), 271 Stats3 = rar_get_mg_stats(MgConf, []), 272 d("stats for the MGs: " 273 "~n ~p", [Stats3]), 274 275 i("reset the MGC statistics"), 276 rar_reset_mgc_stats(Mgc), 277 {ok, MgcStats3} = ?MGC_GET_STATS(Mgc, 1), 278 d("stats (1) for Mgc: " 279 "~n ~p" 280 "~n", [MgcStats3]), 281 282 283 sleep(1000), 284 285 286 %% Tell MGs to stop 287 i("stop the MGs"), 288 rar_stop_mg(MgConf), 289 290 291 sleep(1000), 292 293 294 %% Collect the statistics 295 i("collect the MGC statistics"), 296 {ok, MgcStats4} = ?MGC_GET_STATS(Mgc, 1), 297 d("stats (1) for Mgc: " 298 "~n ~p", [MgcStats4]), 299 {ok, MgcStats5} = ?MGC_GET_STATS(Mgc, 2), 300 d("stats (2) for Mgc: " 301 "~n ~p" 302 "~n", [MgcStats5]), 303 304 %% Tell Mgc to stop 305 i("stop the MGC"), 306 ?MGC_STOP(Mgc), 307 308 i("done", []), 309 ok. 310 311 312rar_connect_mg([], Acc) -> 313 lists:reverse(Acc); 314rar_connect_mg([{Node, Name, Coding, Trans, Verb}|Mg], Acc) -> 315 Pid = rar_connect_mg(Node, Name, Coding, Trans, Verb), 316 rar_connect_mg(Mg, [{Name, Pid}|Acc]). 317 318rar_connect_mg(Node, Name, Coding, Trans, Verb) -> 319 Mid = {deviceName, Name}, 320 {ok, Pid} = ?MG_START(Node, Mid, Coding, Trans, Verb), 321 322 %% Ask the MGs to do a service change 323 Res = ?MG_SERV_CHANGE(Pid), 324 d("rar_connect_mg -> (~s) service change result: ~p", [Name,Res]), 325 326 Pid. 327 328 329rar_stop_mg(MGs) -> 330 [?MG_STOP(Pid) || {_Name, Pid} <- MGs]. 331 332 333rar_get_mg_stats([], Acc) -> 334 lists:reverse(Acc); 335rar_get_mg_stats([{Name, Pid}|Mgs], Acc) -> 336 {ok, Stats} = ?MG_GET_STATS(Pid), 337 d("rar_get_mg_stats -> stats for ~s: " 338 "~n ~p" 339 "~n", [Name, Stats]), 340 rar_get_mg_stats(Mgs, [{Name, Stats}|Acc]). 341 342 343rar_apply_load([]) -> 344 ok; 345rar_apply_load([{_, MG}|MGs]) -> 346 ?MG_APPLY_LOAD(MG,?LOAD_COUNTER_START), 347 rar_apply_load(MGs). 348 349 350rar_reset_mg_stats([]) -> 351 ok; 352rar_reset_mg_stats([{Name, Pid}|MGs]) -> 353 d("rar_reset_mg_stats -> resetting ~s", [Name]), 354 ?MG_RESET_STATS(Pid), 355 rar_reset_mg_stats(MGs). 356 357rar_reset_mgc_stats(Mgc) -> 358 d("rar_reset_mgc_stats -> resetting ~p", [Mgc]), 359 ?MGC_RESET_STATS(Mgc). 360 361 362rar_await_load_complete([]) -> 363 ok; 364rar_await_load_complete(MGs0) -> 365 receive 366 {load_complete, Pid} -> 367 d("received load_complete from ~p", [Pid]), 368 MGs1 = lists:keydelete(Pid, 2, MGs0), 369 rar_await_load_complete(lists:delete(Pid, MGs1)); 370 {'EXIT', Pid, Reason} -> 371 e("exit signal from ~p: ~p", [Pid, Reason]), 372 case lists:keymember(Pid, 2, MGs0) of 373 true -> 374 exit({mg_exit, Pid, Reason}); 375 false -> 376 MGs1 = lists:keydelete(Pid, 2, MGs0), 377 rar_await_load_complete(lists:delete(Pid, MGs1)) 378 end 379 end. 380 381 382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 383 384req_and_pending(suite) -> 385 []; 386req_and_pending(doc) -> 387 []; 388req_and_pending(Config) when is_list(Config) -> 389 Pre = fun() -> 390 MgcNode = make_node_name(mgc), 391 MgNode = make_node_name(mg), 392 d("try starting nodes: " 393 "~n MgcNode: ~p" 394 "~n MgNode: ~p", [MgcNode, MgNode]), 395 Nodes = [MgcNode, MgNode], 396 ok = ?START_NODES(Nodes), 397 Nodes 398 end, 399 Case = fun do_req_and_pending/1, 400 Post = fun(Nodes) -> 401 d("stop nodes (in the reverse order):" 402 "~n ~p", [Nodes]), 403 ?STOP_NODES(lists:reverse(Nodes)) 404 end, 405 try_tc(req_and_pending, Pre, Case, Post). 406 407do_req_and_pending([MgcNode, MgNode]) -> 408 409 %% Start the MGC and MGs 410 i("try start the MGC"), 411 ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}], 412 {ok, Mgc} = 413 ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, ?MGC_VERBOSITY), 414 415 i("try start the MG"), 416 {ok, Mg} = 417 ?MG_START(MgNode, {deviceName, "mg"}, text, tcp, ?MG_VERBOSITY), 418 419 i("connect MG (to MFC)"), 420 Res1 = ?MG_SERV_CHANGE(Mg), 421 d("service change result: ~p", [Res1]), 422 423 sleep(1000), 424 425 i("[MGC] change request action to pending"), 426 {ok, _} = ?MGC_REQ_PEND(Mgc, 3500), 427 428 i("[MG] send notify request"), 429 {ok, Res2} = ?MG_NOTIF_RAR(Mg), 430 d("notify reply: ~p", [Res2]), 431 432 sleep(1000), 433 434 %% Tell MG to stop 435 i("stop the MG"), 436 ?MG_STOP(Mg), 437 438 %% Tell Mgc to stop 439 i("stop the MGC"), 440 ?MGC_STOP(Mgc), 441 442 i("done", []), 443 ok. 444 445 446 447%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 448 449req_and_cancel(suite) -> 450 []; 451req_and_cancel(doc) -> 452 []; 453req_and_cancel(Config) when is_list(Config) -> 454 Pre = fun() -> 455 MgcNode = make_node_name(mgc), 456 MgNode = make_node_name(mg), 457 d("try start nodes: " 458 "~n MgcNode: ~p" 459 "~n MgNode: ~p", 460 [MgcNode, MgNode]), 461 Nodes = [MgcNode, MgNode], 462 ok = ?START_NODES(Nodes), 463 Nodes 464 end, 465 Case = fun do_req_and_cancel/1, 466 Post = fun(Nodes) -> 467 d("stop nodes (in the reverse order):" 468 "~n ~p", [Nodes]), 469 ?STOP_NODES(lists:reverse(Nodes)) 470 end, 471 try_tc(req_and_cancel, Pre, Case, Post). 472 473do_req_and_cancel([MgcNode, MgNode]) -> 474 %% Start the MGC and MGs 475 i("start the MGC"), 476 ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}], 477 {ok, Mgc} = 478 ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, ?MGC_VERBOSITY), 479 480 i("start the MG"), 481 {ok, Mg} = 482 ?MG_START(MgNode, {deviceName, "mg"}, text, tcp, ?MG_VERBOSITY), 483 484 i("connect the MG"), 485 Res1 = ?MG_SERV_CHANGE(Mg), 486 d("service change result: ~p", [Res1]), 487 488 489 sleep(1000), 490 491 i("change request action to pending"), 492 {ok, _} = ?MGC_REQ_DISC(Mgc,5000), 493 494 i("send notify request"), 495 ?MG_NOTIF_REQ(Mg), 496 497 d("wait some to get it going",[]), 498 sleep(1000), 499 500 i("now cancel the notify request"), 501 ok = ?MG_CANCEL(Mg, req_and_cancel), 502 503 i("now await the notify request result"), 504 Res2 = ?MG_NOTIF_AR(Mg), 505 rac_analyze_result(Res2), 506 507 508 %% Tell MGs to stop 509 i("stop the MG"), 510 ?MG_STOP(Mg), 511 512 %% Tell Mgc to stop 513 i("stop the MGC"), 514 ?MGC_STOP(Mgc), 515 516 i("done", []), 517 ok. 518 519 520rac_analyze_result({ok, {_PV,Res}}) -> 521 i("rac_analyze_result -> notify request result:" 522 "~n ~p", [Res]), 523 rac_analyze_result2(Res); 524rac_analyze_result(Unexpected) -> 525 e("rac_analyze_result -> unexpected result: " 526 "~n ~p", [Unexpected]), 527 exit({unexpected_result, Unexpected}). 528 529rac_analyze_result2({error,{user_cancel, req_and_cancel}}) -> 530 ok; 531rac_analyze_result2([]) -> 532 ok; 533rac_analyze_result2([{error,{user_cancel, req_and_cancel}}|Res]) -> 534 rac_analyze_result2(Res); 535rac_analyze_result2([Unknown|_Res]) -> 536 e("rac_analyze_result2 -> unexpected result: " 537 "~n ~p", [Unknown]), 538 exit({unknown_result, Unknown}). 539 540 541%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 542 543make_node_name(Name) -> 544 case string:tokens(atom_to_list(node()), [$@]) of 545 [_,Host] -> 546 list_to_atom(lists:concat([atom_to_list(Name) ++ "@" ++ Host])); 547 _ -> 548 exit("Test node must be started with '-sname'") 549 end. 550 551 552%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 553 554sleep(X) -> 555 receive after X -> ok end. 556 557 558%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 559 560try_tc(TCName, Pre, Case, Post) -> 561 try_tc(TCName, "TEST", ?TEST_VERBOSITY, Pre, Case, Post). 562 563try_tc(TCName, Name, Verbosity, Pre, Case, Post) -> 564 ?TRY_TC(TCName, Name, Verbosity, Pre, Case, Post). 565 566 567 568%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 569 570p(F, A) -> 571 io:format("*** [~s] ~p ***" 572 "~n " ++ F ++ "~n", 573 [?FTS(), self() | A]). 574 575%% e(F) -> 576%% i(F, []). 577 578e(F, A) -> 579 print(info, get(verbosity), "ERROR", get(tc), F, A). 580 581 582i(F) -> 583 i(F, []). 584 585i(F, A) -> 586 print(info, get(verbosity), "INFO", get(tc), F, A). 587 588 589%% d(F) -> 590%% d(F, []). 591 592d(F, A) -> 593 print(debug, get(verbosity), "DBG", get(tc), F, A). 594 595 596printable(_, debug) -> true; 597printable(info, info) -> true; 598printable(_,_) -> false. 599 600print(Severity, Verbosity, P, TC, F, A) -> 601 print(printable(Severity,Verbosity), P, TC, F, A). 602 603print(true, P, TC, F, A) -> 604 io:format("*** [~s] [~s] ~p ~s:~w ***" 605 "~n " ++ F ++ "~n", 606 [?FTS(), P, self(), get(sname), TC | A]); 607print(_, _, _, _, _) -> 608 ok. 609 610