diff options
Diffstat (limited to 'lib/megaco/test/megaco_config_test.erl')
-rw-r--r-- | lib/megaco/test/megaco_config_test.erl | 1110 |
1 files changed, 1110 insertions, 0 deletions
diff --git a/lib/megaco/test/megaco_config_test.erl b/lib/megaco/test/megaco_config_test.erl new file mode 100644 index 0000000000..453c1b8964 --- /dev/null +++ b/lib/megaco/test/megaco_config_test.erl @@ -0,0 +1,1110 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +%%---------------------------------------------------------------------- +%% Purpose: Test application config +%%---------------------------------------------------------------------- + +-module(megaco_config_test). + +-compile(export_all). + +-include("megaco_test_lib.hrl"). +-include_lib("megaco/include/megaco.hrl"). +-include_lib("megaco/src/app/megaco_internal.hrl"). + +t() -> megaco_test_lib:t(?MODULE). +t(Case) -> megaco_test_lib:t({?MODULE, Case}). + +min(M) -> timer:minutes(M). + +%% Test server callbacks +init_per_testcase(Case, Config) -> + C = lists:keydelete(tc_timeout, 1, Config), + do_init_per_testcase(Case, [{tc_timeout, min(3)}|C]). + +do_init_per_testcase(Case, Config) -> + process_flag(trap_exit, true), + megaco_test_lib:init_per_testcase(Case, Config). + +fin_per_testcase(Case, Config) -> + process_flag(trap_exit, false), + megaco_test_lib:fin_per_testcase(Case, Config). + + +-record(command, {id, desc, cmd, verify}). + +-define(TEST_VERBOSITY, debug). +-define(NUM_CNT_PROCS, 100). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Top test case + +all(suite) -> + [ + config, + transaction_id_counter, + tickets + ]. + +transaction_id_counter(suite) -> + [ + transaction_id_counter_mg, + transaction_id_counter_mgc + ]. + +tickets(suite) -> + [ + otp_7216, + otp_8167, + otp_8183 + ]. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Config test case + +config(suite) -> + []; +config(Config) when is_list(Config) -> + ?ACQUIRE_NODES(1, Config), + Mid = fake_mid, + + %% Nice values + Int = 3, + IT = #megaco_incr_timer{max_retries = Int}, + + %% Evil values + NonInt = non_int, + IT2 = #megaco_incr_timer{wait_for = NonInt}, + IT3 = #megaco_incr_timer{factor = NonInt}, + IT4 = #megaco_incr_timer{max_retries = NonInt}, + IT5 = #megaco_incr_timer{max_retries = non_infinity}, + + %% Command range values + Initial = 100, + Verify = 200, + Nice = 300, + Evil = 400, + End = 500, + + Commands = + [ + %% Initial commands + initial_command( Initial + 0, + "enable trace", + fun() -> megaco:enable_trace(100, io) end, ok), + initial_command( Initial + 1, + "start", + fun() -> megaco:start() end, ok), + initial_command( Initial + 2, + "Verify no active requests", + fun() -> megaco:system_info(n_active_requests) end, + 0), + initial_command( Initial + 3, + "Verify no active replies", + fun() -> megaco:system_info(n_active_replies) end, + 0), + initial_command( Initial + 4, + "Verify no active connections", + fun() -> + megaco:system_info(n_active_connections) + end, + 0), + initial_command( Initial + 5, + "Verify no connections", + fun() -> megaco:system_info(connections) end, []), + initial_command( Initial + 6, + "Verify no users", + fun() -> megaco:system_info(users) end, []), + initial_command( Initial + 7, + "Start user", + fun() -> megaco:start_user(Mid, []) end, ok), + + + %% Verify user defaults + verify_user_default_command(Mid, Verify + 1, connections, []), + verify_user_default_command(Mid, Verify + 2, min_trans_id, 1), + verify_user_default_command(Mid, Verify + 3, max_trans_id, infinity), + verify_user_default_command(Mid, Verify + 4, request_timer, + #megaco_incr_timer{}), + verify_user_default_command(Mid, Verify + 5, long_request_timer, timer:seconds(60)), + verify_user_default_command(Mid, Verify + 6, auto_ack, false), + verify_user_default_command(Mid, Verify + 7, pending_timer, 30000), + verify_user_default_command(Mid, Verify + 8, reply_timer, 30000), + verify_user_default_command(Mid, Verify + 9, send_mod, megaco_tcp), + verify_user_default_command(Mid, Verify + 10, encoding_mod, + megaco_pretty_text_encoder), + verify_user_default_command(Mid, Verify + 11, encoding_config, []), + verify_user_default_command(Mid, Verify + 12, protocol_version, 1), + verify_user_default_command(Mid, Verify + 13, reply_data, undefined), + verify_user_default_command(Mid, Verify + 14, receive_handle, + fun(H) when is_record(H, megaco_receive_handle) -> {ok, H}; + (R) -> {error, R} + end), + + + %% Nice update + nice_user_update_command(Mid, Nice + 1, min_trans_id, Int), + nice_user_update_command(Mid, Nice + 2, max_trans_id, Int), + nice_user_update_command(Mid, Nice + 3, max_trans_id, infinity), + nice_user_update_command(Mid, Nice + 4, request_timer, Int), + nice_user_update_command(Mid, Nice + 5, request_timer, infinity), + nice_user_update_command(Mid, Nice + 6, request_timer, IT), + nice_user_update_command(Mid, Nice + 7, long_request_timer, Int), + nice_user_update_command(Mid, Nice + 8, long_request_timer, infinity), + nice_user_update_command(Mid, Nice + 9, long_request_timer, IT), + nice_user_update_command(Mid, Nice + 10, auto_ack, true), + nice_user_update_command(Mid, Nice + 11, auto_ack, false), + nice_user_update_command(Mid, Nice + 12, pending_timer, Int), + nice_user_update_command(Mid, Nice + 13, pending_timer, infinity), + nice_user_update_command(Mid, Nice + 14, pending_timer, IT), + nice_user_update_command(Mid, Nice + 15, reply_timer, Int), + nice_user_update_command(Mid, Nice + 16, reply_timer, infinity), + nice_user_update_command(Mid, Nice + 17, reply_timer, IT), + nice_user_update_command(Mid, Nice + 18, send_mod, an_atom), + nice_user_update_command(Mid, Nice + 19, encoding_mod, an_atom), + nice_user_update_command(Mid, Nice + 20, encoding_config, []), + nice_user_update_command(Mid, Nice + 21, protocol_version, Int), + nice_user_update_command(Mid, Nice + 23, reply_data, IT), + nice_user_update_command(Mid, Nice + 23, resend_indication, true), + nice_user_update_command(Mid, Nice + 24, resend_indication, false), + nice_user_update_command(Mid, Nice + 25, resend_indication, flag), + + + %% Evil update + evil_user_update_command(Mid, Evil + 1, min_trans_id, NonInt), + evil_user_update_command(Mid, Evil + 2, max_trans_id, NonInt), + evil_user_update_command(Mid, Evil + 3, max_trans_id, non_infinity), + evil_user_update_command(Mid, Evil + 4, request_timer, NonInt), + evil_user_update_command(Mid, Evil + 5, request_timer, non_infinity), + evil_user_update_command(Mid, Evil + 6, request_timer, IT2), + evil_user_update_command(Mid, Evil + 7, request_timer, IT3), + evil_user_update_command(Mid, Evil + 8, request_timer, IT4), + evil_user_update_command(Mid, Evil + 9, request_timer, IT5), + evil_user_update_command(Mid, Evil + 10, long_request_timer, NonInt), + evil_user_update_command(Mid, Evil + 11, long_request_timer, non_infinity), + evil_user_update_command(Mid, Evil + 12, long_request_timer, IT2), + evil_user_update_command(Mid, Evil + 13, long_request_timer, IT3), + evil_user_update_command(Mid, Evil + 14, long_request_timer, IT4), + evil_user_update_command(Mid, Evil + 15, long_request_timer, IT5), + evil_user_update_command(Mid, Evil + 16, auto_ack, non_bool), + evil_user_update_command(Mid, Evil + 17, pending_timer, NonInt), + evil_user_update_command(Mid, Evil + 18, pending_timer, non_infinity), + evil_user_update_command(Mid, Evil + 19, pending_timer, IT2), + evil_user_update_command(Mid, Evil + 20, pending_timer, IT3), + evil_user_update_command(Mid, Evil + 21, pending_timer, IT4), + evil_user_update_command(Mid, Evil + 22, pending_timer, IT5), + evil_user_update_command(Mid, Evil + 23, reply_timer, NonInt), + evil_user_update_command(Mid, Evil + 24, reply_timer, non_infinity), + evil_user_update_command(Mid, Evil + 25, reply_timer, IT2), + evil_user_update_command(Mid, Evil + 26, reply_timer, IT3), + evil_user_update_command(Mid, Evil + 27, reply_timer, IT4), + evil_user_update_command(Mid, Evil + 28, reply_timer, IT5), + evil_user_update_command(Mid, Evil + 29, send_mod, {non_atom}), + evil_user_update_command(Mid, Evil + 30, encoding_mod, {non_atom}), + evil_user_update_command(Mid, Evil + 31, encoding_config, non_list), + evil_user_update_command(Mid, Evil + 32, protocol_version, NonInt), + evil_user_update_command(Mid, Evil + 33, resend_indication, flagg), + + + exit_command(End + 1, + "Verify non-existing system info", + fun() -> megaco:system_info(non_exist) end), + exit_command(End + 2, + "Verify non-existing user user info", + fun() -> megaco:user_info(non_exist, trans_id) end), + exit_command(End + 3, "Verify non-existing user info", + fun() -> megaco:user_info(Mid, non_exist) end), + + error_command(End + 4, + "Try updating user info for non-existing user", + fun() -> + megaco:update_user_info(non_exist, trans_id, 1) + end, + no_such_user, 2), + error_command(End + 11, + "Try updating non-existing user info", + fun() -> + megaco:update_user_info(Mid, trans_id, 4711) + end, + bad_user_val, 4), + error_command(End + 12, + "Try start already started user", + fun() -> + megaco:start_user(Mid, []) + end, + user_already_exists, 2), + + command(End + 13, "Verify started users", + fun() -> megaco:system_info(users) end, [Mid]), + command(End + 14, "Stop user", fun() -> megaco:stop_user(Mid) end, ok), + command(End + 15, "Verify started users", + fun() -> megaco:system_info(users) end, []), + error_command(End + 16, "Try stop not started user", + fun() -> megaco:stop_user(Mid) end, no_such_user, 2), + error_command(End + 17, "Try start megaco (it's already started)", + fun() -> megaco:start() end, already_started, 2), + command(End + 18, "Stop megaco", fun() -> megaco:stop() end, ok), + error_command(End + 19, "Try stop megaco (it's not running)", + fun() -> megaco:stop() end, not_started, 2) + ], + + + exec(Commands). + + + +exec([]) -> + ok; +exec([#command{id = No, + desc = Desc, + cmd = Cmd, + verify = Verify}|Commands]) -> + io:format("Executing command ~2w: ~s: ", [No, Desc]), + case (catch Verify((catch Cmd()))) of + {ok, OK} -> + io:format("ok => ~p~n", [OK]), + exec(Commands); + {error, Reason} -> + io:format("error => ~p~n", [Reason]), + {error, {bad_result, No, Reason}}; + Error -> + io:format("exit => ~p~n", [Error]), + {error, {unexpected_result, No, Error}} + end. + +initial_command(No, Desc0, Cmd, VerifyVal) when is_function(Cmd) -> + Desc = lists:flatten(io_lib:format("Initial - ~s", [Desc0])), + command(No, Desc, Cmd, VerifyVal). + +verify_user_default_command(Mid, No, Key, Verify) -> + Desc = lists:flatten(io_lib:format("Defaults - Verify ~w", [Key])), + Cmd = fun() -> megaco:user_info(Mid, Key) end, + command(No, Desc, Cmd, Verify). + +nice_user_update_command(Mid, No, Key, Val) -> + Desc = lists:flatten(io_lib:format("Nice - Update ~w", [Key])), + Cmd = fun() -> megaco:update_user_info(Mid, Key, Val) end, + Verify = fun(ok) -> + case (catch megaco:user_info(Mid, Key)) of + {'EXIT', R} -> + {error, {value_retreival_failed, R}}; + Val -> + {ok, Val}; + Invalid -> + {error, {value_update_failed, Val, Invalid}} + end; + (R) -> + {error, R} + end, + command(No, Desc, Cmd, Verify). + + +evil_user_update_command(Mid, No, Key, Val) -> + Desc = lists:flatten(io_lib:format("Evil: Update ~w", [Key])), + Cmd = fun() -> + case (catch megaco:user_info(Mid, Key)) of + {'EXIT', R} -> + {{error, {old_value_retreival_failed, R}}, + ignore}; + OldVal -> + {OldVal, + (catch megaco:update_user_info(Mid, Key, Val))} + end + end, + Verify = fun({{error, _} = Error, ignore}) -> + Error; + ({OldVal, {error, {bad_user_val, _, _, _}}}) -> + case (catch megaco:user_info(Mid, Key)) of + {'EXIT', R} -> + {error, {value_retreival_failed, R}}; + OldVal -> + {ok, OldVal}; + Invalid -> + {error, {value_update_failed, OldVal, Invalid}} + end; + (R) -> + {error, R} + end, + command(No, Desc, Cmd, Verify). + +exit_command(No, Desc, Cmd) when is_function(Cmd) -> + Verify = fun({'EXIT', _} = E) -> + {ok, E}; + (R) -> + {error, R} + end, + command(No, Desc, Cmd, Verify). + +error_command(No, Desc, Cmd, MainReason, TS) when is_function(Cmd) -> + Verify = fun({error, Reason}) -> + io:format("verify -> Reason: ~n~p~n", [Reason]), + case Reason of + {MainReason, _} when TS == 2 -> + {ok, MainReason}; + {MainReason, _, _, _} when TS == 4 -> + {ok, MainReason}; + _ -> + {error, Reason} + end; + (R) -> + {error, R} + end, + command(No, Desc, Cmd, Verify). + +command(No, Desc, Cmd, Verify) when is_integer(No) and is_list(Desc) and + is_function(Cmd) and is_function(Verify) -> + #command{id = No, + desc = Desc, + cmd = Cmd, + verify = Verify}; +command(No, Desc, Cmd, VerifyVal) when is_integer(No) and is_list(Desc) and + is_function(Cmd) -> + Verify = fun(Val) -> + case Val of + VerifyVal -> + {ok, Val}; + _ -> + {error, Val} + end + end, + #command{id = No, + desc = Desc, + cmd = Cmd, + verify = Verify}. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +transaction_id_counter_mg(suite) -> + []; +transaction_id_counter_mg(doc) -> + ["This test case is intended to test and verify the " + "transaction counter handling of the application " + "in with one connection (MG). "]; +transaction_id_counter_mg(Config) when is_list(Config) -> + put(verbosity, ?TEST_VERBOSITY), + put(sname, "TEST"), + put(tc, transaction_id_counter_mg), + + process_flag(trap_exit, true), + + i("starting"), + + {ok, _ConfigPid} = megaco_config:start_link(), + + %% Basic user data + UserMid = {deviceName, "mg"}, + UserConfig = [ + {min_trans_id, 1} + ], + + %% Basic connection data + RemoteMid = {deviceName, "mgc"}, + RecvHandle = #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE}, + SendHandle = dummy_send_handle, + ControlPid = self(), + + %% Start user + i("start user"), + ok = megaco_config:start_user(UserMid, UserConfig), + + %% Create connection + i("create connection"), + {ok, CD} = + megaco_config:connect(RecvHandle, RemoteMid, SendHandle, ControlPid), + + %% Set counter limits + i("set counter max limit"), + CH = CD#conn_data.conn_handle, + megaco_config:update_conn_info(CH, max_trans_id, 1000), + + %% Create the counter worker procs + i("create counter working procs"), + Pids = create_counter_working_procs(CH, ?NUM_CNT_PROCS, []), + + %% Start the counter worker procs + i("release the counter working procs"), + start_counter_working_procs(Pids), + + %% Await the counter worker procs termination + i("await the counter working procs completion"), + await_completion_counter_working_procs(Pids), + + %% Verify result + i("verify counter result"), + TransId = megaco_config:conn_info(CH, trans_id), + 1 = TransId, + + %% Stop test + i("disconnect"), + {ok, _, _} = megaco_config:disconnect(CH), + i("stop user"), + ok = megaco_config:stop_user(UserMid), + i("stop megaco_config"), + ok = megaco_config:stop(), + + i("done"), + ok. + + + +create_counter_working_procs(_CH, 0, Pids) -> + Pids; +create_counter_working_procs(CH, N, Pids) -> + TC = get(tc), + Pid = erlang:spawn_link(fun() -> counter_init(CH, TC) end), + create_counter_working_procs(CH, N-1, [Pid | Pids]). + +counter_init(CH, TC) -> + put(verbosity, ?TEST_VERBOSITY), + put(sname, lists:flatten(io_lib:format("CNT-~p", [self()]))), + put(tc, TC), + UserMid = CH#megaco_conn_handle.local_mid, + Min = megaco_config:user_info(UserMid, min_trans_id), + Max = megaco_config:conn_info(CH, max_trans_id), + Num = Max - Min + 1, + receive + start -> + %% i("received start command (~p)", [Num]), + ok + end, + counter_loop(CH, Num). + +counter_loop(_CH, 0) -> + %% i("done"), + exit(normal); +counter_loop(CH, Num) when (Num > 0) -> + megaco_config:incr_trans_id_counter(CH, 1), + counter_loop(CH, Num-1). + +start_counter_working_procs([]) -> + %% i("released"), + ok; +start_counter_working_procs([Pid | Pids]) -> + Pid ! start, + start_counter_working_procs(Pids). + +await_completion_counter_working_procs([]) -> + ok; +await_completion_counter_working_procs(Pids) -> + receive + {'EXIT', Pid, normal} -> + Pids2 = lists:delete(Pid, Pids), + await_completion_counter_working_procs(Pids2); + _Any -> + await_completion_counter_working_procs(Pids) + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +transaction_id_counter_mgc(suite) -> + []; +transaction_id_counter_mgc(doc) -> + ["This test case is intended to test and verify the " + "transaction counter handling of the application " + "in with several connections (MGC). "]; +transaction_id_counter_mgc(Config) when is_list(Config) -> + put(verbosity, ?TEST_VERBOSITY), + put(sname, "TEST"), + put(tc, transaction_id_counter_mgc), + process_flag(trap_exit, true), + + i("starting"), + + {ok, _ConfigPid} = megaco_config:start_link(), + + %% Basic user data + UserMid = {deviceName, "mgc"}, + UserConfig = [ + {min_trans_id, 1} + ], + + %% Basic connection data + RemoteMids = + [ + {deviceName, "mg01"}, + {deviceName, "mg02"}, + {deviceName, "mg03"}, + {deviceName, "mg04"}, + {deviceName, "mg05"}, + {deviceName, "mg06"}, + {deviceName, "mg07"}, + {deviceName, "mg08"}, + {deviceName, "mg09"}, + {deviceName, "mg10"} + ], + RecvHandles = + [ + #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE}, + #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE}, + #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE}, + #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE}, + #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE}, + #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE}, + #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE}, + #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE}, + #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE}, + #megaco_receive_handle{local_mid = UserMid, + encoding_mod = ?MODULE, + encoding_config = [], + send_mod = ?MODULE} + ], + SendHandle = dummy_send_handle, + ControlPid = self(), + + %% Start user + i("start user"), + ok = megaco_config:start_user(UserMid, UserConfig), + + %% Create connection + i("create connection(s)"), + CDs = create_connections(RecvHandles, RemoteMids, SendHandle, ControlPid), + + %% Set counter limits + i("set counter max limit(s)"), + set_counter_max_limits(CDs, 1000), + + %% Create the counter worker procs + i("create counter working procs"), + Pids = create_counter_working_procs(CDs, ?NUM_CNT_PROCS), + + %% Start the counter worker procs + i("release the counter working procs"), + start_counter_working_procs(Pids), + + %% Await the counter worker procs termination + i("await the counter working procs completion"), + await_completion_counter_working_procs(Pids), + + %% Verify result + i("verify counter result"), + verify_counter_results(CDs), + + %% Stop test + i("disconnect"), + delete_connections(CDs), + i("stop user"), + ok = megaco_config:stop_user(UserMid), + i("stop megaco_config"), + ok = megaco_config:stop(), + + i("done"), + ok. + +create_connections(RecvHandles, RemoteMids, SendHandle, ControlPid) -> + create_connections(RecvHandles, RemoteMids, SendHandle, ControlPid, []). + +create_connections([], [], _SendHandle, _ControlPid, Acc) -> + lists:reverse(Acc); +create_connections([RecvHandle | RecvHandles], + [RemoteMid | RemoteMids], + SendHandle, ControlPid, Acc) -> + {ok, CD} = + megaco_config:connect(RecvHandle, RemoteMid, SendHandle, ControlPid), + create_connections(RecvHandles, RemoteMids, + SendHandle, ControlPid, [CD | Acc]). + + +set_counter_max_limits([], _MaxTransId) -> + ok; +set_counter_max_limits([#conn_data{conn_handle = CH} | CDs], MaxTransId) -> + megaco_config:update_conn_info(CH, max_trans_id, MaxTransId), + set_counter_max_limits(CDs, MaxTransId). + + +create_counter_working_procs(CDs, NumCntProcs) -> + lists:flatten(create_counter_working_procs2(CDs, NumCntProcs)). + +create_counter_working_procs2([], _NumCntProcs) -> + []; +create_counter_working_procs2([#conn_data{conn_handle = CH} | CDs], + NumCntProcs) -> + [create_counter_working_procs(CH, NumCntProcs, []) | + create_counter_working_procs2(CDs, NumCntProcs)]. + + +verify_counter_results([]) -> + ok; +verify_counter_results([#conn_data{conn_handle = CH} | CDs]) -> + TransId = megaco_config:conn_info(CH, trans_id), + if + (TransId =:= 1) -> + ok; + true -> + ?ERROR({trans_id_verification_failed, CH, TransId}) + end, + verify_counter_results(CDs). + + +delete_connections([]) -> + ok; +delete_connections([#conn_data{conn_handle = CH} | CDs]) -> + {ok, _, _} = megaco_config:disconnect(CH), + delete_connections(CDs). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +otp_7216(suite) -> + []; +otp_7216(Config) when is_list(Config) -> + put(tc, otp_7216), + p("start"), + + p("start the megaco config process"), + megaco_config:start_link(), + + LocalMid1 = {deviceName, "local-mid-1"}, + %% LocalMid2 = {deviceName, "local-mid-2"}, + RemoteMid1 = {deviceName, "remote-mid-1"}, + %% RemoteMid2 = {deviceName, "remote-mid-2"}, + RH = #megaco_receive_handle{local_mid = LocalMid1, + encoding_mod = dummy_codec_module, + encoding_config = [], + send_mod = dummy_transport_module}, + MinTransId = 7216, + MaxTransId = MinTransId + 10, + User1Config = [{min_trans_id, MinTransId}, + {max_trans_id, MaxTransId}], + + VerifySerial = + fun(Actual, Expected) -> + if + Actual == Expected -> + ok; + true -> + throw({error, {invalid_counter_value, Actual}}) + end + end, + + p("start local user: ~p", [LocalMid1]), + ok = megaco_config:start_user(LocalMid1, User1Config), + + p("connect"), + {ok, CD} = megaco_config:connect(RH, RemoteMid1, + dummy_send_handle, self()), + p("connect ok: CD = ~n~p", [CD]), + CH = CD#conn_data.conn_handle, + + + p("*** make the first counter increment ***"), + {ok, CD01} = megaco_config:incr_trans_id_counter(CH, 1), + Serial01 = CD01#conn_data.serial, + p("serial: ~p", [Serial01]), + VerifySerial(Serial01, MinTransId), + p("counter increment 1 ok"), + + + p("*** make two more counter increments ***"), + {ok, _} = megaco_config:incr_trans_id_counter(CH, 1), + {ok, CD02} = megaco_config:incr_trans_id_counter(CH, 1), + Serial02 = CD02#conn_data.serial, + p("serial: ~p", [Serial02]), + VerifySerial(Serial02, MinTransId+2), + p("counter increment 2 ok"), + + + p("*** make a big counter increment ***"), + {ok, CD03} = megaco_config:incr_trans_id_counter(CH, 8), + Serial03 = CD03#conn_data.serial, + p("serial: ~p", [Serial03]), + VerifySerial(Serial03, MinTransId+2+8), + p("counter increment 3 ok"), + + + p("*** make a wrap-around counter increment ***"), + {ok, CD04} = megaco_config:incr_trans_id_counter(CH, 1), + Serial04 = CD04#conn_data.serial, + p("serial: ~p", [Serial04]), + VerifySerial(Serial04, MinTransId), + p("counter increment 4 ok"), + + + p("*** make a big counter increment ***"), + {ok, CD05} = megaco_config:incr_trans_id_counter(CH, 10), + Serial05 = CD05#conn_data.serial, + p("serial: ~p", [Serial05]), + VerifySerial(Serial05, MinTransId+10), + p("counter increment 5 ok"), + + + p("*** make a big wrap-around counter increment ***"), + {ok, CD06} = megaco_config:incr_trans_id_counter(CH, 3), + Serial06 = CD06#conn_data.serial, + p("serial: ~p", [Serial06]), + VerifySerial(Serial06, MinTransId+(3-1)), + p("counter increment 6 ok"), + + + p("*** make a big counter increment ***"), + {ok, CD07} = megaco_config:incr_trans_id_counter(CH, 7), + Serial07 = CD07#conn_data.serial, + p("serial: ~p", [Serial07]), + VerifySerial(Serial07, MinTransId+(3-1)+7), + p("counter increment 7 ok"), + + + p("*** make a big wrap-around counter increment ***"), + {ok, CD08} = megaco_config:incr_trans_id_counter(CH, 5), + Serial08 = CD08#conn_data.serial, + p("serial: ~p", [Serial08]), + VerifySerial(Serial08, MinTransId+(5-1-1)), + p("counter increment 8 ok"), + + + p("disconnect"), + {ok, CD, RCD} = megaco_config:disconnect(CH), + p("disconnect ok: RCD = ~n~p", [RCD]), + + p("stop user"), + ok = megaco_config:stop_user(LocalMid1), + + p("stop megaco config process"), + megaco_config:stop(), + + p("done"), + ok. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +otp_8167(suite) -> + []; +otp_8167(Config) when is_list(Config) -> + put(tc, otp8167), + p("start"), + + p("start the megaco config process"), + megaco_config:start_link(), + + LocalMid1 = {deviceName, "local-mid-1"}, + LocalMid2 = {deviceName, "local-mid-2"}, + RemoteMid1 = {deviceName, "remote-mid-1"}, + %% RemoteMid2 = {deviceName, "remote-mid-2"}, + RH1 = #megaco_receive_handle{local_mid = LocalMid1, + encoding_mod = dummy_codec_module, + encoding_config = [], + send_mod = dummy_transport_module}, +%% RH2 = #megaco_receive_handle{local_mid = LocalMid2, +%% encoding_mod = dummy_codec_module, +%% encoding_config = [], +%% send_mod = dummy_transport_module}, + + User1ConfigA = [{call_proxy_gc_timeout, 1}], + User1ConfigB = [{call_proxy_gc_timeout, 0}], + User2ConfigA = [{call_proxy_gc_timeout, -1}], + User2ConfigB = [{call_proxy_gc_timeout, infinity}], + User2ConfigC = [{call_proxy_gc_timeout, "1"}], + User2ConfigD = [{call_proxy_gc_timeout, 1.0}], + + p("start local user (1A): ~p", [LocalMid1]), + ok = megaco_config:start_user(LocalMid1, User1ConfigA), + p("stop local user (1A): ~p", [LocalMid1]), + ok = megaco_config:stop_user(LocalMid1), + + p("start local user (1B): ~p", [LocalMid1]), + ok = megaco_config:start_user(LocalMid1, User1ConfigB), + p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", + [LocalMid1, -1]), + {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, -1}} = + megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, -1), + p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", + [LocalMid1, infinity]), + {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, infinity}} = + megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, infinity), + p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", + [LocalMid1, "1"]), + {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, "1"}} = + megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, "1"), + p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", + [LocalMid1, 1.0]), + {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, 1.0}} = + megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, 1.0), + p("change value for item call_proxy_gc_timeout for local user: ~p", [LocalMid1]), + ok = megaco_config:update_user_info(LocalMid1, call_proxy_gc_timeout, 10101), + + p("connect"), + {ok, CD} = megaco_config:connect(RH1, RemoteMid1, + dummy_send_handle, self()), + p("connect ok: CD = ~n~p", [CD]), + CH = CD#conn_data.conn_handle, + + p("get value for item call_proxy_gc_timeout for connection: ~p", [CH]), + 10101 = megaco_config:conn_info(CH, call_proxy_gc_timeout), + + p("change value for item call_proxy_gc_timeout for connection: ~p -> ~p", + [CH, 20202]), + ok = megaco_config:update_conn_info(CH, call_proxy_gc_timeout, 20202), + + p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", + [CH, -1]), + {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, -1}} = + megaco_config:update_conn_info(CH, call_proxy_gc_timeout, -1), + + p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", + [CH, infinity]), + {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, infinity}} = + megaco_config:update_conn_info(CH, call_proxy_gc_timeout, infinity), + + p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", + [CH, "1"]), + {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, "1"}} = + megaco_config:update_conn_info(CH, call_proxy_gc_timeout, "1"), + + p("try (and fail) change value for item call_proxy_gc_timeout for connection: ~p -> ~p", + [CH, 1.0]), + {error, {bad_user_val, LocalMid1, call_proxy_gc_timeout, 1.0}} = + megaco_config:update_conn_info(CH, call_proxy_gc_timeout, 1.0), + + p("disconnect: ~p", [CH]), + {ok, _, _} = megaco_config:disconnect(CH), + + p("stop local user (1B): ~p", [LocalMid1]), + ok = megaco_config:stop_user(LocalMid1), + + p("try (and fail) start local user (2A): ~p", [LocalMid2]), + {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, -1}} = + megaco_config:start_user(LocalMid2, User2ConfigA), + + p("try (and fail) start local user (2B): ~p", [LocalMid2]), + {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, infinity}} = + megaco_config:start_user(LocalMid2, User2ConfigB), + + p("try (and fail) start local user (2C): ~p", [LocalMid2]), + {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, "1"}} = + megaco_config:start_user(LocalMid2, User2ConfigC), + + p("try (and fail) start local user (2D): ~p", [LocalMid2]), + {error, {bad_user_val, LocalMid2, call_proxy_gc_timeout, 1.0}} = + megaco_config:start_user(LocalMid2, User2ConfigD), + + p("done"), + ok. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +otp_8183(suite) -> + []; +otp_8183(Config) when is_list(Config) -> + put(tc, otp8183), + p("start"), + + p("start the megaco config process"), + megaco_config:start_link(), + + LocalMid1 = {deviceName, "local-mid-1"}, + LocalMid2 = {deviceName, "local-mid-2"}, + RemoteMid1 = {deviceName, "remote-mid-1"}, +%% RemoteMid2 = {deviceName, "remote-mid-2"}, + RH1 = #megaco_receive_handle{local_mid = LocalMid1, + encoding_mod = dummy_codec_module, + encoding_config = [], + send_mod = dummy_transport_module}, +%% RH2 = #megaco_receive_handle{local_mid = LocalMid2, +%% encoding_mod = dummy_codec_module, +%% encoding_config = [], +%% send_mod = dummy_transport_module}, + + OkValA = 100, + OkValB = 0, + OkValC = plain, + OkValD = 10101, + OkValE = 20202, + BadValA = -1, + BadValB = pain, + BadValC = "1", + BadValD = 1.0, + User1ConfigA = [{request_keep_alive_timeout, OkValA}], + User1ConfigB = [{request_keep_alive_timeout, OkValB}], + User1ConfigC = [{request_keep_alive_timeout, OkValC}], + User2ConfigA = [{request_keep_alive_timeout, BadValA}], + User2ConfigB = [{request_keep_alive_timeout, BadValB}], + User2ConfigC = [{request_keep_alive_timeout, BadValC}], + User2ConfigD = [{request_keep_alive_timeout, BadValD}], + + p("start local user (1A): ~p", [LocalMid1]), + ok = megaco_config:start_user(LocalMid1, User1ConfigA), + p("stop local user (1A): ~p", [LocalMid1]), + ok = megaco_config:stop_user(LocalMid1), + + p("start local user (1B): ~p", [LocalMid1]), + ok = megaco_config:start_user(LocalMid1, User1ConfigB), + p("stop local user (1B): ~p", [LocalMid1]), + ok = megaco_config:stop_user(LocalMid1), + + p("start local user (1C): ~p", [LocalMid1]), + ok = megaco_config:start_user(LocalMid1, User1ConfigC), + + p("try (and fail) change value for item call_proxy_gc_timeout for local user: ~p -> ~p", + [LocalMid1, BadValA]), + {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValA}} = + megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValA), + + p("try (and fail) change value for item request_keep_alive_timeout for local user: ~p -> ~p", + [LocalMid1, BadValB]), + {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValB}} = + megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValB), + + p("try (and fail) change value for item request_keep_alive_timeout for local user: ~p -> ~p", + [LocalMid1, BadValC]), + {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValC}} = + megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValC), + + p("try (and fail) change value for item request_keep_alive_timeout for local user: ~p -> ~p", + [LocalMid1, BadValD]), + {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValD}} = + megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, BadValD), + + p("change value for item request_keep_alive_timeout for local user: ~p", [LocalMid1]), + ok = megaco_config:update_user_info(LocalMid1, request_keep_alive_timeout, OkValD), + + p("connect"), + {ok, CD} = megaco_config:connect(RH1, RemoteMid1, + dummy_send_handle, self()), + p("connect ok: CD = ~n~p", [CD]), + CH = CD#conn_data.conn_handle, + + p("get value for item request_keep_alive_timeout for connection: ~p", [CH]), + OkValD = megaco_config:conn_info(CH, request_keep_alive_timeout), + + p("change value for item request_keep_alive_timeout for connection: ~p -> ~p", + [CH, OkValE]), + ok = megaco_config:update_conn_info(CH, request_keep_alive_timeout, OkValE), + + p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", + [CH, BadValA]), + {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValA}} = + megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValA), + + p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", + [CH, BadValB]), + {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValB}} = + megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValB), + + p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", + [CH, BadValC]), + {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValC}} = + megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValC), + + p("try (and fail) change value for item request_keep_alive_timeout for connection: ~p -> ~p", + [CH, BadValD]), + {error, {bad_user_val, LocalMid1, request_keep_alive_timeout, BadValD}} = + megaco_config:update_conn_info(CH, request_keep_alive_timeout, BadValD), + + p("disconnect: ~p", [CH]), + {ok, _, _} = megaco_config:disconnect(CH), + + p("stop local user (1B): ~p", [LocalMid1]), + ok = megaco_config:stop_user(LocalMid1), + + p("try (and fail) start local user (2A): ~p", [LocalMid2]), + {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValA}} = + megaco_config:start_user(LocalMid2, User2ConfigA), + + p("try (and fail) start local user (2B): ~p", [LocalMid2]), + {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValB}} = + megaco_config:start_user(LocalMid2, User2ConfigB), + + p("try (and fail) start local user (2C): ~p", [LocalMid2]), + {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValC}} = + megaco_config:start_user(LocalMid2, User2ConfigC), + + p("try (and fail) start local user (2D): ~p", [LocalMid2]), + {error, {bad_user_val, LocalMid2, request_keep_alive_timeout, BadValD}} = + megaco_config:start_user(LocalMid2, User2ConfigD), + + p("done"), + ok. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +p(F) -> + p(F, []). + +p(F, A) -> + io:format("[~w] " ++ F ++ "~n", [get(tc)|A]). + + +i(F) -> + i(F, []). + +i(F, A) -> + print(info, get(verbosity), now(), get(tc), "INF", F, A). + +printable(_, debug) -> true; +printable(info, info) -> true; +printable(_,_) -> false. + +print(Severity, Verbosity, Ts, Tc, P, F, A) -> + print(printable(Severity,Verbosity), Ts, Tc, P, F, A). + +print(true, Ts, Tc, P, F, A) -> + io:format("*** [~s] ~s ~p ~s:~w ***" + "~n " ++ F ++ "~n", + [format_timestamp(Ts), P, self(), get(sname), Tc | A]); +print(_, _, _, _, _, _) -> + ok. + +format_timestamp({_N1, _N2, N3} = Now) -> + {Date, Time} = calendar:now_to_datetime(Now), + {YYYY,MM,DD} = Date, + {Hour,Min,Sec} = Time, + FormatDate = + io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w", + [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), + lists:flatten(FormatDate). + |