aboutsummaryrefslogtreecommitdiffstats
path: root/lib/inets/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/inets/test')
-rw-r--r--lib/inets/test/Makefile55
-rw-r--r--lib/inets/test/ftp_SUITE.erl1180
-rw-r--r--lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel18
-rw-r--r--lib/inets/test/ftp_SUITE_data/vsftpd.conf26
-rw-r--r--lib/inets/test/ftp_format_SUITE.erl328
l---------lib/inets/test/ftp_internal.hrl1
-rw-r--r--lib/inets/test/ftp_property_test_SUITE.erl53
-rw-r--r--lib/inets/test/inets_SUITE.erl77
-rw-r--r--lib/inets/test/inets_socketwrap_SUITE.erl34
-rw-r--r--lib/inets/test/inets_sup_SUITE.erl52
-rw-r--r--lib/inets/test/tftp_SUITE.erl949
-rw-r--r--lib/inets/test/tftp_test_lib.erl308
-rw-r--r--lib/inets/test/tftp_test_lib.hrl44
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()).