diff options
Diffstat (limited to 'lib/ssh/test/ssh_connection_SUITE.erl')
-rw-r--r-- | lib/ssh/test/ssh_connection_SUITE.erl | 151 |
1 files changed, 110 insertions, 41 deletions
diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl index a52633a269..bcf3b01824 100644 --- a/lib/ssh/test/ssh_connection_SUITE.erl +++ b/lib/ssh/test/ssh_connection_SUITE.erl @@ -43,6 +43,7 @@ suite() -> all() -> [ {group, openssh}, + small_interrupted_send, interrupted_send, start_shell, start_shell_exec, @@ -81,7 +82,7 @@ sock() -> %%-------------------------------------------------------------------- init_per_suite(Config) -> - Config. + ?CHECK_CRYPTO(Config). end_per_suite(Config) -> Config. @@ -124,7 +125,7 @@ simple_exec(Config) when is_list(Config) -> do_simple_exec(ConnectionRef). -simple_exec_sock(Config) -> +simple_exec_sock(_Config) -> {ok, Sock} = gen_tcp:connect("localhost", ?SSH_DEFAULT_PORT, [{active,false}]), {ok, ConnectionRef} = ssh:connect(Sock, [{silently_accept_hosts, true}, {user_interaction, false}]), @@ -361,44 +362,96 @@ ptty_alloc_pixel(Config) when is_list(Config) -> ssh:close(ConnectionRef). %%-------------------------------------------------------------------- +small_interrupted_send(Config) -> + K = 1024, + M = K*K, + do_interrupted_send(Config, 10*M, 4*K). interrupted_send(Config) -> + M = 1024*1024, + do_interrupted_send(Config, 10*M, 4*M). + +do_interrupted_send(Config, SendSize, EchoSize) -> PrivDir = proplists:get_value(priv_dir, Config), UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth file:make_dir(UserDir), SysDir = proplists:get_value(data_dir, Config), + EchoSS_spec = {ssh_echo_server, [EchoSize,[{dbg,true}]]}, {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir}, {user_dir, UserDir}, {password, "morot"}, - {subsystems, [{"echo_n", {ssh_echo_server, [4000000]}}]}]), - + {subsystems, [{"echo_n",EchoSS_spec}]}]), + + ct:log("connect", []), 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). + ct:log("connected", []), + + %% build big binary + Data = << <<X:32>> || X <- lists:seq(1,SendSize div 4)>>, + + %% expect remote end to send us EchoSize back + <<ExpectedData:EchoSize/binary, _/binary>> = Data, + + %% Spawn listener. Otherwise we could get a deadlock due to filled buffers + Parent = self(), + ResultPid = spawn( + fun() -> + ct:log("open channel",[]), + {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity), + ct:log("start subsystem", []), + case ssh_connection:subsystem(ConnectionRef, ChannelId, "echo_n", infinity) of + success -> + Parent ! {self(), channelId, ChannelId}, + + Result = + try collect_data(ConnectionRef, ChannelId) + of + ExpectedData -> + ok; + _ -> + {fail,"unexpected result"} + catch + Class:Exception -> + {fail, io_lib:format("Exception ~p:~p",[Class,Exception])} + end, + Parent ! {self(), Result}; + Other -> + Parent ! {self(), channelId, error, Other} + end + end), + + receive + {ResultPid, channelId, ChannelId} -> + %% pre-adjust receive window so the other end doesn't block + ct:log("adjust window", []), + ssh_connection:adjust_window(ConnectionRef, ChannelId, size(ExpectedData) + 1), + + ct:log("going to send ~p bytes", [size(Data)]), + case ssh_connection:send(ConnectionRef, ChannelId, Data, 30000) of + {error, closed} -> + ct:log("{error,closed} - That's what we expect :)", []), + ok; + Msg -> + ct:log("Got ~p - that's bad, very bad indeed",[Msg]), + ct:fail({expected,{error,closed}, got, Msg}) + end, + ct:log("going to check the result (if it is available)", []), + receive + {ResultPid, Result} -> + ct:log("Got result: ~p", [Result]), + ssh:close(ConnectionRef), + ssh:stop_daemon(Pid), + Result + end; + + {ResultPid, channelId, error, Other} -> + ssh:close(ConnectionRef), + ssh:stop_daemon(Pid), + {fail, io_lib:format("ssh_connection:subsystem: ~p",[Other])} + end. %%-------------------------------------------------------------------- start_shell() -> @@ -549,10 +602,10 @@ start_shell_sock_daemon_exec(Config) -> spawn_link(fun() -> {ok,Ss} = gen_tcp:connect("localhost", Port, [{active,false}]), - {ok, Pid} = ssh:daemon(Ss, [{system_dir, SysDir}, - {user_dir, UserDir}, - {password, "morot"}, - {exec, fun ssh_exec/1}]) + {ok, _Pid} = ssh:daemon(Ss, [{system_dir, SysDir}, + {user_dir, UserDir}, + {password, "morot"}, + {exec, fun ssh_exec/1}]) end), {ok,Sc} = gen_tcp:accept(Sl), {ok,ConnectionRef} = ssh:connect(Sc, [{silently_accept_hosts, true}, @@ -856,20 +909,36 @@ big_cat_rx(ConnectionRef, ChannelId, Acc) -> timeout end. -receive_data(ExpectedData, ConnectionRef, ChannelId) -> - ExpectedData = collect_data(ConnectionRef, ChannelId). - collect_data(ConnectionRef, ChannelId) -> - collect_data(ConnectionRef, ChannelId, []). + ct:log("Listener ~p running! ConnectionRef=~p, ChannelId=~p",[self(),ConnectionRef,ChannelId]), + collect_data(ConnectionRef, ChannelId, [], 0). -collect_data(ConnectionRef, ChannelId, Acc) -> +collect_data(ConnectionRef, ChannelId, Acc, Sum) -> + TO = 5000, receive - {ssh_cm, ConnectionRef, {data, ChannelId, 0, Data}} -> - collect_data(ConnectionRef, ChannelId, [Data | Acc]); + {ssh_cm, ConnectionRef, {data, ChannelId, 0, Data}} when is_binary(Data) -> + ct:log("collect_data: received ~p bytes. total ~p bytes",[size(Data),Sum+size(Data)]), + collect_data(ConnectionRef, ChannelId, [Data | Acc], Sum+size(Data)); {ssh_cm, ConnectionRef, {eof, ChannelId}} -> - iolist_to_binary(lists:reverse(Acc)) - after 5000 -> - timeout + try + iolist_to_binary(lists:reverse(Acc)) + of + Bin -> + ct:log("collect_data: received eof.~nGot in total ~p bytes",[size(Bin)]), + Bin + catch + C:E -> + ct:log("collect_data: received eof.~nAcc is strange...~nException=~p:~p~nAcc=~p", + [C,E,Acc]), + {error,{C,E}} + end; + Msg -> + ct:log("collect_data: ***** unexpected message *****~n~p",[Msg]), + collect_data(ConnectionRef, ChannelId, Acc, Sum) + + after TO -> + ct:log("collect_data: ----- Nothing received for ~p seconds -----~n",[]), + collect_data(ConnectionRef, ChannelId, Acc, Sum) end. %%%------------------------------------------------------------------- |