diff options
Diffstat (limited to 'lib/ssh/test/ssh_test_lib.erl')
-rw-r--r-- | lib/ssh/test/ssh_test_lib.erl | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl new file mode 100644 index 0000000000..2eb19cec22 --- /dev/null +++ b/lib/ssh/test/ssh_test_lib.erl @@ -0,0 +1,189 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2010. 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_test_lib). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +start_shell(Port, IOServer) -> + spawn_link(?MODULE, init_shell, [Port, IOServer]). + +init_shell(Port, IOServer) -> + Host = ssh_test_lib:hostname(), + UserDir = ssh_test_lib:get_user_dir(), + Options = [{user_interaction, false}, {silently_accept_hosts, + true}] ++ UserDir, + group_leader(IOServer, self()), + loop_shell(Host, Port, Options). + +loop_shell(Host, Port, Options) -> + ssh:shell(Host, Port, Options). + +start_io_server() -> + spawn_link(?MODULE, init_io_server, [self()]). + +init_io_server(TestCase) -> + process_flag(trap_exit, true), + loop_io_server(TestCase, []). + +loop_io_server(TestCase, Buff0) -> + receive + {input, TestCase, Line} -> + %io:format("~p~n",[{input, TestCase, Line}]), + loop_io_server(TestCase, Buff0 ++ [Line]); + {io_request, From, ReplyAs, Request} -> + %io:format("request -> ~p~n",[Request]), + {ok, Reply, Buff} = io_request(Request, TestCase, From, + ReplyAs, Buff0), + %io:format("reply -> ~p~n",[Reply]), + io_reply(From, ReplyAs, Reply), + loop_io_server(TestCase, Buff); + {'EXIT',_, _} -> + erlang:display('EXIT'), + ok + end. + +io_request({put_chars, Chars}, TestCase, _, _, Buff) -> + reply(TestCase, Chars), + {ok, ok, Buff}; +io_request({put_chars, Enc, Chars}, TestCase, _, _, Buff) -> + reply(TestCase, unicode:characters_to_binary(Chars,Enc,latin1)), + {ok, ok, Buff}; + +io_request({get_line, _} = Request, _, From, ReplyAs, [] = Buff) -> + erlang:send_after(1000, self(), {io_request, From, ReplyAs, Request}), + {ok, [], Buff}; +io_request({get_line, _Enc, _Prompt} = Request, _, From, ReplyAs, [] = Buff) -> + erlang:send_after(1000, self(), {io_request, From, ReplyAs, Request}), + {ok, [], Buff}; + +io_request({get_line, _Enc,_}, _, _, _, [Line | Buff]) -> + {ok, Line, Buff}. + +io_reply(_, _, []) -> + ok; +io_reply(From, ReplyAs, Reply) -> + From ! {io_reply, ReplyAs, Reply}. + +reply(_, []) -> + ok; +reply(TestCase, Result) -> + TestCase ! Result. + +receive_exec_result(Msg) -> + test_server:format("Expect data! ~p", [Msg]), + receive + Msg -> + test_server:format("1: Collected data ~p", [Msg]), + expected; + Other -> + {unexpected_msg, Other} + end. +receive_exec_end(ConnectionRef, ChannelId) -> + Eof = {ssh_cm, ConnectionRef, {eof, ChannelId}}, + ExitStatus = {ssh_cm, ConnectionRef, {exit_status, ChannelId, 0}}, + Closed = {ssh_cm, ConnectionRef,{closed, 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]), + case receive_exec_result(ExitStatus) of + expected -> + expected = receive_exec_result(Closed); + {unexpected_msg, Closed} -> + test_server:format("3: Collected data ~p", [Closed]) + end; + expected -> + test_server:format("4: Collected data ~p", [ExitStatus]), + expected = receive_exec_result(Eof), + expected = receive_exec_result(Closed); + Other -> + test_server:fail({unexpected_msg, Other}) + end. + +receive_exec_result(Data, ConnectionRef, ChannelId) -> + Eof = {ssh_cm, ConnectionRef, {eof, ChannelId}}, + Closed = {ssh_cm, ConnectionRef,{closed, ChannelId}}, + expected = ssh_test_lib:receive_exec_result(Data), + expected = ssh_test_lib:receive_exec_result(Eof), + expected = ssh_test_lib:receive_exec_result(Closed). + + +inet_port()-> + {ok, Socket} = gen_tcp:listen(0, [{reuseaddr, true}]), + {ok, Port} = inet:port(Socket), + gen_tcp:close(Socket), + Port. + + +%% copy private keys to given dir from ~/.ssh +get_id_keys(DstDir) -> + SrcDir = filename:join(os:getenv("HOME"), ".ssh"), + RsaOk = copyfile(SrcDir, DstDir, "id_rsa"), + DsaOk = copyfile(SrcDir, DstDir, "id_dsa"), + case {RsaOk, DsaOk} of + {{ok, _}, {ok, _}} -> {ok, both}; + {{ok, _}, _} -> {ok, rsa}; + {_, {ok, _}} -> {ok, dsa}; + {Error, _} -> Error + end. + +remove_id_keys(Dir) -> + file:delete(filename:join(Dir, "id_rsa")), + file:delete(filename:join(Dir, "id_dsa")). + +copyfile(SrcDir, DstDir, Fn) -> + file:copy(filename:join(SrcDir, Fn), + filename:join(DstDir, Fn)). + +failfun(_User, {authmethod,none}) -> + ok; +failfun(User, Reason) -> + error_logger:format("~p failed XXX to login: ~p~n", [User, Reason]). + +hostname() -> + {ok,Host} = inet:gethostname(), + Host. + +save_known_hosts(PrivDir) -> + Src = ssh_file:file_name(user, "known_hosts", []), + Dst = filename:join(PrivDir, "kh_save"), + Ok = file:copy(Src, Dst), + io:format("save ~p -> ~p : ~p", [Src, Dst, Ok]). + +restore_known_hosts(_PrivDir) -> + %% Race condition. + ok. +%% Src = filename:join(PrivDir, "kh_save"), +%% Dst = ssh_file:file_name(user, "known_hosts", []), +%% D1 = file:delete(Dst), +%% C = file:copy(Src, Dst), +%% D2 = file:delete(Src), +%% io:format("restore ~p -> ~p : ~p ~p ~p\n", [Src, Dst, D1, C, D2]). + +get_user_dir() -> + case os:type() of + {win32, _} -> + [{user_dir, filename:join([os:getenv("HOME"), ".ssh"])}]; + _ -> + [] + end. |