Unique variable for each run of a thread - jmeter

I've got a jmeter script to test a user journey through a number of forms.
Ideally the email address for each journey would be unique but it's proven difficult to achieve this.
I have a user defined variable for email;
${__V(${__UUID()}${__RandomString(20,abcdefghijklmnopqrstuvwxyz,)}_jmeter#my-co.com)}
Then a BeanShell PreProcessor to create a uniqueID;
int threadNo = ctx.getThreadNum()+1; //to get the thread number in beanshell
int base = 35000;
int uniqueId = threadNo + base;
vars.put("uniqueId", Integer.toString(uniqueId));
Finally, in the POST data I've been defining;
_${__threadNum}.${uniqueId}.${Email}
However if I want to run a long test, the threads loop so I believe the thread number is the same, so the email doesn't change. Or at least the 403 errors seen during longer tests suggest that.
Can the loop count or some other identifier be used on the uniqueId or in the data for the POST perhaps?

You can use the following:
vars.getIteration() - to get current loop number (on Thread Group level)
Counter element or even better ${__counter(FALSE,)} function which will generate incremented number each time being called. See How to Use a Counter in a JMeter Test for details.
However HTTP Status Code 403 stands for "Forbidden"
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated.
If the request method was not HEAD and the server wishes to make
public why the request has not been fulfilled, it SHOULD describe the
reason for the refusal in the entity. If the server does not wish to
make this information available to the client, the status code 404
(Not Found) can be used instead.
so your problem seems to be connected with something else

Related

How to loop a sampler in a thread group in Jmeter until a specific response value is returned

I have to performance test an application which does a PDF to PNG image conversion. For that, I have 3 requests to be sent, ie, 1 POST and 2 GET requests. My requirement is to measure the performance of one the GET request which does the conversion part and downloads the converted PNG file. Note that this GET request that download the image is dependent on the other POST and the GET request which checks the status of the job. The full work flow in a nutshell is as follows:
Send a POST request to trigger a job to generate a unique identifier string.
Using the string value generated in step 1 above, the GET request checks the status of creation of a PDF document. Since this process has dependencies, the GET request polls until a status of 'Complete' is returned in its response. If the response status is not 'Complete', then we have to retry this GET request.
And finally, once the response from step 2 is returned as 'Complete', the GET request to convert the generated PDF to PNG image has to be triggered.
So 3 requests above are dependent to each other and has to run sequentially as the input for one is the output of the previous request. So we have to run this in the same order (1__> 2 --> 3) for the entire duration of the performance test.
I have tried using the While controller, however, the issue I am facing is, the sampler inside the While controller (ie GET request in step 2 which checks the status) is getting executed only for a limited number of times and not for the entire test duration.
The jmx file I have created is as follows:
Test Plan{
Thread Group{
POST Request sampler{ //step 1
//stores unique string response to variable
}
User Defined variable (initialize a Status variable to null string, initialize a counter variable)
While Controller(condition '${__javaScript("${Status}" == "" && (${counter} < 4),)}')
{
GET Request Sampler { //step 2
Regular expression extractor to get the status from response and store to variable
}
JSR223 Post processor { //to check if the status value = 'Complete', otherwise set status back to null string
/*
String status = vars.get("labelStatus")
if(status.equals("Complete")){
log.info("Label Status is Complete");
}
else{
vars.put("labelStatus","")
}
*/
}//end of JSR223 post processor
}//end of while loop
GET Request sampler to download the PNG image //step 3
} // end of Thread Group
}//end of Test Plan
screenshot of my Jmeter script:
Ideally for each POST request I make (step 1), there should be a corresponding GET request (step 2) which checks for a particular status in response. If the response contains the matching text, then have to exit the while loop and continue with the next sampler (ie GET request in step 3 above) in the thread group. This needs to be repeated in each iteration.
As per your While Controller condition its children will be executed while ${Status} variable is empty or 4 times, whatever comes the first.
I fail to see where do you update the value of the ${Status} variable, it might be the case you made a typo and need to change it to ${labelStatus}?
I would recommend using Debug Sampler and View Results Tree listener combination in order to check the values of ${labelStatus} and ${counter} variables for each While Controller's iteration
Also pay attention to JMeter Scoping Rules as your last JSR223 PostProcessor is being executed after every sampler in the Thread Group and this is something you might want to change.

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

Link variable to data set in JMeter

I'm using JMeter 3.2 to create some performance tests.
I have a set up where a thread group has multiple threads (users) which perform multiple loops requesting a resource, form a server, every time.
Each of the threads go through an once only controller which retrieves a token from a server, which identifies the user, and is required on all subsequent requests. The token is different every time it is generated, I cannot store it in a data set (csv) as it would later be invalid.
I have a data set (.csv file) containing username and password of my test users.
So far so good.. Now the threads need to request a resource on the server requiring the token to be sent. It goes well the first time, but the second time it starts messing up. It seems like each iteration uses data from the next row in the dataset, but the token retrieved (from the once only controller) is not linked to row of data (username and password) used, so something like this happens:
thread1: data1/token1 - good
thread2: data2/token2 - good
Perhaps thread2 finishes first and starts the new iteration:
thread2: data1/token2 - error
thread1: data2/token1 - error
So my question is: how can I link the token retrieved to a row in data set (as a variable), so that the correct token will be sent every time that piece of data is used for a request?
Edit
I have an idea. Creating a Hashtable with some data, from the data set, as key and the token as value, but I have some issue. I've created the following code:
import java.util.Hashtable;
map = new Hashtable();
vars.putObject("map", map);
but it cast the following error:
java.util.Hashtable cannot be cast to java.lang.String
I finally figured it out, though it might not be the most optimal solution. What I did is to create a property (variables won't work), which is a JSONObject. In this I can store an id (for my data) and the token linked to it. I transform it to a string and store it in the property.
In a preprocessor to the http request requiring the token I retrieve the property and parses it back to a JSONObject and can look up the token using the id.

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 Script-Error Message in Response Data but Successful result in sample Result

While running Jmeter scripts, one of the step is failing but Successful Result is coming in Sample Result as:
Sample Count: 1
Error Count: 1
Response code: 200
Response message: OK
But error message is coming in Response Data as:
Unfortunately, we could not delete your entire itinerary because of a database synchronization error.
If you could please re-load your itinerary and try again, we would appreciate it.
Thank you for your patience.
I need to re-submit the Request for that i am using the While loop comparing the Response Data then try to resubmit the request which is not working as.
if(ResponseData.equals("Unfortunately")==true)
{
log.error("Database synchronization error...Re sending Request");
vars.put("resubmitflag","true");
}
The problem i believe that i am not using correct functions for it as
ResponseData.equals will not work as how we can compare whole response data
which is not possible.
Kindly anyone help how to proceed and what functions need to use for that.
If you're talking about Beanshell Post Processor, there are a couple of issues with your code.
ResponseData isn't something, which is available to Beanshell Post Processor. You need either use data (which is byte array previous sampler response representation) or prev (which stands for SampleResult class for previous sampler).
equals method checks 2 strings for being identical. In your case you need to consider either startsWith or even contains method.
See following code samples for reference
String response = new String(data);
if (response.contains("Unfortunately")){
log.error("Database synchronization error...Re sending Request");
vars.put("resubmitflag","true");
}
or
String response = prev.getResponseDataAsString();
.....
See How to use BeanShell guide for more details.
Hope this helps

Resources