How to start a counter at the ThreadNum - jmeter

I'd like to start my counter at ThreadNum * 1000. So I tried various methods, none of which seem to work. Am I missing something?
e.g.
<CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="Counter" enabled="true">
<stringProp name="CounterConfig.start">${__jexl2(ctx.getThreadNum()*1000)}</stringProp>
<stringProp name="CounterConfig.end">999999</stringProp>
<stringProp name="CounterConfig.incr">1</stringProp>
<stringProp name="CounterConfig.name">TOTP</stringProp>
<stringProp name="CounterConfig.format">000000</stringProp>
<boolProp name="CounterConfig.per_user">true</boolProp>
<boolProp name="CounterConfig.reset_on_tg_iteration">true</boolProp>
</CounterConfig>
I am using the counter further down in an HTTP POST as a parameter and can see the parameter is always starting at 000001.
I would use a __counter variable as the POST parameter, but it doesn't look like you can do the preceding zeroes with a __counter.
I tried creating an external variable called START with beanshell :
<BeanShellSampler guiclass="BeanShellSamplerGui" testclass="BeanShellSampler" testname="BeanShell Sampler" enabled="true">
<stringProp name="BeanShellSampler.query">vars.put ("START", "0" + ctx.getThreadNum() * 1000 );
</stringProp>
....
<stringProp name="CounterConfig.start">${START}</stringProp>
....
That has a preceding zero, and still my counter starts at 000000 despite seeing START values of 01000 and 02000 (if I add ${START} as a parameter in the POST request).
Even simply starting the counter at ${__threadNum} didn't seem to make it start at ThreadNum. Is this a field that won't accept a variable value?

I cannot reproduce your issue using latest JMeter 4.0
JMeter starts with 001000 and continues as 002000, 003000, etc.
So try upgrading to JMeter 4.0 (or whatever is the latest version available at the JMeter Downloads page) and try on clean latest installation. If it doesn't help - check out if there are any suspicious entries in jmeter.log file. Also make sure you have ApacheJMeter_functions.jar in "lib/ext" folder of your JMeter installation (or in your project Classpath if you run JMeter from a Java program)

I thought this was an OSX issue.
Both windows are using the same script. Run under OSX on the left, Windows on the right :
You can see on the left, most of the TOTP have the same value, when I was first doing this, they would always be the same, everywhere.
On the right, they are the thread number - EXCEPT the highlighted one which re-uses "6" for thread 8. Mostly Windows gets it right, but sometimes gets it wrong. WTF??
Running from the command line I see the same problem on both platforms. Sometimes it gets it right, sometimes not, with greater or lesser degrees of success... So I think this is a Jmeter issue!

Related

Set decimal separator for JMeter JavaScript engine

The problem
My JMeter test calculates amount of threads that should be allocated to a thread group using JS expressions like this:
threadsGroupA expression: ${__javaScript(${__property(threads)}*${__property(threadPercentageA)})}
threadsGroupB expression: ${__javaScript(${__property(threads)}*${__property(threadPercentageB)})}
The properties passed to script:
threads=100
threadPercentageA=0.3
threadPercentageB=0.7
The expected result is: 30 threads assigned to group A and 70 threads assigned to group B.
This works as expected on my workstation. However, when I try to run it on a server, it does not create threads unless I use comma as a decimal separator in properties file:
threads=100
threadPercentageA=0,3
threadPercentageB=0,7
I am looking for a way to run the test with same property file in any environment.
What I tried
I have tried to force JVM to use locale with a decimal point . by adding -Duser.language=en -Duser.country=US -Duser.region=us (in different permutations) as variablesJMETER_OPTS, JMETER_LANGUAGE and also directly passed to JMeter as command line arguments(JMeter doc reference). None of that seemed to have any effect.
My thoughts
My conclusion at this point is that the problem is happening in JS engine that evaluates __javaScript()function. If there was a way to set locale for JS engine, I would be able to check this, hence the question in subject.
Use __groovy function and cast to integer/double the values before multiply:
${__groovy(props.get("threads").toInteger() * Double.parseDouble(props.get("threadPercentageB")),)}
Try using parseFloat() function for your decimal values like:
${__javaScript(${__property(threads)}*parseFloat(${__property(threadPercentageA))})}
If the output is decimal as well - in JavaScript there is Number.prototype.toLocaleString() function where you can explicitly set the locale for the Number object so you will have the confidence that it will return dot or comma no matter where it is run.
Also be aware that JavaScript engine is removed from the latest JDK/JRE versions so if you have a lot of JavaScript in your JMeter tests it makes sense to consider migrating to GraalVM or switching to __jexl3() or __groovy() functions
JS solution
Use parseFloat(), which always expects ., regardless of locale:
${__javaScript((${__property(threads)}*parseFloat("${__property(threadPercentageA)}")).toFixed())}
Credits for original idea to Dmitri T's answer
Groovy solution
${__groovy((props.get("threads").toInteger() * Double.parseDouble("${props.get('threadPercentageA')}")).round())}
Credits for original idea to user7294900's answer
Note about JMeter thread count handling
Turns out JMeter will not accept number of threads with decimal part, even if it is .0. Therefore, answers above include rounding functions.

