📄 megaco_test_lib.erl
字号:
%% ``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 via the world wide web 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.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%%%----------------------------------------------------------------------%% Purpose: Lightweight test server%%-----------------------------------------------------------------------module(megaco_test_lib).-compile(export_all).-include("megaco_test_lib.hrl").%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Evaluates a test case or test suite%% Returns a list of failing test cases:%% %% {Mod, Fun, ExpectedRes, ActualRes}%%----------------------------------------------------------------------tickets(Case) -> Res = lists:flatten(tickets(Case, default_config())), %% io:format("Res: ~p~n", [Res]), display_result(Res), Res.tickets(Cases, Config) when list(Cases) -> [tickets(Case, Config) || Case <- Cases];tickets(Mod, Config) when atom(Mod) -> Res = tickets(Mod, tickets, Config), Res;tickets(Bad, _Config) -> [{badarg, Bad, ok}].tickets(Mod, Func, Config) -> case (catch Mod:Func(suite)) of [] -> io:format("Eval: ~p:", [{Mod, Func}]), Res = eval(Mod, Func, Config), {R, _, _} = Res, io:format(" ~p~n", [R]), Res;% io:format("Eval: ~p:~p~n", [Mod, Func]),% eval(Mod, Func, Config); Cases when list(Cases) -> io:format("Expand: ~p:~p ... ~n" " ~p~n", [Mod, Func, Cases]), Map = fun({M,_}) when atom(M) -> tickets(M, tickets, Config); (F) when atom(F) -> tickets(Mod, F, Config); (Case) -> Case end, lists:map(Map, Cases); {req, _, {conf, Init, Cases, Finish}} -> case (catch Mod:Init(Config)) of Conf when list(Conf) -> io:format("Expand: ~p:~p ...~n", [Mod, Func]), Map = fun({M,_}) when atom(M) -> tickets(M, tickets, Config); (F) when atom(F) -> tickets(Mod, F, Config); (Case) -> Case end, Res = lists:map(Map, Cases), (catch Mod:Finish(Conf)), Res; {'EXIT', {skipped, Reason}} -> io:format(" => skipping: ~p~n", [Reason]), [{skipped, {Mod, Func}, Reason}]; Error -> io:format(" => init failed: ~p~n", [Error]), [{failed, {Mod, Func}, Error}] end; {'EXIT', {undef, _}} -> io:format("Undefined: ~p~n", [{Mod, Func}]), [{nyi, {Mod, Func}, ok}]; Error -> io:format("Ignoring: ~p:~p: ~p~n", [Mod, Func, Error]), [{failed, {Mod, Func}, Error}] end. t(Case) -> process_flag(trap_exit, true), Res = lists:flatten(t(Case, default_config())), io:format("Res: ~p~n", [Res]), display_result(Res), Res.t({Mod, Fun}, Config) when atom(Mod), atom(Fun) -> case catch apply(Mod, Fun, [suite]) of [] -> io:format("Eval: ~p:", [{Mod, Fun}]), Res = eval(Mod, Fun, Config), {R, _, _} = Res, io:format(" ~p~n", [R]), Res; Cases when list(Cases) -> io:format("Expand: ~p ...~n", [{Mod, Fun}]), Map = fun(Case) when atom(Case)-> {Mod, Case}; (Case) -> Case end, t(lists:map(Map, Cases), Config); {req, _, {conf, Init, Cases, Finish}} -> case (catch apply(Mod, Init, [Config])) of Conf when list(Conf) -> io:format("Expand: ~p ...~n", [{Mod, Fun}]), Map = fun(Case) when atom(Case)-> {Mod, Case}; (Case) -> Case end, Res = t(lists:map(Map, Cases), Conf), (catch apply(Mod, Finish, [Conf])), Res; {'EXIT', {skipped, Reason}} -> io:format(" => skipping: ~p~n", [Reason]), [{skipped, {Mod, Fun}, Reason}]; Error -> io:format(" => failed: ~p~n", [Error]), [{failed, {Mod, Fun}, Error}] end; {'EXIT', {undef, _}} -> io:format("Undefined: ~p~n", [{Mod, Fun}]), [{nyi, {Mod, Fun}, ok}]; Error -> io:format("Ignoring: ~p: ~p~n", [{Mod, Fun}, Error]), [{failed, {Mod, Fun}, Error}] end;t(Mod, Config) when atom(Mod) -> Res = t({Mod, all}, Config), Res;t(Cases, Config) when list(Cases) -> [t(Case, Config) || Case <- Cases];t(Bad, _Config) -> [{badarg, Bad, ok}].eval(Mod, Fun, Config) -> TestCase = {?MODULE, Mod, Fun}, Label = lists:concat(["TEST CASE: ", Fun]), megaco:report_event(40, ?MODULE, Mod, Label ++ " started", [TestCase, Config]), global:register_name(megaco_test_case_sup, self()), Flag = process_flag(trap_exit, true), put(megaco_test_server, true), Config2 = Mod:init_per_testcase(Fun, Config), Pid = spawn_link(?MODULE, do_eval, [self(), Mod, Fun, Config2]), R = wait_for_evaluator(Pid, Mod, Fun, Config2, []), Mod:fin_per_testcase(Fun, Config2), erase(megaco_test_server), global:unregister_name(megaco_test_case_sup), process_flag(trap_exit, Flag), R.-record('REASON', {mod, line, desc}).wait_for_evaluator(Pid, Mod, Fun, Config, Errors) -> TestCase = {?MODULE, Mod, Fun}, Label = lists:concat(["TEST CASE: ", Fun]), receive {done, Pid, ok} when Errors == [] -> megaco:report_event(40, Mod, ?MODULE, Label ++ " ok", [TestCase, Config]), {ok, {Mod, Fun}, Errors}; {done, Pid, ok} -> megaco:report_event(40, Mod, ?MODULE, Label ++ " failed", [TestCase, Config]), {failed, {Mod, Fun}, Errors}; {done, Pid, {ok, _}} when Errors == [] -> megaco:report_event(40, Mod, ?MODULE, Label ++ " ok", [TestCase, Config]), {ok, {Mod, Fun}, Errors}; {done, Pid, {ok, _}} -> megaco:report_event(40, Mod, ?MODULE, Label ++ " failed", [TestCase, Config]), {failed, {Mod, Fun}, Errors}; {done, Pid, Fail} -> megaco:report_event(20, Mod, ?MODULE, Label ++ " failed", [TestCase, Config, {return, Fail}, Errors]), {failed, {Mod,Fun}, Fail}; {'EXIT', Pid, {skipped, Reason}} -> megaco:report_event(20, Mod, ?MODULE, Label ++ " skipped", [TestCase, Config, {skipped, Reason}]), {skipped, {Mod, Fun}, Errors}; {'EXIT', Pid, Reason} -> megaco:report_event(20, Mod, ?MODULE, Label ++ " crashed", [TestCase, Config, {'EXIT', Reason}]), {crashed, {Mod, Fun}, [{'EXIT', Reason} | Errors]}; {fail, Pid, Reason} -> wait_for_evaluator(Pid, Mod, Fun, Config, Errors ++ [Reason]) end.do_eval(ReplyTo, Mod, Fun, Config) -> case (catch apply(Mod, Fun, [Config])) of {'EXIT', {skipped, Reason}} -> ReplyTo ! {'EXIT', self(), {skipped, Reason}}; Other -> ReplyTo ! {done, self(), Other} end, unlink(ReplyTo), exit(shutdown).display_result([]) -> io:format("OK~n", []);display_result(Res) when list(Res) -> Ok = [MF || {ok, MF, _} <- Res], Nyi = [MF || {nyi, MF, _} <- Res], Skipped = [{MF, Reason} || {skipped, MF, Reason} <- Res], Failed = [{MF, Reason} || {failed, MF, Reason} <- Res], Crashed = [{MF, Reason} || {crashed, MF, Reason} <- Res], display_summery(Ok, Nyi, Skipped, Failed, Crashed), display_skipped(Skipped), display_failed(Failed), display_crashed(Crashed).display_summery(Ok, Nyi, Skipped, Failed, Crashed) -> io:format("~nTest case summery:~n", []), display_summery(Ok, "successfull"), display_summery(Nyi, "not yet implemented"), display_summery(Skipped, "skipped"), display_summery(Failed, "failed"), display_summery(Crashed, "crashed"), io:format("~n", []). display_summery(Res, Info) -> io:format(" ~w test cases ~s~n", [length(Res), Info]). display_skipped([]) -> ok;display_skipped(Skipped) -> io:format("Skipped test cases:~n", []), F = fun({MF, Reason}) -> io:format(" ~p => ~p~n", [MF, Reason]) end, lists:foreach(F, Skipped), io:format("~n", []). display_failed([]) -> ok;display_failed(Failed) -> io:format("Failed test cases:~n", []), F = fun({MF, Reason}) -> io:format(" ~p => ~p~n", [MF, Reason]) end, lists:foreach(F, Failed), io:format("~n", []).display_crashed([]) -> ok;display_crashed(Crashed) -> io:format("Crashed test cases:~n", []), F = fun({MF, Reason}) -> io:format(" ~p => ~p~n", [MF, Reason]) end, lists:foreach(F, Crashed), io:format("~n", []). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Verify that the actual result of a test case matches the exected one%% Returns the actual result%% Stores the result in the process dictionary if mismatch
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -