diff options
Diffstat (limited to 'lib/inets/test')
-rw-r--r-- | lib/inets/test/Makefile | 55 | ||||
-rw-r--r-- | lib/inets/test/ftp_SUITE.erl | 1180 | ||||
-rw-r--r-- | lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel | 18 | ||||
-rw-r--r-- | lib/inets/test/ftp_SUITE_data/vsftpd.conf | 26 | ||||
-rw-r--r-- | lib/inets/test/ftp_format_SUITE.erl | 328 | ||||
l--------- | lib/inets/test/ftp_internal.hrl | 1 | ||||
-rw-r--r-- | lib/inets/test/ftp_property_test_SUITE.erl | 53 | ||||
-rw-r--r-- | lib/inets/test/inets_SUITE.erl | 77 | ||||
-rw-r--r-- | lib/inets/test/inets_socketwrap_SUITE.erl | 34 | ||||
-rw-r--r-- | lib/inets/test/inets_sup_SUITE.erl | 52 | ||||
-rw-r--r-- | lib/inets/test/tftp_SUITE.erl | 949 | ||||
-rw-r--r-- | lib/inets/test/tftp_test_lib.erl | 308 | ||||
-rw-r--r-- | lib/inets/test/tftp_test_lib.hrl | 44 |
13 files changed, 9 insertions, 3116 deletions
diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile index 99a7e6a9db..0e33b72095 100644 --- a/lib/inets/test/Makefile +++ b/lib/inets/test/Makefile @@ -44,8 +44,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN) INCLUDES = -I. \ -I$(ERL_TOP)/lib/inets/src/inets_app \ -I$(ERL_TOP)/lib/inets/src/http_lib \ - -I$(ERL_TOP)/lib/inets/src/http_client \ - -I$(ERL_TOP)/lib/inets/src/ftp + -I$(ERL_TOP)/lib/inets/src/http_client CP = cp @@ -68,34 +67,6 @@ INETS_FLAGS = -Dinets_data_dir='"$(INETS_DATA_DIR)"' \ ### ### test suite debug flags ### -ifeq ($(FTP_DEBUG_CLIENT),) - FTP_DEBUG_CLIENT = y -endif - -ifeq ($(FTP_DEBUG_CLIENT),) - FTP_FLAGS += -Dftp_debug_client -endif - -ifeq ($(FTP_TRACE_CLIENT),) - FTP_DEBUG_CLIENT = y -endif - -ifeq ($(FTP_TRACE_CLIENT),y) - FTP_FLAGS += -Dftp_trace_client -endif - -ifneq ($(FTP_DEBUG),) - FTP_DEBUG = s -endif - -ifeq ($(FTP_DEBUG),l) - FTP_FLAGS += -Dftp_log -endif - -ifeq ($(FTP_DEBUG),d) - FTP_FLAGS += -Dftp_debug -Dftp_log -endif - ifeq ($(INETS_DEBUG),) INETS_DEBUG = d endif @@ -151,8 +122,6 @@ MODULES = \ inets_test_lib \ erl_make_certs \ make_certs \ - ftp_SUITE \ - ftp_format_SUITE \ http_format_SUITE \ httpc_SUITE \ httpc_cookie_SUITE \ @@ -169,8 +138,6 @@ MODULES = \ httpd_test_lib \ inets_sup_SUITE \ inets_SUITE \ - tftp_test_lib \ - tftp_SUITE \ uri_SUITE \ inets_socketwrap_SUITE @@ -179,10 +146,8 @@ EBIN = . HRL_FILES = inets_test_lib.hrl \ inets_internal.hrl \ - ftp_internal.hrl \ httpc_internal.hrl \ - http_internal.hrl \ - tftp_test_lib.hrl + http_internal.hrl ERL_FILES = $(MODULES:%=%.erl) @@ -197,18 +162,15 @@ INETS_FILES = inets.config $(INETS_SPECS) # SUB_SUITES = \ # inets_sup_suite \ # inets_httpd_suite \ -# inets_httpc_suite \ -# inets_ftp_suite \ -# inets_tftp_suite +# inets_httpc_suite INETS_DATADIRS = inets_SUITE_data inets_socketwrap_SUITE_data HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data httpd_basic_SUITE_data old_httpd_SUITE_data httpd_bench_SUITE_data HTTPC_DATADIRS = httpc_SUITE_data httpc_proxy_SUITE_data -FTP_DATADIRS = ftp_SUITE_data -DATADIRS = $(INETS_DATADIRS) $(HTTPD_DATADIRS) $(HTTPC_DATADIRS) $(FTP_DATADIRS) +DATADIRS = $(INETS_DATADIRS) $(HTTPD_DATADIRS) $(HTTPC_DATADIRS) EMAKEFILE = Emakefile MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile) @@ -238,7 +200,6 @@ RELTESTSYSBINDIR = $(RELTESTSYSALLDATADIR)/bin # ---------------------------------------------------- ERL_COMPILE_FLAGS += \ $(INCLUDES) \ - $(FTP_FLAGS) \ $(INETS_FLAGS) # ---------------------------------------------------- @@ -334,11 +295,3 @@ info: @echo "INETS_PRIV_DIR = $(INETS_PRIV_DIR)" @echo "INETS_ROOT = $(INETS_ROOT)" @echo "INETS_FLAGS = $(INETS_FLAGS)" - @echo "FTP_FLAGS = $(FTP_FLAGS)" - -tftp: - erlc $(ERL_COMPILE_FLAGS) tftp_test_lib.erl tftp_SUITE.erl && erl -pa ../../inets/ebin -s tftp_SUITE t -s erlang halt - -tftp_work: - echo "tftp_test_lib:t([{tftp_SUITE, all}])." - erlc $(ERL_COMPILE_FLAGS) tftp_test_lib.erl tftp_SUITE.erl && erl -pa ../../inets/ebin diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl deleted file mode 100644 index 3dfec01ba2..0000000000 --- a/lib/inets/test/ftp_SUITE.erl +++ /dev/null @@ -1,1180 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2017. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% -%% - -%% -%% ct:run("../inets_test", ftp_SUITE). -%% - --module(ftp_SUITE). - --include_lib("kernel/include/file.hrl"). --include_lib("common_test/include/ct.hrl"). --include("inets_test_lib.hrl"). - -%% Note: This directive should only be used in test suites. --compile(export_all). - --define(FTP_USER, "anonymous"). --define(FTP_PASS(Cmnt), (fun({ok,__H}) -> "ftp_SUITE_"++Cmnt++"@" ++ __H; - (_) -> "ftp_SUITE_"++Cmnt++"@localhost" - end)(inet:gethostname()) - ). - --define(BAD_HOST, "badhostname"). --define(BAD_USER, "baduser"). --define(BAD_DIR, "baddirectory"). - --record(progress, { - current = 0, - total - }). - -%%-------------------------------------------------------------------- -%% Common Test interface functions ----------------------------------- -%%-------------------------------------------------------------------- -suite() -> - [{timetrap,{seconds,20}}]. - -all() -> - [ - {group, ftp_passive}, - {group, ftp_active}, - {group, ftps_passive}, - {group, ftps_active}, - error_ehost, - clean_shutdown - ]. - -groups() -> - [ - {ftp_passive, [], ftp_tests()}, - {ftp_active, [], ftp_tests()}, - {ftps_passive, [], ftp_tests()}, - {ftps_active, [], ftp_tests()} - ]. - -ftp_tests()-> - [ - user, - bad_user, - pwd, - cd, - lcd, - ls, - nlist, - rename, - delete, - mkdir, - rmdir, - send, - send_3, - send_bin, - send_chunk, - append, - append_bin, - append_chunk, - recv, - recv_3, - recv_bin, - recv_bin_twice, - recv_chunk, - recv_chunk_twice, - recv_chunk_three_times, - type, - quote, - error_elogin, - progress_report_send, - progress_report_recv, - not_owner, - unexpected_call, - unexpected_cast, - unexpected_bang - ]. - -%%-------------------------------------------------------------------- - -%%% Config -%%% key meaning -%%% ................................................................ -%%% ftpservers list of servers to check if they are available -%%% The element is: -%%% {Name, % string(). The os command name -%%% Path, % string(). The os PATH syntax, e.g "/bin:/usr/bin" -%%% StartCommand, % fun()->{ok,start_result()} | {error,string()}. -%%% % The command to start the daemon with. -%%% ChkUp, % fun(start_result()) -> string(). Os command to check -%%% % if the server is running. [] if not running. -%%% % The string in string() is suitable for logging. -%%% StopCommand, % fun(start_result()) -> void(). The command to stop the daemon with. -%%% AugmentFun, % fun(config()) -> config() Adds two funs for transforming names of files -%%% % and directories to the form they are returned from this server -%%% ServerHost, % string(). Mostly "localhost" -%%% ServerPort % pos_integer() -%%% } -%%% - --define(default_ftp_servers, - [{"vsftpd", - "/sbin:/usr/sbin:/usr/local/sbin", - fun(__CONF__, AbsName) -> - DataDir = proplists:get_value(data_dir,__CONF__), - ConfFile = filename:join(DataDir, "vsftpd.conf"), - PrivDir = proplists:get_value(priv_dir,__CONF__), - AnonRoot = PrivDir, - Cmd = [AbsName ++" "++filename:join(DataDir,"vsftpd.conf"), - " -oftpd_banner=erlang_otp_testing", - " -oanon_root=\"",AnonRoot,"\"", - " -orsa_cert_file=\"",filename:join(DataDir,"server-cert.pem"),"\"", - " -orsa_private_key_file=\"",filename:join(DataDir,"server-key.pem"),"\"" - ], - Result = os:cmd(Cmd), - ct:log("Config file:~n~s~n~nServer start command:~n ~s~nResult:~n ~p", - [case file:read_file(ConfFile) of - {ok,X} -> X; - _ -> "" - end, - Cmd, Result - ]), - case Result of - [] -> {ok,'dont care'}; - [Msg] -> {error,Msg} - end - end, - fun(_StartResult) -> os:cmd("ps ax | grep erlang_otp_testing | grep -v grep") - end, - fun(_StartResult) -> os:cmd("kill `ps ax | grep erlang_otp_testing | awk '/vsftpd/{print $1}'`") - end, - fun(__CONF__) -> - AnonRoot = proplists:get_value(priv_dir,__CONF__), - [{id2ftp, fun(Id) -> filename:join(AnonRoot,Id) end}, - {id2ftp_result,fun(Id) -> filename:join(AnonRoot,Id) end} | __CONF__] - end, - "localhost", - 9999 - } - ] - ). - - -init_per_suite(Config) -> - case find_executable(Config) of - false -> - {skip, "No ftp server found"}; - {ok,Data} -> - TstDir = filename:join(proplists:get_value(priv_dir,Config), "test"), - file:make_dir(TstDir), - make_cert_files(dsa, rsa, "server-", proplists:get_value(data_dir,Config)), - start_ftpd([{test_dir,TstDir}, - {ftpd_data,Data} - | Config]) - end. - -end_per_suite(Config) -> - ps_ftpd(Config), - stop_ftpd(Config), - ps_ftpd(Config), - ok. - -%%-------------------------------------------------------------------- -init_per_group(Group, Config) when Group == ftps_active, - Group == ftps_passive -> - catch crypto:stop(), - try crypto:start() of - ok -> - Config - catch - _:_ -> - {skip, "Crypto did not start"} - end; - -init_per_group(_Group, Config) -> - Config. - -end_per_group(_Group, Config) -> - Config. - -%%-------------------------------------------------------------------- -init_per_testcase(Case, Config0) -> - Group = proplists:get_value(name, proplists:get_value(tc_group_properties,Config0)), - TLS = [{tls,[{reuse_sessions,true}]}], - ACTIVE = [{mode,active}], - PASSIVE = [{mode,passive}], - CaseOpts = case Case of - progress_report_send -> [{progress, {?MODULE,progress,#progress{}}}]; - progress_report_recv -> [{progress, {?MODULE,progress,#progress{}}}]; - _ -> [] - end, - ExtraOpts = [verbose | CaseOpts], - Config = - case Group of - ftp_active -> ftp__open(Config0, ACTIVE ++ ExtraOpts); - ftps_active -> ftp__open(Config0, TLS++ ACTIVE ++ ExtraOpts); - ftp_passive -> ftp__open(Config0, PASSIVE ++ ExtraOpts); - ftps_passive -> ftp__open(Config0, TLS++PASSIVE ++ ExtraOpts); - undefined -> Config0 - end, - case Case of - user -> Config; - bad_user -> Config; - error_elogin -> Config; - error_ehost -> Config; - clean_shutdown -> Config; - _ -> - Pid = proplists:get_value(ftp,Config), - ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS(atom_to_list(Group)++"-"++atom_to_list(Case)) ), - ok = ftp:cd(Pid, proplists:get_value(priv_dir,Config)), - Config - end. - - -end_per_testcase(user, _Config) -> ok; -end_per_testcase(bad_user, _Config) -> ok; -end_per_testcase(error_elogin, _Config) -> ok; -end_per_testcase(error_ehost, _Config) -> ok; -end_per_testcase(clean_shutdown, _Config) -> ok; -end_per_testcase(_Case, Config) -> - case proplists:get_value(tc_status,Config) of - ok -> ok; - _ -> - try ftp:latest_ctrl_response(proplists:get_value(ftp,Config)) - of - {ok,S} -> ct:log("***~n*** Latest ctrl channel response:~n*** ~p~n***",[S]) - catch - _:_ -> ok - end - end, - ftp__close(Config). - -%%-------------------------------------------------------------------- -%% Test Cases -------------------------------------------------------- -%%-------------------------------------------------------------------- -user() -> [ - {doc, "Open an ftp connection to a host, and logon as anonymous ftp," - " then logoff"}]. -user(Config) -> - Pid = proplists:get_value(ftp, Config), - ok = ftp:user(Pid, ?FTP_USER, ?FTP_PASS("")),% logon - ok = ftp:close(Pid), % logoff - {error,eclosed} = ftp:pwd(Pid), % check logoff result - ok. - -%%------------------------------------------------------------------------- -bad_user() -> - [{doc, "Open an ftp connection to a host, and logon with bad user."}]. -bad_user(Config) -> - Pid = proplists:get_value(ftp, Config), - {error, euser} = ftp:user(Pid, ?BAD_USER, ?FTP_PASS("")), - ok. - -%%------------------------------------------------------------------------- -pwd() -> - [{doc, "Test ftp:pwd/1 & ftp:lpwd/1"}]. -pwd(Config0) -> - Config = set_state([reset], Config0), - Pid = proplists:get_value(ftp, Config), - {ok, PWD} = ftp:pwd(Pid), - {ok, PathLpwd} = ftp:lpwd(Pid), - PWD = id2ftp_result("", Config), - PathLpwd = id2ftp_result("", Config). - -%%------------------------------------------------------------------------- -cd() -> - ["Open an ftp connection, log on as anonymous ftp, and cd to a" - "directory and to a non-existent directory."]. -cd(Config0) -> - Dir = "test", - Config = set_state([reset,{mkdir,Dir}], Config0), - Pid = proplists:get_value(ftp, Config), - ok = ftp:cd(Pid, id2ftp(Dir,Config)), - {ok, PWD} = ftp:pwd(Pid), - ExpectedPWD = id2ftp_result(Dir, Config), - PWD = ExpectedPWD, - {error, epath} = ftp:cd(Pid, ?BAD_DIR), - ok. - -%%------------------------------------------------------------------------- -lcd() -> - [{doc, "Test api function ftp:lcd/2"}]. -lcd(Config0) -> - Dir = "test", - Config = set_state([reset,{mkdir,Dir}], Config0), - Pid = proplists:get_value(ftp, Config), - ok = ftp:lcd(Pid, id2ftp(Dir,Config)), - {ok, PWD} = ftp:lpwd(Pid), - ExpectedPWD = id2ftp_result(Dir, Config), - PWD = ExpectedPWD, - {error, epath} = ftp:lcd(Pid, ?BAD_DIR). - -%%------------------------------------------------------------------------- -ls() -> - [{doc, "Open an ftp connection; ls the current directory, and the " - "\"test\" directory. We assume that ls never fails, since " - "it's output is meant to be read by humans. "}]. -ls(Config0) -> - Config = set_state([reset,{mkdir,"test"}], Config0), - Pid = proplists:get_value(ftp, Config), - {ok, _R1} = ftp:ls(Pid), - {ok, _R2} = ftp:ls(Pid, id2ftp("test",Config)), - %% neither nlist nor ls operates on a directory - %% they operate on a pathname, which *can* be a - %% directory, but can also be a filename or a group - %% of files (including wildcards). - case proplists:get_value(wildcard_support, Config) of - true -> - {ok, _R3} = ftp:ls(Pid, id2ftp("te*",Config)); - _ -> - ok - end. - -%%------------------------------------------------------------------------- -nlist() -> - [{doc,"Open an ftp connection; nlist the current directory, and the " - "\"test\" directory. Nlist does not behave consistenly over " - "operating systems. On some it is an error to have an empty " - "directory."}]. -nlist(Config0) -> - Config = set_state([reset,{mkdir,"test"}], Config0), - Pid = proplists:get_value(ftp, Config), - {ok, _R1} = ftp:nlist(Pid), - {ok, _R2} = ftp:nlist(Pid, id2ftp("test",Config)), - %% neither nlist nor ls operates on a directory - %% they operate on a pathname, which *can* be a - %% directory, but can also be a filename or a group - %% of files (including wildcards). - case proplists:get_value(wildcard_support, Config) of - true -> - {ok, _R3} = ftp:nlist(Pid, id2ftp("te*",Config)); - _ -> - ok - end. - -%%------------------------------------------------------------------------- -rename() -> - [{doc, "Rename a file."}]. -rename(Config0) -> - Contents = <<"ftp_SUITE test ...">>, - OldFile = "old.txt", - NewFile = "new.txt", - Config = set_state([reset,{mkfile,OldFile,Contents}], Config0), - Pid = proplists:get_value(ftp, Config), - - ok = ftp:rename(Pid, - id2ftp(OldFile,Config), - id2ftp(NewFile,Config)), - - true = (chk_file(NewFile,Contents,Config) - and chk_no_file([OldFile],Config)), - {error,epath} = ftp:rename(Pid, - id2ftp("non_existing_file",Config), - id2ftp(NewFile,Config)), - ok. - -%%------------------------------------------------------------------------- -send() -> - [{doc, "Transfer a file with ftp using send/2."}]. -send(Config0) -> - Contents = <<"ftp_SUITE test ...">>, - SrcDir = "data", - File = "file.txt", - Config = set_state([reset,{mkfile,[SrcDir,File],Contents}], Config0), - Pid = proplists:get_value(ftp, Config), - - chk_no_file([File],Config), - chk_file([SrcDir,File],Contents,Config), - - ok = ftp:lcd(Pid, id2ftp(SrcDir,Config)), - ok = ftp:cd(Pid, id2ftp("",Config)), - ok = ftp:send(Pid, File), - chk_file(File, Contents, Config), - - {error,epath} = ftp:send(Pid, "non_existing_file"), - ok. - -%%------------------------------------------------------------------------- -send_3() -> - [{doc, "Transfer a file with ftp using send/3."}]. -send_3(Config0) -> - Contents = <<"ftp_SUITE test ...">>, - Dir = "incoming", - File = "file.txt", - RemoteFile = "remfile.txt", - Config = set_state([reset,{mkfile,File,Contents},{mkdir,Dir}], Config0), - Pid = proplists:get_value(ftp, Config), - - ok = ftp:cd(Pid, id2ftp(Dir,Config)), - ok = ftp:lcd(Pid, id2ftp("",Config)), - ok = ftp:send(Pid, File, RemoteFile), - chk_file([Dir,RemoteFile], Contents, Config), - - {error,epath} = ftp:send(Pid, "non_existing_file", RemoteFile), - ok. - -%%------------------------------------------------------------------------- -send_bin() -> - [{doc, "Send a binary."}]. -send_bin(Config0) -> - BinContents = <<"ftp_SUITE test ...">>, - File = "file.txt", - Config = set_state([reset], Config0), - Pid = proplists:get_value(ftp, Config), - {error, enotbinary} = ftp:send_bin(Pid, "some string", id2ftp(File,Config)), - ok = ftp:send_bin(Pid, BinContents, id2ftp(File,Config)), - chk_file(File, BinContents, Config), - {error, efnamena} = ftp:send_bin(Pid, BinContents, "/nothere"), - ok. - -%%------------------------------------------------------------------------- -send_chunk() -> - [{doc, "Send a binary using chunks."}]. -send_chunk(Config0) -> - Contents1 = <<"1: ftp_SUITE test ...">>, - Contents2 = <<"2: ftp_SUITE test ...">>, - File = "file.txt", - Config = set_state([reset,{mkdir,"incoming"}], Config0), - Pid = proplists:get_value(ftp, Config), - - ok = ftp:send_chunk_start(Pid, id2ftp(File,Config)), - {error, echunk} = ftp:send_chunk_start(Pid, id2ftp(File,Config)), - {error, echunk} = ftp:cd(Pid, "incoming"), - {error, enotbinary} = ftp:send_chunk(Pid, "some string"), - ok = ftp:send_chunk(Pid, Contents1), - ok = ftp:send_chunk(Pid, Contents2), - ok = ftp:send_chunk_end(Pid), - chk_file(File, <<Contents1/binary,Contents2/binary>>, Config), - - {error, echunk} = ftp:send_chunk(Pid, Contents1), - {error, echunk} = ftp:send_chunk_end(Pid), - {error, efnamena} = ftp:send_chunk_start(Pid, "/"), - ok. - -%%------------------------------------------------------------------------- -delete() -> - [{doc, "Delete a file."}]. -delete(Config0) -> - Contents = <<"ftp_SUITE test ...">>, - File = "file.txt", - Config = set_state([reset,{mkfile,File,Contents}], Config0), - Pid = proplists:get_value(ftp, Config), - ok = ftp:delete(Pid, id2ftp(File,Config)), - chk_no_file([File], Config), - {error,epath} = ftp:delete(Pid, id2ftp(File,Config)), - ok. - -%%------------------------------------------------------------------------- -mkdir() -> - [{doc, "Make a remote directory."}]. -mkdir(Config0) -> - NewDir = "new_dir", - Config = set_state([reset], Config0), - Pid = proplists:get_value(ftp, Config), - ok = ftp:mkdir(Pid, id2ftp(NewDir,Config)), - chk_dir([NewDir], Config), - {error,epath} = ftp:mkdir(Pid, id2ftp(NewDir,Config)), - ok. - -%%------------------------------------------------------------------------- -rmdir() -> - [{doc, "Remove a directory."}]. -rmdir(Config0) -> - Dir = "dir", - Config = set_state([reset,{mkdir,Dir}], Config0), - Pid = proplists:get_value(ftp, Config), - ok = ftp:rmdir(Pid, id2ftp(Dir,Config)), - chk_no_dir([Dir], Config), - {error,epath} = ftp:rmdir(Pid, id2ftp(Dir,Config)), - ok. - -%%------------------------------------------------------------------------- -append() -> - [{doc, "Append a local file twice to a remote file"}]. -append(Config0) -> - SrcFile = "f_src.txt", - DstFile = "f_dst.txt", - Contents = <<"ftp_SUITE test ...">>, - Config = set_state([reset,{mkfile,SrcFile,Contents}], Config0), - Pid = proplists:get_value(ftp, Config), - ok = ftp:append(Pid, id2ftp(SrcFile,Config), id2ftp(DstFile,Config)), - ok = ftp:append(Pid, id2ftp(SrcFile,Config), id2ftp(DstFile,Config)), - chk_file(DstFile, <<Contents/binary,Contents/binary>>, Config), - {error,epath} = ftp:append(Pid, id2ftp("non_existing_file",Config), id2ftp(DstFile,Config)), - ok. - -%%------------------------------------------------------------------------- -append_bin() -> - [{doc, "Append a local file twice to a remote file using append_bin"}]. -append_bin(Config0) -> - DstFile = "f_dst.txt", - Contents = <<"ftp_SUITE test ...">>, - Config = set_state([reset], Config0), - Pid = proplists:get_value(ftp, Config), - ok = ftp:append_bin(Pid, Contents, id2ftp(DstFile,Config)), - ok = ftp:append_bin(Pid, Contents, id2ftp(DstFile,Config)), - chk_file(DstFile, <<Contents/binary,Contents/binary>>, Config). - -%%------------------------------------------------------------------------- -append_chunk() -> - [{doc, "Append chunks."}]. -append_chunk(Config0) -> - File = "f_dst.txt", - Contents = [<<"ER">>,<<"LE">>,<<"RL">>], - Config = set_state([reset], Config0), - Pid = proplists:get_value(ftp, Config), - ok = ftp:append_chunk_start(Pid, id2ftp(File,Config)), - {error, enotbinary} = ftp:append_chunk(Pid, binary_to_list(lists:nth(1,Contents))), - ok = ftp:append_chunk(Pid,lists:nth(1,Contents)), - ok = ftp:append_chunk(Pid,lists:nth(2,Contents)), - ok = ftp:append_chunk(Pid,lists:nth(3,Contents)), - ok = ftp:append_chunk_end(Pid), - chk_file(File, <<"ERLERL">>, Config). - -%%------------------------------------------------------------------------- -recv() -> - [{doc, "Receive a file using recv/2"}]. -recv(Config0) -> - File1 = "f_dst1.txt", - File2 = "f_dst2.txt", - SrcDir = "a_dir", - Contents1 = <<"1 ftp_SUITE test ...">>, - Contents2 = <<"2 ftp_SUITE test ...">>, - Config = set_state([reset, {mkfile,[SrcDir,File1],Contents1}, {mkfile,[SrcDir,File2],Contents2}], Config0), - Pid = proplists:get_value(ftp, Config), - ok = ftp:cd(Pid, id2ftp(SrcDir,Config)), - ok = ftp:lcd(Pid, id2ftp("",Config)), - ok = ftp:recv(Pid, File1), - chk_file(File1, Contents1, Config), - ok = ftp:recv(Pid, File2), - chk_file(File2, Contents2, Config), - {error,epath} = ftp:recv(Pid, "non_existing_file"), - ok. - -%%------------------------------------------------------------------------- -recv_3() -> - [{doc,"Receive a file using recv/3"}]. -recv_3(Config0) -> - DstFile = "f_src.txt", - SrcFile = "f_dst.txt", - Contents = <<"ftp_SUITE test ...">>, - Config = set_state([reset, {mkfile,SrcFile,Contents}], Config0), - Pid = proplists:get_value(ftp, Config), - ok = ftp:cd(Pid, id2ftp("",Config)), - ok = ftp:recv(Pid, SrcFile, id2abs(DstFile,Config)), - chk_file(DstFile, Contents, Config). - -%%------------------------------------------------------------------------- -recv_bin() -> - [{doc, "Receive a file as a binary."}]. -recv_bin(Config0) -> - File = "f_dst.txt", - Contents = <<"ftp_SUITE test ...">>, - Config = set_state([reset, {mkfile,File,Contents}], Config0), - Pid = proplists:get_value(ftp, Config), - {ok,Received} = ftp:recv_bin(Pid, id2ftp(File,Config)), - find_diff(Received, Contents), - {error,epath} = ftp:recv_bin(Pid, id2ftp("non_existing_file",Config)), - ok. - -%%------------------------------------------------------------------------- -recv_bin_twice() -> - [{doc, "Receive two files as a binaries."}]. -recv_bin_twice(Config0) -> - File1 = "f_dst1.txt", - File2 = "f_dst2.txt", - Contents1 = <<"1 ftp_SUITE test ...">>, - Contents2 = <<"2 ftp_SUITE test ...">>, - Config = set_state([reset, {mkfile,File1,Contents1}, {mkfile,File2,Contents2}], Config0), - ct:log("First transfer",[]), - Pid = proplists:get_value(ftp, Config), - {ok,Received1} = ftp:recv_bin(Pid, id2ftp(File1,Config)), - find_diff(Received1, Contents1), - ct:log("Second transfer",[]), - {ok,Received2} = ftp:recv_bin(Pid, id2ftp(File2,Config)), - find_diff(Received2, Contents2), - ct:log("Transfers ready!",[]), - {error,epath} = ftp:recv_bin(Pid, id2ftp("non_existing_file",Config)), - ok. -%%------------------------------------------------------------------------- -recv_chunk() -> - [{doc, "Receive a file using chunk-wise."}]. -recv_chunk(Config0) -> - File = "big_file.txt", - Contents = list_to_binary( lists:duplicate(1000, lists:seq(0,255)) ), - Config = set_state([reset, {mkfile,File,Contents}], Config0), - Pid = proplists:get_value(ftp, Config), - {{error, "ftp:recv_chunk_start/2 not called"},_} = recv_chunk(Pid, <<>>), - ok = ftp:recv_chunk_start(Pid, id2ftp(File,Config)), - {ok, ReceivedContents, _Ncunks} = recv_chunk(Pid, <<>>), - find_diff(ReceivedContents, Contents). - -recv_chunk_twice() -> - [{doc, "Receive two files using chunk-wise."}]. -recv_chunk_twice(Config0) -> - File1 = "big_file1.txt", - File2 = "big_file2.txt", - Contents1 = list_to_binary( lists:duplicate(1000, lists:seq(0,255)) ), - Contents2 = crypto:strong_rand_bytes(1200), - Config = set_state([reset, {mkfile,File1,Contents1}, {mkfile,File2,Contents2}], Config0), - Pid = proplists:get_value(ftp, Config), - {{error, "ftp:recv_chunk_start/2 not called"},_} = recv_chunk(Pid, <<>>), - ok = ftp:recv_chunk_start(Pid, id2ftp(File1,Config)), - {ok, ReceivedContents1, _Ncunks1} = recv_chunk(Pid, <<>>), - ok = ftp:recv_chunk_start(Pid, id2ftp(File2,Config)), - {ok, ReceivedContents2, _Ncunks2} = recv_chunk(Pid, <<>>), - find_diff(ReceivedContents1, Contents1), - find_diff(ReceivedContents2, Contents2). - -recv_chunk_three_times() -> - [{doc, "Receive two files using chunk-wise."}, - {timetrap,{seconds,120}}]. -recv_chunk_three_times(Config0) -> - File1 = "big_file1.txt", - File2 = "big_file2.txt", - File3 = "big_file3.txt", - Contents1 = list_to_binary( lists:duplicate(1000, lists:seq(0,255)) ), - Contents2 = crypto:strong_rand_bytes(1200), - Contents3 = list_to_binary( lists:duplicate(1000, lists:seq(255,0,-1)) ), - - Config = set_state([reset, {mkfile,File1,Contents1}, {mkfile,File2,Contents2}, {mkfile,File3,Contents3}], Config0), - Pid = proplists:get_value(ftp, Config), - {{error, "ftp:recv_chunk_start/2 not called"},_} = recv_chunk(Pid, <<>>), - - ok = ftp:recv_chunk_start(Pid, id2ftp(File1,Config)), - {ok, ReceivedContents1, Nchunks1} = recv_chunk(Pid, <<>>), - - ok = ftp:recv_chunk_start(Pid, id2ftp(File2,Config)), - {ok, ReceivedContents2, _Nchunks2} = recv_chunk(Pid, <<>>), - - ok = ftp:recv_chunk_start(Pid, id2ftp(File3,Config)), - {ok, ReceivedContents3, _Nchunks3} = recv_chunk(Pid, <<>>, 10000, 0, Nchunks1), - - find_diff(ReceivedContents1, Contents1), - find_diff(ReceivedContents2, Contents2), - find_diff(ReceivedContents3, Contents3). - - - -recv_chunk(Pid, Acc) -> - recv_chunk(Pid, Acc, 0, 0, undefined). - - - -%% ExpectNchunks :: integer() | undefined -recv_chunk(Pid, Acc, DelayMilliSec, N, ExpectNchunks) when N+1 < ExpectNchunks -> - %% for all I in integer(), I < undefined - recv_chunk1(Pid, Acc, DelayMilliSec, N, ExpectNchunks); - -recv_chunk(Pid, Acc, DelayMilliSec, N, ExpectNchunks) -> - %% N >= ExpectNchunks-1 - timer:sleep(DelayMilliSec), - recv_chunk1(Pid, Acc, DelayMilliSec, N, ExpectNchunks). - - -recv_chunk1(Pid, Acc, DelayMilliSec, N, ExpectNchunks) -> - ct:log("Call ftp:recv_chunk",[]), - case ftp:recv_chunk(Pid) of - ok -> {ok, Acc, N}; - {ok, Bin} -> recv_chunk(Pid, <<Acc/binary, Bin/binary>>, DelayMilliSec, N+1, ExpectNchunks); - Error -> {Error, N} - end. - -%%------------------------------------------------------------------------- -type() -> - [{doc,"Test that we can change btween ASCCI and binary transfer mode"}]. -type(Config) -> - Pid = proplists:get_value(ftp, Config), - ok = ftp:type(Pid, ascii), - ok = ftp:type(Pid, binary), - ok = ftp:type(Pid, ascii), - {error, etype} = ftp:type(Pid, foobar). - -%%------------------------------------------------------------------------- -quote(Config) -> - Pid = proplists:get_value(ftp, Config), - ["257 \""++_Rest] = ftp:quote(Pid, "pwd"), %% 257 - [_| _] = ftp:quote(Pid, "help"), - %% This negativ test causes some ftp servers to hang. This test - %% is not important for the client, so we skip it for now. - %%["425 Can't build data connection: Connection refused."] - %% = ftp:quote(Pid, "list"), - ok. - -%%------------------------------------------------------------------------- -progress_report_send() -> - [{doc, "Test the option progress for ftp:send/[2,3]"}]. -progress_report_send(Config) when is_list(Config) -> - ReportPid = - spawn_link(?MODULE, progress_report_receiver_init, [self(), 1]), - send(Config), - receive - {ReportPid, ok} -> - ok - end. - -%%------------------------------------------------------------------------- -progress_report_recv() -> - [{doc, "Test the option progress for ftp:recv/[2,3]"}]. -progress_report_recv(Config) when is_list(Config) -> - ReportPid = - spawn_link(?MODULE, progress_report_receiver_init, [self(), 3]), - recv(Config), - receive - {ReportPid, ok} -> - ok - end. - -%%------------------------------------------------------------------------- - -not_owner() -> - [{doc, "Test what happens if a process that not owns the connection tries " - "to use it"}]. -not_owner(Config) when is_list(Config) -> - Pid = proplists:get_value(ftp, Config), - - Parent = self(), - OtherPid = spawn_link( - fun() -> - {error, not_connection_owner} = ftp:pwd(Pid), - ftp:close(Pid), - Parent ! {self(), ok} - end), - receive - {OtherPid, ok} -> - {ok, _} = ftp:pwd(Pid) - end. - - -%%------------------------------------------------------------------------- - - -unexpected_call()-> - [{doc, "Test that behaviour of the ftp process if the api is abused"}]. -unexpected_call(Config) when is_list(Config) -> - Flag = process_flag(trap_exit, true), - Pid = proplists:get_value(ftp, Config), - - %% Serious programming fault, connetion will be shut down - case (catch gen_server:call(Pid, {self(), foobar, 10}, infinity)) of - {error, {connection_terminated, 'API_violation'}} -> - ok; - Unexpected1 -> - exit({unexpected_result, Unexpected1}) - end, - ct:sleep(500), - undefined = process_info(Pid, status), - process_flag(trap_exit, Flag). -%%------------------------------------------------------------------------- - -unexpected_cast()-> - [{doc, "Test that behaviour of the ftp process if the api is abused"}]. -unexpected_cast(Config) when is_list(Config) -> - Flag = process_flag(trap_exit, true), - Pid = proplists:get_value(ftp, Config), - %% Serious programming fault, connetion will be shut down - gen_server:cast(Pid, {self(), foobar, 10}), - ct:sleep(500), - undefined = process_info(Pid, status), - process_flag(trap_exit, Flag). -%%------------------------------------------------------------------------- - -unexpected_bang()-> - [{doc, "Test that connection ignores unexpected bang"}]. -unexpected_bang(Config) when is_list(Config) -> - Flag = process_flag(trap_exit, true), - Pid = proplists:get_value(ftp, Config), - %% Could be an innocent misstake the connection lives. - Pid ! foobar, - ct:sleep(500), - {status, _} = process_info(Pid, status), - process_flag(trap_exit, Flag). - -%%------------------------------------------------------------------------- - -clean_shutdown() -> - [{doc, "Test that owning process that exits with reason " - "'shutdown' does not cause an error message. OTP 6035"}]. - -clean_shutdown(Config) -> - Parent = self(), - HelperPid = spawn( - fun() -> - ftp__open(Config, [verbose]), - Parent ! ok, - receive - nothing -> ok - end - end), - receive - ok -> - PrivDir = proplists:get_value(priv_dir, Config), - LogFile = filename:join([PrivDir,"ticket_6035.log"]), - error_logger:logfile({open, LogFile}), - exit(HelperPid, shutdown), - timer:sleep(2000), - error_logger:logfile(close), - case is_error_report_6035(LogFile) of - true -> ok; - false -> {fail, "Bad logfile"} - end - end. - -%%%---------------------------------------------------------------- -%%% Error codes not tested elsewhere - -error_elogin(Config0) -> - Dir = "test", - OldFile = "old.txt", - NewFile = "new.txt", - SrcDir = "data", - File = "file.txt", - Config = set_state([reset, - {mkdir,Dir}, - {mkfile,OldFile,<<"Contents..">>}, - {mkfile,[SrcDir,File],<<"Contents..">>}], Config0), - - Pid = proplists:get_value(ftp, Config), - ok = ftp:lcd(Pid, id2ftp(SrcDir,Config)), - {error,elogin} = ftp:send(Pid, File), - ok = ftp:lcd(Pid, id2ftp("",Config)), - {error,elogin} = ftp:pwd(Pid), - {error,elogin} = ftp:cd(Pid, id2ftp(Dir,Config)), - {error,elogin} = ftp:rename(Pid, - id2ftp(OldFile,Config), - id2ftp(NewFile,Config)), - ok. - -error_ehost(_Config) -> - {error, ehost} = ftp:open("nohost.nodomain"), - ok. - -%%-------------------------------------------------------------------- -%% Internal functions ----------------------------------------------- -%%-------------------------------------------------------------------- - -make_cert_files(Alg1, Alg2, Prefix, Dir) -> - CaInfo = {CaCert,_} = erl_make_certs:make_cert([{key,Alg1}]), - {Cert,CertKey} = erl_make_certs:make_cert([{key,Alg2},{issuer,CaInfo}]), - CaCertFile = filename:join(Dir, Prefix++"cacerts.pem"), - CertFile = filename:join(Dir, Prefix++"cert.pem"), - KeyFile = filename:join(Dir, Prefix++"key.pem"), - der_to_pem(CaCertFile, [{'Certificate', CaCert, not_encrypted}]), - der_to_pem(CertFile, [{'Certificate', Cert, not_encrypted}]), - der_to_pem(KeyFile, [CertKey]), - ok. - -der_to_pem(File, Entries) -> - PemBin = public_key:pem_encode(Entries), - file:write_file(File, PemBin). - -%%-------------------------------------------------------------------- -chk_file(Path=[C|_], ExpectedContents, Config) when 0<C,C=<255 -> - chk_file([Path], ExpectedContents, Config); - -chk_file(PathList, ExpectedContents, Config) -> - Path = filename:join(PathList), - AbsPath = id2abs(Path,Config), - case file:read_file(AbsPath) of - {ok,ExpectedContents} -> - true; - {ok,ReadContents} -> - {error,{diff,Pos,RC,LC}} = find_diff(ReadContents, ExpectedContents, 1), - ct:log("Bad contents of ~p.~nGot:~n~p~nExpected:~n~p~nDiff at pos ~p ~nRead: ~p~nExp : ~p", - [AbsPath,ReadContents,ExpectedContents,Pos,RC,LC]), - ct:fail("Bad contents of ~p", [Path]); - {error,Error} -> - try begin - {ok,CWD} = file:get_cwd(), - ct:log("file:get_cwd()=~p~nfiles:~n~p",[CWD,file:list_dir(CWD)]) - end - of _ -> ok - catch _:_ ->ok - end, - ct:fail("Error reading ~p: ~p",[Path,Error]) - end. - - -chk_no_file(Path=[C|_], Config) when 0<C,C=<255 -> - chk_no_file([Path], Config); - -chk_no_file(PathList, Config) -> - Path = filename:join(PathList), - AbsPath = id2abs(Path,Config), - case file:read_file(AbsPath) of - {error,enoent} -> - true; - {ok,Contents} -> - ct:log("File ~p exists although it shouldn't. Contents:~n~p", - [AbsPath,Contents]), - ct:fail("File exists: ~p", [Path]); - {error,Error} -> - ct:fail("Unexpected error reading ~p: ~p",[Path,Error]) - end. - - -chk_dir(Path=[C|_], Config) when 0<C,C=<255 -> - chk_dir([Path], Config); - -chk_dir(PathList, Config) -> - Path = filename:join(PathList), - AbsPath = id2abs(Path,Config), - case file:read_file_info(AbsPath) of - {ok, #file_info{type=directory}} -> - true; - {ok, #file_info{type=Type}} -> - ct:fail("Expected dir ~p is a ~p",[Path,Type]); - {error,Error} -> - ct:fail("Expected dir ~p: ~p",[Path,Error]) - end. - -chk_no_dir(PathList, Config) -> - Path = filename:join(PathList), - AbsPath = id2abs(Path,Config), - case file:read_file_info(AbsPath) of - {error,enoent} -> - true; - {ok, #file_info{type=directory}} -> - ct:fail("Dir ~p erroneously exists",[Path]); - {ok, #file_info{type=Type}} -> - ct:fail("~p ~p erroneously exists",[Type,Path]); - {error,Error} -> - ct:fail("Unexpected error for ~p: ~p",[Path,Error]) - end. - -%%-------------------------------------------------------------------- -find_executable(Config) -> - search_executable(proplists:get_value(ftpservers, Config, ?default_ftp_servers)). - - -search_executable([{Name,Paths,_StartCmd,_ChkUp,_StopCommand,_ConfigUpd,_Host,_Port}|Srvrs]) -> - case os_find(Name,Paths) of - false -> - ct:log("~p not found",[Name]), - search_executable(Srvrs); - AbsName -> - ct:comment("Found ~p",[AbsName]), - {ok, {AbsName,_StartCmd,_ChkUp,_StopCommand,_ConfigUpd,_Host,_Port}} - end; -search_executable([]) -> - false. - - -os_find(Name, Paths) -> - case os:find_executable(Name, Paths) of - false -> os:find_executable(Name); - AbsName -> AbsName - end. - -%%%---------------------------------------------------------------- -start_ftpd(Config0) -> - {AbsName,StartCmd,_ChkUp,_StopCommand,ConfigRewrite,Host,Port} = - proplists:get_value(ftpd_data, Config0), - case StartCmd(Config0, AbsName) of - {ok,StartResult} -> - Config = [{ftpd_host,Host}, - {ftpd_port,Port}, - {ftpd_start_result,StartResult} | ConfigRewrite(Config0)], - try - ftp__close(ftp__open(Config,[verbose])) - of - Config1 when is_list(Config1) -> - ct:log("Usuable ftp server ~p started on ~p:~p",[AbsName,Host,Port]), - Config - catch - Class:Exception -> - ct:log("Ftp server ~p started on ~p:~p but is unusable:~n~p:~p", - [AbsName,Host,Port,Class,Exception]), - {skip, [AbsName," started but unusuable"]} - end; - {error,Msg} -> - {skip, [AbsName," not started: ",Msg]} - end. - -stop_ftpd(Config) -> - {_Name,_StartCmd,_ChkUp,StopCommand,_ConfigUpd,_Host,_Port} = proplists:get_value(ftpd_data, Config), - StopCommand(proplists:get_value(ftpd_start_result,Config)). - -ps_ftpd(Config) -> - {_Name,_StartCmd,ChkUp,_StopCommand,_ConfigUpd,_Host,_Port} = proplists:get_value(ftpd_data, Config), - ct:log( ChkUp(proplists:get_value(ftpd_start_result,Config)) ). - - -ftpd_running(Config) -> - {_Name,_StartCmd,ChkUp,_StopCommand,_ConfigUpd,_Host,_Port} = proplists:get_value(ftpd_data, Config), - ChkUp(proplists:get_value(ftpd_start_result,Config)). - -ftp__open(Config, Options) -> - Host = proplists:get_value(ftpd_host,Config), - Port = proplists:get_value(ftpd_port,Config), - ct:log("Host=~p, Port=~p",[Host,Port]), - {ok,Pid} = ftp:open(Host, [{port,Port} | Options]), - [{ftp,Pid}|Config]. - -ftp__close(Config) -> - ok = ftp:close(proplists:get_value(ftp,Config)), - Config. - -split(Cs) -> string:tokens(Cs, "\r\n"). - -find_diff(Bin1, Bin2) -> - case find_diff(Bin1, Bin2, 1) of - {error, {diff,Pos,RC,LC}} -> - ct:log("Contents differ at position ~p.~nOp1: ~p~nOp2: ~p",[Pos,RC,LC]), - ct:fail("Contents differ at pos ~p",[Pos]); - Other -> - Other - end. - -find_diff(A, A, _) -> true; -find_diff(<<H,T1/binary>>, <<H,T2/binary>>, Pos) -> find_diff(T1, T2, Pos+1); -find_diff(RC, LC, Pos) -> {error, {diff, Pos, RC, LC}}. - -set_state(Ops, Config) when is_list(Ops) -> lists:foldl(fun set_state/2, Config, Ops); - -set_state(reset, Config) -> - rm('*', id2abs("",Config)), - PrivDir = proplists:get_value(priv_dir,Config), - file:set_cwd(PrivDir), - ftp:lcd(proplists:get_value(ftp,Config),PrivDir), - set_state({mkdir,""},Config); -set_state({mkdir,Id}, Config) -> - Abs = id2abs(Id, Config), - mk_path(Abs), - file:make_dir(Abs), - Config; -set_state({mkfile,Id,Contents}, Config) -> - Abs = id2abs(Id, Config), - mk_path(Abs), - ok = file:write_file(Abs, Contents), - Config. - -mk_path(Abs) -> lists:foldl(fun mk_path/2, [], filename:split(filename:dirname(Abs))). - -mk_path(F, Pfx) -> - case file:read_file_info(AbsName=filename:join(Pfx,F)) of - {ok,#file_info{type=directory}} -> - AbsName; - {error,eexist} -> - AbsName; - {error,enoent} -> - ok = file:make_dir(AbsName), - AbsName - end. - -rm('*', Pfx) -> - {ok,Fs} = file:list_dir(Pfx), - lists:foreach(fun(F) -> rm(F, Pfx) end, Fs); -rm(F, Pfx) -> - case file:read_file_info(AbsName=filename:join(Pfx,F)) of - {ok,#file_info{type=directory}} -> - {ok,Fs} = file:list_dir(AbsName), - lists:foreach(fun(F1) -> rm(F1,AbsName) end, Fs), - ok = file:del_dir(AbsName); - - {ok,#file_info{type=regular}} -> - ok = file:delete(AbsName); - - {error,enoent} -> - ok - end. - -id2abs(Id, Conf) -> filename:join(proplists:get_value(priv_dir,Conf),ids(Id)). -id2ftp(Id, Conf) -> (proplists:get_value(id2ftp,Conf))(ids(Id)). -id2ftp_result(Id, Conf) -> (proplists:get_value(id2ftp_result,Conf))(ids(Id)). - -ids([[_|_]|_]=Ids) -> filename:join(Ids); -ids(Id) -> Id. - - -is_expected_absName(Id, File, Conf) -> File = (proplists:get_value(id2abs,Conf))(Id). -is_expected_ftpInName(Id, File, Conf) -> File = (proplists:get_value(id2ftp,Conf))(Id). -is_expected_ftpOutName(Id, File, Conf) -> File = (proplists:get_value(id2ftp_result,Conf))(Id). - - -%%%---------------------------------------------------------------- -%%% Help functions for the option '{progress,Progress}' -%%% - -%%%---------------- -%%% Callback: - -progress(#progress{} = P, _File, {file_size, Total} = M) -> - ct:pal("Progress: ~p",[M]), - progress_report_receiver ! start, - P#progress{total = Total}; - -progress(#progress{current = Current} = P, _File, {transfer_size, 0} = M) -> - ct:pal("Progress: ~p",[M]), - progress_report_receiver ! finish, - case P#progress.total of - unknown -> P; - Current -> P; - Total -> ct:fail({error, {progress, {total,Total}, {current,Current}}}), - P - end; - -progress(#progress{current = Current} = P, _File, {transfer_size, Size} = M) -> - ct:pal("Progress: ~p",[M]), - progress_report_receiver ! update, - P#progress{current = Current + Size}; - -progress(P, _File, M) -> - ct:pal("Progress **** Strange: ~p",[M]), - P. - - -%%%---------------- -%%% Help process that counts the files transferred: - -progress_report_receiver_init(Parent, N) -> - register(progress_report_receiver, self()), - progress_report_receiver_expect_N_files(Parent, N). - -progress_report_receiver_expect_N_files(_Parent, 0) -> - ct:pal("progress_report got all files!", []); -progress_report_receiver_expect_N_files(Parent, N) -> - ct:pal("progress_report expects ~p more files",[N]), - receive - start -> ok - end, - progress_report_receiver_loop(Parent, N-1). - - -progress_report_receiver_loop(Parent, N) -> - ct:pal("progress_report expect update | finish. N = ~p",[N]), - receive - update -> - ct:pal("progress_report got update",[]), - progress_report_receiver_loop(Parent, N); - finish -> - ct:pal("progress_report got finish, send ~p to ~p",[{self(),ok}, Parent]), - Parent ! {self(), ok}, - progress_report_receiver_expect_N_files(Parent, N) - end. - -%%%---------------------------------------------------------------- -%%% Help functions for bug OTP-6035 - -is_error_report_6035(LogFile) -> - case file:read_file(LogFile) of - {ok, Bin} -> - nomatch =/= binary:match(Bin, <<"=ERROR REPORT====">>); - _ -> - false - end. - diff --git a/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel deleted file mode 100644 index 75096ce687..0000000000 --- a/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel +++ /dev/null @@ -1,18 +0,0 @@ -%% Add a host name in the appropriate list -%% Each "platform" contains a list of hostnames (a string) that can -%% be used for testing the ftp client. -%% The definition below are an example!! -[{solaris8_sparc, ["solaris8_sparc_dummy1", "solaris8_sparc_dummy2"]}, - {solaris9_sparc, ["solaris9_sparc_dummy1"]}, - {solaris10_sparc, ["solaris10_sparc_dummy1"]}, - {solaris10_x86, ["solaris10_x86_dummy1", "solaris10_x86_dummy2"]}, - {linux_x86, ["linux_x86_dummy1", "linux_x86_dummy2"]}, - {linux_ppc, ["linux_ppc_dummy1"]}, - {macosx_ppc, ["macosx_ppc_dummy1"]}, - {macosx_x86, ["macosx_x86_dummy1", "macosx_x86_dummy2"]}, - {openbsd_x86, []}, - {freebsd_x86, ["freebsd_x86_dummy1"]}, - {netbsd_x86, []}, - {windows_xp, []}, - {windows_2003_server, ["win2003_dummy1"]}, - {ticket_test, ["solaris8_x86_dummy1", "linux_x86_dummy1"]}]. diff --git a/lib/inets/test/ftp_SUITE_data/vsftpd.conf b/lib/inets/test/ftp_SUITE_data/vsftpd.conf deleted file mode 100644 index a5584f5916..0000000000 --- a/lib/inets/test/ftp_SUITE_data/vsftpd.conf +++ /dev/null @@ -1,26 +0,0 @@ - -### -### Some parameters are given in the vsftpd start command. -### -### Typical command-line paramters are such that has a file path -### component like cert files. -### - - -listen=YES -listen_port=9999 -run_as_launching_user=YES -ssl_enable=YES -allow_anon_ssl=YES - -background=YES - -write_enable=YES -anonymous_enable=YES -anon_upload_enable=YES -anon_mkdir_write_enable=YES -anon_other_write_enable=YES -anon_world_readable_only=NO - -### Shouldn't be necessary.... -require_ssl_reuse=NO diff --git a/lib/inets/test/ftp_format_SUITE.erl b/lib/inets/test/ftp_format_SUITE.erl deleted file mode 100644 index 95d594a44b..0000000000 --- a/lib/inets/test/ftp_format_SUITE.erl +++ /dev/null @@ -1,328 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2016. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% -%% --module(ftp_format_SUITE). --author('[email protected]'). - --include_lib("common_test/include/ct.hrl"). --include("ftp_internal.hrl"). - -%% Note: This directive should only be used in test suites. --compile(export_all). - -suite() -> - [{ct_hooks,[ts_install_cth]}, - {timetrap,{seconds,5}} - ]. - -all() -> - [{group, ftp_response}, format_error]. - -groups() -> - [{ftp_response, [], - [ftp_150, ftp_200, ftp_220, ftp_226, ftp_257, ftp_331, - ftp_425, ftp_other_status_codes, ftp_multiple_lines_status_in_msg, - ftp_multiple_lines, ftp_multipel_ctrl_messages]}]. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -init_per_testcase(_, Config) -> - Config. -end_per_testcase(_, _) -> - ok. - -%%------------------------------------------------------------------------- -%% Test cases starts here. -%%------------------------------------------------------------------------- - -ftp_150() -> - [{doc, "Especially check that respons can be devided in a random place."}]. -ftp_150(Config) when is_list(Config) -> - FtpResponse = ["150 ASCII data conn", "ection for /bin/ls ", - "(134.138.177", ".89,50434) (0 bytes).\r\n"], - - "150 ASCII data connection for /bin/ls " - "(134.138.177.89,50434) (0 bytes).\r\n" = Msg = - parse(ftp_response, parse_lines, [[], start], FtpResponse), - {pos_prel, _} = ftp_response:interpret(Msg). - -ftp_200() -> - [{doc, "Especially check that respons can be devided after the first status " - "code character and in the end delimiter."}]. -ftp_200(Config) when is_list(Config) -> - FtpResponse = ["2", "00 PORT command successful.", [?CR], [?LF]], - - "200 PORT command successful.\r\n" = Msg = - parse(ftp_response, parse_lines, [[], start], FtpResponse), - {pos_compl, _} = ftp_response:interpret(Msg), - ok. - -ftp_220() -> - [{doc, "Especially check that respons can be devided after the " - "first with space "}]. -ftp_220(Config) when is_list(Config) -> - FtpResponse = ["220 ","fingon FTP server (SunOS 5.8) ready.\r\n"], - - "220 fingon FTP server (SunOS 5.8) ready.\r\n" = Msg = - parse(ftp_response, parse_lines, [[], start], FtpResponse), - {pos_compl, _} = ftp_response:interpret(Msg), - ok. - -ftp_226() -> - [{doc, "Especially check that respons can be devided after second status code" - " character and in the end delimiter."}]. -ftp_226(Config) when is_list(Config) -> - FtpResponse = ["22" "6 Transfer complete.\r", [?LF]], - - "226 Transfer complete.\r\n" = Msg = - parse(ftp_response, parse_lines, [[], start], FtpResponse), - {pos_compl, _} = ftp_response:interpret(Msg), - ok. - -ftp_257() -> - [{doc, "Especially check that quoted chars do not cause a problem."}]. -ftp_257(Config) when is_list(Config) -> - FtpResponse = ["257 \"/\" is current directory.\r\n"], - - "257 \"/\" is current directory.\r\n" = Msg = - parse(ftp_response, parse_lines, [[], start], FtpResponse), - {pos_compl, _} = ftp_response:interpret(Msg), - ok. - -ftp_331() -> - [{doc, "Especially check that respons can be devided after the third status " - " status code character."}]. -ftp_331(Config) when is_list(Config) -> - %% Brake before white space after code - FtpResponse = - ["331"," Guest login ok, send ient as password.\r\n"], - - "331 Guest login ok, send ient as password.\r\n" = Msg = - parse(ftp_response, parse_lines, [[], start], FtpResponse), - {pos_interm, _} = ftp_response:interpret(Msg), - ok. - -ftp_425() -> - [{doc, "Especially check a message that was received in only one part."}]. -ftp_425(Config) when is_list(Config) -> - FtpResponse = - ["425 Can't build data connection: Connection refused.\r\n"], - - "425 Can't build data connection: Connection refused.\r\n" - = Msg = parse(ftp_response, parse_lines, [[], start], FtpResponse), - {trans_neg_compl, _} = ftp_response:interpret(Msg), - ok. - -ftp_multiple_lines_status_in_msg() -> - [{doc, "check that multiple lines gets parsed correct, even if we have " - " the status code within the msg being sent"}]. -ftp_multiple_lines_status_in_msg(Config) when is_list(Config) -> - ML = "230-User usr-230 is logged in\r\n" ++ - "230 OK. Current directory is /\r\n", - {ok, ML, <<>>} = ftp_response:parse_lines(list_to_binary(ML), [], start), - ok. - -ftp_multiple_lines() -> - [{doc, "Especially check multiple lines devided in significant places"}]. -ftp_multiple_lines(Config) when is_list(Config) -> - FtpResponse = ["21", "4","-The", - " following commands are recognized:\r\n" - " USER EPRT STRU MAIL* ALLO CWD", - " STAT* XRMD \r\n" - " PASS LPRT MODE MSND* " - " REST* XCWD HELP PWD ", [?CRLF], - " ACCT* EPSV RETR MSOM* RNFR LIST " - " NOOP XPWD \r\n", - " REIN* LPSV STOR MSAM* RNTO NLST " - " MKD CDUP \r\n" - " QUIT PASV APPE MRSQ* ABOR SITE* " - " XMKD XCUP \r\n" - " PORT TYPE MLFL* MRCP* DELE SYST " - " RMD STOU \r\n" - "214 (*'s => unimplemented)", [?CR], [?LF]], - - - FtpResponse1 = ["214-", "The", - " following commands are recognized:\r\n" - " USER EPRT STRU MAIL* ALLO CWD", - " STAT* XRMD \r\n" - " PASS LPRT MODE MSND* " - " REST* XCWD HELP PWD ", [?CRLF], - " ACCT* EPSV RETR MSOM* RNFR LIST " - " NOOP XPWD \r\n", - " REIN* LPSV STOR MSAM* RNTO NLST " - " MKD CDUP \r\n" - " QUIT PASV APPE MRSQ* ABOR SITE* " - " XMKD XCUP \r\n" - " PORT TYPE MLFL* MRCP* DELE SYST " - " RMD STOU \r\n" - "2", "14 (*'s => unimplemented)", [?CR], [?LF]], - - FtpResponse2 = ["214-", "The", - " following commands are recognized:\r\n" - " USER EPRT STRU MAIL* ALLO CWD", - " STAT* XRMD \r\n" - " PASS LPRT MODE MSND* " - " REST* XCWD HELP PWD ", [?CRLF], - " ACCT* EPSV RETR MSOM* RNFR LIST " - " NOOP XPWD \r\n", - " REIN* LPSV STOR MSAM* RNTO NLST " - " MKD CDUP \r\n" - " QUIT PASV APPE MRSQ* ABOR SITE* " - " XMKD XCUP \r\n" - " PORT TYPE MLFL* MRCP* DELE SYST " - " RMD STOU \r\n" - "21", "4"," (*'s => unimplemented)", [?CR], [?LF]], - - MultiLineResultStr = - "214-The following commands are recognized:\r\n" - " USER EPRT STRU MAIL* ALLO CWD STAT* " - "XRMD \r\n" - " PASS LPRT MODE MSND* REST* XCWD HELP " - "PWD \r\n" - " ACCT* EPSV RETR MSOM* RNFR LIST NOOP " - "XPWD \r\n" - " REIN* LPSV STOR MSAM* RNTO NLST MKD " - "CDUP \r\n" - " QUIT PASV APPE MRSQ* ABOR SITE* XMKD " - "XCUP \r\n" - " PORT TYPE MLFL* MRCP* DELE SYST RMD " - "STOU \r\n" - "214 (*'s => unimplemented)\r\n", - - MultiLineResultStr = - parse(ftp_response, parse_lines, [[], start], FtpResponse), - {pos_compl, _} = ftp_response:interpret(MultiLineResultStr), - - MultiLineResultStr = parse(ftp_response, parse_lines, [[], start], - FtpResponse1), - - MultiLineResultStr = parse(ftp_response, parse_lines, [[], start], - FtpResponse2), - ok. - -ftp_other_status_codes() -> - [{doc, "Check that other valid status codes, than the ones above, are handled" - "by ftp_response:interpret/1. Note there are som ftp status codes" - "that will not be received with the current ftp instruction support," - "they are not included here."}]. -ftp_other_status_codes(Config) when is_list(Config) -> - - %% 1XX - {pos_prel, _ } = ftp_response:interpret("120 Foobar\r\n"), - - %% 2XX - {pos_compl, _ } = ftp_response:interpret("202 Foobar\r\n"), - {pos_compl, _ } = ftp_response:interpret("221 Foobar\r\n"), - {pos_compl, _ } = ftp_response:interpret("227 Foobar\r\n"), - {pos_compl, _ } = ftp_response:interpret("230 Foobar\r\n"), - {pos_compl, _ } = ftp_response:interpret("250 Foobar\r\n"), - - %% 3XX - {pos_interm_acct, _ } = ftp_response:interpret("332 Foobar\r\n"), - {pos_interm, _ } = ftp_response:interpret("350 Foobar\r\n"), - - %% 4XX - {trans_neg_compl, _ } = ftp_response:interpret("421 Foobar\r\n"), - {trans_neg_compl, _ } = ftp_response:interpret("426 Foobar\r\n"), - {enofile, _ } = ftp_response:interpret("450 Foobar\r\n"), - {trans_neg_compl, _ } = ftp_response:interpret("451 Foobar\r\n"), - {etnospc, _ } = ftp_response:interpret("452 Foobar\r\n"), - - %% 5XX - {perm_neg_compl, _ } = ftp_response:interpret("500 Foobar\r\n"), - {perm_neg_compl, _ } = ftp_response:interpret("501 Foobar\r\n"), - {perm_neg_compl, _ } = ftp_response:interpret("503 Foobar\r\n"), - {perm_neg_compl, _ } = ftp_response:interpret("504 Foobar\r\n"), - {elogin, _ } = ftp_response:interpret("530 Foobar\r\n"), - {perm_neg_compl, _ } = ftp_response:interpret("532 Foobar\r\n"), - {epath, _ } = ftp_response:interpret("550 Foobar\r\n"), - {epnospc, _ } = ftp_response:interpret("552 Foobar\r\n"), - {efnamena, _ } = ftp_response:interpret("553 Foobar\r\n"), - ok. - -ftp_multipel_ctrl_messages() -> - [{doc, "The ftp server may send more than one control message as a reply," - "check that they are handled one at the time."}]. -ftp_multipel_ctrl_messages(Config) when is_list(Config) -> - FtpResponse = ["200 PORT command successful.\r\n200 Foobar\r\n"], - - {"200 PORT command successful.\r\n" = Msg, NextMsg} = - parse(ftp_response, parse_lines, [[], start], FtpResponse), - {pos_compl, _} = ftp_response:interpret(Msg), - NewMsg = parse(ftp_response, parse_lines, [[], start], NextMsg), - {pos_compl, _} = ftp_response:interpret(NewMsg), - ok. - - -%%------------------------------------------------------------------------- -format_error(Config) when is_list(Config) -> - "Synchronisation error during chunk sending." = - ftp:formaterror(echunk), - "Session has been closed." = ftp:formaterror(eclosed), - "Connection to remote server prematurely closed." = - ftp:formaterror(econn), - "File or directory already exists." = ftp:formaterror(eexists), - "Host not found, FTP server not found, or connection rejected." = - ftp:formaterror(ehost), - "User not logged in." = ftp:formaterror(elogin), - "Term is not a binary." = ftp:formaterror(enotbinary), - "No such file or directory, already exists, or permission denied." - = ftp:formaterror(epath), - "No such type." = ftp:formaterror(etype), - "User name or password not valid." = ftp:formaterror(euser), - "Insufficient storage space in system." = ftp:formaterror(etnospc), - "Exceeded storage allocation (for current directory or dataset)." - = ftp:formaterror(epnospc), - "File name not allowed." = ftp:formaterror(efnamena), - "Unknown error: foobar" = ftp:formaterror({error, foobar}). - -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- -parse(Module, Function, Args, Bin) when is_binary(Bin) -> - parse(Module, Function, Args, [binary_to_list(Bin)]); - -parse(Module, Function, [AccLines, StatusCode], [Data | Rest]) -> - case Module:Function(list_to_binary(Data), AccLines, StatusCode) of - {ok, Result, <<>>} -> - Result; - {ok, Result, Next} -> - {Result, Next}; - {continue, {NewData, NewAccLines, NewStatusCode}} -> - case Rest of - [] -> - ct:fail({wrong_input, Data, Rest}); - [_ | _] -> - parse(Module, Function, [NewAccLines, NewStatusCode], - [binary_to_list(NewData) ++ hd(Rest) | tl(Rest)]) - end - end. diff --git a/lib/inets/test/ftp_internal.hrl b/lib/inets/test/ftp_internal.hrl deleted file mode 120000 index af57081f14..0000000000 --- a/lib/inets/test/ftp_internal.hrl +++ /dev/null @@ -1 +0,0 @@ -../src/ftp/ftp_internal.hrl
\ No newline at end of file diff --git a/lib/inets/test/ftp_property_test_SUITE.erl b/lib/inets/test/ftp_property_test_SUITE.erl deleted file mode 100644 index b314882296..0000000000 --- a/lib/inets/test/ftp_property_test_SUITE.erl +++ /dev/null @@ -1,53 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% -%% - -%%% Run like this: -%%% ct:run_test([{suite,"ftp_property_test_SUITE"}, {logdir,"/ldisk/OTP/LOG"}]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% %%% -%%% WARNING %%% -%%% %%% -%%% This is experimental code which may be changed or removed %%% -%%% anytime without any warning. %%% -%%% %%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --module(ftp_property_test_SUITE). - --compile(export_all). - --include_lib("common_test/include/ct.hrl"). - -all() -> [prop_ftp_case]. - - -init_per_suite(Config) -> - inets:start(), - ct_property_test:init_per_suite(Config). - - -%%%---- test case -prop_ftp_case(Config) -> - ct_property_test:quickcheck( - ftp_simple_client_server:prop_ftp(Config), - Config - ). diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl index 1abd96a228..07ce594a1d 100644 --- a/lib/inets/test/inets_SUITE.erl +++ b/lib/inets/test/inets_SUITE.erl @@ -41,9 +41,7 @@ groups() -> [{services_test, [], [start_inets, start_httpc, - start_httpd, - start_ftpc, - start_tftpd + start_httpd ]}, {app_test, [], [app, appup]}]. @@ -298,79 +296,6 @@ start_httpd(Config) when is_list(Config) -> %%------------------------------------------------------------------------- -start_ftpc(doc) -> - [{doc, "Start/stop of ftpc service"}]; -start_ftpc(Config0) when is_list(Config0) -> - process_flag(trap_exit, true), - ok = inets:start(), - case ftp_SUITE:init_per_suite(Config0) of - {skip, _} = Skip -> - Skip; - Config -> - FtpdHost = proplists:get_value(ftpd_host,Config), - {ok, Pid0} = inets:start(ftpc, [{host, FtpdHost}]), - Pids0 = [ServicePid || {_, ServicePid} <- - inets:services()], - true = lists:member(Pid0, Pids0), - [_|_] = inets:services_info(), - inets:stop(ftpc, Pid0), - ct:sleep(100), - Pids1 = [ServicePid || {_, ServicePid} <- - inets:services()], - false = lists:member(Pid0, Pids1), - {ok, Pid1} = - inets:start(ftpc, [{host, FtpdHost}], stand_alone), - Pids2 = [ServicePid || {_, ServicePid} <- - inets:services()], - false = lists:member(Pid1, Pids2), - ok = inets:stop(stand_alone, Pid1), - receive - {'EXIT', Pid1, shutdown} -> - ok - after 100 -> - ct:fail(stand_alone_not_shutdown) - end, - ok = inets:stop(), - catch ftp_SUITE:end_per_SUITE(Config) - end. - -%%------------------------------------------------------------------------- - -start_tftpd() -> - [{doc, "Start/stop of tfpd service"}]. -start_tftpd(Config) when is_list(Config) -> - process_flag(trap_exit, true), - ok = inets:start(), - {ok, Pid0} = inets:start(tftpd, [{host, "localhost"}, {port, 0}]), - Pids0 = [ServicePid || {_, ServicePid} <- inets:services()], - true = lists:member(Pid0, Pids0), - [_|_] = inets:services_info(), - inets:stop(tftpd, Pid0), - ct:sleep(100), - Pids1 = [ServicePid || {_, ServicePid} <- inets:services()], - false = lists:member(Pid0, Pids1), - {ok, Pid1} = - inets:start(tftpd, [{host, "localhost"}, {port, 0}], stand_alone), - Pids2 = [ServicePid || {_, ServicePid} <- inets:services()], - false = lists:member(Pid1, Pids2), - ok = inets:stop(stand_alone, Pid1), - receive - {'EXIT', Pid1, shutdown} -> - ok - after 100 -> - ct:fail(stand_alone_not_shutdown) - end, - ok = inets:stop(), - application:load(inets), - application:set_env(inets, services, [{tftpd,[{host, "localhost"}, - {port, 0}]}]), - ok = inets:start(), - (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()), - application:unset_env(inets, services), - ok = inets:stop(). - -%%------------------------------------------------------------------------- - httpd_reload() -> [{doc, "Reload httpd configuration without restarting service"}]. httpd_reload(Config) when is_list(Config) -> diff --git a/lib/inets/test/inets_socketwrap_SUITE.erl b/lib/inets/test/inets_socketwrap_SUITE.erl index 7ea7e08ed1..fc87c595a9 100644 --- a/lib/inets/test/inets_socketwrap_SUITE.erl +++ b/lib/inets/test/inets_socketwrap_SUITE.erl @@ -30,7 +30,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [start_httpd_fd, start_tftpd_fd]. + [start_httpd_fd]. init_per_suite(Config) -> case os:type() of @@ -90,37 +90,7 @@ start_httpd_fd(Config) when is_list(Config) -> ct:fail(open_port_failed) end end. -%%------------------------------------------------------------------------- -start_tftpd_fd() -> - [{doc, "Start/stop of tfpd service with socket wrapper"}]. -start_tftpd_fd(Config) when is_list(Config) -> - DataDir = proplists:get_value(data_dir, Config), - case setup_node_info(node()) of - {skip, _} = Skip -> - Skip; - {Node, NodeArg} -> - InetPort = inets_test_lib:inet_port(node()), - ct:pal("Node: ~p~n", [Node]), - Wrapper = filename:join(DataDir, "setuid_socket_wrap"), - Cmd = Wrapper ++ - " -s -tftpd_69,0:" ++ integer_to_list(InetPort) - ++ " -p " ++ os:find_executable("erl") ++ - " -- " ++ NodeArg, - ct:pal("cmd: ~p~n", [Cmd]), - case open_port({spawn, Cmd}, [stderr_to_stdout]) of - Port when is_port(Port) -> - wait_node_up(Node, 10), - ct:pal("~p", [rpc:call(Node, init, get_argument, [tftpd_69])]), - ok = rpc:call(Node, inets, start, []), - {ok, Pid} = rpc:call(Node, inets, start, - [tftpd,[{host, "localhost"}]]), - {ok, Info} = rpc:call(Node, tftp, info, [Pid]), - {value,{port, InetPort}} = lists:keysearch(port, 1, Info), - rpc:call(Node, erlang, halt, []); - _ -> - ct:fail(open_port_failed) - end - end. + %%------------------------------------------------------------------------- %% Internal functions %%------------------------------------------------------------------------- diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl index 1e664337e6..727e91e987 100644 --- a/lib/inets/test/inets_sup_SUITE.erl +++ b/lib/inets/test/inets_sup_SUITE.erl @@ -32,8 +32,7 @@ suite() -> ]. all() -> - [default_tree, ftpc_worker, tftpd_worker, - httpd_config, httpd_subtree, httpd_subtree_profile, + [default_tree, httpd_config, httpd_subtree, httpd_subtree_profile, httpc_subtree]. groups() -> @@ -147,15 +146,11 @@ default_tree() -> "in the default case."}]. default_tree(Config) when is_list(Config) -> TopSupChildren = supervisor:which_children(inets_sup), - 4 = length(TopSupChildren), + 2 = length(TopSupChildren), {value, {httpd_sup, _, supervisor,[httpd_sup]}} = lists:keysearch(httpd_sup, 1, TopSupChildren), {value, {httpc_sup, _,supervisor,[httpc_sup]}} = lists:keysearch(httpc_sup, 1, TopSupChildren), - {value, {ftp_sup,_,supervisor,[ftp_sup]}} = - lists:keysearch(ftp_sup, 1, TopSupChildren), - {value, {tftp_sup,_,supervisor,[tftp_sup]}} = - lists:keysearch(tftp_sup, 1, TopSupChildren), HttpcSupChildren = supervisor:which_children(httpc_sup), {value, {httpc_profile_sup,_, supervisor, [httpc_profile_sup]}} = @@ -163,8 +158,6 @@ default_tree(Config) when is_list(Config) -> {value, {httpc_handler_sup,_, supervisor, [httpc_handler_sup]}} = lists:keysearch(httpc_handler_sup, 1, HttpcSupChildren), - [] = supervisor:which_children(ftp_sup), - [] = supervisor:which_children(httpd_sup), %% Default profile @@ -172,48 +165,7 @@ default_tree(Config) when is_list(Config) -> = supervisor:which_children(httpc_profile_sup), [] = supervisor:which_children(httpc_handler_sup), - - [] = supervisor:which_children(tftp_sup), - - ok. -ftpc_worker() -> - [{doc, "Makes sure the ftp worker processes are added and removed " - "appropriatly to/from the supervison tree."}]. -ftpc_worker(Config0) when is_list(Config0) -> - [] = supervisor:which_children(ftp_sup), - case ftp_SUITE:init_per_suite(Config0) of - {skip, _} = Skip -> - Skip; - Config -> - FtpdHost = proplists:get_value(ftpd_host,Config), - {ok, Pid} = inets:start(ftpc, [{host, FtpdHost}]), - case supervisor:which_children(ftp_sup) of - [{_,_, worker, [ftp]}] -> - inets:stop(ftpc, Pid), - ct:sleep(5000), - [] = supervisor:which_children(ftp_sup), - catch ftp_SUITE:end_per_SUITE(Config), - ok; - Children -> - catch ftp_SUITE:end_per_SUITE(Config), - exit({unexpected_children, Children}) - end - end. - -tftpd_worker() -> - [{doc, "Makes sure the tftp sub tree is correct."}]. -tftpd_worker(Config) when is_list(Config) -> - [] = supervisor:which_children(tftp_sup), - {ok, Pid0} = inets:start(tftpd, [{host, inets_test_lib:hostname()}, - {port, 0}]), - {ok, _Pid1} = inets:start(tftpd, [{host, inets_test_lib:hostname()}, - {port, 0}], stand_alone), - - [{_,Pid0, worker, _}] = supervisor:which_children(tftp_sup), - inets:stop(tftpd, Pid0), - ct:sleep(5000), - [] = supervisor:which_children(tftp_sup), ok. httpd_config() -> diff --git a/lib/inets/test/tftp_SUITE.erl b/lib/inets/test/tftp_SUITE.erl deleted file mode 100644 index 09049e36af..0000000000 --- a/lib/inets/test/tftp_SUITE.erl +++ /dev/null @@ -1,949 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2006-2016. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% - --module(tftp_SUITE). - --compile(export_all). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Includes and defines -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --include("tftp_test_lib.hrl"). - --define(START_DAEMON(PortX, OptionsX), - fun(Port, Options) -> - {ok, Pid} = ?VERIFY({ok, _Pid}, tftp:start([{port, Port} | Options])), - if - Port == 0 -> - {ok, ActualOptions} = ?IGNORE(tftp:info(Pid)), - {value, {port, ActualPort}} = - lists:keysearch(port, 1, ActualOptions), - {ActualPort, Pid}; - true -> - {Port, Pid} - end - end(PortX, OptionsX)). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% API -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -t() -> - tftp_test_lib:t([{?MODULE, all}]). - -t(Cases) -> - tftp_test_lib:t(Cases, default_config()). - -t(Cases, Config) -> - tftp_test_lib:t(Cases, Config). - -default_config() -> - []. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Test server callbacks -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -init_per_testcase(Case, Config) -> - tftp_test_lib:init_per_testcase(Case, Config). - -end_per_testcase(Case, Config) when is_list(Config) -> - tftp_test_lib:end_per_testcase(Case, Config). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Top test case -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -suite() -> [{ct_hooks,[ts_install_cth]}]. - -all() -> - [simple, extra, reuse_connection, resend_client, - resend_server, large_file]. - -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Simple -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -simple(doc) -> - ["Start the daemon and perform simple a read and write."]; -simple(suite) -> - []; -simple(Config) when is_list(Config) -> - ?VERIFY(ok, application:start(inets)), - - {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, brief}])), - - %% Read fail - RemoteFilename = "tftp_temporary_remote_test_file.txt", - LocalFilename = "tftp_temporary_local_test_file.txt", - Blob = list_to_binary(lists:duplicate(2000, $1)), - %% Blob = <<"Some file contents\n">>, - Size = size(Blob), - ?IGNORE(file:delete(RemoteFilename)), - ?VERIFY({error, {client_open, enoent, _}}, - tftp:read_file(RemoteFilename, binary, [{port, Port}])), - - %% Write and read - ?VERIFY({ok, Size}, tftp:write_file(RemoteFilename, Blob, [{port, Port}])), - ?VERIFY({ok, Blob}, tftp:read_file(RemoteFilename, binary, [{port, Port}])), - ?IGNORE(file:delete(LocalFilename)), - ?VERIFY({ok, Size}, tftp:read_file(RemoteFilename, LocalFilename, [{port, Port}])), - - %% Cleanup - unlink(DaemonPid), - exit(DaemonPid, kill), - ?VERIFY(ok, file:delete(LocalFilename)), - ?VERIFY(ok, file:delete(RemoteFilename)), - ?VERIFY(ok, application:stop(inets)), - ok. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Extra -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -extra(doc) -> - ["Verify new stuff for IS 1.2."]; -extra(suite) -> - []; -extra(Config) when is_list(Config) -> - ?VERIFY({'EXIT', {badarg,{fake_key, fake_flag}}}, - tftp:start([{port, 0}, {fake_key, fake_flag}])), - - {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, brief}])), - - RemoteFilename = "tftp_extra_temporary_remote_test_file.txt", - LocalFilename = "tftp_extra_temporary_local_test_file.txt", - Blob = <<"Some file contents\n">>, - Size = size(Blob), - Host = "127.0.0.1", - Peer = {inet, Host, Port}, - Generic = - [ - {state, []}, - {prepare, fun extra_prepare/6}, - {open, fun extra_open/6}, - {read, fun extra_read/1}, - {write, fun extra_write/2}, - {abort, fun extra_abort/3 } - ], - Options = [{host, Host}, - {port, Port}, - %%{ debug,all}, - {callback, {".*", tftp_test_lib, Generic}}], - ?VERIFY(ok, file:write_file(LocalFilename, Blob)), - ?VERIFY({ok, [{count, Size}, Peer]}, - tftp:write_file(RemoteFilename, LocalFilename, Options)), - ?VERIFY(ok, file:delete(LocalFilename)), - - ?VERIFY({ok,[{bin, Blob}, Peer]}, - tftp:read_file(RemoteFilename, LocalFilename, Options)), - - %% Cleanup - unlink(DaemonPid), - exit(DaemonPid, kill), - ?VERIFY(ok, file:delete(LocalFilename)), - ?VERIFY(ok, file:delete(RemoteFilename)), - ok. - --record(extra_state, {file, blksize, count, acc, peer}). - -%%------------------------------------------------------------------- -%% Prepare -%%------------------------------------------------------------------- - -extra_prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, []) -> - %% Client side - BlkSize = list_to_integer(tftp_test_lib:lookup_option("blksize", "512", SuggestedOptions)), - State = #extra_state{blksize = BlkSize, peer = Peer}, - extra_open(Peer, Access, LocalFilename, Mode, SuggestedOptions, State), - {ok, SuggestedOptions, State}; -extra_prepare(_Peer, _Access, _Bin, _Mode, _SuggestedOptions, _Initial) -> - {error, {undef, "Illegal callback options."}}. - -%%------------------------------------------------------------------- -%% Open -%%------------------------------------------------------------------- - -extra_open(Peer, Access, LocalFilename, Mode, SuggestedOptions, []) -> - %% Server side - case extra_prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, []) of - {ok, AcceptedOptions, []} -> - BlkSize = list_to_integer(tftp_test_lib:lookup_option("blksize", "512", AcceptedOptions)), - State = #extra_state{blksize = BlkSize, peer = Peer}, - extra_open(Peer, Access, LocalFilename, Mode, AcceptedOptions, State); - {error, {Code, Text}} -> - {error, {Code, Text}} - end; -extra_open(_Peer, Access, LocalFilename, _Mode, NegotiatedOptions, #extra_state{} = State) -> - {File, Acc} = - case Access of - read -> - if - is_binary(LocalFilename) -> - {undefined, LocalFilename}; - is_list(LocalFilename) -> - {ok, Bin} = file:read_file(LocalFilename), - {LocalFilename, Bin} - end; - write -> - {LocalFilename, []} - end, - %% Both sides - State2 = State#extra_state{file = File, acc = Acc, count = 0}, - {ok, NegotiatedOptions, State2}. - -%%------------------------------------------------------------------- -%% Read -%%------------------------------------------------------------------- - -extra_read(#extra_state{acc = Bin} = State) when is_binary(Bin) -> - BlkSize = State#extra_state.blksize, - Count = State#extra_state.count + size(Bin), - if - size(Bin) >= BlkSize -> - <<Block:BlkSize/binary, Bin2/binary>> = Bin, - State2 = State#extra_state{acc = Bin2, count = Count}, - {more, Block, State2}; - size(Bin) < BlkSize -> - Res = [{count, Count}, State#extra_state.peer], - {last, Bin, Res} - end. - -%%------------------------------------------------------------------- -%% Write -%%------------------------------------------------------------------- - -extra_write(Bin, #extra_state{acc = List} = State) when is_binary(Bin), is_list(List) -> - Size = size(Bin), - BlkSize = State#extra_state.blksize, - if - Size == BlkSize -> - {more, State#extra_state{acc = [Bin | List]}}; - Size < BlkSize -> - Bin2 = list_to_binary(lists:reverse([Bin | List])), - Res = [{bin, Bin2}, State#extra_state.peer], - file:write_file(State#extra_state.file, Bin2), - {last, Res} - end. - -%%------------------------------------------------------------------- -%% Abort -%%------------------------------------------------------------------- - -extra_abort(_Code, _Text, #extra_state{}) -> - ok. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Re-send client -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -resend_client(doc) -> - ["Verify that the server behaves correctly when the client re-sends packets."]; -resend_client(suite) -> - []; -resend_client(Config) when is_list(Config) -> - Host = {127, 0, 0, 1}, - {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, all}])), - - ?VERIFY(ok, resend_read_client(Host, Port, 10)), - ?VERIFY(ok, resend_read_client(Host, Port, 512)), - ?VERIFY(ok, resend_read_client(Host, Port, 1025)), - - ?VERIFY(ok, resend_write_client(Host, Port, 10)), - ?VERIFY(ok, resend_write_client(Host, Port, 512)), - ?VERIFY(ok, resend_write_client(Host, Port, 1025)), - - %% Cleanup - unlink(DaemonPid), - exit(DaemonPid, kill), - ok. - -resend_read_client(Host, Port, BlkSize) -> - RemoteFilename = "tftp_resend_read_client.tmp", - Block1 = lists:duplicate(BlkSize, $1), - Block2 = lists:duplicate(BlkSize, $2), - Block3 = lists:duplicate(BlkSize, $3), - Block4 = lists:duplicate(BlkSize, $4), - Block5 = lists:duplicate(BlkSize, $5), - Blocks = [Block1, Block2, Block3, Block4, Block5], - Blob = list_to_binary(Blocks), - ?VERIFY(ok, file:write_file(RemoteFilename, Blob)), - - Timeout = timer:seconds(3), - ?VERIFY(timeout, recv(0)), - - %% Open socket - {ok, Socket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])), - - ReadList = [0, 1, RemoteFilename, 0, "octet", 0], - Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]), - NewPort = - if - BlkSize =:= 512 -> - %% Send READ - ReadBin = list_to_binary(ReadList), - ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)), - - %% Sleep a while in order to provoke the server to re-send the packet - timer:sleep(Timeout + timer:seconds(1)), - - %% Recv DATA #1 (the packet that the server think that we have lost) - {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, Data1Bin}, recv(Timeout)), - NewPort0; - true -> - %% Send READ - BlkSizeList = integer_to_list(BlkSize), - Options = ["blksize", 0, BlkSizeList, 0], - ReadBin = list_to_binary([ReadList | Options]), - ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)), - - %% Recv OACK - OptionAckBin = list_to_binary([0, 6 | Options]), - {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)), - - %% Send ACK #0 - Ack0Bin = <<0, 4, 0, 0>>, - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort0, Ack0Bin)), - - %% Send ACK #0 AGAIN (pretend that we timed out) - timer:sleep(timer:seconds(1)), - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort0, Ack0Bin)), - - %% Recv DATA #1 (the packet that the server think that we have lost) - ?VERIFY({udp, Socket, Host, NewPort0, Data1Bin}, recv(Timeout)), - NewPort0 - end, - - %% Recv DATA #1 AGAIN (the re-sent package) - ?VERIFY({udp, Socket, Host, NewPort, Data1Bin}, recv(Timeout)), - - %% Send ACK #1 - Ack1Bin = <<0, 4, 0, 1>>, - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack1Bin)), - - %% Recv DATA #2 - Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]), - ?VERIFY({udp, Socket, Host, NewPort, Data2Bin}, recv(Timeout)), - - %% Send ACK #2 - Ack2Bin = <<0, 4, 0, 2>>, - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack2Bin)), - - %% Recv DATA #3 - Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]), - ?VERIFY({udp, Socket, Host, NewPort, Data3Bin}, recv(Timeout)), - - %% Send ACK #3 - Ack3Bin = <<0, 4, 0, 3>>, - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack3Bin)), - - %% Send ACK #3 AGAIN (pretend that we timed out) - timer:sleep(timer:seconds(1)), - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack3Bin)), - - %% Recv DATA #4 (the packet that the server think that we have lost) - Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]), - ?VERIFY({udp, Socket, Host, NewPort, Data4Bin}, recv(Timeout)), - - %% Recv DATA #4 AGAIN (the re-sent package) - ?VERIFY({udp, Socket, Host, NewPort, Data4Bin}, recv(Timeout)), - - %% Send ACK #2 which is out of range - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack2Bin)), - - %% Send ACK #4 - Ack4Bin = <<0, 4, 0, 4>>, - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack4Bin)), - - %% Recv DATA #5 - Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]), - ?VERIFY({udp, Socket, Host, NewPort, Data5Bin}, recv(Timeout)), - - %% Send ACK #5 - Ack5Bin = <<0, 4, 0, 5>>, - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack5Bin)), - - %% Close socket - ?VERIFY(ok, gen_udp:close(Socket)), - - ?VERIFY(timeout, recv(Timeout)), - ?VERIFY(ok, file:delete(RemoteFilename)), - ok. - -resend_write_client(Host, Port, BlkSize) -> - RemoteFilename = "tftp_resend_write_client.tmp", - Block1 = lists:duplicate(BlkSize, $1), - Block2 = lists:duplicate(BlkSize, $2), - Block3 = lists:duplicate(BlkSize, $3), - Block4 = lists:duplicate(BlkSize, $4), - Block5 = lists:duplicate(BlkSize, $5), - Blocks = [Block1, Block2, Block3, Block4, Block5], - Blob = list_to_binary(Blocks), - ?IGNORE(file:delete(RemoteFilename)), - ?VERIFY({error, enoent}, file:read_file(RemoteFilename)), - - Timeout = timer:seconds(3), - ?VERIFY(timeout, recv(0)), - - %% Open socket - {ok, Socket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])), - - WriteList = [0, 2, RemoteFilename, 0, "octet", 0], - NewPort = - if - BlkSize =:= 512 -> - %% Send WRITE - WriteBin = list_to_binary(WriteList), - ?VERIFY(ok, gen_udp:send(Socket, Host, Port, WriteBin)), - - %% Sleep a while in order to provoke the server to re-send the packet - timer:sleep(Timeout + timer:seconds(1)), - - %% Recv ACK #0 (the packet that the server think that we have lost) - Ack0Bin = <<0, 4, 0, 0>>, - ?VERIFY({udp, Socket, Host, _, Ack0Bin}, recv(Timeout)), - - %% Recv ACK #0 AGAIN (the re-sent package) - {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, Ack0Bin}, recv(Timeout)), - NewPort0; - true -> - %% Send WRITE - BlkSizeList = integer_to_list(BlkSize), - WriteBin = list_to_binary([WriteList, "blksize", 0, BlkSizeList, 0]), - ?VERIFY(ok, gen_udp:send(Socket, Host, Port, WriteBin)), - - %% Sleep a while in order to provoke the server to re-send the packet - timer:sleep(timer:seconds(1)), - - %% Recv OACK (the packet that the server think that we have lost) - OptionAckBin = list_to_binary([0, 6, "blksize",0, BlkSizeList, 0]), - ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)), - - %% Recv OACK AGAIN (the re-sent package) - {udp, _, _, NewPort0, _} = ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)), - NewPort0 - end, - - %% Send DATA #1 - Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]), - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data1Bin)), - - %% Recv ACK #1 - Ack1Bin = <<0, 4, 0, 1>>, - ?VERIFY({udp, Socket, Host, NewPort, Ack1Bin}, recv(Timeout)), - - %% Send DATA #2 - Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]), - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data2Bin)), - - %% Recv ACK #2 - Ack2Bin = <<0, 4, 0, 2>>, - ?VERIFY({udp, Socket, Host, NewPort, Ack2Bin}, recv(Timeout)), - - %% Send DATA #3 - Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]), - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data3Bin)), - - %% Recv ACK #3 - Ack3Bin = <<0, 4, 0, 3>>, - ?VERIFY({udp, Socket, Host, NewPort, Ack3Bin}, recv(Timeout)), - - %% Send DATA #3 AGAIN (pretend that we timed out) - timer:sleep(timer:seconds(1)), - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data3Bin)), - - %% Recv ACK #3 AGAIN (the packet that the server think that we have lost) - ?VERIFY({udp, Socket, Host, NewPort, Ack3Bin}, recv(Timeout)), - - %% Send DATA #2 which is out of range - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data2Bin)), - - %% Send DATA #4 - Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]), - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data4Bin)), - - %% Recv ACK #4 - Ack4Bin = <<0, 4, 0, 4>>, - ?VERIFY({udp, Socket, Host, NewPort, Ack4Bin}, recv(Timeout)), - - %% Send DATA #5 - Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]), - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Data5Bin)), - - %% Recv ACK #5 - Ack5Bin = <<0, 4, 0, 5>>, - ?VERIFY({udp, Socket, Host, NewPort, Ack5Bin}, recv(Timeout)), - - %% Close socket - ?VERIFY(ok, gen_udp:close(Socket)), - - ?VERIFY(timeout, recv(Timeout)), - ?VERIFY({ok, Blob}, file:read_file(RemoteFilename)), - ?VERIFY(ok, file:delete(RemoteFilename)), - ok. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Re-send server -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -resend_server(doc) -> - ["Verify that the server behaves correctly when the server re-sends packets."]; -resend_server(suite) -> - []; -resend_server(Config) when is_list(Config) -> - Host = {127, 0, 0, 1}, - - ?VERIFY(ok, resend_read_server(Host, 10)), - ?VERIFY(ok, resend_read_server(Host, 512)), - ?VERIFY(ok, resend_read_server(Host, 1025)), - - ?VERIFY(ok, resend_write_server(Host, 10)), - ?VERIFY(ok, resend_write_server(Host, 512)), - ?VERIFY(ok, resend_write_server(Host, 1025)), - ok. - -resend_read_server(Host, BlkSize) -> - RemoteFilename = "tftp_resend_read_server.tmp", - Block1 = lists:duplicate(BlkSize, $1), - Block2 = lists:duplicate(BlkSize, $2), - Block3 = lists:duplicate(BlkSize, $3), - Block4 = lists:duplicate(BlkSize, $4), - Block5 = lists:duplicate(BlkSize, $5), - Block6 = [], - Blocks = [Block1, Block2, Block3, Block4, Block5, Block6], - Blob = list_to_binary(Blocks), - - Timeout = timer:seconds(3), - ?VERIFY(timeout, recv(0)), - - %% Open daemon socket - {ok, DaemonSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])), - {ok, DaemonPort} = ?IGNORE(inet:port(DaemonSocket)), - - %% Open server socket - {ok, ServerSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])), - ?IGNORE(inet:port(ServerSocket)), - - %% Prepare client process - ReplyTo = self(), - ClientFun = - fun(Extra) -> - Options = [{port, DaemonPort}, {debug, brief}] ++ Extra, - Res = ?VERIFY({ok, Blob}, tftp:read_file(RemoteFilename, binary, Options)), - ReplyTo ! {self(), {tftp_client_reply, Res}}, - exit(normal) - end, - - ReadList = [0, 1, RemoteFilename, 0, "octet", 0], - Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]), - Ack1Bin = <<0, 4, 0, 1>>, - {ClientPort, ClientPid} = - if - BlkSize =:= 512 -> - %% Start client process - ClientPid0 = spawn_link(fun() -> ClientFun([]) end), - - %% Recv READ - ReadBin = list_to_binary(ReadList), - {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, ReadBin}, recv(Timeout)), - - %% Send DATA #1 - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, Data1Bin)), - - %% Sleep a while in order to provoke the client to re-send the packet - timer:sleep(Timeout + timer:seconds(1)), - - %% Recv ACK #1 (the packet that the server think that we have lost) - ?VERIFY({udp, ServerSocket, Host, ClientPort0, Ack1Bin}, recv(Timeout)), - - %% Recv ACK #1 AGAIN (the re-sent package) - ?VERIFY({udp, ServerSocket, Host, _, Ack1Bin}, recv(Timeout)), - {ClientPort0, ClientPid0}; - true -> - %% Start client process - BlkSizeList = integer_to_list(BlkSize), - ClientPid0 = spawn_link(fun() -> ClientFun([{"blksize", BlkSizeList}]) end), - - %% Recv READ - Options = ["blksize", 0, BlkSizeList, 0], - ReadBin = list_to_binary([ReadList | Options]), - {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, ReadBin}, recv(Timeout)), - - %% Send OACK - BlkSizeList = integer_to_list(BlkSize), - OptionAckBin = list_to_binary([0, 6, "blksize",0, BlkSizeList, 0]), - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, OptionAckBin)), - - %% Sleep a while in order to provoke the client to re-send the packet - timer:sleep(Timeout + timer:seconds(1)), - - %% Recv ACK #0 (the packet that the server think that we have lost) - Ack0Bin = <<0, 4, 0, 0>>, - ?VERIFY({udp, ServerSocket, Host, ClientPort0, Ack0Bin}, recv(Timeout)), - - %% Recv ACK #0 AGAIN (the re-sent package) - ?VERIFY({udp, ServerSocket, Host, ClientPort0, Ack0Bin}, recv(Timeout)), - - %% Send DATA #1 - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, Data1Bin)), - - %% Recv ACK #1 - ?VERIFY({udp, ServerSocket, Host, _, Ack1Bin}, recv(Timeout)), - {ClientPort0, ClientPid0} - end, - - %% Send DATA #2 - Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]), - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data2Bin)), - - %% Recv ACK #2 - Ack2Bin = <<0, 4, 0, 2>>, - ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack2Bin}, recv(Timeout)), - - %% Send DATA #3 - Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]), - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data3Bin)), - - %% Recv ACK #3 - Ack3Bin = <<0, 4, 0, 3>>, - ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack3Bin}, recv(Timeout)), - - %% Send DATA #3 AGAIN (pretend that we timed out) - timer:sleep(timer:seconds(1)), - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data3Bin)), - - %% Recv ACK #3 AGAIN (the packet that the server think that we have lost) - ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack3Bin}, recv(Timeout)), - - %% Send DATA #4 - Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]), - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data4Bin)), - - %% Recv ACK #4 - Ack4Bin = <<0, 4, 0, 4>>, - ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack4Bin}, recv(Timeout)), - - %% Send DATA #3 which is out of range - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data3Bin)), - - %% Send DATA #5 - Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]), - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data5Bin)), - - %% Recv ACK #5 - Ack5Bin = <<0, 4, 0, 5>>, - ?VERIFY({udp, ServerSocket, Host, ClientPort, Ack5Bin}, recv(Timeout)), - - %% Send DATA #6 - Data6Bin = list_to_binary([0, 3, 0, 6 | Block6]), - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Data6Bin)), - - %% Close daemon and server sockets - ?VERIFY(ok, gen_udp:close(ServerSocket)), - ?VERIFY(ok, gen_udp:close(DaemonSocket)), - - ?VERIFY({ClientPid, {tftp_client_reply, {ok, Blob}}}, recv(Timeout)), - - ?VERIFY(timeout, recv(Timeout)), - ok. - -resend_write_server(Host, BlkSize) -> - RemoteFilename = "tftp_resend_write_server.tmp", - Block1 = lists:duplicate(BlkSize, $1), - Block2 = lists:duplicate(BlkSize, $2), - Block3 = lists:duplicate(BlkSize, $3), - Block4 = lists:duplicate(BlkSize, $4), - Block5 = lists:duplicate(BlkSize, $5), - Block6 = [], - Blocks = [Block1, Block2, Block3, Block4, Block5, Block6], - Blob = list_to_binary(Blocks), - Size = size(Blob), - - Timeout = timer:seconds(3), - ?VERIFY(timeout, recv(0)), - - %% Open daemon socket - {ok, DaemonSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])), - {ok, DaemonPort} = ?IGNORE(inet:port(DaemonSocket)), - - %% Open server socket - {ok, ServerSocket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])), - ?IGNORE(inet:port(ServerSocket)), - - %% Prepare client process - ReplyTo = self(), - ClientFun = - fun(Extra) -> - Options = [{port, DaemonPort}, {debug, brief}] ++ Extra, - Res = ?VERIFY({ok, Size}, tftp:write_file(RemoteFilename, Blob, Options)), - ReplyTo ! {self(), {tftp_client_reply, Res}}, - exit(normal) - end, - - WriteList = [0, 2, RemoteFilename, 0, "octet", 0], - Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]), - {ClientPort, ClientPid} = - if - BlkSize =:= 512 -> - %% Start client process - ClientPid0 = spawn_link(fun() -> ClientFun([]) end), - - %% Recv WRITE - WriteBin = list_to_binary(WriteList), - io:format("WriteBin ~p\n", [WriteBin]), - {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, WriteBin}, recv(Timeout)), - - %% Send ACK #1 - Ack0Bin = <<0, 4, 0, 0>>, - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, Ack0Bin)), - - %% Sleep a while in order to provoke the client to re-send the packet - timer:sleep(Timeout + timer:seconds(1)), - - %% Recv DATA #1 (the packet that the server think that we have lost) - ?VERIFY({udp, ServerSocket, Host, ClientPort0, Data1Bin}, recv(Timeout)), - - %% Recv DATA #1 AGAIN (the re-sent package) - ?VERIFY({udp, ServerSocket, Host, _, Data1Bin}, recv(Timeout)), - {ClientPort0, ClientPid0}; - true -> - %% Start client process - BlkSizeList = integer_to_list(BlkSize), - ClientPid0 = spawn_link(fun() -> ClientFun([{"blksize", BlkSizeList}]) end), - - %% Recv WRITE - Options = ["blksize", 0, BlkSizeList, 0], - WriteBin = list_to_binary([WriteList | Options]), - {udp, _, _, ClientPort0, _} = ?VERIFY({udp, DaemonSocket, Host, _, WriteBin}, recv(Timeout)), - - %% Send OACK - BlkSizeList = integer_to_list(BlkSize), - OptionAckBin = list_to_binary([0, 6, "blksize",0, BlkSizeList, 0]), - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort0, OptionAckBin)), - - %% Sleep a while in order to provoke the client to re-send the packet - timer:sleep(Timeout + timer:seconds(1)), - - %% Recv DATA #1 (the packet that the server think that we have lost) - ?VERIFY({udp, ServerSocket, Host, ClientPort0, Data1Bin}, recv(Timeout)), - - %% Recv DATA #1 AGAIN (the re-sent package) - ?VERIFY({udp, ServerSocket, Host, ClientPort0, Data1Bin}, recv(Timeout)), - {ClientPort0, ClientPid0} - end, - - %% Send ACK #1 - Ack1Bin = <<0, 4, 0, 1>>, - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack1Bin)), - - %% Recv DATA #2 - Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]), - ?VERIFY({udp, ServerSocket, Host, ClientPort, Data2Bin}, recv(Timeout)), - - %% Send ACK #2 - Ack2Bin = <<0, 4, 0, 2>>, - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack2Bin)), - - %% Recv DATA #3 - Data3Bin = list_to_binary([0, 3, 0, 3 | Block3]), - ?VERIFY({udp, ServerSocket, Host, ClientPort, Data3Bin}, recv(Timeout)), - - %% Send ACK #3 - Ack3Bin = <<0, 4, 0, 3>>, - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack3Bin)), - - %% Send ACK #3 AGAIN (pretend that we timed out) - timer:sleep(timer:seconds(1)), - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack3Bin)), - - %% Recv DATA #4 (the packet that the server think that we have lost) - Data4Bin = list_to_binary([0, 3, 0, 4 | Block4]), - ?VERIFY({udp, ServerSocket, Host, ClientPort, Data4Bin}, recv(Timeout)), - - %% Recv DATA #4 AGAIN (the re-sent package) - ?VERIFY({udp, ServerSocket, Host, ClientPort, Data4Bin}, recv(Timeout)), - - %% Send ACK #4 - Ack4Bin = <<0, 4, 0, 4>>, - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack4Bin)), - - %% Recv DATA #5 - Data5Bin = list_to_binary([0, 3, 0, 5 | Block5]), - ?VERIFY({udp, ServerSocket, Host, ClientPort, Data5Bin}, recv(Timeout)), - - %% Send ACK #3 which is out of range - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack3Bin)), - - %% Send ACK #5 - Ack5Bin = <<0, 4, 0, 5>>, - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack5Bin)), - - %% Recv DATA #6 - Data6Bin = list_to_binary([0, 3, 0, 6 | Block6]), - ?VERIFY({udp, ServerSocket, Host, ClientPort, Data6Bin}, recv(Timeout)), - - %% Send ACK #6 - Ack6Bin = <<0, 4, 0, 6>>, - ?VERIFY(ok, gen_udp:send(ServerSocket, Host, ClientPort, Ack6Bin)), - - %% Close daemon and server sockets - ?VERIFY(ok, gen_udp:close(ServerSocket)), - ?VERIFY(ok, gen_udp:close(DaemonSocket)), - - ?VERIFY({ClientPid, {tftp_client_reply, {ok, Size}}}, recv(Timeout)), - - ?VERIFY(timeout, recv(Timeout)), - ok. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -reuse_connection(doc) -> - ["Verify that the server can reuse an ongiong connection when same client resends request."]; -reuse_connection(suite) -> - []; -reuse_connection(Config) when is_list(Config) -> - Host = {127, 0, 0, 1}, - {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, all}])), - - RemoteFilename = "reuse_connection.tmp", - BlkSize = 512, - Block1 = lists:duplicate(BlkSize, $1), - Block2 = lists:duplicate(BlkSize div 2, $2), - Blocks = [Block1, Block2], - Blob = list_to_binary(Blocks), - ?VERIFY(ok, file:write_file(RemoteFilename, Blob)), - - Seconds = 3, - Timeout = timer:seconds(Seconds), - ?VERIFY(timeout, recv(0)), - - %% Open socket - {ok, Socket} = ?VERIFY({ok, _}, gen_udp:open(0, [binary, {reuseaddr, true}, {active, true}])), - - ReadList = [0, 1, RemoteFilename, 0, "octet", 0], - Data1Bin = list_to_binary([0, 3, 0, 1 | Block1]), - - %% Send READ - TimeoutList = integer_to_list(Seconds), - Options = ["timeout", 0, TimeoutList, 0], - ReadBin = list_to_binary([ReadList | Options]), - ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)), - - %% Send yet another READ for same file - ?VERIFY(ok, gen_udp:send(Socket, Host, Port, ReadBin)), - - %% Recv OACK - OptionAckBin = list_to_binary([0, 6 | Options]), - {udp, _, _, NewPort, _} = ?VERIFY({udp, Socket, Host, _, OptionAckBin}, recv(Timeout)), - - %% Send ACK #0 - Ack0Bin = <<0, 4, 0, 0>>, - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack0Bin)), - - %% Recv DATA #1 - ?VERIFY({udp, Socket, Host, NewPort, Data1Bin}, recv(Timeout)), - - %% Send ACK #1 - Ack1Bin = <<0, 4, 0, 1>>, - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack1Bin)), - - %% Recv DATA #2 - Data2Bin = list_to_binary([0, 3, 0, 2 | Block2]), - ?VERIFY({udp, Socket, Host, NewPort, Data2Bin}, recv(Timeout)), - - %% Send ACK #2 - Ack2Bin = <<0, 4, 0, 2>>, - ?VERIFY(ok, gen_udp:send(Socket, Host, NewPort, Ack2Bin)), - - %% Close socket - ?VERIFY(ok, gen_udp:close(Socket)), - - ?VERIFY(timeout, recv(Timeout)), - ?VERIFY(ok, file:delete(RemoteFilename)), - - %% Cleanup - unlink(DaemonPid), - exit(DaemonPid, kill), - ok. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Large file: transfer > 65535 blocks -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -large_file(doc) -> - ["Start the daemon and test transfer of files greater than 32M."]; -large_file(suite) -> - []; -large_file(Config) when is_list(Config) -> - ?VERIFY(ok, application:start(inets)), - - {Port, DaemonPid} = ?IGNORE(?START_DAEMON(0, [{debug, brief}])), - - %% Read fail - RemoteFilename = "tftp_temporary_large_file_remote_test_file.txt", - LocalFilename = "tftp_temporary_large_file_local_test_file.txt", - - {ok, FH} = file:open(LocalFilename, [write,exclusive]), - {ok, Size} = file:position(FH, {eof, 2*512*65535}), - ok = file:truncate(FH), - ?IGNORE(file:close(FH)), - - %% Write and read - ?VERIFY({ok, Size}, tftp:write_file(RemoteFilename, LocalFilename, [{port, Port}])), - ?IGNORE(file:delete(LocalFilename)), - ?VERIFY({ok, Size}, tftp:read_file(RemoteFilename, LocalFilename, [{port, Port}])), - - %% Cleanup - unlink(DaemonPid), - exit(DaemonPid, kill), - ?VERIFY(ok, file:delete(LocalFilename)), - ?VERIFY(ok, file:delete(RemoteFilename)), - ?VERIFY(ok, application:stop(inets)), - ok. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Goodies -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -recv(Timeout) -> - receive - Msg -> - Msg - after Timeout -> - timeout - end. diff --git a/lib/inets/test/tftp_test_lib.erl b/lib/inets/test/tftp_test_lib.erl deleted file mode 100644 index f07795324f..0000000000 --- a/lib/inets/test/tftp_test_lib.erl +++ /dev/null @@ -1,308 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2007-2016. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% - --module(tftp_test_lib). - --compile(export_all). - --include("tftp_test_lib.hrl"). - -%% -%% ----- -%% - -init_per_testcase(_Case, Config) when is_list(Config) -> - io:format("\n ", []), - ?IGNORE(application:stop(inets)), - Config. - -end_per_testcase(_Case, Config) when is_list(Config) -> - ?IGNORE(application:stop(inets)), - Config. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Infrastructure for test suite -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -error(Actual, Mod, Line) -> - (catch global:send(tftp_global_logger, {failed, Mod, Line})), - log("<ERROR> Bad result: ~p\n", [Actual], Mod, Line), - Label = lists:concat([Mod, "(", Line, ") unexpected result"]), - et:report_event(60, Mod, Mod, Label, - [{line, Mod, Line}, {error, Actual}]), - case global:whereis_name(tftp_test_case_sup) of - undefined -> - ignore; - Pid -> - Fail = #'REASON'{mod = Mod, line = Line, desc = Actual}, - Pid ! {fail, self(), Fail} - end, - Actual. - -log(Format, Args, Mod, Line) -> - case global:whereis_name(tftp_global_logger) of - undefined -> - io:format(user, "~p(~p): " ++ Format, - [Mod, Line] ++ Args); - Pid -> - io:format(Pid, "~p(~p): " ++ Format, - [Mod, Line] ++ Args) - end. - -default_config() -> - []. - -t() -> - t([{?MODULE, all}]). - -t(Cases) -> - t(Cases, default_config()). - -t(Cases, Config) -> - process_flag(trap_exit, true), - Res = lists:flatten(do_test(Cases, Config)), - io:format("Res: ~p\n", [Res]), - display_result(Res), - Res. - -do_test({Mod, Fun}, Config) when is_atom(Mod), is_atom(Fun) -> - case catch apply(Mod, Fun, [suite]) of - [] -> - io:format("Eval: ~p:", [{Mod, Fun}]), - Res = eval(Mod, Fun, Config), - {R, _, _} = Res, - io:format(" ~p\n", [R]), - Res; - - Cases when is_list(Cases) -> - io:format("Expand: ~p ...\n", [{Mod, Fun}]), - Map = fun(Case) when is_atom(Case)-> {Mod, Case}; - (Case) -> Case - end, - do_test(lists:map(Map, Cases), Config); - - {req, _, {conf, Init, Cases, Finish}} -> - case (catch apply(Mod, Init, [Config])) of - Conf when is_list(Conf) -> - io:format("Expand: ~p ...\n", [{Mod, Fun}]), - Map = fun(Case) when is_atom(Case)-> {Mod, Case}; - (Case) -> Case - end, - Res = do_test(lists:map(Map, Cases), Conf), - (catch apply(Mod, Finish, [Conf])), - Res; - - {'EXIT', {skipped, Reason}} -> - io:format(" => skipping: ~p\n", [Reason]), - [{skipped, {Mod, Fun}, Reason}]; - - Error -> - io:format(" => failed: ~p\n", [Error]), - [{failed, {Mod, Fun}, Error}] - end; - - {'EXIT', {undef, _}} -> - io:format("Undefined: ~p\n", [{Mod, Fun}]), - [{nyi, {Mod, Fun}, ok}]; - - Error -> - io:format("Ignoring: ~p: ~p\n", [{Mod, Fun}, Error]), - [{failed, {Mod, Fun}, Error}] - end; -do_test(Mod, Config) when is_atom(Mod) -> - Res = do_test({Mod, all}, Config), - Res; -do_test(Cases, Config) when is_list(Cases) -> - [do_test(Case, Config) || Case <- Cases]; -do_test(Bad, _Config) -> - [{badarg, Bad, ok}]. - -eval(Mod, Fun, Config) -> - TestCase = {?MODULE, Mod, Fun}, - Label = lists:concat(["TEST CASE: ", Fun]), - et:report_event(40, ?MODULE, Mod, Label ++ " started", - [TestCase, Config]), - global:register_name(tftp_test_case_sup, self()), - Flag = process_flag(trap_exit, true), - Config2 = Mod:init_per_testcase(Fun, Config), - Pid = spawn_link(?MODULE, do_eval, [self(), Mod, Fun, Config2]), - R = wait_for_evaluator(Pid, Mod, Fun, Config2, []), - Mod:end_per_testcase(Fun, Config2), - global:unregister_name(tftp_test_case_sup), - process_flag(trap_exit, Flag), - R. - -wait_for_evaluator(Pid, Mod, Fun, Config, Errors) -> - TestCase = {?MODULE, Mod, Fun}, - Label = lists:concat(["TEST CASE: ", Fun]), - receive - {done, Pid, ok} when Errors == [] -> - et:report_event(40, Mod, ?MODULE, Label ++ " ok", - [TestCase, Config]), - {ok, {Mod, Fun}, Errors}; - {done, Pid, {ok, _}} when Errors == [] -> - et:report_event(40, Mod, ?MODULE, Label ++ " ok", - [TestCase, Config]), - {ok, {Mod, Fun}, Errors}; - {done, Pid, Fail} -> - et:report_event(20, Mod, ?MODULE, Label ++ " failed", - [TestCase, Config, {return, Fail}, Errors]), - {failed, {Mod,Fun}, Fail}; - {'EXIT', Pid, {skipped, Reason}} -> - et:report_event(20, Mod, ?MODULE, Label ++ " skipped", - [TestCase, Config, {skipped, Reason}]), - {skipped, {Mod, Fun}, Errors}; - {'EXIT', Pid, Reason} -> - et:report_event(20, Mod, ?MODULE, Label ++ " crashed", - [TestCase, Config, {'EXIT', Reason}]), - {crashed, {Mod, Fun}, [{'EXIT', Reason} | Errors]}; - {fail, Pid, Reason} -> - wait_for_evaluator(Pid, Mod, Fun, Config, Errors ++ [Reason]) - end. - -do_eval(ReplyTo, Mod, Fun, Config) -> - case (catch apply(Mod, Fun, [Config])) of - {'EXIT', {skipped, Reason}} -> - ReplyTo ! {'EXIT', self(), {skipped, Reason}}; - Other -> - ReplyTo ! {done, self(), Other} - end, - unlink(ReplyTo), - exit(shutdown). - -display_result([]) -> - io:format("OK\n", []); -display_result(Res) when is_list(Res) -> - Ok = [MF || {ok, MF, _} <- Res], - Nyi = [MF || {nyi, MF, _} <- Res], - Skipped = [{MF, Reason} || {skipped, MF, Reason} <- Res], - Failed = [{MF, Reason} || {failed, MF, Reason} <- Res], - Crashed = [{MF, Reason} || {crashed, MF, Reason} <- Res], - display_summary(Ok, Nyi, Skipped, Failed, Crashed), - display_skipped(Skipped), - display_failed(Failed), - display_crashed(Crashed). - -display_summary(Ok, Nyi, Skipped, Failed, Crashed) -> - io:format("\nTest case summary:\n", []), - display_summary(Ok, "successful"), - display_summary(Nyi, "not yet implemented"), - display_summary(Skipped, "skipped"), - display_summary(Failed, "failed"), - display_summary(Crashed, "crashed"), - io:format("\n", []). - -display_summary(Res, Info) -> - io:format(" ~w test cases ~s\n", [length(Res), Info]). - -display_skipped([]) -> - ok; -display_skipped(Skipped) -> - io:format("Skipped test cases:\n", []), - F = fun({MF, Reason}) -> io:format(" ~p => ~p\n", [MF, Reason]) end, - lists:foreach(F, Skipped), - io:format("\n", []). - - -display_failed([]) -> - ok; -display_failed(Failed) -> - io:format("Failed test cases:\n", []), - F = fun({MF, Reason}) -> io:format(" ~p => ~p\n", [MF, Reason]) end, - lists:foreach(F, Failed), - io:format("\n", []). - -display_crashed([]) -> - ok; -display_crashed(Crashed) -> - io:format("Crashed test cases:\n", []), - F = fun({MF, Reason}) -> io:format(" ~p => ~p\n", [MF, Reason]) end, - lists:foreach(F, Crashed), - io:format("\n", []). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% generic callback -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --record(generic_state, {state, prepare, open, read, write, abort}). - -prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, Initial) when is_list(Initial) -> - State = lookup_option(state, mandatory, Initial), - Prepare = lookup_option(prepare, mandatory, Initial), - Open = lookup_option(open, mandatory, Initial), - Read = lookup_option(read, mandatory, Initial), - Write = lookup_option(write, mandatory, Initial), - Abort = lookup_option(abort, mandatory, Initial), - case Prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, State) of - {ok, AcceptedOptions, NewState} -> - {ok, - AcceptedOptions, - #generic_state{state = NewState, - prepare = Prepare, - open = Open, - read = Read, - write = Write, - abort = Abort}}; - Other -> - Other - end. - -open(Peer, Access, LocalFilename, Mode, SuggestedOptions, Initial) when is_list(Initial) -> - case prepare(Peer, Access, LocalFilename, Mode, SuggestedOptions, Initial) of - {ok, SuggestedOptions2, GenericState} -> - open(Peer, Access, LocalFilename, Mode, SuggestedOptions2, GenericState); - Other -> - Other - end; -open(Peer, Access, LocalFilename, Mode, SuggestedOptions, #generic_state{state = State, open = Open} = GenericState) -> - case Open(Peer, Access, LocalFilename, Mode, SuggestedOptions, State) of - {ok, SuggestedOptions2, NewState} -> - {ok, SuggestedOptions2, GenericState#generic_state{state = NewState}}; - Other -> - Other - end. - -read(#generic_state{state = State, read = Read} = GenericState) -> - case Read(State) of - {more, DataBlock, NewState} -> - {more, DataBlock, GenericState#generic_state{state = NewState}}; - Other -> - Other - end. - -write(DataBlock, #generic_state{state = State, write = Write} = GenericState) -> - case Write(DataBlock, State) of - {more, NewState} -> - {more, GenericState#generic_state{state = NewState}}; - Other -> - Other - end. - -abort(Code, Text, #generic_state{state = State, abort = Abort}) -> - Abort(Code, Text, State). - -lookup_option(Key, Default, Options) -> - case lists:keysearch(Key, 1, Options) of - {value, {_, Val}} -> - Val; - false -> - Default - end. - diff --git a/lib/inets/test/tftp_test_lib.hrl b/lib/inets/test/tftp_test_lib.hrl deleted file mode 100644 index e7a5a37d2c..0000000000 --- a/lib/inets/test/tftp_test_lib.hrl +++ /dev/null @@ -1,44 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2007-2016. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% - --record('REASON', {mod, line, desc}). - --define(LOG(Format, Args), - tftp_test_lib:log(Format, Args, ?MODULE, ?LINE)). - --define(ERROR(Reason), - tftp_test_lib:error(Reason, ?MODULE, ?LINE)). - --define(VERIFY(Expected, Expr), - fun() -> - AcTuAlReS = (catch (Expr)), - case AcTuAlReS of - Expected -> ?LOG("Ok, ~p\n", [AcTuAlReS]); - _ -> ?ERROR(AcTuAlReS) - end, - AcTuAlReS - end()). - --define(IGNORE(Expr), - fun() -> - AcTuAlReS = (catch (Expr)), - ?LOG("Ok, ~p\n", [AcTuAlReS]), - AcTuAlReS - end()). |