diff options
Diffstat (limited to 'lib/ssh/test')
-rw-r--r-- | lib/ssh/test/Makefile | 4 | ||||
-rw-r--r-- | lib/ssh/test/ssh.spec.vxworks | 3 | ||||
-rw-r--r-- | lib/ssh/test/ssh_basic_SUITE.erl | 381 | ||||
-rw-r--r-- | lib/ssh/test/ssh_connection_SUITE.erl | 313 | ||||
-rw-r--r-- | lib/ssh/test/ssh_connection_SUITE_data/ssh_host_rsa_key | 15 | ||||
-rw-r--r-- | lib/ssh/test/ssh_echo_server.erl | 71 | ||||
-rw-r--r-- | lib/ssh/test/ssh_sftp_SUITE.erl | 376 | ||||
-rw-r--r-- | lib/ssh/test/ssh_sftpd_SUITE.erl | 343 | ||||
-rw-r--r-- | lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl | 178 | ||||
-rw-r--r-- | lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl | 4 | ||||
-rw-r--r-- | lib/ssh/test/ssh_test_lib.erl | 19 | ||||
-rw-r--r-- | lib/ssh/test/ssh_to_openssh_SUITE.erl | 234 |
12 files changed, 1036 insertions, 905 deletions
diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile index 25072688ad..f5db31baee 100644 --- a/lib/ssh/test/Makefile +++ b/lib/ssh/test/Makefile @@ -36,7 +36,9 @@ MODULES= \ ssh_to_openssh_SUITE \ ssh_sftp_SUITE \ ssh_sftpd_SUITE \ - ssh_sftpd_erlclient_SUITE + ssh_sftpd_erlclient_SUITE \ + ssh_connection_SUITE \ + ssh_echo_server HRL_FILES_NEEDED_IN_TEST= \ $(ERL_TOP)/lib/ssh/src/ssh.hrl \ diff --git a/lib/ssh/test/ssh.spec.vxworks b/lib/ssh/test/ssh.spec.vxworks deleted file mode 100644 index 81f665283c..0000000000 --- a/lib/ssh/test/ssh.spec.vxworks +++ /dev/null @@ -1,3 +0,0 @@ -{topcase, {dir, "../ssh_test"}}. -{require_nodenames, 1}. -%{skip, {M, F, "Not yet implemented"}}. diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl index 2ceaa9daa5..93029c5038 100644 --- a/lib/ssh/test/ssh_basic_SUITE.erl +++ b/lib/ssh/test/ssh_basic_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -22,7 +22,6 @@ -module(ssh_basic_SUITE). -include_lib("common_test/include/ct.hrl"). --include("test_server_line.hrl"). %% Note: This directive should only be used in test suites. -compile(export_all). @@ -30,78 +29,12 @@ -define(NEWLINE, <<"\r\n">>). %%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initialization before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - case catch crypto:start() of - ok -> - Config; - _Else -> - {skip, "Crypto could not be started!"} - end. - -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite +%% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- -end_per_suite(_Config) -> - ssh:stop(), - crypto:stop(), - ok. -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initialization before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initialization before each test case -%%-------------------------------------------------------------------- -init_per_testcase(_TestCase, Config) -> - ssh:start(), - Config. +suite() -> + [{ct_hooks,[ts_install_cth]}]. -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- - -end_per_testcase(TestCase, Config) when TestCase == server_password_option; - TestCase == server_userpassword_option -> - UserDir = filename:join(?config(priv_dir, Config), nopubkey), - ssh_test_lib:del_dirs(UserDir), - end_per_testcase(Config); -end_per_testcase(_TestCase, Config) -> - end_per_testcase(Config). -end_per_testcase(_Config) -> - ssh:stop(), - ok. - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- all() -> [app_test, {group, dsa_key}, @@ -110,17 +43,29 @@ all() -> {group, rsa_pass_key}, {group, internal_error}, daemon_already_started, - server_password_option, server_userpassword_option, + server_password_option, + server_userpassword_option, close]. groups() -> - [{dsa_key, [], [exec, exec_compressed, shell, known_hosts]}, - {rsa_key, [], [exec, exec_compressed, shell, known_hosts]}, + [{dsa_key, [], [send, exec, exec_compressed, shell, known_hosts, idle_time, rekey]}, + {rsa_key, [], [send, exec, exec_compressed, shell, known_hosts, idle_time, rekey]}, {dsa_pass_key, [], [pass_phrase]}, {rsa_pass_key, [], [pass_phrase]}, {internal_error, [], [internal_error]} ]. - +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + case catch crypto:start() of + ok -> + Config; + _Else -> + {skip, "Crypto could not be started!"} + end. +end_per_suite(_Config) -> + ssh:stop(), + crypto:stop(). +%%-------------------------------------------------------------------- init_per_group(dsa_key, Config) -> DataDir = ?config(data_dir, Config), PrivDir = ?config(priv_dir, Config), @@ -173,23 +118,35 @@ end_per_group(internal_error, Config) -> end_per_group(_, Config) -> Config. +%%-------------------------------------------------------------------- +init_per_testcase(_TestCase, Config) -> + ssh:start(), + Config. + +end_per_testcase(TestCase, Config) when TestCase == server_password_option; + TestCase == server_userpassword_option -> + UserDir = filename:join(?config(priv_dir, Config), nopubkey), + ssh_test_lib:del_dirs(UserDir), + end_per_testcase(Config); +end_per_testcase(_TestCase, Config) -> + end_per_testcase(Config). +end_per_testcase(_Config) -> + ssh:stop(), + ok. -%% Test cases starts here. %%-------------------------------------------------------------------- -app_test(suite) -> - []; -app_test(doc) -> - ["Application consistency test."]; +%% Test Cases -------------------------------------------------------- +%%-------------------------------------------------------------------- +app_test() -> + [{doc, "App lication consistency test."}]. app_test(Config) when is_list(Config) -> ?t:app_test(ssh), ok. %%-------------------------------------------------------------------- -misc_ssh_options(doc) -> - ["Test that we can set some misc options not tested elsewhere, " - "some options not yet present are not decided if we should support or " - "if they need thier own test case."]; -misc_ssh_options(suite) -> - []; +misc_ssh_options() -> + [{doc, "Test that we can set some misc options not tested elsewhere, " + "some options not yet present are not decided if we should support or " + "if they need thier own test case."}]. misc_ssh_options(Config) when is_list(Config) -> SystemDir = filename:join(?config(priv_dir, Config), system), UserDir = ?config(priv_dir, Config), @@ -206,12 +163,8 @@ misc_ssh_options(Config) when is_list(Config) -> basic_test([{client_opts, CMiscOpt1 ++ ClientOpts}, {server_opts, SMiscOpt1 ++ ServerOpts}]). %%-------------------------------------------------------------------- -exec(doc) -> - ["Test api function ssh_connection:exec"]; - -exec(suite) -> - []; - +exec() -> + [{doc, "Test api function ssh_connection:exec"}]. exec(Config) when is_list(Config) -> process_flag(trap_exit, true), SystemDir = filename:join(?config(priv_dir, Config), system), @@ -232,7 +185,7 @@ exec(Config) when is_list(Config) -> expected -> ok; Other0 -> - test_server:fail(Other0) + ct:fail(Other0) end, ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId0), @@ -246,18 +199,14 @@ exec(Config) when is_list(Config) -> expected -> ok; Other1 -> - test_server:fail(Other1) + ct:fail(Other1) end, ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId1), ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- -exec_compressed(doc) -> - ["Test that compression option works"]; - -exec_compressed(suite) -> - []; - +exec_compressed() -> + [{doc, "Test that compression option works"}]. exec_compressed(Config) when is_list(Config) -> process_flag(trap_exit, true), SystemDir = filename:join(?config(priv_dir, Config), system), @@ -279,19 +228,58 @@ exec_compressed(Config) when is_list(Config) -> expected -> ok; Other -> - test_server:fail(Other) + ct:fail(Other) end, ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId), ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- +idle_time() -> + [{doc, "Idle timeout test"}]. +idle_time(Config) -> + SystemDir = filename:join(?config(priv_dir, Config), system), + UserDir = ?config(priv_dir, Config), -shell(doc) -> - ["Test that ssh:shell/2 works"]; - -shell(suite) -> - []; + {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, + {user_dir, UserDir}, + {failfun, fun ssh_test_lib:failfun/2}]), + ConnectionRef = + ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, + {user_dir, UserDir}, + {user_interaction, false}, + {idle_time, 2000}]), + {ok, Id} = ssh_connection:session_channel(ConnectionRef, 1000), + ssh_connection:close(ConnectionRef, Id), + receive + after 10000 -> + {error,channel_closed} = ssh_connection:session_channel(ConnectionRef, 1000) + end, + ssh:stop_daemon(Pid). +%%-------------------------------------------------------------------- +rekey() -> + [{doc, "Idle timeout test"}]. +rekey(Config) -> + SystemDir = filename:join(?config(priv_dir, Config), system), + UserDir = ?config(priv_dir, Config), + {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, + {user_dir, UserDir}, + {failfun, fun ssh_test_lib:failfun/2}, + {rekey_limit, 0}]), + ConnectionRef = + ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, + {user_dir, UserDir}, + {user_interaction, false}, + {rekey_limit, 0}]), + receive + after 200000 -> + %%By this time rekeying would have been done + ssh:close(ConnectionRef), + ssh:stop_daemon(Pid) + end. +%%-------------------------------------------------------------------- +shell() -> + [{doc, "Test that ssh:shell/2 works"}]. shell(Config) when is_list(Config) -> process_flag(trap_exit, true), SystemDir = filename:join(?config(priv_dir, Config), system), @@ -299,76 +287,22 @@ shell(Config) when is_list(Config) -> {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir}, {failfun, fun ssh_test_lib:failfun/2}]), - test_server:sleep(500), + ct:sleep(500), IO = ssh_test_lib:start_io_server(), Shell = ssh_test_lib:start_shell(Port, IO, UserDir), receive {'EXIT', _, _} -> - test_server:fail(no_ssh_connection); + ct:fail(no_ssh_connection); ErlShellStart -> - test_server:format("Erlang shell start: ~p~n", [ErlShellStart]), + ct:pal("Erlang shell start: ~p~n", [ErlShellStart]), do_shell(IO, Shell) end. -do_shell(IO, Shell) -> - receive - ErlPrompt0 -> - test_server:format("Erlang prompt: ~p~n", [ErlPrompt0]) - end, - IO ! {input, self(), "1+1.\r\n"}, - receive - Echo0 -> - test_server:format("Echo: ~p ~n", [Echo0]) - end, - receive - ?NEWLINE -> - ok - end, - receive - Result0 = <<"2">> -> - test_server:format("Result: ~p~n", [Result0]) - end, - receive - ?NEWLINE -> - ok - end, - receive - ErlPrompt1 -> - test_server:format("Erlang prompt: ~p~n", [ErlPrompt1]) - end, - exit(Shell, kill), - %% Does not seem to work in the testserver! - %% IO ! {input, self(), "q().\r\n"}, - %% receive - %% ?NEWLINE -> - %% ok - %% end, - %% receive - %% Echo1 -> - %% test_server:format("Echo: ~p ~n", [Echo1]) - %% end, - %% receive - %% ?NEWLINE -> - %% ok - %% end, - %% receive - %% Result1 -> - %% test_server:format("Result: ~p~n", [Result1]) - %% end, - receive - {'EXIT', Shell, killed} -> - ok - end. - %%-------------------------------------------------------------------- -daemon_already_started(doc) -> - ["Test that get correct error message if you try to start a daemon", - "on an adress that already runs a daemon see also seq10667" ]; - -daemon_already_started(suite) -> - []; - +daemon_already_started() -> + [{doc, "Test that get correct error message if you try to start a daemon", + "on an adress that already runs a daemon see also seq10667"}]. daemon_already_started(Config) when is_list(Config) -> SystemDir = ?config(data_dir, Config), UserDir = ?config(priv_dir, Config), @@ -383,10 +317,8 @@ daemon_already_started(Config) when is_list(Config) -> ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- -server_password_option(doc) -> - ["validate to server that uses the 'password' option"]; -server_password_option(suite) -> - []; +server_password_option() -> + [{doc, "validate to server that uses the 'password' option"}]. server_password_option(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth @@ -412,17 +344,15 @@ server_password_option(Config) when is_list(Config) -> {user_interaction, false}, {user_dir, UserDir}]), - test_server:format("Test of wrong password: Error msg: ~p ~n", [Reason]), + ct:pal("Test of wrong password: Error msg: ~p ~n", [Reason]), ssh:close(ConnectionRef), ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- -server_userpassword_option(doc) -> - ["validate to server that uses the 'password' option"]; -server_userpassword_option(suite) -> - []; +server_userpassword_option() -> + [{doc, "validate to server that uses the 'password' option"}]. server_userpassword_option(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth @@ -457,10 +387,8 @@ server_userpassword_option(Config) when is_list(Config) -> ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- -known_hosts(doc) -> - ["check that known_hosts is updated correctly"]; -known_hosts(suite) -> - []; +known_hosts() -> + [{doc, "check that known_hosts is updated correctly"}]. known_hosts(Config) when is_list(Config) -> SystemDir = ?config(data_dir, Config), PrivDir = ?config(priv_dir, Config), @@ -486,12 +414,8 @@ known_hosts(Config) when is_list(Config) -> ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- -pass_phrase(doc) -> - ["Test that we can use keyes protected by pass phrases"]; - -pass_phrase(suite) -> - []; - +pass_phrase() -> + [{doc, "Test that we can use keyes protected by pass phrases"}]. pass_phrase(Config) when is_list(Config) -> process_flag(trap_exit, true), SystemDir = filename:join(?config(priv_dir, Config), system), @@ -511,12 +435,8 @@ pass_phrase(Config) when is_list(Config) -> %%-------------------------------------------------------------------- -internal_error(doc) -> - ["Test that client does not hang if disconnects due to internal error"]; - -internal_error(suite) -> - []; - +internal_error() -> + [{doc,"Test that client does not hang if disconnects due to internal error"}]. internal_error(Config) when is_list(Config) -> process_flag(trap_exit, true), SystemDir = filename:join(?config(priv_dir, Config), system), @@ -532,12 +452,29 @@ internal_error(Config) when is_list(Config) -> ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- -close(doc) -> - ["Simulate that we try to close an already closed connection"]; +send() -> + [{doc, "Test ssh_connection:send/3"}]. +send(Config) when is_list(Config) -> + process_flag(trap_exit, true), + SystemDir = filename:join(?config(priv_dir, Config), system), + UserDir = ?config(priv_dir, Config), + + {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, + {user_dir, UserDir}, + {failfun, fun ssh_test_lib:failfun/2}]), + ConnectionRef = + ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, + {user_dir, UserDir}, + {user_interaction, false}]), + {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity), + ok = ssh_connection:send(ConnectionRef, ChannelId, <<"Data">>), + ok = ssh_connection:send(ConnectionRef, ChannelId, << >>), + ssh:stop_daemon(Pid). -close(suite) -> - []; +%%-------------------------------------------------------------------- +close() -> + [{doc, "Simulate that we try to close an already closed connection"}]. close(Config) when is_list(Config) -> SystemDir = ?config(data_dir, Config), PrivDir = ?config(priv_dir, Config), @@ -557,10 +494,8 @@ close(Config) when is_list(Config) -> exit(CM, {shutdown, normal}), ok = ssh:close(CM). - - %%-------------------------------------------------------------------- -%% Internal functions +%% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- basic_test(Config) -> @@ -571,3 +506,53 @@ basic_test(Config) -> {ok, CM} = ssh:connect(Host, Port, ClientOpts), ok = ssh:close(CM), ssh:stop_daemon(Pid). + +do_shell(IO, Shell) -> + receive + ErlPrompt0 -> + ct:pal("Erlang prompt: ~p~n", [ErlPrompt0]) + end, + IO ! {input, self(), "1+1.\r\n"}, + receive + Echo0 -> + ct:pal("Echo: ~p ~n", [Echo0]) + end, + receive + ?NEWLINE -> + ok + end, + receive + Result0 = <<"2">> -> + ct:pal("Result: ~p~n", [Result0]) + end, + receive + ?NEWLINE -> + ok + end, + receive + ErlPrompt1 -> + ct:pal("Erlang prompt: ~p~n", [ErlPrompt1]) + end, + exit(Shell, kill). + %%Does not seem to work in the testserver! + %% IO ! {input, self(), "q().\r\n"}, + %% receive + %% ?NEWLINE -> + %% ok + %% end, + %% receive + %% Echo1 -> + %% ct:pal("Echo: ~p ~n", [Echo1]) + %% end, + %% receive + %% ?NEWLINE -> + %% ok + %% end, + %% receive + %% Result1 -> + %% ct:pal("Result: ~p~n", [Result1]) + %% end, + %% receive + %% {'EXIT', Shell, killed} -> + %% ok + %% end. diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl new file mode 100644 index 0000000000..6c781e0e91 --- /dev/null +++ b/lib/ssh/test/ssh_connection_SUITE.erl @@ -0,0 +1,313 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(ssh_connection_SUITE). + +-include_lib("common_test/include/ct.hrl"). + +-compile(export_all). + +-define(SSH_DEFAULT_PORT, 22). +-define(EXEC_TIMEOUT, 10000). + +%%-------------------------------------------------------------------- +%% Common Test interface functions ----------------------------------- +%%-------------------------------------------------------------------- + +suite() -> + [{ct_hooks,[ts_install_cth]}]. + +all() -> + [ + {group, openssh_payload}, + interrupted_send + ]. +groups() -> + [{openssh_payload, [], [simple_exec, + small_cat, + big_cat, + send_after_exit + ]}]. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + case catch crypto:start() of + ok -> + Config; + _Else -> + {skip, "Crypto could not be started!"} + end. + +end_per_suite(_Config) -> + crypto:stop(). + +%%-------------------------------------------------------------------- +init_per_group(openssh_payload, _Config) -> + case gen_tcp:connect("localhost", 22, []) of + {error,econnrefused} -> + {skip,"No openssh deamon"}; + {ok, Socket} -> + gen_tcp:close(Socket) + end; +init_per_group(_, Config) -> + Config. + +end_per_group(_, Config) -> + Config. + +%%-------------------------------------------------------------------- +init_per_testcase(_TestCase, Config) -> + ssh:start(), + Config. + +end_per_testcase(_Config) -> + ssh:stop(). + +%%-------------------------------------------------------------------- +%% Test Cases -------------------------------------------------------- +%%-------------------------------------------------------------------- +simple_exec() -> + [{doc, "Simple openssh connectivity test for ssh_connection:exec"}]. + +simple_exec(Config) when is_list(Config) -> + ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true}, + {user_interaction, false}]), + {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity), + success = ssh_connection:exec(ConnectionRef, ChannelId0, + "echo testing", infinity), + + %% receive response to input + receive + {ssh_cm, ConnectionRef, {data, ChannelId0, 0, <<"testing\n">>}} -> + ok + end, + + %% receive close messages + receive + {ssh_cm, ConnectionRef, {eof, ChannelId0}} -> + ok + end, + receive + {ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} -> + ok + end, + receive + {ssh_cm, ConnectionRef,{closed, ChannelId0}} -> + ok + end. + +%%-------------------------------------------------------------------- +small_cat() -> + [{doc, "Use 'cat' to echo small data block back to us."}]. + +small_cat(Config) when is_list(Config) -> + ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true}, + {user_interaction, false}]), + {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity), + success = ssh_connection:exec(ConnectionRef, ChannelId0, + "cat", infinity), + + Data = <<"I like spaghetti squash">>, + ok = ssh_connection:send(ConnectionRef, ChannelId0, Data), + ok = ssh_connection:send_eof(ConnectionRef, ChannelId0), + + %% receive response to input + receive + {ssh_cm, ConnectionRef, {data, ChannelId0, 0, Data}} -> + ok + end, + + %% receive close messages + receive + {ssh_cm, ConnectionRef, {eof, ChannelId0}} -> + ok + end, + receive + {ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} -> + ok + end, + receive + {ssh_cm, ConnectionRef,{closed, ChannelId0}} -> + ok + end. + +%%-------------------------------------------------------------------- +big_cat() -> + [{doc,"Use 'cat' to echo large data block back to us."}]. + +big_cat(Config) when is_list(Config) -> + ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true}, + {user_interaction, false}]), + {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity), + success = ssh_connection:exec(ConnectionRef, ChannelId0, + "cat", infinity), + + %% build 10MB binary + Data = << <<X:32>> || X <- lists:seq(1,2500000)>>, + + %% pre-adjust receive window so the other end doesn't block + ssh_connection:adjust_window(ConnectionRef, ChannelId0, size(Data)), + + ct:pal("sending ~p byte binary~n",[size(Data)]), + ok = ssh_connection:send(ConnectionRef, ChannelId0, Data, 10000), + ok = ssh_connection:send_eof(ConnectionRef, ChannelId0), + + %% collect echoed data until eof + case big_cat_rx(ConnectionRef, ChannelId0) of + {ok, Data} -> + ok; + {ok, Other} -> + case size(Data) =:= size(Other) of + true -> + ct:pal("received and sent data are same" + "size but do not match~n",[]); + false -> + ct:pal("sent ~p but only received ~p~n", + [size(Data), size(Other)]) + end, + ct:fail(receive_data_mismatch); + Else -> + ct:fail(Else) + end, + + %% receive close messages (eof already consumed) + receive + {ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} -> + ok + end, + receive + {ssh_cm, ConnectionRef,{closed, ChannelId0}} -> + ok + end. + +%%-------------------------------------------------------------------- +send_after_exit() -> + [{doc, "Send channel data after the channel has been closed."}]. + +send_after_exit(Config) when is_list(Config) -> + ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true}, + {user_interaction, false}]), + {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity), + + %% Shell command "false" will exit immediately + success = ssh_connection:exec(ConnectionRef, ChannelId0, + "false", infinity), + + timer:sleep(2000), %% Allow incoming eof/close/exit_status ssh messages to be processed + + Data = <<"I like spaghetti squash">>, + case ssh_connection:send(ConnectionRef, ChannelId0, Data, 2000) of + {error, closed} -> ok; + ok -> + ct:fail({expected,{error,closed}}); + {error, timeout} -> + ct:fail({expected,{error,closed}}); + Else -> + ct:fail(Else) + end, + + %% receive close messages + receive + {ssh_cm, ConnectionRef, {eof, ChannelId0}} -> + ok + end, + receive + {ssh_cm, ConnectionRef, {exit_status, ChannelId0, _}} -> + ok + end, + receive + {ssh_cm, ConnectionRef,{closed, ChannelId0}} -> + ok + end. +%%-------------------------------------------------------------------- +interrupted_send() -> + [{doc, "Use a subsystem that echos n char and then sends eof to cause a channel exit partway through a large send."}]. + +interrupted_send(Config) when is_list(Config) -> + PrivDir = ?config(priv_dir, Config), + UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth + file:make_dir(UserDir), + SysDir = ?config(data_dir, Config), + {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir}, + {user_dir, UserDir}, + {password, "morot"}, + {subsystems, [{"echo_n", {ssh_echo_server, [4000000]}}]}]), + + ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true}, + {user, "foo"}, + {password, "morot"}, + {user_interaction, false}, + {user_dir, UserDir}]), + + {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity), + + success = ssh_connection:subsystem(ConnectionRef, ChannelId, "echo_n", infinity), + + %% build 10MB binary + Data = << <<X:32>> || X <- lists:seq(1,2500000)>>, + + %% expect remote end to send us 4MB back + <<ExpectedData:4000000/binary, _/binary>> = Data, + + %% pre-adjust receive window so the other end doesn't block + ssh_connection:adjust_window(ConnectionRef, ChannelId, size(ExpectedData) + 1), + + case ssh_connection:send(ConnectionRef, ChannelId, Data, 10000) of + {error, closed} -> + ok; + Msg -> + ct:fail({expected,{error,closed}, got, Msg}) + end, + receive_data(ExpectedData, ConnectionRef, ChannelId), + ssh:close(ConnectionRef), + ssh:stop_daemon(Pid). + +%%-------------------------------------------------------------------- +%% Internal functions ------------------------------------------------ +%%-------------------------------------------------------------------- +big_cat_rx(ConnectionRef, ChannelId) -> + big_cat_rx(ConnectionRef, ChannelId, []). + +big_cat_rx(ConnectionRef, ChannelId, Acc) -> + receive + {ssh_cm, ConnectionRef, {data, ChannelId, 0, Data}} -> + %% ssh_connection:adjust_window(ConnectionRef, ChannelId, size(Data)), + %% window was pre-adjusted, don't adjust again here + big_cat_rx(ConnectionRef, ChannelId, [Data | Acc]); + {ssh_cm, ConnectionRef, {eof, ChannelId}} -> + {ok, iolist_to_binary(lists:reverse(Acc))} + after ?EXEC_TIMEOUT -> + timeout + end. + +receive_data(ExpectedData, ConnectionRef, ChannelId) -> + ExpectedData = collect_data(ConnectionRef, ChannelId). + +collect_data(ConnectionRef, ChannelId) -> + collect_data(ConnectionRef, ChannelId, []). + +collect_data(ConnectionRef, ChannelId, Acc) -> + receive + {ssh_cm, ConnectionRef, {data, ChannelId, 0, Data}} -> + collect_data(ConnectionRef, ChannelId, [Data | Acc]); + {ssh_cm, ConnectionRef, {eof, ChannelId}} -> + iolist_to_binary(lists:reverse(Acc)) + after 5000 -> + timeout + end. diff --git a/lib/ssh/test/ssh_connection_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_connection_SUITE_data/ssh_host_rsa_key new file mode 100644 index 0000000000..6ae7ee023d --- /dev/null +++ b/lib/ssh/test/ssh_connection_SUITE_data/ssh_host_rsa_key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337 +zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB +6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB +AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW +NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++ +udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW +WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt +n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5 +sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY ++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt +64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB +m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT +tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR +-----END RSA PRIVATE KEY----- diff --git a/lib/ssh/test/ssh_echo_server.erl b/lib/ssh/test/ssh_echo_server.erl new file mode 100644 index 0000000000..315ffecfd7 --- /dev/null +++ b/lib/ssh/test/ssh_echo_server.erl @@ -0,0 +1,71 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2005-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% + +%%% Description: Example ssh server +-module(ssh_echo_server). +-behaviour(ssh_daemon_channel). +-record(state, { + n, + id, + cm + }). +-export([init/1, handle_msg/2, handle_ssh_msg/2, terminate/2]). + +init([N]) -> + {ok, #state{n = N}}. + +handle_msg({ssh_channel_up, ChannelId, ConnectionManager}, State) -> + {ok, State#state{id = ChannelId, + cm = ConnectionManager}}. + +handle_ssh_msg({ssh_cm, CM, {data, ChannelId, 0, Data}}, #state{n = N} = State) -> + M = N - size(Data), + case M > 0 of + true -> + ssh_connection:send(CM, ChannelId, Data), + {ok, State#state{n = M}}; + false -> + <<SendData:N/binary, _/binary>> = Data, + ssh_connection:send(CM, ChannelId, SendData), + ssh_connection:send_eof(CM, ChannelId), + {stop, ChannelId, State} + end; +handle_ssh_msg({ssh_cm, _ConnectionManager, + {data, _ChannelId, 1, Data}}, State) -> + error_logger:format(standard_error, " ~p~n", [binary_to_list(Data)]), + {ok, State}; + +handle_ssh_msg({ssh_cm, _ConnectionManager, {eof, _ChannelId}}, State) -> + {ok, State}; + +handle_ssh_msg({ssh_cm, _, {signal, _, _}}, State) -> + %% Ignore signals according to RFC 4254 section 6.9. + {ok, State}; + +handle_ssh_msg({ssh_cm, _, {exit_signal, ChannelId, _, _Error, _}}, + State) -> + {stop, ChannelId, State}; + +handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, _Status}}, State) -> + {stop, ChannelId, State}. + +terminate(_Reason, _State) -> + ok. diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl index d40b1d544d..56b1363b7a 100644 --- a/lib/ssh/test/ssh_sftp_SUITE.erl +++ b/lib/ssh/test/ssh_sftp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2012. All Rights Reserved. +%% Copyright Ericsson AB 2005-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -24,7 +24,6 @@ -compile(export_all). -include_lib("common_test/include/ct.hrl"). - -include_lib("kernel/include/file.hrl"). % Default timetrap timeout @@ -33,16 +32,20 @@ -define(USER, "Alladin"). -define(PASSWD, "Sesame"). -%% Test server callback functions %%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. +%% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- + +suite() -> + [{ct_hooks,[ts_install_cth]}]. + +all() -> + [{group, erlang_server}, + {group, openssh_server}, + sftp_nonexistent_subsystem + ]. + + init_per_suite(Config) -> case (catch crypto:start()) of ok -> @@ -52,35 +55,67 @@ init_per_suite(Config) -> {skip,"Could not start crypto!"} end. -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- end_per_suite(Config) -> ssh:stop(), crypto:stop(), Config. %%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case +groups() -> + [{erlang_server, [], [open_close_file, open_close_dir, read_file, read_dir, + write_file, rename_file, mk_rm_dir, remove_file, links, + retrieve_attributes, set_attributes, async_read, + async_write, position, pos_read, pos_write]}, + {openssh_server, [], [open_close_file, open_close_dir, read_file, read_dir, + write_file, rename_file, mk_rm_dir, remove_file, links, + retrieve_attributes, set_attributes, async_read, + async_write, position, pos_read, pos_write]}]. + +init_per_group(erlang_server, Config) -> + PrivDir = ?config(priv_dir, Config), + SysDir = ?config(data_dir, Config), + Sftpd = + ssh_test_lib:daemon([{system_dir, SysDir}, + {user_dir, PrivDir}, + {user_passwords, + [{?USER, ?PASSWD}]}]), + [{group, erlang_server}, {sftpd, Sftpd} | Config]; + +init_per_group(openssh_server, Config) -> + Host = ssh_test_lib:hostname(), + case (catch ssh_sftp:start_channel(Host, + [{user_interaction, false}, + {silently_accept_hosts, true}])) of + {ok, _ChannelPid, Connection} -> + ssh:close(Connection), + [{group, openssh_server} | Config]; + _ -> + {skip, "No openssh server"} + end. + +end_per_group(erlang_server, Config) -> + Config; +end_per_group(_, Config) -> + Config. + %%-------------------------------------------------------------------- + +init_per_testcase(sftp_nonexistent_subsystem, Config) -> + PrivDir = ?config(priv_dir, Config), + SysDir = ?config(data_dir, Config), + Sftpd = ssh_test_lib:daemon([{system_dir, SysDir}, + {user_dir, PrivDir}, + {subsystems, []}, + {user_passwords, + [{?USER, ?PASSWD}]} + ]), + [{sftpd, Sftpd} | Config]; + init_per_testcase(Case, Config) -> prep(Config), TmpConfig0 = lists:keydelete(watchdog, 1, Config), TmpConfig = lists:keydelete(sftp, 1, TmpConfig0), - Dog = test_server:timetrap(?default_timeout), + Dog = ct:timetrap(?default_timeout), case ?config(group, Config) of erlang_server -> @@ -105,14 +140,8 @@ init_per_testcase(Case, Config) -> [{sftp, Sftp}, {watchdog, Dog} | TmpConfig] end. -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- +end_per_testcase(sftp_nonexistent_subsystem, Config) -> + Config; end_per_testcase(rename_file, Config) -> PrivDir = ?config(priv_dir, Config), NewFileName = filename:join(PrivDir, "test.txt"), @@ -124,69 +153,13 @@ end_per_testcase(_, Config) -> end_per_testcase(Config) -> {Sftp, Connection} = ?config(sftp, Config), ssh_sftp:stop_channel(Sftp), - ssh:close(Connection), - Dog = ?config(watchdog, Config), - test_server:timetrap_cancel(Dog), - ok. + ssh:close(Connection). %%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [{group, erlang_server}, - {group, openssh_server}]. - -groups() -> - [{erlang_server, [], [open_close_file, open_close_dir, read_file, read_dir, - write_file, rename_file, mk_rm_dir, remove_file, links, - retrieve_attributes, set_attributes, async_read, - async_write, position, pos_read, pos_write]}, - {openssh_server, [], [open_close_file, open_close_dir, read_file, read_dir, - write_file, rename_file, mk_rm_dir, remove_file, links, - retrieve_attributes, set_attributes, async_read, - async_write, position, pos_read, pos_write]}]. - -init_per_group(erlang_server, Config) -> - PrivDir = ?config(priv_dir, Config), - SysDir = ?config(data_dir, Config), - Sftpd = - ssh_test_lib:daemon([{system_dir, SysDir}, - {user_dir, PrivDir}, - {user_passwords, - [{?USER, ?PASSWD}]}, - {failfun, - fun ssh_test_lib:failfun/2}]), - [{group, erlang_server}, {sftpd, Sftpd} | Config]; - -init_per_group(openssh_server, Config) -> - Host = ssh_test_lib:hostname(), - case (catch ssh_sftp:start_channel(Host, - [{user_interaction, false}, - {silently_accept_hosts, true}])) of - {ok, _ChannelPid, Connection} -> - ssh:close(Connection), - [{group, openssh_server} | Config]; - _ -> - {skip, "No openssh server"} - end. - -end_per_group(erlang_server, Config) -> - Config; -end_per_group(_, Config) -> - Config. - - -%% Test cases starts here. +%% Test Cases -------------------------------------------------------- %%-------------------------------------------------------------------- -open_close_file(doc) -> - ["Test API functions open/3 and close/2"]; -open_close_file(suite) -> - []; +open_close_file() -> + [{doc, "Test API functions open/3 and close/2"}]. open_close_file(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "sftp.txt"), @@ -198,21 +171,15 @@ open_close_file(Config) when is_list(Config) -> ok = open_close_file(Sftp, FileName, [write, creat]), ok = open_close_file(Sftp, FileName, [write, trunc]), ok = open_close_file(Sftp, FileName, [append]), - ok = open_close_file(Sftp, FileName, [read, binary]), - - ok. + ok = open_close_file(Sftp, FileName, [read, binary]). open_close_file(Server, File, Mode) -> {ok, Handle} = ssh_sftp:open(Server, File, Mode), - ok = ssh_sftp:close(Server, Handle), - ok. - + ok = ssh_sftp:close(Server, Handle). %%-------------------------------------------------------------------- -open_close_dir(doc) -> - ["Test API functions opendir/2 and close/2"]; -open_close_dir(suite) -> - []; +open_close_dir() -> + [{doc, "Test API functions opendir/2 and close/2"}]. open_close_dir(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), {Sftp, _} = ?config(sftp, Config), @@ -220,138 +187,92 @@ open_close_dir(Config) when is_list(Config) -> {ok, Handle} = ssh_sftp:opendir(Sftp, PrivDir), ok = ssh_sftp:close(Sftp, Handle), - {error, _} = ssh_sftp:opendir(Sftp, FileName), + {error, _} = ssh_sftp:opendir(Sftp, FileName). - ok. %%-------------------------------------------------------------------- -read_file(doc) -> - ["Test API funtion read_file/2"]; -read_file(suite) -> - []; +read_file() -> + [{doc, "Test API funtion read_file/2"}]. read_file(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "sftp.txt"), - {Sftp, _} = ?config(sftp, Config), - {ok, Data} = ssh_sftp:read_file(Sftp, FileName), + {ok, Data} = file:read_file(FileName). - {ok, Data} = file:read_file(FileName), - - ok. %%-------------------------------------------------------------------- -read_dir(doc) -> - ["Test API function list_dir/2"]; -read_dir(suite) -> - []; +read_dir() -> + [{doc,"Test API function list_dir/2"}]. read_dir(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), {Sftp, _} = ?config(sftp, Config), {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir), - test_server:format("sftp list dir: ~p~n", [Files]), - ok. + ct:pal("sftp list dir: ~p~n", [Files]). %%-------------------------------------------------------------------- -write_file(doc) -> - ["Test API function write_file/2"]; -write_file(suite) -> - []; +write_file() -> + [{doc, "Test API function write_file/2"}]. write_file(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "sftp.txt"), - {Sftp, _} = ?config(sftp, Config), Data = list_to_binary("Hej hopp!"), - ssh_sftp:write_file(Sftp, FileName, [Data]), - - {ok, Data} = file:read_file(FileName), - - ok. + {ok, Data} = file:read_file(FileName). %%-------------------------------------------------------------------- -remove_file(doc) -> - ["Test API function delete/2"]; -remove_file(suite) -> - []; +remove_file() -> + [{doc,"Test API function delete/2"}]. remove_file(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "sftp.txt"), - {Sftp, _} = ?config(sftp, Config), {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir), - true = lists:member(filename:basename(FileName), Files), - ok = ssh_sftp:delete(Sftp, FileName), - {ok, NewFiles} = ssh_sftp:list_dir(Sftp, PrivDir), - false = lists:member(filename:basename(FileName), NewFiles), - - {error, _} = ssh_sftp:delete(Sftp, FileName), - - ok. - + {error, _} = ssh_sftp:delete(Sftp, FileName). %%-------------------------------------------------------------------- -rename_file(doc) -> - ["Test API function rename_file/2"]; -rename_file(suite) -> - []; +rename_file() -> + [{doc, "Test API function rename_file/2"}]. rename_file(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "sftp.txt"), NewFileName = filename:join(PrivDir, "test.txt"), {Sftp, _} = ?config(sftp, Config), - {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir), - - test_server:format("FileName: ~p, Files: ~p~n", [FileName, Files]), - + ct:pal("FileName: ~p, Files: ~p~n", [FileName, Files]), true = lists:member(filename:basename(FileName), Files), false = lists:member(filename:basename(NewFileName), Files), - ok = ssh_sftp:rename(Sftp, FileName, NewFileName), - {ok, NewFiles} = ssh_sftp:list_dir(Sftp, PrivDir), - - test_server:format("FileName: ~p, Files: ~p~n", [FileName, NewFiles]), + ct:pal("FileName: ~p, Files: ~p~n", [FileName, NewFiles]), false = lists:member(filename:basename(FileName), NewFiles), - true = lists:member(filename:basename(NewFileName), NewFiles), - - ok. + true = lists:member(filename:basename(NewFileName), NewFiles). %%-------------------------------------------------------------------- -mk_rm_dir(doc) -> - ["Test API functions make_dir/2, del_dir/2"]; -mk_rm_dir(suite) -> - []; +mk_rm_dir() -> + [{doc,"Test API functions make_dir/2, del_dir/2"}]. mk_rm_dir(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), {Sftp, _} = ?config(sftp, Config), + DirName = filename:join(PrivDir, "test"), - ok = ssh_sftp:make_dir(Sftp, DirName), ok = ssh_sftp:del_dir(Sftp, DirName), - NewDirName = filename:join(PrivDir, "foo/bar"), - {error, _} = ssh_sftp:make_dir(Sftp, NewDirName), - {error, _} = ssh_sftp:del_dir(Sftp, PrivDir), - - ok. + {error, _} = ssh_sftp:del_dir(Sftp, PrivDir). %%-------------------------------------------------------------------- -links(doc) -> - ["Tests API function make_symlink/3"]; -links(suite) -> - []; +links() -> + [{doc,"Tests API function make_symlink/3"}]. links(Config) when is_list(Config) -> - case test_server:os_type() of + case os:type() of {win32, _} -> {skip, "Links are not fully supported by windows"}; _ -> @@ -361,74 +282,60 @@ links(Config) when is_list(Config) -> LinkFileName = filename:join(PrivDir, "link_test.txt"), ok = ssh_sftp:make_symlink(Sftp, LinkFileName, FileName), - {ok, FileName} = ssh_sftp:read_link(Sftp, LinkFileName), - ok + {ok, FileName} = ssh_sftp:read_link(Sftp, LinkFileName) end. %%-------------------------------------------------------------------- -retrieve_attributes(doc) -> - ["Test API function read_file_info/3"]; -retrieve_attributes(suite) -> - []; +retrieve_attributes() -> + [{doc, "Test API function read_file_info/3"}]. retrieve_attributes(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "sftp.txt"), - {Sftp, _} = ?config(sftp, Config), + {Sftp, _} = ?config(sftp, Config), {ok, FileInfo} = ssh_sftp:read_file_info(Sftp, FileName), - {ok, NewFileInfo} = file:read_file_info(FileName), %% TODO comparison. There are some differences now is that ok? - test_server:format("SFTP: ~p FILE: ~p~n", [FileInfo, NewFileInfo]), - ok. + ct:pal("SFTP: ~p FILE: ~p~n", [FileInfo, NewFileInfo]). %%-------------------------------------------------------------------- -set_attributes(doc) -> - ["Test API function write_file_info/3"]; -set_attributes(suite) -> - []; +set_attributes() -> + [{doc,"Test API function write_file_info/3"}]. set_attributes(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), - {Sftp, _} = ?config(sftp, Config), + {Sftp, _} = ?config(sftp, Config), {ok,Fd} = file:open(FileName, write), io:put_chars(Fd,"foo"), - ok = ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#400}), {error, eacces} = file:write_file(FileName, "hello again"), ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#600}), - ok = file:write_file(FileName, "hello again"), - - ok. + ok = file:write_file(FileName, "hello again"). %%-------------------------------------------------------------------- -async_read(doc) -> - ["Test API aread/3"]; -async_read(suite) -> - []; +async_read() -> + [{doc,"Test API aread/3"}]. async_read(Config) when is_list(Config) -> {Sftp, _} = ?config(sftp, Config), PrivDir = ?config(priv_dir, Config), + FileName = filename:join(PrivDir, "sftp.txt"), {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]), {async, Ref} = ssh_sftp:aread(Sftp, Handle, 20), receive {async_reply, Ref, {ok, Data}} -> - test_server:format("Data: ~p~n", [Data]), + ct:pal("Data: ~p~n", [Data]), ok; Msg -> - test_server:fail(Msg) - end, - ok. + ct:fail(Msg) + end. %%-------------------------------------------------------------------- -async_write(doc) -> - ["Test API awrite/3"]; -async_write(suite) -> - []; +async_write() -> + [{doc,"Test API awrite/3"}]. async_write(Config) when is_list(Config) -> {Sftp, _} = ?config(sftp, Config), PrivDir = ?config(priv_dir, Config), @@ -441,16 +348,13 @@ async_write(Config) when is_list(Config) -> {async_reply, Ref, ok} -> {ok, Data} = file:read_file(FileName); Msg -> - test_server:fail(Msg) - end, - ok. + ct:fail(Msg) + end. %%-------------------------------------------------------------------- -position(doc) -> - ["Test API functions position/3"]; -position(suite) -> - []; +position() -> + [{doc, "Test API functions position/3"}]. position(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), @@ -458,7 +362,6 @@ position(Config) when is_list(Config) -> Data = list_to_binary("1234567890"), ssh_sftp:write_file(Sftp, FileName, [Data]), - {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]), {ok, 3} = ssh_sftp:position(Sftp, Handle, {bof, 3}), @@ -477,15 +380,11 @@ position(Config) when is_list(Config) -> {ok, "1"} = ssh_sftp:read(Sftp, Handle, 1), {ok, 1} = ssh_sftp:position(Sftp, Handle, cur), - {ok, "2"} = ssh_sftp:read(Sftp, Handle, 1), - - ok. + {ok, "2"} = ssh_sftp:read(Sftp, Handle, 1). %%-------------------------------------------------------------------- -pos_read(doc) -> - ["Test API functions pread/3 and apread/3"]; -pos_read(suite) -> - []; +pos_read() -> + [{doc,"Test API functions pread/3 and apread/3"}]. pos_read(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), @@ -494,7 +393,6 @@ pos_read(Config) when is_list(Config) -> ssh_sftp:write_file(Sftp, FileName, [Data]), {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]), - {async, Ref} = ssh_sftp:apread(Sftp, Handle, {bof, 5}, 4), NewData = "opp!", @@ -503,21 +401,17 @@ pos_read(Config) when is_list(Config) -> {async_reply, Ref, {ok, NewData}} -> ok; Msg -> - test_server:fail(Msg) + ct:fail(Msg) end, NewData1 = "hopp", - {ok, NewData1} = ssh_sftp:pread(Sftp, Handle, {bof, 4}, 4), + {ok, NewData1} = ssh_sftp:pread(Sftp, Handle, {bof, 4}, 4). - ok. %%-------------------------------------------------------------------- -pos_write(doc) -> - ["Test API functions pwrite/4 and apwrite/4"]; -pos_write(suite) -> - []; +pos_write() -> + [{doc,"Test API functions pwrite/4 and apwrite/4"}]. pos_write(Config) when is_list(Config) -> - PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), {Sftp, _} = ?config(sftp, Config), @@ -533,17 +427,27 @@ pos_write(Config) when is_list(Config) -> {async_reply, Ref, ok} -> ok; Msg -> - test_server:fail(Msg) + ct:fail(Msg) end, ok = ssh_sftp:pwrite(Sftp, Handle, eof, list_to_binary("!")), NewData1 = list_to_binary("Bye, see you tomorrow!"), - {ok, NewData1} = ssh_sftp:read_file(Sftp, FileName), + {ok, NewData1} = ssh_sftp:read_file(Sftp, FileName). - ok. +%%-------------------------------------------------------------------- +sftp_nonexistent_subsystem() -> + [{doc, "Try to execute sftp subsystem on a server that does not support it"}]. +sftp_nonexistent_subsystem(Config) when is_list(Config) -> + {_,Host, Port} = ?config(sftpd, Config), + {error,"server failed to start sftp subsystem"} = + ssh_sftp:start_channel(Host, Port, + [{user_interaction, false}, + {user, ?USER}, {password, ?PASSWD}, + {silently_accept_hosts, true}]). -%% Internal functions +%%-------------------------------------------------------------------- +%% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- prep(Config) -> PrivDir = ?config(priv_dir, Config), diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl index 695a7caa7d..7b22e45d5e 100644 --- a/lib/ssh/test/ssh_sftpd_SUITE.erl +++ b/lib/ssh/test/ssh_sftpd_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2012. All Rights Reserved. +%% Copyright Ericsson AB 2006-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -24,12 +24,10 @@ -compile(export_all). -include_lib("common_test/include/ct.hrl"). --include("test_server_line.hrl"). +-include_lib("kernel/include/file.hrl"). -include("ssh_xfer.hrl"). -include("ssh.hrl"). --include_lib("kernel/include/file.hrl"). - -define(USER, "Alladin"). -define(PASSWD, "Sesame"). -define(XFER_PACKET_SIZE, 32768). @@ -41,16 +39,33 @@ -define(is_set(F, Bits), ((F) band (Bits)) == (F)). -%% Test server callback functions %%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. +%% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- + +all() -> + [open_close_file, + open_close_dir, + read_file, + read_dir, + write_file, + rename_file, + mk_rm_dir, + remove_file, + real_path, + retrieve_attributes, + set_attributes, + links, + ver3_rename, + relpath, + sshd_read_file, + ver6_basic]. + +groups() -> + []. + +%%-------------------------------------------------------------------- + init_per_suite(Config) -> case (catch crypto:start()) of ok -> @@ -66,34 +81,24 @@ init_per_suite(Config) -> {skip,"Could not start crypto!"} end. -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- end_per_suite(Config) -> SysDir = ?config(priv_dir, Config), ssh_test_lib:clean_dsa(SysDir), UserDir = filename:join(?config(priv_dir, Config), nopubkey), file:del_dir(UserDir), ssh:stop(), - crypto:stop(), - ok. + crypto:stop(). %%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + %%-------------------------------------------------------------------- + init_per_testcase(TestCase, Config) -> ssh:start(), prep(Config), @@ -102,12 +107,18 @@ init_per_testcase(TestCase, Config) -> SystemDir = filename:join(?config(priv_dir, Config), system), Port = ssh_test_lib:inet_port(node()), - - {ok, Sftpd} = - ssh_sftpd:listen(Port, [{system_dir, SystemDir}, - {user_dir, PrivDir}, - {user_passwords,[{?USER, ?PASSWD}]}, - {pwdfun, fun(_,_) -> true end}]), + Options = [{system_dir, SystemDir}, + {user_dir, PrivDir}, + {user_passwords,[{?USER, ?PASSWD}]}, + {pwdfun, fun(_,_) -> true end}], + {ok, Sftpd} = case TestCase of + ver6_basic -> + SubSystems = [ssh_sftpd:subsystem_spec([{sftpd_vsn, 6}])], + ssh:daemon(Port, [{subsystems, SubSystems}|Options]); + _ -> + SubSystems = [ssh_sftpd:subsystem_spec([])], + ssh:daemon(Port, [{subsystems, SubSystems}|Options]) + end, Cm = ssh_test_lib:connect(Port, [{user_dir, ClientUserDir}, @@ -138,56 +149,22 @@ init_per_testcase(TestCase, Config) -> {ok, <<?SSH_FXP_VERSION, ?UINT32(Version), _Ext/binary>>, _} = reply(Cm, Channel), - test_server:format("Client: ~p Server ~p~n", [ProtocolVer, Version]), + ct:pal("Client: ~p Server ~p~n", [ProtocolVer, Version]), [{sftp, {Cm, Channel}}, {sftpd, Sftpd }| Config]. -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- end_per_testcase(_TestCase, Config) -> ssh_sftpd:stop(?config(sftpd, Config)), {Cm, Channel} = ?config(sftp, Config), ssh_connection:close(Cm, Channel), ssh:close(Cm), - ssh:stop(), - ok. + ssh:stop(). %%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [open_close_file, open_close_dir, read_file, read_dir, - write_file, rename_file, mk_rm_dir, remove_file, - real_path, retrieve_attributes, set_attributes, links, - ver3_rename_OTP_6352, seq10670, sshd_read_file]. - -groups() -> - []. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%% Test cases starts here. +%% Test Cases -------------------------------------------------------- %%-------------------------------------------------------------------- -open_close_file(doc) -> - ["Test SSH_FXP_OPEN and SSH_FXP_CLOSE commands"]; -open_close_file(suite) -> - []; +open_close_file() -> + [{doc, "Test SSH_FXP_OPEN and SSH_FXP_CLOSE commands"}]. open_close_file(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), @@ -214,15 +191,11 @@ open_close_file(Config) when is_list(Config) -> ?UINT32(?SSH_FX_FAILURE), _/binary>>, _} = open_file(PrivDir, Cm, Channel, NewReqId1, ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES, - ?SSH_FXF_OPEN_EXISTING), - - ok. + ?SSH_FXF_OPEN_EXISTING). %%-------------------------------------------------------------------- -open_close_dir(doc) -> - ["Test SSH_FXP_OPENDIR and SSH_FXP_CLOSE commands"]; -open_close_dir(suite) -> - []; +open_close_dir() -> + [{doc,"Test SSH_FXP_OPENDIR and SSH_FXP_CLOSE commands"}]. open_close_dir(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), {Cm, Channel} = ?config(sftp, Config), @@ -248,10 +221,8 @@ open_close_dir(Config) when is_list(Config) -> end. %%-------------------------------------------------------------------- -read_file(doc) -> - ["Test SSH_FXP_READ command"]; -read_file(suite) -> - []; +read_file() -> + [{doc, "Test SSH_FXP_READ command"}]. read_file(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), @@ -270,28 +241,22 @@ read_file(Config) when is_list(Config) -> Data/binary>>, _} = read_file(Handle, 100, 0, Cm, Channel, NewReqId), - {ok, Data} = file:read_file(FileName), + {ok, Data} = file:read_file(FileName). - ok. %%-------------------------------------------------------------------- -read_dir(doc) -> - ["Test SSH_FXP_READDIR command"]; -read_dir(suite) -> - []; +read_dir() -> + [{doc,"Test SSH_FXP_READDIR command"}]. read_dir(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), {Cm, Channel} = ?config(sftp, Config), ReqId = 0, {ok, <<?SSH_FXP_HANDLE, ?UINT32(ReqId), Handle/binary>>, _} = open_dir(PrivDir, Cm, Channel, ReqId), - ok = read_dir(Handle, Cm, Channel, ReqId), - ok. + ok = read_dir(Handle, Cm, Channel, ReqId). %%-------------------------------------------------------------------- -write_file(doc) -> - ["Test SSH_FXP_WRITE command"]; -write_file(suite) -> - []; +write_file() -> + [{doc, "Test SSH_FXP_WRITE command"}]. write_file(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), @@ -311,15 +276,11 @@ write_file(Config) when is_list(Config) -> _/binary>>, _} = write_file(Handle, Data, 0, Cm, Channel, NewReqId), - {ok, Data} = file:read_file(FileName), - - ok. + {ok, Data} = file:read_file(FileName). %%-------------------------------------------------------------------- -remove_file(doc) -> - ["Test SSH_FXP_REMOVE command"]; -remove_file(suite) -> - []; +remove_file() -> + [{doc, "Test SSH_FXP_REMOVE command"}]. remove_file(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), @@ -336,15 +297,11 @@ remove_file(Config) when is_list(Config) -> {ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId), ?UINT32(?SSH_FX_FAILURE), _/binary>>, _} = - remove(PrivDir, Cm, Channel, NewReqId), - - ok. + remove(PrivDir, Cm, Channel, NewReqId). %%-------------------------------------------------------------------- -rename_file(doc) -> - ["Test SSH_FXP_RENAME command"]; -rename_file(suite) -> - []; +rename_file() -> + [{doc, "Test SSH_FXP_RENAME command"}]. rename_file(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), @@ -377,15 +334,11 @@ rename_file(Config) when is_list(Config) -> {ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId2), ?UINT32(?SSH_FX_OP_UNSUPPORTED), _/binary>>, _} = rename(FileName, NewFileName, Cm, Channel, NewReqId2, 6, - ?SSH_FXP_RENAME_ATOMIC), - - ok. + ?SSH_FXP_RENAME_ATOMIC). %%-------------------------------------------------------------------- -mk_rm_dir(doc) -> - ["Test SSH_FXP_MKDIR and SSH_FXP_RMDIR command"]; -mk_rm_dir(suite) -> - []; +mk_rm_dir() -> + [{doc, "Test SSH_FXP_MKDIR and SSH_FXP_RMDIR command"}]. mk_rm_dir(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), {Cm, Channel} = ?config(sftp, Config), @@ -395,7 +348,7 @@ mk_rm_dir(Config) when is_list(Config) -> _/binary>>, _} = mkdir(DirName, Cm, Channel, ReqId), NewReqId = 1, - {ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId), ?UINT32(?SSH_FX_FAILURE), + {ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId), ?UINT32(?SSH_FX_FILE_ALREADY_EXISTS), _/binary>>, _} = mkdir(DirName, Cm, Channel, NewReqId), NewReqId1 = 2, @@ -404,16 +357,13 @@ mk_rm_dir(Config) when is_list(Config) -> NewReqId2 = 3, {ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId2), ?UINT32(?SSH_FX_NO_SUCH_FILE), - _/binary>>, _} = rmdir(DirName, Cm, Channel, NewReqId2), + _/binary>>, _} = rmdir(DirName, Cm, Channel, NewReqId2). - ok. %%-------------------------------------------------------------------- -real_path(doc) -> - ["Test SSH_FXP_REALPATH command"]; -real_path(suite) -> - []; +real_path() -> + [{doc, "Test SSH_FXP_REALPATH command"}]. real_path(Config) when is_list(Config) -> - case test_server:os_type() of + case os:type() of {win32, _} -> {skip, "Not a relevant test on windows"}; _ -> @@ -432,20 +382,14 @@ real_path(Config) when is_list(Config) -> RealPath = filename:absname(binary_to_list(Path)), AbsPrivDir = filename:absname(PrivDir), - test_server:format("Path: ~p PrivDir: ~p~n", [RealPath, AbsPrivDir]), - - true = RealPath == AbsPrivDir, + ct:pal("Path: ~p PrivDir: ~p~n", [RealPath, AbsPrivDir]), - ok + true = RealPath == AbsPrivDir end. %%-------------------------------------------------------------------- -links(doc) -> - []; -links(suite) -> - []; links(Config) when is_list(Config) -> - case test_server:os_type() of + case os:type() of {win32, _} -> {skip, "Links are not fully supported by windows"}; _ -> @@ -467,15 +411,12 @@ links(Config) when is_list(Config) -> true = binary_to_list(Path) == FileName, - test_server:format("Path: ~p~n", [binary_to_list(Path)]), - ok + ct:pal("Path: ~p~n", [binary_to_list(Path)]) end. %%-------------------------------------------------------------------- -retrieve_attributes(doc) -> - ["Test SSH_FXP_STAT, SSH_FXP_LSTAT AND SSH_FXP_FSTAT commands"]; -retrieve_attributes(suite) -> - []; +retrieve_attributes() -> + [{"Test SSH_FXP_STAT, SSH_FXP_LSTAT AND SSH_FXP_FSTAT commands"}]. retrieve_attributes(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), @@ -536,16 +477,13 @@ retrieve_attributes(Config) when is_list(Config) -> Owner = list_to_integer(binary_to_list(BinOwner)), Group = list_to_integer(binary_to_list(BinGroup)) - end, AttrValues), + end, AttrValues). - ok. %%-------------------------------------------------------------------- -set_attributes(doc) -> - ["Test SSH_FXP_SETSTAT AND SSH_FXP_FSETSTAT commands"]; -set_attributes(suite) -> - []; +set_attributes() -> + [{doc, "Test SSH_FXP_SETSTAT AND SSH_FXP_FSETSTAT commands"}]. set_attributes(Config) when is_list(Config) -> - case test_server:os_type() of + case os:type() of {win32, _} -> {skip, "Known error bug in erts file:read_file_info"}; _ -> @@ -574,10 +512,10 @@ set_attributes(Config) when is_list(Config) -> %% Can not test that NewPermissions = Permissions as %% on Unix platforms, other bits than those listed in the %% API may be set. - test_server:format("Org: ~p New: ~p~n", [OrigPermissions, NewPermissions]), + ct:pal("Org: ~p New: ~p~n", [OrigPermissions, NewPermissions]), true = OrigPermissions =/= NewPermissions, - test_server:format("Try to open the file"), + ct:pal("Try to open the file"), NewReqId = 2, {ok, <<?SSH_FXP_HANDLE, ?UINT32(NewReqId), Handle/binary>>, _} = open_file(FileName, Cm, Channel, NewReqId, @@ -589,25 +527,20 @@ set_attributes(Config) when is_list(Config) -> NewReqId1 = 3, - test_server:format("Set original permissions on the now open file"), + ct:pal("Set original permissions on the now open file"), {ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId1), ?UINT32(?SSH_FX_OK), _/binary>>, _} = set_attributes_open_file(Handle, NewAtters, Cm, Channel, NewReqId1), {ok, NewFileInfo1} = file:read_file_info(FileName), - OrigPermissions = NewFileInfo1#file_info.mode, - ok + OrigPermissions = NewFileInfo1#file_info.mode end. %%-------------------------------------------------------------------- -ver3_rename_OTP_6352(doc) -> - ["Test that ver3 rename message is handled"]; - -ver3_rename_OTP_6352(suite) -> - []; - -ver3_rename_OTP_6352(Config) when is_list(Config) -> +ver3_rename() -> + [{doc, "Test that ver3 rename message is handled OTP 6352"}]. +ver3_rename(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), FileName = filename:join(PrivDir, "test.txt"), NewFileName = filename:join(PrivDir, "test1.txt"), @@ -616,22 +549,16 @@ ver3_rename_OTP_6352(Config) when is_list(Config) -> {ok, <<?SSH_FXP_STATUS, ?UINT32(ReqId), ?UINT32(?SSH_FX_OK), _/binary>>, _} = - rename(FileName, NewFileName, Cm, Channel, ReqId, 3, 0), - - ok. + rename(FileName, NewFileName, Cm, Channel, ReqId, 3, 0). %%-------------------------------------------------------------------- -seq10670(doc) -> - ["Check that realpath works ok"]; - -seq10670(suite) -> - []; - -seq10670(Config) when is_list(Config) -> +relpath() -> + [{doc, "Check that realpath works ok seq10670"}]. +relpath(Config) when is_list(Config) -> ReqId = 0, {Cm, Channel} = ?config(sftp, Config), - case test_server:os_type() of + case os:type() of {win32, _} -> {skip, "Not a relevant test on windows"}; _ -> @@ -644,11 +571,46 @@ seq10670(Config) when is_list(Config) -> {ok, <<?SSH_FXP_NAME, ?UINT32(ReqId), ?UINT32(_), ?UINT32(Len), Path:Len/binary, _/binary>>, _} = real_path("/usr/bin/../..", Cm, Channel, ReqId), - Root = Path end. -%% Internal functions +%%-------------------------------------------------------------------- +sshd_read_file() -> + [{doc,"Test SSH_FXP_READ command, using sshd-server"}]. +sshd_read_file(Config) when is_list(Config) -> + PrivDir = ?config(priv_dir, Config), + FileName = filename:join(PrivDir, "test.txt"), + + ReqId = 0, + {Cm, Channel} = ?config(sftp, Config), + + {ok, <<?SSH_FXP_HANDLE, ?UINT32(ReqId), Handle/binary>>, _} = + open_file(FileName, Cm, Channel, ReqId, + ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES, + ?SSH_FXF_OPEN_EXISTING), + + NewReqId = 1, + + {ok, <<?SSH_FXP_DATA, ?UINT32(NewReqId), ?UINT32(_Length), + Data/binary>>, _} = + read_file(Handle, 100, 0, Cm, Channel, NewReqId), + + {ok, Data} = file:read_file(FileName). +%%-------------------------------------------------------------------- +ver6_basic() -> + [{doc, "Test SFTP Version 6"}]. +ver6_basic(Config) when is_list(Config) -> + PrivDir = ?config(priv_dir, Config), + %FileName = filename:join(PrivDir, "test.txt"), + {Cm, Channel} = ?config(sftp, Config), + ReqId = 0, + {ok, <<?SSH_FXP_STATUS, ?UINT32(ReqId), % Ver 6 we have 5 + ?UINT32(?SSH_FX_FILE_IS_A_DIRECTORY), _/binary>>, _} = + open_file(PrivDir, Cm, Channel, ReqId, + ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES, + ?SSH_FXF_OPEN_EXISTING). +%%-------------------------------------------------------------------- +%% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- prep(Config) -> PrivDir = ?config(priv_dir, Config), @@ -684,7 +646,7 @@ reply(Cm, Channel, RBuf) -> {ssh_cm, Cm, {closed, Channel}} -> closed; {ssh_cm, Cm, Msg} -> - test_server:fail(Msg) + ct:fail(Msg) end. @@ -778,7 +740,7 @@ read_dir(Handle, Cm, Channel, ReqId) -> case reply(Cm, Channel) of {ok, <<?SSH_FXP_NAME, ?UINT32(ReqId), ?UINT32(Count), ?UINT32(Len), Listing:Len/binary, _/binary>>, _} -> - test_server:format("Count: ~p Listing: ~p~n", + ct:pal("Count: ~p Listing: ~p~n", [Count, binary_to_list(Listing)]), read_dir(Handle, Cm, Channel, ReqId); {ok, <<?SSH_FXP_STATUS, ?UINT32(ReqId), @@ -921,32 +883,5 @@ encode_file_type(Type) -> undefined -> ?SSH_FILEXFER_TYPE_UNKNOWN end. -%%-------------------------------------------------------------------- -sshd_read_file(doc) -> - ["Test SSH_FXP_READ command, using sshd-server"]; -sshd_read_file(suite) -> - []; -sshd_read_file(Config) when is_list(Config) -> - PrivDir = ?config(priv_dir, Config), - FileName = filename:join(PrivDir, "test.txt"), - - ReqId = 0, - {Cm, Channel} = ?config(sftp, Config), - - {ok, <<?SSH_FXP_HANDLE, ?UINT32(ReqId), Handle/binary>>, _} = - open_file(FileName, Cm, Channel, ReqId, - ?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES, - ?SSH_FXF_OPEN_EXISTING), - - NewReqId = 1, - - {ok, <<?SSH_FXP_DATA, ?UINT32(NewReqId), ?UINT32(_Length), - Data/binary>>, _} = - read_file(Handle, 100, 0, Cm, Channel, NewReqId), - - {ok, Data} = file:read_file(FileName), - - ok. - not_default_permissions() -> 8#600. %% User read-write-only diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl index 4c469ed5f7..cc34cc0793 100644 --- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl +++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2012. All Rights Reserved. +%% Copyright Ericsson AB 2007-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -24,24 +24,32 @@ -compile(export_all). -include_lib("common_test/include/ct.hrl"). --include("test_server_line.hrl"). - -include_lib("kernel/include/file.hrl"). -define(USER, "Alladin"). -define(PASSWD, "Sesame"). -define(SSH_MAX_PACKET_SIZE, 32768). -%% Test server callback functions %%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initiation before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. +%% Common Test interface functions ----------------------------------- +%%-------------------------------------------------------------------- + +suite() -> + [{ct_hooks,[ts_install_cth]}]. + +all() -> + [close_file, + quit, + file_cb, + root_dir, + list_dir_limited, + ver6_basic]. + +groups() -> + []. + %%-------------------------------------------------------------------- + init_per_suite(Config) -> catch ssh:stop(), case catch crypto:start() of @@ -60,12 +68,6 @@ init_per_suite(Config) -> {skip,"Could not start ssh!"} end. -%%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- end_per_suite(Config) -> UserDir = filename:join(?config(priv_dir, Config), nopubkey), file:del_dir(UserDir), @@ -75,18 +77,14 @@ end_per_suite(Config) -> ok. %%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initiation before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initiation before each test case + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. %%-------------------------------------------------------------------- + init_per_testcase(TestCase, Config) -> ssh:start(), PrivDir = ?config(priv_dir, Config), @@ -115,7 +113,12 @@ init_per_testcase(TestCase, Config) -> [{system_dir, SystemDir}, {user_dir, PrivDir}, {subsystems, [Spec]}]; - + "ver6_basic" -> + Spec = + ssh_sftpd:subsystem_spec([{sftpd_vsn, 6}]), + [{system_dir, SystemDir}, + {user_dir, PrivDir}, + {subsystems, [Spec]}]; _ -> [{user_dir, PrivDir}, {system_dir, SystemDir}] @@ -132,53 +135,21 @@ init_per_testcase(TestCase, Config) -> NewConfig = lists:keydelete(sftpd, 1, TmpConfig), [{port, Port}, {sftp, {ChannelPid, Connection}}, {sftpd, Sftpd} | NewConfig]. -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- end_per_testcase(_TestCase, Config) -> catch ssh_sftpd:stop(?config(sftpd, Config)), {Sftp, Connection} = ?config(sftp, Config), catch ssh_sftp:stop_channel(Sftp), catch ssh:close(Connection), - ssh:stop(), - ok. + ssh:stop(). %%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- -all() -> - [close_file_OTP_6350, quit_OTP_6349, file_cb_OTP_6356, - root_dir, list_dir_limited]. - -groups() -> - []. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - -%% Test cases starts here. +%% Test cases starts here. ------------------------------------------- %%-------------------------------------------------------------------- -close_file_OTP_6350(doc) -> - ["Test that sftpd closes its fildescriptors after compleating the " - "transfer"]; - -close_file_OTP_6350(suite) -> - []; +close_file() -> + [{doc, "Test that sftpd closes its fildescriptors after compleating the " + "transfer OTP-6350"}]. -close_file_OTP_6350(Config) when is_list(Config) -> +close_file(Config) when is_list(Config) -> DataDir = ?config(data_dir, Config), FileName = filename:join(DataDir, "test.txt"), @@ -186,28 +157,20 @@ close_file_OTP_6350(Config) when is_list(Config) -> NumOfPorts = length(erlang:ports()), - test_server:format("Number of open ports: ~p~n", [NumOfPorts]), + ct:pal("Number of open ports: ~p~n", [NumOfPorts]), {ok, <<_/binary>>} = ssh_sftp:read_file(Sftp, FileName), - NumOfPorts = length(erlang:ports()), - - test_server:format("Number of open ports: ~p~n", - [length(erlang:ports())]), - - ok. + NumOfPorts = length(erlang:ports()). %%-------------------------------------------------------------------- -quit_OTP_6349(doc) -> - [" When the sftp client ends the session the " +quit() -> + [{doc, " When the sftp client ends the session the " "server will now behave correctly and not leave the " - "client hanging."]; + "client hanging. OTP-6349"}]. -quit_OTP_6349(suite) -> - []; - -quit_OTP_6349(Config) when is_list(Config) -> +quit(Config) when is_list(Config) -> DataDir = ?config(data_dir, Config), FileName = filename:join(DataDir, "test.txt"), UserDir = ?config(priv_dir, Config), @@ -230,19 +193,15 @@ quit_OTP_6349(Config) when is_list(Config) -> {ok, <<_/binary>>} = ssh_sftp:read_file(NewSftp, FileName), - ok = ssh_sftp:stop_channel(NewSftp), - ok. + ok = ssh_sftp:stop_channel(NewSftp). %%-------------------------------------------------------------------- -file_cb_OTP_6356(doc) -> - ["Test that it is possible to change the callback module for" - " the sftpds filehandling."]; +file_cb() -> + [{"Test that it is possible to change the callback module for" + " the sftpds filehandling. OTP-6356"}]. -file_cb_OTP_6356(suite) -> - []; - -file_cb_OTP_6356(Config) when is_list(Config) -> +file_cb(Config) when is_list(Config) -> DataDir = ?config(data_dir, Config), PrivDir = ?config(priv_dir, Config), FileName = filename:join(DataDir, "test.txt"), @@ -279,17 +238,13 @@ file_cb_OTP_6356(Config) when is_list(Config) -> NewDir = filename:join(PrivDir, "testdir"), ok = ssh_sftp:make_dir(Sftp, NewDir), alt_file_handler_check(alt_make_dir), - + ok = ssh_sftp:del_dir(Sftp, NewDir), alt_file_handler_check(alt_read_link_info), alt_file_handler_check(alt_write_file_info), - alt_file_handler_check(alt_del_dir), - ok. + alt_file_handler_check(alt_del_dir). +%%-------------------------------------------------------------------- -root_dir(doc) -> - [""]; -root_dir(suite) -> - []; root_dir(Config) when is_list(Config) -> {Sftp, _} = ?config(sftp, Config), FileName = "test.txt", @@ -298,26 +253,35 @@ root_dir(Config) when is_list(Config) -> {ok, Bin} = ssh_sftp:read_file(Sftp, FileName), {ok, Listing} = ssh_sftp:list_dir(Sftp, "."), - test_server:format("Listing: ~p~n", [Listing]), - ok. + ct:pal("Listing: ~p~n", [Listing]). -list_dir_limited(doc) -> - [""]; -list_dir_limited(suite) -> - []; +%%-------------------------------------------------------------------- list_dir_limited(Config) when is_list(Config) -> {Sftp, _} = ?config(sftp, Config), {ok, Listing} = ssh_sftp:list_dir(Sftp, "."), - test_server:format("Listing: ~p~n", [Listing]), - ok. + ct:pal("Listing: ~p~n", [Listing]). +%%-------------------------------------------------------------------- +ver6_basic() -> + [{doc, "Test some version 6 features"}]. +ver6_basic(Config) when is_list(Config) -> + PrivDir = ?config(priv_dir, Config), + NewDir = filename:join(PrivDir, "testdir2"), + {Sftp, _} = ?config(sftp, Config), + ok = ssh_sftp:make_dir(Sftp, NewDir), + %%Test file_is_a_directory + {error, file_is_a_directory} = ssh_sftp:delete(Sftp, NewDir). +%%-------------------------------------------------------------------- +%% Internal functions ------------------------------------------------ +%%-------------------------------------------------------------------- + alt_file_handler_check(Msg) -> receive Msg -> ok; Other -> - test_server:fail({Msg, Other}) + ct:fail({Msg, Other}) after 10000 -> - test_server:fail("Not alt file handler") + ct:fail("Not alt file handler") end. diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl index 9e119c4929..8ad383d8c9 100644 --- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl +++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -48,7 +48,7 @@ get_cwd(State) -> {file:get_cwd(), State}. is_dir(AbsPath, State) -> - sftpd_file_alt_tester ! alt_is_dir, + %sftpd_file_alt_tester ! alt_is_dir, {filelib:is_dir(AbsPath), State}. list_dir(AbsPath, State) -> diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl index 609663c87a..6ed3dfa68c 100644 --- a/lib/ssh/test/ssh_test_lib.erl +++ b/lib/ssh/test/ssh_test_lib.erl @@ -25,8 +25,7 @@ -compile(export_all). -include_lib("public_key/include/public_key.hrl"). --include("test_server.hrl"). --include("test_server_line.hrl"). +-include_lib("common_test/include/ct.hrl"). -define(TIMEOUT, 50000). @@ -129,16 +128,16 @@ reply(TestCase, Result) -> TestCase ! Result. receive_exec_result(Msg) -> - test_server:format("Expect data! ~p", [Msg]), + ct:pal("Expect data! ~p", [Msg]), receive {ssh_cm,_,{data,_,1, Data}} -> - test_server:format("StdErr: ~p~n", [Data]), + ct:pal("StdErr: ~p~n", [Data]), receive_exec_result(Msg); Msg -> - test_server:format("1: Collected data ~p", [Msg]), + ct:pal("1: Collected data ~p", [Msg]), expected; Other -> - test_server:format("Other ~p", [Other]), + ct:pal("Other ~p", [Other]), {unexpected_msg, Other} end. @@ -150,19 +149,19 @@ receive_exec_end(ConnectionRef, ChannelId) -> case receive_exec_result(ExitStatus) of {unexpected_msg, Eof} -> %% Open ssh seems to not allways send these messages %% in the same order! - test_server:format("2: Collected data ~p", [Eof]), + ct:pal("2: Collected data ~p", [Eof]), case receive_exec_result(ExitStatus) of expected -> expected = receive_exec_result(Closed); {unexpected_msg, Closed} -> - test_server:format("3: Collected data ~p", [Closed]) + ct:pal("3: Collected data ~p", [Closed]) end; expected -> - test_server:format("4: Collected data ~p", [ExitStatus]), + ct:pal("4: Collected data ~p", [ExitStatus]), expected = receive_exec_result(Eof), expected = receive_exec_result(Closed); Other -> - test_server:fail({unexpected_msg, Other}) + ct:fail({unexpected_msg, Other}) end. receive_exec_result(Data, ConnectionRef, ChannelId) -> diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl index c337617ee4..8b5343cecc 100644 --- a/lib/ssh/test/ssh_to_openssh_SUITE.erl +++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -21,7 +21,6 @@ -module(ssh_to_openssh_SUITE). -include_lib("common_test/include/ct.hrl"). --include("test_server_line.hrl"). %% Note: This directive should only be used in test suites. -compile(export_all). @@ -29,76 +28,10 @@ -define(TIMEOUT, 50000). -define(SSH_DEFAULT_PORT, 22). -%% Test server callback functions %%-------------------------------------------------------------------- -%% Function: init_per_suite(Config) -> Config -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Initialization before the whole suite -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%%-------------------------------------------------------------------- -init_per_suite(Config) -> - case catch crypto:start() of - ok -> - case gen_tcp:connect("localhost", 22, []) of - {error,econnrefused} -> - {skip,"No openssh deamon"}; - _ -> - Config - end; - _Else -> - {skip,"Could not start crypto!"} - end. - +%% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> _ -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after the whole suite -%%-------------------------------------------------------------------- -end_per_suite(_Config) -> - crypto:stop(), - ok. -%%-------------------------------------------------------------------- -%% Function: init_per_testcase(TestCase, Config) -> Config -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% -%% Description: Initialization before each test case -%% -%% Note: This function is free to add any key/value pairs to the Config -%% variable, but should NOT alter/remove any existing entries. -%% Description: Initialization before each test case -%%-------------------------------------------------------------------- -init_per_testcase(_TestCase, Config) -> - ssh:start(), - Config. - -%%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> _ -%% Case - atom() -%% Name of the test case that is about to be run. -%% Config - [tuple()] -%% A list of key/value pairs, holding the test case configuration. -%% Description: Cleanup after each test case -%%-------------------------------------------------------------------- -end_per_testcase(_TestCase, _Config) -> - ssh:stop(), - ok. - -%%-------------------------------------------------------------------- -%% Function: all(Clause) -> TestCases -%% Clause - atom() - suite | doc -%% TestCases - [Case] -%% Case - atom() -%% Name of a test case. -%% Description: Returns a list of all test cases in this test suite -%%-------------------------------------------------------------------- all() -> case os:find_executable("ssh") of false -> @@ -116,12 +49,31 @@ groups() -> erlang_client_openssh_server_setenv, erlang_client_openssh_server_publickey_rsa, erlang_client_openssh_server_publickey_dsa, - erlang_client_openssh_server_password]}, + erlang_client_openssh_server_password, + erlang_client_openssh_server_nonexistent_subsystem + ]}, {erlang_server, [], [erlang_server_openssh_client_exec, erlang_server_openssh_client_exec_compressed, erlang_server_openssh_client_pulic_key_dsa]} ]. +init_per_suite(Config) -> + case catch crypto:start() of + ok -> + case gen_tcp:connect("localhost", 22, []) of + {error,econnrefused} -> + {skip,"No openssh deamon"}; + _ -> + Config + end; + _Else -> + {skip,"Could not start crypto!"} + end. + +end_per_suite(_Config) -> + crypto:stop(), + ok. + init_per_group(erlang_server, Config) -> DataDir = ?config(data_dir, Config), UserDir = ?config(priv_dir, Config), @@ -137,13 +89,20 @@ end_per_group(erlang_server, Config) -> end_per_group(_, Config) -> Config. -%% TEST cases starts here. +init_per_testcase(_TestCase, Config) -> + ssh:start(), + Config. + +end_per_testcase(_TestCase, _Config) -> + ssh:stop(), + ok. + +%%-------------------------------------------------------------------- +%% Test Cases -------------------------------------------------------- %%-------------------------------------------------------------------- -erlang_shell_client_openssh_server(doc) -> - ["Test that ssh:shell/2 works"]; -erlang_shell_client_openssh_server(suite) -> - []; +erlang_shell_client_openssh_server() -> + [{doc, "Test that ssh:shell/2 works"}]. erlang_shell_client_openssh_server(Config) when is_list(Config) -> process_flag(trap_exit, true), @@ -159,21 +118,18 @@ erlang_shell_client_openssh_server(Config) when is_list(Config) -> ok end; Other0 -> - test_server:fail({unexpected_msg, Other0}) + ct:fail({unexpected_msg, Other0}) end, receive {'EXIT', Shell, normal} -> ok; Other1 -> - test_server:fail({unexpected_msg, Other1}) + ct:fail({unexpected_msg, Other1}) end. %-------------------------------------------------------------------- -erlang_client_openssh_server_exec(doc) -> - ["Test api function ssh_connection:exec"]; - -erlang_client_openssh_server_exec(suite) -> - []; +erlang_client_openssh_server_exec() -> + [{doc, "Test api function ssh_connection:exec"}]. erlang_client_openssh_server_exec(Config) when is_list(Config) -> ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true}, @@ -187,11 +143,11 @@ erlang_client_openssh_server_exec(Config) when is_list(Config) -> ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId0); {unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} = ExitStatus0} -> - test_server:format("0: Collected data ~p", [ExitStatus0]), + ct:pal("0: Collected data ~p", [ExitStatus0]), ssh_test_lib:receive_exec_result(Data0, ConnectionRef, ChannelId0); Other0 -> - test_server:fail(Other0) + ct:fail(Other0) end, {ok, ChannelId1} = ssh_connection:session_channel(ConnectionRef, infinity), @@ -203,19 +159,16 @@ erlang_client_openssh_server_exec(Config) when is_list(Config) -> ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId1); {unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId1, 0}} = ExitStatus1} -> - test_server:format("0: Collected data ~p", [ExitStatus1]), + ct:pal("0: Collected data ~p", [ExitStatus1]), ssh_test_lib:receive_exec_result(Data1, ConnectionRef, ChannelId1); Other1 -> - test_server:fail(Other1) + ct:fail(Other1) end. %%-------------------------------------------------------------------- -erlang_client_openssh_server_exec_compressed(doc) -> - ["Test that compression option works"]; - -erlang_client_openssh_server_exec_compressed(suite) -> - []; +erlang_client_openssh_server_exec_compressed() -> + [{doc, "Test that compression option works"}]. erlang_client_openssh_server_exec_compressed(Config) when is_list(Config) -> ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true}, @@ -230,18 +183,15 @@ erlang_client_openssh_server_exec_compressed(Config) when is_list(Config) -> ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId); {unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId, 0}} = ExitStatus} -> - test_server:format("0: Collected data ~p", [ExitStatus]), + ct:pal("0: Collected data ~p", [ExitStatus]), ssh_test_lib:receive_exec_result(Data, ConnectionRef, ChannelId); Other -> - test_server:fail(Other) + ct:fail(Other) end. %%-------------------------------------------------------------------- -erlang_server_openssh_client_exec(doc) -> - ["Test that exec command works."]; - -erlang_server_openssh_client_exec(suite) -> - []; +erlang_server_openssh_client_exec() -> + [{doc, "Test that exec command works."}]. erlang_server_openssh_client_exec(Config) when is_list(Config) -> SystemDir = ?config(data_dir, Config), @@ -252,12 +202,12 @@ erlang_server_openssh_client_exec(Config) when is_list(Config) -> {failfun, fun ssh_test_lib:failfun/2}]), - test_server:sleep(500), + ct:sleep(500), Cmd = "ssh -p " ++ integer_to_list(Port) ++ " -o UserKnownHostsFile=" ++ KnownHosts ++ " " ++ Host ++ " 1+1.", - test_server:format("Cmd: ~p~n", [Cmd]), + ct:pal("Cmd: ~p~n", [Cmd]), SshPort = open_port({spawn, Cmd}, [binary]), @@ -265,17 +215,14 @@ erlang_server_openssh_client_exec(Config) when is_list(Config) -> {SshPort,{data, <<"2\n">>}} -> ok after ?TIMEOUT -> - test_server:fail("Did not receive answer") + ct:fail("Did not receive answer") end, ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- -erlang_server_openssh_client_exec_compressed(doc) -> - ["Test that exec command works."]; - -erlang_server_openssh_client_exec_compressed(suite) -> - []; +erlang_server_openssh_client_exec_compressed() -> + [{doc, "Test that exec command works."}]. erlang_server_openssh_client_exec_compressed(Config) when is_list(Config) -> SystemDir = ?config(data_dir, Config), @@ -286,7 +233,7 @@ erlang_server_openssh_client_exec_compressed(Config) when is_list(Config) -> {compression, zlib}, {failfun, fun ssh_test_lib:failfun/2}]), - test_server:sleep(500), + ct:sleep(500), Cmd = "ssh -p " ++ integer_to_list(Port) ++ " -o UserKnownHostsFile=" ++ KnownHosts ++ " -C "++ Host ++ " 1+1.", @@ -296,17 +243,14 @@ erlang_server_openssh_client_exec_compressed(Config) when is_list(Config) -> {SshPort,{data, <<"2\n">>}} -> ok after ?TIMEOUT -> - test_server:fail("Did not receive answer") + ct:fail("Did not receive answer") end, ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- -erlang_client_openssh_server_setenv(doc) -> - ["Test api function ssh_connection:setenv"]; - -erlang_client_openssh_server_setenv(suite) -> - []; +erlang_client_openssh_server_setenv() -> + [{doc, "Test api function ssh_connection:setenv"}]. erlang_client_openssh_server_setenv(Config) when is_list(Config) -> ConnectionRef = @@ -332,15 +276,15 @@ erlang_client_openssh_server_setenv(Config) when is_list(Config) -> {data,0,1, UnxpectedData}}} -> %% Some os may return things as %% ENV_TEST: Undefined variable.\n" - test_server:format("UnxpectedData: ~p", [UnxpectedData]), + ct:pal("UnxpectedData: ~p", [UnxpectedData]), ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId); {unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId, 0}} = ExitStatus} -> - test_server:format("0: Collected data ~p", [ExitStatus]), + ct:pal("0: Collected data ~p", [ExitStatus]), ssh_test_lib:receive_exec_result(Data, ConnectionRef, ChannelId); Other -> - test_server:fail(Other) + ct:fail(Other) end. %%-------------------------------------------------------------------- @@ -348,10 +292,8 @@ erlang_client_openssh_server_setenv(Config) when is_list(Config) -> %% setenv not meaningfull on erlang ssh daemon! %%-------------------------------------------------------------------- -erlang_client_openssh_server_publickey_rsa(doc) -> - ["Validate using rsa publickey."]; -erlang_client_openssh_server_publickey_rsa(suite) -> - []; +erlang_client_openssh_server_publickey_rsa() -> + [{doc, "Validate using rsa publickey."}]. erlang_client_openssh_server_publickey_rsa(Config) when is_list(Config) -> {ok,[[Home]]} = init:get_argument(home), KeyFile = filename:join(Home, ".ssh/id_rsa"), @@ -377,10 +319,8 @@ erlang_client_openssh_server_publickey_rsa(Config) when is_list(Config) -> %%-------------------------------------------------------------------- -erlang_client_openssh_server_publickey_dsa(doc) -> - ["Validate using dsa publickey."]; -erlang_client_openssh_server_publickey_dsa(suite) -> - []; +erlang_client_openssh_server_publickey_dsa() -> + [{doc, "Validate using dsa publickey."}]. erlang_client_openssh_server_publickey_dsa(Config) when is_list(Config) -> {ok,[[Home]]} = init:get_argument(home), KeyFile = filename:join(Home, ".ssh/id_dsa"), @@ -404,12 +344,8 @@ erlang_client_openssh_server_publickey_dsa(Config) when is_list(Config) -> {skip, "no ~/.ssh/id_dsa"} end. %%-------------------------------------------------------------------- -erlang_server_openssh_client_pulic_key_dsa(doc) -> - ["Validate using dsa publickey."]; - -erlang_server_openssh_client_pulic_key_dsa(suite) -> - []; - +erlang_server_openssh_client_pulic_key_dsa() -> + [{doc, "Validate using dsa publickey."}]. erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) -> SystemDir = ?config(data_dir, Config), PrivDir = ?config(priv_dir, Config), @@ -419,7 +355,7 @@ erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) -> {public_key_alg, ssh_dsa}, {failfun, fun ssh_test_lib:failfun/2}]), - test_server:sleep(500), + ct:sleep(500), Cmd = "ssh -p " ++ integer_to_list(Port) ++ " -o UserKnownHostsFile=" ++ KnownHosts ++ @@ -430,17 +366,13 @@ erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) -> {SshPort,{data, <<"2\n">>}} -> ok after ?TIMEOUT -> - test_server:fail("Did not receive answer") + ct:fail("Did not receive answer") end, ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- -erlang_client_openssh_server_password(doc) -> - ["Test client password option"]; - -erlang_client_openssh_server_password(suite) -> - []; - +erlang_client_openssh_server_password() -> + [{doc, "Test client password option"}]. erlang_client_openssh_server_password(Config) when is_list(Config) -> %% to make sure we don't public-key-auth UserDir = ?config(data_dir, Config), @@ -451,7 +383,7 @@ erlang_client_openssh_server_password(Config) when is_list(Config) -> {user_interaction, false}, {user_dir, UserDir}]), - test_server:format("Test of user foo that does not exist. " + ct:pal("Test of user foo that does not exist. " "Error msg: ~p~n", [Reason0]), User = string:strip(os:cmd("whoami"), right, $\n), @@ -465,25 +397,39 @@ erlang_client_openssh_server_password(Config) when is_list(Config) -> {password, "foo"}, {user_interaction, false}, {user_dir, UserDir}]), - test_server:format("Test of wrong Pasword. " + ct:pal("Test of wrong Pasword. " "Error msg: ~p~n", [Reason1]); _ -> - test_server:format("Whoami failed reason: ~n", []) + ct:pal("Whoami failed reason: ~n", []) end. %%-------------------------------------------------------------------- + +erlang_client_openssh_server_nonexistent_subsystem() -> + [{doc, "Test client password option"}]. +erlang_client_openssh_server_nonexistent_subsystem(Config) when is_list(Config) -> + + ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, + [{user_interaction, false}, + silently_accept_hosts]), + + {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity), + + failure = ssh_connection:subsystem(ConnectionRef, ChannelId, "foo", infinity). + +%%-------------------------------------------------------------------- % %% Not possible to send password with openssh without user interaction %% %%-------------------------------------------------------------------- %%-------------------------------------------------------------------- -%%% Internal functions +%%% Internal functions ----------------------------------------------- %%-------------------------------------------------------------------- receive_hej() -> receive <<"Hej\n">> = Hej-> - test_server:format("Expected result: ~p~n", [Hej]); + ct:pal("Expected result: ~p~n", [Hej]); Info -> - test_server:format("Extra info: ~p~n", [Info]), + ct:pal("Extra info: ~p~n", [Info]), receive_hej() end. |