Sunday, November 28, 2010

JMeter and AJAX - Part III

A four part post on JMeter and AJAX
Part I - A general discussion on why we might not need to worry about testing AJAX on JMETER
Part II - A diversion on creating a sampler that will allow us to synchronize between specific threads
Part III - A simple sample on executing some AJAX requests in parallel
Part III-1 - A diversion on how to use session ids between threads
Part IV - A more complex sample

In Part II we developed a sampler that would let us synchronize selected threads. I split that out because someday I might be tempted to actually write that timer. So lets now try and execute some AJAX requests in parallel. The demo site we will use is http://www.ajaxdaddy.com/demo-dhtml-autocomplete.html (Please don't run extensive load tests against this site - it isn't mine)
The site has an AJAX based autocomplete for countries. Access the site in FireFox, turn on Firebug and type au into the textbox and you can see the AJAX calls being made in firebug

We can see that two AJAX calls are made, one when we typed 'a' and one when we typed 'u' (There is an AJAX design pattern that applies here which doesn't seem to have been followed). So we will access this page and try to simulate two parallel calls.


The Init and Delay Sampler are from Part II. The Init sampler ensures only 1 thread does the initialization bits. The delay sampler has the rest of the code. After the Init sampler we just make all the threads wait so that no threads run before we are ready to begin (so don't use any ramp up time as that would be nullified here). Its essential the sync timer has a count equal to the count of threads in the threadgroup.
The IF controller is used so that only the main threads perform the request to the main page. Recall for 6 threads to run 2 at a time , we have the groups as Thread(1,2) , Threads(3,4), Threads(5,6). The even numbered threads will only be used for the AJAX requests. The Odd numbered threads will be used for the main sample and the AJAX requests. In our case the landing page needs to be accessed by the odd numbered threads. The even numbered threads will skip and land at the delay sampler waiting for their respective soulmates to join them(I'm currently waiting to be reunited with my wife hence the flowery language).
Anyway we have added a Gaussian random timer to allow the odd numbered threads to arrive at different times. When the odd numbered thread does arrive at the delay sampler, it along with its even numbered pair will be released to execute the Make AJAX request sampler (which chooses a word at random from the CSV file we have defined text,assert e.g. a,australia).

Hence two requests will be executed in parallel for the AJAX request sampler. If we had further requests after this we would have added another IF controller(only odd numbered threads) and coded the samples under this. if we wanted 3 requests in parallel we would have to adjust the Init sampler to say we want groups of 3.
Run the test. Though the samples may appear interleaved , note down the sample start times of the groups of threads that were supposed to execute in parallel, they will be more or less the same.

But I have cheated. The samples in parallel didn't really depend on each others data. The AJAX requests were exactly the same , differing in data. The AJAX requests didn't depend on the user's session thereby reducing the complexity of the script.

Lets attempt an example which needs the above. Onwards to Part IV (as soon as I find a good demo!)

5 comments:

Unknown said...

Thank you for posting your fantastic insights on Jmeter!

Shmuel Krakower said...

Hi,
As you said in the last paragraph, you cheated, meaning that each ajax call was made by different thread / user.

What would you suggest to allow few ajax calls to be triggered in parallel?

Shmuel.

Deepak Shetty said...

@Shmuel
The AJAX requests are in parallel. The remaining things I would have to do is
a. Share sessions - this means that the first thread would have to save its session cookie somewhere ( lets say in properties under a naming scheme) where the second thread can read it from and use beanshell to add the cookie
b. have different requests for the second thread which can be done by having different CSV's or even a IF controller

The reason I abandoned this is with the new ability to add concurrent downloading of embedding resources , its probably easier to extend the existing HTTPSampler (to say allow a list of ajax requests or a pattern) and then use the same code of download embedded requests to fetch these URLs)

Anonymous said...

Hi Deepak,

Do you have an idea how to make two different request in parallel under the same unit group instead of two identical request in parallel like in your example?

thanks in advance for your response

Anonymous said...

or how to synchronize 2 different request under 2 unit group (with one thread (to begin... :)?