1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2000-2021. 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: Test application config 24%%---------------------------------------------------------------------- 25 26-module(megaco_config_SUITE). 27 28-export([ 29 suite/0, all/0, groups/0, 30 init_per_suite/1, end_per_suite/1, 31 init_per_group/2, end_per_group/2, 32 init_per_testcase/2, end_per_testcase/2, 33 34 config/1, 35 transaction_id_counter_mg/1, 36 transaction_id_counter_mgc/1, 37 otp_7216/1, 38 otp_8167/1, 39 otp_8183/1 40 ]). 41 42-include_lib("megaco/include/megaco.hrl"). 43-include_lib("megaco/src/app/megaco_internal.hrl"). 44-include("megaco_test_lib.hrl"). 45 46-record(command, {id, desc, cmd, verify}). 47 48-define(TEST_VERBOSITY, debug). 49-define(NUM_CNT_PROCS, 100). 50 51 52%%====================================================================== 53%% Common Test interface functions 54%%====================================================================== 55 56suite() -> 57 [{ct_hooks, [ts_install_cth]}]. 58 59all() -> 60 [ 61 config, 62 {group, transaction_id_counter}, 63 {group, tickets} 64 ]. 65 66groups() -> 67 [ 68 {transaction_id_counter, [], transaction_id_counter_cases()}, 69 {tickets, [], tickets_cases()} 70 ]. 71 72 73 74transaction_id_counter_cases() -> 75 [ 76 transaction_id_counter_mg, 77 transaction_id_counter_mgc 78 ]. 79 80tickets_cases() -> 81 [ 82 otp_7216, 83 otp_8167, 84 otp_8183 85 ]. 86 87 88 89%% 90%% ----- 91%% 92 93init_per_suite(Config0) when is_list(Config0) -> 94 95 p("init_per_suite -> entry with" 96 "~n Config: ~p" 97 "~n Nodes: ~p", [Config0, erlang:nodes()]), 98 99 case ?LIB:init_per_suite(Config0) of 100 {skip, _} = SKIP -> 101 SKIP; 102 103 Config1 when is_list(Config1) -> 104 105 %% We need a (local) monitor on this node also 106 megaco_test_sys_monitor:start(), 107 108 p("init_per_suite -> end when" 109 "~n Config: ~p" 110 "~n Nodes: ~p", [Config1, erlang:nodes()]), 111 112 Config1 113 end. 114 115end_per_suite(Config0) when is_list(Config0) -> 116 117 p("end_per_suite -> entry with" 118 "~n Config0: ~p" 119 "~n Nodes: ~p", [Config0, erlang:nodes()]), 120 121 megaco_test_sys_monitor:stop(), 122 Config1 = ?LIB:end_per_suite(Config0), 123 124 p("end_per_suite -> end when" 125 "~n Nodes: ~p", [erlang:nodes()]), 126 Config1. 127 128 129 130%% 131%% ----- 132%% 133 134init_per_group(_GroupName, Config) -> 135 Config. 136 137end_per_group(_GroupName, Config) -> 138 Config. 139 140 141%% 142%% ----- 143%% 144 145%% Test server callbacks 146init_per_testcase(Case, Config) when (Case =:= otp_7216) orelse 147 (Case =:= otp_8167) orelse 148 (Case =:= otp_8183) -> 149 i("init_per_testcase -> entry with" 150 "~n Config: ~p" 151 "~n Nodes: ~p", [Config, erlang:nodes()]), 152 153 megaco_test_global_sys_monitor:reset_events(), 154 155 i("try starting megaco_config"), 156 case megaco_config:start_link() of 157 {ok, _} -> 158 C = lists:keydelete(tc_timeout, 1, Config), 159 do_init_per_testcase(Case, [{tc_timeout, min(3)}|C]); 160 {error, Reason} -> 161 i("Failed starting megaco_config: " 162 "~n ~p", [Reason]), 163 {skip, ?F("Failed starting config: ~p", [Reason])} 164 end; 165init_per_testcase(Case, Config) -> 166 C = lists:keydelete(tc_timeout, 1, Config), 167 do_init_per_testcase(Case, [{tc_timeout, min(3)}|C]). 168 169do_init_per_testcase(Case, Config) -> 170 process_flag(trap_exit, true), 171 megaco_test_lib:init_per_testcase(Case, Config). 172 173min(M) -> timer:minutes(M). 174 175 176end_per_testcase(Case, Config) when (Case =:= otp_7216) orelse 177 (Case =:= otp_8167) orelse 178 (Case =:= otp_8183) -> 179 p("end_per_testcase -> entry with" 180 "~n Config: ~p" 181 "~n Nodes: ~p", [Config, erlang:nodes()]), 182 183 p("system events during test: " 184 "~n ~p", [megaco_test_global_sys_monitor:events()]), 185 186 (catch megaco_config:stop()), 187 process_flag(trap_exit, false), 188 megaco_test_lib:end_per_testcase(Case, Config); 189end_per_testcase(Case, Config) -> 190 process_flag(trap_exit, false), 191 megaco_test_lib:end_per_testcase(Case, Config). 192 193 194 195%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 196%% Config test case 197 198config(suite) -> 199 []; 200config(Config) when is_list(Config) -> 201 ?ACQUIRE_NODES(1, Config), 202 Mid = fake_mid, 203 204 %% Nice values 205 Int = 3, 206 IT = #megaco_incr_timer{max_retries = Int}, 207 208 %% Evil values 209 NonInt = non_int, 210 IT2 = #megaco_incr_timer{wait_for = NonInt}, 211 IT3 = #megaco_incr_timer{factor = NonInt}, 212 IT4 = #megaco_incr_timer{max_retries = NonInt}, 213 IT5 = #megaco_incr_timer{max_retries = non_infinity}, 214 215 %% Command range values 216 Initial = 100, 217 Verify = 200, 218 Nice = 300, 219 Evil = 400, 220 End = 500, 221 222 InitialCmd = 223 fun(No, Desc, Cmd, VerifyVal) -> 224 initial_command(Initial + No, Desc, Cmd, VerifyVal) 225 end, 226 227 VerifyCmd = 228 fun(M, No, Key, V) -> 229 verify_user_default_command(M, Verify + No, Key, V) 230 end, 231 232 NiceCmd = 233 fun(M, No, Key, Val) -> 234 nice_user_update_command(M, Nice + No, Key, Val) 235 end, 236 237 EvilCmd = 238 fun(M, No, Key, Val) -> 239 evil_user_update_command(M, Evil + No, Key, Val) 240 end, 241 242 %% End commands 243 ExitCmd = 244 fun(No, Desc, Cmd) -> 245 exit_command(End + No, Desc, Cmd) 246 end, 247 ErrorCmd = 248 fun(No, Desc, Cmd, MainReason, TS) -> 249 error_command(End + No, Desc, Cmd, MainReason, TS) 250 end, 251 PlainCmd = 252 fun(No, Desc, Cmd, V) -> 253 command(End + No, Desc, Cmd, V) 254 end, 255 256 Commands = 257 [ 258 %% Initial commands 259 InitialCmd(0, 260 "enable trace", 261 fun() -> megaco:enable_trace(100, io) end, 262 ok), 263 InitialCmd(1, 264 "start", 265 fun() -> megaco:start() end, 266 ok), 267 InitialCmd(2, 268 "Verify no active requests", 269 fun() -> megaco:system_info(n_active_requests) end, 270 0), 271 InitialCmd(3, 272 "Verify no active replies", 273 fun() -> megaco:system_info(n_active_replies) end, 274 0), 275 InitialCmd(4, 276 "Verify no active connections", 277 fun() -> megaco:system_info(n_active_connections) end, 278 0), 279 InitialCmd(5, 280 "Verify no connections", 281 fun() -> megaco:system_info(connections) end, 282 []), 283 InitialCmd(6, 284 "Verify no users", 285 fun() -> megaco:system_info(users) end, 286 []), 287 InitialCmd(7, 288 "Start user", 289 fun() -> megaco:start_user(Mid, []) end, 290 ok), 291 292 293 %% Verify user defaults 294 VerifyCmd(Mid, 1, connections, []), 295 VerifyCmd(Mid, 2, min_trans_id, 1), 296 VerifyCmd(Mid, 3, max_trans_id, infinity), 297 VerifyCmd(Mid, 4, request_timer, #megaco_incr_timer{}), 298 VerifyCmd(Mid, 5, long_request_timer, timer:seconds(60)), 299 VerifyCmd(Mid, 6, auto_ack, false), 300 VerifyCmd(Mid, 7, pending_timer, 30000), 301 VerifyCmd(Mid, 8, reply_timer, 30000), 302 VerifyCmd(Mid, 9, send_mod, megaco_tcp), 303 VerifyCmd(Mid, 10, encoding_mod, megaco_pretty_text_encoder), 304 VerifyCmd(Mid, 11, encoding_config, []), 305 VerifyCmd(Mid, 12, protocol_version, 1), 306 VerifyCmd(Mid, 13, reply_data, undefined), 307 VerifyCmd(Mid, 14, receive_handle, 308 fun(H) when is_record(H, megaco_receive_handle) -> 309 {ok, H}; 310 (R) -> 311 {error, R} 312 end), 313 314 315 %% Nice update 316 NiceCmd(Mid, 1, min_trans_id, Int), 317 NiceCmd(Mid, 2, max_trans_id, Int), 318 NiceCmd(Mid, 3, max_trans_id, infinity), 319 NiceCmd(Mid, 4, request_timer, Int), 320 NiceCmd(Mid, 5, request_timer, infinity), 321 NiceCmd(Mid, 6, request_timer, IT), 322 NiceCmd(Mid, 7, long_request_timer, Int), 323 NiceCmd(Mid, 8, long_request_timer, infinity), 324 NiceCmd(Mid, 9, long_request_timer, IT), 325 NiceCmd(Mid, 10, auto_ack, true), 326 NiceCmd(Mid, 11, auto_ack, false), 327 NiceCmd(Mid, 12, pending_timer, Int), 328 NiceCmd(Mid, 13, pending_timer, infinity), 329 NiceCmd(Mid, 14, pending_timer, IT), 330 NiceCmd(Mid, 15, reply_timer, Int), 331 NiceCmd(Mid, 16, reply_timer, infinity), 332 NiceCmd(Mid, 17, reply_timer, IT), 333 NiceCmd(Mid, 18, send_mod, an_atom), 334 NiceCmd(Mid, 19, encoding_mod, an_atom), 335 NiceCmd(Mid, 20, encoding_config, []), 336 NiceCmd(Mid, 21, protocol_version, Int), 337 NiceCmd(Mid, 23, reply_data, IT), 338 NiceCmd(Mid, 23, resend_indication, true), 339 NiceCmd(Mid, 24, resend_indication, false), 340 NiceCmd(Mid, 25, resend_indication, flag), 341 342 343 %% Evil update 344 EvilCmd(Mid, 1, min_trans_id, NonInt), 345 EvilCmd(Mid, 2, max_trans_id, NonInt), 346 EvilCmd(Mid, 3, max_trans_id, non_infinity), 347 EvilCmd(Mid, 4, request_timer, NonInt), 348 EvilCmd(Mid, 5, request_timer, non_infinity), 349 EvilCmd(Mid, 6, request_timer, IT2), 350 EvilCmd(Mid, 7, request_timer, IT3), 351 EvilCmd(Mid, 8, request_timer, IT4), 352 EvilCmd(Mid, 9, request_timer, IT5), 353 EvilCmd(Mid, 10, long_request_timer, NonInt), 354 EvilCmd(Mid, 11, long_request_timer, non_infinity), 355 EvilCmd(Mid, 12, long_request_timer, IT2), 356 EvilCmd(Mid, 13, long_request_timer, IT3), 357 EvilCmd(Mid, 14, long_request_timer, IT4), 358 EvilCmd(Mid, 15, long_request_timer, IT5), 359 EvilCmd(Mid, 16, auto_ack, non_bool), 360 EvilCmd(Mid, 17, pending_timer, NonInt), 361 EvilCmd(Mid, 18, pending_timer, non_infinity), 362 EvilCmd(Mid, 19, pending_timer, IT2), 363 EvilCmd(Mid, 20, pending_timer, IT3), 364 EvilCmd(Mid, 21, pending_timer, IT4), 365 EvilCmd(Mid, 22, pending_timer, IT5), 366 EvilCmd(Mid, 23, reply_timer, NonInt), 367 EvilCmd(Mid, 24, reply_timer, non_infinity), 368 EvilCmd(Mid, 25, reply_timer, IT2), 369 EvilCmd(Mid, 26, reply_timer, IT3), 370 EvilCmd(Mid, 27, reply_timer, IT4), 371 EvilCmd(Mid, 28, reply_timer, IT5), 372 EvilCmd(Mid, 29, send_mod, {non_atom}), 373 EvilCmd(Mid, 30, encoding_mod, {non_atom}), 374 EvilCmd(Mid, 31, encoding_config, non_list), 375 EvilCmd(Mid, 32, protocol_version, NonInt), 376 EvilCmd(Mid, 33, resend_indication, flagg), 377 378 379 %% End 380 ExitCmd(1, "Verify non-existing system info", 381 fun() -> megaco:system_info(non_exist) end), 382 ExitCmd(2, "Verify non-existing user user info", 383 fun() -> megaco:user_info(non_exist, trans_id) end), 384 ExitCmd(3, "Verify non-existing user info", 385 fun() -> megaco:user_info(Mid, non_exist) end), 386 387 ErrorCmd(4, "Try updating user info for non-existing user", 388 fun() -> 389 megaco:update_user_info(non_exist, trans_id, 1) 390 end, 391 no_such_user, 2), 392 ErrorCmd(11, "Try updating non-existing user info", 393 fun() -> 394 megaco:update_user_info(Mid, trans_id, 4711) 395 end, 396 bad_user_val, 4), 397 ErrorCmd(12, "Try start already started user", 398 fun() -> megaco:start_user(Mid, []) end, 399 user_already_exists, 2), 400 401 PlainCmd(13, "Verify started users", 402 fun() -> megaco:system_info(users) end, [Mid]), 403 PlainCmd(14, "Stop user", fun() -> megaco:stop_user(Mid) end, ok), 404 PlainCmd(15, "Verify started users", 405 fun() -> megaco:system_info(users) end, []), 406 ErrorCmd(16, "Try stop not started user", 407 fun() -> megaco:stop_user(Mid) end, no_such_user, 2), 408 ErrorCmd(17, "Try start megaco (it's already started)", 409 fun() -> megaco:start() end, already_started, 2), 410 PlainCmd(18, "Stop megaco", fun() -> megaco:stop() end, ok), 411 ErrorCmd(19, "Try stop megaco (it's not running)", 412 fun() -> megaco:stop() end, not_started, 2) 413 ], 414 415 416 exec(Commands). 417 418 419 420exec([]) -> 421 ok; 422exec([#command{id = No, 423 desc = Desc, 424 cmd = Cmd, 425 verify = Verify}|Commands]) -> 426 io:format("Executing command ~3w: ~s: ", [No, Desc]), 427 case (catch Verify((catch Cmd()))) of 428 {ok, OK} -> 429 io:format("ok => ~p~n", [OK]), 430 exec(Commands); 431 {error, Reason} -> 432 io:format("error => ~p~n", [Reason]), 433 {error, {bad_result, No, Reason}}; 434 Error -> 435 io:format("exit => ~p~n", [Error]), 436 {error, {unexpected_result, No, Error}} 437 end. 438 439initial_command(No, Desc0, Cmd, VerifyVal) when is_function(Cmd) -> 440 Desc = lists:flatten(io_lib:format("Initial - ~s", [Desc0])), 441 command(No, Desc, Cmd, VerifyVal). 442 443verify_user_default_command(Mid, No, Key, Verify) -> 444 Desc = lists:flatten(io_lib:format("Defaults - Verify ~w", [Key])), 445 Cmd = fun() -> megaco:user_info(Mid, Key) end, 446 command(No, Desc, Cmd, Verify). 447 448nice_user_update_command(Mid, No, Key, Val) -> 449 Desc = lists:flatten(io_lib:format("Nice - Update ~w", [Key])), 450 Cmd = fun() -> megaco:update_user_info(Mid, Key, Val) end, 451 Verify = fun(ok) -> 452 case (catch megaco:user_info(Mid, Key)) of 453 {'EXIT', R} -> 454 {error, {value_retreival_failed, R}}; 455 Val -> 456 {ok, Val}; 457 Invalid -> 458 {error, {value_update_failed, Val, Invalid}} 459 end; 460 (R) -> 461 {error, R} 462 end, 463 command(No, Desc, Cmd, Verify). 464 465 466evil_user_update_command(Mid, No, Key, Val) -> 467 Desc = lists:flatten(io_lib:format("Evil - Update ~w", [Key])), 468 Cmd = fun() -> 469 case (catch megaco:user_info(Mid, Key)) of 470 {'EXIT', R} -> 471 {{error, {old_value_retreival_failed, R}}, 472 ignore}; 473 OldVal -> 474 {OldVal, 475 (catch megaco:update_user_info(Mid, Key, Val))} 476 end 477 end, 478 Verify = fun({{error, _} = Error, ignore}) -> 479 Error; 480 ({OldVal, {error, {bad_user_val, _, _, _}}}) -> 481 case (catch megaco:user_info(Mid, Key)) of 482 {'EXIT', R} -> 483 {error, {value_retreival_failed, R}}; 484 OldVal -> 485 {ok, OldVal}; 486 Invalid -> 487 {error, {value_update_failed, OldVal, Invalid}} 488 end; 489 (R) -> 490 {error, R} 491 end, 492 command(No, Desc, Cmd, Verify). 493 494exit_command(No, Desc, Cmd) when is_function(Cmd) -> 495 Verify = fun({'EXIT', _} = E) -> 496 {ok, E}; 497 (R) -> 498 {error, R} 499 end, 500 command(No, Desc, Cmd, Verify). 501 502error_command(No, Desc, Cmd, MainReason, TS) when is_function(Cmd) -> 503 Verify = fun({error, Reason}) -> 504 io:format("verify -> Reason: ~n~p~n", [Reason]), 505 case Reason of 506 {MainReason, _} when TS == 2 -> 507 {ok, MainReason}; 508 {MainReason, _, _, _} when TS == 4 -> 509 {ok, MainReason}; 510 _ -> 511 {error, Reason} 512 end; 513 (R) -> 514 {error, R} 515 end, 516 command(No, Desc, Cmd, Verify). 517 518command(No, Desc, Cmd, Verify) 519 when (is_integer(No) andalso 520 is_list(Desc) andalso 521 is_function(Cmd) andalso 522 is_function(Verify)) -> 523 #command{id = No, 524 desc = Desc, 525 cmd = Cmd, 526 verify = Verify}; 527command(No, Desc, Cmd, VerifyVal) 528 when (is_integer(No) andalso 529 is_list(Desc) andalso 530 is_function(Cmd)) -> 531 Verify = fun(Val) -> 532 case Val of 533 VerifyVal -> 534 {ok, Val}; 535 _ -> 536 {error, Val} 537 end 538 end, 539 #command{id = No, 540 desc = Desc, 541 cmd = Cmd, 542 verify = Verify}. 543 544 545%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 546 547transaction_id_counter_mg(suite) -> 548 []; 549transaction_id_counter_mg(doc) -> 550 ["This test case is intended to test and verify the " 551 "transaction counter handling of the application " 552 "in with one connection (MG). "]; 553transaction_id_counter_mg(Config) when is_list(Config) -> 554 put(verbosity, ?TEST_VERBOSITY), 555 put(sname, "TEST"), 556 put(tc, transaction_id_counter_mg), 557 558 process_flag(trap_exit, true), 559 560 i("starting"), 561 562 {ok, _ConfigPid} = megaco_config:start_link(), 563 564 %% Basic user data 565 UserMid = {deviceName, "mg"}, 566 UserConfig = [ 567 {min_trans_id, 1} 568 ], 569 570 %% Basic connection data 571 RemoteMid = {deviceName, "mgc"}, 572 RecvHandle = #megaco_receive_handle{local_mid = UserMid, 573 encoding_mod = ?MODULE, 574 encoding_config = [], 575 send_mod = ?MODULE}, 576 SendHandle = dummy_send_handle, 577 ControlPid = self(), 578 579 %% Start user 580 i("start user"), 581 ok = megaco_config:start_user(UserMid, UserConfig), 582 583 %% Create connection 584 i("create connection"), 585 {ok, CD} = 586 megaco_config:connect(RecvHandle, RemoteMid, SendHandle, ControlPid), 587 588 %% Set counter limits 589 i("set counter max limit"), 590 CH = CD#conn_data.conn_handle, 591 megaco_config:update_conn_info(CH, max_trans_id, 1000), 592 593 %% Create the counter worker procs 594 i("create counter working procs"), 595 Pids = create_counter_working_procs(CH, ?NUM_CNT_PROCS, []), 596 597 %% Start the counter worker procs 598 i("release the counter working procs"), 599 start_counter_working_procs(Pids), 600 601 %% Await the counter worker procs termination 602 i("await the counter working procs completion"), 603 ok = await_completion_counter_working_procs(Pids), 604 605 %% Verify result 606 i("verify counter result"), 607 TransId = megaco_config:conn_info(CH, trans_id), 608 1 = TransId, 609 610 %% Stop test 611 i("disconnect"), 612 {ok, _, _} = megaco_config:disconnect(CH), 613 i("stop user"), 614 ok = megaco_config:stop_user(UserMid), 615 i("stop megaco_config"), 616 ok = megaco_config:stop(), 617 618 i("done"), 619 ok. 620 621 622 623create_counter_working_procs(_CH, 0, Pids) -> 624 Pids; 625create_counter_working_procs(CH, N, Pids) -> 626 TC = get(tc), 627 Pid = erlang:spawn_link(fun() -> counter_init(CH, TC) end), 628 create_counter_working_procs(CH, N-1, [Pid | Pids]). 629 630counter_init(CH, TC) -> 631 put(verbosity, ?TEST_VERBOSITY), 632 put(sname, lists:flatten(io_lib:format("CNT-~p", [self()]))), 633 put(tc, TC), 634 UserMid = CH#megaco_conn_handle.local_mid, 635 Min = megaco_config:user_info(UserMid, min_trans_id), 636 Max = megaco_config:conn_info(CH, max_trans_id), 637 Num = Max - Min + 1, 638 receive 639 start -> 640 %% i("received start command (~p)", [Num]), 641 ok 642 end, 643 counter_loop(CH, Num). 644 645counter_loop(_CH, 0) -> 646 %% i("done"), 647 exit(normal); 648counter_loop(CH, Num) when (Num > 0) -> 649 megaco_config:incr_trans_id_counter(CH, 1), 650 counter_loop(CH, Num-1). 651 652start_counter_working_procs([]) -> 653 %% i("released"), 654 ok; 655start_counter_working_procs([Pid | Pids]) -> 656 Pid ! start, 657 start_counter_working_procs(Pids). 658 659await_completion_counter_working_procs(Pids) -> 660 await_completion_counter_working_procs(0, ts(), Pids, [], []). 661 662await_completion_counter_working_procs(MaxTSD, _TS, [], _OKs, [] = _ERRs) -> 663 i("done when ok with max TS-diff: ~p", [MaxTSD]), 664 ok; 665await_completion_counter_working_procs(MaxTSD, _TS, [], _OKs, ERRs) -> 666 i("done when error (~w) with max TS-diff: ~p", [length(ERRs), MaxTSD]), 667 {error, ERRs}; 668await_completion_counter_working_procs(MaxTSD, TS, Pids, OKs, ERRs) -> 669 receive 670 {'EXIT', Pid, normal} -> 671 %% i("counter working process completion[~w, ~w, ~w] -> " 672 %% "Expected exit from counter process: " 673 %% "~n Time since last event: ~s" 674 %% "~n Pid: ~p", 675 %% [length(Pids), length(OKs), length(ERRs), tsd(TS), Pid]), 676 TSD = ts() - TS, 677 MaxTSD2 = 678 if (TSD > MaxTSD) -> 679 i("counter working process completion[~w, ~w, ~w] -> " 680 "Expected exit from counter process: " 681 "~n New max time since last event: ~s" 682 "~n Pid: ~p", 683 [length(Pids), 684 length(OKs), 685 length(ERRs), 686 tsd(TSD), 687 Pid]), 688 TSD; 689 true -> 690 MaxTSD 691 end, 692 Pids2 = lists:delete(Pid, Pids), 693 await_completion_counter_working_procs(MaxTSD2, ts(), 694 Pids2, [Pid | OKs], ERRs); 695 696 {'EXIT', Pid, {timetrap_timeout, _Timeout, Stack} = _Reason} -> 697 TSD = ts() - TS, 698 MaxTSD2 = 699 if (TSD > MaxTSD) -> 700 TSD; 701 true -> 702 MaxTSD 703 end, 704 e("counter working process completion[~w, ~w, ~w] -> " 705 "Test case timeout timetrap" 706 "~n Time since last event: ~s (max ~s)" 707 "~n Pid: ~p (~p)" 708 "~n Stack: ~p", 709 [length(Pids), length(OKs), length(ERRs), 710 tsd(TSD), tsd(MaxTSD2), 711 Pid, lists:member(Pid, Pids), 712 Stack]), 713 %% The test case (timetrap) has timed out, which either means 714 %% we are running on very slow hw or some system functions 715 %% are slowing us down (this test case should never normally 716 %% time out). 717 case megaco_test_global_sys_monitor:events(?SECS(5)) of 718 {error, timeout} -> 719 i("counter working process completion[~w, ~w, ~w] -> " 720 "idle:sys-mon timeout", 721 [length(Pids), length(OKs), length(ERRs)]), 722 ?SKIP("TC idle; sys-monitor evs timeout"); 723 [] -> 724 i("counter working process completion[~w, ~w, ~w] -> idle", 725 [length(Pids), length(OKs), length(ERRs)]), 726 ?SKIP("TC idle"); 727 SysEvs -> 728 e("counter working process completion[~w, ~w, ~w] -> " 729 "system event(s): " 730 "~n ~p", 731 [length(Pids), length(OKs), length(ERRs), SysEvs]), 732 ?SKIP("TC system events") 733 end; 734 735 {'EXIT', Pid, Reason} -> 736 TSD = ts() - TS, 737 MaxTSD2 = 738 if (TSD > MaxTSD) -> 739 TSD; 740 true -> 741 MaxTSD 742 end, 743 e("counter working process completion[~w, ~w, ~w] -> " 744 "Unexpected exit from counter process: " 745 "~n Time since last event: ~s (max ~s)" 746 "~n Pid: ~p" 747 "~n Reason: ~p", 748 [length(Pids), length(OKs), length(ERRs), 749 tsd(TSD), tsd(MaxTSD2), 750 Pid, Reason]), 751 Pids2 = lists:delete(Pid, Pids), 752 await_completion_counter_working_procs(MaxTSD2, ts(), 753 Pids2, OKs, [Pid | ERRs]); 754 755 Any -> 756 TSD = ts() - TS, 757 MaxTSD2 = 758 if (TSD > MaxTSD) -> 759 TSD; 760 true -> 761 MaxTSD 762 end, 763 e("counter working process completion[~w, ~w, ~w] -> " 764 "Unexpected message: " 765 "~n Time since last event: ~s (max ~s)" 766 "~n ~p", 767 [length(Pids), length(OKs), length(ERRs), 768 tsd(TSD), tsd(MaxTSD2), 769 Any]), 770 await_completion_counter_working_procs(MaxTSD2, TS, 771 Pids, OKs, ERRs) 772 773 after 1000 -> 774 %% If nothing has happened for this long, something is wrong: 775 %% Check system events 776 TS2 = ts(), 777 TSD = TS2 - TS, 778 case megaco_test_global_sys_monitor:events() of 779 [] -> 780 TS3 = ts(), 781 i("counter working process completion[~w, ~w, ~w] -> idle" 782 "~n Time since last event: ~s" 783 "~n (global) sys monitor events: ~s", 784 [length(Pids), length(OKs), length(ERRs), 785 tsd(TSD), tsd(TS3 - TS2)]), 786 await_completion_counter_working_procs(MaxTSD, TS, 787 Pids, OKs, ERRs); 788 SysEvs -> 789 TS3 = ts(), 790 e("counter working process completion[~w, ~w, ~w] -> " 791 "system event(s): " 792 "~n Time since last event: ~s" 793 "~n (global) sys monitor events: ~s" 794 "~n ~p", 795 [length(Pids), length(OKs), length(ERRs), 796 tsd(TSD), tsd(TS3 - TS2), 797 SysEvs]), 798 ?SKIP("TC idle with system events") 799 end 800 end. 801 802 803%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 804 805transaction_id_counter_mgc(suite) -> 806 []; 807transaction_id_counter_mgc(doc) -> 808 ["This test case is intended to test and verify the " 809 "transaction counter handling of the application " 810 "in with several connections (MGC). "]; 811transaction_id_counter_mgc(Config) when is_list(Config) -> 812 Name = transaction_id_counter_mgc, 813 Pre = fun() -> 814 i("starting config server"), 815 {ok, _ConfigPid} = megaco_config:start_link(), 816 817 %% Basic user data 818 UserMid = {deviceName, "mgc"}, 819 UserConfig = [ 820 {min_trans_id, 1} 821 ], 822 823 %% Basic connection data 824 RemoteMids = 825 [ 826 {deviceName, "mg01"}, 827 {deviceName, "mg02"}, 828 {deviceName, "mg03"}, 829 {deviceName, "mg04"}, 830 {deviceName, "mg05"}, 831 {deviceName, "mg06"}, 832 {deviceName, "mg07"}, 833 {deviceName, "mg08"}, 834 {deviceName, "mg09"}, 835 {deviceName, "mg10"} 836 ], 837 RecvHandles = 838 [ 839 #megaco_receive_handle{local_mid = UserMid, 840 encoding_mod = ?MODULE, 841 encoding_config = [], 842 send_mod = ?MODULE}, 843 #megaco_receive_handle{local_mid = UserMid, 844 encoding_mod = ?MODULE, 845 encoding_config = [], 846 send_mod = ?MODULE}, 847 #megaco_receive_handle{local_mid = UserMid, 848 encoding_mod = ?MODULE, 849 encoding_config = [], 850 send_mod = ?MODULE}, 851 #megaco_receive_handle{local_mid = UserMid, 852 encoding_mod = ?MODULE, 853 encoding_config = [], 854 send_mod = ?MODULE}, 855 #megaco_receive_handle{local_mid = UserMid, 856 encoding_mod = ?MODULE, 857 encoding_config = [], 858 send_mod = ?MODULE}, 859 #megaco_receive_handle{local_mid = UserMid, 860 encoding_mod = ?MODULE, 861 encoding_config = [], 862 send_mod = ?MODULE}, 863 #megaco_receive_handle{local_mid = UserMid, 864 encoding_mod = ?MODULE, 865 encoding_config = [], 866 send_mod = ?MODULE}, 867 #megaco_receive_handle{local_mid = UserMid, 868 encoding_mod = ?MODULE, 869 encoding_config = [], 870 send_mod = ?MODULE}, 871 #megaco_receive_handle{local_mid = UserMid, 872 encoding_mod = ?MODULE, 873 encoding_config = [], 874 send_mod = ?MODULE}, 875 #megaco_receive_handle{local_mid = UserMid, 876 encoding_mod = ?MODULE, 877 encoding_config = [], 878 send_mod = ?MODULE} 879 ], 880 SendHandle = dummy_send_handle, 881 ControlPid = self(), 882 883 %% Start user 884 i("start user"), 885 ok = megaco_config:start_user(UserMid, UserConfig), 886 887 %% Create connection 888 i("create connection(s)"), 889 CDs = create_connections(RecvHandles, 890 RemoteMids, 891 SendHandle, 892 ControlPid), 893 894 %% Set counter limits 895 i("set counter max limit(s)"), 896 set_counter_max_limits(CDs, 1000), 897 898 {UserMid, CDs} 899 end, 900 Case = fun({_, CDs}) -> 901 %% Create the counter worker procs 902 i("create counter working procs"), 903 Pids = create_counter_working_procs(CDs, ?NUM_CNT_PROCS), 904 905 %% Start the counter worker procs 906 i("release the counter working procs"), 907 start_counter_working_procs(Pids), 908 909 %% Await the counter worker procs termination 910 i("await the counter working procs completion"), 911 ok = await_completion_counter_working_procs(Pids), 912 913 %% Verify result 914 i("verify counter result"), 915 verify_counter_results(CDs) 916 end, 917 918 Post = fun({UserMid, CDs}) -> 919 %% Stop test 920 i("disconnect"), 921 delete_connections(CDs), 922 i("stop user"), 923 ok = megaco_config:stop_user(UserMid), 924 i("stop megaco_config"), 925 ok = megaco_config:stop() 926 end, 927 try_tc(Name, Pre, Case, Post). 928 929 930create_connections(RecvHandles, RemoteMids, SendHandle, ControlPid) -> 931 create_connections(RecvHandles, RemoteMids, SendHandle, ControlPid, []). 932 933create_connections([], [], _SendHandle, _ControlPid, Acc) -> 934 lists:reverse(Acc); 935create_connections([RecvHandle | RecvHandles], 936 [RemoteMid | RemoteMids], 937 SendHandle, ControlPid, Acc) -> 938 {ok, CD} = 939 megaco_config:connect(RecvHandle, RemoteMid, SendHandle, ControlPid), 940 create_connections(RecvHandles, RemoteMids, 941 SendHandle, ControlPid, [CD | Acc]). 942 943 944set_counter_max_limits([], _MaxTransId) -> 945 ok; 946set_counter_max_limits([#conn_data{conn_handle = CH} | CDs], MaxTransId) -> 947 megaco_config:update_conn_info(CH, max_trans_id, MaxTransId), 948 set_counter_max_limits(CDs, MaxTransId). 949 950 951create_counter_working_procs(CDs, NumCntProcs) -> 952 lists:flatten(create_counter_working_procs2(CDs, NumCntProcs)). 953 954create_counter_working_procs2([], _NumCntProcs) -> 955 []; 956create_counter_working_procs2([#conn_data{conn_handle = CH} | CDs], 957 NumCntProcs) -> 958 [create_counter_working_procs(CH, NumCntProcs, []) | 959 create_counter_working_procs2(CDs, NumCntProcs)]. 960 961 962verify_counter_results(CDs) -> 963 verify_counter_results(CDs, [], []). 964 965verify_counter_results([], _OKs, [] = _Errors) -> 966 i("counter verification success"), 967 ok; 968verify_counter_results([], OKs, Errors) -> 969 e("counter verification failed: " 970 "~n Num OKs: ~p" 971 "~n Num Errors: ~p", [length(OKs), length(Errors)]), 972 error; 973verify_counter_results([#conn_data{conn_handle = CH} = CD| CDs], OKs, Errors) -> 974 TransId = megaco_config:conn_info(CH, trans_id), 975 if 976 (TransId =:= 1) -> 977 verify_counter_results(CDs, [CD|OKs], Errors); 978 true -> 979 e("invalid transaction is for connection: " 980 "~n CD: ~p" 981 "~n TransId: ~p", [CD, TransId]), 982 verify_counter_results(CDs, OKs, [{CD, TransId}|Errors]) 983 end. 984 985 986delete_connections([]) -> 987 ok; 988delete_connections([#conn_data{conn_handle = CH} | CDs]) -> 989 {ok, _, _} = megaco_config:disconnect(CH), 990 delete_connections(CDs). 991 992 993 994%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 995 996otp_7216(suite) -> 997 []; 998otp_7216(Config) when is_list(Config) -> 999 put(tc, otp_7216), 1000 p("start"), 1001 1002 LocalMid1 = {deviceName, "local-mid-1"}, 1003 %% LocalMid2 = {deviceName, "local-mid-2"}, 1004 RemoteMid1 = {deviceName, "remote-mid-1"}, 1005 %% RemoteMid2 = {deviceName, "remote-mid-2"}, 1006 RH = #megaco_receive_handle{local_mid = LocalMid1, 1007 encoding_mod = dummy_codec_module, 1008 encoding_config = [], 1009 send_mod = dummy_transport_module}, 1010 MinTransId = 7216, 1011 MaxTransId = MinTransId + 10, 1012 User1Config = [{min_trans_id, MinTransId}, 1013 {max_trans_id, MaxTransId}], 1014 1015 VerifySerial = 1016 fun(Actual, Expected) -> 1017 if 1018 Actual == Expected -> 1019 ok; 1020 true -> 1021 throw({error, {invalid_counter_value, Actual}}) 1022 end 1023 end, 1024 1025 p("start local user: ~p", [LocalMid1]), 1026 ok = megaco_config:start_user(LocalMid1, User1Config), 1027 1028 p("connect"), 1029 {ok, CD} = megaco_config:connect(RH, RemoteMid1, 1030 dummy_send_handle, self()), 1031 p("connect ok: CD = ~n~p", [CD]), 1032 CH = CD#conn_data.conn_handle, 1033 1034 1035 p("*** make the first counter increment ***"), 1036 {ok, CD01} = megaco_config:incr_trans_id_counter(CH, 1), 1037 Serial01 = CD01#conn_data.serial, 1038 p("serial: ~p", [Serial01]), 1039 VerifySerial(Serial01, MinTransId), 1040 p("counter increment 1 ok"), 1041 1042 1043 p("*** make two more counter increments ***"), 1044 {ok, _} = megaco_config:incr_trans_id_counter(CH, 1), 1045 {ok, CD02} = megaco_config:incr_trans_id_counter(CH, 1), 1046 Serial02 = CD02#conn_data.serial, 1047 p("serial: ~p", [Serial02]), 1048 VerifySerial(Serial02, MinTransId+2), 1049 p("counter increment 2 ok"), 1050 1051 1052 p("*** make a big counter increment ***"), 1053 {ok, CD03} = megaco_config:incr_trans_id_counter(CH, 8), 1054 Serial03 = CD03#conn_data.serial, 1055 p("serial: ~p", [Serial03]), 1056 VerifySerial(Serial03, MinTransId+2+8), 1057 p("counter increment 3 ok"), 1058 1059 1060 p("*** make a wrap-around counter increment ***"), 1061 {ok, CD04} = megaco_config:incr_trans_id_counter(CH, 1), 1062 Serial04 = CD04#conn_data.serial, 1063 p("serial: ~p", [Serial04]), 1064 VerifySerial(Serial04, MinTransId), 1065 p("counter increment 4 ok"), 1066 1067 1068 p("*** make a big counter increment ***"), 1069 {ok, CD05} = megaco_config:incr_trans_id_counter(CH, 10), 1070 Serial05 = CD05#conn_data.serial, 1071 p("serial: ~p", [Serial05]), 1072 VerifySerial(Serial05, MinTransId+10), 1073 p("counter increment 5 ok"), 1074 1075 1076 p("*** make a big wrap-around counter increment ***"), 1077 {ok, CD06} = megaco_config:incr_trans_id_counter(CH, 3), 1078 Serial06 = CD06#conn_data.serial, 1079 p("serial: ~p", [Serial06]), 1080 VerifySerial(Serial06, MinTransId+(3-1)), 1081 p("counter increment 6 ok"), 1082 1083 1084 p("*** make a big counter increment ***"), 1085 {ok, CD07} = megaco_config:incr_trans_id_counter(CH, 7), 1086 Serial07 = CD07#conn_data.serial, 1087 p("serial: ~p", [Serial07]), 1088 VerifySerial(Serial07, MinTransId+(3-1)+7), 1089 p("counter increment 7 ok"), 1090 1091 1092 p("*** make a big wrap-around counter increment ***"), 1093 {ok, CD08} = megaco_config:incr_trans_id_counter(CH, 5), 1094 Serial08 = CD08#conn_data.serial, 1095 p("serial: ~p", [Serial08]), 1096 VerifySerial(Serial08, MinTransId+(5-1-1)), 1097 p("counter increment 8 ok"), 1098 1099 1100 p("disconnect"), 1101 {ok, CD, RCD} = megaco_config:disconnect(CH), 1102 p("disconnect ok: RCD = ~n~p", [RCD]), 1103 1104 p("stop user"), 1105 ok = megaco_config:stop_user(LocalMid1), 1106 1107 p("stop megaco config process"), 1108 megaco_config:stop(), 1109 1110 p("done"), 1111 ok. 1112 1113 1114%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1115 1116otp_8167(suite) -> 1117 []; 1118otp_8167(Config) when is_list(Config) -> 1119 put(tc, otp8167), 1120 p("start"), 1121 1122 LocalMid1 = {deviceName, "local-mid-1"}, 1123 LocalMid2 = {deviceName, "local-mid-2"}, 1124 RemoteMid1 = {deviceName, "remote-mid-1"}, 1125 %% RemoteMid2 = {deviceName, "remote-mid-2"}, 1126 RH1 = #megaco_receive_handle{local_mid = LocalMid1, 1127 encoding_mod = dummy_codec_module, 1128 encoding_config = [], 1129 send_mod = dummy_transport_module}, 1130%% RH2 = #megaco_receive_handle{local_mid = LocalMid2, 1131%% encoding_mod = dummy_codec_module, 1132%% encoding_config = [], 1133%% send_mod = dummy_transport_module}, 1134 1135 User1ConfigA = [{call_proxy_gc_timeout, 1}], 1136 User1ConfigB = [{call_proxy_gc_timeout, 0}], 1137 User2ConfigA = [{call_proxy_gc_timeout, -1}], 1138 User2ConfigB = [{call_proxy_gc_timeout, infinity}], 1139 User2ConfigC = [{call_proxy_gc_timeout, "1"}], 1140 User2ConfigD = [{call_proxy_gc_timeout, 1.0}], 1141 1142 p("start local user (1A): ~p", [LocalMid1]), 1143 ok = megaco_config:start_user(LocalMid1, User1ConfigA), 1144 p("stop local user (1A): ~p", [LocalMid1]), 1145 ok = megaco_config:stop_user(LocalMid1), 1146 1147 p("start local user (1B): ~p", [LocalMid1]), 1148 ok = megaco_config:start_user(LocalMid1, User1ConfigB), 1149 p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", 1150 [LocalMid1, -1]), 1151 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, -1}} = 1152 megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, -1), 1153 p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", 1154 [LocalMid1, infinity]), 1155 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, infinity}} = 1156 megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, infinity), 1157 p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", 1158 [LocalMid1, "1"]), 1159 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, "1"}} = 1160 megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, "1"), 1161 p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", 1162 [LocalMid1, 1.0]), 1163 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, 1.0}} = 1164 megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, 1.0), 1165 p("change value for item call_proxy_gc_timeout for local user: ~p", [LocalMid1]), 1166 ok = megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, 10101), 1167 1168 p("connect"), 1169 {ok, CD} = megaco_config:connect(RH1, RemoteMid1, 1170 dummy_send_handle, self()), 1171 p("connect ok: CD = ~n~p", [CD]), 1172 CH = CD#conn_data.conn_handle, 1173 1174 p("get value for item cancel from connection: ~p", [CH]), 1175 false = megaco_config:conn_info(CH, cancel), 1176 1177 p("get value for item cancel from connection data", []), 1178 false = megaco_config:conn_info(CD, cancel), 1179 1180 p("get value for item call_proxy_gc_timeout for connection: ~p", [CH]), 1181 10101 = megaco_config:conn_info(CH, call_proxy_gc_timeout), 1182 1183 p("change value for item call_proxy_gc_timeout for connection: ~p -> ~p", 1184 [CH, 20202]), 1185 ok = megaco_config:update_conn_info(CH, call_proxy_gc_timeout, 20202), 1186 1187 p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", 1188 [CH, -1]), 1189 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, -1}} = 1190 megaco_config:update_conn_info(CH, call_proxy_gc_timeout, -1), 1191 1192 p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", 1193 [CH, infinity]), 1194 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, infinity}} = 1195 megaco_config:update_conn_info(CH, call_proxy_gc_timeout, infinity), 1196 1197 p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", 1198 [CH, "1"]), 1199 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, "1"}} = 1200 megaco_config:update_conn_info(CH, call_proxy_gc_timeout, "1"), 1201 1202 p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", 1203 [CH, 1.0]), 1204 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, 1.0}} = 1205 megaco_config:update_conn_info(CH, call_proxy_gc_timeout, 1.0), 1206 1207 p("disconnect: ~p", [CH]), 1208 {ok, _, _} = megaco_config:disconnect(CH), 1209 1210 p("stop local user (1B): ~p", [LocalMid1]), 1211 ok = megaco_config:stop_user(LocalMid1), 1212 1213 p("try (and fail) start local user (2A): ~p", [LocalMid2]), 1214 {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, -1}} = 1215 megaco_config:start_user(LocalMid2, User2ConfigA), 1216 1217 p("try (and fail) start local user (2B): ~p", [LocalMid2]), 1218 {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, infinity}} = 1219 megaco_config:start_user(LocalMid2, User2ConfigB), 1220 1221 p("try (and fail) start local user (2C): ~p", [LocalMid2]), 1222 {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, "1"}} = 1223 megaco_config:start_user(LocalMid2, User2ConfigC), 1224 1225 p("try (and fail) start local user (2D): ~p", [LocalMid2]), 1226 {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, 1.0}} = 1227 megaco_config:start_user(LocalMid2, User2ConfigD), 1228 1229 p("done"), 1230 ok. 1231 1232 1233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1234 1235otp_8183(suite) -> 1236 []; 1237otp_8183(Config) when is_list(Config) -> 1238 put(tc, otp8183), 1239 p("start"), 1240 1241 LocalMid1 = {deviceName, "local-mid-1"}, 1242 LocalMid2 = {deviceName, "local-mid-2"}, 1243 RemoteMid1 = {deviceName, "remote-mid-1"}, 1244%% RemoteMid2 = {deviceName, "remote-mid-2"}, 1245 RH1 = #megaco_receive_handle{local_mid = LocalMid1, 1246 encoding_mod = dummy_codec_module, 1247 encoding_config = [], 1248 send_mod = dummy_transport_module}, 1249%% RH2 = #megaco_receive_handle{local_mid = LocalMid2, 1250%% encoding_mod = dummy_codec_module, 1251%% encoding_config = [], 1252%% send_mod = dummy_transport_module}, 1253 1254 OkValA = 100, 1255 OkValB = 0, 1256 OkValC = plain, 1257 OkValD = 10101, 1258 OkValE = 20202, 1259 BadValA = -1, 1260 BadValB = pain, 1261 BadValC = "1", 1262 BadValD = 1.0, 1263 User1ConfigA = [{request_keep_alive_timeout, OkValA}], 1264 User1ConfigB = [{request_keep_alive_timeout, OkValB}], 1265 User1ConfigC = [{request_keep_alive_timeout, OkValC}], 1266 User2ConfigA = [{request_keep_alive_timeout, BadValA}], 1267 User2ConfigB = [{request_keep_alive_timeout, BadValB}], 1268 User2ConfigC = [{request_keep_alive_timeout, BadValC}], 1269 User2ConfigD = [{request_keep_alive_timeout, BadValD}], 1270 1271 p("start local user (1A): ~p", [LocalMid1]), 1272 ok = megaco_config:start_user(LocalMid1, User1ConfigA), 1273 p("stop local user (1A): ~p", [LocalMid1]), 1274 ok = megaco_config:stop_user(LocalMid1), 1275 1276 p("start local user (1B): ~p", [LocalMid1]), 1277 ok = megaco_config:start_user(LocalMid1, User1ConfigB), 1278 p("stop local user (1B): ~p", [LocalMid1]), 1279 ok = megaco_config:stop_user(LocalMid1), 1280 1281 p("start local user (1C): ~p", [LocalMid1]), 1282 ok = megaco_config:start_user(LocalMid1, User1ConfigC), 1283 1284 p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", 1285 [LocalMid1, BadValA]), 1286 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValA}} = 1287 megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValA), 1288 1289 p("try (and fail) change value for item request_keep_alive_timeout for local user: ~p -> ~p", 1290 [LocalMid1, BadValB]), 1291 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValB}} = 1292 megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValB), 1293 1294 p("try (and fail) change value for item request_keep_alive_timeout for local user: ~p -> ~p", 1295 [LocalMid1, BadValC]), 1296 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValC}} = 1297 megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValC), 1298 1299 p("try (and fail) change value for item request_keep_alive_timeout for local user: ~p -> ~p", 1300 [LocalMid1, BadValD]), 1301 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValD}} = 1302 megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValD), 1303 1304 p("change value for item request_keep_alive_timeout for local user: ~p", [LocalMid1]), 1305 ok = megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, OkValD), 1306 1307 p("connect"), 1308 {ok, CD} = megaco_config:connect(RH1, RemoteMid1, 1309 dummy_send_handle, self()), 1310 p("connect ok: CD = ~n~p", [CD]), 1311 CH = CD#conn_data.conn_handle, 1312 1313 p("get value for item request_keep_alive_timeout for connection: ~p", [CH]), 1314 OkValD = megaco_config:conn_info(CH, request_keep_alive_timeout), 1315 1316 p("change value for item request_keep_alive_timeout for connection: ~p -> ~p", 1317 [CH, OkValE]), 1318 ok = megaco_config:update_conn_info(CH, request_keep_alive_timeout, OkValE), 1319 1320 p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", 1321 [CH, BadValA]), 1322 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValA}} = 1323 megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValA), 1324 1325 p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", 1326 [CH, BadValB]), 1327 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValB}} = 1328 megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValB), 1329 1330 p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", 1331 [CH, BadValC]), 1332 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValC}} = 1333 megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValC), 1334 1335 p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", 1336 [CH, BadValD]), 1337 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValD}} = 1338 megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValD), 1339 1340 p("disconnect: ~p", [CH]), 1341 {ok, _, _} = megaco_config:disconnect(CH), 1342 1343 p("stop local user (1B): ~p", [LocalMid1]), 1344 ok = megaco_config:stop_user(LocalMid1), 1345 1346 p("try (and fail) start local user (2A): ~p", [LocalMid2]), 1347 {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValA}} = 1348 megaco_config:start_user(LocalMid2, User2ConfigA), 1349 1350 p("try (and fail) start local user (2B): ~p", [LocalMid2]), 1351 {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValB}} = 1352 megaco_config:start_user(LocalMid2, User2ConfigB), 1353 1354 p("try (and fail) start local user (2C): ~p", [LocalMid2]), 1355 {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValC}} = 1356 megaco_config:start_user(LocalMid2, User2ConfigC), 1357 1358 p("try (and fail) start local user (2D): ~p", [LocalMid2]), 1359 {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValD}} = 1360 megaco_config:start_user(LocalMid2, User2ConfigD), 1361 1362 p("done"), 1363 ok. 1364 1365 1366%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1367 1368try_tc(TCName, Pre, Case, Post) -> 1369 try_tc(TCName, "TEST", ?TEST_VERBOSITY, Pre, Case, Post). 1370 1371try_tc(TCName, Name, Verbosity, Pre, Case, Post) -> 1372 ?TRY_TC(TCName, Name, Verbosity, Pre, Case, Post). 1373 1374 1375%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1376 1377ts() -> 1378 erlang:monotonic_time(milli_seconds). 1379 1380tsd(TSD) -> 1381 if (TSD < 1000) -> 1382 ?F("~w ms", [TSD]); 1383 (TSD < 60000) -> 1384 ?F("~w secs", [TSD div 1000]); 1385 true -> 1386 ?F("~w mins", [TSD div 60000]) 1387 end. 1388 1389 1390 1391 1392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1393 1394p(F) -> 1395 p(F, []). 1396 1397p(F, A) -> 1398 case get(tc) of 1399 undefined -> 1400 io:format(F ++ "~n", A); 1401 TC -> 1402 io:format("[~w] " ++ F ++ "~n", [TC|A]) 1403 end. 1404 1405 1406i(F) -> 1407 i(F, []). 1408 1409i(F, A) -> 1410 print(info, get(verbosity), get(tc), "INFO", F, A). 1411 1412e(F, A) -> 1413 print(info, get(verbosity), get(tc), "ERROR", F, A). 1414 1415printable(_, debug) -> true; 1416printable(info, info) -> true; 1417printable(_,_) -> false. 1418 1419print(Severity, Verbosity, Tc, P, F, A) -> 1420 print(printable(Severity,Verbosity), Tc, P, F, A). 1421 1422print(true, Tc, P, F, A) -> 1423 io:format("*** [~s] ~s ~p ~s:~w ***" 1424 "~n " ++ F ++ "~n", 1425 [?FTS(), P, self(), get(sname), Tc | A]); 1426print(_, _, _, _, _) -> 1427 ok. 1428