1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20%%
21
22-module(httpd_load).
23
24-include_lib("common_test/include/ct.hrl").
25
26%% General testcases bodies called from httpd_SUITE
27-export([load_test/5]).
28
29%% Help functions
30-export([load_test_client/8]).
31
32%%-------------------------------------------------------------------------
33%% Test cases starts here.
34%%-------------------------------------------------------------------------
35load_test(Type, Port, Host, Node,  NofTesters) ->
36    URIs =
37	[
38	 "/index.html",
39	 "/echo.shtml",
40	 "/",
41	 "/flastmod.shtml",
42	 "/misc/"
43	],
44    Fun = fun(Mod, Host1, Port1, Node1, Req, Exp) ->
45		  ok = httpd_test_lib:verify_request(Mod, Host1, Port1,
46						     Node1, Req, Exp)
47	  end,
48    load_test(Fun, URIs ++ URIs, Type, Host, Port, Node, NofTesters, []).
49%%--------------------------------------------------------------------
50%% Internal functions
51%%--------------------------------------------------------------------
52
53load_test(_, _, _, _, _, _, 0, []) ->
54    ok;
55load_test(Fun, URIs, Type, Host, Port, Node,  0, List) ->
56    receive
57	{Pid, done} ->
58	    load_test(Fun, URIs, Type, Host, Port, Node,  0,
59		      lists:delete(Pid, List));
60	{'EXIT', Pid, normal} ->
61	    load_test(Fun, URIs, Type, Host, Port, Node,  0,
62		      lists:delete(Pid, List));
63	{'EXIT', Pid, Reason} ->
64	    Str = lists:flatten(io_lib:format("client ~p exited: ~p",
65					      [Pid,Reason])),
66	    ct:fail(Str);
67	_ ->
68	    load_test(Fun, URIs, Type, Host, Port, Node,  0, List)
69    end;
70
71load_test(Fun, URIs, Type, Host, Port, Node,  X, List) ->
72    Pid = spawn_link(?MODULE, load_test_client,
73		     [Fun, URIs, Type,  Host,  Port,  Node,  self(), 100]),
74    load_test(Fun, lists:reverse(URIs), Type, Host, Port, Node,  X-1,
75	      [Pid | List]).
76
77load_test_client(_Fun, [], _Type, _Host, _Port, _Node,  Boss, _Timeout) ->
78    load_test_client_done(Boss);
79load_test_client(Fun, [URI|URIs], Type, Host, Port, Node,  Boss, Timeout) ->
80    Req = "GET "++URI++" HTTP/1.0\r\nConnection: Close\r\n"
81	"From: m@erix\r\nReferer: http://www.ericsson.se/\r\n\r\n",
82    Timeout1 =
83	case (catch Fun(Type,  Host,  Port,  Node,  Req,
84			[{statuscode, 200}, {statuscode, 500},
85			 {statuscode, 503}, {version, "HTTP/1.0"}])) of
86	    {'EXIT', {suite_failed, connection_closed, _, _}} ->
87		%% Some platforms seems to handle heavy load badly.
88		%% So, back off and see if this helps
89		2 * Timeout;
90	    _ ->
91		Timeout
92	end,
93    ct:sleep(Timeout1),
94    load_test_client(Fun, URIs, Type, Host, Port, Node, Boss, Timeout1).
95
96load_test_client_done(Boss) ->
97    Boss ! {self(), done}.
98
99