4
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
6
%% The contents of this file are subject to the Erlang Public License,
7
%% Version 1.1, (the "License"); you may not use this file except in
8
%% compliance with the License. You should have received a copy of the
9
%% Erlang Public License along with this software. If not, it can be
10
%% retrieved online at http://www.erlang.org/.
12
%% Software distributed under the License is distributed on an "AS IS"
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
%% the License for the specific language governing rights and limitations
22
-include_lib("common_test/include/ct.hrl").
23
-include("test_server_line.hrl").
24
-include("inets_test_lib.hrl").
26
%% Note: This directive should only be used in test suites.
29
-define(NUM_DEFAULT_SERVICES, 1).
31
suite() -> [{ct_hooks,[ts_install_cth]}].
34
[{group, app_test}, {group, appup_test},
35
{group, services_test}, httpd_reload].
39
[start_inets, start_httpc, start_httpd, start_ftpc,
41
{app_test, [], [{inets_app_test, all}]},
42
{appup_test, [], [{inets_appup_test, all}]}].
44
init_per_group(_GroupName, Config) ->
47
end_per_group(_GroupName, Config) ->
53
%%--------------------------------------------------------------------
54
%% Function: init_per_suite(Config) -> Config
56
%% A list of key/value pairs, holding the test case configuration.
57
%% Description: Initiation before the whole suite
59
%% Note: This function is free to add any key/value pairs to the Config
60
%% variable, but should NOT alter/remove any existing entries.
61
%%--------------------------------------------------------------------
62
init_per_suite(Config) ->
65
%%--------------------------------------------------------------------
66
%% Function: end_per_suite(Config) -> _
68
%% A list of key/value pairs, holding the test case configuration.
69
%% Description: Cleanup after the whole suite
70
%%--------------------------------------------------------------------
71
end_per_suite(_Config) ->
74
%%--------------------------------------------------------------------
75
%% Function: init_per_testcase(Case, Config) -> Config
77
%% Name of the test case that is about to be run.
79
%% A list of key/value pairs, holding the test case configuration.
81
%% Description: Initiation before each test case
83
%% Note: This function is free to add any key/value pairs to the Config
84
%% variable, but should NOT alter/remove any existing entries.
85
%%--------------------------------------------------------------------
86
init_per_testcase(_Case, Config) ->
90
%%--------------------------------------------------------------------
91
%% Function: end_per_testcase(Case, Config) -> _
93
%% Name of the test case that is about to be run.
95
%% A list of key/value pairs, holding the test case configuration.
96
%% Description: Cleanup after each test case
97
%%--------------------------------------------------------------------
98
end_per_testcase(_, Config) ->
101
%%-------------------------------------------------------------------------
102
%% Test cases starts here.
103
%%-------------------------------------------------------------------------
107
%%-------------------------------------------------------------------------
110
["Test inets API functions"];
111
start_inets(suite) ->
113
start_inets(Config) when is_list(Config) ->
114
[_|_] = inets:service_names(),
116
{error,inets_not_started} = inets:services(),
117
{error,inets_not_started} = inets:services_info(),
121
%% httpc default profile always started
122
[_|_] = inets:services(),
123
[_|_] = inets:services_info(),
125
{error,{already_started,inets}} = inets:start(),
128
{error,{not_started,inets}} = inets:stop(),
130
ok = inets:start(transient),
133
ok = inets:start(permanent),
137
%%-------------------------------------------------------------------------
140
["Start/stop of httpc service"];
141
start_httpc(suite) ->
143
start_httpc(Config) when is_list(Config) ->
144
process_flag(trap_exit, true),
145
tsp("start_httpc -> entry with"
146
"~n Config: ~p", [Config]),
148
PrivDir = ?config(priv_dir, Config),
150
tsp("start_httpc -> start (empty) inets"),
153
tsp("start_httpc -> start httpc (as inets service) with profile foo"),
154
{ok, Pid0} = inets:start(httpc, [{profile, foo}]),
156
tsp("start_httpc -> check running services"),
157
Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
158
true = lists:member(Pid0, Pids0),
159
[_|_] = inets:services_info(),
161
tsp("start_httpc -> stop httpc"),
162
inets:stop(httpc, Pid0),
164
tsp("start_httpc -> sleep some"),
165
test_server:sleep(100),
167
tsp("start_httpc -> check running services"),
168
Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
169
false = lists:member(Pid0, Pids1),
171
tsp("start_httpc -> start httpc (stand-alone) with profile bar"),
172
{ok, Pid1} = inets:start(httpc, [{profile, bar}], stand_alone),
174
tsp("start_httpc -> check running services"),
175
Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
176
false = lists:member(Pid1, Pids2),
178
tsp("start_httpc -> stop httpc"),
179
ok = inets:stop(stand_alone, Pid1),
181
{'EXIT', Pid1, shutdown} ->
184
tsf(stand_alone_not_shutdown)
187
tsp("start_httpc -> stop inets"),
190
tsp("start_httpc -> unload inets"),
191
application:load(inets),
193
tsp("start_httpc -> set inets environment (httpc profile foo)"),
194
application:set_env(inets, services, [{httpc,[{profile, foo},
195
{data_dir, PrivDir}]}]),
197
tsp("start_httpc -> start inets"),
200
tsp("start_httpc -> check running services"),
201
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
203
tsp("start_httpc -> unset inets env"),
204
application:unset_env(inets, services),
206
tsp("start_httpc -> stop inets"),
209
tsp("start_httpc -> start (empty) inets"),
212
tsp("start_httpc -> start inets httpc service with profile foo"),
213
{ok, Pid3} = inets:start(httpc, [{profile, foo}]),
215
tsp("start_httpc -> stop inets service httpc with profile foo"),
216
ok = inets:stop(httpc, foo),
218
tsp("start_httpc -> check running services"),
219
Pids3 = [ServicePid || {_, ServicePid} <- inets:services()],
220
false = lists:member(Pid3, Pids3),
222
tsp("start_httpc -> stop inets"),
225
tsp("start_httpc -> done"),
229
%%-------------------------------------------------------------------------
232
["Start/stop of httpd service"];
233
start_httpd(suite) ->
235
start_httpd(Config) when is_list(Config) ->
236
process_flag(trap_exit, true),
237
i("start_httpd -> entry with"
238
"~n Config: ~p", [Config]),
239
PrivDir = ?config(priv_dir, Config),
240
HttpdConf = [{server_name, "httpd_test"}, {server_root, PrivDir},
241
{document_root, PrivDir}, {bind_address, "localhost"}],
243
i("start_httpd -> start inets"),
246
i("start_httpd -> start httpd service"),
247
{ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
248
Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
249
true = lists:member(Pid0, Pids0),
250
[_|_] = inets:services_info(),
252
i("start_httpd -> stop httpd service"),
253
inets:stop(httpd, Pid0),
254
test_server:sleep(500),
255
Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
256
false = lists:member(Pid0, Pids1),
257
i("start_httpd -> start (stand-alone) httpd service"),
259
inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf],
261
Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
262
false = lists:member(Pid1, Pids2),
263
i("start_httpd -> stop (stand-alone) httpd service"),
264
ok = inets:stop(stand_alone, Pid1),
266
{'EXIT', Pid1, shutdown} ->
269
test_server:fail(stand_alone_not_shutdown)
271
i("start_httpd -> stop inets"),
273
File0 = filename:join(PrivDir, "httpd.conf"),
274
{ok, Fd0} = file:open(File0, [write]),
275
Str = io_lib:format("~p.~n", [[{port, 0}, {ipfamily, inet} | HttpdConf]]),
276
ok = file:write(Fd0, Str),
279
i("start_httpd -> [application] load inets"),
280
application:load(inets),
281
i("start_httpd -> [application] set httpd services env with proplist-file"),
282
application:set_env(inets,
283
services, [{httpd, [{proplist_file, File0}]}]),
284
i("start_httpd -> start inets"),
286
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
287
i("start_httpd -> [application] unset services env"),
288
application:unset_env(inets, services),
289
i("start_httpd -> stop inets"),
292
File1 = filename:join(PrivDir, "httpd_apache.conf"),
294
{ok, Fd1} = file:open(File1, [write]),
295
file:write(Fd1, "ServerName httpd_test\r\n"),
296
file:write(Fd1, "ServerRoot " ++ PrivDir ++ "\r\n"),
297
file:write(Fd1, "DocumentRoot " ++ PrivDir ++" \r\n"),
298
file:write(Fd1, "BindAddress *|inet\r\n"),
299
file:write(Fd1, "Port 0\r\n"),
302
i("start_httpd -> [application] load inets"),
303
application:load(inets),
304
i("start_httpd -> [application] set httpd services env with file"),
305
application:set_env(inets,
306
services, [{httpd, [{file, File1}]}]),
307
i("start_httpd -> start inets"),
309
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
310
i("start_httpd -> [application] unset services env"),
311
application:unset_env(inets, services),
312
i("start_httpd -> stop inets"),
316
i("start_httpd -> [application] load inets"),
317
application:load(inets),
318
i("start_httpd -> [application] set httpd services OLD env"),
319
application:set_env(inets,
320
services, [{httpd, File1}]),
321
i("start_httpd -> start inets"),
323
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
324
i("start_httpd -> [application] unset services enc"),
325
application:unset_env(inets, services),
326
i("start_httpd -> stop inets"),
329
i("start_httpd -> start inets"),
331
i("start_httpd -> try (and fail) start httpd service - server_name"),
332
{error, {missing_property, server_name}} =
333
inets:start(httpd, [{port, 0},
334
{server_root, PrivDir},
335
{document_root, PrivDir},
336
{bind_address, "localhost"}]),
337
i("start_httpd -> try (and fail) start httpd service - missing document_root"),
338
{error, {missing_property, document_root}} =
339
inets:start(httpd, [{port, 0},
340
{server_name, "httpd_test"},
341
{server_root, PrivDir},
342
{bind_address, "localhost"}]),
343
i("start_httpd -> try (and fail) start httpd service - missing server_root"),
344
{error, {missing_property, server_root}} =
345
inets:start(httpd, [{port, 0},
346
{server_name, "httpd_test"},
347
{document_root, PrivDir},
348
{bind_address, "localhost"}]),
349
i("start_httpd -> try (and fail) start httpd service - missing port"),
350
{error, {missing_property, port}} =
351
inets:start(httpd, HttpdConf),
352
i("start_httpd -> stop inets"),
354
i("start_httpd -> done"),
358
%%-------------------------------------------------------------------------
361
["Start/stop of ftpc service"];
364
start_ftpc(Config) when is_list(Config) ->
365
process_flag(trap_exit, true),
366
inets:disable_trace(),
367
inets:enable_trace(max, io, ftpc),
371
{_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config),
372
case inets:start(ftpc, [{host, FtpdHost}]) of
374
Pids0 = [ServicePid || {_, ServicePid} <-
376
true = lists:member(Pid0, Pids0),
377
[_|_] = inets:services_info(),
378
inets:stop(ftpc, Pid0),
379
test_server:sleep(100),
380
Pids1 = [ServicePid || {_, ServicePid} <-
382
false = lists:member(Pid0, Pids1),
384
inets:start(ftpc, [{host, FtpdHost}], stand_alone),
385
Pids2 = [ServicePid || {_, ServicePid} <-
387
false = lists:member(Pid1, Pids2),
388
ok = inets:stop(stand_alone, Pid1),
390
{'EXIT', Pid1, shutdown} ->
393
tsf(stand_alone_not_shutdown)
396
inets:disable_trace(),
399
inets:disable_trace(),
400
{skip, "Unable to reach selected FTP server " ++ FtpdHost}
404
throw:{error, not_found} ->
405
inets:disable_trace(),
406
{skip, "No available FTP servers"}
411
%%-------------------------------------------------------------------------
414
["Start/stop of tfpd service"];
415
start_tftpd(suite) ->
417
start_tftpd(Config) when is_list(Config) ->
418
process_flag(trap_exit, true),
420
{ok, Pid0} = inets:start(tftpd, [{host, "localhost"}, {port, 0}]),
421
Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
422
true = lists:member(Pid0, Pids0),
423
[_|_] = inets:services_info(),
424
inets:stop(tftpd, Pid0),
425
test_server:sleep(100),
426
Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
427
false = lists:member(Pid0, Pids1),
429
inets:start(tftpd, [{host, "localhost"}, {port, 0}], stand_alone),
430
Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
431
false = lists:member(Pid1, Pids2),
432
ok = inets:stop(stand_alone, Pid1),
434
{'EXIT', Pid1, shutdown} ->
437
test_server:fail(stand_alone_not_shutdown)
440
application:load(inets),
441
application:set_env(inets, services, [{tftpd,[{host, "localhost"},
444
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
445
application:unset_env(inets, services),
449
%%-------------------------------------------------------------------------
452
["Reload httpd configuration without restarting service"];
453
httpd_reload(suite) ->
455
httpd_reload(Config) when is_list(Config) ->
456
process_flag(trap_exit, true),
457
i("httpd_reload -> starting"),
458
PrivDir = ?config(priv_dir, Config),
459
DataDir = ?config(data_dir, Config),
460
HttpdConf = [{server_name, "httpd_test"},
461
{server_root, PrivDir},
462
{document_root, PrivDir},
463
{bind_address, "localhost"}],
465
inets:enable_trace(max, io),
467
i("httpd_reload -> start inets"),
470
test_server:sleep(5000),
471
i("httpd_reload -> inets started - start httpd service"),
473
{ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
474
test_server:sleep(5000),
475
i("httpd_reload -> httpd service started (~p) - get port", [Pid0]),
477
[{port, Port0}] = httpd:info(Pid0, [port]),
478
test_server:sleep(5000),
479
i("httpd_reload -> Port: ~p - get document root", [Port0]),
481
[{document_root, PrivDir}] = httpd:info(Pid0, [document_root]),
482
test_server:sleep(5000),
483
i("httpd_reload -> document root: ~p - reload config", [PrivDir]),
485
ok = httpd:reload_config([{port, Port0}, {ipfamily, inet},
486
{server_name, "httpd_test"},
487
{server_root, PrivDir},
488
{document_root, DataDir},
489
{bind_address, "localhost"}], non_disturbing),
490
test_server:sleep(5000),
491
io:format("~w:~w:httpd_reload - reloaded - get document root~n", [?MODULE, ?LINE]),
493
[{document_root, DataDir}] = httpd:info(Pid0, [document_root]),
494
test_server:sleep(5000),
495
i("httpd_reload -> document root: ~p - reload config", [DataDir]),
497
ok = httpd:reload_config([{port, Port0}, {ipfamily, inet},
498
{server_name, "httpd_test"},
499
{server_root, PrivDir},
500
{document_root, PrivDir},
501
{bind_address, "localhost"}], disturbing),
503
[{document_root, PrivDir}] = httpd:info(Pid0, [document_root]),
504
ok = inets:stop(httpd, Pid0),
507
File = filename:join(PrivDir, "httpd_apache.conf"),
509
{ok, Fd0} = file:open(File, [write]),
510
file:write(Fd0, "ServerName httpd_test\r\n"),
511
file:write(Fd0, "ServerRoot " ++ PrivDir ++ "\r\n"),
512
file:write(Fd0, "DocumentRoot " ++ PrivDir ++" \r\n"),
513
file:write(Fd0, "BindAddress *\r\n"),
514
file:write(Fd0, "Port 0\r\n"),
517
application:load(inets),
518
application:set_env(inets,
519
services, [{httpd, [{file, File}]}]),
522
[Pid1] = [HttpdPid || {httpd, HttpdPid} <- inets:services()],
523
[{server_name, "httpd_test"}] = httpd:info(Pid1, [server_name]),
524
[{port, Port1}] = httpd:info(Pid1, [port]),
525
{ok, Fd1} = file:open(File, [write]),
526
file:write(Fd1, "ServerName httpd_test2\r\n"),
527
file:write(Fd1, "ServerRoot " ++ PrivDir ++ "\r\n"),
528
file:write(Fd1, "DocumentRoot " ++ PrivDir ++" \r\n"),
529
file:write(Fd1, "BindAddress *\r\n"),
530
file:write(Fd1, "Port " ++ integer_to_list(Port1) ++ "\r\n"),
533
ok = httpd:reload_config(File, non_disturbing),
534
[{server_name, "httpd_test2"}] = httpd:info(Pid1, [server_name]),
536
{ok, Fd2} = file:open(File, [write]),
537
file:write(Fd2, "ServerName httpd_test\r\n"),
538
file:write(Fd2, "ServerRoot " ++ PrivDir ++ "\r\n"),
539
file:write(Fd2, "DocumentRoot " ++ PrivDir ++" \r\n"),
540
file:write(Fd2, "BindAddress *\r\n"),
541
file:write(Fd2, "Port " ++ integer_to_list(Port1) ++ "\r\n"),
543
ok = httpd:reload_config(File, disturbing),
544
[{server_name, "httpd_test"}] = httpd:info(Pid1, [server_name]),
546
ok = inets:stop(httpd, Pid1),
547
application:unset_env(inets, services),
549
i("httpd_reload -> starting"),
554
test_server:fail(Reason).
559
Timestamp = formated_timestamp(),
560
test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n", [Timestamp, self(), ?MODULE | A]).
566
Timestamp = formated_timestamp(),
567
io:format("*** ~s ~w:" ++ F ++ "~n", [Timestamp, ?MODULE | A]).
569
formated_timestamp() ->
570
format_timestamp( os:timestamp() ).
572
format_timestamp({_N1, _N2, N3} = Now) ->
573
{Date, Time} = calendar:now_to_datetime(Now),
575
{Hour,Min,Sec} = Time,
577
io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
578
[YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
579
lists:flatten(FormatDate).