Is it a JMeter bug if ctx.getThreadNum() returns number starting from 0 instead of 1?

I'm facing an issue while using the ctx.getThreadNum() inside JSR223 Post Processor.
From the JMeter API documentation of getThreadNum(), it shows:
the threadNum starting from one
But what I'm actually getting from the code is: returning the threadNum starting from ZERO
Seeing the attached image below:
I even try to compare with the function ${__threadNum}, and this function returns the number as expected (1) instead of ctx.getThreadNum() returns 0.
Could anyone please help to give me an advice if I'm doing something wrong? Or this is a bug from JMeter?
You are right that it's a documentation bug
threadNum actually start with 0 and not as stated in documentation
I opened a bug JMeterContext getThreadNum start at 0 and not 1
It'll be fixed next JMeter version
Notice java indexes start with 0, so it is valid implementation, but I agree that at least documentation should be changed
It's not a bug, that's how it works, it is documented here:
https://jmeter.apache.org/usermanual/functions.html#__threadNum
But there was a javadoc bug that has been reported and is now fixed:
https://bz.apache.org/bugzilla/show_bug.cgi?id=63616
So just add 1 to java code when comparing, but anyway never use ${} or a function ${__threadNum} inside JSR223 Groovy code, it will break caching of Compiled JSR223.
You can use rather the Parameters field to call the function ${__threadNum}

Reseting "Thread Context"

I would like to know if it is possible to reset the thread context (all of its variables) at the begining of a new iteration.
The problem that I am having is that the thread keeps all the variables (and its values) from its previous iterations and sometimes it things can get messy.
If I am not mistaken, on VisualStudio Performance tests you can specify the percentage of "new users" to indicate how many VirtualUsers are going to have its contexts reseted on their next test iteration.
Do we have something similar native on JMeter or do we need to write some code to do it?
Thanks in advance!
I'm not sure you really want/need it, but you can remove all JMeter variables using JSR223 script with remove method:
for (Map.Entry entry : vars.entrySet()) {
vars.put(entry.getKey(), null);
}
It depends on the type of variables you create and how you use them.
For ex:
Regular Expression Extractor
Here It creates a variable regex.var and if the response matches the expression it will have some value assigned to it. If the next iteration does not match the expression, It will still keep the previous iteration value. To avoid this problem, assign a default value or check the 'Use empty default value'. so that every iteration will basically reset the value.
User Designed Variables - Each and every thread will have its own copy of the variable and threads could be modifying its variable value throughout the entire duration of the test. If you want that to be reset for every iteration, it is completely your responsibility.
I think this could be helpful.
JMeter - Understanding Variables Scope

How to use regular expression with a property value in testcomplete

