Is it possible execute some action on thread failure in Jmeter? - jmeter

Let's say I have a Jmeter test which emulate some user login and several more actions. I also have 'start new thread on error' turned on. So in case some user fail - it will just get another user and keep processing the test for specified amount of time.
But I have some periodic calls for authorized user and to emulate them I'll need to use "Inter-Thread Communication" and additional thread group(-s). Basically this works fine in following way - in main thread I do login and fill some FIFO queue with required cookies, and obtain that cookie in another thread group. In that another thread group I do also check one more FIFO queue (that is filled on user logout), and stop that thread if get what I need.
The problem here is when main thread is fail after login. In that case child thread will be executed 'forever', since that periodic call keeps session active.
And the question - is there some possibility in Jmeter to execute some action on thread failure (smth like finally block). Basically I need fill that second FIFO queue either on logout or on thread failure

Add a Beanshell Assertion at the same level as all your requests go. It'll apply to each of the requests and in case of failure you'll be able to do what your need.
Something like:
Thread Group
Login Sampler
Some other Sampler
Some else Sampler
Beanshell Assertion
The example assertion code:
if (!SampleResult.isSuccessful()){
log.info("Test " + SampleResult.getSampleLabel() + " has failed");
// handle the error
}
See How to Use JMeter Assertions in 3 Easy Steps guide for more information on JMeter Assertions.

I also had to logout on sample error which needs something like try-catch-finally. An IF Controller with condition ${JMeterThread.last_sample_ok} and checked Evaluate for all children? as below, satisfied my need in a clean way:
TestPlan
HTTP Cookie Manager
HTTP Request Defaults
ThreadGroup - (continue on error)
HTTP Request - login
IfController - (Evaluate ${JMeterThread.last_sample_ok} for all children)
HTTP Request 1
HTTP Request 2
....
HTTP Request n
HTTP Request - logout (after and outside of IF)

Related

missing items in jmeter result tree

here is structure of my test.
recording controller
transaction controller
homepage (transaction controller)
HTTP Request 1
Response Assertion (response code = 200)
HTTP Request 2
Response Assertion (response code = 200)
HTTP Request 3
Response Assertion (response code = 200)
....
login (transaction controller)
HTTP Request 1
Response Assertion (response code = 200)
....
logout (transaction controller)
HTTP Request 1
Response Assertion (response code = 200)
....
View Results Tree
Test is placed inside Ultimate Thread Group (up to 20 threads at once). I placed into each HTTP Request Response Assertion.
When run the the test and after that look in the result tree everything is green, so OK.
But when I clicked through result tree I recognised, that sometimes some items are
missing, but not every time.
see: for example:
transaction controller
homepage
login
(logout is missing !!!)
Question is why?
With Ultimate Thread Group you don't have fixed number of loops/iterations, so if you specify some "Hold load for" time span and a thread (virtual user) will be shut down "in the middle" of test execution, i.e. somewhere at homepage transaction - it will simply not be able to finish all the remaining requests.
Like
if you set Hold Load For to 1 second - only 1 request will be executed
if you set Hold Load For to 5 seconds - a couple of requests will be executed
if you set it to 5 minutes - most probably all the requests will be executed at least once, but the number of the requests will mostly depend on your application response time
So if you want the whole sequence to be executed - switch to "normal" Thread Group and specify the desired number of iterations
Also using JMeter GUI mode and View Results Tree listener for executing load tests is not the best idea, you should be running your JMeter tests in command-line non-GUI mode and use HTML Reporting Dashboard for results analysis.

Shutting down Threads Groups while finishing all the requests inside the transaction controller

I have a JMeter Test Plan to perform performance and load tests on a SAP Web Client. The Test plan contains 5 Thread Groups.
In each Thread Groups i have a Transaction Controller that contains N Requests where they execute Login - Process - Logoff .
I need to be able to run the Test Plan with 20 users on infinite loop and then shutdown after 1 hour BUT perform the logoff of all the users that are still on the Web Client (Last request on each transaction controller).
As of this moment the shutdown simply stops the test on the active thread, whatever it is, without finishing the Transaction Controller.
Any ideas?
This could be achieved by adding a While controller as a parent controller to the Transaction controllers. While controller should check the duration and exit when the duration is more than one hour.
Outside the While controlled add a Test Action Sampler and configure it to stop the current Thread.
Sample test plan with a solution is available # GitHub
You can introduce a JVM Shutdown Hook to intercept JMeter shutdown and be able to finish the running tasks.
Example implementation:
Add setUp Thread Group to your Test Plan
Add JSR223 Sampler to the setUp Thread Group
Put the following code into "Script" area:
def myHook = new Thread({ ->
try {
println('' + new Date() + '\tShutdown detected, waiting for 5 for logging out')
Thread.sleep(5000)
println('' + new Date() + '\tExiting...')
} catch (InterruptedException ignored) {
}
})
Runtime.getRuntime().addShutdownHook(myHook)
That's it, the hook will be called when you send termination signal to JMeter and there you can put whatever logic you need:

Handling Asynchronous API Call in Jmeter

