Monday, May 28, 2007

Passing Parameters To JMeter In Ant

As well as using JChav as part of our deployment cycle, I have additionally been using it to monitor some production servers. For the production servers you obviously don't run them at any load that is likely to affect the real users. However 1 thread running a set of tests once an hour (thanks to cron) can give a good view of performance over time. I am fully aware of other software that can be used to monitor my sites, but given that I already have a JMeter script designed to test key points of the application it seems like the right solution.

The production server I am using is a cluster placed behind a load balancer and I want to be able to run the tests against each instance. The application already has a URI to manually set each server to use (i.e. the load balancer server affinity), my issue is how do I maintain a single JMeter script but be able to set domain/server specific details?

The great news is that the good folks responsible for JMeter have already thought this through and added a property system.

So given an HTTPSampler that looks like this :

<HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="SetServer to server1 " enabled="true">

it can be replaced with :

<HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="SetServer to ${__property(affinity)} " enabled="true">

The JMeter Ant task also allows you to set the property, so you can do the following :

<jmeter jmeterhome="${jmeter.install.dir}" testplan="${jmeter.testplan}" resultlog="${jmeter.result.file}"> <property name="affinity" value="server1"/> <property name="" value="xml"/> </jmeter>

This will call my JMeter script passing a parameter named affinity with the value server1.

I want to call my script with several values and store them in different output directories etc. i.e. call my ant script with the property affinitty set to server1, then server2 etc etc.

I've come up with a hack that works for me, but I'm sure that a better way exists. What I have done is to separate my ant builds into 2 files. The first builds a single instance, and looks like this :

<jmeter jmeterhome="${jmeter.install.dir}" testplan="${jmeter.testplan}" resultlog="${jmeter.result.file}"> <property name="affinity" value="${servername}"/> <property name="" value="xml"/> </jmeter>
servername is now a parameter into this script, and all the other directory dependencies etc use that parameter too.

I then create a master build which calls the build single for each value :

<echo>Testing server1.</echo> <ant antfile="build-singleone.xml"> <property name="servername" value="server1"/> </ant> <echo>Testing server2.</echo> <ant antfile="build-singleone.xml"> <property name="servername" value="server2"/> </ant> <echo>Testing server3.</echo> <ant antfile="build-singleone.xml"> <property name="servername" value="server3"/> </ant>

I don't like the repetition in the script, but it does work.

No comments: