Posted 03/27/2008 in ajax

First off - never leave home before launching any site or server architecture without HTTPERF.

Here's the download link to my patch to HTTPERF 0.9.0: httperf-0.9.0-wsesslog-headers.patch

This is the most robust and elegantly simple load testing CLI (command line interface) I've yet ever seen or been happy to use. The one feature that is most impressive is the --wsesslog feature (excerpt from the httperf man page):
              This  specifies  a session workload generator similar to --wsess
              (please read that description first).  With  --wsesslog  though,
              many aspects of user sessions, including the number and sequence
              of URI's, request method, think-time  and  burst-length  parame-
              ters, can be specified in an input file F.  Two other parameters
              are retained from --wsess, namely N, the number of  sessions  to
              initiate,  and  X, the burst-to-burst user think time (note that
              this becomes a default time since the  input  file  F  can  also
              specify  user  think time on a per-burst basis.  A small example
              input file can most-easily show the settable parameters:

              # Comment lines start with a ``#'' as the first
              # character.  Lines with only whitespace delimit
              # sessions (multiple blank lines do not generate
              # ``null'' sessions).  All other lines specify a
              # uri-sequence (1 uri per line).  If the first
              # character of the line is whitespace (e.g. space
              # or tab), the uri is considered to be part of a
              # burst that is sent out after the previous
              # non-burst uri.

              # session 1 definition (this is a comment)
              /foo.html think=2.0
              /foo2.html method=POST contents='Post data'

              # session 2 definition
              /foo3.html method=POST contents="Multiline\ndata"
              /foo4.html method=HEAD

              The above description specifies 2 sessions.  The  first  session
              will  start  with  a  request for /foo.html.  When the /foo.html
              response  comes  back,  a  burst  of  2  requests  will   follow
              (/pict1.gif  and  /pict2.gif).  When the last of those responses
              is received, a two second user think time is inserted before the
              next request of /foo2.html is issued.  This request is sent as a
              POST.  The posted data can be contained between single- or  dou-
              ble-quotes.  Newlines can appear within posted data as ``\n'' or
              as a ``\''.  The /foo2.html response is followed by a  burst
              request  of /pict3.gif and /pict4.gif, which concludes this ses-
              sion.  The second session is started some time after the  first,
              as specified by the --rate or --period options.

              The  second  session  consists  of  2  requests separated by the
              default user think time as specified by the X parameter  of  the
              --wsesslog  option.  If the N parameter of --wsesslog is greater
              than the number of sessions defined in input file  F,  then  the
              defined  sessions are used repeatedly until N sessions have been
              created (i.e., the defined sessions are used  in  a  round-robin

              One  should  avoid  using  --wsesslog  in conjunction with other
              httperf options that also control session behavior and  workload
              URI's, namely --burst-length, --wsess, --wlog, and --wset.

This essentially is a very robust way to teach HTTPERF how to simulate user "sessions" or use-cases. This essentially can contain any combination of HTTP GETs or POSTs among other commands. Considering most AJAX frameworks utilize a HTTP POST for sending data this route of testing might seem easy. The one shortcoming with httperf-0.9.0 (latest as of this writing) is that it's missing a specific request header for each HTTP POST to simulate the AJAX request:
Content-Type: application/x-www-form-urlencoded

I've put together a quick patch that you can apply to the wsesslog.c file to enable you to script specific request headers for any individual request in the wsesslog script. Case in point here's a snippet of a wsesslog including the newly added headers=X argument:
# application/x-www-form-urlencoded
/ajax_handler.php method=POST headers='Content-Type: application/x-www-form-urlencoded\n' contents='arg1%3Dtest1%26arg2%3Dtest2'

# application/json
/ajax_handler.php method=POST headers='Content-Type: application/x-www-form-urlencoded\n' contents='arg1%3Dtest1%26arg2%3Dtest2'

Here's another example of including cookies in your header and JSON content in the POST:
# simply load a single test.asmx test() function with session support and an object as the post arguments
/test.asmx/test method=POST headers='Content-Type: application/json; charset=utf-8\nCookie: ASP.NET_SessionId=o0naaq555jzbp245h0e3njv5;AUTH=8uRq%2bPj7g59S\n' contents='%7B%22arg1%22:%22test%22%7B'

And to further show how you would build a more complete test-case:
# initial page load

# first AJAX function
/test.asmx/test method=POST headers='Content-Type: application/json; charset=utf-8\nCookie: ASP.NET_SessionId=o0naaq555jzbp245h0e3njv5;AUTH=8uRq%2bPj7g59SQGiVhKytsQh3Tg7nCHhpGoU9vuP%\n' contents='%7B%22arg1%22:%22test1%22%7B'

# second AJAX function
/test.asmx/test method=POST headers='Content-Type: application/json; charset=utf-8\nCookie: ASP.NET_SessionId=o0naaq555jzbp245h0e3njv5;AUTH=8uRq%2bPj7g59SQGiVhKytsQh3Tg7nCHhpGoU9vuP%2\n' contents='%7B%22arg1%22:%22test2%22%7B'

This includes acquiring assets per "request". The tabbed lines denote sub-requests as part of the parent request. The blank lines denote a new "request" as part of the test case.

Here's the download link to my patch to HTTPERF 0.9.0: httperf-0.9.0-wsesslog-headers.patch

Save the patch as httperf-0.9.0/src/gen/httperf-0.9.0-wsesslog-headers.patch and apply the patch:
# cd httperf-0.9.0/src/gen
# patch < ~/httperf-0.9.0-wsesslog-headers.patch
patching file wsesslog.c
new comment
EMAIL (hidden)
MESSAGE TAGS ALLOWED: <code> <a> <pre class="code [tab4|tabX|inline|bash]"> <br>