I have a thread group, which runs multiple threads concurrently.
Each thread makes a request using an ID from a csv file.
So different threads within the thread group can end up making a request with the same ID over time.
I want to use the cookie that is returned, for the specific ID in the request, even though its made by a different thread.
At the moment I have a Regular Expression Extractor pulling the cookie value, which created a variable based on its ID, for example, where ID is 56789 and the cookie is 1234, the variable would be 56789_1234.
I then use ${__V(${id}_g1)} to pull the cookie, associated with a specific ID for another request.
(Essentially a bunch of variables are created, prefixed with the ID and the last returned cookie value, and each subsequent request can then use the ID for its request to pull out the correct cookie)
And then create the cookie as so:
import org.apache.jmeter.protocol.http.control.CookieManager;
import org.apache.jmeter.protocol.http.control.Cookie;
CookieManager manager = sampler.getCookieManager();
Cookie AWSALB = new Cookie("AWSALB","${cookieVal}","domain","path",false,Long.MAX_VALUE);
manager.add(AWSALB);
(I assign ${__V(${id}_g1)} to 'cookieVal' using jp#gc - Set Variables Action)
However, I still cant share the range of variables that are being created amongst all threads.
I've tried properties, but I believe it only works between Thread Groups, and if the groups run consecutively.
I'd like all threads within the group to be able to read all the variables extracted by other threads.
You can "stick" each thread (virtual user) to its own ID (or set of IDs from the CSV), i.e. use separate files for each user and __CSVRead() function or single file and __groovy() function to read the values
If you still want to continue with your approach take a look at Inter-Thread Communication Plugin which provides a FIFO queue
Another way is using JMeter Properties if form of name-value pairs of ID=cookie_value, if there is no cookie value for the ID - write the value into the property, if there is - read the value from the property instead of requesting a new cookie
Although trying properties, I didn't seem to get it to work. Even though the properties were created (as identified in Debug Postprocessor), I still couldn't access them between threads for some reason.
However I solved this by using Beanshell Samplers before and after the request, writing out the single cookie value to an individual txt file per ID, with the txt files name being the ID. Each time any thread makes a request with this ID, it then updates the value in the corresponding txt file, and then before each request, reads the specific txt file for that ID to retrieve the last returned cookie.
UPDATE
As the number of threads increased, so did the possibility of threads becoming blocked when trying to access/write to the same .txt file at the same time.
I switched to using __CSVRead(), which so far has worked well.
Related
Background: I'm using python 3 (with Flask and Bootstrap) to create a website with fields to capture data. There is an API running from a HighQ database to take data from a record, and once the form is submitted, put updated / new data back into the same record in the HighQ database (and also to an SQL database). This is all working successfully.
This is a tool that is being used internally within the company I work for, and hosted on the intranet, so I haven't set up user logins as I want it to be as quick and easy as possible for the team to use this form and update records.
Issue: When two or more instances of the form are being used at the same time (whether it's on one persons computer, or if two people are testing on their own computers) the data submitted from one person's form will overwrite the destination record that the other person has called into their form. I'm struggling to find the solution that ensures each time the form is launched, it ringfences the data so that this does not happen.
I've tried a number of things to resolve this (including lots of stackoverflow searches):
Originally I used global variables to pass data across different routes. I thought the issue was that everyone launching the form could access the same global variables, so I changed the code to remove any global variables, and instead used a combination of taking content within each of the fields in the site, and saving it as a local variable within the route I needed it in, and for any variables that were not obtainable from a field, I saved them to the 'session'.
The problem is still persisting and i'm now at a loss on what to try next. Any help on this would be much appreciated.
Currently I'm facing this issue after implementing SecurityManager. A simple gist of what I did was, create an object with populated values if an user logins. If another user logins, I would overwrite one specific variable in the previous user's object. Then I proceed to stop server and starts it again. When I check through pulse, my two objects are there as expected but that one specific variable reverted to its initial value before the second user logins. It's the same for subsequent users. Any helps are appreciated.
Requires region.put(retrieved object's key, the retrieved object) back instead of just object.setVariable().
I have a Thread Group wherein I have three samplers. They are HTML Requests. The first one returns a person and gives me the name, age and address. The second one changes the attribute name of the person but has no response.
The third sampler is the same as the first.
The second sampler isn't working and doesn't change the name.
I want a failure message like: "The name of the person was $(name1) and should be changed to $(name2), but the name is $(name3)" or something like that.
I do the whole things with Groovy so is there any way to generate variables with the output of the first and third request and the input of the second?
Most probably you're looking for Response Assertion, you can conditionally mark samplers as failed depending on various criteria. It might be the case that you won't even need scripting like.
Just add Response Assertion as a child of 3rd request and configure it to expect ${name3} variable to be present in the response (you can use Perl-5 style regular expressions for this as well) and if the name will not be present - the sampler will get failed and you will see the relevant failure message
More information: How to Use JMeter Assertions in Three Easy Steps
I do not think you can do it the way you describe it, because samplers are processed sequentially, so you can not process first, third and go to second request. You might want to re-evaluate your approach.
I'm currently busy with an test automation project for mobile devices and I want to store my results in a database.
I do this with a custom assertclass which I created, this one stores the result.
The layout is as following -> There are runs which contain Tests which contain Steps.
When I want to run in parallel, I create a unique id for the run based on thread and date and store this one in a static list. This is #BeforeTest.
At the #BeforeClass, I search in the list for the right thread and assign the correct name to the variable of the class.
But I receive constantly a Nullpointerexception for the list in the beforeclass or the variable is null while it was filled in in the #beforetest.
What are we missing here? Or how is this done when you need to store a parameter that is generated once for the whole run?
Thanks in advance,
Jonas Vandevelde
I have a scenario. I have a list of user id's displayed on the windows form. As soon as I click one of the user id's I go and get the user details from the DB. To retain the responsiveness of the application, on selection changed event of the listbox, I create new BackgroundWorker(BW) objects and hit the DB. I show 'Searching user 'abc'...' in the status bar.
Now, if the user moves between the user ids using arrow keys (4-5 times), by above design I have created multiple BW objects to make the request. But finally when the data comes back for particular user (which may not be the one where user is currently selected in the listview), since it was async call, I still end up displaying all the users in the status bar.
What I would like to do is, I want to go and get the details only for the last user. Till that time I want to display 'Searching user...' only.
Please let me know solution for this...
When the user switches users, you can cancel the worker processes that are currently running (check to make sure they are running). I believe that would accomplish what you are after.
How about waiting for a second or two before you start your Background Worker?
Once the user clicks on a user id, start a timer with 1 second interval and after that one second, start your BackgroundWorker. If user clicks on a different user id, reset the timer. This way, if user keeps clicking on different user ids in quick succession, you won't do anything. Once user has taken a break, you start your background worker.
One option would be to keep a string field in the form containing the user ID. In the background worker, after you hit the DB, check that this field is still equal to the user ID that it got passed in, EDIT: and, if it's different, make the result null. Manipulate the field using the methods on the Interlocked class to avoid the need to lock. That's wrong; reference types can be read and written atomically with Interlocked.
2nd EDIT: You could also return the original user ID from the background worker along with the result, and check that it's the most recent one clicked in your Completed handler.
Alternatively, if you're keeping references to all of the BackgroundWorkers, you could use their cancellation support.
I've used this to cancel BackgroundWorkers before and it worked great.
public void cancelWorker( BackgroundWorker worker )
{
if (worker != null)
{
if (worker.IsBusy)
{
worker.CancelAsync();
while (worker.IsBusy)
{
Application.DoEvents();
}
}
}
}
I've heard controversy over using Application.DoEvents(); but I had problems with endless loops if I used Thread.sleep or other.
You might want to use polling of some sort so you don't end up with backgroundWorkers fumbling over eachother - especially if the callback ends up calling something like the UI on a separate thread so they can actually cause race conditions.