I am using Jmeter for functional Testing, below is a problem that I am facing and need some help/suggestion on how to overcome that.
I have a thread-group that consists of 2 requests, 1st is API call and 2nd is sending message to Active MQ.
Now the flow is that I need to do first the API call (this will wait for response), then send the message to a particular Active MQ queue and then only I will get the response for the API.
But since jmeter does sequential execution of requests, its get stuck at the API call waiting for the reply and never executes the second part.
I worked on the below solution but even that did not help.
1 Use a parallel controller and put both the API and ACtive MQ call under the same.
2 Add a Timer to the Active MQ call, so that it just did after the API call (2 Sec)
But when I checked in details I see that both the requests are sent at the same time and the timer does not come into effect anywhere.
Any way I can handle this scenario?
Please note I will get a response to the API only when I send message to the particular Active MQ Queue, else it will timeout in a minute.
Your Parallel Controller approach will work, however you need to amend the configuration a little bit, something like:
You could put your ActiveMQ Request under a different Thread Group and use Inter-Thread Communication Plugin for synchronization between threads
You can keep the current setup but replace the JMS Sampler with the JSR223 Sampler and send the message to ActiveMQ programmatically:
Textual code representation for your convenicence:
sleep(2000)
def connectionFactory = new org.apache.activemq.ActiveMQConnectionFactory('your activemq URL')
def connection = connectionFactory.createConnection()
connection.start()
def session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)
def destination = session.createQueue('your queue name')
def producer = session.createProducer(destination)
def message = session.createTextMessage('your message body')
producer.send(message)
connection.close()
For your Problem statement, following design will work.
Use 2 Thread Groups, add API call to first Thread group and Message to Active MQ call to second Thread Group
Add a delay to second Thread Group so that it should not run before first Thread Group
Run Test Plan
Use while controller. It will keep on executing till the desired outcome then the next request will be executed.
Hope this helps.
Update:-
While Loop controller execute its samplers until the condition specified is not set to False. The condition can be any variable or function that eventually evaluates to the string 'false'.
So, you need to specify a variable or function in While Loop, that has value 'true' and becomes 'false' somewhere else in the script. Once it changes to 'false', JMeter will exit the While loop.
For example if you are using a X-Path extractor in your script which have a variable named Status and its value changes from 'Start' to 'Finish' during the execution and you want to execute your script till 'Finish' has not been met, then you can use the expression ${__javaScript("'${imp_Status}'!='finish'",)} in your While loop and it will execute the samplers under While controller till the status = finish is met.
It is sort of polling based on certain condition. In your first API reponse, consider one value to be appear as the condition upon which first api call is successful.
It sounds that you just need to define timeout for HTTP Request,
If you define Response Timeout as 60000 (milliseconds), and it will only wait for a minute and then continue to next request
Connect Timeout Connection Timeout. Number of milliseconds to wait for a connection to open. No
Response Timeout Response Timeout. Number of milliseconds to wait for a response. Note that this applies to each wait for a response. If the server response is sent in several chunks, the overall elapsed time may be longer than the timeout.

How do I resend a sampler upon a failed assertion on JMeter?

I am designing a load test in JMeter.
With the current application that we have whenever a HTTP request is sent, the web server will very occasionally send back a page with a message. To get around this we just have to reload the page. This page could come up for literally any HTTP request.
Is there any way to design a test in JMeter where when a sampler fails, the sampler simply retries?
I'm not sure how I can get a Beanshell sampler to resend a HTTP request.
It is possible via additional Beanshell Assertion
You can re-run arbitrary sampler from the Beanshell Assertion as simple as
ctx.getCurrentSampler().sample(null);
Add a Beanshell Assertion after all other assertions. It matters as assertions are being executed upside-down.
Put the following code into Beanshell Assertion's "Script" area (just change "message" to what your server returns on error.
import org.apache.jmeter.samplers.SampleResult;
if (new String(ResponseData).equals("message")) {
SampleResult result = ctx.getCurrentSampler().sample(null);
if (result.getResponseDataAsString().equals("message")) {
Failure = true;
} else {
SampleResult.setSuccessful(true);
}
}
You'll have only one result recorded.
If assertion passes 1st time - it'll be successful
If assertion fails 1st time and passes 2nd time - it'll be successful
If assertion fails 2 times - it'll be recorded as failed.
For extended information on Beanshell scripting check out How to use BeanShell: JMeter's favorite built-in component guide.
Create such hierarchy:
Thread Group (1 user, 1 second ramp-up, forever)
-While Controller (empty condition = forever)
--Counter (start ā€“ 1, increment ā€“ 1, reference name ā€“ counter)
--HTTP request
---Timer (I prefer constant Timer, responseble for pause betwee retrying)
---BeanShell Post Processor
BeanShell Post Processor should contains(pseudo code):
if(Integer.parseInt(vars.get("counter")>5)
{
prev.setSuccessful(false);
prev.setStopTestNow(true);
}
if(successCondition)
{
prev.setStopTest(true);
}
There is no direct way to achieve it, but I think you can use While controller in conjuction with Regex extractor to resend the failed requests.
Logical flow could be,
1. HTTP request
2. Regex extractor post processor - check response contains failure extract value in msg variable, default is success
3. While controller - run till msg=failure, default value of msg is success
Example screenshot,
Let me know if this works.

How to stop thread If response assertion fails in Jmeter

I want to implement error handling in my script (like textcheck in LR).
Iā€™m able to validate the Text using Response Assertion.
But my question is how to stop the thread if the Response Assertion (text check) fails.
In Thread group, choose Stop Thread under Action to be taken after a sample error. This will stop the test once assertion fails
If you need to limit this behaviour to one request, add a Result Status Action Handler as a child of the request, then set it to Stop Thread

Resources