From 95a574b3620ec3d7420c7807b2d84f4602512229 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Mon, 27 Jan 2014 14:05:44 +0100 Subject: Make it possible to use raw telnet logs in parallel test case groups --- lib/common_test/src/ct_conn_log_h.erl | 84 +++++++++++++--------- lib/common_test/src/ct_util.erl | 11 ++- lib/common_test/src/cth_conn_log.erl | 61 ++++++++++++++-- lib/common_test/test/ct_telnet_SUITE.erl | 3 +- .../ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl | 57 +++++++-------- 5 files changed, 145 insertions(+), 71 deletions(-) diff --git a/lib/common_test/src/ct_conn_log_h.erl b/lib/common_test/src/ct_conn_log_h.erl index 6e0e0baab2..2b83ff1abb 100644 --- a/lib/common_test/src/ct_conn_log_h.erl +++ b/lib/common_test/src/ct_conn_log_h.erl @@ -30,79 +30,90 @@ handle_event/2, handle_call/2, handle_info/2, terminate/2]). --record(state, {group_leader,logs=[]}). +-record(state, {logs=[], default_gl}). -define(WIDTH,80). %%%----------------------------------------------------------------- %%% Callbacks -init({GL,Logs}) -> - open_files(Logs,#state{group_leader=GL}). +init({GL,ConnLogs}) -> + open_files(GL,ConnLogs,#state{default_gl=GL}). -open_files([{ConnMod,{LogType,Logs}}|T],State) -> - case do_open_files(Logs,[]) of +open_files(GL,[{ConnMod,{LogType,ConnLogs}}|T],State) -> + case do_open_files(GL,ConnLogs,[]) of {ok,Fds} -> - open_files(T,State#state{logs=[{ConnMod,{LogType,Fds}} | - State#state.logs]}); + open_files(GL,T,State#state{logs=[{GL,[{ConnMod,{LogType,Fds}}]} | + State#state.logs]}); Error -> Error end; -open_files([],State) -> +open_files(_GL,[],State) -> {ok,State}. - -do_open_files([{Tag,File}|Logs],Acc) -> +do_open_files(GL,[{Tag,File}|ConnLogs],Acc) -> case file:open(File, [write,append,{encoding,utf8}]) of {ok,Fd} -> - do_open_files(Logs,[{Tag,Fd}|Acc]); + do_open_files(GL,ConnLogs,[{Tag,Fd}|Acc]); {error,Reason} -> {error,{could_not_open_log,File,Reason}} end; -do_open_files([],Acc) -> +do_open_files(_GL,[],Acc) -> {ok,lists:reverse(Acc)}. +handle_event({info_report,_,{From,update,{GL,ConnLogs}}}, + State) when node(GL) == node() -> + + %%! --- Tue Jan 28 12:18:50 2014 --- peppe was here! + io:format(user, "!!! ADDING NEW LOGS FOR ~p~n", [GL]), + + open_files(GL,ConnLogs,#state{}), + From ! {updated,GL}, + {ok, State}; handle_event({_Type, GL, _Msg}, State) when node(GL) /= node() -> {ok, State}; -handle_event({_Type,_GL,{Pid,{ct_connection,Mod,Action,ConnName},Report}}, +handle_event({_Type,GL,{Pid,{ct_connection,Mod,Action,ConnName},Report}}, State) -> Info = conn_info(Pid,#conn_log{name=ConnName,action=Action,module=Mod}), - write_report(now(),Info,Report,State), + write_report(now(),Info,Report,GL,State), {ok, State}; -handle_event({_Type,_GL,{Pid,Info=#conn_log{},Report}},State) -> - write_report(now(),conn_info(Pid,Info),Report,State), +handle_event({_Type,GL,{Pid,Info=#conn_log{},Report}}, State) -> + write_report(now(),conn_info(Pid,Info),Report,GL,State), {ok, State}; -handle_event({error_report,_,{Pid,_,[{ct_connection,ConnName}|R]}},State) -> +handle_event({error_report,GL,{Pid,_,[{ct_connection,ConnName}|R]}}, State) -> %% Error reports from connection - write_error(now(),conn_info(Pid,#conn_log{name=ConnName}),R,State), + write_error(now(),conn_info(Pid,#conn_log{name=ConnName}),R,GL,State), {ok, State}; -handle_event(_, State) -> +handle_event(_What, State) -> {ok, State}. -handle_info(_, State) -> +handle_info(_What, State) -> {ok, State}. handle_call(_Query, State) -> {ok, {error, bad_query}, State}. terminate(_,#state{logs=Logs}) -> - [file:close(Fd) || {_,{_,Fds}} <- Logs, {_,Fd} <- Fds], + lists:foreach( + fun({_GL,ConnLogs}) -> + [file:close(Fd) || {_,{_,Fds}} <- ConnLogs, {_,Fd} <- Fds] + end, Logs), ok. %%%----------------------------------------------------------------- %%% Writing reports -write_report(_Time,#conn_log{header=false,module=ConnMod}=Info,Data,State) -> - {LogType,Fd} = get_log(Info,State), +write_report(_Time,#conn_log{header=false,module=ConnMod}=Info,Data,GL,State) -> + {LogType,Fd} = get_log(Info,GL,State), io:format(Fd,"~n~ts",[format_data(ConnMod,LogType,Data)]); -write_report(Time,#conn_log{module=ConnMod}=Info,Data,State) -> - {LogType,Fd} = get_log(Info,State), +write_report(Time,#conn_log{module=ConnMod}=Info,Data,GL,State) -> + {LogType,Fd} = get_log(Info,GL,State), io:format(Fd,"~n~ts~ts~ts",[format_head(ConnMod,LogType,Time), format_title(LogType,Info), format_data(ConnMod,LogType,Data)]). -write_error(Time,#conn_log{module=ConnMod}=Info,Report,State) -> - case get_log(Info,State) of +write_error(Time,#conn_log{module=ConnMod}=Info,Report,GL,State) -> + case get_log(Info,GL,State) of {html,_} -> %% The error will anyway be written in the html log by the %% sasl error handler, so don't write it again. @@ -114,14 +125,19 @@ write_error(Time,#conn_log{module=ConnMod}=Info,Report,State) -> format_error(LogType,Report)]) end. -get_log(Info,State) -> - case proplists:get_value(Info#conn_log.module,State#state.logs) of - {html,_} -> - {html,State#state.group_leader}; - {LogType,Fds} -> - {LogType,get_fd(Info,Fds)}; +get_log(Info,GL,State) -> + case proplists:get_value(GL, State#state.logs) of undefined -> - {html,State#state.group_leader} + {html,State#state.default_gl}; + ConnLogs -> + case proplists:get_value(Info#conn_log.module,ConnLogs) of + {html,_} -> + {html,GL}; + {LogType,Fds} -> + {LogType,get_fd(Info,Fds)}; + undefined -> + {html,GL} + end end. get_fd(#conn_log{name=undefined},Fds) -> diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl index bcc4caa62e..1d851f8d2f 100644 --- a/lib/common_test/src/ct_util.erl +++ b/lib/common_test/src/ct_util.erl @@ -382,9 +382,14 @@ loop(Mode,TestData,StartDir) -> TestData1 = case lists:keysearch(Key,1,TestData) of {value,{Key,Val}} -> - NewVal = Fun(Val), - return(From,NewVal), - [{Key,NewVal}|lists:keydelete(Key,1,TestData)]; + case Fun(Val) of + '$delete' -> + return(From,deleted), + lists:keydelete(Key,1,TestData); + NewVal -> + return(From,NewVal), + [{Key,NewVal}|lists:keydelete(Key,1,TestData)] + end; _ -> case lists:member(create,Opts) of true -> diff --git a/lib/common_test/src/cth_conn_log.erl b/lib/common_test/src/cth_conn_log.erl index d5762bada8..050bda6eda 100644 --- a/lib/common_test/src/cth_conn_log.erl +++ b/lib/common_test/src/cth_conn_log.erl @@ -104,7 +104,7 @@ get_log_opts(Opts) -> pre_init_per_testcase(TestCase,Config,CthState) -> Logs = lists:map( - fun({ConnMod,{LogType,Hosts}}) -> + fun({ConnMod,{LogType,Hosts}}) -> ct_util:set_testdata({{?MODULE,ConnMod},LogType}), case LogType of LogType when LogType==raw; LogType==pretty -> @@ -136,10 +136,61 @@ pre_init_per_testcase(TestCase,Config,CthState) -> end end, CthState), - error_logger:add_report_handler(ct_conn_log_h,{group_leader(),Logs}), + + GL = group_leader(), + Update = + fun(Init) when Init == undefined; Init == [] -> + + %%! --- Tue Jan 28 12:13:08 2014 --- peppe was here! + io:format(user, "### ~p: ADDING NEW HANDLER FOR ~p~n", + [TestCase,GL]), + + error_logger:add_report_handler(ct_conn_log_h,{GL,Logs}), + [TestCase]; + (PrevUsers) -> + + %%! --- Tue Jan 28 12:13:08 2014 --- peppe was here! + io:format(user, "### ~p: CONNECTING ~p TO EXISTING HANDLER~n", + [TestCase,GL]), + + error_logger:info_report(update,{GL,Logs}), + receive + {updated,GL} -> + [TestCase|PrevUsers] + after + 5000 -> + {error,no_response} + end + end, + ct_util:update_testdata(?MODULE, Update, [create]), {Config,CthState}. -post_end_per_testcase(_TestCase,_Config,Return,CthState) -> - [ct_util:delete_testdata({?MODULE,ConnMod}) || {ConnMod,_} <- CthState], - error_logger:delete_report_handler(ct_conn_log_h), +post_end_per_testcase(TestCase,_Config,Return,CthState) -> + Update = + fun(PrevUsers) -> + case lists:delete(TestCase, PrevUsers) of + [] -> + '$delete'; + PrevUsers1 -> + PrevUsers1 + end + end, + case ct_util:update_testdata(?MODULE, Update) of + deleted -> + [ct_util:delete_testdata({?MODULE,ConnMod}) || + {ConnMod,_} <- CthState], + + %%! --- Tue Jan 28 13:29:37 2014 --- peppe was here! + io:format(user, "### ~p: REMOVING ERROR LOGGER~n", [TestCase]), + + error_logger:delete_report_handler(ct_conn_log_h); + {error,no_response} -> + exit({?MODULE,no_response_from_logger}); + _PrevUsers -> + %%! --- Tue Jan 28 13:29:37 2014 --- peppe was here! + io:format(user, "### ~p: *NOT* REMOVING ERROR LOGGER~n", [TestCase]), + + ok + end, {Return,CthState}. + diff --git a/lib/common_test/test/ct_telnet_SUITE.erl b/lib/common_test/test/ct_telnet_SUITE.erl index 9eb6c4033c..bb6cc0be5d 100644 --- a/lib/common_test/test/ct_telnet_SUITE.erl +++ b/lib/common_test/test/ct_telnet_SUITE.erl @@ -50,7 +50,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. groups() -> [{legacy, [], [unix_telnet,own_server,timetrap]}, - {raw, [], [unix_telnet]},%,own_server,timetrap]}, + {raw, [], [unix_telnet,own_server,timetrap]}, +%{raw, [], [unix_telnet]}, {html, [], [unix_telnet,own_server]}, {silent, [], [unix_telnet,own_server]}]. diff --git a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl index a443893c5d..dbb9e9449a 100644 --- a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl +++ b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl @@ -5,12 +5,8 @@ -include_lib("common_test/include/ct.hrl"). --define(no_of_sessions, 2). +-define(no_of_sessions, 4). -define(conn_name(N), (list_to_atom("telnet_server_conn"++integer_to_list(N)))). --define(req_n(), (begin - ?MODULE ! {self(),req}, - receive _N -> _N after 2000 -> 0 end - end)). -define(get_n(Cfg), (proplists:get_value(n, Cfg))). %%-------------------------------------------------------------------- @@ -23,15 +19,20 @@ suite() -> [ ]. operations() -> - [start_stop, send_and_get, expect, already_closed, + [start_stop +, send_and_get, expect, already_closed, cmd, sendf, close_wrong_type]. -mult_case(_Case, 0) -> []; -mult_case(Case, N) -> [Case | mult_case(Case, N-1)]. +mult_case(_Case, 0) -> + []; +mult_case(Case, N) -> + [list_to_atom(atom_to_list(Case)++integer_to_list(N)) | + mult_case(Case, N-1)]. groups() -> [{single_connection,[],operations()}, - {multiple_connections,[parallel],mult_case(sessions,?no_of_sessions)}]. + {multiple_connections,[parallel], + lists:reverse(mult_case(sessions,?no_of_sessions))}]. all() -> [{group,single_connection}, @@ -40,11 +41,9 @@ all() -> init_per_suite(Config) -> ct:pal("Will use these log hook options: ~p", [ct:get_config(ct_conn_log,[])]), - SerialNo = spawn(?MODULE, serialno, [1,?no_of_sessions]), Config. end_per_suite(_Config) -> - catch exit(whereis(?MODULE), kill), ok. init_per_group(Group, Config) -> @@ -58,8 +57,15 @@ init_per_group(Group, Config) -> end_per_group(_GroupName, Config) -> Config. -init_per_testcase(sessions, Config) -> - N = ?req_n(), +init_per_testcase(Case, Config) when (Case == sessions1) or + (Case == sessions2) or + (Case == sessions3) or + (Case == sessions4) -> + + %%! --- Tue Jan 28 13:46:47 2014 --- peppe was here! + io:format(user, ">>> ~p STARTING~n", [Case]), + + N = lists:last(atom_to_list(Case))-48, ct:log("Using connection ~w for session ~w on ~w", [?conn_name(N),N,self()]), ct:require(?conn_name(N),{unix,[telnet]}), @@ -69,7 +75,11 @@ init_per_testcase(Case, Config) -> [Case,?conn_name(?get_n(Config))]), Config. -end_per_testcase(_, _) -> +end_per_testcase(_Case, _) -> + + %%! --- Tue Jan 28 13:46:47 2014 --- peppe was here! + io:format(user, "<<< ~p ENDING~n", [_Case]), + ok. %%%----------------------------------------------------------------- @@ -79,6 +89,11 @@ sessions(Config) -> [apply(?MODULE,Op,[Config]) || Op <- operations()], ok. +sessions1(Config) -> sessions(Config). +sessions2(Config) -> sessions(Config). +sessions3(Config) -> sessions(Config). +sessions4(Config) -> sessions(Config). + start_stop(Config) -> ct:log("Opening ~w...", [?conn_name(?get_n(Config))]), {ok, Handle} = ct_telnet:open(?conn_name(?get_n(Config))), @@ -130,18 +145,4 @@ close_wrong_type(_) -> %%%----------------------------------------------------------------- %%% HELP FUNCS -serialno(Start, Stop) -> - register(?MODULE, self()), - loop(Start, Stop). - -loop(X, Y) when X > Y -> - done; -loop(X, Y) -> - receive - {Pid,req} -> - Pid ! X - end, - loop(X+1, Y). - - -- cgit v1.2.3