I have a JMeter script running for x number of users. I want to conditionally close a user thread in a while controller. For example, if my while controller exits for a user thread, I need to stop the thread. Is it possible? Sorry if this is duplicate or a dumb question.
There are at least 2 options on how you can conditionally stop test thread or even the whole test:
Use Test Action sampler in combination with If Controller
Use Beanshell Sampler or PostProcessor and invoke setStopThread method of SampleResult class. See How to use BeanShell guide for example. For reference:
if (condition){
SampleResult.setStopThread(true); // for Beanshell Sampler
prev.setStopThread(true); // for Beanshell Post Processor
}
ctx.getThread().stop() sets the "stop" flag in the current thread, it works anywhere the JMeterContext ctx is exposed.
I have just done and verified it in a complex test script.
Related
I have a scenario in JMeter like if the transaction enters into the if loop controller, then the execution should get stop when the all the requests in the if controller gets completed.
It should not execute the calls which are outside the controller.
How to achieve this case? can somebody suggest an idea?
There are 2 options:
Add Flow Control Action sampler as the last request in the If Controller and configure it like:
Or add JSR223 Sampler as the last request in the If Controller and put the following code into "Script" area
ctx.getThread().stop()
SampleResult.setIgnore()
See Top 8 JMeter Java Classes You Should Be Using with Groovy article to learn what do these ctx and SampleResult guys mean.
That's it, if thread enters the If Controller it will execute Sampler1, Sampler 2 and Sampler 3 and then stop. If thread doesn't enter the If Controller it will execute Sampler 1 and Sampler 4.
In my Test Plan , i have multiple transactions(not related). Is there a way to stop just the current transaction only on a sampler error. If I use the setting to stop thread/ continue next thread , it just drops the thread for each transactions, which is not very helpful for what i want to achieve. Any help please. Thanks
What do you mean by "transaction"?
"Sample error" can be caught by If Controller using ${JMeterThread.last_sample_ok} pre-defined variable as the condition and from there you can:
Add Flow Control Action sampler and use one of below 3 actions:
Or add a Module Controller pointing to a Test Fragment holding the actions which you would like to execute on Sampler's error. See Easily Write a GOTO Statement in JMeter article for more details.
My test plan is as follows:
Thread group
\_..other items
\_While controller (with blank condition)
\_Web socket single read sampler
\_..other items
My problem is, because I use blank condition, the While controller executes till the sampler errors out. So my question is, is there a way to filter out this last sampler? There are no other conditions I can use in the While controller as the number of times the child sampler has to be executed is not constant.
Thanks!
Add JSR223 PostProcessor as a child of the WebSocket Single Read Sampler
Put the following code into "Script" area:
if (!prev.isSuccessful()) {
prev.setIgnore()
}
In the above code prev stands for the parent SampleResult and the setIgnore() function tells JMeter to not to collect the result for the given Sampler.
More information on this and other JMeter API shortcuts: Top 8 JMeter Java Classes You Should Be Using with Groovy
I need to read file once and its result to be processed further in sampler.
My strategy is ThreadGroup--> BeanShell Preprocessor + BeanShell Sampler
My preprocessor should read file once for whole Thread Group and result to be used in Sampler for specific no. of thread.(i do not want to read file for each thread)
I wrote file reader code in preprocessor, now need to use the result in sampler.
Don't use the Beanshell PreProcessor as it will be executed by each thread. Use a separate Thread Group with 1 thread to read the values.
Don't use Beanshell Samplers to create the actual load, in case of more or less severe load it will become a bottleneck.
Use JSR223 Test Elements and "groovy" language for scripting - this way you'll be able to get maximum performance from your code.
Now answers:
int number = ctx.getThread().getThreadNum(); // get current thread number
props.put("value_for_thread_" + number, "foo"); // store some value specific for the specific thread
String value = props.get("value_for_thread_5"); // get value for thread 5
Where:
ctx - is a shorthand for JMeterContext
props - stands for JMeter Properties, an instance of java.util.Properties deriving all the methods and fields, global for the whole JVM instance.
See JavaDocs for aforementioned objects to see what else can be done and Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! guide for instructions on installing groovy scripting engine, scripting best practices and benchmark of Beanshell, JSR223+groovy and Java code.
Use Jmeter variables to store the values you've read, and then use them in subsequent steps. Please note that the pre-processor will run every time your thread loop is executed.
In your beanshell preprocessor, you can store a variable like this:
vars.put("name","value")
and then access it later either as
vars.get("name")
in beanshell, or as ${name} in fields of any other sampler.
Please note that if your preprocessor is part of your main thread group, it will be run every time your thread loops. If this is an expensive operation or values do not change during the run, you might want to use a setup thread group.
I have a test plan in jMeter that requires some parameters that needs to be calculated before running the test. In order to calculate these parameters, I created a JSR223 PreProcessor directly under test plan as seen below.
My problem is PreProcessor seems to run before every request which is not what I want. I need to calculate these parameters only once and use them in testing.
Is there a way to run the JSR223 PreProcessor only once, or should I use another method?
Thanks in advance.
Edit:
As #ubik-load-pack suggested, I tried "setUp Thread Group" as following but variables created in the code was not available under "Thread Group". They were also present neither in the logs (logging is used in the code) nor in the View Results Tree (via Debug PostProcessor)
I also tried "Once Only Controller" which also didn't work, same as above.
For more information here is content of my JSR223 PreProcessor. (Not the whole code, there will be more variables here so using date functions is not a solution for me by the way.)
By design a PreProcessor runs before any Sampler runs.
So if you want to run something only once per user, you can do the following:
Use a Once Only Controller and put in it a JSR223 Sampler that will contain your code.
If you want to do it once for all users, then use a setupThreadGroup
that will contain your JSR223 Sampler and configure it with 1 thread. It will run once before the regular Thread Groups are started.
EDIT after you updated your question:
As I wrote, you cannot use the setupThreadGroup approach if you want to reuse variables in Thread Groups so stick to OnceOnlyController approach for your request
With the Once Only Controller it is not working because you misread my answer, I am suggesting to use a JSR223 Sampler not PreProcessor as a preprocessor will run only if there is a sampler that runs.
If you use a Sampler, and you have multiple ThreadGroups, then you'll have to copy that sampler into each ThreadGroup, since you can't put Samplers outside of ThreadGroups.
you can use jsr223 PreProcessor with:
if(vars.get("init")=="OK") return;
vars.put("init","OK")
//your code
I'm doing a slightly dirty workaround at the top of the preprocessor:
log.info("in PreProcessor. Sampler name: " + sampler.getName())
if (sampler.getName() != "HTTP Request") {
log.info("not running again")
return
}
In my case I cannot add another sampler because it will mess up my timer calculations.