%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1997-2018. 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(inets_SUITE). -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(NUM_DEFAULT_SERVICES, 1). suite() -> [{ct_hooks,[ts_install_cth]}, {timetrap,{seconds,5}} ]. all() -> [{group, app_test}, {group, services_test}, httpd_reload]. groups() -> [{services_test, [], [start_inets, start_httpc, start_httpd ]}, {app_test, [], [app, appup]}]. init_per_group(_GroupName, Config) -> Config. end_per_group(_GroupName, Config) -> Config. %%-------------------------------------------------------------------- %% Function: init_per_suite(Config) -> Config %% Config - [tuple()] %% A list of key/value pairs, holding the test case configuration. %% Description: Initiation before the whole suite %% %% 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_suite(Config) -> Config. %%-------------------------------------------------------------------- %% Function: end_per_suite(Config) -> _ %% Config - [tuple()] %% A list of key/value pairs, holding the test case configuration. %% Description: Cleanup after the whole suite %%-------------------------------------------------------------------- end_per_suite(_Config) -> ok. %%-------------------------------------------------------------------- %% Function: init_per_testcase(Case, Config) -> Config % Case - atom() %% Name of the test case that is about to be run. %% Config - [tuple()] %% A list of key/value pairs, holding the test case configuration. %% %% Description: Initiation before each test case %% %% 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(httpd_reload, Config) -> inets:stop(), ct:timetrap({seconds, 40}), Config; init_per_testcase(_Case, Config) -> inets:stop(), Config. %%-------------------------------------------------------------------- %% Function: end_per_testcase(Case, Config) -> _ %% Case - atom() %% Name of the test case that is about to be run. %% Config - [tuple()] %% A list of key/value pairs, holding the test case configuration. %% Description: Cleanup after each test case %%-------------------------------------------------------------------- end_per_testcase(_, Config) -> Config. %%------------------------------------------------------------------------- %% Test cases starts here. %%------------------------------------------------------------------------- app() -> [{doc, "Test that the inets app file is ok"}]. app(Config) when is_list(Config) -> ok = ?t:app_test(inets). %%-------------------------------------------------------------------- appup() -> [{doc, "Test that the inets appup file is ok"}]. appup(Config) when is_list(Config) -> ok = ?t:appup_test(inets). start_inets() -> [{doc, "Test inets API functions"}]. start_inets(Config) when is_list(Config) -> [_|_] = inets:service_names(), {error,inets_not_started} = inets:services(), {error,inets_not_started} = inets:services_info(), ok = inets:start(), %% httpc default profile always started [_|_] = inets:services(), [_|_] = inets:services_info(), {error,{already_started,inets}} = inets:start(), ok = inets:stop(), {error,{not_started,inets}} = inets:stop(), ok = inets:start(transient), ok = inets:stop(), ok = inets:start(permanent), ok = inets:stop(). %%------------------------------------------------------------------------- start_httpc() -> [{doc, "Start/stop of httpc service"}]. start_httpc(Config) when is_list(Config) -> process_flag(trap_exit, true), PrivDir = proplists:get_value(priv_dir, Config), ok = inets:start(), {ok, Pid0} = inets:start(httpc, [{profile, foo}]), Pids0 = [ServicePid || {_, ServicePid} <- inets:services()], true = lists:member(Pid0, Pids0), [_|_] = inets:services_info(), inets:stop(httpc, Pid0), ct:sleep(100), Pids1 = [ServicePid || {_, ServicePid} <- inets:services()], false = lists:member(Pid0, Pids1), {ok, Pid1} = inets:start(httpc, [{profile, bar}], 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, [{httpc,[{profile, foo}, {data_dir, PrivDir}]}]), ok = inets:start(), (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()), application:unset_env(inets, services), ok = inets:stop(), ok = inets:start(), {ok, Pid3} = inets:start(httpc, [{profile, foo}]), ok = inets:stop(httpc, foo), Pids3 = [ServicePid || {_, ServicePid} <- inets:services()], false = lists:member(Pid3, Pids3), ok = inets:stop(). %%------------------------------------------------------------------------- start_httpd() -> [{doc, "Start/stop of httpd service"}]. start_httpd(Config) when is_list(Config) -> process_flag(trap_exit, true), PrivDir = proplists:get_value(priv_dir, Config), HttpdConf = [{server_name, "httpd_test"}, {server_root, PrivDir}, {document_root, PrivDir}, {bind_address, any}], ok = inets:start(), {ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]), Pids0 = [ServicePid || {_, ServicePid} <- inets:services()], true = lists:member(Pid0, Pids0), [_|_] = inets:services_info(), inets:stop(httpd, Pid0), Pids1 = [ServicePid || {_, ServicePid} <- inets:services()], false = lists:member(Pid0, Pids1), {ok, Pid0b} = inets:start(httpd, [{port, 0}, {ipfamily, inet6fb4} | HttpdConf]), Pids0b = [ServicePid || {_, ServicePid} <- inets:services()], true = lists:member(Pid0b, Pids0b), [_|_] = inets:services_info(), inets:stop(httpd, Pid0b), Pids1 = [ServicePid || {_, ServicePid} <- inets:services()], false = lists:member(Pid0b, Pids1), {ok, Pid1} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf], 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(), File0 = filename:join(PrivDir, "httpd.conf"), {ok, Fd0} = file:open(File0, [write]), Str = io_lib:format("~p.~n", [[{port, 0}, {ipfamily, inet} | HttpdConf]]), ok = file:write(Fd0, Str), file:close(Fd0), application:load(inets), application:set_env(inets, services, [{httpd, [{proplist_file, File0}]}]), ok = inets:start(), (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()), application:unset_env(inets, services), ok = inets:stop(), File1 = filename:join(PrivDir, "httpd_apache.conf"), {ok, Fd1} = file:open(File1, [write]), file:write(Fd1, "ServerName httpd_test\r\n"), file:write(Fd1, "ServerRoot " ++ PrivDir ++ "\r\n"), file:write(Fd1, "DocumentRoot " ++ PrivDir ++" \r\n"), file:write(Fd1, "BindAddress *|inet\r\n"), file:write(Fd1, "Port 0\r\n"), file:close(Fd1), application:load(inets), application:set_env(inets, services, [{httpd, [{file, File1}]}]), ok = inets:start(), (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()), application:unset_env(inets, services), ok = inets:stop(), %% OLD format application:load(inets), application:set_env(inets, services, [{httpd, File1}]), ok = inets:start(), (?NUM_DEFAULT_SERVICES + 1) = length(inets:services()), application:unset_env(inets, services), ok = inets:stop(), ok = inets:start(), {error, {missing_property, server_name}} = inets:start(httpd, [{port, 0}, {server_root, PrivDir}, {document_root, PrivDir}, {bind_address, "localhost"}]), {error, {missing_property, document_root}} = inets:start(httpd, [{port, 0}, {server_name, "httpd_test"}, {server_root, PrivDir}, {bind_address, "localhost"}]), {error, {missing_property, server_root}} = inets:start(httpd, [{port, 0}, {server_name, "httpd_test"}, {document_root, PrivDir}, {bind_address, "localhost"}]), {error, {missing_property, port}} = inets:start(httpd, HttpdConf), ok = inets:stop(). %%------------------------------------------------------------------------- httpd_reload() -> [{doc, "Reload httpd configuration without restarting service"}]. httpd_reload(Config) when is_list(Config) -> process_flag(trap_exit, true), PrivDir = proplists:get_value(priv_dir, Config), DataDir = proplists:get_value(data_dir, Config), HttpdConf = [{server_name, "httpd_test"}, {server_root, PrivDir}, {document_root, PrivDir}, {bind_address, "localhost"}], ok = inets:start(), ct:sleep(5000), {ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]), ct:sleep(5000), [{port, Port0}] = httpd:info(Pid0, [port]), ct:sleep(5000), [{document_root, PrivDir}] = httpd:info(Pid0, [document_root]), ct:sleep(5000), ok = httpd:reload_config([{port, Port0}, {ipfamily, inet}, {server_name, "httpd_test"}, {server_root, PrivDir}, {document_root, DataDir}, {bind_address, "localhost"}], non_disturbing), ct:sleep(5000), [{document_root, DataDir}] = httpd:info(Pid0, [document_root]), ct:sleep(5000), ok = httpd:reload_config([{port, Port0}, {ipfamily, inet}, {server_name, "httpd_test"}, {server_root, PrivDir}, {document_root, PrivDir}, {bind_address, "localhost"}], disturbing), [{document_root, PrivDir}] = httpd:info(Pid0, [document_root]), ok = inets:stop(httpd, Pid0), ok = inets:stop(), File = filename:join(PrivDir, "httpd_apache.conf"), {ok, Fd0} = file:open(File, [write]), file:write(Fd0, "ServerName httpd_test\r\n"), file:write(Fd0, "ServerRoot " ++ PrivDir ++ "\r\n"), file:write(Fd0, "DocumentRoot " ++ PrivDir ++" \r\n"), file:write(Fd0, "BindAddress *\r\n"), file:write(Fd0, "Port 0\r\n"), file:close(Fd0), application:load(inets), application:set_env(inets, services, [{httpd, [{file, File}]}]), ok = inets:start(), [Pid1] = [HttpdPid || {httpd, HttpdPid} <- inets:services()], [{server_name, "httpd_test"}] = httpd:info(Pid1, [server_name]), [{port, Port1}] = httpd:info(Pid1, [port]), {ok, Fd1} = file:open(File, [write]), file:write(Fd1, "ServerName httpd_test2\r\n"), file:write(Fd1, "ServerRoot " ++ PrivDir ++ "\r\n"), file:write(Fd1, "DocumentRoot " ++ PrivDir ++" \r\n"), file:write(Fd1, "BindAddress *\r\n"), file:write(Fd1, "Port " ++ integer_to_list(Port1) ++ "\r\n"), file:close(Fd1), ok = httpd:reload_config(File, non_disturbing), [{server_name, "httpd_test2"}] = httpd:info(Pid1, [server_name]), {ok, Fd2} = file:open(File, [write]), file:write(Fd2, "ServerName httpd_test\r\n"), file:write(Fd2, "ServerRoot " ++ PrivDir ++ "\r\n"), file:write(Fd2, "DocumentRoot " ++ PrivDir ++" \r\n"), file:write(Fd2, "BindAddress *\r\n"), file:write(Fd2, "Port " ++ integer_to_list(Port1) ++ "\r\n"), file:close(Fd2), ok = httpd:reload_config(File, disturbing), [{server_name, "httpd_test"}] = httpd:info(Pid1, [server_name]), ok = inets:stop(httpd, Pid1), application:unset_env(inets, services), ok = inets:stop().