Wednesday, March 02, 2011

WebStresser: A very simple web load testing tool

I’ve been doing some experiments recently with WCF, seeing how much load I can throw at different configurations. I’m especially interested in seeing what difference async web services can make with IO intensive operations. One problem I had was finding a good HTTP load tool. I tried to get WCAT working, but found it complex and hard to understand. It also gives almost no feedback at all when you get something wrong.

In the end I wrote my own little load tool around WebRequest. It’s almost trivial, but there are few little hoops you need to jump through in order to make it work. I’ve wrapped it up as a little console application, WebStresser. You can get the source from github here:

https://github.com/mikehadlow/WebStresser

Or download a precompiled binary which requires .NET 3.5 or greater to work. It’s also reported to work fine on Mono:

https://github.com/downloads/mikehadlow/WebStresser/WebStresser.zip

To use it, just run it with a minimum of a URL:

WebStresser -u=http://localhost:5401/

Which outputs:

Starting test...
Completed: 0 Faulted: 0 Connections: 1
Completed All 1
Faulted 0
Elapsed ms 2,001
Calls per second 0
Avergate call duration ms 1,127

By default it just executes a single GET request to the given URI. If you want to see the response, add the –r option:

webstresser -u=http://localhost:5401/ -r

Which outputs:

Starting test...
Completed: 0 Faulted: 0 Connections: 1

http://localhost:5401/
Status: 200, OK
X-AspNetMvc-Version: 3.0
Connection: Close
Content-Length: 7259
Cache-Control: private
Content-Type: text/html; charset=utf-8
Date: Wed, 02 Mar 2011 21:49:37 GMT
Server: ASP.NET Development Server/10.0.0.0
X-AspNet-Version: 4.0.30319

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3. .... etc

To run a load test, just tell it how many requests to make with the –i option, and the delay, in milliseconds, between each request with the –t option. Here I’m running 100 requests 20 ms apart:

webstresser -u=http://localhost:5401/ -i=100 -t=20

Finally here’s an example calling a SOAP web service. Note the SOAPAction header and the –p option that points to a file with the postdata:

webstresser -u=http://mike-2008r2:8123/proxy -m=POST -i=100 -t=10 -p=postdata.txt 
-H=SOAPAction:http://tempuri.org/ICustomerService/GetCustomerDetails

For help:
webstresser -h

Options
-?, -h, --help
-u, --uri=VALUE REQUIRED: The URI you want to call
-m, --method=VALUE The HTTP method. Default is GET
-i, --iterations=VALUE Number of iterations to run, default is 1
-t, --interval=VALUE Iterval between each call in milliseconds, default
is 10000
-p, --postdata=VALUE Path to file containing post data
-r, --responses Print responses
-k, --keepalive KeepAlive header value (true or false), default is
true
-a, --accept=VALUE Accept header value, default is 'text/xml'
-c, --contenttype=VALUE ContentType header value, default is 'text/xml;
charset="utf-8"'
-z, --timeout=VALUE Timeout in milliseconds, default is 10000
-H[=VALUE1:VALUE2] Add a header to the request. e.g: -H MyHeader=
MyValue

I’m using the excellent Mono.Options library to do command line processing. It makes putting this kind of tool together very easy.

Happy stressing!

5 comments:

James said...

Hi Mike

We've just been investigating perf/load tests, and we're using WCat, we'll probably stick with it for its ability to push out the tests to clients and its scenarios/transactions/request breakdown. But your tool looks like an interesting option for thrashing a single request.

By the looks of your example, your hitting the VS web server, do you think it could be easily integrated with an auto build/test solution?

Cheers

Jim

Mike Hadlow said...

Hi James,

I'd agree WCat is a far more sophisticated tool than WebStresser. I guess I'm looking at the simplest scenario where you just want to pound on a single endpoint from one client machine.

Being a command line tool would make it easy to integrate into any scripted environment like automated test. The main limitation is that it doesn't provide any hooks into the server performance, so it would be hard to decide if you tests had succeeded/failed.

Anonymous said...

Hi Mike, I started to work with your application and it's very ease to use.
My question is related to the postdata.txt file.
Please, can you show an example of sending 3 values for ASP.NET with respective variable name?

Thanks in advance

Cheers

Jojje

Mike Hadlow said...

Hi Jojje,

Just use a tool like Fiddler2 to capture a request to your application and then paste the post data into the postdata.txt file.

Marcelo Manzur C. said...

Hi... after few hours of experimentation I found the method to send get request with data to server. You have to add quotes to the url.
-u="http://xxxxxxx:port/yyyyyy?data"

It work for me....

mmanzur@gmail.com