📄 megaco_test_lib.erl
字号:
error(Actual, Mod, Line) -> global:send(megaco_global_logger, {failed, Mod, Line}), log("<ERROR> Bad result: ~p~n", [Actual], Mod, Line), Label = lists:concat([Mod, "(", Line, ") unexpected result"]), megaco:report_event(60, Mod, Mod, Label, [{line, Mod, Line}, {error, Actual}]), case global:whereis_name(megaco_test_case_sup) of undefined -> ignore; Pid -> Fail = #'REASON'{mod = Mod, line = Line, desc = Actual}, Pid ! {fail, self(), Fail} end, Actual.log(Format, Args, Mod, Line) -> case global:whereis_name(megaco_global_logger) of undefined -> io:format(user, "~p~p(~p): " ++ Format, [self(), Mod, Line] ++ Args); Pid -> io:format(Pid, "~p~p(~p): " ++ Format, [self(), Mod, Line] ++ Args) end.skip(Actual, File, Line) -> log("Skipping test case~n", [], File, Line), String = lists:flatten(io_lib:format("Skipping test case ~p(~p): ~p~n", [File, Line, Actual])), exit({skipped, String}).fatal_skip(Actual, File, Line) -> error(Actual, File, Line), exit(shutdown).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Flush the message queue and return its messagesflush() -> receive Msg -> [Msg | flush()] after 1000 -> [] end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Check if process is alive and kickingstill_alive(Pid) -> case catch erlang:is_process_alive(Pid) of % New BIF in Erlang/OTP R5 true -> true; false -> false; {'EXIT', _} -> % Pre R5 backward compatibility case process_info(Pid, message_queue_len) of undefined -> false; _ -> true end end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The proxy processproxy_start(ProxyId) -> spawn_link(?MODULE, proxy_init, [ProxyId, self()]).proxy_start(Node, ProxyId) -> spawn_link(Node, ?MODULE, proxy_init, [ProxyId, self()]).proxy_init(ProxyId, Controller) -> process_flag(trap_exit, true), ?LOG("[~p] proxy started by ~p~n",[ProxyId, Controller]), proxy_loop(ProxyId, Controller).proxy_loop(OwnId, Controller) -> receive {'EXIT', Controller, Reason} -> p("proxy_loop -> received exit from controller" "~n Reason: ~p" "~n", [Reason]), exit(Reason); {apply, Fun} -> p("proxy_loop -> received apply request~n", []), Res = Fun(), p("proxy_loop -> apply result: " "~n ~p" "~n", [Res]), Controller ! {res, OwnId, Res}, proxy_loop(OwnId, Controller); OtherMsg -> p("proxy_loop -> received unknown message: " "~n OtherMsg: ~p" "~n", [OtherMsg]), Controller ! {msg, OwnId, OtherMsg}, proxy_loop(OwnId, Controller) end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Test server callbacksinit_per_testcase(_Case, Config) -> Pid = group_leader(), Name = megaco_global_logger, case global:whereis_name(Name) of undefined -> global:register_name(megaco_global_logger, Pid); Pid -> io:format("init_per_testcase -> " "already registered to ~p~n", [Pid]), ok; OtherPid when pid(OtherPid) -> io:format("init_per_testcase -> " "already registered to other ~p (~p)~n", [OtherPid,Pid]), exit({already_registered, {megaco_global_logger, OtherPid, Pid}}) end, set_kill_timer(Config).fin_per_testcase(_Case, Config) -> Name = megaco_global_logger, case global:whereis_name(Name) of undefined -> io:format("fin_per_testcase -> already un-registered~n", []), ok; Pid when pid(Pid) -> global:unregister_name(megaco_global_logger), ok end, reset_kill_timer(Config).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Set kill timerset_kill_timer(Config) -> case init:get_argument(megaco_test_timeout) of {ok, _} -> Config; _ -> Time = case lookup_config(tc_timeout, Config) of [] -> timer:minutes(5); ConfigTime when integer(ConfigTime) -> ConfigTime end, Dog = case get(megaco_test_server) of true -> spawn_link(?MODULE, watchdog, [self(), Time]); _ -> test_server:timetrap(Time) end, [{kill_timer, Dog}|Config] end.reset_kill_timer(Config) -> DogKiller = case get(megaco_test_server) of true -> fun(P) when is_pid(P) -> P ! stop; (_) -> ok end; _ -> fun(Ref) -> test_server:timetrap_cancel(Ref) end end, case lists:keysearch(kill_timer, 1, Config) of {value, {kill_timer, Dog}} -> DogKiller(Dog), lists:keydelete(kill_timer, 1, Config); _ -> Config end.watchdog(Pid, Time) -> erlang:now(), receive stop -> ok after Time -> case (catch process_info(Pid)) of undefined -> ok; Info -> ?LOG("<ERROR> Watchdog in test case timed out " "for ~p after ~p min" "~n~p" "~n", [Pid, Time div (1000*60), Info]), exit(Pid, kill) end end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%prepare_test_case(Actions, N, Config, File, Line) -> OrigNodes = lookup_config(nodes, Config), TestNodes = lookup_config(nodenames, Config), %% For testserver This = node(), SomeNodes = OrigNodes ++ (TestNodes -- OrigNodes), AllNodes = [This | (SomeNodes -- [This])], Nodes = pick_n_nodes(N, AllNodes, File, Line), start_nodes(Nodes, File, Line), do_prepare_test_case(Actions, Nodes, Config, File, Line).do_prepare_test_case([init | Actions], Nodes, Config, File, Line) -> process_flag(trap_exit, true), megaco_test_lib:flush(), do_prepare_test_case(Actions, Nodes, Config, File, Line);do_prepare_test_case([{stop_app, App} | Actions], Nodes, Config, File, Line) -> _Res = rpc:multicall(Nodes, application, stop, [App]), do_prepare_test_case(Actions, Nodes, Config, File, Line);do_prepare_test_case([], Nodes, _Config, _File, _Line) -> Nodes.pick_n_nodes(all, AllNodes, _File, _Line) -> AllNodes;pick_n_nodes(N, AllNodes, _File, _Line) when integer(N), length(AllNodes) >= N -> AllNodes -- lists:nthtail(N, AllNodes);pick_n_nodes(N, AllNodes, File, Line) -> fatal_skip({too_few_nodes, N, AllNodes}, File, Line). lookup_config(Key,Config) -> case lists:keysearch(Key, 1, Config) of {value,{Key,Val}} -> Val; _ -> [] end.default_config() -> [{nodes, default_nodes()}].default_nodes() -> mk_nodes(2, []).mk_nodes(0, Nodes) -> Nodes;mk_nodes(N, []) -> mk_nodes(N - 1, [node()]);mk_nodes(N, Nodes) when N > 0 -> Head = hd(Nodes), [Name, Host] = node_to_name_and_host(Head), Nodes ++ [mk_node(I, Name, Host) || I <- lists:seq(1, N)].mk_node(N, Name, Host) -> list_to_atom(lists:concat([Name ++ integer_to_list(N) ++ "@" ++ Host])). %% Returns [Name, Host] node_to_name_and_host(Node) -> string:tokens(atom_to_list(Node), [$@]).start_nodes([Node | Nodes], File, Line) -> case net_adm:ping(Node) of pong -> start_nodes(Nodes, File, Line); pang -> [Name, Host] = node_to_name_and_host(Node), case slave:start_link(Host, Name) of {ok, NewNode} when NewNode == Node -> Path = code:get_path(), {ok, Cwd} = file:get_cwd(), true = rpc:call(Node, code, set_path, [Path]), ok = rpc:call(Node, file, set_cwd, [Cwd]), true = rpc:call(Node, code, set_path, [Path]), {_, []} = rpc:multicall(global, sync, []), start_nodes(Nodes, File, Line); Other -> fatal_skip({cannot_start_node, Node, Other}, File, Line) end end;start_nodes([], _File, _Line) -> ok.p(F,A) -> io:format("~p" ++ F ++ "~n", [self()|A]).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -