From f40f4686848bbabb9357b33d08d4b4039d9d7c63 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Fri, 24 Jan 2014 12:19:05 +0100 Subject: Implement tests for logging traffic for multiple telnet connections Also fix remaining problems in source code --- lib/common_test/src/ct_conn_log_h.erl | 28 ++----- lib/common_test/src/ct_telnet.erl | 10 +-- lib/common_test/src/unix_telnet.erl | 8 +- lib/common_test/test/ct_telnet_SUITE.erl | 14 ++-- .../ct_telnet_SUITE_data/ct_telnet_basic_SUITE.erl | 98 ++++++++++++++++++---- .../ct_telnet_own_server_SUITE.erl | 28 +++---- .../ct_telnet_timetrap_SUITE.erl | 4 +- 7 files changed, 125 insertions(+), 65 deletions(-) (limited to 'lib') diff --git a/lib/common_test/src/ct_conn_log_h.erl b/lib/common_test/src/ct_conn_log_h.erl index 286844d526..6e0e0baab2 100644 --- a/lib/common_test/src/ct_conn_log_h.erl +++ b/lib/common_test/src/ct_conn_log_h.erl @@ -52,7 +52,7 @@ open_files([],State) -> do_open_files([{Tag,File}|Logs],Acc) -> - case file:open(File, [write,{encoding,utf8}]) of + case file:open(File, [write,append,{encoding,utf8}]) of {ok,Fd} -> do_open_files(Logs,[{Tag,Fd}|Acc]); {error,Reason} -> @@ -63,17 +63,12 @@ do_open_files([],Acc) -> handle_event({_Type, GL, _Msg}, State) when node(GL) /= node() -> {ok, State}; -handle_event({_Type,_GL,{Pid,{ct_connection,Action,ConnName},Report}},State) -> - %% NOTE: if the format of this event is changed - %% ({ct_connection,Action,ConnName}) then remember to change - %% test_server_h:report_receiver as well!!! - Info = conn_info(Pid,#conn_log{name=ConnName,action=Action}), +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), {ok, State}; handle_event({_Type,_GL,{Pid,Info=#conn_log{},Report}},State) -> - %% NOTE: if the format of this event is changed - %% (Info=#conn_log{}) then remember to change - %% test_server_h:report_receiver as well!!! write_report(now(),conn_info(Pid,Info),Report,State), {ok, State}; handle_event({error_report,_,{Pid,_,[{ct_connection,ConnName}|R]}},State) -> @@ -151,12 +146,7 @@ format_head(ConnMod,_,Time,Text) -> io_lib:format("~n~ts",[Head]). format_title(raw,#conn_log{client=Client}=Info) -> - case actionstr(Info) of - {no_server,Action} -> - io_lib:format("Client ~w ~s",[Client,Action]); - Action -> - io_lib:format("Client ~w ~s ~ts",[Client,Action,serverstr(Info)]) - end; + io_lib:format("Client ~w ~s ~ts",[Client,actionstr(Info),serverstr(Info)]); format_title(_,Info) -> Title = pad_char_end(?WIDTH,pretty_title(Info),$=), io_lib:format("~n~ts", [Title]). @@ -211,10 +201,8 @@ pretty_title(#conn_log{client=Client}=Info) -> actionstr(#conn_log{action=send}) -> "----->"; actionstr(#conn_log{action=cmd}) -> "----->"; actionstr(#conn_log{action=recv}) -> "<-----"; -actionstr(#conn_log{action=open}) -> "open session to"; -actionstr(#conn_log{action=close}) -> "close session to"; -actionstr(#conn_log{action=info}) -> {no_server,"info"}; -actionstr(#conn_log{action=error}) -> {no_server,"error"}; +actionstr(#conn_log{action=open}) -> "opened session to"; +actionstr(#conn_log{action=close}) -> "closed session to"; actionstr(_) -> "<---->". serverstr(#conn_log{name=undefined,address={undefined,_}}) -> @@ -222,7 +210,7 @@ serverstr(#conn_log{name=undefined,address={undefined,_}}) -> serverstr(#conn_log{name=undefined,address=Address}) -> io_lib:format("~p",[Address]); serverstr(#conn_log{name=Alias,address={undefined,_}}) -> - io_lib:format("~w()",[Alias]); + io_lib:format("~w",[Alias]); serverstr(#conn_log{name=Alias,address=Address}) -> io_lib:format("~w(~p)",[Alias,Address]). diff --git a/lib/common_test/src/ct_telnet.erl b/lib/common_test/src/ct_telnet.erl index 5fc89be0c5..f9dd62ee37 100644 --- a/lib/common_test/src/ct_telnet.erl +++ b/lib/common_test/src/ct_telnet.erl @@ -181,7 +181,7 @@ open(KeyOrName,ConnType,TargetMod,Extra) -> end; Bool -> Bool end, - log(undefined,open,"Opening connection ~p to ~p", + log(undefined,open,"Connecting to ~p(~p)", [KeyOrName,Addr1]), ct_gen_conn:start(KeyOrName,full_addr(Addr1,ConnType), {TargetMod,KeepAlive,Extra},?MODULE) @@ -200,7 +200,7 @@ open(KeyOrName,ConnType,TargetMod,Extra) -> close(Connection) -> case get_handle(Connection) of {ok,Pid} -> - log(undefined,close,"Closing connection for handle: ~w",[Pid]), + log(undefined,close,"Connection closed, handle: ~w",[Pid]), case ct_gen_conn:stop(Pid) of {error,{process_down,Pid,noproc}} -> {error,already_closed}; @@ -600,9 +600,9 @@ reconnect(Ip,Port,N,State=#state{name=Name, %% @hidden terminate(TelnPid,State) -> - log(State,close,"Closing telnet connection.\nId: ~w",[TelnPid]), - ct_telnet_client:close(TelnPid). - + Result = ct_telnet_client:close(TelnPid), + log(State,close,"Telnet connection for ~w closed.",[TelnPid]), + Result. %%%================================================================= %%% Internal function diff --git a/lib/common_test/src/unix_telnet.erl b/lib/common_test/src/unix_telnet.erl index 8b24e959e8..e049c3bf39 100644 --- a/lib/common_test/src/unix_telnet.erl +++ b/lib/common_test/src/unix_telnet.erl @@ -137,19 +137,21 @@ connect1(Name,Ip,Port,Timeout,KeepAlive,Username,Password) -> {error,Error} end; Error -> - log(Name,recv,"Login failed\n~p\n",[Error]), + log(Name,recv,"Login to ~p:~p failed\n~p\n",[Ip,Port,Error]), {error,Error} end; {ok,[{prompt,_OtherPrompt1},{prompt,_OtherPrompt2}],_} -> {ok,Pid}; Error -> log(Name,error, - "Did not get expected prompt\n~p\n",[Error]), + "Did not get expected prompt from ~p:~p\n~p\n", + [Ip,Port,Error]), {error,Error} end; Error -> log(Name,error, - "Could not open telnet connection\n~p\n",[Error]), + "Could not open telnet connection to ~p:~p\n~p\n", + [Ip,Port,Error]), Error end, end_gen_log(), diff --git a/lib/common_test/test/ct_telnet_SUITE.erl b/lib/common_test/test/ct_telnet_SUITE.erl index 1536d093a6..9eb6c4033c 100644 --- a/lib/common_test/test/ct_telnet_SUITE.erl +++ b/lib/common_test/test/ct_telnet_SUITE.erl @@ -50,7 +50,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. groups() -> [{legacy, [], [unix_telnet,own_server,timetrap]}, - {raw, [], [unix_telnet,own_server]}, + {raw, [], [unix_telnet]},%,own_server,timetrap]}, {html, [], [unix_telnet,own_server]}, {silent, [], [unix_telnet,own_server]}]. @@ -170,8 +170,10 @@ telnet_config(unix_telnet, LogType) -> [{unix, ct:get_config(unix)}, {ct_conn_log, [{ct_telnet,[{log_type,LogType}, - {hosts,[the_telnet_server]}] - }]}]; + {hosts,[telnet_server_conn1, + telnet_server_conn2, + telnet_server_conn3, + telnet_server_conn4]}]}]}]; telnet_config(_, LogType) -> [{unix,[{telnet,"localhost"}, {port, ?erl_telnet_server_port}, @@ -183,8 +185,10 @@ telnet_config(_, LogType) -> true -> [{ct_conn_log, [{ct_telnet,[{log_type,LogType}, - {hosts,[the_telnet_server]}] - }]}] + {hosts,[telnet_server_conn1, + telnet_server_conn2, + telnet_server_conn3, + telnet_server_conn4]}]}]}] end]. %%%----------------------------------------------------------------- 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 203062eba0..a443893c5d 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,50 +5,95 @@ -include_lib("common_test/include/ct.hrl"). +-define(no_of_sessions, 2). +-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))). + %%-------------------------------------------------------------------- %% TEST SERVER CALLBACK FUNCTIONS %%-------------------------------------------------------------------- suite() -> [ - {require,the_telnet_server,{unix,[telnet]}}, {require,ct_conn_log}, {ct_hooks, [{cth_conn_log,[]}]} ]. -all() -> +operations() -> [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)]. + groups() -> - []. + [{single_connection,[],operations()}, + {multiple_connections,[parallel],mult_case(sessions,?no_of_sessions)}]. + +all() -> + [{group,single_connection}, + {group,multiple_connections}]. 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(_GroupName, Config) -> - Config. +init_per_group(Group, Config) -> + if Group == single_connection -> + ct:require(?conn_name(1),{unix,[telnet]}); + true -> + ok + end, + [{n,1} | Config]. end_per_group(_GroupName, Config) -> Config. -start_stop(_Config) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), +init_per_testcase(sessions, Config) -> + N = ?req_n(), + ct:log("Using connection ~w for session ~w on ~w", + [?conn_name(N),N,self()]), + ct:require(?conn_name(N),{unix,[telnet]}), + [{n,N} | proplists:delete(n,Config)]; +init_per_testcase(Case, Config) -> + ct:log("Testcase ~w using connection ~w", + [Case,?conn_name(?get_n(Config))]), + Config. + +end_per_testcase(_, _) -> + ok. + +%%%----------------------------------------------------------------- +%%% TEST CASES + +sessions(Config) -> + [apply(?MODULE,Op,[Config]) || Op <- operations()], + ok. + +start_stop(Config) -> + ct:log("Opening ~w...", [?conn_name(?get_n(Config))]), + {ok, Handle} = ct_telnet:open(?conn_name(?get_n(Config))), ok = ct_telnet:close(Handle), ok. -send_and_get(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + +send_and_get(Config) -> + {ok, Handle} = ct_telnet:open(?conn_name(?get_n(Config))), ok = ct_telnet:send(Handle, "ayt"), {ok, _Data} = ct_telnet:get_data(Handle), ok = ct_telnet:close(Handle), ok. -expect(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), +expect(Config) -> + {ok, Handle} = ct_telnet:open(?conn_name(?get_n(Config))), ok = ct_telnet:send(Handle, "echo ayt"), ok = case ct_telnet:expect(Handle, ["ayt"]) of {ok, _} -> @@ -59,21 +104,21 @@ expect(_) -> ok = ct_telnet:close(Handle), ok. -already_closed(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), +already_closed(Config) -> + {ok, Handle} = ct_telnet:open(?conn_name(?get_n(Config))), ok = ct_telnet:close(Handle), {error, already_closed} = ct_telnet:close(Handle), ok. -cmd(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), +cmd(Config) -> + {ok, Handle} = ct_telnet:open(?conn_name(?get_n(Config))), {ok, _} = ct_telnet:cmd(Handle, "display"), {ok, _} = ct_telnet:cmdf(Handle, "~s ~s", ["set", "bsasdel"]), ok = ct_telnet:close(Handle), ok. -sendf(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), +sendf(Config) -> + {ok, Handle} = ct_telnet:open(?conn_name(?get_n(Config))), ok = ct_telnet:sendf(Handle, "~s", ["ayt"]), ok = ct_telnet:close(Handle), ok. @@ -81,3 +126,22 @@ sendf(_) -> close_wrong_type(_) -> {error, _} = ct_telnet:close(whatever), ok. + +%%%----------------------------------------------------------------- +%%% 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). + + + diff --git a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl index c5589eddc8..8d142e85a8 100644 --- a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl +++ b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_own_server_SUITE.erl @@ -10,7 +10,7 @@ suite() -> [ - {require,the_telnet_server,{unix,[telnet]}}, + {require,telnet_server_conn1,{unix,[telnet]}}, {require,ct_conn_log}, {ct_hooks, [{cth_conn_log,[]}]} ]. @@ -49,7 +49,7 @@ end_per_group(_GroupName, Config) -> %% Simple expect expect(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo ayt"), {ok,["ayt"]} = ct_telnet:expect(Handle, ["ayt"]), ok = ct_telnet:close(Handle), @@ -57,7 +57,7 @@ expect(_) -> %% Expect with repeat option expect_repeat(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo_ml xy xy"), {ok,[["xy"],["xy"]],done} = ct_telnet:expect(Handle, ["xy"],[{repeat,2}]), ok = ct_telnet:close(Handle), @@ -65,7 +65,7 @@ expect_repeat(_) -> %% Expect with sequence option expect_sequence(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo_ml ab cd ef"), {ok,[["ab"],["cd"],["ef"]]} = ct_telnet:expect(Handle, [["ab"],["cd"],["ef"]], @@ -76,7 +76,7 @@ expect_sequence(_) -> %% Check that expect returns when a prompt is found, even if pattern %% is not matched. expect_error_prompt(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo xxx> yyy"), {error,{prompt,"> "}} = ct_telnet:expect(Handle, ["yyy"]), ok = ct_telnet:close(Handle), @@ -86,7 +86,7 @@ expect_error_prompt(_) -> %% expected pattern is received - as long as not newline or prompt is %% received it will not match. expect_error_timeout(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo_no_prompt xxx"), {error,timeout} = ct_telnet:expect(Handle, ["xxx"], [{timeout,1000}]), ok = ct_telnet:close(Handle), @@ -95,7 +95,7 @@ expect_error_timeout(_) -> %% expect with ignore_prompt option should not return even if a prompt %% is found. The pattern after the prompt (here "> ") can be matched. ignore_prompt(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo xxx> yyy"), {ok,["yyy"]} = ct_telnet:expect(Handle, ["yyy"], [ignore_prompt]), ok = ct_telnet:close(Handle), @@ -103,7 +103,7 @@ ignore_prompt(_) -> %% expect with ignore_prompt and repeat options. ignore_prompt_repeat(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo_ml yyy> yyy>"), {ok,[["yyy"],["yyy"]],done} = ct_telnet:expect(Handle, ["yyy"], [{repeat,2}, @@ -113,7 +113,7 @@ ignore_prompt_repeat(_) -> %% expect with ignore_prompt and sequence options. ignore_prompt_sequence(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo_ml xxx> yyy> zzz> "), {ok,[["xxx"],["yyy"],["zzz"]]} = ct_telnet:expect(Handle, [["xxx"],["yyy"],["zzz"]], @@ -127,7 +127,7 @@ ignore_prompt_sequence(_) -> %% As for expect without the ignore_prompt option, it a newline or a %% prompt is required in order for the pattern to match. ignore_prompt_timeout(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo xxx"), {error,timeout} = ct_telnet:expect(Handle, ["yyy"], [ignore_prompt, {timeout,1000}]), @@ -146,7 +146,7 @@ ignore_prompt_timeout(_) -> %% no_prompt_check option shall match pattern both when prompt is sent %% and when it is not. no_prompt_check(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo xxx"), {ok,["xxx"]} = ct_telnet:expect(Handle, ["xxx"], [no_prompt_check]), ok = ct_telnet:send(Handle, "echo_no_prompt yyy"), @@ -156,7 +156,7 @@ no_prompt_check(_) -> %% no_prompt_check and repeat options no_prompt_check_repeat(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo_ml xxx xxx"), {ok,[["xxx"],["xxx"]],done} = ct_telnet:expect(Handle,["xxx"], [{repeat,2}, @@ -170,7 +170,7 @@ no_prompt_check_repeat(_) -> %% no_prompt_check and sequence options no_prompt_check_sequence(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo_ml_no_prompt ab cd ef"), {ok,[["ab"],["cd"],["ef"]]} = ct_telnet:expect(Handle, [["ab"],["cd"],["ef"]], @@ -182,7 +182,7 @@ no_prompt_check_sequence(_) -> %% Check that expect returns after idle timeout when no_prompt_check %% option is used. no_prompt_check_timeout(_) -> - {ok, Handle} = ct_telnet:open(the_telnet_server), + {ok, Handle} = ct_telnet:open(telnet_server_conn1), ok = ct_telnet:send(Handle, "echo xxx"), {error,timeout} = ct_telnet:expect(Handle, ["yyy"], [no_prompt_check, {timeout,1000}]), diff --git a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_timetrap_SUITE.erl b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_timetrap_SUITE.erl index 1959ee3cb8..c45a4f0984 100644 --- a/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_timetrap_SUITE.erl +++ b/lib/common_test/test/ct_telnet_SUITE_data/ct_telnet_timetrap_SUITE.erl @@ -4,7 +4,7 @@ -include_lib("common_test/include/ct.hrl"). --define(name, the_telnet_server). +-define(name, telnet_server_conn1). %%-------------------------------------------------------------------- %% TEST SERVER CALLBACK FUNCTIONS @@ -17,6 +17,8 @@ end_per_suite(_Config) -> ok. suite() -> [{require,?name,{unix,[telnet]}}, + {require,ct_conn_log}, + {ct_hooks, [{cth_conn_log,[]}]}, {timetrap,{seconds,7}}]. all() -> -- cgit v1.2.3