In my Jmeter 3.0 test plan, I have multiple thread groups. Now I want to
distribute users among them on the basis of percentage.
I have declared Variables in user defined variable and then used the following statement in thread group
${__BeanShell(${__evalVar(threads)}*${__evalVar(WeightOfGroup1)}/100)}
But I am getting the following exception while doing so
2017/09/20 19:25:39 ERROR - jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval In file: inline evaluation of: ``**ERROR - see log file*****ERROR - see log file**/100;'' Encountered "*" at line 1, column 1.
2017/09/20 19:25:39 WARN - jmeter.functions.BeanShell: Error running BSH script org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval In file: inline evaluation of: ``**ERROR - see log file*****ERROR - see log file**/100;'' Encountered "*" at line 1, column 1.
You cannot use variables in thread group definitions, since variables are local to a thread, and thus are initialized after thread group starts its threads.
You have 2 options:
Use properties, as described in this solution. Calculation you are trying to do will need to be modified too, for example like this:
${__javaScript(Math.max(1\,Math.round(props.get('threads')*props.get('WeightOfGroup1')/100)))}
Assuming here that you have both threads and WeightOfGroup1 properties defined. Also notice that you need to round the number to integer. To avoid ending up with 0 threads, I also take the maximum between 1 and formula calculation (so it will run at least one thread) - this is optional of course.
From your use case it actually looks like you don't need thread groups. Instead, you could use one thread group, have Throughput Controller for each fragment which previously was your thread group, and express your distribution goal in Throughput Controller parameter. In that case you don't need to calculate percentage, just specify what you need the percentage to be, e.g.:
I think this solution is more elegant, so unless there are any other reasons to use multiple thread groups, I'd go with that.
Related
Context: Want to generate unique and different value when the thread runs in loop.
Currently it is generating the same value.
Script Inside JSR223 Preprocessor,
String subscribeSchemaNamePreProcesser="agent-Perf-${__Random(1,99999,)}"
log.info("Schema Name --------------->"+subscribeSchemaNamePreProcesser)
vars.put("subscribeSchemaNamePreProcesser", subscribeSchemaNamePreProcesser)
When run with number of threads more than 1(i.e. 2 thread 1 loop), it is generating different value
When run with number of loops more than 1 (i.e. 1 thread 2 loop), it is generating the same value (want to fix it)
anything I missed
Don't inline JMeter Functions or Variables into Groovy scripts, they will be cached and only first occurrence will be used for subsequent calls.
You need to change this line:
String subscribeSchemaNamePreProcesser="agent-Perf-${__Random(1,99999,)}"
to this one:
String subscribeSchemaNamePreProcesser = "agent-Perf-" + org.apache.commons.lang3.RandomUtils.nextInt(1, 99999)
More information:
JSR223 Sampler
Apache Groovy - Why and How You Should Use It
I am currently running 10 different threads like this:
each of the thread response will provide a different id in the response and i want to save them and use it as a request in the next test case(10 threads) so there will be 10 ids and 10 threads and each thread will have a unique id as a request. This is what I am doing:
Here is the first request
This is how I am extracting the values
This is how i am using the final request however i am not able to get the desired results
UPDATE:
I tried Dmitri Answer but still no luck i am extracting the id by using this
I used __threadNum() function as the prefix or postfix for the property name like:
${__setProperty(loginassistant_${__threadNum},${loginassistant_},)}
and read it similarly:
${__P(loginassistant_${__threadNum},)}
but it is not working and it is setting the value as a static string(see screenshot below):
This is how and where i am defining my loginassistant using the simple controller:
You're using properties which are global, if you have more than one thread the next thread will overwrite the property defined by the previous thread so it could be mismatch.
If you don't need to pass values across thread groups - go for JMeter Variables instead, variables are local to the thread (virtual user) and the properties are global for the whole JMeter/JVM instance
If you do need to pass values across thread groups - either use __threadNum() function as the prefix or postfix for the property name like:
${__setProperty(loginassistant_${__threadNum},${loginassistant},)}
and read it similarly:
${__P(loginassistant_${__threadNum},)}
or go for Inter-Thread Communication Plugin
i want to control my sampler execution by using a random variable . I have a sequence of hits login,welcome,Bla,log out . i want the log out to be performed for 6/10 requests and let others do not login(so to speak 6 requests will perform the whole sequence including log out, 4 of them will perform will not perform log out ).How to achieve the same in JMETER
I have added a random variable rand and set it between 1-10 at the beginning of the thread group .Then just above Logout sampler i placed an IF controller were i check ${rand}>4 . How ever i always get all sequence executed . Please suggest what am i doing wrong
Your approach is a little bit weird, my expectation is that the problem is in the following areas:
Your IF Controller condition is wrong (check jmeter.log file for any suspicious entries)
Your random variable setting is wrong, i.e. it has the same value for all virtual users (threads) so they will either be executed all or none
So I would recommend using Throughput Controller or Switch Controller in order to set up this 60/40 distribution.
See Running JMeter Samplers with Defined Percentage Probability article for more details.
Random Variable in Jmeter is saved in long format be default so
${rand} > 4 won't work. You need to change
Condition to ${rand} > 4.0
or change Random Variable Output format to 00 (2 digits)
see Manual
This was accomplished by creating a combination of config element- random variable and an IF controller
1) a random variable was created with Minim and maxim value to meet above condition
2) and IF controller was able to check ${myrand}>4;
This had derived the desired result - thank you all
In JMeter, I have a requirement where I want to run a particular thread group after all the other thread groups complete their run, I know the tearDown thread group has the similar behavior but unfortunately, the logic has to be part of my regular thread.
Let's say there are 4 thread groups A,B,C & D in my test plan and I want the thread group D only to be executed after A, B & C will complete their run.
Can we achieve this without using "setup, teardown & Run groups one at a time" ??
Problem ScreenShot:
I can suggest 2 options:
Use Inter-Thread Communication Plugin. See example test plan for details.
If for some reason you are not in position to use JMeter Plugins you can achieve the same using JMeter Properties like:
When Thread Group A finishes set a JMeter Property, i.e. ThreadGroupADone=true using __setProperty() function like
${__setProperty(ThreadGroupADone,true,)}
In Thread Group D:
Add While Controller at the beginning of the Thread Group and use the following condition:
${__javaScript("${__P(ThreadGroupADone,)}"=="false",)}
Add Test Action sampler as a child of the While Controller and configure it to pause for a reasonable amount of seconds, i.e. 5 so each 5 seconds While Controller will check ThreadGroupADone property value and if it is still false - sleep for another 5 seconds. When property value will become true - Thread Group D will proceed.
I have a Bean shell preprocessor which ends up setting up some global variables like host name and the path according to the value that the user passes.
The variables that the bean shell sets would be used by all the thread group.
Currently i've placed my BS pre-processor outside a thread and it runs perfectly..
The issue is that it runs for every thread which isn't performance friendly.
I just want it to run once at the start of the Test plan to improve performance.
I tried to put it into a setUp thread but it doesn't work.
Is there something other that the BS-preprocessor that i can use which would be performance effective(which runs only once for the entire plan rather than for every thread).
You can put it under If Controller and use the following condition:
${__BeanShell(vars.getIteration() == 1)} && ${__threadNum} == 1
You can use setUp Thread Group which is designed for executing pre-test actions but in that case change all occurrences of vars.put() to props.put() as JMeter variables scope is limited to current thread group only and Properties are global for the whole JVM instance. See How to Use Variables in Different Thread Groups guide for additional information
JMeter SetUp thread group and TearDown thread group are meant for exactly this. These threads run at the start and the end of test plan. So, just add Setup thread group and add beanshells into. See links for more information:
http://jmeter.apache.org/usermanual/component_reference.html#setUp_Thread_Group
In the other hand, vars are limited for each thread groups. Use props to put a value which is shared with all thread groups.
This worked for me... Just configure a User Defined Variable called firstTimeIndicator and set the value to 1
String firstTimeIndicator = "";
firstTimeIndicator = vars.get("firstTimeIndicator");
if (firstTimeIndicator.equals("1")) {
log.info("The code inside the if statement executes once per test run...");
firstTimeIndicator = "0";
vars.put("firstTimeIndicator",firstTimeIndicator);
}
log.info("The code after the if statement executes once per thread");