I'm from UFT background. I've just started using testcomplete yesterday. My manager told me to evaluate this tool.
I've come to a place where I have to use regular expression with a property value. Here's the code:
Aliases.HX01W00W.Window("IEFWINDOW", "Outbound Service - 0092020203030303 1 2", 1).Window("IEFWINDOW", "Service", 1).Window("Edit", "NY", 149)
This line of code works perfectly. I can set a value in the edit box. I can also get a property value from this object. However, if you can see, this part of the code always changes: Window("IEFWINDOW", "Outbound Service - 0092020203030303 1 2", 1).
Only, the word Service doesn't change.
I've tried changing that piece of code to:
Window("IEFWINDOW", ".*Service.*", 1)
Window("IEFWINDOW", "*Service*", 1)
In UFT this line: Window("text:=.*Service.*")identifies the window.
How can I use regular expression on this part of the code so I can interact with this object?
If someone can provide similar piece of code that actually works would be highly appreciated.
Thanks,
Wildcards should work for you:
Window("IEFWINDOW", "*Service*", 1)
Anyway, you can use regular expressions as well:
Aliases.HX01W00W.FindChild(Array("WndClass", "WndCaption"), Array("IEFWINDOW", "regexp:.*Service.*"))
More information can be found in the Using Regular Expressions in Scripts help topic.

JMeter "if controller" with parameters?

I was reading the JMeter documentation and came across this info box about "If Controllers":
No variables are made available to the script when the condition is interpreted as Javascript. If you need access to such variables, then select "Interpret Condition as Variable Expression?" and use a __javaScript() function call. You can then use the objects "vars", "log", "ctx" etc. in the script.
I don't quite follow this. Does this mean if I want access to a "User Defined Parameter" then I can access it only by writing some JavaScript? The example that follows this box then refers to "${COUNT}"
Could someone clarify the usage of the If Controller, maybe with an example or two?
All these answers are wrong! You need to put the variable reference in quotes, like so:
"${my_variable}"=="foo"
You can simply use something like
${my_variable}=='1'
Sometimes JMeter documentation can be confusing :)
Edit 27 september 2017:
The answer here works but has a very bad performance impact when number of threads exceeds 40.
See below for correct and most performing answer:
https://stackoverflow.com/a/46976447/460802
See:
https://bz.apache.org/bugzilla/show_bug.cgi?id=61675
UNCHECK the CHECKBOX
"Interpret condition as variable expression"
I wasted a couple of hours without unchecking this checkbox. It worked with and without semicolon(;) at the end of the statement. Make sure that you have set the User-Defined Variables before calling the if controller.
All the following variations worked for me in Jakarta Jmeter 1.5
${__javaScript("${HOMEPAGE}"=="Y")}
${__javaScript("${HOMEPAGE}"=="Y")};
"${HOMEPAGE}"=="Y"
"${HOMEPAGE}"=="Y";
If Controller will internally use javascript to evaluate the condition but this can have a performance penalty.
A better option (default one starting from JMeter 4, see https://bz.apache.org/bugzilla/show_bug.cgi?id=61675) is to check "Interpret Condition as Variable Expression?", then in the condition field you have 2 options:
Option 1 : Use a variable that contains true or false. For example If you want to test if last sample was successful, you can use
${JMeterThread.last_sample_ok}
or any variable you want that contains true/false
${myVar}
Option 2 : Use a function (${__jexl3()} is advised) to evaluate an expression that must return true or false.
For example if COUNT is equal to 1:
${__jexl3("${COUNT}"== "1",)}
OR
${__jexl3(${COUNT}== 1,)}
Starting with 4.0, if you don't use the "Interpret Condition as Variable Expression?", a warning in RED will be displayed:
If you'd like to learn more about JMeter and performance testing this book can help you.
God bless the http://habrahabr.ru
Have tried until found these.
Using the quotes was my solution.
As Gerrie said you need to check your variable
${my_var} == 'value'
But be careful with the 'User Defined Variables'
Note that all the UDV elements in a
test plan - no matter where they are -
are processed at the start.
That basically means that you cannot define 'User Defined Variables' inside an 'If Controller'. Take a look to the 'BeanShell' instead.
Replace:
${my_variable}=='1'
with
"${my_variable}" == "1"
if it's string value pass as below and its performance effective
${__groovy("${key}"=="value")}
I have used ${code_g1}== 200 in condition and it worked for me.

Resources