diff options
Diffstat (limited to 'lib/common_test/test')
15 files changed, 682 insertions, 389 deletions
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile index 1532b6c1f7..b1eddfedd7 100644 --- a/lib/common_test/test/Makefile +++ b/lib/common_test/test/Makefile @@ -69,7 +69,8 @@ MODULES= \ erl2html2_SUITE \ test_server_SUITE \ test_server_test_lib \ - ct_release_test_SUITE + ct_release_test_SUITE \ + ct_log_SUITE ERL_FILES= $(MODULES:%=%.erl) HRL_FILES= test_server_test_lib.hrl diff --git a/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl b/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl index c64774cd4f..0b3f834732 100644 --- a/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl +++ b/lib/common_test/test/ct_config_SUITE_data/config/test/config_dynamic_SUITE.erl @@ -74,7 +74,7 @@ test_get_known_variable(_)-> test_localtime_update(_)-> Seconds = 5, LT1 = ct:get_config(localtime), - ct:sleep(Seconds*1000), + timer:sleep(Seconds*1000), % don't want scaling of this timer LT2 = ct:reload_config(localtime), case is_diff_ok(LT1, LT2, Seconds) of {false, Actual, Exp}-> diff --git a/lib/common_test/test/ct_gen_conn_SUITE_data/conn_SUITE.erl b/lib/common_test/test/ct_gen_conn_SUITE_data/conn_SUITE.erl index 1404df6410..19eb1211fa 100644 --- a/lib/common_test/test/ct_gen_conn_SUITE_data/conn_SUITE.erl +++ b/lib/common_test/test/ct_gen_conn_SUITE_data/conn_SUITE.erl @@ -73,24 +73,28 @@ handles_to_multi_conn_pids(_Config) -> ConnPid3 = ct_gen_conn:get_conn_pid(Handle3), {true,true} = {is_process_alive(Handle3),is_process_alive(ConnPid3)}, + monitor_procs([Handle1,ConnPid1,Handle2,ConnPid2,Handle3,ConnPid3]), + ok = proto:close(Handle1), - ct:sleep(100), + ok = wait_procs_down([Handle1,ConnPid1]), {false,false} = {is_process_alive(Handle1),is_process_alive(ConnPid1)}, {true,true} = {is_process_alive(Handle2),is_process_alive(ConnPid2)}, ok = proto:kill_conn_proc(Handle2), - ct:sleep(100), + ok = wait_procs_down([ConnPid2]), {true,false} = {is_process_alive(Handle2),is_process_alive(ConnPid2)}, ConnPid2x = ct_gen_conn:get_conn_pid(Handle2), true = is_process_alive(ConnPid2x), + monitor_procs([ConnPid2x]), + ok = proto:close(Handle2), - ct:sleep(100), + ok = wait_procs_down([Handle2,ConnPid2x]), {false,false} = {is_process_alive(Handle2),is_process_alive(ConnPid2x)}, application:set_env(ct_test, reconnect, false), ok = proto:kill_conn_proc(Handle3), - ct:sleep(100), + ok = wait_procs_down([Handle3,ConnPid3]), {false,false} = {is_process_alive(Handle3),is_process_alive(ConnPid3)}, ok. @@ -116,24 +120,28 @@ handles_to_single_conn_pids(_Config) -> {undefined,Handle3,_,_}] = lists:sort(ct_util:get_connections(ConnPid)), ct:pal("CONNS = ~n~p", [Conns]), + monitor_procs([Handle1,Handle2,Handle3,ConnPid]), ok = proto:close(Handle1), - ct:sleep(100), + ok = wait_procs_down([Handle1]), {false,true} = {is_process_alive(Handle1),is_process_alive(ConnPid)}, ok = proto:kill_conn_proc(Handle2), - ct:sleep(100), + ok = wait_procs_down([ConnPid]), NewConnPid = ct_gen_conn:get_conn_pid(Handle2), NewConnPid = ct_gen_conn:get_conn_pid(Handle3), true = is_process_alive(Handle2), true = is_process_alive(Handle3), + false = is_process_alive(ConnPid), + + monitor_procs([NewConnPid]), ok = proto:close(Handle2), - ct:sleep(100), + ok = wait_procs_down([Handle2]), {false,true} = {is_process_alive(Handle2),is_process_alive(NewConnPid)}, application:set_env(ct_test, reconnect, false), ok = proto:kill_conn_proc(Handle3), - ct:sleep(100), + ok = wait_procs_down([Handle3,NewConnPid]), {false,false} = {is_process_alive(Handle3),is_process_alive(NewConnPid)}, ok. @@ -158,30 +166,37 @@ names_to_multi_conn_pids(_Config) -> Handle1 = proto:open(mconn1), + monitor_procs([Handle1,ConnPid1,Handle2,ConnPid2,Handle3,ConnPid3]), + ok = proto:close(mconn1), - ct:sleep(100), + ok = wait_procs_down([Handle1,ConnPid1]), {false,false} = {is_process_alive(Handle1),is_process_alive(ConnPid1)}, ok = proto:kill_conn_proc(Handle2), - ct:sleep(100), + ok = wait_procs_down([ConnPid2]), Handle2 = proto:open(mconn2), % should've been reconnected already {true,false} = {is_process_alive(Handle2),is_process_alive(ConnPid2)}, ConnPid2x = ct_gen_conn:get_conn_pid(Handle2), true = is_process_alive(ConnPid2x), + monitor_procs([ConnPid2x]), + ok = proto:close(mconn2), - ct:sleep(100), + ok = wait_procs_down([Handle2,ConnPid2x]), {false,false} = {is_process_alive(Handle2),is_process_alive(ConnPid2x)}, Handle2y = proto:open(mconn2), ConnPid2y = ct_gen_conn:get_conn_pid(Handle2y), {true,true} = {is_process_alive(Handle2y),is_process_alive(ConnPid2y)}, + + monitor_procs([Handle2y,ConnPid2y]), + ok = proto:close(mconn2), - ct:sleep(100), + ok = wait_procs_down([Handle2y,ConnPid2y]), {false,false} = {is_process_alive(Handle2y),is_process_alive(ConnPid2y)}, application:set_env(ct_test, reconnect, false), ok = proto:kill_conn_proc(Handle3), - ct:sleep(100), + ok = wait_procs_down([Handle3,ConnPid3]), {false,false} = {is_process_alive(Handle3),is_process_alive(ConnPid3)}, ok. @@ -211,16 +226,20 @@ names_to_single_conn_pids(_Config) -> {sconn3,Handle3,_,_}] = lists:sort(ct_util:get_connections(ConnPid)), ct:pal("CONNS on ~p = ~n~p", [ConnPid,Conns]), + monitor_procs([Handle1,Handle2,Handle3,ConnPid]), + ok = proto:close(sconn1), - ct:sleep(100), + ok = wait_procs_down([Handle1]), {false,true} = {is_process_alive(Handle1),is_process_alive(ConnPid)}, ok = proto:kill_conn_proc(Handle2), - ct:sleep(100), + ok = wait_procs_down([ConnPid]), {true,false} = {is_process_alive(Handle2),is_process_alive(ConnPid)}, Handle2 = proto:open(sconn2), % should've been reconnected already NewConnPid = ct_gen_conn:get_conn_pid(Handle2), true = is_process_alive(NewConnPid), + + monitor_procs([NewConnPid]), Conns1 = [{sconn2,Handle2,_,_}, {sconn3,Handle3,_,_}] = @@ -228,14 +247,29 @@ names_to_single_conn_pids(_Config) -> ct:pal("CONNS on ~p = ~n~p", [NewConnPid,Conns1]), ok = proto:close(sconn2), - ct:sleep(100), + ok = wait_procs_down([Handle2]), {false,true} = {is_process_alive(Handle2),is_process_alive(NewConnPid)}, application:set_env(ct_test, reconnect, false), ok = proto:kill_conn_proc(Handle3), - ct:sleep(100), + ok = wait_procs_down([Handle3,NewConnPid]), {false,false} = {is_process_alive(Handle3),is_process_alive(NewConnPid)}, ok. +%%%----------------------------------------------------------------- +monitor_procs(Pids) -> + [erlang:monitor(process,Pid) || Pid <- Pids], + ok. + +wait_procs_down([]) -> + ok; +wait_procs_down(Pids) -> + receive + {'DOWN',_,process,Pid,_} -> + wait_procs_down(lists:delete(Pid,Pids)) + after 2000 -> + timeout + end. + diff --git a/lib/common_test/test/ct_log_SUITE.erl b/lib/common_test/test/ct_log_SUITE.erl new file mode 100644 index 0000000000..9bdd44cbdf --- /dev/null +++ b/lib/common_test/test/ct_log_SUITE.erl @@ -0,0 +1,328 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2009-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% +%% + +%%%------------------------------------------------------------------- +%%% File: ct_log_SUITE +%%% +%%% Description: Test that ct:log, ct:pal and io:format print to +%%% the test case log file as expected, with or without special HTML +%%% characters being escaped. +%%% +%%%------------------------------------------------------------------- +-module(ct_log_SUITE). + +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("common_test/include/ct_event.hrl"). + +-define(eh, ct_test_support_eh). + +%%-------------------------------------------------------------------- +%% TEST SERVER CALLBACK FUNCTIONS +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + Config. + +end_per_suite(_Config) -> + ok. + +init_per_testcase(_TestCase, Config) -> + Config. + +end_per_testcase(_TestCase, _Config) -> + ok. + +suite() -> [{ct_hooks,[ts_install_cth]}]. + +all() -> + [{group,print_and_verify}]. + +groups() -> + [{print_and_verify,[sequence],[print,verify]}]. + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% TEST CASES +%%-------------------------------------------------------------------- + +%%%----------------------------------------------------------------- +%%% +print(Config) -> + TcLogFile = proplists:get_value(tc_logfile, Config), + Pid = self(), + String = atom_to_list(?MODULE), + + %% START mark + io:format("LOGGING START~n"), + + %% io:format + io:format("1. Printing nothing~n", []), + io:format("2. Printing a string: ~s~n", [String]), + io:format("3. Printing a string: ~p~n", [String]), + io:format("4. Printing a tuple: ~w~n", [{module,?MODULE}]), + io:format("5. Printing a pid: ~w~n", [Pid]), + io:format("6. Printing HTML: <pre>~s</pre>~n", [String]), + + %% --- API --- + %% pal(Format) -> + %% = ct:pal(default, 50, Format, []). + %% pal(X1, X2) -> ok + %% X1 = Category | Importance | Format + %% X2 = Format | FormatArgs + %% pal(X1, X2, X3) -> ok + %% X1 = Category | Importance + %% X2 = Importance | Format + %% X3 = Format | FormatArgs + %% pal(Category, Importance, Format, FormatArgs) -> ok + %% ------ + ct:pal("1. Printing nothing"), + ct:pal("2. Printing nothing", []), + ct:pal("3. Printing a string: ~s", [String]), + ct:pal("4. Printing a string: ~p", [String]), + ct:pal("5. Printing a tuple: ~w", [{module,?MODULE}]), + ct:pal("6. Printing a pid: ~w", [Pid]), + ct:pal("7. Printing HTML: <pre>~s</pre>", [String]), + ct:pal(ct_internal, "8. Printing with category"), + ct:pal(ct_internal, "9. Printing with ~s", ["category"]), + ct:pal(50, "10. Printing with importance"), + ct:pal(50, "11. Printing with ~s", ["importance"]), + ct:pal(ct_internal, 50, "12. Printing with ~s", ["category and importance"]), + + %% --- API --- + %% log(Format) -> ok + %% = ct:log(default, 50, Format, [], []). + %% log(X1, X2) -> ok + %% X1 = Category | Importance | Format + %% X2 = Format | FormatArgs + %% log(X1, X2, X3) -> ok + %% X1 = Category | Importance + %% X2 = Importance | Format + %% X3 = Format | FormatArgs | Opts + %% log(X1, X2, X3, X4) -> ok + %% X1 = Category | Importance + %% X2 = Importance | Format + %% X3 = Format | FormatArgs + %% X4 = FormatArgs | Opts + %% log(Category, Importance, Format, FormatArgs, Opts) -> ok + %% ------ + ct:log("1. Printing nothing"), + ct:log("2. Printing nothing", []), + ct:log("3. Printing a string: ~s", [String]), + ct:log("4. Printing a string: ~p", [String]), + ct:log("5. Printing a tuple: ~w", [{module,?MODULE}]), + ct:log("6. Printing a pid: ~w", [Pid]), + ct:log("7. Printing HTML: <pre>~s</pre>", [String]), + ct:log("8. Printing a pid escaped: ~w", [Pid], [esc_chars]), + ct:log("9. Printing a string escaped: ~p", [String], [esc_chars]), + ct:log("10. Printing HTML escaped: <pre>~s</pre>", [String], [esc_chars]), + ct:log("11. Printing a string, no css: ~s", [String], [no_css]), + ct:log("12. Printing a pid escaped, no css: ~w", [Pid], + [esc_chars, no_css]), + ct:log(ct_internal, "13. Printing with category"), + ct:log(ct_internal, "14. Printing with ~s", ["category"]), + ct:log(ct_internal, "15. Printing with ~s, no_css", ["category"], + [no_css]), + ct:log(50, "16. Printing with importance"), + ct:log(50, "17. Printing with ~s", ["importance"]), + ct:log(50, "18. Printing with ~s, no_css", ["importance"], [no_css]), + ct:log(ct_internal, 50, "19. Printing with category and importance"), + ct:log(ct_internal, 50, "20. Printing with ~s", ["category and importance"]), + ct:log(ct_internal, 50, "21. Printing a pid escaped with ~s, no_css: ~w", + ["category and importance",Pid], [esc_chars,no_css]), + + %% END mark + ct:log("LOGGING END", [], [no_css]), + {save_config,[{the_logfile,TcLogFile},{the_pid,Pid},{the_string,String}]}. + + +verify(Config) -> + {print,SavedCfg} = proplists:get_value(saved_config, Config), + TcLogFile = proplists:get_value(the_logfile, SavedCfg), + Pid = proplists:get_value(the_pid, SavedCfg), + StrPid = lists:flatten(io_lib:format("~p",[Pid])), + EscPid = "<" ++ string:substr(StrPid, 2, length(StrPid)-2) ++ ">", + String = proplists:get_value(the_string, SavedCfg), + ct:log("Read from prev testcase: ~p & ~p", [TcLogFile,Pid]), + {ok,Dev} = file:open(TcLogFile, [read]), + ok = read_until(Dev, "LOGGING START\n"), + + %% io:format + match_line(Dev, "1. Printing nothing", []), + read_nl(Dev), + match_line(Dev, "2. Printing a string: ~s", [String]), + read_nl(Dev), + match_line(Dev, "3. Printing a string: ~p", [String]), + read_nl(Dev), + match_line(Dev, "4. Printing a tuple: ~w", [{module,?MODULE}]), + read_nl(Dev), + match_line(Dev, "5. Printing a pid: ~s", [EscPid]), + read_nl(Dev), + match_line(Dev, "6. Printing HTML: <pre>~s</pre>", [String]), + read_nl(Dev), + %% ct:pal + read_header(Dev), + match_line(Dev, "1. Printing nothing", []), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "2. Printing nothing", []), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "3. Printing a string: ~s", [String]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "4. Printing a string: ~p", [String]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "5. Printing a tuple: ~w", [{module,?MODULE}]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "6. Printing a pid: ~s", [EscPid]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "7. Printing HTML: <pre>~s</pre>", [String]), + read_footer(Dev), + read_header(Dev, "\"ct_internal\""), + match_line(Dev, "8. Printing with category", []), + read_footer(Dev), + read_header(Dev, "\"ct_internal\""), + match_line(Dev, "9. Printing with ~s", ["category"]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "10. Printing with importance", []), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "11. Printing with ~s", ["importance"]), + read_footer(Dev), + read_header(Dev, "\"ct_internal\""), + match_line(Dev, "12. Printing with ~s", ["category and importance"]), + read_footer(Dev), + %% ct:log + read_header(Dev), + match_line(Dev, "1. Printing nothing", []), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "2. Printing nothing", []), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "3. Printing a string: ~s", [String]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "4. Printing a string: ~p", [String]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "5. Printing a tuple: ~w", [{module,?MODULE}]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "6. Printing a pid: ~w", [Pid]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "7. Printing HTML: <pre>~s</pre>", [String]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "8. Printing a pid escaped: ~s", [EscPid]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "9. Printing a string escaped: ~p", [String]), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "10. Printing HTML escaped: <pre>~s</pre>", + [String]), + read_footer(Dev), + match_line(Dev, "11. Printing a string, no css: ~s", [String]), + match_line(Dev, "12. Printing a pid escaped, no css: ~s", [EscPid]), + read_header(Dev, "\"ct_internal\""), + match_line(Dev, "13. Printing with category", []), + read_footer(Dev), + read_header(Dev, "\"ct_internal\""), + match_line(Dev, "14. Printing with ~s", ["category"]), + read_footer(Dev), + match_line(Dev, "15. Printing with ~s, no_css", ["category"]), + read_header(Dev), + match_line(Dev, "16. Printing with importance", []), + read_footer(Dev), + read_header(Dev), + match_line(Dev, "17. Printing with ~s", ["importance"]), + read_footer(Dev), + match_line(Dev, "18. Printing with ~s, no_css", ["importance"]), + read_header(Dev, "\"ct_internal\""), + match_line(Dev, "19. Printing with category and importance", []), + read_footer(Dev), + read_header(Dev, "\"ct_internal\""), + match_line(Dev, "20. Printing with ~s", ["category and importance"]), + read_footer(Dev), + match_line(Dev, "21. Printing a pid escaped with ~s, no_css: ~s", + ["category and importance",EscPid]), + + file:close(Dev), + ok. + +%%%----------------------------------------------------------------- +%%% HELP FUNCTIONS +%%%----------------------------------------------------------------- + +read_until(Dev, Pat) -> + case file:read_line(Dev) of + {ok,Pat} -> + file:read_line(Dev), % \n + ok; + eof -> + file:close(Dev), + {error,{not_found,Pat}}; + _ -> + read_until(Dev, Pat) + end. + +match_line(Dev, Format, Args) -> + Pat = lists:flatten(io_lib:format(Format, Args)), + Line = element(2, file:read_line(Dev)), + case re:run(Line, Pat) of + {match,_} -> + ok; + nomatch -> + ct:pal("ERROR! No match for ~p.\nLine = ~p", [Pat,Line]), + file:close(Dev), + ct:fail({mismatch,Pat,Line}) + end. + +read_header(Dev) -> + read_header(Dev, "\"default\""). + +read_header(Dev, Cat) -> + file:read_line(Dev), % \n + "</pre>\n" = element(2, file:read_line(Dev)), + {match,_} = + re:run(element(2, file:read_line(Dev)), "<div class="++Cat++"><pre><b>" + "\\*\\*\\* User \\d{4}-\\d{2}-\\d{2} " + "\\d{2}:\\d{2}:\\d{2}.\\d{1,} \\*\\*\\*</b>"). + +read_footer(Dev) -> + "</pre></div>\n" = element(2, file:read_line(Dev)), + "<pre>\n" = element(2, file:read_line(Dev)). + +read_nl(Dev) -> + file:read_line(Dev). + + diff --git a/lib/common_test/test/ct_netconfc_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE.erl index 03fbc17bd2..2919f01605 100644 --- a/lib/common_test/test/ct_netconfc_SUITE.erl +++ b/lib/common_test/test/ct_netconfc_SUITE.erl @@ -44,16 +44,28 @@ %% there will be clashes with logging processes etc). %%-------------------------------------------------------------------- init_per_suite(Config) -> - case application:load(crypto) of - {error,Reason} when Reason=/={already_loaded,crypto} -> - {skip, Reason}; - _ -> - case application:load(ssh) of - {error,Reason} when Reason=/={already_loaded,ssh} -> - {skip, Reason}; - _ -> - ct_test_support:init_per_suite(Config) - end + case check_crypto_and_ssh() of + ok -> + ct_test_support:init_per_suite(Config); + Skip -> + Skip + end. + +check_crypto_and_ssh() -> + (catch code:load_file(crypto)), + case code:is_loaded(crypto) of + {file,_} -> + case ssh:start() of + Ok when Ok==ok; Ok=={error,{already_started,ssh}} -> + ct:log("ssh started",[]), + ok; + Other -> + ct:log("could not start ssh: ~p",[Other]), + {skip, "SSH could not be started!"} + end; + Other -> + ct:log("could not load crypto: ~p",[Other]), + {skip, "crypto could not be loaded!"} end. end_per_suite(Config) -> diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl index 065639dd36..2aa6c4d354 100644 --- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl +++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl @@ -123,41 +123,38 @@ init_per_testcase(_Case, Config) -> end_per_testcase(_Case, _Config) -> ok. -init_per_suite() -> - [{timetrap,2*?default_timeout}]. % making dsa files can be slow init_per_suite(Config) -> - case catch ssh:start() of - Ok when Ok==ok; Ok=={error,{already_started,ssh}} -> + (catch code:load_file(crypto)), + case {ssh:start(),code:is_loaded(crypto)} of + {Ok,{file,_}} when Ok==ok; Ok=={error,{already_started,ssh}} -> ct:log("ssh started",[]), - {ok, _} = netconfc_test_lib:get_id_keys(Config), - netconfc_test_lib:make_dsa_files(Config), - ct:log("dsa files created",[]), - Server = ?NS:start(?config(data_dir,Config)), + SshDir = filename:join(filename:dirname(code:which(?MODULE)), + "ssh_dir"), + Server = ?NS:start(SshDir), ct:log("netconf server started",[]), - [{server,Server}|Config]; + [{netconf_server,Server},{ssh_dir,SshDir}|Config]; Other -> - ct:log("could not start ssh: ~p",[Other]), + ct:log("could not start ssh or load crypto: ~p",[Other]), {skip, "SSH could not be started!"} end. end_per_suite(Config) -> - ?NS:stop(?config(server,Config)), + ?NS:stop(?config(netconf_server,Config)), ssh:stop(), crypto:stop(), - netconfc_test_lib:remove_id_keys(Config), Config. hello(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client), ok. hello_from_server_first(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), ?NS:hello(1), - {ok,Client} = ct_netconfc:only_open(?DEFAULT_SSH_OPTS(DataDir)), + {ok,Client} = ct_netconfc:only_open(?DEFAULT_SSH_OPTS(SshDir)), ct:sleep(500), ?NS:expect(hello), ?ok = ct_netconfc:hello(Client, [{capability, ["urn:com:ericsson:ebase:1.1.0"]}], infinity), @@ -166,8 +163,8 @@ hello_from_server_first(Config) -> ok. hello_named(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(any_name,DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(any_name,SshDir), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client), ok. @@ -175,8 +172,8 @@ hello_named(Config) -> hello_configured() -> [{require, netconf1}]. hello_configured(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_configured_success(netconf1,DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_configured_success(netconf1,SshDir), ?NS:expect_do_reply('close-session',close,ok), {error, {no_such_name,netconf1}} = ct_netconfc:close_session(netconf1), ?ok = ct_netconfc:close_session(Client), @@ -185,10 +182,10 @@ hello_configured(Config) -> hello_configured_extraopts() -> [{require, netconf1}]. hello_configured_extraopts(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), %% Test that the cofiguration overwrites the ExtraOpts parameter %% to ct_netconfc:open/2. - {ok,Client} = open_configured_success(netconf1,DataDir,[{password,"faulty"}]), + {ok,Client} = open_configured_success(netconf1,SshDir,[{password,"faulty"}]), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client), ok. @@ -196,8 +193,8 @@ hello_configured_extraopts(Config) -> hello_required() -> [{require, my_named_connection, netconf1}]. hello_required(Config) -> - DataDir = ?config(data_dir,Config), - {ok,_Client} = open_configured_success(my_named_connection,DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,_Client} = open_configured_success(my_named_connection,SshDir), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(my_named_connection), ok. @@ -205,69 +202,69 @@ hello_required(Config) -> hello_required_exists() -> [{require, my_named_connection, netconf1}]. hello_required_exists(Config) -> - DataDir = ?config(data_dir,Config), - {ok,_Client1} = open_configured_success(my_named_connection,DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,_Client1} = open_configured_success(my_named_connection,SshDir), %% Check that same name can not be used twice {error,{connection_exists,_Client1}} = - ct_netconfc:open(my_named_connection,[{user_dir,DataDir}]), + ct_netconfc:open(my_named_connection,[{user_dir,SshDir}]), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(my_named_connection), ct:sleep(500), %% Then check that it can be used again after the first is closed - {ok,_Client2} = open_configured_success(my_named_connection,DataDir), + {ok,_Client2} = open_configured_success(my_named_connection,SshDir), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(my_named_connection), ok. hello_global_pwd(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir,[{user,"any-user"}, + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir,[{user,"any-user"}, {password,"global-xxx"}]), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client), ok. hello_no_session_id(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), ?NS:hello(no_session_id), ?NS:expect(no_session_id,hello), - {error,{incorrect_hello,no_session_id_found}} = open(DataDir), + {error,{incorrect_hello,no_session_id_found}} = open(SshDir), ok. hello_incomp_base_vsn(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), ?NS:hello(1,{base,"1.1"}), ?NS:expect(hello), - {error,{incompatible_base_capability_vsn,"1.1"}} = open(DataDir), + {error,{incompatible_base_capability_vsn,"1.1"}} = open(SshDir), ok. hello_no_base_cap(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), ?NS:hello(1,no_base), ?NS:expect(hello), - {error,{incorrect_hello,no_base_capability_found}} = open(DataDir), + {error,{incorrect_hello,no_base_capability_found}} = open(SshDir), ok. hello_no_caps(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), ?NS:hello(1,no_caps), ?NS:expect(hello), - {error,{incorrect_hello,capabilities_not_found}} = open(DataDir), + {error,{incorrect_hello,capabilities_not_found}} = open(SshDir), ok. no_server_hello(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), ?NS:expect(undefined,hello), - {error,{hello_session_failed,timeout}} = open(DataDir,[{timeout,2000}]), + {error,{hello_session_failed,timeout}} = open(SshDir,[{timeout,2000}]), ok. no_client_hello(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), ?NS:hello(1), - {ok,Client} = ct_netconfc:only_open(?DEFAULT_SSH_OPTS(DataDir)), + {ok,Client} = ct_netconfc:only_open(?DEFAULT_SSH_OPTS(SshDir)), %% Allow server hello to arrive ct:sleep(500), @@ -280,8 +277,8 @@ no_client_hello(Config) -> ok. get_session_id(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), 1 = ct_netconfc:get_session_id(Client), @@ -290,8 +287,8 @@ get_session_id(Config) -> ok. get_capabilities(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), Caps = ct_netconfc:get_capabilities(Client), BaseCap = ?NETCONF_BASE_CAP ++ ?NETCONF_BASE_CAP_VSN, @@ -302,49 +299,49 @@ get_capabilities(Config) -> ok. faulty_user(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), {error,{ssh,could_not_connect_to_server, "Unable to connect using the available authentication methods"}} = - open(DataDir,[{user,"yyy"}]), + open(SshDir,[{user,"yyy"}]), ok. faulty_passwd(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), {error,{ssh,could_not_connect_to_server, "Unable to connect using the available authentication methods"}} = - open(DataDir,[{password,"yyy"}]), + open(SshDir,[{password,"yyy"}]), ok. faulty_port(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), {error,{ssh,could_not_connect_to_server,econnrefused}} = - open(DataDir,[{port,2062}]), + open(SshDir,[{port,2062}]), ok. no_host(Config) -> - DataDir = ?config(data_dir,Config), - Opts = lists:keydelete(ssh,1,?DEFAULT_SSH_OPTS(DataDir)), + SshDir = ?config(ssh_dir,Config), + Opts = lists:keydelete(ssh,1,?DEFAULT_SSH_OPTS(SshDir)), {error,no_host_address} = ct_netconfc:open(Opts), ok. no_port(Config) -> - DataDir = ?config(data_dir,Config), - Opts = lists:keydelete(port,1,?DEFAULT_SSH_OPTS(DataDir)), + SshDir = ?config(ssh_dir,Config), + Opts = lists:keydelete(port,1,?DEFAULT_SSH_OPTS(SshDir)), {error,no_port} = ct_netconfc:open(Opts), ok. invalid_opt(Config) -> - DataDir = ?config(data_dir,Config), - Opts1 = ?DEFAULT_SSH_OPTS(DataDir) ++ [{timeout,invalidvalue}], + SshDir = ?config(ssh_dir,Config), + Opts1 = ?DEFAULT_SSH_OPTS(SshDir) ++ [{timeout,invalidvalue}], {error,{invalid_option,{timeout,invalidvalue}}} = ct_netconfc:open(Opts1), - Opts2 = ?DEFAULT_SSH_OPTS(DataDir) ++ [{some_other_opt,true}], + Opts2 = ?DEFAULT_SSH_OPTS(SshDir) ++ [{some_other_opt,true}], {error,{ssh,could_not_connect_to_server,{options,_}}} = ct_netconfc:open(Opts2), ok. timeout_close_session(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect('close-session'), true = erlang:is_process_alive(Client), {error,timeout} = ct_netconfc:close_session(Client,1000), @@ -352,8 +349,8 @@ timeout_close_session(Config) -> ok. get(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), Data = [{server,[{xmlns,"myns"}],[{name,[],["myserver"]}]}], ?NS:expect_reply('get',{data,Data}), {ok,Data} = ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]}), @@ -362,9 +359,9 @@ get(Config) -> ok. get_a_lot(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), - Descr = lists:append(lists:duplicate(1000,"Description of myserver! ")), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), + Descr = lists:append(lists:duplicate(100,"Description of myserver! ")), Server = {server,[{xmlns,"myns"}],[{name,[],["myserver"]}, {description,[],[Descr]}]}, Data = lists:duplicate(100,Server), @@ -375,8 +372,8 @@ get_a_lot(Config) -> ok. timeout_get(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect('get'), {error,timeout} = ct_netconfc:get(Client,{server,[{xmlns,"myns"}],[]},1000), ?NS:expect_do_reply('close-session',close,ok), @@ -392,8 +389,8 @@ timeout_get(Config) -> %% Note that we can only hope that the test case triggers the problem %% every now and then, as it is very timing dependent... flush_timeout_get(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), Data = [{server,[{xmlns,"myns"}],[{name,[],["myserver"]}]}], ?NS:expect_reply('get',{data,Data}), timer:sleep(1000), @@ -406,8 +403,8 @@ flush_timeout_get(Config) -> ok. get_xpath(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), Data = [{server,[{xmlns,"myns"}],[{name,[],["myserver"]}]}], ?NS:expect_reply({'get',xpath},{data,Data}), {ok,Data} = ct_netconfc:get(Client,{xpath,"/server"}), @@ -416,8 +413,8 @@ get_xpath(Config) -> ok. get_config(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), Data = [{server,[{xmlns,"myns"}],[{name,[],["myserver"]}]}], ?NS:expect_reply('get-config',{data,Data}), {ok,Data} = ct_netconfc:get_config(Client,running, @@ -427,8 +424,8 @@ get_config(Config) -> ok. get_config_xpath(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), Data = [{server,[{xmlns,"myns"}],[{name,[],["myserver"]}]}], ?NS:expect_reply({'get-config',xpath},{data,Data}), {ok,Data} = ct_netconfc:get_config(Client,running,{xpath,"/server"}), @@ -437,8 +434,8 @@ get_config_xpath(Config) -> ok. edit_config(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_reply('edit-config',ok), ?ok = ct_netconfc:edit_config(Client,running, {server,[{xmlns,"myns"}], @@ -448,8 +445,8 @@ edit_config(Config) -> ok. edit_config_opt_params(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_reply({'edit-config',{'default-operation',"none"}},ok), ?ok = ct_netconfc:edit_config(Client,running, {server,[{xmlns,"myns"}], @@ -460,8 +457,8 @@ edit_config_opt_params(Config) -> ok. copy_config(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_reply('copy-config',ok), ?ok = ct_netconfc:copy_config(Client,startup,running), ?NS:expect_do_reply('close-session',close,ok), @@ -469,8 +466,8 @@ copy_config(Config) -> ok. delete_config(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_reply('delete-config',ok), ?ok = ct_netconfc:delete_config(Client,startup), ?NS:expect_do_reply('close-session',close,ok), @@ -478,8 +475,8 @@ delete_config(Config) -> ok. lock(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_reply('lock',ok), ?ok = ct_netconfc:lock(Client,running), ?NS:expect_do_reply('close-session',close,ok), @@ -487,8 +484,8 @@ lock(Config) -> ok. unlock(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_reply('unlock',ok), ?ok = ct_netconfc:unlock(Client,running), ?NS:expect_do_reply('close-session',close,ok), @@ -496,12 +493,12 @@ unlock(Config) -> ok. kill_session(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:hello(2), ?NS:expect(2,hello), - {ok,_OtherClient} = open(DataDir), + {ok,_OtherClient} = open(SshDir), ?NS:expect_do_reply('kill-session',{kill,2},ok), ?ok = ct_netconfc:kill_session(Client,2), @@ -512,8 +509,8 @@ kill_session(Config) -> ok. get_no_such_client(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client), @@ -529,8 +526,8 @@ get_no_such_client(Config) -> ok. action(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), Data = [{myactionreturn,[{xmlns,"myns"}],["value"]}], %% test either to receive {data,Data} or {ok,Data}, %% both need to be handled @@ -549,8 +546,8 @@ action(Config) -> ok. send_any_rpc(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), Data = [{server,[{xmlns,"myns"}],[{name,[],["myserver"]}]}], GetConf = {'get-config', [{source,["running"]}, @@ -571,8 +568,8 @@ send_any_rpc(Config) -> ok. send_any(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), %% Correct get-config rpc Data = [{server,[{xmlns,"myns"}],[{name,[],["myserver"]}]}], @@ -604,8 +601,8 @@ send_any(Config) -> ok. hide_password(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), Password = "my_very_secret_password", Data = [{passwords,[{xmlns,"myns"}], [{password,[{xmlns,"pwdns"}],[Password]}, @@ -633,8 +630,8 @@ hide_password(Config) -> ok. not_proper_xml(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), NS = list_to_binary(?NETCONF_NAMESPACE), NotProper = <<"<rpc-reply message-id=\"1\" xmlns=\"", NS/binary,"\"><data></rpc-reply>">>, @@ -646,8 +643,8 @@ not_proper_xml(Config) -> ok. prefixed_namespace(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), NS = list_to_binary(?NETCONF_NAMESPACE), %% Test that data element can be properly decoded and that @@ -679,8 +676,8 @@ prefixed_namespace(Config) -> %% i.e. when the complete rpc-reply is not contained in one single ssh %% data message. receive_chunked_data(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), %% Construct the data to return from netconf server Data = [{servers,[{xmlns,"myns"}], @@ -727,8 +724,8 @@ receive_chunked_data(Config) -> %% Same as receive_chunked_data, but timeout waiting for last part. timeout_receive_chunked_data(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), %% Construct the data to return from netconf server Data = [{servers,[{xmlns,"myns"}], @@ -773,8 +770,8 @@ timeout_receive_chunked_data(Config) -> %% Same as receive_chunked_data, but close while waiting for last part. close_while_waiting_for_chunked_data(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), %% Construct the data to return from netconf server Data = [{servers,[{xmlns,"myns"}], @@ -816,8 +813,8 @@ close_while_waiting_for_chunked_data(Config) -> ok. connection_crash(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), %% Test that if the test survives killing the connection %% process. Earlier this caused ct_util_server to terminate, and @@ -828,8 +825,8 @@ connection_crash(Config) -> ok. get_event_streams(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), StreamNames = ["NETCONF","stream1","stream2"], Streams = [{N,[{description,"descr of " ++ N}]} || N <- StreamNames], StreamsXml = [{stream,[{name,[N]}|[{Tag,[Value]} || {Tag,Value} <- Data]]} @@ -849,31 +846,31 @@ get_event_streams(Config) -> ok. create_subscription(Config) -> - DataDir = ?config(data_dir,Config), + SshDir = ?config(ssh_dir,Config), %% All defaults - {ok,Client1} = open_success(DataDir), + {ok,Client1} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream]},ok), ?ok = ct_netconfc:create_subscription(Client1), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client1), %% All defaults with timeout - {ok,Client1a} = open_success(DataDir), + {ok,Client1a} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream]},ok), ?ok = ct_netconfc:create_subscription(Client1a,5000), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client1a), %% All defaults timing out - {ok,Client1b} = open_success(DataDir), + {ok,Client1b} = open_success(SshDir), ?NS:expect({'create-subscription',[stream]}), {error,timeout} = ct_netconfc:create_subscription(Client1b,100), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client1b), %% Stream - {ok,Client2} = open_success(DataDir), + {ok,Client2} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream]},ok), Stream = "some_stream", ?ok = ct_netconfc:create_subscription(Client2,Stream), @@ -881,7 +878,7 @@ create_subscription(Config) -> ?ok = ct_netconfc:close_session(Client2), %% Filter - {ok,Client3} = open_success(DataDir), + {ok,Client3} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream,filter]},ok), Filter = {notification,?NETMOD_NOTIF_NAMESPACE_ATTR, [eventTime]}, @@ -890,28 +887,28 @@ create_subscription(Config) -> ?ok = ct_netconfc:close_session(Client3), %% Filter with timeout - {ok,Client3a} = open_success(DataDir), + {ok,Client3a} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream,filter]},ok), ?ok = ct_netconfc:create_subscription(Client3a,Filter,5000), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client3a), %% Filter timing out - {ok,Client3b} = open_success(DataDir), + {ok,Client3b} = open_success(SshDir), ?NS:expect({'create-subscription',[stream,filter]}), {error,timeout}=ct_netconfc:create_subscription(Client3b,Filter,100), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client3b), %% Stream and filter - {ok,Client4} = open_success(DataDir), + {ok,Client4} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream,filter]},ok), ?ok = ct_netconfc:create_subscription(Client4,Stream,Filter), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client4), %% Start/stop time - {ok,Client5} = open_success(DataDir), + {ok,Client5} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream,startTime,stopTime]},ok), StartTime = xs_datetime({D,{H,M,S}}= calendar:local_time()), StopTime = xs_datetime({D,{H+2,M,S}}), @@ -920,14 +917,14 @@ create_subscription(Config) -> ?ok = ct_netconfc:close_session(Client5), %% Start/stop time with timeout - {ok,Client5a} = open_success(DataDir), + {ok,Client5a} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream,startTime,stopTime]},ok), ?ok = ct_netconfc:create_subscription(Client5a,StartTime,StopTime,5000), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client5a), %% Start/stop time timing out - {ok,Client5b} = open_success(DataDir), + {ok,Client5b} = open_success(SshDir), ?NS:expect({'create-subscription',[stream,startTime,stopTime]}), {error,timeout} = ct_netconfc:create_subscription(Client5b,StartTime,StopTime,100), @@ -935,14 +932,14 @@ create_subscription(Config) -> ?ok = ct_netconfc:close_session(Client5b), %% Stream and start/stop time - {ok,Client6} = open_success(DataDir), + {ok,Client6} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream,startTime,stopTime]},ok), ?ok = ct_netconfc:create_subscription(Client6,Stream,StartTime,StopTime), ?NS:expect_do_reply('close-session',close,ok), ?ok = ct_netconfc:close_session(Client6), %% Filter and start/stop time - {ok,Client7} = open_success(DataDir), + {ok,Client7} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream,filter,startTime,stopTime]}, ok), ?ok = ct_netconfc:create_subscription(Client7,Filter, @@ -951,7 +948,7 @@ create_subscription(Config) -> ?ok = ct_netconfc:close_session(Client7), %% Stream, filter and start/stop time - {ok,Client8} = open_success(DataDir), + {ok,Client8} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream,filter,startTime,stopTime]}, ok), ?ok = ct_netconfc:create_subscription(Client8,Stream,Filter, @@ -960,7 +957,7 @@ create_subscription(Config) -> ?ok = ct_netconfc:close_session(Client8), %% Multiple filters - {ok,Client9} = open_success(DataDir), + {ok,Client9} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream,filter]},ok), MultiFilters = [{event,[{xmlns,"http://my.namespaces.com/event"}], [{eventClass,["fault"]}, @@ -975,8 +972,8 @@ create_subscription(Config) -> ok. receive_one_event(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream]},ok), ?ok = ct_netconfc:create_subscription(Client), @@ -1002,8 +999,8 @@ receive_one_event(Config) -> ok. receive_multiple_events(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream]},ok), ?ok = ct_netconfc:create_subscription(Client), @@ -1043,8 +1040,8 @@ receive_multiple_events(Config) -> ok. receive_event_and_rpc(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream]},ok), ?ok = ct_netconfc:create_subscription(Client), @@ -1103,8 +1100,8 @@ receive_event_and_rpc(Config) -> receive_event_and_rpc_in_chunks(Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(DataDir), + SshDir = ?config(ssh_dir,Config), + {ok,Client} = open_success(SshDir), ?NS:expect_reply({'create-subscription',[stream]},ok), ?ok = ct_netconfc:create_subscription(Client), diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl index 04bfe75187..a65275da43 100644 --- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl +++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_remote_SUITE.erl @@ -51,7 +51,7 @@ init_per_testcase(Case, Config) -> stop_node(Case), Config. -end_per_testcase(Case, Config) -> +end_per_testcase(Case, _Config) -> stop_node(Case), ok. @@ -61,25 +61,22 @@ stop_node(Case) -> rpc:call(Node,erlang,halt,[]). -init_per_suite() -> - [{timetrap,2*?default_timeout}]. % making dsa files can be slow init_per_suite(Config) -> - case ssh:start() of - Ok when Ok==ok; Ok=={error,{already_started,ssh}} -> + (catch code:load_file(crypto)), + case {ssh:start(),code:is_loaded(crypto)} of + {Ok,{file,_}} when Ok==ok; Ok=={error,{already_started,ssh}} -> ct:log("SSH started locally",[]), - {ok, _} = netconfc_test_lib:get_id_keys(Config), - netconfc_test_lib:make_dsa_files(Config), - ct:log("dsa files created",[]), - Config; + SshDir = filename:join(filename:dirname(code:which(?MODULE)), + "ssh_dir"), + [{ssh_dir,SshDir}|Config]; Other -> - ct:log("could not start ssh locally: ~p",[Other]), + ct:log("could not start ssh or load crypto locally: ~p",[Other]), {skip, "SSH could not be started locally!"} end. end_per_suite(Config) -> ssh:stop(), crypto:stop(), - netconfc_test_lib:remove_id_keys(Config), Config. %% This test case is related to seq12645 @@ -89,21 +86,20 @@ remote_crash(Config) -> {ok,Node} = ct_slave:start(nc_remote_crash), Pa = filename:dirname(code:which(?NS)), true = rpc:call(Node,code,add_patha,[Pa]), - - case rpc:call(Node,ssh,start,[]) of - Ok when Ok==ok; Ok=={error,{already_started,ssh}} -> + rpc:call(Node,code,load_file,[crypto]), + case {rpc:call(Node,ssh,start,[]),rpc:call(Node,code,is_loaded,[crypto])} of + {Ok,{file,_}} when Ok==ok; Ok=={error,{already_started,ssh}} -> ct:log("SSH started remote",[]), - Server = rpc:call(Node,?NS,start,[?config(data_dir,Config)]), + ns(Node,start,[?config(ssh_dir,Config)]), ct:log("netconf server started remote",[]), remote_crash(Node,Config); Other -> - ct:log("could not start ssh remote: ~p",[Other]), + ct:log("could not start ssh or load crypto remote: ~p",[Other]), {skip, "SSH could not be started remote!"} end. remote_crash(Node,Config) -> - DataDir = ?config(data_dir,Config), - {ok,Client} = open_success(Node,DataDir), + {ok,Client} = open_success(Node,?config(ssh_dir,Config)), ns(Node,expect_reply,[{'create-subscription',[stream]},ok]), ?ok = ct_netconfc:create_subscription(Client), diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl deleted file mode 100644 index e058bc7600..0000000000 --- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl +++ /dev/null @@ -1,166 +0,0 @@ --module(netconfc_test_lib). - --export([get_id_keys/1, remove_id_keys/1, make_dsa_files/1]). --include_lib("common_test/include/ct.hrl"). --include_lib("public_key/include/public_key.hrl"). - -%%%----------------------------------------------------------------- -%%% BEGIN SSH key management -%% copy private keys to given dir from ~/.ssh -get_id_keys(Config) -> - DstDir = ?config(priv_dir, Config), - SrcDir = filename:join(os:getenv("HOME"), ".ssh"), - RsaOk = copyfile(SrcDir, DstDir, "id_rsa"), - DsaOk = copyfile(SrcDir, DstDir, "id_dsa"), - case {RsaOk, DsaOk} of - {{ok, _}, {ok, _}} -> {ok, both}; - {{ok, _}, _} -> {ok, rsa}; - {_, {ok, _}} -> {ok, dsa}; - {Error, _} -> Error - end. - -%% Remove later on. Use make_dsa_files instead. -remove_id_keys(Config) -> - Dir = ?config(priv_dir, Config), - file:delete(filename:join(Dir, "id_rsa")), - file:delete(filename:join(Dir, "id_dsa")). - - -make_dsa_files(Config) -> - make_dsa_files(Config, rfc4716_public_key). -make_dsa_files(Config, Type) -> - {DSA, EncodedKey} = gen_dsa(128, 20), - PKey = DSA#'DSAPrivateKey'.y, - P = DSA#'DSAPrivateKey'.p, - Q = DSA#'DSAPrivateKey'.q, - G = DSA#'DSAPrivateKey'.g, - Dss = #'Dss-Parms'{p=P, q=Q, g=G}, - {ok, Hostname} = inet:gethostname(), - {ok, {A, B, C, D}} = inet:getaddr(Hostname, inet), - IP = lists:concat([A, ".", B, ".", C, ".", D]), - Attributes = [], % Could be [{comment,"user@" ++ Hostname}], - HostNames = [{hostnames,[IP, IP]}], - PublicKey = [{{PKey, Dss}, Attributes}], - KnownHosts = [{{PKey, Dss}, HostNames}], - - KnownHostsEnc = public_key:ssh_encode(KnownHosts, known_hosts), - KnownHosts = public_key:ssh_decode(KnownHostsEnc, known_hosts), - - PublicKeyEnc = public_key:ssh_encode(PublicKey, Type), - - SystemTmpDir = ?config(data_dir, Config), - filelib:ensure_dir(SystemTmpDir), - file:make_dir(SystemTmpDir), - - DSAFile = filename:join(SystemTmpDir, "ssh_host_dsa_key.pub"), - file:delete(DSAFile), - - DSAPrivateFile = filename:join(SystemTmpDir, "ssh_host_dsa_key"), - file:delete(DSAPrivateFile), - - KHFile = filename:join(SystemTmpDir, "known_hosts"), - file:delete(KHFile), - - PemBin = public_key:pem_encode([EncodedKey]), - - file:write_file(DSAFile, PublicKeyEnc), - file:write_file(KHFile, KnownHostsEnc), - file:write_file(DSAPrivateFile, PemBin), - ok. - - -%%-------------------------------------------------------------------- -%% @doc Creates a dsa key (OBS: for testing only) -%% the sizes are in bytes -%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()} -%% @end -%%-------------------------------------------------------------------- -gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) -> - Key = gen_dsa2(LSize, NSize), - {Key, encode_key(Key)}. - -encode_key(Key = #'DSAPrivateKey'{}) -> - Der = public_key:der_encode('DSAPrivateKey', Key), - {'DSAPrivateKey', Der, not_encrypted}. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% DSA key generation (OBS: for testing only) -%% See http://en.wikipedia.org/wiki/Digital_Signature_Algorithm -%% and the fips_186-3.pdf -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -gen_dsa2(LSize, NSize) -> - Q = prime(NSize), %% Choose N-bit prime Q - X0 = prime(LSize), - P0 = prime((LSize div 2) +1), - - %% Choose L-bit prime modulus P such that p-1 is a multiple of q. - case dsa_search(X0 div (2*Q*P0), P0, Q, 1000) of - error -> - gen_dsa2(LSize, NSize); - P -> - G = crypto:mod_pow(2, (P-1) div Q, P), % Choose G a number whose multiplicative order modulo p is q. - %% such that This may be done by setting g = h^(p-1)/q mod p, commonly h=2 is used. - - X = prime(20), %% Choose x by some random method, where 0 < x < q. - Y = crypto:mod_pow(G, X, P), %% Calculate y = g^x mod p. - - #'DSAPrivateKey'{version=0, p = P, q = Q, - g = crypto:bytes_to_integer(G), y = crypto:bytes_to_integer(Y), x = X} - end. - -%% See fips_186-3.pdf -dsa_search(T, P0, Q, Iter) when Iter > 0 -> - P = 2*T*Q*P0 + 1, - case is_prime(P, 50) of - true -> P; - false -> dsa_search(T+1, P0, Q, Iter-1) - end; -dsa_search(_,_,_,_) -> - error. - - -%%%%%%% Crypto Math %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -prime(ByteSize) -> - Rand = odd_rand(ByteSize), - prime_odd(Rand, 0). - -prime_odd(Rand, N) -> - case is_prime(Rand, 50) of - true -> - Rand; - false -> - prime_odd(Rand+2, N+1) - end. - -%% see http://en.wikipedia.org/wiki/Fermat_primality_test -is_prime(_, 0) -> true; -is_prime(Candidate, Test) -> - CoPrime = odd_rand(10000, Candidate), - Result = crypto:mod_pow(CoPrime, Candidate, Candidate) , - is_prime(CoPrime, crypto:bytes_to_integer(Result), Candidate, Test). - -is_prime(CoPrime, CoPrime, Candidate, Test) -> - is_prime(Candidate, Test-1); -is_prime(_,_,_,_) -> - false. - -odd_rand(Size) -> - Min = 1 bsl (Size*8-1), - Max = (1 bsl (Size*8))-1, - odd_rand(Min, Max). - -odd_rand(Min,Max) -> - Rand = crypto:rand_uniform(Min,Max), - case Rand rem 2 of - 0 -> - Rand + 1; - _ -> - Rand - end. - -copyfile(SrcDir, DstDir, Fn) -> - file:copy(filename:join(SrcDir, Fn), - filename:join(DstDir, Fn)). - -%%% END SSH key management -%%%----------------------------------------------------------------- diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl b/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl index 9fb1fb6547..e62bc617fa 100644 --- a/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl +++ b/lib/common_test/test/ct_netconfc_SUITE_data/ns.erl @@ -279,7 +279,7 @@ send({CM,Ch},Data) -> %%% Split into many small parts and send to client send_frag({CM,Ch},Data) -> - Sz = rand:uniform(2000), + Sz = rand:uniform(1000), case Data of <<Chunk:Sz/binary,Rest/binary>> -> ssh_connection:send(CM, Ch, Chunk), diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/ssh_dir/ssh_host_dsa_key b/lib/common_test/test/ct_netconfc_SUITE_data/ssh_dir/ssh_host_dsa_key new file mode 100644 index 0000000000..4ee0b8657e --- /dev/null +++ b/lib/common_test/test/ct_netconfc_SUITE_data/ssh_dir/ssh_host_dsa_key @@ -0,0 +1,13 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBvQIBAAKBgQDuGhXsDoUC/x98Q1KEgdf+pQjzBXFu0gMf6C2P47FILALVjvzt +HvpXarT8Y0XZb4/i5XndcKazmRArEVmPzRT0Pp7gSJpOclY/f1YrplvtMjeQaZ/Y +eD5JoQFpgIUduiifdRRt0r5gXYejCfACa+ZSFiXTvI+ZXpHC7rH+qRCRdwIVAL6Z +VUd15Rm/C4NrLD/nIL8tnnE3AoGBAOo9qlMBtN1MdmvJZ+Pa/x8O5+VxQvAVNysb +DDIZQtT58ko5r3sRA783zHtUft80FA8pUAhkrnRKnqn+bK42Xrm/IMXJd8Wi9LBy +pN5Pg37B/k6pXs2qzLDYnCCBEW9EBBUn6fyZMK7DDs/BTU7Rf0dCh1/YsxRrm0yJ +reFOd+1gAoGBAJTq0lPrrUB62NXllTbVNAusIQX870BHBHuo3K3OFYGYD85z1gwy +e495snKyYOT9QfkBiuH/VGxP2BgIQH+cr5hTWsFZ/09mdhEC5sj/bVDrhwexklVx +ZeHxpIVmpB97jXomdXVR2ZoP92Gco+qU8tXcBdopQQcybk5j4fUxa+KQAhUAmGWZ +bHhbiRb/ip5oN6edhUe47TU= +-----END DSA PRIVATE KEY----- + diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/ssh_dir/ssh_host_dsa_key.pub b/lib/common_test/test/ct_netconfc_SUITE_data/ssh_dir/ssh_host_dsa_key.pub new file mode 100644 index 0000000000..bca37299b0 --- /dev/null +++ b/lib/common_test/test/ct_netconfc_SUITE_data/ssh_dir/ssh_host_dsa_key.pub @@ -0,0 +1,11 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +AAAAB3NzaC1kc3MAAACBAO4aFewOhQL/H3xDUoSB1/6lCPMFcW7SAx/oLY/jsUgsAtWO +/O0e+ldqtPxjRdlvj+Lled1wprOZECsRWY/NFPQ+nuBImk5yVj9/ViumW+0yN5Bpn9h4 +PkmhAWmAhR26KJ91FG3SvmBdh6MJ8AJr5lIWJdO8j5lekcLusf6pEJF3AAAAFQC+mVVH +deUZvwuDayw/5yC/LZ5xNwAAAIEA6j2qUwG03Ux2a8ln49r/Hw7n5XFC8BU3KxsMMhlC +1PnySjmvexEDvzfMe1R+3zQUDylQCGSudEqeqf5srjZeub8gxcl3xaL0sHKk3k+DfsH+ +TqlezarMsNicIIERb0QEFSfp/JkwrsMOz8FNTtF/R0KHX9izFGubTImt4U537WAAAACB +AJTq0lPrrUB62NXllTbVNAusIQX870BHBHuo3K3OFYGYD85z1gwye495snKyYOT9QfkB +iuH/VGxP2BgIQH+cr5hTWsFZ/09mdhEC5sj/bVDrhwexklVxZeHxpIVmpB97jXomdXVR +2ZoP92Gco+qU8tXcBdopQQcybk5j4fUxa+KQ +---- END SSH2 PUBLIC KEY ---- diff --git a/lib/common_test/test/ct_repeat_testrun_SUITE.erl b/lib/common_test/test/ct_repeat_testrun_SUITE.erl index 632597c214..f8b6a379f6 100644 --- a/lib/common_test/test/ct_repeat_testrun_SUITE.erl +++ b/lib/common_test/test/ct_repeat_testrun_SUITE.erl @@ -66,25 +66,47 @@ %% there will be clashes with logging processes etc). %%-------------------------------------------------------------------- init_per_suite(Config0) -> - Config = ct_test_support:init_per_suite(Config0), - DataDir = ?config(data_dir, Config), - Suite1 = filename:join([DataDir,"a_test","r1_SUITE"]), - Suite2 = filename:join([DataDir,"b_test","r2_SUITE"]), - Opts0 = ct_test_support:get_opts(Config), - Opts1 = Opts0 ++ [{suite,Suite1},{testcase,tc2},{label,timing1}], - Opts2 = Opts0 ++ [{suite,Suite2},{testcase,tc2},{label,timing2}], - - %% Make sure both suites are compiled - {1,0,{0,0}} = ct_test_support:run(ct,run_test,[Opts1],Config), - {1,0,{0,0}} = ct_test_support:run(ct,run_test,[Opts2],Config), - - %% Time the shortest testcase to use for offset - {_T0,{1,0,{0,0}}} = timer:tc(ct_test_support,run,[ct,run_test,[Opts1],Config]), - - %% -2 is to ensure we hit inside the target test case and not after -% T = round(T0/1000000)-2, - T=0, - [{offset,T}|Config]. + TTInfo = {_T,{_Scaled,ScaleVal}} = ct:get_timetrap_info(), + ct:pal("Timetrap info = ~w", [TTInfo]), + if ScaleVal > 1 -> + {skip,"Skip on systems running e.g. cover or debug!"}; + ScaleVal =< 1 -> + Config = ct_test_support:init_per_suite(Config0), + DataDir = ?config(data_dir, Config), + Suite1 = filename:join([DataDir,"a_test","r1_SUITE"]), + Suite2 = filename:join([DataDir,"b_test","r2_SUITE"]), + Opts0 = ct_test_support:get_opts(Config), + Opts1 = Opts0 ++ [{suite,Suite1},{testcase,tc2},{label,timing1}], + Opts2 = Opts0 ++ [{suite,Suite2},{testcase,tc2},{label,timing2}], + + %% Make sure both suites are compiled + {1,0,{0,0}} = ct_test_support:run(ct,run_test,[Opts1],Config), + {1,0,{0,0}} = ct_test_support:run(ct,run_test,[Opts2],Config), + + %% Check if file i/o is too slow for correct measurements + Opts3 = Opts0 ++ [{suite,Suite1},{testcase,tc1},{label,timing3}], + {T,_} = + timer:tc( + fun() -> + {1,0,{0,0}} = ct_test_support:run(ct,run_test, + [Opts3],Config), + {1,0,{0,0}} = ct_test_support:run(ct,run_test, + [Opts3],Config) + end), + %% The time to compare with here must match the timeout value + %% in the test suite. Accept 30% logging overhead (26 sec total). + if T > 26000000 -> + ct:pal("Timing test took ~w sec (< 27 sec expected). " + "Skipping the suite!", + [trunc(T/1000000)]), + ct_test_support:end_per_suite(Config), + {skip,"File I/O too slow for this suite"}; + true -> + ct:pal("Timing test took ~w sec. Proceeding...", + [trunc(T/1000000)]), + [{offset,0}|Config] + end + end. end_per_suite(Config) -> ct_test_support:end_per_suite(Config). 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 9dc9095f47..985fa40ad2 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 @@ -308,8 +308,19 @@ large_string(_) -> VerifyStr = [C || C <- lists:flatten(Data1), C/=$ , C/=$\r, C/=$\n, C/=$>], ok = ct_telnet:send(Handle, "echo_sep "++BigString), - ct:sleep(50), - {ok,Data2} = ct_telnet:get_data(Handle), + %% On some slow machines, 50 ms might not be enough to get the + %% first packet of data. We will therefore keep trying for a + %% second before we give up this... + F = fun RepeatUntilData(N) -> + ct:sleep(50), + case ct_telnet:get_data(Handle) of + {ok,[]} when N>1 -> + RepeatUntilData(N-1); + Other -> + Other + end + end, + {ok,Data2} = F(20), ct:log("[GET DATA #2] Received ~w chars: ~s", [length(lists:flatten(Data2)),Data2]), VerifyStr = [C || C <- lists:flatten(Data2), C/=$ , C/=$\r, C/=$\n, C/=$>], diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl index 477fcb8a26..e926abd885 100644 --- a/lib/common_test/test/ct_test_support.erl +++ b/lib/common_test/test/ct_test_support.erl @@ -484,7 +484,8 @@ get_events(_, Config) -> {event_receiver,CTNode} ! {self(),get_events}, Events = receive {event_receiver,Evs} -> Evs end, test_server:format(Level, "Stopping event receiver!~n", []), - {event_receiver,CTNode} ! stop, + {event_receiver,CTNode} ! {self(),stop}, + receive {event_receiver,stopped} -> ok end, Events. er() -> @@ -499,8 +500,9 @@ er_loop(Evs) -> {From,get_events} -> From ! {event_receiver,lists:reverse(Evs)}, er_loop(Evs); - stop -> + {From,stop} -> unregister(event_receiver), + From ! {event_receiver,stopped}, ok end. diff --git a/lib/common_test/test/telnet_server.erl b/lib/common_test/test/telnet_server.erl index 107d98d72c..65300b0bdf 100644 --- a/lib/common_test/test/telnet_server.erl +++ b/lib/common_test/test/telnet_server.erl @@ -59,7 +59,7 @@ init(Opts) -> accept(State), ok = gen_tcp:close(LSock), dbg("telnet_server closed the listen socket ~p\n", [LSock]), - ct:sleep(1000), + timer:sleep(1000), ok. listen(0, _Port, _Opts) -> @@ -68,7 +68,7 @@ listen(Retries, Port, Opts) -> case gen_tcp:listen(Port, Opts) of {error,eaddrinuse} -> dbg("Listen port not released, trying again..."), - ct:sleep(5000), + timer:sleep(5000), listen(Retries-1, Port, Opts); Ok = {ok,_LSock} -> Ok; @@ -117,38 +117,64 @@ init_client(#state{client=Sock}=State) -> dbg("Server sending: ~p~n",["login: "]), R = case gen_tcp:send(Sock,"login: ") of ok -> - loop(State, 1); + loop(State); Error -> Error end, _ = gen_tcp:close(Sock), R. -loop(State, N) -> +loop(State=#state{client=Sock}) -> receive - {tcp,_,Data} -> + {tcp,Sock,Data} -> try handle_data(Data,State) of {ok,State1} -> - loop(State1, N); + loop(State1); closed -> + _ = flush(State), closed catch throw:Error -> + _ = flush(State), Error end; - {tcp_closed, _} -> + {tcp_closed,Sock} -> closed; - {tcp_error,_,Error} -> + {tcp_error,Sock,Error} -> {error,tcp,Error}; disconnect -> - Sock = State#state.client, dbg("Server closing connection on socket ~p~n", [Sock]), + timer:sleep(1000), ok = gen_tcp:close(Sock), - closed; + _ = flush(State); stop -> + _ = flush(State), stopped end. +flush(State=#state{client=Sock}) -> + receive + {tcp,Sock,Data} = M-> + dbg("Message flushed after close or error: ~p~n", [M]), + try handle_data(Data,State) of + {ok,State1} -> + flush(State1); + closed -> + flush(State) + catch + throw:Error -> + Error + end; + {tcp_closed,Sock} = M -> + dbg("Message flushed after close or error: ~p~n", [M]), + ok; + {tcp_error,Sock,Error} = M -> + dbg("Message flushed after close or error: ~p~n", [M]), + {error,tcp,Error} + after 100 -> + ok + end. + handle_data(Cmd,#state{break=true}=State) -> dbg("Server got data when in break mode: ~p~n",[Cmd]), handle_break_cmd(Cmd,State); @@ -193,6 +219,9 @@ handle_cmd([?AYT|T],State) -> %% Used when testing 'newline' option in ct_telnet:send and ct_telnet:cmd. send("yes\r\n> ",State), handle_data(T,State); +handle_cmd([?NOP|T],State) -> + %% Used for 'keep alive' + handle_data(T,State); handle_cmd([_H|T],State) -> %% Not responding to this command handle_cmd(T,State); @@ -203,6 +232,9 @@ handle_break_cmd([$q|T],State) -> %% Dummy cmd allowed in break mode - quit break mode send("\r\n> ",State), handle_data(T,State#state{break=false}); +handle_break_cmd([_H|T],State) -> + %% Unknown command i break mode - ignore + handle_break_cmd(T,State); handle_break_cmd([],State) -> {ok,State}. @@ -220,7 +252,7 @@ do_handle_data("echo_sep " ++ Data,State) -> Msgs = string:tokens(Data," "), lists:foreach(fun(Msg) -> send(Msg,State), - ct:sleep(10) + timer:sleep(10) end, Msgs), send("\r\n> ",State), {ok,State}; @@ -245,7 +277,7 @@ do_handle_data("echo_loop " ++ Data,State) -> do_handle_data("echo_delayed_prompt "++Data,State) -> [MsStr|EchoData] = string:tokens(Data, " "), send(string:join(EchoData,"\n"),State), - ct:sleep(list_to_integer(MsStr)), + timer:sleep(list_to_integer(MsStr)), send("\r\n> ",State), {ok,State}; do_handle_data("disconnect_after " ++WaitStr,State) -> @@ -298,7 +330,7 @@ send_loop(T0,T,Data,State) -> ok; true -> send(Data,State), - ct:sleep(500), + timer:sleep(500), send_loop(T0,T,Data,State) end. |