1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2000-2016. 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_test). 27 28-compile(export_all). 29 30-include("megaco_test_lib.hrl"). 31-include_lib("megaco/include/megaco.hrl"). 32-include_lib("megaco/src/app/megaco_internal.hrl"). 33 34t() -> megaco_test_lib:t(?MODULE). 35t(Case) -> megaco_test_lib:t({?MODULE, Case}). 36 37min(M) -> timer:minutes(M). 38 39%% Test server callbacks 40init_per_testcase(Case, Config) -> 41 C = lists:keydelete(tc_timeout, 1, Config), 42 do_init_per_testcase(Case, [{tc_timeout, min(3)}|C]). 43 44do_init_per_testcase(Case, Config) -> 45 process_flag(trap_exit, true), 46 megaco_test_lib:init_per_testcase(Case, Config). 47 48end_per_testcase(Case, Config) -> 49 process_flag(trap_exit, false), 50 megaco_test_lib:end_per_testcase(Case, Config). 51 52 53-record(command, {id, desc, cmd, verify}). 54 55-define(TEST_VERBOSITY, debug). 56-define(NUM_CNT_PROCS, 100). 57 58 59%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 60%% Top test case 61 62all() -> 63 [config, {group, transaction_id_counter}, 64 {group, tickets}]. 65 66groups() -> 67 [{transaction_id_counter, [], 68 [transaction_id_counter_mg, 69 transaction_id_counter_mgc]}, 70 {tickets, [], [otp_7216, otp_8167, otp_8183]}]. 71 72init_per_group(_GroupName, Config) -> 73 Config. 74 75end_per_group(_GroupName, Config) -> 76 Config. 77 78 79%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 80%% Config test case 81 82config(suite) -> 83 []; 84config(Config) when is_list(Config) -> 85 ?ACQUIRE_NODES(1, Config), 86 Mid = fake_mid, 87 88 %% Nice values 89 Int = 3, 90 IT = #megaco_incr_timer{max_retries = Int}, 91 92 %% Evil values 93 NonInt = non_int, 94 IT2 = #megaco_incr_timer{wait_for = NonInt}, 95 IT3 = #megaco_incr_timer{factor = NonInt}, 96 IT4 = #megaco_incr_timer{max_retries = NonInt}, 97 IT5 = #megaco_incr_timer{max_retries = non_infinity}, 98 99 %% Command range values 100 Initial = 100, 101 Verify = 200, 102 Nice = 300, 103 Evil = 400, 104 End = 500, 105 106 InitialCmd = 107 fun(No, Desc, Cmd, VerifyVal) -> 108 initial_command(Initial + No, Desc, Cmd, VerifyVal) 109 end, 110 111 VerifyCmd = 112 fun(M, No, Key, V) -> 113 verify_user_default_command(M, Verify + No, Key, V) 114 end, 115 116 NiceCmd = 117 fun(M, No, Key, Val) -> 118 nice_user_update_command(M, Nice + No, Key, Val) 119 end, 120 121 EvilCmd = 122 fun(M, No, Key, Val) -> 123 evil_user_update_command(M, Evil + No, Key, Val) 124 end, 125 126 %% End commands 127 ExitCmd = 128 fun(No, Desc, Cmd) -> 129 exit_command(End + No, Desc, Cmd) 130 end, 131 ErrorCmd = 132 fun(No, Desc, Cmd, MainReason, TS) -> 133 error_command(End + No, Desc, Cmd, MainReason, TS) 134 end, 135 PlainCmd = 136 fun(No, Desc, Cmd, V) -> 137 command(End + No, Desc, Cmd, V) 138 end, 139 140 Commands = 141 [ 142 %% Initial commands 143 InitialCmd(0, 144 "enable trace", 145 fun() -> megaco:enable_trace(100, io) end, 146 ok), 147 InitialCmd(1, 148 "start", 149 fun() -> megaco:start() end, 150 ok), 151 InitialCmd(2, 152 "Verify no active requests", 153 fun() -> megaco:system_info(n_active_requests) end, 154 0), 155 InitialCmd(3, 156 "Verify no active replies", 157 fun() -> megaco:system_info(n_active_replies) end, 158 0), 159 InitialCmd(4, 160 "Verify no active connections", 161 fun() -> megaco:system_info(n_active_connections) end, 162 0), 163 InitialCmd(5, 164 "Verify no connections", 165 fun() -> megaco:system_info(connections) end, 166 []), 167 InitialCmd(6, 168 "Verify no users", 169 fun() -> megaco:system_info(users) end, 170 []), 171 InitialCmd(7, 172 "Start user", 173 fun() -> megaco:start_user(Mid, []) end, 174 ok), 175 176 177 %% Verify user defaults 178 VerifyCmd(Mid, 1, connections, []), 179 VerifyCmd(Mid, 2, min_trans_id, 1), 180 VerifyCmd(Mid, 3, max_trans_id, infinity), 181 VerifyCmd(Mid, 4, request_timer, #megaco_incr_timer{}), 182 VerifyCmd(Mid, 5, long_request_timer, timer:seconds(60)), 183 VerifyCmd(Mid, 6, auto_ack, false), 184 VerifyCmd(Mid, 7, pending_timer, 30000), 185 VerifyCmd(Mid, 8, reply_timer, 30000), 186 VerifyCmd(Mid, 9, send_mod, megaco_tcp), 187 VerifyCmd(Mid, 10, encoding_mod, megaco_pretty_text_encoder), 188 VerifyCmd(Mid, 11, encoding_config, []), 189 VerifyCmd(Mid, 12, protocol_version, 1), 190 VerifyCmd(Mid, 13, reply_data, undefined), 191 VerifyCmd(Mid, 14, receive_handle, 192 fun(H) when is_record(H, megaco_receive_handle) -> 193 {ok, H}; 194 (R) -> 195 {error, R} 196 end), 197 198 199 %% Nice update 200 NiceCmd(Mid, 1, min_trans_id, Int), 201 NiceCmd(Mid, 2, max_trans_id, Int), 202 NiceCmd(Mid, 3, max_trans_id, infinity), 203 NiceCmd(Mid, 4, request_timer, Int), 204 NiceCmd(Mid, 5, request_timer, infinity), 205 NiceCmd(Mid, 6, request_timer, IT), 206 NiceCmd(Mid, 7, long_request_timer, Int), 207 NiceCmd(Mid, 8, long_request_timer, infinity), 208 NiceCmd(Mid, 9, long_request_timer, IT), 209 NiceCmd(Mid, 10, auto_ack, true), 210 NiceCmd(Mid, 11, auto_ack, false), 211 NiceCmd(Mid, 12, pending_timer, Int), 212 NiceCmd(Mid, 13, pending_timer, infinity), 213 NiceCmd(Mid, 14, pending_timer, IT), 214 NiceCmd(Mid, 15, reply_timer, Int), 215 NiceCmd(Mid, 16, reply_timer, infinity), 216 NiceCmd(Mid, 17, reply_timer, IT), 217 NiceCmd(Mid, 18, send_mod, an_atom), 218 NiceCmd(Mid, 19, encoding_mod, an_atom), 219 NiceCmd(Mid, 20, encoding_config, []), 220 NiceCmd(Mid, 21, protocol_version, Int), 221 NiceCmd(Mid, 23, reply_data, IT), 222 NiceCmd(Mid, 23, resend_indication, true), 223 NiceCmd(Mid, 24, resend_indication, false), 224 NiceCmd(Mid, 25, resend_indication, flag), 225 226 227 %% Evil update 228 EvilCmd(Mid, 1, min_trans_id, NonInt), 229 EvilCmd(Mid, 2, max_trans_id, NonInt), 230 EvilCmd(Mid, 3, max_trans_id, non_infinity), 231 EvilCmd(Mid, 4, request_timer, NonInt), 232 EvilCmd(Mid, 5, request_timer, non_infinity), 233 EvilCmd(Mid, 6, request_timer, IT2), 234 EvilCmd(Mid, 7, request_timer, IT3), 235 EvilCmd(Mid, 8, request_timer, IT4), 236 EvilCmd(Mid, 9, request_timer, IT5), 237 EvilCmd(Mid, 10, long_request_timer, NonInt), 238 EvilCmd(Mid, 11, long_request_timer, non_infinity), 239 EvilCmd(Mid, 12, long_request_timer, IT2), 240 EvilCmd(Mid, 13, long_request_timer, IT3), 241 EvilCmd(Mid, 14, long_request_timer, IT4), 242 EvilCmd(Mid, 15, long_request_timer, IT5), 243 EvilCmd(Mid, 16, auto_ack, non_bool), 244 EvilCmd(Mid, 17, pending_timer, NonInt), 245 EvilCmd(Mid, 18, pending_timer, non_infinity), 246 EvilCmd(Mid, 19, pending_timer, IT2), 247 EvilCmd(Mid, 20, pending_timer, IT3), 248 EvilCmd(Mid, 21, pending_timer, IT4), 249 EvilCmd(Mid, 22, pending_timer, IT5), 250 EvilCmd(Mid, 23, reply_timer, NonInt), 251 EvilCmd(Mid, 24, reply_timer, non_infinity), 252 EvilCmd(Mid, 25, reply_timer, IT2), 253 EvilCmd(Mid, 26, reply_timer, IT3), 254 EvilCmd(Mid, 27, reply_timer, IT4), 255 EvilCmd(Mid, 28, reply_timer, IT5), 256 EvilCmd(Mid, 29, send_mod, {non_atom}), 257 EvilCmd(Mid, 30, encoding_mod, {non_atom}), 258 EvilCmd(Mid, 31, encoding_config, non_list), 259 EvilCmd(Mid, 32, protocol_version, NonInt), 260 EvilCmd(Mid, 33, resend_indication, flagg), 261 262 263 %% End 264 ExitCmd(1, "Verify non-existing system info", 265 fun() -> megaco:system_info(non_exist) end), 266 ExitCmd(2, "Verify non-existing user user info", 267 fun() -> megaco:user_info(non_exist, trans_id) end), 268 ExitCmd(3, "Verify non-existing user info", 269 fun() -> megaco:user_info(Mid, non_exist) end), 270 271 ErrorCmd(4, "Try updating user info for non-existing user", 272 fun() -> 273 megaco:update_user_info(non_exist, trans_id, 1) 274 end, 275 no_such_user, 2), 276 ErrorCmd(11, "Try updating non-existing user info", 277 fun() -> 278 megaco:update_user_info(Mid, trans_id, 4711) 279 end, 280 bad_user_val, 4), 281 ErrorCmd(12, "Try start already started user", 282 fun() -> megaco:start_user(Mid, []) end, 283 user_already_exists, 2), 284 285 PlainCmd(13, "Verify started users", 286 fun() -> megaco:system_info(users) end, [Mid]), 287 PlainCmd(14, "Stop user", fun() -> megaco:stop_user(Mid) end, ok), 288 PlainCmd(15, "Verify started users", 289 fun() -> megaco:system_info(users) end, []), 290 ErrorCmd(16, "Try stop not started user", 291 fun() -> megaco:stop_user(Mid) end, no_such_user, 2), 292 ErrorCmd(17, "Try start megaco (it's already started)", 293 fun() -> megaco:start() end, already_started, 2), 294 PlainCmd(18, "Stop megaco", fun() -> megaco:stop() end, ok), 295 ErrorCmd(19, "Try stop megaco (it's not running)", 296 fun() -> megaco:stop() end, not_started, 2) 297 ], 298 299 300 exec(Commands). 301 302 303 304exec([]) -> 305 ok; 306exec([#command{id = No, 307 desc = Desc, 308 cmd = Cmd, 309 verify = Verify}|Commands]) -> 310 io:format("Executing command ~3w: ~s: ", [No, Desc]), 311 case (catch Verify((catch Cmd()))) of 312 {ok, OK} -> 313 io:format("ok => ~p~n", [OK]), 314 exec(Commands); 315 {error, Reason} -> 316 io:format("error => ~p~n", [Reason]), 317 {error, {bad_result, No, Reason}}; 318 Error -> 319 io:format("exit => ~p~n", [Error]), 320 {error, {unexpected_result, No, Error}} 321 end. 322 323initial_command(No, Desc0, Cmd, VerifyVal) when is_function(Cmd) -> 324 Desc = lists:flatten(io_lib:format("Initial - ~s", [Desc0])), 325 command(No, Desc, Cmd, VerifyVal). 326 327verify_user_default_command(Mid, No, Key, Verify) -> 328 Desc = lists:flatten(io_lib:format("Defaults - Verify ~w", [Key])), 329 Cmd = fun() -> megaco:user_info(Mid, Key) end, 330 command(No, Desc, Cmd, Verify). 331 332nice_user_update_command(Mid, No, Key, Val) -> 333 Desc = lists:flatten(io_lib:format("Nice - Update ~w", [Key])), 334 Cmd = fun() -> megaco:update_user_info(Mid, Key, Val) end, 335 Verify = fun(ok) -> 336 case (catch megaco:user_info(Mid, Key)) of 337 {'EXIT', R} -> 338 {error, {value_retreival_failed, R}}; 339 Val -> 340 {ok, Val}; 341 Invalid -> 342 {error, {value_update_failed, Val, Invalid}} 343 end; 344 (R) -> 345 {error, R} 346 end, 347 command(No, Desc, Cmd, Verify). 348 349 350evil_user_update_command(Mid, No, Key, Val) -> 351 Desc = lists:flatten(io_lib:format("Evil - Update ~w", [Key])), 352 Cmd = fun() -> 353 case (catch megaco:user_info(Mid, Key)) of 354 {'EXIT', R} -> 355 {{error, {old_value_retreival_failed, R}}, 356 ignore}; 357 OldVal -> 358 {OldVal, 359 (catch megaco:update_user_info(Mid, Key, Val))} 360 end 361 end, 362 Verify = fun({{error, _} = Error, ignore}) -> 363 Error; 364 ({OldVal, {error, {bad_user_val, _, _, _}}}) -> 365 case (catch megaco:user_info(Mid, Key)) of 366 {'EXIT', R} -> 367 {error, {value_retreival_failed, R}}; 368 OldVal -> 369 {ok, OldVal}; 370 Invalid -> 371 {error, {value_update_failed, OldVal, Invalid}} 372 end; 373 (R) -> 374 {error, R} 375 end, 376 command(No, Desc, Cmd, Verify). 377 378exit_command(No, Desc, Cmd) when is_function(Cmd) -> 379 Verify = fun({'EXIT', _} = E) -> 380 {ok, E}; 381 (R) -> 382 {error, R} 383 end, 384 command(No, Desc, Cmd, Verify). 385 386error_command(No, Desc, Cmd, MainReason, TS) when is_function(Cmd) -> 387 Verify = fun({error, Reason}) -> 388 io:format("verify -> Reason: ~n~p~n", [Reason]), 389 case Reason of 390 {MainReason, _} when TS == 2 -> 391 {ok, MainReason}; 392 {MainReason, _, _, _} when TS == 4 -> 393 {ok, MainReason}; 394 _ -> 395 {error, Reason} 396 end; 397 (R) -> 398 {error, R} 399 end, 400 command(No, Desc, Cmd, Verify). 401 402command(No, Desc, Cmd, Verify) 403 when (is_integer(No) andalso 404 is_list(Desc) andalso 405 is_function(Cmd) andalso 406 is_function(Verify)) -> 407 #command{id = No, 408 desc = Desc, 409 cmd = Cmd, 410 verify = Verify}; 411command(No, Desc, Cmd, VerifyVal) 412 when (is_integer(No) andalso 413 is_list(Desc) andalso 414 is_function(Cmd)) -> 415 Verify = fun(Val) -> 416 case Val of 417 VerifyVal -> 418 {ok, Val}; 419 _ -> 420 {error, Val} 421 end 422 end, 423 #command{id = No, 424 desc = Desc, 425 cmd = Cmd, 426 verify = Verify}. 427 428 429%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 430 431transaction_id_counter_mg(suite) -> 432 []; 433transaction_id_counter_mg(doc) -> 434 ["This test case is intended to test and verify the " 435 "transaction counter handling of the application " 436 "in with one connection (MG). "]; 437transaction_id_counter_mg(Config) when is_list(Config) -> 438 put(verbosity, ?TEST_VERBOSITY), 439 put(sname, "TEST"), 440 put(tc, transaction_id_counter_mg), 441 442 process_flag(trap_exit, true), 443 444 i("starting"), 445 446 {ok, _ConfigPid} = megaco_config:start_link(), 447 448 %% Basic user data 449 UserMid = {deviceName, "mg"}, 450 UserConfig = [ 451 {min_trans_id, 1} 452 ], 453 454 %% Basic connection data 455 RemoteMid = {deviceName, "mgc"}, 456 RecvHandle = #megaco_receive_handle{local_mid = UserMid, 457 encoding_mod = ?MODULE, 458 encoding_config = [], 459 send_mod = ?MODULE}, 460 SendHandle = dummy_send_handle, 461 ControlPid = self(), 462 463 %% Start user 464 i("start user"), 465 ok = megaco_config:start_user(UserMid, UserConfig), 466 467 %% Create connection 468 i("create connection"), 469 {ok, CD} = 470 megaco_config:connect(RecvHandle, RemoteMid, SendHandle, ControlPid), 471 472 %% Set counter limits 473 i("set counter max limit"), 474 CH = CD#conn_data.conn_handle, 475 megaco_config:update_conn_info(CH, max_trans_id, 1000), 476 477 %% Create the counter worker procs 478 i("create counter working procs"), 479 Pids = create_counter_working_procs(CH, ?NUM_CNT_PROCS, []), 480 481 %% Start the counter worker procs 482 i("release the counter working procs"), 483 start_counter_working_procs(Pids), 484 485 %% Await the counter worker procs termination 486 i("await the counter working procs completion"), 487 await_completion_counter_working_procs(Pids), 488 489 %% Verify result 490 i("verify counter result"), 491 TransId = megaco_config:conn_info(CH, trans_id), 492 1 = TransId, 493 494 %% Stop test 495 i("disconnect"), 496 {ok, _, _} = megaco_config:disconnect(CH), 497 i("stop user"), 498 ok = megaco_config:stop_user(UserMid), 499 i("stop megaco_config"), 500 ok = megaco_config:stop(), 501 502 i("done"), 503 ok. 504 505 506 507create_counter_working_procs(_CH, 0, Pids) -> 508 Pids; 509create_counter_working_procs(CH, N, Pids) -> 510 TC = get(tc), 511 Pid = erlang:spawn_link(fun() -> counter_init(CH, TC) end), 512 create_counter_working_procs(CH, N-1, [Pid | Pids]). 513 514counter_init(CH, TC) -> 515 put(verbosity, ?TEST_VERBOSITY), 516 put(sname, lists:flatten(io_lib:format("CNT-~p", [self()]))), 517 put(tc, TC), 518 UserMid = CH#megaco_conn_handle.local_mid, 519 Min = megaco_config:user_info(UserMid, min_trans_id), 520 Max = megaco_config:conn_info(CH, max_trans_id), 521 Num = Max - Min + 1, 522 receive 523 start -> 524 %% i("received start command (~p)", [Num]), 525 ok 526 end, 527 counter_loop(CH, Num). 528 529counter_loop(_CH, 0) -> 530 %% i("done"), 531 exit(normal); 532counter_loop(CH, Num) when (Num > 0) -> 533 megaco_config:incr_trans_id_counter(CH, 1), 534 counter_loop(CH, Num-1). 535 536start_counter_working_procs([]) -> 537 %% i("released"), 538 ok; 539start_counter_working_procs([Pid | Pids]) -> 540 Pid ! start, 541 start_counter_working_procs(Pids). 542 543await_completion_counter_working_procs([]) -> 544 ok; 545await_completion_counter_working_procs(Pids) -> 546 receive 547 {'EXIT', Pid, normal} -> 548 Pids2 = lists:delete(Pid, Pids), 549 await_completion_counter_working_procs(Pids2); 550 _Any -> 551 await_completion_counter_working_procs(Pids) 552 end. 553 554 555%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 556 557transaction_id_counter_mgc(suite) -> 558 []; 559transaction_id_counter_mgc(doc) -> 560 ["This test case is intended to test and verify the " 561 "transaction counter handling of the application " 562 "in with several connections (MGC). "]; 563transaction_id_counter_mgc(Config) when is_list(Config) -> 564 put(verbosity, ?TEST_VERBOSITY), 565 put(sname, "TEST"), 566 put(tc, transaction_id_counter_mgc), 567 process_flag(trap_exit, true), 568 569 i("starting"), 570 571 {ok, _ConfigPid} = megaco_config:start_link(), 572 573 %% Basic user data 574 UserMid = {deviceName, "mgc"}, 575 UserConfig = [ 576 {min_trans_id, 1} 577 ], 578 579 %% Basic connection data 580 RemoteMids = 581 [ 582 {deviceName, "mg01"}, 583 {deviceName, "mg02"}, 584 {deviceName, "mg03"}, 585 {deviceName, "mg04"}, 586 {deviceName, "mg05"}, 587 {deviceName, "mg06"}, 588 {deviceName, "mg07"}, 589 {deviceName, "mg08"}, 590 {deviceName, "mg09"}, 591 {deviceName, "mg10"} 592 ], 593 RecvHandles = 594 [ 595 #megaco_receive_handle{local_mid = UserMid, 596 encoding_mod = ?MODULE, 597 encoding_config = [], 598 send_mod = ?MODULE}, 599 #megaco_receive_handle{local_mid = UserMid, 600 encoding_mod = ?MODULE, 601 encoding_config = [], 602 send_mod = ?MODULE}, 603 #megaco_receive_handle{local_mid = UserMid, 604 encoding_mod = ?MODULE, 605 encoding_config = [], 606 send_mod = ?MODULE}, 607 #megaco_receive_handle{local_mid = UserMid, 608 encoding_mod = ?MODULE, 609 encoding_config = [], 610 send_mod = ?MODULE}, 611 #megaco_receive_handle{local_mid = UserMid, 612 encoding_mod = ?MODULE, 613 encoding_config = [], 614 send_mod = ?MODULE}, 615 #megaco_receive_handle{local_mid = UserMid, 616 encoding_mod = ?MODULE, 617 encoding_config = [], 618 send_mod = ?MODULE}, 619 #megaco_receive_handle{local_mid = UserMid, 620 encoding_mod = ?MODULE, 621 encoding_config = [], 622 send_mod = ?MODULE}, 623 #megaco_receive_handle{local_mid = UserMid, 624 encoding_mod = ?MODULE, 625 encoding_config = [], 626 send_mod = ?MODULE}, 627 #megaco_receive_handle{local_mid = UserMid, 628 encoding_mod = ?MODULE, 629 encoding_config = [], 630 send_mod = ?MODULE}, 631 #megaco_receive_handle{local_mid = UserMid, 632 encoding_mod = ?MODULE, 633 encoding_config = [], 634 send_mod = ?MODULE} 635 ], 636 SendHandle = dummy_send_handle, 637 ControlPid = self(), 638 639 %% Start user 640 i("start user"), 641 ok = megaco_config:start_user(UserMid, UserConfig), 642 643 %% Create connection 644 i("create connection(s)"), 645 CDs = create_connections(RecvHandles, RemoteMids, SendHandle, ControlPid), 646 647 %% Set counter limits 648 i("set counter max limit(s)"), 649 set_counter_max_limits(CDs, 1000), 650 651 %% Create the counter worker procs 652 i("create counter working procs"), 653 Pids = create_counter_working_procs(CDs, ?NUM_CNT_PROCS), 654 655 %% Start the counter worker procs 656 i("release the counter working procs"), 657 start_counter_working_procs(Pids), 658 659 %% Await the counter worker procs termination 660 i("await the counter working procs completion"), 661 await_completion_counter_working_procs(Pids), 662 663 %% Verify result 664 i("verify counter result"), 665 verify_counter_results(CDs), 666 667 %% Stop test 668 i("disconnect"), 669 delete_connections(CDs), 670 i("stop user"), 671 ok = megaco_config:stop_user(UserMid), 672 i("stop megaco_config"), 673 ok = megaco_config:stop(), 674 675 i("done"), 676 ok. 677 678create_connections(RecvHandles, RemoteMids, SendHandle, ControlPid) -> 679 create_connections(RecvHandles, RemoteMids, SendHandle, ControlPid, []). 680 681create_connections([], [], _SendHandle, _ControlPid, Acc) -> 682 lists:reverse(Acc); 683create_connections([RecvHandle | RecvHandles], 684 [RemoteMid | RemoteMids], 685 SendHandle, ControlPid, Acc) -> 686 {ok, CD} = 687 megaco_config:connect(RecvHandle, RemoteMid, SendHandle, ControlPid), 688 create_connections(RecvHandles, RemoteMids, 689 SendHandle, ControlPid, [CD | Acc]). 690 691 692set_counter_max_limits([], _MaxTransId) -> 693 ok; 694set_counter_max_limits([#conn_data{conn_handle = CH} | CDs], MaxTransId) -> 695 megaco_config:update_conn_info(CH, max_trans_id, MaxTransId), 696 set_counter_max_limits(CDs, MaxTransId). 697 698 699create_counter_working_procs(CDs, NumCntProcs) -> 700 lists:flatten(create_counter_working_procs2(CDs, NumCntProcs)). 701 702create_counter_working_procs2([], _NumCntProcs) -> 703 []; 704create_counter_working_procs2([#conn_data{conn_handle = CH} | CDs], 705 NumCntProcs) -> 706 [create_counter_working_procs(CH, NumCntProcs, []) | 707 create_counter_working_procs2(CDs, NumCntProcs)]. 708 709 710verify_counter_results([]) -> 711 ok; 712verify_counter_results([#conn_data{conn_handle = CH} | CDs]) -> 713 TransId = megaco_config:conn_info(CH, trans_id), 714 if 715 (TransId =:= 1) -> 716 ok; 717 true -> 718 ?ERROR({trans_id_verification_failed, CH, TransId}) 719 end, 720 verify_counter_results(CDs). 721 722 723delete_connections([]) -> 724 ok; 725delete_connections([#conn_data{conn_handle = CH} | CDs]) -> 726 {ok, _, _} = megaco_config:disconnect(CH), 727 delete_connections(CDs). 728 729 730 731%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 732 733otp_7216(suite) -> 734 []; 735otp_7216(Config) when is_list(Config) -> 736 put(tc, otp_7216), 737 p("start"), 738 739 p("start the megaco config process"), 740 megaco_config:start_link(), 741 742 LocalMid1 = {deviceName, "local-mid-1"}, 743 %% LocalMid2 = {deviceName, "local-mid-2"}, 744 RemoteMid1 = {deviceName, "remote-mid-1"}, 745 %% RemoteMid2 = {deviceName, "remote-mid-2"}, 746 RH = #megaco_receive_handle{local_mid = LocalMid1, 747 encoding_mod = dummy_codec_module, 748 encoding_config = [], 749 send_mod = dummy_transport_module}, 750 MinTransId = 7216, 751 MaxTransId = MinTransId + 10, 752 User1Config = [{min_trans_id, MinTransId}, 753 {max_trans_id, MaxTransId}], 754 755 VerifySerial = 756 fun(Actual, Expected) -> 757 if 758 Actual == Expected -> 759 ok; 760 true -> 761 throw({error, {invalid_counter_value, Actual}}) 762 end 763 end, 764 765 p("start local user: ~p", [LocalMid1]), 766 ok = megaco_config:start_user(LocalMid1, User1Config), 767 768 p("connect"), 769 {ok, CD} = megaco_config:connect(RH, RemoteMid1, 770 dummy_send_handle, self()), 771 p("connect ok: CD = ~n~p", [CD]), 772 CH = CD#conn_data.conn_handle, 773 774 775 p("*** make the first counter increment ***"), 776 {ok, CD01} = megaco_config:incr_trans_id_counter(CH, 1), 777 Serial01 = CD01#conn_data.serial, 778 p("serial: ~p", [Serial01]), 779 VerifySerial(Serial01, MinTransId), 780 p("counter increment 1 ok"), 781 782 783 p("*** make two more counter increments ***"), 784 {ok, _} = megaco_config:incr_trans_id_counter(CH, 1), 785 {ok, CD02} = megaco_config:incr_trans_id_counter(CH, 1), 786 Serial02 = CD02#conn_data.serial, 787 p("serial: ~p", [Serial02]), 788 VerifySerial(Serial02, MinTransId+2), 789 p("counter increment 2 ok"), 790 791 792 p("*** make a big counter increment ***"), 793 {ok, CD03} = megaco_config:incr_trans_id_counter(CH, 8), 794 Serial03 = CD03#conn_data.serial, 795 p("serial: ~p", [Serial03]), 796 VerifySerial(Serial03, MinTransId+2+8), 797 p("counter increment 3 ok"), 798 799 800 p("*** make a wrap-around counter increment ***"), 801 {ok, CD04} = megaco_config:incr_trans_id_counter(CH, 1), 802 Serial04 = CD04#conn_data.serial, 803 p("serial: ~p", [Serial04]), 804 VerifySerial(Serial04, MinTransId), 805 p("counter increment 4 ok"), 806 807 808 p("*** make a big counter increment ***"), 809 {ok, CD05} = megaco_config:incr_trans_id_counter(CH, 10), 810 Serial05 = CD05#conn_data.serial, 811 p("serial: ~p", [Serial05]), 812 VerifySerial(Serial05, MinTransId+10), 813 p("counter increment 5 ok"), 814 815 816 p("*** make a big wrap-around counter increment ***"), 817 {ok, CD06} = megaco_config:incr_trans_id_counter(CH, 3), 818 Serial06 = CD06#conn_data.serial, 819 p("serial: ~p", [Serial06]), 820 VerifySerial(Serial06, MinTransId+(3-1)), 821 p("counter increment 6 ok"), 822 823 824 p("*** make a big counter increment ***"), 825 {ok, CD07} = megaco_config:incr_trans_id_counter(CH, 7), 826 Serial07 = CD07#conn_data.serial, 827 p("serial: ~p", [Serial07]), 828 VerifySerial(Serial07, MinTransId+(3-1)+7), 829 p("counter increment 7 ok"), 830 831 832 p("*** make a big wrap-around counter increment ***"), 833 {ok, CD08} = megaco_config:incr_trans_id_counter(CH, 5), 834 Serial08 = CD08#conn_data.serial, 835 p("serial: ~p", [Serial08]), 836 VerifySerial(Serial08, MinTransId+(5-1-1)), 837 p("counter increment 8 ok"), 838 839 840 p("disconnect"), 841 {ok, CD, RCD} = megaco_config:disconnect(CH), 842 p("disconnect ok: RCD = ~n~p", [RCD]), 843 844 p("stop user"), 845 ok = megaco_config:stop_user(LocalMid1), 846 847 p("stop megaco config process"), 848 megaco_config:stop(), 849 850 p("done"), 851 ok. 852 853 854%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 855 856otp_8167(suite) -> 857 []; 858otp_8167(Config) when is_list(Config) -> 859 put(tc, otp8167), 860 p("start"), 861 862 p("start the megaco config process"), 863 megaco_config:start_link(), 864 865 LocalMid1 = {deviceName, "local-mid-1"}, 866 LocalMid2 = {deviceName, "local-mid-2"}, 867 RemoteMid1 = {deviceName, "remote-mid-1"}, 868 %% RemoteMid2 = {deviceName, "remote-mid-2"}, 869 RH1 = #megaco_receive_handle{local_mid = LocalMid1, 870 encoding_mod = dummy_codec_module, 871 encoding_config = [], 872 send_mod = dummy_transport_module}, 873%% RH2 = #megaco_receive_handle{local_mid = LocalMid2, 874%% encoding_mod = dummy_codec_module, 875%% encoding_config = [], 876%% send_mod = dummy_transport_module}, 877 878 User1ConfigA = [{call_proxy_gc_timeout, 1}], 879 User1ConfigB = [{call_proxy_gc_timeout, 0}], 880 User2ConfigA = [{call_proxy_gc_timeout, -1}], 881 User2ConfigB = [{call_proxy_gc_timeout, infinity}], 882 User2ConfigC = [{call_proxy_gc_timeout, "1"}], 883 User2ConfigD = [{call_proxy_gc_timeout, 1.0}], 884 885 p("start local user (1A): ~p", [LocalMid1]), 886 ok = megaco_config:start_user(LocalMid1, User1ConfigA), 887 p("stop local user (1A): ~p", [LocalMid1]), 888 ok = megaco_config:stop_user(LocalMid1), 889 890 p("start local user (1B): ~p", [LocalMid1]), 891 ok = megaco_config:start_user(LocalMid1, User1ConfigB), 892 p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", 893 [LocalMid1, -1]), 894 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, -1}} = 895 megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, -1), 896 p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", 897 [LocalMid1, infinity]), 898 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, infinity}} = 899 megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, infinity), 900 p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", 901 [LocalMid1, "1"]), 902 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, "1"}} = 903 megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, "1"), 904 p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", 905 [LocalMid1, 1.0]), 906 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, 1.0}} = 907 megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, 1.0), 908 p("change value for item call_proxy_gc_timeout for local user: ~p", [LocalMid1]), 909 ok = megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, 10101), 910 911 p("connect"), 912 {ok, CD} = megaco_config:connect(RH1, RemoteMid1, 913 dummy_send_handle, self()), 914 p("connect ok: CD = ~n~p", [CD]), 915 CH = CD#conn_data.conn_handle, 916 917 p("get value for item cancel from connection: ~p", [CH]), 918 false = megaco_config:conn_info(CH, cancel), 919 920 p("get value for item cancel from connection data", []), 921 false = megaco_config:conn_info(CD, cancel), 922 923 p("get value for item call_proxy_gc_timeout for connection: ~p", [CH]), 924 10101 = megaco_config:conn_info(CH, call_proxy_gc_timeout), 925 926 p("change value for item call_proxy_gc_timeout for connection: ~p -> ~p", 927 [CH, 20202]), 928 ok = megaco_config:update_conn_info(CH, call_proxy_gc_timeout, 20202), 929 930 p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", 931 [CH, -1]), 932 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, -1}} = 933 megaco_config:update_conn_info(CH, call_proxy_gc_timeout, -1), 934 935 p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", 936 [CH, infinity]), 937 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, infinity}} = 938 megaco_config:update_conn_info(CH, call_proxy_gc_timeout, infinity), 939 940 p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", 941 [CH, "1"]), 942 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, "1"}} = 943 megaco_config:update_conn_info(CH, call_proxy_gc_timeout, "1"), 944 945 p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", 946 [CH, 1.0]), 947 {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, 1.0}} = 948 megaco_config:update_conn_info(CH, call_proxy_gc_timeout, 1.0), 949 950 p("disconnect: ~p", [CH]), 951 {ok, _, _} = megaco_config:disconnect(CH), 952 953 p("stop local user (1B): ~p", [LocalMid1]), 954 ok = megaco_config:stop_user(LocalMid1), 955 956 p("try (and fail) start local user (2A): ~p", [LocalMid2]), 957 {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, -1}} = 958 megaco_config:start_user(LocalMid2, User2ConfigA), 959 960 p("try (and fail) start local user (2B): ~p", [LocalMid2]), 961 {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, infinity}} = 962 megaco_config:start_user(LocalMid2, User2ConfigB), 963 964 p("try (and fail) start local user (2C): ~p", [LocalMid2]), 965 {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, "1"}} = 966 megaco_config:start_user(LocalMid2, User2ConfigC), 967 968 p("try (and fail) start local user (2D): ~p", [LocalMid2]), 969 {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, 1.0}} = 970 megaco_config:start_user(LocalMid2, User2ConfigD), 971 972 p("done"), 973 ok. 974 975 976%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 977 978otp_8183(suite) -> 979 []; 980otp_8183(Config) when is_list(Config) -> 981 put(tc, otp8183), 982 p("start"), 983 984 p("start the megaco config process"), 985 megaco_config:start_link(), 986 987 LocalMid1 = {deviceName, "local-mid-1"}, 988 LocalMid2 = {deviceName, "local-mid-2"}, 989 RemoteMid1 = {deviceName, "remote-mid-1"}, 990%% RemoteMid2 = {deviceName, "remote-mid-2"}, 991 RH1 = #megaco_receive_handle{local_mid = LocalMid1, 992 encoding_mod = dummy_codec_module, 993 encoding_config = [], 994 send_mod = dummy_transport_module}, 995%% RH2 = #megaco_receive_handle{local_mid = LocalMid2, 996%% encoding_mod = dummy_codec_module, 997%% encoding_config = [], 998%% send_mod = dummy_transport_module}, 999 1000 OkValA = 100, 1001 OkValB = 0, 1002 OkValC = plain, 1003 OkValD = 10101, 1004 OkValE = 20202, 1005 BadValA = -1, 1006 BadValB = pain, 1007 BadValC = "1", 1008 BadValD = 1.0, 1009 User1ConfigA = [{request_keep_alive_timeout, OkValA}], 1010 User1ConfigB = [{request_keep_alive_timeout, OkValB}], 1011 User1ConfigC = [{request_keep_alive_timeout, OkValC}], 1012 User2ConfigA = [{request_keep_alive_timeout, BadValA}], 1013 User2ConfigB = [{request_keep_alive_timeout, BadValB}], 1014 User2ConfigC = [{request_keep_alive_timeout, BadValC}], 1015 User2ConfigD = [{request_keep_alive_timeout, BadValD}], 1016 1017 p("start local user (1A): ~p", [LocalMid1]), 1018 ok = megaco_config:start_user(LocalMid1, User1ConfigA), 1019 p("stop local user (1A): ~p", [LocalMid1]), 1020 ok = megaco_config:stop_user(LocalMid1), 1021 1022 p("start local user (1B): ~p", [LocalMid1]), 1023 ok = megaco_config:start_user(LocalMid1, User1ConfigB), 1024 p("stop local user (1B): ~p", [LocalMid1]), 1025 ok = megaco_config:stop_user(LocalMid1), 1026 1027 p("start local user (1C): ~p", [LocalMid1]), 1028 ok = megaco_config:start_user(LocalMid1, User1ConfigC), 1029 1030 p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", 1031 [LocalMid1, BadValA]), 1032 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValA}} = 1033 megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValA), 1034 1035 p("try (and fail) change value for item request_keep_alive_timeout for local user: ~p -> ~p", 1036 [LocalMid1, BadValB]), 1037 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValB}} = 1038 megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValB), 1039 1040 p("try (and fail) change value for item request_keep_alive_timeout for local user: ~p -> ~p", 1041 [LocalMid1, BadValC]), 1042 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValC}} = 1043 megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValC), 1044 1045 p("try (and fail) change value for item request_keep_alive_timeout for local user: ~p -> ~p", 1046 [LocalMid1, BadValD]), 1047 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValD}} = 1048 megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValD), 1049 1050 p("change value for item request_keep_alive_timeout for local user: ~p", [LocalMid1]), 1051 ok = megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, OkValD), 1052 1053 p("connect"), 1054 {ok, CD} = megaco_config:connect(RH1, RemoteMid1, 1055 dummy_send_handle, self()), 1056 p("connect ok: CD = ~n~p", [CD]), 1057 CH = CD#conn_data.conn_handle, 1058 1059 p("get value for item request_keep_alive_timeout for connection: ~p", [CH]), 1060 OkValD = megaco_config:conn_info(CH, request_keep_alive_timeout), 1061 1062 p("change value for item request_keep_alive_timeout for connection: ~p -> ~p", 1063 [CH, OkValE]), 1064 ok = megaco_config:update_conn_info(CH, request_keep_alive_timeout, OkValE), 1065 1066 p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", 1067 [CH, BadValA]), 1068 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValA}} = 1069 megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValA), 1070 1071 p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", 1072 [CH, BadValB]), 1073 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValB}} = 1074 megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValB), 1075 1076 p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", 1077 [CH, BadValC]), 1078 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValC}} = 1079 megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValC), 1080 1081 p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", 1082 [CH, BadValD]), 1083 {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValD}} = 1084 megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValD), 1085 1086 p("disconnect: ~p", [CH]), 1087 {ok, _, _} = megaco_config:disconnect(CH), 1088 1089 p("stop local user (1B): ~p", [LocalMid1]), 1090 ok = megaco_config:stop_user(LocalMid1), 1091 1092 p("try (and fail) start local user (2A): ~p", [LocalMid2]), 1093 {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValA}} = 1094 megaco_config:start_user(LocalMid2, User2ConfigA), 1095 1096 p("try (and fail) start local user (2B): ~p", [LocalMid2]), 1097 {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValB}} = 1098 megaco_config:start_user(LocalMid2, User2ConfigB), 1099 1100 p("try (and fail) start local user (2C): ~p", [LocalMid2]), 1101 {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValC}} = 1102 megaco_config:start_user(LocalMid2, User2ConfigC), 1103 1104 p("try (and fail) start local user (2D): ~p", [LocalMid2]), 1105 {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValD}} = 1106 megaco_config:start_user(LocalMid2, User2ConfigD), 1107 1108 p("done"), 1109 ok. 1110 1111 1112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1113 1114p(F) -> 1115 p(F, []). 1116 1117p(F, A) -> 1118 io:format("[~w] " ++ F ++ "~n", [get(tc)|A]). 1119 1120 1121i(F) -> 1122 i(F, []). 1123 1124i(F, A) -> 1125 print(info, get(verbosity), now(), get(tc), "INF", F, A). 1126 1127printable(_, debug) -> true; 1128printable(info, info) -> true; 1129printable(_,_) -> false. 1130 1131print(Severity, Verbosity, Ts, Tc, P, F, A) -> 1132 print(printable(Severity,Verbosity), Ts, Tc, P, F, A). 1133 1134print(true, Ts, Tc, P, F, A) -> 1135 io:format("*** [~s] ~s ~p ~s:~w ***" 1136 "~n " ++ F ++ "~n", 1137 [format_timestamp(Ts), P, self(), get(sname), Tc | A]); 1138print(_, _, _, _, _, _) -> 1139 ok. 1140 1141format_timestamp({_N1, _N2, N3} = Now) -> 1142 {Date, Time} = calendar:now_to_datetime(Now), 1143 {YYYY,MM,DD} = Date, 1144 {Hour,Min,Sec} = Time, 1145 FormatDate = 1146 io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w", 1147 [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), 1148 lists:flatten(FormatDate). 1149 1150