%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2012-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% %% %CopyrightEnd% %% -module(test_server_break_SUITE). -export([all/1, init_per_suite/1, end_per_suite/1]). -export([init_per_testcase/2, end_per_testcase/2]). -export([break_in_init_tc/1, break_in_tc/1, break_in_end_tc/1, break_in_end_tc_after_fail/1, break_in_end_tc_after_abort/1, check_all_breaks/1]). -include_lib("common_test/include/ct.hrl"). all(suite) -> [break_in_init_tc, break_in_tc, break_in_end_tc, break_in_end_tc_after_fail, break_in_end_tc_after_abort, check_all_breaks]. %must be the last test - checks result of previous tests init_per_suite(Config) -> spawn(fun break_and_continue_sup/0), Config. end_per_suite(_Config) -> ok. init_per_testcase(Case,Config) when Case==break_in_init_tc -> Config1 = init_timetrap(500,Config), break_and_check(Case), Config1; init_per_testcase(Case,Config) when Case==check_all_breaks -> init_timetrap({seconds,20},Config); init_per_testcase(_Case,Config) -> init_timetrap(500,Config). init_timetrap(T,Config) -> Dog = ?t:timetrap(T), [{watchdog, Dog}|Config]. end_per_testcase(Case,Config) when Case==break_in_end_tc; Case==break_in_end_tc_after_fail; Case==break_in_end_tc_after_abort -> break_and_check(Case), cancel_timetrap(Config); end_per_testcase(_Case,Config) -> cancel_timetrap(Config). cancel_timetrap(Config) -> Dog=?config(watchdog, Config), ?t:timetrap_cancel(Dog), ok. %%%----------------------------------------------------------------- %%% Test cases break_in_init_tc(Config) when is_list(Config) -> ok. break_in_tc(Config) when is_list(Config) -> break_and_check(break_in_tc), ok. break_in_end_tc(Config) when is_list(Config) -> ok. break_in_end_tc_after_fail(Config) when is_list(Config) -> ?t:fail(test_case_should_fail). break_in_end_tc_after_abort(Config) when is_list(Config) -> ?t:adjusted_sleep(2000). % will cause a timetrap timeout %% This test case checks that all breaks in previous test cases was %% also continued, and that the break lasted as long as expected. %% The reason for this is that some of the breaks above are in %% end_per_testcase, and failures there will only produce a warning, %% not an error - so this is to catch the error for real. check_all_breaks(Config) when is_list(Config) -> break_and_continue_sup ! {done,self()}, receive {Breaks,Continued} -> check_all_breaks(Breaks,Continued) end. %%%----------------------------------------------------------------- %%% Internal functions check_all_breaks([{From,Case,T,Start}|Breaks],[{From,End}|Continued]) -> Diff = timer:now_diff(End,Start), DiffSec = round(Diff/1000000), TSec = round(T/1000000), if DiffSec==TSec -> ?t:format("Break in ~p successfully continued after ~p second(s)~n", [Case,DiffSec]), check_all_breaks(Breaks,Continued); true -> ?t:format("Faulty duration of break in ~p: continued after ~p second(s)~n", [Case,DiffSec]), ?t:fail({faulty_diff,Case,DiffSec,TSec}) end; check_all_breaks([],[]) -> ok; check_all_breaks(Breaks,Continued) -> %% This is probably a case of a missing continue - i.e. a break %% has been started, but it was never continued. ?t:fail({no_match_in_breaks_and_continued,Breaks,Continued}). break_and_check(Case) -> break_and_continue_sup ! {break,Case,1000,self()}, ?t:break(atom_to_list(Case)), break_and_continue_sup ! {continued,self()}, ok. break_and_continue_sup() -> register(break_and_continue_sup,self()), break_and_continue_loop([],[]). break_and_continue_loop(Breaks,Continued) -> receive {break,Case,T,From} -> Start = now(), {RealT,_} = timer:tc(?t,adjusted_sleep,[T]), ?t:continue(), break_and_continue_loop([{From,Case,RealT,Start}|Breaks],Continued); {continued,From} -> break_and_continue_loop(Breaks,[{From,now()}|Continued]); {done,From} -> From ! {lists:reverse(Breaks),lists:reverse(Continued)} end.