Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

random thinktime using a given range (TSUN-80)

SVN Revision: 871
  • Loading branch information...
commit e75318f91be5f5ecf3fbef0a6ca1eb2573acac5a 1 parent 473098e
@nniclausse nniclausse authored
View
4 examples/http_setdynvars.xml.in
@@ -21,7 +21,7 @@
</load>
<options>
- <option name="file_server" id='userdb' value="/home/nniclaus/.tsung/test_file_server.csv"/>
+ <option name="file_server" id='userdb' value="/home/nniclaus/.tsung/users-gforge.csv"/>
<option type="ts_http" name="user_agent">
<user_agent probability="100">
Some browser version 42
@@ -60,7 +60,7 @@
</http>
</request>
- <thinktime value="5" random="true"/>
+ <thinktime min="2" max="4"></thinktime>
<request subst="true">
<dyn_variable name="title" regexp="&lt;title&gt;\(.*\)&lt;/title&gt;"/>
View
2  examples/pgsql.xml.in
@@ -35,7 +35,7 @@
</request>
</transaction>
- <thinktime value="12"/>
+ <thinktime value="2"/>
<transaction name="select">
<request><pgsql type="sql">SELECT * from accounts;</pgsql></request>
View
42 examples/thinks.xml.in
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!DOCTYPE tsung SYSTEM "@prefix@/share/@PACKAGE_NAME@/@DTD@">
+<tsung loglevel="notice">
+
+ <clients>
+ <client host="localhost" use_controller_vm="true"/>
+ </clients>
+
+ <servers>
+ <server host="127.0.0.1" port="5432" type="tcp"/>
+ </servers>
+
+ <load>
+ <arrivalphase phase="1" duration="10" unit="minute">
+ <users interarrival="30" unit="second"></users>
+ </arrivalphase>
+ </load>
+
+<options>
+ <option name="thinktime" value="2" random="false" override="true"/>
+</options>
+
+ <sessions>
+ <session probability="100" name="pgsql-example" type="ts_pgsql">
+ <transaction name="connection">
+ <request>
+ <pgsql type="connect" database="bench" username="bench" />
+ </request>
+ </transaction>
+
+ <request>
+ <pgsql type="authenticate" password="sesame"/>
+ </request>
+
+ <thinktime value="200"/>
+
+ <request><pgsql type="close"></pgsql></request>
+ <thinktime min="2" max="7"/>
+
+ </session>
+ </sessions>
+</tsung>
View
42 examples/thinks2.xml.in
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!DOCTYPE tsung SYSTEM "@prefix@/share/@PACKAGE_NAME@/@DTD@">
+<tsung loglevel="notice">
+
+ <clients>
+ <client host="localhost" use_controller_vm="true"/>
+ </clients>
+
+ <servers>
+ <server host="127.0.0.1" port="5432" type="tcp"/>
+ </servers>
+
+ <load>
+ <arrivalphase phase="1" duration="10" unit="minute">
+ <users interarrival="30" unit="second"></users>
+ </arrivalphase>
+ </load>
+
+<options>
+ <option name="thinktime" value="3" random="true" override="false"/>
+</options>
+
+ <sessions>
+ <session probability="100" name="pgsql-example" type="ts_pgsql">
+ <transaction name="connection">
+ <request>
+ <pgsql type="connect" database="bench" username="bench" />
+ </request>
+ </transaction>
+
+ <request>
+ <pgsql type="authenticate" password="sesame"/>
+ </request>
+
+ <thinktime value="1"/>
+
+ <request><pgsql type="close"></pgsql></request>
+ <thinktime/>
+
+ </session>
+ </sessions>
+</tsung>
View
56 src/test/ts_test_config.erl
@@ -28,14 +28,68 @@ read_config_jabber_test() ->
myset_env(),
ts_user_server:start([]),
?assertMatch({ok, Config}, ts_config:read("./examples/jabber.xml")).
+
+config_get_session_test() ->
+ myset_env(),
+ ts_user_server:start([]),
+ ts_config_server:start_link(["/tmp"]),
+ ok = ts_config_server:read_config("./examples/http_setdynvars.xml"),
+ {ok, {Session,Size,IP,Server} } = ts_config_server:get_next_session("localhost"),
+ ?assertMatch(1, Session#session.id).
+
+
read_config_badpop_test() ->
myset_env(),
ts_user_server:start([]),
{ok, Config} = ts_config:read("./src/test/badpop.xml"),
?assertMatch({error,[{error,{bad_sum,_,_}}]}, ts_config_server:check_config(Config)).
+config_minmax_test() ->
+ myset_env(),
+ {ok, {Session,Size,IP,Server} } = ts_config_server:get_next_session("localhost"),
+ Id = Session#session.id,
+ ?assertMatch({thinktime,{range,2000,4000}}, ts_config_server:get_req(Id,7)).
+
+config_minmax2_test() ->
+ myset_env(),
+ {ok, {Session,Size,IP,Server} } = ts_config_server:get_next_session("localhost"),
+ Id = Session#session.id,
+ {thinktime, Req} = ts_config_server:get_req(Id,7),
+ Ref=ts_client:set_thinktime(Req),
+ receive
+ {timeout,Ref2,end_thinktime} -> ok
+ end,
+ ?assertMatch(Ref, Ref2).
+
+config_thinktime_test() ->
+ myset_env(),
+ ok = ts_config_server:read_config("./examples/thinks.xml"),
+ {ok, {Session,Size,IP,Server} } = ts_config_server:get_next_session("localhost"),
+ Id = Session#session.id,
+ {thinktime, Req=2000} = ts_config_server:get_req(Id,5),
+ {thinktime, 2000} = ts_config_server:get_req(Id,7),
+ Ref=ts_client:set_thinktime(Req),
+ receive
+ {timeout,Ref2,end_thinktime} -> ok
+ end,
+ ?assertMatch(Ref, Ref2).
+
+config_thinktime2_test() ->
+ myset_env(),
+ ok = ts_config_server:read_config("./examples/thinks2.xml"),
+ {ok, {Session,Size,IP,Server} } = ts_config_server:get_next_session("localhost"),
+ Id = Session#session.id,
+ {thinktime, Req} = ts_config_server:get_req(Id,5),
+ Ref=ts_client:set_thinktime(Req),
+ receive
+ {timeout,Ref2,end_thinktime} -> ok
+ end,
+ random:seed(), % reinit seed for others tests
+ ?assertMatch({random,1000}, Req).
myset_env()->
- application:set_env(stdlib,debug_level,0),
+ myset_env(0).
+myset_env(Level)->
+ application:set_env(stdlib,debug_level,Level),
application:set_env(stdlib,thinktime_override,"false"),
application:set_env(stdlib,thinktime_random,"false").
View
4 src/tsung/ts_client.erl
@@ -148,6 +148,7 @@ handle_sync_event(_Event, _From, StateName, StateData) ->
%% inet data
handle_info({NetEvent, _Socket, Data}, wait_ack, State) when NetEvent==tcp;
NetEvent==ssl ->
+ ?DebugF("TCP data received: size=~p ~n",[size(Data)]),
case handle_data_msg(Data, State) of
{NewState=#state_rcv{ack_done=true}, Opts} ->
NewSocket = ts_utils:inet_setopts(NewState#state_rcv.protocol,
@@ -562,6 +563,7 @@ handle_close_while_sending(State=#state_rcv{persistent = true,
ts_utils:close_socket(Proto, State#state_rcv.socket),
set_connected_status(false),
Think = PO#proto_opts.retry_timeout,
+ %%FIXME: report the error to ts_mon ?
?LOGF("Server must have closed connection upon us, waiting ~p msec~n",
[Think], ?NOTICE),
set_thinktime(Think),
@@ -659,6 +661,8 @@ protocol_options(gen_udp,#proto_opts{udp_rcv_size=Rcv, udp_snd_size=Snd}) ->
set_thinktime(infinity) -> ok;
set_thinktime({random, Think}) ->
set_thinktime(round(ts_stats:exponential(1/Think)));
+set_thinktime({range, Min, Max}) ->
+ set_thinktime(ts_stats:uniform(Min,Max));
set_thinktime(Think) ->
%% dot not use timer:send_after because it does not scale well:
%% http://www.erlang.org/ml-archive/erlang-questions/200202/msg00024.html
View
11 src/tsung/ts_stats.erl
@@ -30,7 +30,7 @@
-author('nicolas.niclausse@niclux.org').
-export([exponential/1, exponential/2, pareto/2,
- normal/0, normal/1, normal/2,
+ normal/0, normal/1, normal/2, uniform/2,
invgaussian/2,
mean/1, mean/3,
variance/1,
@@ -52,6 +52,9 @@ sample (F, X, Param, 0) ->
sample (F, X, Param, N) ->
sample(F, [F(Param)|X], Param, N-1 ).
+uniform(Min,Max)->
+ Min+random:uniform(Max-Min).
+
%% random sample from an exponential distribution
exponential(Param) ->
-math:log(random:uniform())/Param.
@@ -76,14 +79,14 @@ invgaussian([Mu,Lambda],N) ->
invgaussian(Param,N) ->
sample(fun(X) -> invgaussian(X) end , Param, N).
-
+
%% random sample from a Inverse Gaussian distribution
invgaussian(#invgaussian{mu=Mu, lambda=Lambda}) ->
Y = Mu*pow(normal(), 2),
X1 = Mu+Mu*Y/(2*Lambda)-Mu*sqrt(4*Lambda*Y+pow(Y,2))/(2*Lambda),
U = random:uniform(),
X = (Mu/(Mu+X1))-U,
- case X >=0 of
+ case X >=0 of
true -> X1;
false -> Mu*Mu/X1
end.
@@ -97,7 +100,7 @@ normal([Mean,StdDev],N) ->
normal(Param,N) ->
sample(fun(X) -> normal(X) end , Param, N).
-
+
normal(N) when integer(N)->
normal(#normal{},N);
normal(#normal{mean=M,stddev=S}) ->
View
24 src/tsung_controller/ts_config.erl
@@ -426,8 +426,13 @@ parse(Element = #xmlElement{name=option, attributes=Attrs},
"thinktime" ->
Val = getAttr(integer,Attrs, value),
ets:insert(Tab,{{thinktime, value}, Val}),
- Random = getAttr(string,Attrs, random,
- ?config(thinktime_random)),
+ Random = case { getAttr(integer, Attrs, min),
+ getAttr(integer, Attrs, max)} of
+ {Min, Max } when is_integer(Min), is_integer(Max) ->
+ {"range", Min, Max};
+ {"",""} ->
+ getAttr(string,Attrs, random, ?config(thinktime_random))
+ end,
ets:insert(Tab,{{thinktime, random}, Random}),
Override = getAttr(string, Attrs, override,
?config(thinktime_override)),
@@ -495,20 +500,27 @@ parse(Element = #xmlElement{name=option, attributes=Attrs},
parse(Element = #xmlElement{name=thinktime, attributes=Attrs},
Conf = #config{cur_req_id=ReqId, curid=Id, session_tab = Tab,
sessions = [CurS |_]}) ->
- DefThink = get_default(Tab,{thinktime, value},thinktime_value),
+ DefThink = get_default(Tab,{thinktime, value},thinktime_value),
DefRandom = get_default(Tab,{thinktime, random},thinktime_random),
{Think, Randomize} =
case get_default(Tab,{thinktime, override},thinktime_override) of
"true" ->
{DefThink, DefRandom};
"false" ->
- CurThink = getAttr(integer, Attrs, value,DefThink),
- CurRandom=getAttr(string, Attrs,random,DefRandom),
- {CurThink, CurRandom}
+ case { getAttr(integer, Attrs, min), getAttr(integer, Attrs, max)} of
+ {Min, Max } when is_integer(Min), is_integer(Max) ->
+ {"", {"range", Min, Max} };
+ {"",""} ->
+ CurThink = getAttr(integer, Attrs, value,DefThink),
+ CurRandom = getAttr(string, Attrs,random,DefRandom),
+ {CurThink, CurRandom}
+ end
end,
RealThink = case Randomize of
"true" ->
{random, Think * 1000};
+ {"range", Min2, Max2} ->
+ {range, Min2 * 1000, Max2 * 1000};
"false" ->
round(Think * 1000)
end,
View
5 tsung-1.0.dtd
@@ -104,7 +104,10 @@ repeat)*>
<!ELEMENT thinktime EMPTY>
<!ATTLIST thinktime
random (true|false) "false"
- value NMTOKEN #REQUIRED>
+ value NMTOKEN #IMPLIED
+ min NMTOKEN #IMPLIED
+ max NMTOKEN #IMPLIED
+ >
<!ELEMENT user_agent (#PCDATA)*>
<!ATTLIST user_agent
Please sign in to comment.
Something went wrong with that request. Please try again.