📄 megaco_mib_test.erl
字号:
Gen = traffic_verify_get_stats(gen, Stats), Trans = traffic_verify_get_stats(trans, Stats), traffic_verify_mg_stats_gen(Name, Gen), traffic_verify_mg_stats_trans(Name, Trans, Out, In), traffic_verify_mg_stats1(MgStats, Out, In).traffic_verify_mg_stats_gen(Mg, []) -> d("traffic_verify_mg_stats_gen -> ~s checked out OK",[Mg]), ok;traffic_verify_mg_stats_gen(Mg, [{medGwyGatewayNumErrors, 0}|Stats]) -> traffic_verify_mg_stats_gen(Mg, Stats);traffic_verify_mg_stats_gen(Mg, [{medGwyGatewayNumErrors, Val}|_]) -> exit({global_error_counter, Val, Mg});traffic_verify_mg_stats_gen(Mg, [{_Handle, Counters}|Stats]) -> traffic_verify_counter(Mg, medGwyGatewayNumErrors, Counters, 0), traffic_verify_mg_stats_gen(Mg, Stats).traffic_verify_mg_stats_trans(Mg, Counters, Out, In) -> traffic_verify_counter(Mg, medGwyGatewayNumErrors, Counters, 0), traffic_verify_counter(Mg, medGwyGatewayNumOutMessages, Counters, Out), traffic_verify_counter(Mg, medGwyGatewayNumInMessages, Counters, In).traffic_verify_get_stats(S, Stats) -> case lists:keysearch(S, 1, Stats) of {value, {S, Val}} -> Val; false -> exit({not_found, S, Stats}) end. traffic_verify_counter(Name, Counter, Counters, Expected) -> case lists:keysearch(Counter, 1, Counters) of {value, {Counter, Expected}} -> ok; {value, {Counter, Val}} -> exit({illegal_counter_value, Counter, Val, Expected, Name}); false -> exit({not_found, Counter, Counters, Name, Expected}) end. traffic_connect_mg([], Acc) -> lists:reverse(Acc);traffic_connect_mg([{Node, Name, Coding, Trans}|Mg], Acc) -> Pid = traffic_connect_mg(Node, Name, Coding, Trans), traffic_connect_mg(Mg, [{Name, Pid}|Acc]).traffic_connect_mg(Node, Name, Coding, Trans) -> Mid = {deviceName, Name}, {ok, Pid} = start_mg(Node, Mid, Coding, Trans, ?MG_VERBOSITY), %% Ask the MGs to do a service change {ok, Res} = service_change(Pid), d("traffic_connect_mg -> (~s) service change result: ~p", [Name,Res]), Pid.traffic_stop_mg(MGs) -> [stop(Pid) || {_Name, Pid} <- MGs].traffic_get_mg_stats([], Acc) -> lists:reverse(Acc);traffic_get_mg_stats([{Name, Pid}|Mgs], Acc) -> {ok, Stats} = get_stats(Pid, 1), d("traffic_get_mg_stats -> stats for ~s: ~n~p~n", [Name, Stats]), traffic_get_mg_stats(Mgs, [{Name, Stats}|Acc]).traffic_apply_load([]) -> ok;traffic_apply_load([{_,MG}|MGs]) -> MG ! {apply_load, self(), ?LOAD_COUNTER_START}, receive {apply_load_ack, MG} -> traffic_apply_load(MGs); {'EXIT', MG, Reason} -> exit({mg_exit, MG, Reason}) after 10000 -> exit({apply_load_ack_timeout, MG}) end.traffic_reset_mg_stats([]) -> ok;traffic_reset_mg_stats([{Name, Pid}|MGs]) -> d("traffic_reset_mg_stats -> resetting ~s", [Name]), traffic_reset_stats(Pid), traffic_reset_mg_stats(MGs).traffic_reset_mgc_stats(Mgc) -> d("traffic_reset_mgc_stats -> resetting ~p", [Mgc]), traffic_reset_stats(Mgc). traffic_reset_stats(Pid) -> Pid ! {reset_stats, self()}, receive {reset_stats_ack, Pid} -> ok; {'EXIT', Pid, Reason} -> exit({client_exit, Pid, Reason}) after 10000 -> exit({reset_stats_ack_timeout, Pid}) end. traffic_await_load_complete([]) -> ok;traffic_await_load_complete(MGs0) -> receive {load_complete, Pid} -> d("received load_complete from ~p", [Pid]), MGs1 = lists:keydelete(Pid, 2, MGs0), traffic_await_load_complete(lists:delete(Pid, MGs1)); {'EXIT', Pid, Reason} -> i("exit signal from ~p: ~p", [Pid, Reason]), case lists:keymember(Pid, 2, MGs0) of true -> exit({mg_exit, Pid, Reason}); false -> MGs1 = lists:keydelete(Pid, 2, MGs0), traffic_await_load_complete(lists:delete(Pid, MGs1)) end end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%make_node_name(Name) -> case string:tokens(atom_to_list(node()), [$@]) of [_,Host] -> list_to_atom(lists:concat([atom_to_list(Name) ++ "@" ++ Host])); _ -> exit("Test node must be started with '-sname'") end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%start_mgc(Node, Mid, ET, Verbosity) -> d("start mgc[~p]: ~p", [Node, Mid]), RI = {receive_info, mk_recv_info(ET)}, Config = [{local_mid, Mid}, RI], Pid = spawn_link(Node, ?MODULE, mgc, [self(), Verbosity, Config]), await_started(Pid).mk_recv_info(ET) -> mk_recv_info(ET, []).mk_recv_info([], Acc) -> Acc;mk_recv_info([{text,tcp}|ET], Acc) -> RI = [{encoding_module, megaco_pretty_text_encoder}, {encoding_config, []}, {transport_module, megaco_tcp}, {port, 2944}], mk_recv_info(ET, [RI|Acc]);mk_recv_info([{text,udp}|ET], Acc) -> RI = [{encoding_module, megaco_pretty_text_encoder}, {encoding_config, []}, {transport_module, megaco_udp}, {port, 2944}], mk_recv_info(ET, [RI|Acc]);mk_recv_info([{binary,tcp}|ET], Acc) -> RI = [{encoding_module, megaco_ber_bin_encoder}, {encoding_config, []}, {transport_module, megaco_tcp}, {port, 2945}], mk_recv_info(ET, [RI|Acc]);mk_recv_info([{binary,udp}|ET], Acc) -> RI = [{encoding_module, megaco_ber_bin_encoder}, {encoding_config, []}, {transport_module, megaco_udp}, {port, 2945}], mk_recv_info(ET, [RI|Acc]);mk_recv_info([ET|_], _) -> throw({error, {invaalid_encoding_transport, ET}}).mgc(Parent, Verbosity, Config) -> process_flag(trap_exit, true), put(verbosity, Verbosity), put(sname, "MGC"), i("mgc -> starting"), {Mid, TcpSup, UdpSup} = mgc_init(Config), notify_started(Parent), S = #mgc{parent = Parent, tcp_sup = TcpSup, udp_sup = UdpSup, mid = Mid}, i("mgc -> started"), mgc_loop(S).mgc_init(Config) -> d("mgc_init -> entry"), Mid = get_conf(local_mid, Config), RI = get_conf(receive_info, Config), d("mgc_init -> start megaco"), application:start(megaco), d("mgc_init -> start megaco user"), megaco:start_user(Mid, []), d("mgc_init -> update user info (user_mod)"), megaco:update_user_info(Mid, user_mod, ?MODULE), d("mgc_init -> update user info (user_args)"), megaco:update_user_info(Mid, user_args, [self()]), d("mgc_init -> get user info (receive_handle)"), RH = megaco:user_info(Mid,receive_handle), d("mgc_init -> parse receive info"), ListenTo = mgc_parse_receive_info(RI, RH), d("mgc_init -> start transports"), {Tcp, Udp} = mgc_start_transports(ListenTo), {Mid, Tcp, Udp}. mgc_loop(S) -> d("mgc_loop -> await request"), receive {stop, Parent} when S#mgc.parent == Parent -> i("mgc_loop -> stopping", []), Mid = S#mgc.mid, (catch mgc_close_conns(Mid)), megaco:stop_user(Mid), application:stop(megaco), i("mgc_loop -> stopped", []), Parent ! {stopped, self()}, exit(normal); %% Reset stats {reset_stats, Parent} when S#mgc.parent == Parent -> i("mgc_loop -> got request to reset stats counters"), mgc_reset_stats(S#mgc.mid), Parent ! {reset_stats_ack, self()}, mgc_loop(S); %% Give me statistics {statistics, 1, Parent} when S#mgc.parent == Parent -> i("mgc_loop -> got request for statistics 1"), {ok, Gen} = megaco:get_stats(), GetTrans = fun(CH) -> Reason = {statistics, CH}, Pid = megaco:conn_info(CH, control_pid), SendMod = megaco:conn_info(CH, send_mod), SendHandle = megaco:conn_info(CH, send_handle), {ok, Stats} = case SendMod of megaco_tcp -> megaco_tcp:get_stats(SendHandle); megaco_udp -> megaco_udp:get_stats(SendHandle); SendMod -> exit(Pid, Reason) end, {SendHandle, Stats} end, Mid = S#mgc.mid, Trans = lists:map(GetTrans, megaco:user_info(Mid, connections)), Parent ! {statistics, 1, [{gen, Gen}, {trans, Trans}], self()}, mgc_loop(S); {statistics, 2, Parent} when S#mgc.parent == Parent -> i("mgc_loop -> got request for statistics 2"), {ok, Gen} = megaco:get_stats(), #mgc{tcp_sup = TcpSup, udp_sup = UdpSup} = S, TcpStats = get_trans_stats(TcpSup, megaco_tcp), UdpStats = get_trans_stats(UdpSup, megaco_udp), Parent ! {statistics, 2, [{gen, Gen}, {trans, [TcpStats, UdpStats]}], self()}, mgc_loop(S); %% Megaco callback messages {request, Request, From} -> d("mgc_loop -> received megaco request: ~n~p~n From: ~p", [Request, From]), Reply = mgc_handle_request(Request), d("mgc_loop -> send request reply: ~n~p", [Reply]), From ! {reply, Reply, self()}, mgc_loop(S); {'EXIT', Pid, Reason} -> error_msg("MGC received unexpected exit signal from ~p:~n~p", [Pid, Reason]), mgc_loop(S); Invalid -> i("mgc_loop -> received invalid request: ~p", [Invalid]), mgc_loop(S) end.mgc_reset_stats(Mid) -> megaco:reset_stats(), mgc_reset_trans_stats(megaco:user_info(Mid, connections), []).mgc_reset_trans_stats([], _Reset) -> ok;mgc_reset_trans_stats([CH|CHs], Reset) -> SendMod = megaco:conn_info(CH, send_mod), case lists:member(SendMod, Reset) of true -> mgc_reset_trans_stats(CHs, Reset); false -> SendMod:reset_stats(), mgc_reset_trans_stats(CHs, [SendMod|Reset]) end. mgc_close_conns(Mid) -> Reason = {self(), ignore}, Disco = fun(CH) -> (catch mgc_close_conn(CH, Reason)) end, lists:map(Disco, megaco:user_info(Mid, connections)).mgc_close_conn(CH, Reason) -> d("close connection to ~p", [CH#megaco_conn_handle.remote_mid]), Pid = megaco:conn_info(CH, control_pid), SendMod = megaco:conn_info(CH, send_mod), SendHandle = megaco:conn_info(CH, send_handle), megaco:disconnect(CH, Reason), case SendMod of megaco_tcp -> megaco_tcp:close(SendHandle); megaco_udp -> megaco_udp:close(SendHandle); SendMod -> exit(Pid, Reason) end. get_trans_stats(P, SendMod) when pid(P) -> case (catch SendMod:get_stats()) of {ok, Stats} -> {SendMod, Stats}; Else -> {SendMod, Else} end;get_trans_stats(_P, SendMod) -> {SendMod, undefined}.mgc_parse_receive_info([], _RH) -> throw({error, no_receive_info});mgc_parse_receive_info(RI, RH) -> mgc_parse_receive_info(RI, RH, []).mgc_parse_receive_info([], _RH, ListenTo) -> ListenTo;mgc_parse_receive_info([RI|RIs], RH, ListenTo) -> d("mgc_parse_receive_info -> parse receive info"), RH1 = mgc_parse_receive_info1(RI, RH), case (catch mgc_parse_receive_info1(RI, RH)) of {error, Reason} -> i("failed parsing receive info: ~p~n~p", [RI, Reason]), exit({failed_parsing_recv_info, RI, Reason}); RH1 -> mgc_parse_receive_info(RIs, RH, [RH1|ListenTo]) end. mgc_parse_receive_info1(RI, RH) -> d("mgc_parse_receive_info1 -> get encoding module"), EM = get_encoding_module(RI), d("mgc_parse_receive_info1 -> get encoding config"), EC = get_encoding_config(RI, EM), d("mgc_parse_receive_info1 -> get transport module"), TM = get_transport_module(RI), d("mgc_parse_receive_info1 -> get transport port"), TP = get_transport_port(RI), RH1 = RH#megaco_receive_handle{send_mod = TM, encoding_mod = EM, encoding_config = EC}, {TP, RH1}.mgc_start_transports([]) ->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -