diff options
Diffstat (limited to 'lib/inets/test')
-rw-r--r-- | lib/inets/test/Makefile | 78 | ||||
-rw-r--r-- | lib/inets/test/ftp_SUITE_data/TAR.exclude | 2 | ||||
-rw-r--r-- | lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel | 17 | ||||
-rw-r--r-- | lib/inets/test/ftp_SUITE_data/inets_test_hosts | 15 | ||||
-rw-r--r-- | lib/inets/test/ftp_suite_lib.erl | 116 | ||||
-rw-r--r-- | lib/inets/test/ftp_ticket_test.erl | 13 | ||||
-rw-r--r-- | lib/inets/test/httpc_SUITE.erl | 794 | ||||
-rw-r--r-- | lib/inets/test/httpc_cookie_SUITE.erl | 201 | ||||
-rw-r--r-- | lib/inets/test/httpd_SUITE.erl | 128 | ||||
-rw-r--r-- | lib/inets/test/inets_SUITE.erl | 153 | ||||
-rw-r--r-- | lib/inets/test/inets_sup_SUITE.erl | 92 |
11 files changed, 1125 insertions, 484 deletions
diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile index d13ffea544..1dd7a51717 100644 --- a/lib/inets/test/Makefile +++ b/lib/inets/test/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1997-2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 1997-2010. All Rights Reserved. +# # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in # compliance with the License. You should have received a copy of the # Erlang Public License along with this software. If not, it can be # retrieved online at http://www.erlang.org/. -# +# # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. -# +# # %CopyrightEnd% # # @@ -32,6 +32,12 @@ VSN = $(INETS_VSN) # ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN) + + +# ---------------------------------------------------- # Target Specs # ---------------------------------------------------- INCLUDES = -I. \ @@ -188,22 +194,26 @@ HRL_FILES = inets_test_lib.hrl \ ERL_FILES = $(MODULES:%=%.erl) -TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) - -INETS_FILES = Makefile.inets rules.mk suite_targets.mk \ - inets.config inets.spec inets.spec.vxworks - - SOURCE = $(ERL_FILES) $(HRL_FILES) +TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + INETS_SPECS = inets.spec inets.spec.vxworks +INETS_FILES = inets.config $(INETS_SPECS) -INETS_DATADIR = inets_SUITE_data inets_sup_SUITE_data -HTTPD_DATADIR = httpd_test_data httpd_SUITE_data -HTTPC_DATADIR = httpc_SUITE_data -FTP_DATADIR = ftp_SUITE_data +# SUB_SUITES = \ +# inets_sup_suite \ +# inets_httpd_suite \ +# inets_httpc_suite \ +# inets_ftp_suite \ +# inets_tftp_suite -DATADIRS = $(INETS_DATADIR) $(HTTPD_DATADIR) $(HTTPC_DATADIR) $(FTP_DATADIR) +INETS_DATADIRS = inets_SUITE_data inets_sup_SUITE_data +HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data +HTTPC_DATADIRS = httpc_SUITE_data +FTP_DATADIRS = ftp_SUITE_data + +DATADIRS = $(INETS_DATADIRS) $(HTTPD_DATADIRS) $(HTTPC_DATADIRS) $(FTP_DATADIRS) EMAKEFILE = Emakefile MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile) @@ -216,10 +226,10 @@ BUILDTARGET = emakebuild RELTEST_FILES = $(EMAKEFILE) $(INETS_SPECS) $(SOURCE) endif + # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN) RELTESTSYSDIR = $(RELEASE_PATH)/inets_test RELTESTSYSALLDATADIR = $(RELTESTSYSDIR)/all_SUITE_data @@ -276,9 +286,19 @@ release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/test $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/test $(INSTALL_DATA) $(INETS_FILES) $(RELSYSDIR)/test - $(INSTALL_DIR) $(RELSYSDIR)/test/$(HTTPD_DATADIR) - tar chf - -C $(HTTPD_DATADIR) . | (cd $(RELSYSDIR)/test/$(HTTPD_DATADIR); tar xf -) - (cd $(RELSYSDIR)/test; mv Makefile.inets Makefile) + @for d in $(DATADIRS); do \ + echo "installing data dir $$d"; \ + echo $$d/TAR.exclude2 > $$d/TAR.exclude2; \ + cat $$d/TAR.exclude >> $$d/TAR.exclude2; \ + find $$d -name '*.contrib*' >> $$d/TAR.exclude2; \ + find $$d -name '*.keep*' >> $$d/TAR.exclude2; \ + find $$d -name '*.mkelem*' >> $$d/TAR.exclude2; \ + find $$d -name '*~' >> $$d/TAR.exclude2; \ + find $$d -name 'erl_crash.dump' >> $$d/TAR.exclude2; \ + find $$d -name 'core' >> $$d/TAR.exclude2; \ + find $$d -name '.cmake.state' >> $$d/TAR.exclude2; \ + tar cfX - $$d/TAR.exclude2 $$d | (cd $(RELSYSDIR)/test; tar xf -); \ + done release_tests_spec: opt $(INSTALL_DIR) $(RELTESTSYSDIR) @@ -287,7 +307,6 @@ release_tests_spec: opt tar chf - $(DATADIRS) | (cd $(RELTESTSYSDIR); tar xf -) $(INSTALL_DIR) $(RELTESTSYSALLDATADIR) $(INSTALL_DATA) $(MAKEFILE_SRC) $(RELTESTSYSALLDATADIR)/Makefile.src - $(INSTALL_DATA) copy_files.erl $(RELTESTSYSALLDATADIR)/copy_files.erl $(INSTALL_DIR) $(RELTESTSYSBINDIR) chmod -f -R +x $(RELTESTSYSBINDIR) tar cf - -C $(INETS_SSL_LIB_DIR) . | (cd $(RELTESTSYSALLDATADIR); tar xf -) @@ -301,7 +320,24 @@ info: @echo "MAKE_EMAKE = $(MAKE_EMAKE)" @echo "EMAKEFILE = $(EMAKEFILE)" @echo "BUILDTARGET = $(BUILDTARGET)" + @echo "" + @echo "MODULES = $(MODULES)" + @echo "ERL_FILES = $(ERL_FILES)" + @echo "SOURCE = $(SOURCE)" @echo "TARGET_FILES = $(TARGET_FILES)" + @echo "" + @echo "INETS_SPECS = $(INETS_SPECS)" + @echo "INETS_FILES = $(INETS_FILES)" + @echo "" + @echo "RELEASE_PATH = $(RELEASE_PATH)" + @echo "RELSYSDIR = $(RELSYSDIR)" + @echo "RELTESTSYSDIR = $(RELTESTSYSDIR)" + @echo "RELTESTSYSALLDATADIR = $(RELTESTSYSALLDATADIR)" + @echo "RELTESTSYSBINDIR = $(RELTESTSYSBINDIR)" + @echo "" + @echo "DATADIRS = $(DATADIRS)" + @echo "REL_DATADIRS = $(REL_DATADIRS)" + @echo "" @echo "INETS_DATA_DIR = $(INETS_DATA_DIR)" @echo "INETS_PRIV_DIR = $(INETS_PRIV_DIR)" @echo "INETS_SSL_LIB_DIR = $(INETS_SSL_LIB_DIR)" diff --git a/lib/inets/test/ftp_SUITE_data/TAR.exclude b/lib/inets/test/ftp_SUITE_data/TAR.exclude new file mode 100644 index 0000000000..2078965740 --- /dev/null +++ b/lib/inets/test/ftp_SUITE_data/TAR.exclude @@ -0,0 +1,2 @@ +ftp_SUITE_data/TAR.exclude +ftp_SUITE_data/ftpd_hosts diff --git a/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel new file mode 100644 index 0000000000..a820f8d014 --- /dev/null +++ b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel @@ -0,0 +1,17 @@ +%% 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. +[{solaris8_sparc, []}, + {solaris9_sparc, []}, + {solaris10_sparc, []}, + {solaris10_x86, []}, + {linux_x86, []}, + {linux_ppc, []}, + {macosx_ppc, []}, + {macosx_x86, []}, + {openbsd_x86, []}, + {freebsd_x86, []}, + {netbsd_x86, []}, + {windows_xp, []}, + {windows_2003_server, []}, + {ticket_test, []}]. diff --git a/lib/inets/test/ftp_SUITE_data/inets_test_hosts b/lib/inets/test/ftp_SUITE_data/inets_test_hosts deleted file mode 100644 index 20623b9edc..0000000000 --- a/lib/inets/test/ftp_SUITE_data/inets_test_hosts +++ /dev/null @@ -1,15 +0,0 @@ -%% Add a host name in the appropriate list -[{solaris8_sparc, ["fingon"]}, - {solaris9_sparc, []}, - {solaris10_sparc, []}, - {solaris10_x86, []}, - {linux_x86, []}, - {linux_ppc, []}, - {macosx_ppc, []}, - {macosx_x86, []}, - {openbsd_x86, []}, - {freebsd_x86, []}, - {netbsd_x86, []}, - {windows_xp, []}, - {windows_2003_server, ["fobi"]}, - {ticket_test,["fingon","finrod"]}]. diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl index 29339da6e5..75e1a5a7f9 100644 --- a/lib/inets/test/ftp_suite_lib.erl +++ b/lib/inets/test/ftp_suite_lib.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2005-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -23,6 +23,7 @@ -include("test_server.hrl"). -include("test_server_line.hrl"). +-include("inets_test_lib.hrl"). %% Test server specific exports % -export([init_per_testcase/2, end_per_testcase/2]). @@ -37,7 +38,6 @@ --define(FTP_HOSTS(X),ftp_hosts(X)). -define(FTP_USER, "anonymous"). -define(FTP_PASS, passwd()). -define(FTP_PORT, 21). @@ -73,7 +73,7 @@ ftpd_init(FtpdTag, Config) -> Hosts = case ?config(ftpd_hosts, Config) of undefined -> - ?FTP_HOSTS(data_dir(Config)); + ftpd_hosts(data_dir(Config)); H -> H end, @@ -123,6 +123,59 @@ get_ftpd_host([Host|Hosts]) -> get_ftpd_host(Hosts) end. + +%%-------------------------------------------------------------------- + +dirty_select_ftpd_host(Config) -> + Hosts = + case ?config(ftpd_hosts, Config) of + undefined -> + ftpd_hosts(data_dir(Config)); + H -> + H + end, + dirty_select_ftpd_host2(Hosts). + +dirty_select_ftpd_host2([]) -> + throw({error, not_found}); +dirty_select_ftpd_host2([{PlatformTag, Hosts} | PlatformHosts]) -> + case dirty_select_ftpd_host3(Hosts) of + none -> + dirty_select_ftpd_host2(PlatformHosts); + {ok, Host} -> + {PlatformTag, Host} + end. + +dirty_select_ftpd_host3([]) -> + none; +dirty_select_ftpd_host3([Host|Hosts]) when is_list(Host) -> + case dirty_select_ftpd_host4(Host) of + true -> + {ok, Host}; + false -> + dirty_select_ftpd_host3(Hosts) + end; +dirty_select_ftpd_host3([_|Hosts]) -> + dirty_select_ftpd_host3(Hosts). + +%% This is a very simple and dirty test that there is a +%% (FTP) deamon on the other end. +dirty_select_ftpd_host4(Host) -> + Port = 21, + IpFam = inet, + Opts = [IpFam, binary, {packet, 0}, {active, false}], + Timeout = ?SECS(5), + case gen_tcp:connect(Host, Port, Opts, Timeout) of + {ok, Sock} -> + gen_tcp:close(Sock), + true; + _Error -> + false + end. + + +%%-------------------------------------------------------------------- + test_filenames() -> {ok, Host} = inet:gethostname(), File = Host ++ "_ftp_test.txt", @@ -1048,12 +1101,20 @@ ticket_6035(Config) -> "~n Config: ~p", [Config]), PrivDir = ?config(priv_dir, Config), LogFile = filename:join([PrivDir,"ticket_6035.log"]), - Pid = spawn(?MODULE,open_wait_6035,[self()]), - error_logger:logfile({open,LogFile}), - ok = kill_ftp_proc_6035(Pid,LogFile), - error_logger:logfile(close), - p("ticket_6035 -> done", []), - ok. + try + begin + Host = dirty_select_ftpd_host(Config), + Pid = spawn(?MODULE, open_wait_6035, [Host, self()]), + error_logger:logfile({open, LogFile}), + ok = kill_ftp_proc_6035(Pid,LogFile), + error_logger:logfile(close), + p("ticket_6035 -> done", []), + ok + end + catch + throw:{error, not_found} -> + {skip, "No available FTP servers"} + end. kill_ftp_proc_6035(Pid, LogFile) -> p("kill_ftp_proc_6035 -> entry"), @@ -1072,8 +1133,7 @@ kill_ftp_proc_6035(Pid, LogFile) -> is_error_report_6035(LogFile) end. -open_wait_6035(From) -> - FtpServer = "elrond", +open_wait_6035(FtpServer, From) -> p("open_wait_6035 -> try connect to ~s", [FtpServer]), case ftp:open(FtpServer, [{timeout, timer:seconds(15)}]) of {ok, Pid} -> @@ -1491,14 +1551,15 @@ passwd() -> end, "ftp_SUITE@" ++ Host. -ftp_hosts(Config) -> - DataDir = ?config(data_dir,Config), - FileName = filename:join([DataDir,"../ftp_SUITE_data/",inets_test_hosts]), - io:format("FileName: ~p~n",[FileName]), +ftpd_hosts(Config) -> + DataDir = ?config(data_dir, Config), + FileName = filename:join([DataDir, "../ftp_SUITE_data/", ftpd_hosts]), + io:format("FileName: ~p~n", [FileName]), case file:consult(FileName) of - {ok,[Hosts]} when is_list(Hosts) -> + {ok, [Hosts]} when is_list(Hosts) -> Hosts; - _ -> [] + _ -> + [] end. wrapper(Prefix,doc,Func) -> @@ -1507,13 +1568,14 @@ wrapper(_,X,Func) -> Func(X). data_dir(Config) -> - case ?config(data_dir,Config) of + case ?config(data_dir, Config) of List when (length(List) > 0) -> - PathList = filename:split(List), - {NewPathList,_} = lists:split((length(PathList)-1),PathList), - DataDir=filename:join(NewPathList++[ftp_SUITE_data]), - _NewConfig = lists:keyreplace(data_dir,1,Config, - {data_dir,DataDir}); + PathList = filename:split(List), + {NewPathList,_} = lists:split((length(PathList)-1), PathList), + DataDir = filename:join(NewPathList ++ [ftp_SUITE_data]), + NewConfig = + lists:keyreplace(data_dir,1,Config, {data_dir,DataDir}), + NewConfig; _ -> Config end. diff --git a/lib/inets/test/ftp_ticket_test.erl b/lib/inets/test/ftp_ticket_test.erl index 96e443fab5..6748df03bb 100644 --- a/lib/inets/test/ftp_ticket_test.erl +++ b/lib/inets/test/ftp_ticket_test.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2006-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2006-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -39,8 +39,7 @@ all(suite) -> {conf,init,tickets(),fin}. init(Config) -> - [{ftp_remote_host, "elrond"}|Config]. -% ?LIB_MOD:ftpd_init(ticket_test,Config). + ?LIB_MOD:ftpd_init(ticket_test, Config). tickets() -> [ticket_6035]. diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index 3485966307..4914a16264 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -1,25 +1,28 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% +%% +%% ts:run(inets, httpc_SUITE, [batch]). +%% + -module(httpc_SUITE). --author('[email protected]'). -include("test_server.hrl"). -include("test_server_line.hrl"). @@ -55,6 +58,7 @@ %% Description: Returns documentation/test cases in this test suite %% or a skip tuple if the platform is not supported. %%-------------------------------------------------------------------- + all(doc) -> ["Test the http client in the intes application."]; all(suite) -> @@ -93,7 +97,7 @@ all(suite) -> http_server_does_not_exist, http_invalid_http, http_emulate_lower_versions, - http_relaxed, + http_relaxed, page_does_not_exist, proxy_page_does_not_exist, proxy_https_not_supported, @@ -138,12 +142,12 @@ init_per_suite(Config) -> end, {ok, FileInfo} = file:read_file_info(Cgi), - ok = file:write_file_info(Cgi, - FileInfo#file_info{mode = 8#00755}), + ok = file:write_file_info(Cgi, FileInfo#file_info{mode = 8#00755}), - [{server_root, ServerRoot}, {doc_root, DocRoot}, - {local_port, ?IP_PORT}, {local_ssl_port, ?SSL_PORT} - | Config]. + [{server_root, ServerRoot}, + {doc_root, DocRoot}, + {local_port, ?IP_PORT}, + {local_ssl_port, ?SSL_PORT} | Config]. %%-------------------------------------------------------------------- %% Function: end_per_suite(Config) -> _ @@ -170,11 +174,17 @@ end_per_suite(Config) -> %% Note: This function is free to add any key/value pairs to the Config %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- +init_per_testcase(otp_8154_1 = Case, Config) -> + init_per_testcase(Case, 5, Config); init_per_testcase(Case, Config) -> - io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE,Case]), + init_per_testcase(Case, 2, Config). + +init_per_testcase(Case, Timeout, Config) -> + io:format(user, "~n~n*** INIT ~w:~w[~w] ***~n~n", + [?MODULE, Timeout, Case]), PrivDir = ?config(priv_dir, Config), application:stop(inets), - Dog = test_server:timetrap(inets_test_lib:minutes(10)), + Dog = test_server:timetrap(inets_test_lib:minutes(Timeout)), TmpConfig = lists:keydelete(watchdog, 1, Config), IpConfFile = integer_to_list(?IP_PORT) ++ ".conf", SslConfFile = integer_to_list(?SSL_PORT) ++ ".conf", @@ -185,11 +195,10 @@ init_per_testcase(Case, Config) -> application:stop(ssl), TmpConfig2 = lists:keydelete(local_ssl_server, 1, TmpConfig), + %% Will start inets Server = - %% Will start inets - inets_test_lib:start_http_server( - filename:join(PrivDir, - SslConfFile)), + inets_test_lib:start_http_server( + filename:join(PrivDir, SslConfFile)), [{watchdog, Dog}, {local_ssl_server, Server} | TmpConfig2]; "proxy" ++ Rest -> case Rest of @@ -224,7 +233,8 @@ init_per_testcase(Case, Config) -> http:set_options([{proxy, {{?PROXY, ?PROXY_PORT}, ["localhost", ?IPV6_LOCAL_HOST]}}]), - inets:enable_trace(max, io), + inets:enable_trace(max, io, httpc), + %% snmp:set_trace([gen_tcp, inet_tcp, prim_inet]), NewConfig. %%-------------------------------------------------------------------- @@ -269,7 +279,10 @@ tickets(suite) -> no_content_204_otp_6982, missing_CR_otp_7304, otp_7883, - otp_8154 + otp_8154, + otp_8106, + otp_8056, + otp_8371 ]. @@ -295,9 +308,9 @@ http_head(Config) when is_list(Config) -> {ok, {{_,200,_}, [_ | _], []}} -> ok; {ok, WrongReply} -> - test_server:fail({wrong_reply, WrongReply}); + tsf({wrong_reply, WrongReply}); Error -> - test_server:fail({failed, Error}) + tsf({failed, Error}) end; _ -> {skip, "Failed to start local http-server"} @@ -308,28 +321,47 @@ http_get(doc) -> http_get(suite) -> []; http_get(Config) when is_list(Config) -> - case ?config(local_server, Config) of + tsp("http_get -> entry with" + "~n Config: ~p", [Config]), + case ?config(local_server, Config) of ok -> - Port = ?config(local_port, Config), - URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", - Timeout = timer:seconds(1), - ConnTimeout = Timeout + timer:seconds(1), - {ok, {{_,200,_}, [_ | _], Body = [_ | _]}} = - http:request(get, {URL, []}, - [{timeout, Timeout}, {connect_timeout, ConnTimeout}], []), - %% eqvivivalent to http:request(get, {URL, []}, [], []), - inets_test_lib:check_body(Body), - {ok, {{_,200,_}, [_ | _], Bin}} = - http:request(get, {URL, []}, [], [{body_format, binary}]), - case Bin of - Bin when is_binary(Bin) -> - ok; - _ -> - test_server:fail(body_format_not_binary) - end; - _ -> - {skip, "Failed to start local http-server"} - end. + tsp("local-server running"), + Method = get, + Port = ?config(local_port, Config), + URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", + Request = {URL, []}, + Timeout = timer:seconds(1), + ConnTimeout = Timeout + timer:seconds(1), + HttpOptions1 = [{timeout, Timeout}, {connect_timeout, ConnTimeout}], + Options1 = [], + Body = + case http:request(Method, Request, HttpOptions1, Options1) of + {ok, {{_,200,_}, [_ | _], ReplyBody = [_ | _]}} -> + ReplyBody; + {ok, UnexpectedReply1} -> + tsf({unexpected_reply, UnexpectedReply1}); + {error, _} = Error1 -> + tsf({bad_reply, Error1}) + end, + + %% eqvivivalent to http:request(get, {URL, []}, [], []), + inets_test_lib:check_body(Body), + + HttpOptions2 = [], + Options2 = [{body_format, binary}], + case http:request(Method, Request, HttpOptions2, Options2) of + {ok, {{_,200,_}, [_ | _], Bin}} when is_binary(Bin) -> + ok; + {ok, {{_,200,_}, [_ | _], BadBin}} -> + tsf({body_format_not_binary, BadBin}); + {ok, UnexpectedReply2} -> + tsf({unexpected_reply, UnexpectedReply2}); + {error, _} = Error2 -> + tsf({bad_reply, Error2}) + end; + _ -> + {skip, "Failed to start local http-server"} + end. %%------------------------------------------------------------------------- http_post(doc) -> @@ -389,7 +421,9 @@ http_emulate_lower_versions(Config) when is_list(Config) -> {skip, "Failed to start local http-server"} end. + %%------------------------------------------------------------------------- + http_relaxed(doc) -> ["Test relaxed mode"]; http_relaxed(suite) -> @@ -397,12 +431,7 @@ http_relaxed(suite) -> http_relaxed(Config) when is_list(Config) -> ok = http:set_options([{ipv6, disabled}]), % also test the old option %% ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_reason_phrase.html", @@ -428,13 +457,8 @@ http_dummy_pipe(suite) -> []; http_dummy_pipe(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), + {DummyServerPid, Port} = dummy_server(self(), ipv4), - Port = receive - {port, ServerPort} -> - ServerPort - end, - URL = ?URL_START ++ integer_to_list(Port) ++ "/foobar.html", test_pipeline(URL), @@ -451,78 +475,126 @@ http_inets_pipe(Config) when is_list(Config) -> case ?config(local_server, Config) of ok -> - Port = ?config(local_port, Config), - URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", + Port = ?config(local_port, Config), + URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", test_pipeline(URL); _ -> {skip, "Failed to start local http-server"} end. test_pipeline(URL) -> - + p("test_pipeline -> entry with" + "~n URL: ~p", [URL]), + http:set_options([{pipeline_timeout, 50000}]), + p("test_pipeline -> issue (async) request 1"), {ok, RequestId1} = http:request(get, {URL, []}, [], [{sync, false}]), test_server:format("RequestId1: ~p~n", [RequestId1]), + p("test_pipeline -> RequestId1: ~p", [RequestId1]), %% Make sure pipeline is initiated + p("test_pipeline -> sleep some", []), test_server:sleep(4000), + p("test_pipeline -> issue (async) request 2"), {ok, RequestId2} = http:request(get, {URL, []}, [], [{sync, false}]), - test_server:format("RequestId2: ~p~n", [RequestId2]), + tsp("RequestId2: ~p", [RequestId2]), + p("test_pipeline -> RequestId2: ~p", [RequestId2]), - {ok, {{_,200,_}, [_ | _], [_ | _]}} - = http:request(get, {URL, []}, [], []), + p("test_pipeline -> issue (sync) request 3"), + {ok, {{_,200,_}, [_ | _], [_ | _]}} = + http:request(get, {URL, []}, [], []), + + p("test_pipeline -> expect reply for (async) request 1 or 2"), receive {http, {RequestId1, {{_, 200, _}, _, _}}} -> + p("test_pipeline -> received reply for (async) request 1 - now wait for 2"), receive {http, {RequestId2, {{_, 200, _}, _, _}}} -> + p("test_pipeline -> received reply for (async) request 2"), ok; {http, Msg1} -> test_server:fail(Msg1) end; {http, {RequestId2, {{_, 200, _}, _, _}}} -> + io:format("test_pipeline -> received reply for (async) request 2 - now wait for 1"), receive {http, {RequestId1, {{_, 200, _}, _, _}}} -> + io:format("test_pipeline -> received reply for (async) request 1"), ok; {http, Msg2} -> test_server:fail(Msg2) end; {http, Msg3} -> - test_server:fail(Msg3) + test_server:fail(Msg3) + after 60000 -> + receive Any1 -> + tsp("received crap after timeout: ~n ~p", [Any1]), + test_server:fail({error, {timeout, Any1}}) + end end, + p("test_pipeline -> sleep some"), + test_server:sleep(4000), + + p("test_pipeline -> issue (async) request 4"), {ok, RequestId3} = - http:request(get, {URL, []}, [], [{sync, false}]), - test_server:format("RequestId3: ~p~n", [RequestId3]), + http:request(get, {URL, []}, [], [{sync, false}]), + tsp("RequestId3: ~p", [RequestId3]), + p("test_pipeline -> RequestId3: ~p", [RequestId3]), + + p("test_pipeline -> issue (async) request 5"), {ok, RequestId4} = http:request(get, {URL, []}, [], [{sync, false}]), - test_server:format("RequestId4: ~p~n", [RequestId4]), + tsp("RequestId4: ~p~n", [RequestId4]), + p("test_pipeline -> RequestId4: ~p", [RequestId4]), + + p("test_pipeline -> cancel (async) request 4"), ok = http:cancel_request(RequestId3), + + p("test_pipeline -> expect *no* reply for cancelled (async) request 4 (for 3 secs)"), receive {http, {RequestId3, _}} -> - test_server:fail(http_cancel_request_failed) + test_server:fail(http_cancel_request_failed) after 3000 -> ok end, + + p("test_pipeline -> expect reply for (async) request 4"), Body = receive - Res = {http, {RequestId4, {{_, 200, _}, _, BinBody4}}} -> - test_server:format(" Receive : ~p~n", [Res]), + {http, {RequestId4, {{_, 200, _}, _, BinBody4}}} = Res -> + p("test_pipeline -> received reply for (async) request 5"), + tsp("Receive : ~p", [Res]), BinBody4; {http, Msg4} -> test_server:fail(Msg4) + after 60000 -> + receive Any2 -> + tsp("received crap after timeout: ~n ~p", [Any2]), + test_server:fail({error, {timeout, Any2}}) + end end, + + p("test_pipeline -> check reply for (async) request 5"), inets_test_lib:check_body(binary_to_list(Body)), + p("test_pipeline -> ensure no unexpected incomming"), receive {http, Any} -> test_server:fail({unexpected_message, Any}) after 500 -> ok - end. + end, + + p("test_pipeline -> done"), + ok. + + + %%------------------------------------------------------------------------- http_trace(doc) -> ["Perform a TRACE request that goes through a proxy."]; @@ -700,12 +772,7 @@ http_headers_dummy(suite) -> []; http_headers_dummy(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy_headers.html", @@ -770,12 +837,7 @@ http_bad_response(suite) -> []; http_bad_response(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_crlf.html", @@ -868,64 +930,90 @@ http_redirect(doc) -> http_redirect(suite) -> []; http_redirect(Config) when is_list(Config) -> + tsp("http_redirect -> entry with" + "~n Config: ~p", [Config]), case ?config(local_server, Config) of ok -> + tsp("http_redirect -> set ipfamily option to inet"), ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + + tsp("http_redirect -> start dummy server inet"), + {DummyServerPid, Port} = dummy_server(self(), ipv4), + tsp("http_redirect -> server port = ~p", [Port]), URL300 = ?URL_START ++ integer_to_list(Port) ++ "/300.html", + tsp("http_redirect -> issue request 1: " + "~n ~p", [URL300]), {ok, {{_,200,_}, [_ | _], [_|_]}} = http:request(get, {URL300, []}, [], []), - {ok, {{_,300,_}, [_ | _], _}} - = http:request(get, {URL300, []}, [{autoredirect, false}], - []), + tsp("http_redirect -> issue request 2: " + "~n ~p", [URL300]), + {ok, {{_,300,_}, [_ | _], _}} = + http:request(get, {URL300, []}, [{autoredirect, false}], []), URL301 = ?URL_START ++ integer_to_list(Port) ++ "/301.html", - + tsp("http_redirect -> issue request 3: " + "~n ~p", [URL301]), {ok, {{_,200,_}, [_ | _], [_|_]}} = http:request(get, {URL301, []}, [], []), + tsp("http_redirect -> issue request 4: " + "~n ~p", [URL301]), {ok, {{_,200,_}, [_ | _], []}} = http:request(head, {URL301, []}, [], []), + tsp("http_redirect -> issue request 5: " + "~n ~p", [URL301]), {ok, {{_,301,_}, [_ | _], [_|_]}} = http:request(post, {URL301, [],"text/plain", "foobar"}, [], []), URL302 = ?URL_START ++ integer_to_list(Port) ++ "/302.html", + tsp("http_redirect -> issue request 6: " + "~n ~p", [URL302]), {ok, {{_,200,_}, [_ | _], [_|_]}} = http:request(get, {URL302, []}, [], []), + tsp("http_redirect -> issue request 7: " + "~n ~p", [URL302]), {ok, {{_,200,_}, [_ | _], []}} = http:request(head, {URL302, []}, [], []), + tsp("http_redirect -> issue request 8: " + "~n ~p", [URL302]), {ok, {{_,302,_}, [_ | _], [_|_]}} = http:request(post, {URL302, [],"text/plain", "foobar"}, [], []), URL307 = ?URL_START ++ integer_to_list(Port) ++ "/307.html", + tsp("http_redirect -> issue request 9: " + "~n ~p", [URL307]), {ok, {{_,200,_}, [_ | _], [_|_]}} = http:request(get, {URL307, []}, [], []), + tsp("http_redirect -> issue request 10: " + "~n ~p", [URL307]), {ok, {{_,200,_}, [_ | _], []}} = http:request(head, {URL307, []}, [], []), + tsp("http_redirect -> issue request 11: " + "~n ~p", [URL307]), {ok, {{_,307,_}, [_ | _], [_|_]}} = http:request(post, {URL307, [],"text/plain", "foobar"}, [], []), + tsp("http_redirect -> stop dummy server"), DummyServerPid ! stop, - ok = http:set_options([{ipfamily, inet6fb4}]); % ********** ipfamily = inet6 ************* + tsp("http_redirect -> reset ipfamily option (to inet6fb4)"), + ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + tsp("http_redirect -> done"), + ok; + _ -> {skip, "Failed to start local http-server"} end. @@ -938,12 +1026,7 @@ http_redirect_loop(suite) -> []; http_redirect_loop(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/redirectloop.html", @@ -960,12 +1043,7 @@ http_internal_server_error(suite) -> []; http_internal_server_error(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URL500 = ?URL_START ++ integer_to_list(Port) ++ "/500.html", @@ -1001,12 +1079,7 @@ http_userinfo(suite) -> http_userinfo(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URLAuth = "http://alladin:sesame@localhost:" ++ integer_to_list(Port) ++ "/userinfo.html", @@ -1032,12 +1105,7 @@ http_cookie(suite) -> []; http_cookie(Config) when is_list(Config) -> ok = http:set_options([{cookies, enabled}, {ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URLStart = ?URL_START ++ integer_to_list(Port), @@ -1335,8 +1403,8 @@ proxy_https_not_supported(doc) -> proxy_https_not_supported(suite) -> []; proxy_https_not_supported(Config) when is_list(Config) -> - {error, https_through_proxy_is_not_currently_supported} - = http:request(get, {"https://login.yahoo.com", []}, [], []), + {error, {failed_connecting, https_through_proxy_is_not_currently_supported}} = + http:request(get, {"https://login.yahoo.com", []}, [], []), ok. @@ -1374,51 +1442,68 @@ http_stream_once(doc) -> http_stream_once(suite) -> []; http_stream_once(Config) when is_list(Config) -> + p("http_stream_once -> entry with" + "~n Config: ~p", [Config]), + + p("http_stream_once -> set ipfamily to inet", []), ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - Port = receive - {port, ServerPort} -> - ServerPort - end, + p("http_stream_once -> start dummy server", []), + {DummyServerPid, Port} = dummy_server(self(), ipv4), PortStr = integer_to_list(Port), + p("http_stream_once -> once", []), once(?URL_START ++ PortStr ++ "/once.html"), + p("http_stream_once -> once_chunked", []), once(?URL_START ++ PortStr ++ "/once_chunked.html"), + p("http_stream_once -> dummy", []), once(?URL_START ++ PortStr ++ "/dummy.html"), + p("http_stream_once -> stop dummy server", []), DummyServerPid ! stop, + p("http_stream_once -> set ipfamily to inet6fb4", []), ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + p("http_stream_once -> done", []), ok. once(URL) -> + p("once -> issue sync request for ~p", [URL]), {ok, {{_,200,_}, [_ | _], Body}} = http:request(get, {URL, []}, [], []), + p("once -> issue async (self stream) request for ~p", [URL]), {ok, RequestId} = http:request(get, {URL, []}, [], [{sync, false}, {stream, {self, once}}]), - NewPid = receive - {http, {RequestId, stream_start, _Headers, Pid}} -> - Pid; - {http, Msg} -> - test_server:fail(Msg) - end, + p("once -> await stream_start reply for (async) request ~p", [RequestId]), + NewPid = + receive + {http, {RequestId, stream_start, _Headers, Pid}} -> + p("once -> received stream_start reply for (async) request ~p: ~p", + [RequestId, Pid]), + Pid; + {http, Msg} -> + test_server:fail(Msg) + end, - test_server:format("Request handler: ~p~n", [NewPid]), + tsp("once -> request handler: ~p", [NewPid]), + p("once -> await stream reply for (async) request ~p", [RequestId]), BodyPart = receive {http, {RequestId, stream, BinBodyPart}} -> + p("once -> received stream reply for (async) request ~p: " + "~n~p", [RequestId, binary_to_list(BinBodyPart)]), BinBodyPart end, - test_server:format("First body part: ~p~n", - [binary_to_list(BodyPart)]), + tsp("once -> first body part '~p' received", [binary_to_list(BodyPart)]), StreamedBody = receive_streamed_body(RequestId, BinBodyPart, NewPid), Body = binary_to_list(StreamedBody), + + p("once -> done when Bode: ~p", [Body]), ok. @@ -1509,12 +1594,7 @@ ipv6(Config) when is_list(Config) -> case lists:member(list_to_atom(Hostname), ?config(ipv6_hosts, Config)) of true -> - DummyServerPid = dummy_server(self(), ipv6), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv6), URL = "http://[" ++ ?IPV6_LOCAL_HOST ++ "]:" ++ integer_to_list(Port) ++ "/foobar.html", @@ -1576,12 +1656,7 @@ http_invalid_http(suite) -> []; http_invalid_http(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/invalid_http.html", @@ -1638,12 +1713,7 @@ transfer_encoding_otp_6807(suite) -> []; transfer_encoding_otp_6807(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/capital_transfer_encoding.html", @@ -1676,12 +1746,7 @@ empty_response_header_otp_6830(suite) -> []; empty_response_header_otp_6830(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/no_headers.html", {ok, {{_,200,_}, [], [_ | _]}} = http:request(URL), @@ -1698,12 +1763,7 @@ no_content_204_otp_6982(suite) -> []; no_content_204_otp_6982(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/no_content.html", {ok, {{_,204,_}, [], []}} = http:request(URL), @@ -1721,12 +1781,7 @@ missing_CR_otp_7304(suite) -> []; missing_CR_otp_7304(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), - - Port = receive - {port, ServerPort} -> - ServerPort - end, + {DummyServerPid, Port} = dummy_server(self(), ipv4), URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_CR.html", {ok, {{_,200,_}, _, [_ | _]}} = http:request(URL), @@ -1747,13 +1802,8 @@ otp_7883_1(suite) -> otp_7883_1(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), + {DummyServerPid, Port} = dummy_server(self(), ipv4), - Port = receive - {port, ServerPort} -> - ServerPort - end, - URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html", {error, socket_closed_remotely} = http:request(URL), DummyServerPid ! stop, @@ -1768,13 +1818,8 @@ otp_7883_2(suite) -> otp_7883_2(Config) when is_list(Config) -> ok = http:set_options([{ipfamily, inet}]), - DummyServerPid = dummy_server(self(), ipv4), + {DummyServerPid, Port} = dummy_server(self(), ipv4), - Port = receive - {port, ServerPort} -> - ServerPort - end, - URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html", Method = get, Request = {URL, []}, @@ -1810,7 +1855,7 @@ otp_8154_1(Config) when is_list(Config) -> {ok, Server, Port} = start_slow_server(RespSeqNumServer), Clients = run_clients(105, Port, ReqSeqNumServer), %% ok = wait_for_clients(Clients), - ok = wait4clients(Clients, timer:minutes(2)), + ok = wait4clients(Clients, timer:minutes(3)), Server ! shutdown, RespSeqNumServer ! shutdown, ReqSeqNumServer ! shutdown, @@ -1820,6 +1865,7 @@ start_inets() -> inets:start(), ok. + %% ----------------------------------------------------- %% A sequence number handler %% The purpose is to be able to pair requests with responses. @@ -1886,25 +1932,25 @@ run_clients(NumClients, ServerPort, SeqNumServer) -> end, lists:seq(1, NumClients)). -wait_for_clients(Clients) -> - lists:foreach( - fun({Id, Pid, MRef}) -> - io:format("waiting for client ~w termination~n", [Id]), - receive - {'DOWN', MRef, process, Pid, normal} -> - io:format("waiting for clients: " - "normal exit from ~w (~p)~n", - [Id, Pid]), - ok; - {'DOWN', MRef, process, Pid, Reason} -> - io:format("waiting for clients: " - "unexpected exit from ~w (~p):" - "~n Reason: ~p" - "~n", [Id, Pid, Reason]), - erlang:error(Reason) - end - end, - Clients). +%% wait_for_clients(Clients) -> +%% lists:foreach( +%% fun({Id, Pid, MRef}) -> +%% io:format("waiting for client ~w termination~n", [Id]), +%% receive +%% {'DOWN', MRef, process, Pid, normal} -> +%% io:format("waiting for clients: " +%% "normal exit from ~w (~p)~n", +%% [Id, Pid]), +%% ok; +%% {'DOWN', MRef, process, Pid, Reason} -> +%% io:format("waiting for clients: " +%% "unexpected exit from ~w (~p):" +%% "~n Reason: ~p" +%% "~n", [Id, Pid, Reason]), +%% erlang:error(Reason) +%% end +%% end, +%% Clients). wait4clients([], _Timeout) -> @@ -2074,6 +2120,201 @@ f(F, A) -> lists:flatten(io_lib:format(F,A)). +%%------------------------------------------------------------------------- + +otp_8106(suite) -> + [ + otp_8106_pid, + otp_8106_fun, + otp_8106_mfa + ]. + + +otp_8106_pid(doc) -> + ["OTP-8106 - deliver reply info using \"other\" pid"]; +otp_8106_pid(suite) -> + []; +otp_8106_pid(Config) when is_list(Config) -> + case ?config(local_server, Config) of + ok -> + ReceiverPid = create_receiver(pid), + Receiver = ReceiverPid, + + otp8106(ReceiverPid, Receiver, Config), + + stop_receiver(ReceiverPid), + + ok; + _ -> + {skip, "Failed to start local http-server"} + end. + + +otp_8106_fun(doc) -> + ["OTP-8106 - deliver reply info using fun"]; +otp_8106_fun(suite) -> + []; +otp_8106_fun(Config) when is_list(Config) -> + case ?config(local_server, Config) of + ok -> + ReceiverPid = create_receiver(function), + Receiver = otp_8106_deliver_fun(ReceiverPid), + + otp8106(ReceiverPid, Receiver, Config), + + stop_receiver(ReceiverPid), + + ok; + _ -> + {skip, "Failed to start local http-server"} + end. + + +otp_8106_mfa(doc) -> + ["OTP-8106 - deliver reply info using mfa callback"]; +otp_8106_mfa(suite) -> + []; +otp_8106_mfa(Config) when is_list(Config) -> + case ?config(local_server, Config) of + ok -> + ReceiverPid = create_receiver(mfa), + Receiver = {?MODULE, otp_8106_deliver, [mfa, ReceiverPid]}, + + otp8106(ReceiverPid, Receiver, Config), + + stop_receiver(ReceiverPid), + + ok; + _ -> + {skip, "Failed to start local http-server"} + end. + + + otp8106(ReceiverPid, Receiver, Config) -> + Port = ?config(local_port, Config), + URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", + Request = {URL, []}, + HTTPOptions = [], + Options = [{sync, false}, {receiver, Receiver}], + + {ok, RequestId} = + httpc:request(get, Request, HTTPOptions, Options), + + Body = + receive + {reply, ReceiverPid, {RequestId, {{_, 200, _}, _, B}}} -> + B; + {reply, ReceiverPid, Msg} -> + tsf(Msg); + {bad_reply, ReceiverPid, Msg} -> + tsf(Msg) + end, + + inets_test_lib:check_body(binary_to_list(Body)), + ok. + + +create_receiver(Type) -> + Parent = self(), + Receiver = fun() -> receiver(Type, Parent) end, + spawn_link(Receiver). + +stop_receiver(Pid) -> + Pid ! {stop, self()}. + +receiver(Type, Parent) -> + receive + {stop, Parent} -> + exit(normal); + + {http, ReplyInfo} when (Type =:= pid) -> + Parent ! {reply, self(), ReplyInfo}, + receiver(Type, Parent); + + {Type, ReplyInfo} -> + Parent ! {reply, self(), ReplyInfo}, + receiver(Type, Parent); + + Crap -> + Parent ! {reply, self(), {bad_reply, Crap}}, + receiver(Type, Parent) + end. + + +otp_8106_deliver_fun(ReceiverPid) -> + fun(ReplyInfo) -> otp_8106_deliver(ReplyInfo, function, ReceiverPid) end. + +otp_8106_deliver(ReplyInfo, Type, ReceiverPid) -> + ReceiverPid ! {Type, ReplyInfo}, + ok. + + + +%%------------------------------------------------------------------------- + +otp_8056(doc) -> + "OTP-8056"; +otp_8056(suite) -> + []; +otp_8056(Config) when is_list(Config) -> + Method = get, + Port = ?config(local_port, Config), + URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html", + Request = {URL, []}, + HTTPOptions = [], + Options1 = [{sync, true}, {stream, {self, once}}], + Options2 = [{sync, true}, {stream, self}], + {error, streaming_error} = httpc:request(Method, Request, + HTTPOptions, Options1), + tsp("request 1 failed as expected"), + {error, streaming_error} = httpc:request(Method, Request, + HTTPOptions, Options2), + tsp("request 2 failed as expected"), + ok. + + +%%------------------------------------------------------------------------- + +otp_8371(doc) -> + ["OTP-8371"]; +otp_8371(suite) -> + []; +otp_8371(Config) when is_list(Config) -> + ok = http:set_options([{ipv6, disabled}]), % also test the old option + {DummyServerPid, Port} = dummy_server(self(), ipv4), + + URL = ?URL_START ++ integer_to_list(Port) ++ + "/ensure_host_header_with_port.html", + + case http:request(get, {URL, []}, [], []) of + {ok, Result} -> + case Result of + {{_, 200, _}, _Headers, Body} -> + tsp("expected response with" + "~n Body: ~p", [Body]), + ok; + {StatusLine, Headers, Body} -> + tsp("expected response with" + "~n StatusLine: ~p" + "~n Headers: ~p" + "~n Body: ~p", [StatusLine, Headers, Body]), + tsf({unexpected_result, + [{status_line, StatusLine}, + {headers, Headers}, + {body, Body}]}); + _ -> + tsf({unexpected_result, Result}) + end; + Error -> + tsf({request_failed, Error}) + end, + + DummyServerPid ! stop, + ok = http:set_options([{ipv6, enabled}]), + ok. + + + %%-------------------------------------------------------------------- %% Internal functions %%-------------------------------------------------------------------- @@ -2171,7 +2412,7 @@ receive_streamed_body(RequestId, Body) -> receive_streamed_body(RequestId, Body, Pid) -> http:stream_next(Pid), - test_server:format("Requested next stream ~n", []), + test_server:format("~p:receive_streamed_body -> requested next stream ~n", [?MODULE]), receive {http, {RequestId, stream, BinBodyPart}} -> receive_streamed_body(RequestId, @@ -2186,7 +2427,11 @@ receive_streamed_body(RequestId, Body, Pid) -> dummy_server(Caller, IpV) -> - spawn(httpc_SUITE, dummy_server_init, [Caller, IpV]). + Pid = spawn(httpc_SUITE, dummy_server_init, [Caller, IpV]), + receive + {port, Port} -> + {Pid, Port} + end. dummy_server_init(Caller, IpV) -> {ok, ListenSocket} = @@ -2201,7 +2446,7 @@ dummy_server_init(Caller, IpV) -> {active, false}]) end, {ok, Port} = inet:port(ListenSocket), - test_server:format("Port: ~p~n", [Port]), + tsp("dummy_server_init -> Port: ~p", [Port]), Caller ! {port, Port}, dummy_server_loop({httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]}, [], ListenSocket). @@ -2209,8 +2454,7 @@ dummy_server_init(Caller, IpV) -> dummy_server_loop(MFA, Handlers, ListenSocket) -> receive stop -> - lists:foreach(fun(Handler) -> Handler ! stop end, - Handlers) + lists:foreach(fun(Handler) -> Handler ! stop end, Handlers) after 0 -> {ok, Socket} = gen_tcp:accept(ListenSocket), HandlerPid = dummy_request_handler(MFA, Socket), @@ -2231,9 +2475,13 @@ dummy_request_handler_init(MFA, Socket) -> dummy_request_handler_loop(MFA, Socket). dummy_request_handler_loop({Module, Function, Args}, Socket) -> + tsp("dummy_request_handler_loop -> entry with" + "~n Module: ~p" + "~n Function: ~p" + "~n Args: ~p", [Module, Function, Args]), receive {tcp, _, Data} -> - test_server:format("dummy_request_handler_loop -> Data ~p~n", [Data]), + tsp("dummy_request_handler_loop -> Data ~p", [Data]), case handle_request(Module, Function, [Data | Args], Socket) of stop -> gen_tcp:close(Socket); @@ -2245,48 +2493,59 @@ dummy_request_handler_loop({Module, Function, Args}, Socket) -> end. handle_request(Module, Function, Args, Socket) -> + tsp("handle_request -> entry with" + "~n Module: ~p" + "~n Function: ~p" + "~n Args: ~p", [Module, Function, Args]), case Module:Function(Args) of {ok, Result} -> - case handle_http_msg(Result, Socket) of + tsp("handle_request -> ok" + "~n Result: ~p", [Result]), + case (catch handle_http_msg(Result, Socket)) of stop -> stop; <<>> -> - {httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]}; + tsp("handle_request -> empty data"), + {httpd_request, parse, [[<<>>, ?HTTP_MAX_HEADER_SIZE]]}; Data -> handle_request(httpd_request, parse, - [Data |[?HTTP_MAX_HEADER_SIZE]], - Socket) + [Data |[?HTTP_MAX_HEADER_SIZE]], Socket) end; NewMFA -> + tsp("handle_request -> " + "~n NewMFA: ~p", [NewMFA]), NewMFA end. handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) -> - - NextRequest = case RelUri of - "/dummy_headers.html" -> - <<>>; - "/no_headers.html" -> - stop; - "/just_close.html" -> - stop; - _ -> - ContentLength = content_length(Headers), - case size(Body) - ContentLength of - 0 -> - <<>>; - _ -> - <<_BodyThisReq:ContentLength/binary, - Next/binary>> = Body, - Next - end - end, + tsp("handle_http_msg -> entry with: " + "~n RelUri: ~p" + "~n Headers: ~p" + "~n Body: ~p", [RelUri, Headers, Body]), + NextRequest = + case RelUri of + "/dummy_headers.html" -> + <<>>; + "/no_headers.html" -> + stop; + "/just_close.html" -> + stop; + _ -> + ContentLength = content_length(Headers), + case size(Body) - ContentLength of + 0 -> + <<>>; + _ -> + <<_BodyThisReq:ContentLength/binary, + Next/binary>> = Body, + Next + end + end, - test_server:format("NextRequest: ~p~n", [NextRequest]), - + tsp("handle_http_msg -> NextRequest: ~p", [NextRequest]), case (catch ets:lookup(cookie, cookies)) of [{cookies, true}]-> - test_server:format("Headers ~p~n", [Headers]), + tsp("handle_http_msg -> check cookies ~p", []), check_cookie(Headers); _ -> ok @@ -2304,6 +2563,26 @@ handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) -> "HTTP/1.0 204 No Content\r\n\r\n"; "/no_headers.html" -> "HTTP/1.0 200 OK\r\n\r\nTEST"; + "/ensure_host_header_with_port.html" -> + %% tsp("handle_http_msg -> validate host with port"), + case ensure_host_header_with_port(Headers) of + true -> + B = + "<HTML><BODY>" ++ + "host with port" ++ + "</BODY></HTML>", + Len = integer_to_list(length(B)), + "HTTP/1.1 200 ok\r\n" ++ + "Content-Length:" ++ Len ++ "\r\n\r\n" ++ B; + false -> + B = + "<HTML><BODY>" ++ + "Internal Server Error - host without port" ++ + "</BODY></HTML>", + Len = integer_to_list(length(B)), + "HTTP/1.1 500 Internal Server Error\r\n" ++ + "Content-Length:" ++ Len ++ "\r\n\r\n" ++ B + end; "/300.html" -> NewUri = ?URL_START ++ integer_to_list(?IP_PORT) ++ "/dummy.html", @@ -2337,7 +2616,7 @@ handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) -> "/500.html" -> "HTTP/1.1 500 Internal Server Error\r\n" ++ "Content-Length:47\r\n\r\n" ++ - "<HTML><BODY>Internal Server Error</BODY<</HTML>"; + "<HTML><BODY>Internal Server Error</BODY></HTML>"; "/503.html" -> case ets:lookup(unavailable, 503) of [{503, unavailable}] -> @@ -2452,16 +2731,35 @@ handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) -> DefaultResponse end, - test_server:format("Msg: ~p~n", [Msg]), + tsp("handle_http_msg -> Msg: ~p", [Msg]), case Msg of + ok -> + %% Previously, this resulted in an {error, einval}. Now what? + ok; close -> %% Nothing to send, just close gen_tcp:close(Socket); - _ -> + _ when is_list(Msg) orelse is_binary(Msg) -> gen_tcp:send(Socket, Msg) end, + tsp("handle_http_msg -> done"), NextRequest. +ensure_host_header_with_port([]) -> + false; +ensure_host_header_with_port(["host: " ++ Host| _]) -> + case string:tokens(Host, [$:]) of + [ActualHost, Port] -> + tsp("ensure_host_header_with_port -> " + "~n ActualHost: ~p" + "~n Port: ~p", [ActualHost, Port]), + true; + _ -> + false + end; +ensure_host_header_with_port([_|T]) -> + ensure_host_header_with_port(T). + auth_header([]) -> auth_header_not_found; auth_header(["authorization:" ++ Value | _]) -> @@ -2507,9 +2805,10 @@ provocate_not_modified_bug(Url) -> []) of {ok, {{_, 304, _}, _, _}} -> %% The expected reply page_unchanged; - {ok, {{_, 200, _}, _, _}} -> %% If the page has changed since the - %% last request we retry to - %% trigger the bug + {ok, {{_, 200, _}, _, _}} -> + %% If the page has changed since the + %% last request we retry to + %% trigger the bug provocate_not_modified_bug(Url); {error, timeout} -> %% Not what we expected. Tcpdump can be used to @@ -2528,5 +2827,20 @@ pick_header(Headers, Name) -> end. -%% p(F, A) -> -%% io:format("~p ~w:" ++ F ++ "~n", [self(), ?MODULE | A]). +not_implemented_yet() -> + exit(not_implemented_yet). + + +p(F) -> + p(F, []). + +p(F, A) -> + io:format("~p ~w:" ++ F ++ "~n", [self(), ?MODULE | A]). + +tsp(F) -> + tsp(F, []). +tsp(F, A) -> + test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]). + +tsf(Reason) -> + test_server:fail(Reason). diff --git a/lib/inets/test/httpc_cookie_SUITE.erl b/lib/inets/test/httpc_cookie_SUITE.erl index 7d91631934..ad5df656c6 100644 --- a/lib/inets/test/httpc_cookie_SUITE.erl +++ b/lib/inets/test/httpc_cookie_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2005-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -31,7 +31,7 @@ domain_cookie/1, secure_cookie/1, update_cookie/1, update_cookie_session/1, cookie_attributes/1]). --define(URL, "http://myhost.cookie.test.org"). +-define(URL, "http://myhost.cookie.test.org"). -define(URL_DOMAIN, "http://myhost2.cookie.test.org"). -define(URL_SECURE, "https://myhost.cookie.test.org"). @@ -50,15 +50,21 @@ %% variable, but should NOT alter/remove any existing entries. %% Description: Initiation before each test case %%-------------------------------------------------------------------- -init_per_testcase(session_cookies_only, Config) -> +init_per_testcase(session_cookies_only = Case, Config0) -> + tsp("init_per_testcase(~p) -> entry with" + "~n Config0: ~p", [Case, Config0]), + Config = init_workdir(Case, Config0), application:start(inets), http:set_options([{cookies, verify}]), watch_dog(Config); -init_per_testcase(_, Config) -> - PrivDir = ?config(priv_dir, Config), +init_per_testcase(Case, Config0) -> + tsp("init_per_testcase(~p) -> entry with" + "~n Config0: ~p", [Case, Config0]), + Config = init_workdir(Case, Config0), + CaseDir = ?config(case_top_dir, Config), application:load(inets), - application:set_env(inets, services, [{httpc,{default, PrivDir}}]), + application:set_env(inets, services, [{httpc, {default, CaseDir}}]), application:start(inets), http:set_options([{cookies, verify}]), watch_dog(Config). @@ -68,6 +74,24 @@ watch_dog(Config) -> NewConfig = lists:keydelete(watchdog, 1, Config), [{watchdog, Dog} | NewConfig]. +init_workdir(Case, Config) -> + PrivDir = ?config(priv_dir, Config), + SuiteTopDir = filename:join(PrivDir, ?MODULE), + case file:make_dir(SuiteTopDir) of + ok -> + ok; + {error, eexist} -> + ok; + Error -> + tsf({failed_creating_subsuite_top_dir, Error}) + end, + + CaseTopDir = filename:join(SuiteTopDir, Case), + ?line ok = file:make_dir(CaseTopDir), + [{suite_top_dir, SuiteTopDir}, + {case_top_dir, CaseTopDir} | Config]. + + %%-------------------------------------------------------------------- %% Function: end_per_testcase(TestCase, Config) -> _ %% Case - atom() @@ -76,10 +100,10 @@ watch_dog(Config) -> %% A list of key/value pairs, holding the test case configuration. %% Description: Cleanup after each test case %%-------------------------------------------------------------------- -end_per_testcase(_TestCase, Config) -> +end_per_testcase(Case, Config) -> + tsp("end_per_testcase(~p) -> entry with" + "~n Config: ~p", [Case, Config]), application:stop(inets), - File = filename:join(?config(priv_dir, Config), "http_default_cookie_db"), - file:delete(File), Dog = ?config(watchdog, Config), test_server:timetrap_cancel(Dog), ok. @@ -96,9 +120,18 @@ all(doc) -> ["Describe the main purpose of this suite"]; all(suite) -> - [session_cookies_only, netscape_cookies, cookie_cancel, - cookie_expires, persistent_cookie, domain_cookie, secure_cookie, - update_cookie, update_cookie_session, cookie_attributes]. + [ + session_cookies_only, + netscape_cookies, + cookie_cancel, + cookie_expires, + persistent_cookie, + domain_cookie, + secure_cookie, + update_cookie, + update_cookie_session, + cookie_attributes + ]. %% Test cases starts here. %%-------------------------------------------------------------------- @@ -108,6 +141,8 @@ session_cookies_only(doc) -> session_cookies_only(suite) -> []; session_cookies_only(Config) when is_list(Config) -> + tsp("session_cookies_only -> Cookies 1: ~p", [httpc:which_cookies()]), + SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;" ";max-age=60000"}], http:verify_cookies(SetCookieHeaders, ?URL), @@ -115,8 +150,9 @@ session_cookies_only(Config) when is_list(Config) -> = http:cookie_header(?URL), application:stop(inets), application:start(inets), - {"cookie",""} - = http:cookie_header(?URL), + {"cookie",""} = http:cookie_header(?URL), + + tsp("session_cookies_only -> Cookies 2: ~p", [httpc:which_cookies()]), ok. netscape_cookies(doc) -> @@ -124,12 +160,16 @@ netscape_cookies(doc) -> netscape_cookies(suite) -> []; netscape_cookies(Config) when is_list(Config) -> + tsp("netscape_cookies -> Cookies 1: ~p", [httpc:which_cookies()]), + Expires = future_netscape_date(), SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/; " "expires=" ++ Expires}], http:verify_cookies(SetCookieHeaders, ?URL), - {"cookie","$Version=0; test_cookie=true; $Path=/"} - = http:cookie_header(?URL), + {"cookie","$Version=0; test_cookie=true; $Path=/"} = + http:cookie_header(?URL), + + tsp("netscape_cookies -> Cookies 2: ~p", [httpc:which_cookies()]), ok. cookie_cancel(doc) -> @@ -138,6 +178,8 @@ cookie_cancel(doc) -> cookie_cancel(suite) -> []; cookie_cancel(Config) when is_list(Config) -> + tsp("cookie_cancel -> Cookies 1: ~p", [httpc:which_cookies()]), + SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;" "max-age=60000"}], http:verify_cookies(SetCookieHeaders, ?URL), @@ -147,6 +189,8 @@ cookie_cancel(Config) when is_list(Config) -> "max-age=0"}], http:verify_cookies(NewSetCookieHeaders, ?URL), {"cookie", ""} = http:cookie_header(?URL), + + tsp("cookie_cancel -> Cookies 2: ~p", [httpc:which_cookies()]), ok. cookie_expires(doc) -> @@ -154,6 +198,8 @@ cookie_expires(doc) -> cookie_expires(suite) -> []; cookie_expires(Config) when is_list(Config) -> + tsp("cookie_expires -> Cookies 1: ~p", [httpc:which_cookies()]), + SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;" "max-age=5"}], http:verify_cookies(SetCookieHeaders, ?URL), @@ -161,56 +207,95 @@ cookie_expires(Config) when is_list(Config) -> = http:cookie_header(?URL), test_server:sleep(10000), {"cookie", ""} = http:cookie_header(?URL), + + tsp("cookie_expires -> Cookies 2: ~p", [httpc:which_cookies()]), ok. -persistent_cookie(doc)-> +persistent_cookie(doc) -> ["Test domian cookie attribute"]; persistent_cookie(suite) -> []; persistent_cookie(Config) when is_list(Config)-> + tsp("persistent_cookie -> Cookies 1: ~p", [httpc:which_cookies()]), + SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;" "max-age=60000"}], http:verify_cookies(SetCookieHeaders, ?URL), - {"cookie","$Version=0; test_cookie=true; $Path=/"} - = http:cookie_header(?URL), - PrivDir = ?config(priv_dir, Config), + {"cookie","$Version=0; test_cookie=true; $Path=/"} = + http:cookie_header(?URL), + CaseDir = ?config(case_top_dir, Config), application:stop(inets), application:load(inets), - application:set_env(inets, services, [{httpc,{default, PrivDir}}]), + application:set_env(inets, services, [{httpc, {default, CaseDir}}]), application:start(inets), - http:set_options([{cookies, enabled}]), - {"cookie","$Version=0; test_cookie=true; $Path=/"} - = http:cookie_header(?URL), + http:set_options([{cookies, enabled}]), + {"cookie","$Version=0; test_cookie=true; $Path=/"} = http:cookie_header(?URL), + + tsp("persistent_cookie -> Cookies 2: ~p", [httpc:which_cookies()]), ok. -domain_cookie(doc)-> + +domain_cookie(doc) -> ["Test the domian cookie attribute"]; domain_cookie(suite) -> []; -domain_cookie(Config) when is_list(Config)-> +domain_cookie(Config) when is_list(Config) -> + tsp("domain_cookie -> Cookies 1: ~p", [httpc:which_cookies()]), + SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;" "domain=.cookie.test.org"}], http:verify_cookies(SetCookieHeaders, ?URL), {"cookie","$Version=0; test_cookie=true; $Path=/; " - "$Domain=.cookie.test.org"} - = http:cookie_header(?URL_DOMAIN), + "$Domain=.cookie.test.org"} = + http:cookie_header(?URL_DOMAIN), + + tsp("domain_cookie -> Cookies 2: ~p", [httpc:which_cookies()]), ok. -secure_cookie(doc)-> + +secure_cookie(doc) -> ["Test the secure cookie attribute"]; secure_cookie(suite) -> []; -secure_cookie(Config) when is_list(Config)-> +secure_cookie(Config) when is_list(Config) -> + tsp("secure_cookie -> entry with" + "~n Config: ~p", [Config]), + + inets:enable_trace(max, io, httpc), + + %% httpc:reset_cookies(), + + tsp("secure_cookie -> Cookies 1: ~p", [httpc:which_cookies()]), + SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/; secure"}], - http:verify_cookies(SetCookieHeaders, ?URL), - {"cookie","$Version=0; test_cookie=true; $Path=/"} - = http:cookie_header(?URL_SECURE), - {"cookie",""} - = http:cookie_header(?URL), + tsp("secure_cookie -> verify cookies (1)"), + ok = http:verify_cookies(SetCookieHeaders, ?URL), + + tsp("secure_cookie -> Cookies 2: ~p", [httpc:which_cookies()]), + + tsp("secure_cookie -> check cookie (secure)"), + check_cookie("$Version=0; test_cookie=true; $Path=/", ?URL_SECURE), + + tsp("secure_cookie -> check cookie (plain)"), + check_cookie("", ?URL), + + tsp("secure_cookie -> verify cookies (2)"), SetCookieHeaders1 = [{"set-cookie", "test1_cookie=true; path=/; secure"}], - http:verify_cookies(SetCookieHeaders1, ?URL), - {"cookie","$Version=0; test_cookie=true; $Path=/; " - "test1_cookie=true; $Path=/"} = http:cookie_header(?URL_SECURE), + ok = http:verify_cookies(SetCookieHeaders1, ?URL), + + tsp("secure_cookie -> Cookies 3: ~p", [httpc:which_cookies()]), + + tsp("secure_cookie -> cookie header (3)"), + check_cookie("$Version=0; test_cookie=true; $Path=/; " + "test1_cookie=true; $Path=/", + ?URL_SECURE), +%% {"cookie","$Version=0; test_cookie=true; $Path=/; " +%% "test1_cookie=true; $Path=/"} = http:cookie_header(?URL_SECURE), + + tsp("secure_cookie -> Cookies 4: ~p", [httpc:which_cookies()]), + + inets:disable_trace(), + tsp("secure_cookie -> done"), ok. update_cookie(doc)-> @@ -257,13 +342,31 @@ cookie_attributes(Config) when is_list(Config) -> "foo=bar;" %% Nonsense should be ignored "max-age=60000"}], http:verify_cookies(SetCookieHeaders, ?URL), - {"cookie","$Version=1; test_cookie=true"} - = http:cookie_header(?URL), + {"cookie","$Version=1; test_cookie=true"} = http:cookie_header(?URL), ok. + %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- + +check_cookie(Expect, URL) -> + case http:cookie_header(URL) of + {"cookie", Expect} -> + ok; + {"cookie", Unexpected} -> + case lists:prefix(Expect, Unexpected) of + true -> + Extra = Unexpected -- Expect, + tsf({extra_cookie_info, Extra}); + false -> + tsf({unknown_cookie, Expect, Unexpected}) + end; + Bad -> + tsf({bad_cookies, Bad}) + end. + + future_netscape_date() -> [Day, DD, Mon, YYYY] = netscape_date(date()), lists:flatten(io_lib:format("~s, ~s ~s ~s 12:30:00 GMT", @@ -336,3 +439,13 @@ month_str(9) ->"Sep"; month_str(10) ->"Oct"; month_str(11) ->"Nov"; month_str(12) ->"Dec". + + +tsp(F) -> + tsp(F, []). +tsp(F, A) -> + test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]). + +tsf(Reason) -> + test_server:fail(Reason). + diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl index b7e97aa3ec..7403d4a643 100644 --- a/lib/inets/test/httpd_SUITE.erl +++ b/lib/inets/test/httpd_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2005-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -444,35 +444,35 @@ ip(doc) -> ["HTTP tests using TCP/IP"]; ip(suite) -> [ -%% ip_mod_alias, -%% ip_mod_actions, -%% ip_mod_security, -%% ip_mod_auth, -%% ip_mod_auth_api, -%% ip_mod_auth_mnesia_api, -%% ip_mod_htaccess, -%% ip_mod_cgi, -%% ip_mod_esi, -%% ip_mod_get, -%% ip_mod_head, -%% ip_mod_all, -%% ip_load_light, -%% ip_load_medium, -%% ip_load_heavy, -%% ip_dos_hostname, -%% ip_time_test, -%% ip_block_disturbing_idle, -%% ip_block_non_disturbing_idle, -%% ip_block_503, -%% ip_block_disturbing_active, -%% ip_block_non_disturbing_active, -%% ip_block_disturbing_active_timeout_not_released, -%% ip_block_disturbing_active_timeout_released, -%% ip_block_non_disturbing_active_timeout_not_released, -%% ip_block_non_disturbing_active_timeout_released, -%% ip_block_disturbing_blocker_dies, -%% ip_block_non_disturbing_blocker_dies, -%% ip_restart_no_block, + ip_mod_alias, + ip_mod_actions, + ip_mod_security, + ip_mod_auth, + ip_mod_auth_api, + ip_mod_auth_mnesia_api, + ip_mod_htaccess, + ip_mod_cgi, + ip_mod_esi, + ip_mod_get, + ip_mod_head, + ip_mod_all, + ip_load_light, + ip_load_medium, + ip_load_heavy, + ip_dos_hostname, + ip_time_test, + ip_block_disturbing_idle, + ip_block_non_disturbing_idle, + ip_block_503, + ip_block_disturbing_active, + ip_block_non_disturbing_active, + ip_block_disturbing_active_timeout_not_released, + ip_block_disturbing_active_timeout_released, + ip_block_non_disturbing_active_timeout_not_released, + ip_block_non_disturbing_active_timeout_released, + ip_block_disturbing_blocker_dies, + ip_block_non_disturbing_blocker_dies, + ip_restart_no_block, ip_restart_disturbing_block, ip_restart_non_disturbing_block ]. @@ -482,37 +482,37 @@ ssl(doc) -> ["HTTP test using SSL"]; ssl(suite) -> [ -%% ssl_mod_alias, -%% ssl_mod_actions, -%% ssl_mod_security, -%% ssl_mod_auth, -%% ssl_mod_auth_api, -%% ssl_mod_auth_mnesia_api, -%% ssl_mod_htaccess, -%% ssl_mod_cgi, -%% ssl_mod_esi, -%% ssl_mod_get, -%% ssl_mod_head, -%% ssl_mod_all, -%% ssl_load_light, -%% ssl_load_medium, -%% ssl_load_heavy, -%% ssl_dos_hostname, -%% ssl_time_test, -%% ssl_restart_no_block, + ssl_mod_alias, + ssl_mod_actions, + ssl_mod_security, + ssl_mod_auth, + ssl_mod_auth_api, + ssl_mod_auth_mnesia_api, + ssl_mod_htaccess, + ssl_mod_cgi, + ssl_mod_esi, + ssl_mod_get, + ssl_mod_head, + ssl_mod_all, + ssl_load_light, + ssl_load_medium, + ssl_load_heavy, + ssl_dos_hostname, + ssl_time_test, + ssl_restart_no_block, ssl_restart_disturbing_block, - ssl_restart_non_disturbing_block%% , -%% ssl_block_disturbing_idle, -%% ssl_block_non_disturbing_idle, -%% ssl_block_503, -%% ssl_block_disturbing_active, -%% ssl_block_non_disturbing_active, -%% ssl_block_disturbing_active_timeout_not_released, -%% ssl_block_disturbing_active_timeout_released, -%% ssl_block_non_disturbing_active_timeout_not_released, -%% ssl_block_non_disturbing_active_timeout_released, -%% ssl_block_disturbing_blocker_dies, -%% ssl_block_non_disturbing_blocker_dies + ssl_restart_non_disturbing_block, + ssl_block_disturbing_idle, + ssl_block_non_disturbing_idle, + ssl_block_503, + ssl_block_disturbing_active, + ssl_block_non_disturbing_active, + ssl_block_disturbing_active_timeout_not_released, + ssl_block_disturbing_active_timeout_released, + ssl_block_non_disturbing_active_timeout_not_released, + ssl_block_non_disturbing_active_timeout_released, + ssl_block_disturbing_blocker_dies, + ssl_block_non_disturbing_blocker_dies ]. %%------------------------------------------------------------------------- diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl index c249bdf81b..56983caace 100644 --- a/lib/inets/test/inets_SUITE.erl +++ b/lib/inets/test/inets_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -21,12 +21,12 @@ -include("test_server.hrl"). -include("test_server_line.hrl"). +-include("inets_test_lib.hrl"). %% Note: This directive should only be used in test suites. -compile(export_all). -define(NUM_DEFAULT_SERVICES, 1). --define(FTP_HOST,"tuor"). all(doc) -> ["Test suites for the inets application."]; @@ -35,14 +35,20 @@ all(suite) -> [ app_test, appup_test, + services_test, + httpd_reload + ]. + +services_test(suite) -> + [ start_inets, start_httpc, start_httpd, start_ftpc, - start_tftpd, - httpd_reload + start_tftpd ]. + %%-------------------------------------------------------------------- %% Function: init_per_suite(Config) -> Config %% Config - [tuple()] @@ -139,40 +145,88 @@ start_httpc(suite) -> []; start_httpc(Config) when is_list(Config) -> process_flag(trap_exit, true), + tsp("start_httpc -> entry with" + "~n Config: ~p", [Config]), + PrivDir = ?config(priv_dir, Config), + + tsp("start_httpc -> start (empty) inets"), ok = inets:start(), + + tsp("start_httpc -> start httpc (as inets service) with profile foo"), {ok, Pid0} = inets:start(httpc, [{profile, foo}]), + + tsp("start_httpc -> check running services"), Pids0 = [ServicePid || {_, ServicePid} <- inets:services()], true = lists:member(Pid0, Pids0), [_|_] = inets:services_info(), + + tsp("start_httpc -> stop httpc"), inets:stop(httpc, Pid0), + + tsp("start_httpc -> sleep some"), test_server:sleep(100), + + tsp("start_httpc -> check running services"), Pids1 = [ServicePid || {_, ServicePid} <- inets:services()], false = lists:member(Pid0, Pids1), + + tsp("start_httpc -> start httpc (stand-alone) with profile bar"), {ok, Pid1} = inets:start(httpc, [{profile, bar}], stand_alone), + + tsp("start_httpc -> check running services"), Pids2 = [ServicePid || {_, ServicePid} <- inets:services()], false = lists:member(Pid1, Pids2), + + tsp("start_httpc -> stop httpc"), ok = inets:stop(stand_alone, Pid1), receive {'EXIT', Pid1, shutdown} -> ok after 100 -> - test_server:fail(stand_alone_not_shutdown) + tsf(stand_alone_not_shutdown) end, + + tsp("start_httpc -> stop inets"), ok = inets:stop(), + + tsp("start_httpc -> unload inets"), application:load(inets), + + tsp("start_httpc -> set inets environment (httpc profile foo)"), application:set_env(inets, services, [{httpc,[{profile, foo}, {data_dir, PrivDir}]}]), + + tsp("start_httpc -> start inets"), ok = inets:start(), + + tsp("start_httpc -> check running services"), (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()), + + tsp("start_httpc -> unset inets env"), application:unset_env(inets, services), + + tsp("start_httpc -> stop inets"), ok = inets:stop(), + + tsp("start_httpc -> start (empty) inets"), ok = inets:start(), + + tsp("start_httpc -> start inets httpc service with profile foo"), {ok, Pid3} = inets:start(httpc, [{profile, foo}]), + + tsp("start_httpc -> stop inets service httpc with profile foo"), ok = inets:stop(httpc, foo), + + tsp("start_httpc -> check running services"), Pids3 = [ServicePid || {_, ServicePid} <- inets:services()], false = lists:member(Pid3, Pids3), - ok = inets:stop(). + + tsp("start_httpc -> stop inets"), + ok = inets:stop(), + + tsp("start_httpc -> done"), + ok. %%------------------------------------------------------------------------- @@ -191,11 +245,13 @@ start_httpd(Config) when is_list(Config) -> i("start_httpd -> start inets"), ok = inets:start(), + i("start_httpd -> start httpd service"), {ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]), Pids0 = [ServicePid || {_, ServicePid} <- inets:services()], true = lists:member(Pid0, Pids0), [_|_] = inets:services_info(), + i("start_httpd -> stop httpd service"), inets:stop(httpd, Pid0), test_server:sleep(500), @@ -310,30 +366,49 @@ start_ftpc(suite) -> []; start_ftpc(Config) when is_list(Config) -> process_flag(trap_exit, true), + inets:disable_trace(), + inets:enable_trace(max, io, ftpc), ok = inets:start(), - case inets:start(ftpc, [{host, ?FTP_HOST}]) of - {ok, Pid0} -> - Pids0 = [ServicePid || {_, ServicePid} <- inets:services()], - true = lists:member(Pid0, Pids0), - [_|_] = inets:services_info(), - inets:stop(ftpc, Pid0), - test_server:sleep(100), - Pids1 = [ServicePid || {_, ServicePid} <- inets:services()], - false = lists:member(Pid0, Pids1), - {ok, Pid1} = inets:start(ftpc, [{host, ?FTP_HOST}], 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 -> - test_server:fail(stand_alone_not_shutdown) - end, - ok = inets:stop(); - _ -> - {skip, "Unable to reach test FTP server " ++ ?FTP_HOST} + try + begin + {_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config), + case inets:start(ftpc, [{host, FtpdHost}]) of + {ok, Pid0} -> + Pids0 = [ServicePid || {_, ServicePid} <- + inets:services()], + true = lists:member(Pid0, Pids0), + [_|_] = inets:services_info(), + inets:stop(ftpc, Pid0), + test_server: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 -> + tsf(stand_alone_not_shutdown) + end, + ok = inets:stop(), + inets:disable_trace(), + ok; + _ -> + inets:disable_trace(), + {skip, "Unable to reach selected FTP server " ++ FtpdHost} + end + end + catch + throw:{error, not_found} -> + inets:disable_trace(), + {skip, "No available FTP servers"} end. + %%------------------------------------------------------------------------- @@ -478,15 +553,24 @@ httpd_reload(Config) when is_list(Config) -> ok. +tsf(Reason) -> + test_server:fail(Reason). + +tsp(F) -> + tsp(F, []). +tsp(F, A) -> + Timestamp = formated_timestamp(), + test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n", [Timestamp, self(), ?MODULE | A]). + i(F) -> i(F, []). i(F, A) -> Timestamp = formated_timestamp(), - io:format("*** ~s ~w:~w:" ++ F ++ "~n", [Timestamp, ?MODULE, ?LINE | A]). + io:format("*** ~s ~w:" ++ F ++ "~n", [Timestamp, ?MODULE | A]). formated_timestamp() -> - format_timestamp( now() ). + format_timestamp( os:timestamp() ). format_timestamp({_N1, _N2, N3} = Now) -> {Date, Time} = calendar:now_to_datetime(Now), @@ -496,3 +580,4 @@ format_timestamp({_N1, _N2, N3} = Now) -> io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w", [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), lists:flatten(FormatDate). + diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl index 755ab594ed..ba41e0960c 100644 --- a/lib/inets/test/inets_sup_SUITE.erl +++ b/lib/inets/test/inets_sup_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -26,8 +26,6 @@ %% Note: This directive should only be used in test suites. -compile(export_all). --define(FTP_HOST, "tuor"). - all(doc) -> ["Test that the inets supervisorstructur is the expected one."]; all(suite) -> @@ -223,20 +221,34 @@ ftpc_worker(doc) -> ftpc_worker(suite) -> []; ftpc_worker(Config) when is_list(Config) -> + inets:disable_trace(), + inets:enable_trace(max, io, ftpc), [] = supervisor:which_children(ftp_sup), - case inets:start(ftpc, [{host, ?FTP_HOST}]) of - {ok, Pid} -> - case supervisor:which_children(ftp_sup) of - [{_,_, worker, [ftp]}] -> - inets:stop(ftpc, Pid), - test_server:sleep(5000), - [] = supervisor:which_children(ftp_sup), - ok; - Children -> - exit({unexpected_children, Children}) - end; - _ -> - {skip, "Unable to reach test FTP server"} + try + begin + {_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config), + case inets:start(ftpc, [{host, FtpdHost}]) of + {ok, Pid} -> + case supervisor:which_children(ftp_sup) of + [{_,_, worker, [ftp]}] -> + inets:stop(ftpc, Pid), + test_server:sleep(5000), + [] = supervisor:which_children(ftp_sup), + inets:disable_trace(), + ok; + Children -> + inets:disable_trace(), + exit({unexpected_children, Children}) + end; + _ -> + inets:disable_trace(), + {skip, "Unable to reach test FTP server"} + end + end + catch + throw:{error, not_found} -> + inets:disable_trace(), + {skip, "No available FTP servers"} end. @@ -252,7 +264,7 @@ tftpd_worker(Config) when is_list(Config) -> {ok, Pid0} = inets:start(tftpd, [{host, "localhost"}, {port, inet_port()}]), {ok, _Pid1} = inets:start(tftpd, [{host, "localhost"}, - {port, inet_port()}], stand_alone), + {port, inet_port()}], stand_alone), [{_,Pid0, worker, _}] = supervisor:which_children(tftp_sup), inets:stop(tftpd, Pid0), @@ -356,25 +368,33 @@ httpc_subtree(doc) -> httpc_subtree(suite) -> []; httpc_subtree(Config) when is_list(Config) -> - io:format("httpd_subtree -> entry with" - "~n Config: ~p" - "~n", [Config]), + tsp("httpc_subtree -> entry with" + "~n Config: ~p", [Config]), + tsp("httpc_subtree -> start inets service httpc with profile foo"), {ok, Foo} = inets:start(httpc, [{profile, foo}]), - io:format("httpc_subtree -> foo started~n", []), + + tsp("httpc_subtree -> " + "start stand-alone inets service httpc with profile bar"), {ok, Bar} = inets:start(httpc, [{profile, bar}], stand_alone), - io:format("httpc_subtree -> bar started~n", []), - + + tsp("httpc_subtree -> retreive list of httpc instances"), HttpcChildren = supervisor:which_children(httpc_profile_sup), - io:format("httpc_subtree -> HttpcChildren: ~p~n", [HttpcChildren]), + tsp("httpc_subtree -> HttpcChildren: ~n~p", [HttpcChildren]), - {value, {httpc_manager, _, worker,[httpc_manager]}} = + tsp("httpc_subtree -> verify httpc stand-alone instances"), + {value, {httpc_manager, _, worker, [httpc_manager]}} = lists:keysearch(httpc_manager, 1, HttpcChildren), - {value,{{http,foo}, Pid, worker,[httpc_manager]}} = - lists:keysearch({http, foo}, 1, HttpcChildren), - false = lists:keysearch({http, bar}, 1, HttpcChildren), + + tsp("httpc_subtree -> verify httpc (named) instances"), + {value,{{httpc,foo}, Pid, worker, [httpc_manager]}} = + lists:keysearch({httpc, foo}, 1, HttpcChildren), + false = lists:keysearch({httpc, bar}, 1, HttpcChildren), + tsp("httpc_subtree -> stop inets"), inets:stop(httpc, Pid), + + tsp("httpc_subtree -> done"), ok. inet_port() -> @@ -384,3 +404,11 @@ inet_port() -> Port. +tsp(F) -> + tsp(F, []). +tsp(F, A) -> + test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]). + +tsf(Reason) -> + test_server:fail(Reason). + |