I have been involved on continuously testing systems for robustness. One of my toy projects is the JMeterRestSampler, a plugin for JMeter to ease creation of such tests and automate their execution on a continuous integration server.
Robustness testing
In this context, a robust system is such that if it is subject to a constant load for a given amount of time, its response is correct and its throughput is constant.
The aim of a robustness test is to identify design or development issues such as memory leaks or random/unfrequent bugs that over time may degrade or crash the system. It's worth pointing out that robustness tests differ from load or stress tests which aim more at identifying bottlenecks or actual system limits (responses to peaks or bursts).
Continuously test for robustness is hence a must to improve the quality of the system under construction.
I, Robbie and Raghav presented a session at Agile '08 and XPDay 08 on this very topic.
Specifically for robustness, a test is defined by running scenarios concurrently. A scenario is a set of operations on the system that emulate typical usage. Our examples at both the presentation were based on the robustness tests we built for Aloha, an application server for Voice over IP applications. In this context a scenario - typical usage of the system - is for example "Connect voice call between two participants" that translates into a sequence of simpler operations performed via the application server's public interface.
Robustness with JMeter
When preparing the XPDay presentation, I started musing with JMeter to see if it offered simple means to build robustness tests. The bare essentials i was looking for are
- the possibility to build scenarios in relation to the system under test (given the above definition of scenario)
- automate tests and run them from a continuous integration server and
- the possibility to report on the outcome of the tests.
As I have been involved in building REST APIs for several months, I chose to experiment assuming that the system under test offered a REST exposure.
Scenarios
In JMeter robustness scenarios can be modeled as ThreadGroups. A ThreadGroup groups a set of sampling operations on the system under test. Each sampling operation is executed serially within the thread running the ThreadGroup and each ThreadGroup can be run in loop and in parallel with other ThreadGroups for as long as necessary, either terminating them after a fixed number of runs or after a given time.
All the goodies shipped with JMeter can be used like pre/post processing instructions, definitions of user variables, throttling, etc. (see JMeter manual for more).
The following picture shows a simple test plan for a system under test with a robustness test made of 2 scenarios: "Register customer" and "Place an order". For the "Register customer" scenario, the ThreadGroup will be run in 10 parallel threads and each thead will run in loop for 100 times (so, in toal, the system will be running 1000 scenarios).
Sampling REST resources
JMeter offers a wide selection of samplers for sampling systems and collecting results. It does not offer, though, a proper sampler for the definition of REST requests. In the spirit of readable tests for documentation I wanted each sampler (effectively a REST request) to look like a REST request with a URI, method, list of headers and a body (much in the spirit of the RestFixture). So I discarded the HTTP sampler as too bound to HTTP requests.
So the first stab was to build a new sampler: the REST Sampler. It allows to define a rest request by setting all the relevant parameters: the URI, the headers, the body, the verb. It also processes JMeter assertions and post processors (attached as chidren to the sampler node) to perform basic assertions on the response elements and, for example to extract data from the last response and store it for future reference.
The REST sampler
Asserting the response code of the last response
Extracting data from the response for future reference, via JMeter variables
Monitoring the remote system: JMX Sampler
As said, part of a robustness build is to observe the system under test for key indicators of the health of the system. If the system under test is built in Java, one key element is the amount of heap memory allocated by to the system at any point in time: the trend of the average value of the heap memory may spot memory leaks. To grab this data in the context of a robustness test via JMeter, I have added a JMX Sampler, which basically connects to the given JMX URL and retrieves Heap memory information.
Next, I wanted to present the information collected. If JMeter is run via GUI, a JMX listener can be added to gather and chart the memory data.
It's possible to add more than one JMX sampler pointing to different JMX servers in such cases when the REST application is distributed. Charts of each Heap memory usage are displayed in the same listener window. Also, the charts can be saved in one or more files if needed.
Test Automation
The REST and JMX samplers plus the JMX listener can be used to build robustness tests necessary to test systems exposing REST interfaces. The next step is automation.
Automation is achieved with Ant and the JMeter task, which allows to run the same test plan but from whitin an Ant task (hence invokable via any Continuous integration server). Documentation on how to use the JMeter ant task is available in the website.
I, though, thought to extend the task to generate charts using the data available in the JMeter result output file. The Charts generated are one for the time occurred for each of the rest requests (which gives an indication on how the performance of the system are degrading overtime) and one for the JMX sampling as detailed above.
<taskdef name="jmeter"
classname="smartrics.jmeter.ant.JMeterTaskExt"
classpathref="project.classpath" />
<target name="run" depends="clean, init, copy">
<jmeter jmeterhome="${jmeter.home}"
resultlogdir="${artefacts}"
failure="false"
failureproperty="jmeter.failed"
chartsoutputdir="${artefacts}"
succecssThresholdPerc="98"
jmeterproperties="${jmeter.home}/bin/user.properties">
<testplans dir="${build}" includes="Robustness.jmx" />
</jmeter>
</target>
<target name="report">
<xslt in="${artefacts}/Robustness.jtl"
out="${artefacts}/Robustness.html"
style="${etc}/jmeter-results-detail-report_21.xsl" />
<copy todir="${artefacts}">
<fileset dir="${etc}" includes="*.jpg" />
</copy>
</target>
The location where the files are generated is defined by the attribute chartsoutputdir="...", if omitted no chart will be generated.
Correctness and the failure threshold
In certain cases a build may be allowed to pass even if some of the assertions did not pass. Such behaviour is admissible in systems that implement, for example, optimistic locking or other mechanisms that trade correctness for performance. Each REST sampler flags the sample as sucess or failure depending on the result of each associated assertion. By counting such flag values it's easy to determine the percentage of successes.
If the Tester decides that failure is acceptable, she can specify the succecssThresholdPerc="..." attribute to define the minimum percentage of successes that need to happen in order for the build to pass.
Build and isntallation instructions
Build
The JMeterRestSampler is available here:
http://github.com/smartrics/JMeterRestSampler
After checkout, add a properties/${user.name}.properties file and define the jmeter.home property. Then run ant.
${user.name} is the username of the logged in user.
If the build passes the file build/JMeterRestSampler.jar is generated.
Install
Edit the ${jmeter.home}/bin/user.properties and set the searh_paths property to the location of the JMeterRestSampler.java file: search_paths=/path/to/JMeterRestSampler.jar. Alternatively, copy the JMeterRestSampler.jar in the directory ${jmeter.home}/lib/ext.
If installation is successful, when starting JMeter, the Rest Sampler and JMX Sampler should be available in the Add/Sampler ThreadGroup context popup menu.
Eclipse project
The .classpath and .project Eclipse metadata files are included. To successfully compile the project within Eclipse, once imported, you need to define two workspace variables JMETER_HOME and ANT_HOME to respectively point to your JMeter home and Ant home directories.
License
The software is licensed using a BSD license.
Disclaimer
I should point out that the JMeterRestSampler is no more than a toy to prove the concept of Robustness testing via JMeter. It started as a spike back in the days of XPDay 08 and evolved - slowly - to it's complete form. I am not intentioned to improve it in the foreseeable future.
47 comments:
Thanks man, exactly what I was looking for, works a treat!
Note that I had to build with JMeter 2.3.2 as the latest version (2.3.3) has api changes.
Exactly what I was after - good work dude!
Only problem so far was that the repo URL had changed:
http://rest-fixture.googlecode.com/svn/trunk/JMeterRestSampler
Cheers, and happy RESTing
Al.
I'm a noob.
I can't build it!
@Anonymous
> I'm a noob.
> I can't build it!
let me know if i can help
I am unable to build with the most recent Jmeter 2.3.4 do you have a fix for this yet?
I think about improving the rest jmeter plugin. Can I extend your project or do you prefer a fork?
What ever you would prefer. Any help would be appreciated.
Thank you
Jan, I am going to move the JMeterRestSampler in a separate svn repo and pass on the details.
Jan, The code is now available here
http://code.google.com/p/jmeter-rest-sampler/
get back in contact with me for arrangements
Hi Smartics.
Thank you for this project, very helpful.
With jmeter 2.3.4 the porject can't be complied due to changes in the "SaveService.loadTestResults" signature.
Any ideas how to handle
Thanks
Doron
Hi DonHas, thanks.
I haven't tryed recompiling the sources with the latest version of JMeter. Looking quickly at the source code of JMeter 2.3.4, there's a call to loadTestResult in this file
src/core/org/apache/jmeter/reporters/ResultCollector.java
you can attempt to fix the code from there. Jan (who commented above) seems to have fixed it. I will get back in touch with him and see if I can get a fix for this.
Will post on the blog if I succeed.
Thanks for your reply,
There another issue that you might help me to solve.
For my rest tests I'm posting data to rest server, in order to debug my code I'm using "View Results Tree" however the "post data" section is always empty.
Any ideas how can I fixed it.
Thanks
Doron
Hi,
can anyone upload the .jar for the REST sampler in code.google.com?
Thanks,
Marcos
Hi,
Even I am facing issues with the loadTestResullts() method signature. Does anybody have the code changes required?
Appreciate any help on this..
Thanks..
Hi,
That for this, this is was I needd. I'm running on the same compilation as everyone. Is the cmpliled jar is available from somewhere ?
How can i post a json body using Rest Sampler.
I looked at DataEtractor.handleResults(). And then I stared at it for some more time. Still no epiphany! Ok ok I'm a noob. Any help/idea would be mightily appreciated. Please!?
-syd
i have not find rest sampler in list of samplers .
Has anyone figured out loadTestResult yet?
Thanks in advance,
Andrew
I'll look at the compatibility issue with the newer JMeter and post a fix ASAP
That would be awesome. Looking forward to it as we have to use JMeter 2.3.2 with that to work.
Thanks a bunch,
Andrew
The code has been moved here http://github.com/smartrics/JMeterRestSampler
I have patched it to work with JMeter 2.3.4
The fix for JMeter 2.4 isn't as straightforwad, so I'll look into it when i have some time, sorry
Hi Guys,
Thanks for such a good plugin.
I dont know wheather it is a right place to ask this question. Please forgive me if this is not the right place to ask a question. I am new to Jmeter.
I want to store the result as it comes in 'View Results Tree' listners in different files like it comes in 3 different panel Sampler request, request, response data.
Can some one please suggest me how can I achieve this.
Please help me if any has got any knowledge about this.
Hi, I am not sure you can do that. The only way I see is to post process the results file and extract the data manually.
Thanks for the reply smartrics.
Great plugin, thanks a lot.
When I look at the results in my View Results Tree listener, the Request tab doesn't show the request body that was sent to the server. Is this something you've seen as well?
I ended up writing a small patch to restore this functionality, let me know if you are interested in merging it into your code.
@Lauri, yeah no problem . Ideally a pull request on github would be better... otherwise however you prefer.
Hello
I just downloaded the JMeterRestSampler, but seems to be unable to build it. Can somebody please help. I get the following error:
$ ant
Buildfile: C:\jakarta-jmeter-2.4\RESTfulservices\smartrics-JMeterRestSampler-c46ed7d\JMeterRestSampler\build.xml
clean:
[delete] Deleting directory C:\jakarta-jmeter-2.4\RESTfulservices\smartrics-JMeterRestSampler-c46ed7d\JMeterRestSampler\build
init:
[mkdir] Created dir: C:\jakarta-jmeter-2.4\RESTfulservices\smartrics-JMeterRestSampler-c46ed7d\JMeterRestSampler\build
compile:
[mkdir] Created dir: C:\jakarta-jmeter-2.4\RESTfulservices\smartrics-JMeterRestSampler-c46ed7d\JMeterRestSampler\build\classes\main
[javac] C:\jakarta-jmeter-2.4\RESTfulservices\smartrics-JMeterRestSampler-c46ed7d\JMeterRestSampler\build.xml:28: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 21 source files to C:\jakarta-jmeter-2.4\RESTfulservices\smartrics-JMeterRestSampler-c46ed7d\JMeterRestSampler\build\classes\main
BUILD FAILED
C:\jakarta-jmeter-2.4\RESTfulservices\smartrics-JMeterRestSampler-c46ed7d\JMeterRestSampler\build.xml:28: C:\jakarta-jmeter-2.4\RESTfulservices\smartrics-JMeterRestSampler-c46ed7d\JMeterRestSampler\lib does not exist.
Thanks for all your help.
TesterInDenver
TesterInDenver, good spot!- it's a bug in the build file. I have fixed it now and just commited. So one of the following two: either make the lib directory manually as sibling of the src (same dir as where the build file is) or fetch/download the code again.
Hello
For some reason, the Rest sampler puts a space after the first ":" in the Authorization Header. The header has the following information: Authorization ${authString}. When I replace the colons with a (i.e. ";", there is no space. Since the sessionID is an in-house development effort, the Authorization Header must include the colons. Is there a workaround?
Here is the string I need to create:
Authorization Basic 2:1307334312:9bf77a1d388d5b403d3383be4b11df00. Notice no space before or after the colons ":".
Here are the variables via debug sampler:
newDate=1307334312
newDate2=1307334312
s=239erx487ysSkUA2dLkd7sySX
timehash=9bf77a1d388d5b403d3383be4b11df00
Here is the output:
Authorization Basic 2: 1307334312:9bf77a1d388d5b403d3383be4b11df00. Notice the space after the 1st colon. When I change the 1st colon to a different character (i.e. ";"), the space is inserted after the second colon. What is the uniqueness of the ":"? I need to use a colon as a delimiter between the fields.
I have the following beanshell script:
String authString = "Basic 2" + ":" + "${newDate2}" + ":" + "${timehash}";
vars.put("authorizationString",authString);
@Anonymous - not sure if I understand the problem correctly.
if it's an HTTP header you are talking about, the space after the colon is inserted by the HTTP client as per HTTP spec http://www.w3.org/Protocols/HTTP/1.0/draft-ietf-http-spec.html#Message-Headers
I can think of various solutions. here they follow in no particoular order
1- put : at the beginning of your Auth token or
2- make the parser on the server a bit more flexible (to ignore spaces) or
3- inject between JMeter and the server a proxy that re-writes the request (Apache can do that!)
4- patch/shadow httpclient
5- mod the sampler to use a different http client that does what you need
hi,
this looks great, also i succeeded in compiling and building the jar and add the relevant sampler, but I see no result in the listener, am i missing something?
10x
hi Oded, it's likely that you're using a newer version of jmeter which is not supported.
i can't support this project anymore; but i found on github forks that have been fixed to work with later version of jmeter.
check this out
https://github.com/smartrics/JMeterRestSampler/issues/1
Can someone tell me where I can put parameters and how to put parameters to rest. I want to send following param-
'{"display_name": "xyz","service":"ordred"}'
Hello Smartrics
I got your Code from https://github.com/smartrics/JMeterRestSampler as a Zip File as my Git is showing error in cloning but as i am trying to build the code i am getting this error ..
C:\PETools\jakarta-jmeter-2.3.2\JMeterRestSampler>ant
Buildfile: build.xml
clean:
[delete] Deleting directory C:\PETools\jakarta-jmeter-2.3.2\JMeterRestSampler\build
init:
[mkdir] Created dir: C:\PETools\jakarta-jmeter-2.3.2\JMeterRestSampler\build
compile:
[mkdir] Created dir: C:\PETools\jakarta-jmeter-2.3.2\JMeterRestSampler\build\classes\main
[javac] Compiling 21 source files to C:\PETools\jakarta-jmeter-2.3.2\JMeterRestSampler\build\classes\main
[javac] C:\PETools\jakarta-jmeter-2.3.2\JMeterRestSampler\src\main\java\smartrics\jmeter\ant\DataExtractor.java:24:
cannot find symbol
[javac] symbol : class ResultCollectorHelper
[javac] location: package org.apache.jmeter.reporters
[javac] import org.apache.jmeter.reporters.ResultCollectorHelper;
[javac] ^
[javac] 1 error
BUILD FAILED
C:\PETools\jakarta-jmeter-2.3.2\JMeterRestSampler\build.xml:25: Compile failed; see the compiler error output for detail
s.
Total time: 1 second
C:\PETools\jakarta-jmeter-2.3.2\JMeterRestSampler>
I changed the Jmeter home path at properties\user.properties and build.properties also. Is still i am missing some thing?
Please Help me to resolve this .
I appreciate your help in this regard.
Thanks
Adity
Hi, please try JMeter 2.3.4
Also please use github issue tracking to report any issue
Thanks a Lot , I used Jmeter 2.3.4 and its working for me . Thank a lot u save my lots of time to write a Script for providing the load to Rest
how can we get the result of REST sampler ?
Hi Cannizzo,
how can I check the sampler works correctly?
Hi Smartics,
I've added the .jar file from code.google.com, when i start the Jmeter and add parameters into the restsampler, i get the following error. I'm using 2.6 version of Jmeter. can you please tell me if the JMeterRestSampler_for_JMeter2.3.4.jar is specific for 2.3.4 only?
2012/05/15 15:49:15 ERROR - jmeter.threads.JMeterThread: Test failed! java.lang.NoSuchMethodError: org.apache.jorphan.util.JOrphanUtils.closeQuietly(Ljava/io/InputStream;)V
at smartrics.jmeter.sampler.RestSampler.sample(Unknown Source)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1054)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1043)
at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:416)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:271)
at java.lang.Thread.run(Thread.java:680)
@deepti - it works with 2.3.4, I have never tested it with higher versions, so it may be that it won't work.
Thank you Smartics. it works with 2.3.4 for me too.
Thank you for plugin, I've forked your repo to try it.
JMeter is rather good tool, but its main disadvantage is that its reporting tools are not very descriptive. And it makes to use third-party JMeter plugin to have better graphs.
Help to use CSV file for dynamic RESTful service testing in JMeter. The XML file mentioned in the path in the HTTP Request screen need to have dynamic value. I used like ${customerOrder} . customerOrder is used in the CSV Data Set config.
thanks
Abhijit
Abhijit - i am not supporting JMeter Rest sampler; sorry.
Post a Comment