How to run the request based on previous request response data - jmeter

I have test plan with following request in sequence with 2 loops.
ApiHttp request
Mqtt request
I need to run 1st loop & verify API reaponse is true or false:
If it's true, run Mqtt request , else start the 2nd loop and same verify the API response, if it's true run Mqtt else stop.
In above scenarios, I put beanshell to read the API response:
vars.put("response", new String(data));
But don't know how to verify of its true or false & execute the Mqtt. Any help pls.

Add If Controller as the very first test element under the Thread Group and use the __groovy() function as the condition:
${__groovy(vars.getIteration() <= 2,)}
Put ApiHttp request as a child of the If Controller
Add another If Controller after the ApiHttp request and use the following __groovy() function as the condition:
${__groovy(ctx.getPreviousResult().getResponseDataAsString().contains('true'))}
Add Mqtt request as a child of the If Controller
Add Flow Control Action sampler after the Mqtt request and configure it like:

First switch from Beanshell to JSR223 Test elements and use Groovy.
Use If Controller and just put in it:
${response}
To stop the test based on iteration number, be aware that a Loop Controller exposes iteration as a variable based on name of variable, for example if your LoopController is named LC, then you can access iteration as:
vars["__jm__LC__idx"].toInteger()
And to stop a test from Groovy using JSR223 Assertion you can throw:
throw new org.apache.jorphan.util.JMeterStopTestException();
See:
https://jmeter.apache.org/api/org/apache/jorphan/util/JMeterStopTestException.html

Related

Is there anyway to hold response until we get full response from server in Jmeter?

The services I'm trying to test, will work on long pooling method.
They won't give results in first response.
When I run my API script I am not getting full response in first time.
How can I wait in this case for the remaining portion of response to be received?
I want to use values from this response into next call..
In the above screen my response should wait when complete:True
As far as I understand your requirement you need to repeat the Gethotels request until complete attribute becomes true.
In order to accomplish this:
Add a JSON Extractor as a child of the Gethotels request and set it up as follows:
Put your Gethotels request under the While Controller and use the following __jexl3() function as the condition:
${__jexl3("${complete}" != "true",)}
That's it, While Controller loop the Gethotels request until complete becomes true

JMeter: Polling for a simple HTTP request

please could you give me an example on how to use a while loop to keep checking (polling) if my HTTP GET request (REST api call) has returned the successful response or not. Say for example, third attempt brings the successful response and I come out of the loop, How do I measure the time it has taken?
Please use While controller:
1) init counter JSR223 Sampler --> vars.put("counter","1");
2) while controller
3) inside while controller put your HTTP get
4) put a regex to retrieve what you are looking for (or JSON extractor)
5) Another JSR223 Assertion to check the result of what you retreived
if(!detail.equals("REGEX_FAILED")){
......
}
7) timer so you wait
8) increment counter

jMeter - Re-use response data in follow-up requests

We have a service that works the following way:
First, a request with search parameters is sent, for which we get back a searchId. This searchId is then used to continue fetching information until service response it has no more data left (hasMore parameter becomes "false").
The question is this - I have set up jMeter to send first requests, but not certain how then to keep sending requests in parallel for each response in the Thread Group, and need your advice on it. My thought was to set up another Thread Group since I cannot set it inside the first one, but then how do I get access to responses and process them in parallel?
EDITED:
This is what I ended up with. First Beanshell Sampler extracts searchId and hasMore and puts it into vars. Second Sampler extracts hasMore and again puts it into vars, overwriting the first. At the end, the While loop worked as intended, using ${__javaScript("${hasMore}" == "1",)}.
I would recommend designing your test as follows:
Request to get searchId
While Controller with condition like ${__javaScript("${hasMore}" != "false",)}
Request to continue to fetch information
PostProcessor to extract hasMore parameter and store it into the relevant JMeter Variable
This way "fetch information" requests will be executing until hasMore parameter becomes false. See Using the While Controller in JMeter article for more details.
I suggest 2 Thread group
First Thread group:
Save searchIds in file (JSR223 Sampler) or database (JDBC Sampler) with key as counter (1,2,...) and value as the searchId value
Save a number of IDs in property ${__setProperty(threadCount,${counter})}.
Second Thread group:
In definition - Number of thread use ${__P(threadCount)}
Read from file (JSR223 Sampler) or database (JDBC Sampler)
using ${__threadNum} as key get the relevant searchId you need

JMeter- Sending one email for multiple http responses

I am using csv for http requests and sending emails in case of failure. Can I send only one email at the end of http requests from csv file. Like if 10 http request failed then I want to send a single email containing urls of all pages for which response was 404 or a failure response returned by server. Image Attached
Add JSR223 Listener to the main Thread Group
Put the following code into "Script" area:
if (!prev.isSuccessful()) {
StringBuilder builder = new StringBuilder()
def failures = props.get("failures")
if (failures != null) {
builder.append(failures)
}
builder.append(prev.getUrlAsString())
builder.append(System.getProperty("line.separator"))
props.put("failures", builder.toString());
}
Add tearDown Thread Group with 1 virtual user and 1 loop to your Test Plan
Add If Controller to this tearDown Thread Group
Use ${__groovy(props.get("failures") != null,)} as the If Controller's condition
Put your SMTP Sampler as a child of the if controller
Use ${__P(failures,)} in the mail body - it will hold failed samplers URLs.
Assuming above configuration JMeter will send only one email with the list of all failed samplers URLs and only if any sampler has failed. Feel free to amend the code as required.
References:
__P() function
__groovy() function
Groovy is the New Black
I made it simple and moved SMTP Sample under tearDown ThreadGroup and attached Aggregate Report with Email which contains all information which I want to send in email.
Also In Aggregate Report I selected option that show only Errors which made this report more concise.
Thanks for Answers. #Dmitri T
If anyone having issue feel free to consult.

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.

Resources