JMeter: doesn't increment counter value - jmeter

I'm working on a load test for Eclipse RAP-based application in JMeter. I need to replace requestCounter in each http request with variable. Variable should be incremented by 1 in next requests.
Tried to use JMeter's __counter function ${__counter(FALSE)} for my ${COUNTER} variable:
1) in User Defined Variables (didn't increment counter http://screencast.com/t/5MP1ovdHJN5p),
2) in CSV Data Set (function body was inserted instead of number http://screencast.com/t/mUIaYF3Oc).
Replaced ${__counter(FALSE)} with ${__javaScript(${__counter(FALSE)})} - still no success.
3) Counter config element brings the same result as User Defined Variable - not incrementing value for next request.
Plan:
+Thread_group
+Counter config element/User Defined Variables/CSV Data Set
+Request group
++ HTTP request1: {"head":{"requestCounter":${COUNTER}} #should be 1
++ HTTP request2: {"head":{"requestCounter":${COUNTER}} #should be 2
++ HTTP request2: {"head":{"requestCounter":${COUNTER}} #should be 3
...
Any suggestions?

you don't need to update the request counter manually. For RAP 2.1+ we updated the Wiki with the current info about load testing:
https://wiki.eclipse.org/RAP/LoadTesting

Related

thread Local Cached Connection

I was using JMeter properties for storing the threadLocalCachedConnection object. I made sure to use unique property names as properties.
In thread group 1, I had a JSR223 PostProcessor to scrape session per thread(VU), and then store it in a property called sessionID.
And I added another JSR223 PostProcessor as a child of the last sampler in the Thread Group1.
def connection = sampler.threadLocalCachedConnection
props.put("presenterConnection" + ctx.getThreadNum(), connection.get())
In Thread Group 2, I added a JSR223 PreProcessor as a child of the first sampler.
def presenterConnection = props.get('presenterConnection' + ctx.getThreadNum())
sampler.threadLocalCachedConnection.set(presenterConnection)
String sendCommand = "SEND\n" +
"content-type:application/json;charset=UTF-8\n" +
"destination:/v1/session/${__property(sessionId)}/command\n" +
"id:perftest01-presenter-${__property(sessionId)}\n" +
"\n" +
"{\"type\": \"go-to-slide\", \"data\": {\"index\": 0}}\n" +
'\0' // note: NULL char at end
;
vars.put("wsStompSendCommand", sendCommand);
I tested with 2 threads (VUs). Why both threads were using the last sessionId instead of using one sessionId per thread??
As per JMeter Documentation:
Properties are not the same as variables. Variables are local to a thread; properties are common to all threads
so your line
props.put('sessionId', vars.get('sessionUUID'))
creates a global sessionId propety which is:
common for all Threads no matter in which Thread Group they are
exists until you shut down JMeter/JVM
You need to play the same trick as with the presenterConnection to wit:
props.put('sessionId_'+ ctx.getThreadNum(), vars.get('sessionUUID'))
and then read it where required:
def sessionId = props.get('sessionId_'+ ctx.getThreadNum())
More information: Apache Groovy: What Is Groovy Used For?

JMeter: Extracting and passing Transaction controller name in JMeter test plan

In my JMeter test plan, i have 3 transaction controllers.
I want to extract the transaction controller name and pass it to the Jmeter script.
I am unable to extract the transaction controller name, which is displayed into "Log viewer Panel".
To print transaction name , i have used BeanShell Listener, with following code :
String tname= sampleResult.toString();
if(tname.startsWith("T01_Login"))
{
log.info("*Transaction Name = " +sampleResult.toString() + " - Response time = " + sampleResult.getTime());
String temp = sampleResult.toString();
String temp2 = sampleResult.getTime().toString();
vars.put("Transaction_Name",temp);
vars.put("Response", temp2);
log.info(vars.get("Response"));
log.info(vars.get("Transaction_Name"));
}
I have used BSF post processor to store/extract the transaction name, by using following code:
Language selected in : Javascript
var transact = ${Transaction_Name};
vars.put ("TRANSACT",transact);
log.info(TRANSACT);
When checked into LogViewer panel, following text is displayed:
2017/03/27 17:06:13 INFO - jmeter.util.BeanShellTestElement: *Transaction Name = T01_Login - Response time = 39829
2017/03/27 17:06:13 INFO - jmeter.util.BeanShellTestElement: 39829
2017/03/27 17:06:13 INFO - jmeter.util.BeanShellTestElement: T01_Login
Kindly provide your valuable suggestion on this.
To resolve the error which prevents post-processor from running, use vars.get, instead of var transact = ${Transaction_Name};, i.e.
var transact = vars.get("Transaction_Name");
And setting another variable (vars.put ("TRANSACT",transact);) is unnecessary: just use Transaction_Name. (And another small note: BSF set of objects is now deprecated, so switch them to either JSR322 or BeanShell)
But it will not work anyways, because the order of execution is
Sampler > Post-processor > Listener > Transaction Controller > Listener
So the value of Transaction_Name inside post-processor will either be empty (on first iteration), or will be coming from previous iteration, which I guess is not what you want.
You don't mention your use case, but some options you have are:
Have a special sampler AFTER transaction controller to do what you wanted in that post-processor. For example:
Transaction Controller
Some Sampler
...
JSR223 / Beanshell sampler
This second sampler can obtain proper transaction name, since it's running after the transaction
Save transaction name into variable before calling a transaction. Set transaction controller name to that variable:
JSR223 / Beanshell sampler
sets variable: vars.put("Transaction_Name", "T01_Login");
${Transaction_Name} <-- this is the name of the transaction controller
Sampler
Post-processor <-- here the Transaction_Name can be obtained.

JMeter - Strange Behavior when Variables used in CookieManager

JMeter Version 2.13 r1665067
So I seem to be having some trouble when using User-Defined Variables and/or JMeter Property Variables inside a CookieManager.
If I use a variable as the value for a Cookie inside the CookieManager, whether or not it's a User-Defined Var or a Property Var I have the same problem when trying to view the Cookie's value(s) inside a BeanShell Pre and PostProcessor.
If my Cookie Manager has this below: *The 1st line is when using properties variable and 2nd line is when using a var from a User Defined Variable, *FYI both lines are NOT used at the same time:
CookieManager:
NAME VALUE DOMAIN PATH
1st) MYID ${__P(propCookie)} www.mydomain.com /
OR
2nd) MYID ${userCookie} www.mydomain.com /
The propCookie variable is passed on the CLI or defined in a .properties file like below:
COMMAND-LINE --> -JpropCookie=SRV1
IN PROP FILE --> propCookie=SRV1
And the userCookie variable is defined inside a User Defined Variables Config Element like so:
NAME VALUE DESCRIPTION
userCookie ${__P(propCookie)} User var using prop variable as value
Then, when I run my test I can see in the Request Tab of the Results Tree that it is showing the Cookie and it has the correct value assigned to it, which is good... But when I attempt to view the Cookies in a BeanShell Pre/Post-Processor, it simply shows the Variable and NOT the actual value.
BeanShell PreProcessor Code
import org.apache.jmeter.protocol.http.control.Cookie;
import org.apache.jmeter.protocol.http.control.CookieManager;
log.info("### Inside BeanShell PreProcessor:");
CookieManager manager = sampler.getCookieManager();
log.info("Cookie Count = '" + manager.getCookieCount() + "'");
for (int i = 0; i < manager.getCookieCount(); i++) {
Cookie cookie = manager.get(i);
log.info("\t\t Cookie.getName() = '" + cookie.getName() + "'");
log.info("\t\t Cookie.getValue() = '" + cookie.getValue() + "'");
}
Here is the BeanShell Script's Output in the Log:
2015/04/29 14:33:00 INFO - jmeter.util.BeanShellTestElement: ### Inside BeanShell PreProcessor:
2015/04/29 14:45:58 INFO - jmeter.util.BeanShellTestElement: Cookie Count = '1'
2015/04/29 14:33:00 INFO - jmeter.util.BeanShellTestElement: Cookie.getName() = 'MYID'
2015/04/29 14:33:00 INFO - jmeter.util.BeanShellTestElement: Cookie.getValue() = '${userCookie}'
So as you can see in the output from the BeanShell, the getValue() function is printing the Variable assigned to the Cookie's value exactly like this --> "${userCookie}", and NOT what the actual Cookie's value is, which is "SRV1"...
Lastly, if I try to use the "COOKIE_" variable which is supposed to get automatically created, and I use this in BeanShell, vars.get("COOKIE_MYID"), it prints "null" every time... I have all the proper Cookie properties set in the jmeter.properties file, like these here, so I'm not sure what the problem is:
CookieManager.allow_variable_cookies=true
CookieManager.save.cookies=true
CookieManager.name.prefix=COOKIE_
I'm pretty much stumped for why this is happening so if anyone has any ideas for why this is happening, please feel free it would be greatly appreciated!
Thanks in Advance,
Matt
HTTP Request Sampler actually sets the cookie using CookieManager's getCookieHeaderForURL method which substitutes the value properly.
In Beanshell,
import org.apache.jmeter.protocol.http.control.Cookie;
import org.apache.jmeter.protocol.http.control.CookieManager;
manager = sampler.getCookieManager();
log.info(manager.getCookieHeaderForURL(new URL("http://www.google.com"))); //update the URL
This gives the cookies with updated values.
CookieManager's get & add methods are used to get & add cookies to the HTTP Cookie Manager at run time. So, getValue method gives the value as it is. getCookieHeaderForURL gets the appropriate cookies from the Cookie Manager for the domain with updated values.

IF controller (radio button/counter) and Loop Controller in Jmeter

I'd like to practice IF controller basically as follow:
TEST_PLAN
+Thread_group: (user: 3, ramp: 3, loop:2)
+Loop_Controller(loop:4)
++ HTTP request1: go to page_1
+IF_Controller1
++ HTTP request2: go to page_2
++ counter (config element)
+IF_Controller2
++ HTTP request3: click Back button
My condition "HTTP request 2" is only executed if loop (output "Loop_Controller" >4). How to do that ?
And, for IF_Controller2: it's will be executed after each of question on this page has checked (page has 5 questions, 1 question has 5 answer radio button.)
I also follow the Counter element and Counter functions, but don't know how to combine them?
and one more things: to use the variable in IF statement, they should be put on previous activities ? (in my case: IF controller: ${count}, thereby variable "count" should be put on HTTP request 1)
Thanks,
You need to place COUNTER as a child of Loop Controller, not If Controller. In this case you'll get the following scenario:
HTTP Request 1 (loop 1)
HTTP Request 1 (loop 2)
HTTP Request 1 (loop 3)
HTTP Request 1 (loop 4)
** HERE we're getting out of Loop Controller and go to 2nd Loop of Thread Group, If controller doesn't fire as counter value is 4 and condition is >4**
HTTP Request 1 (loop 5)
HTTP Request 1 (loop 6)
HTTP Request 1 (loop 7)
HTTP Request 1 (loop 8)
** HERE counter value is 8 and If controller condition is met so **
HTTP Request 2
Being child of If Controller counter isn't getting incremented
Counter Configuration:
Start: 1
Increment: 1
Reference Name: N
If Controller Configuration:
${N} > 4
See How to use JMeter's 'IF' Controller and get Pie guide for more details.

JMeter, threads using dynamic incremented value

I have created a JMeter functional test that essentially:
creates a user;
logs in with the user;
deletes the user.
Now, I need to be able to thread this, and dynamically generate a username with a default prefix and a numerically incremented suffix (ie TestUser_1, TestUser_2, ... etc).
I used the counter, and things were working fine until I really punched up the number of threads/loops. When I did this, I was getting a conflict with the counter. Some threads were trying to read the counter, but the counter had already been incremented by another thread. This resulted in trying to delete a thread that was just created, then trying to log in with a thread that was just deleted.
The project is set up like this:
Test Plan
Thread group
Counter
User Defined Variables
Samplers
I was hoping to solve this problem by using the counter to append a number to the user defined variables upon thread execution, but the counter cannot be accessed in the user defined variables.
Any ideas on how I can solve this problem?
Thank you in advance.
I've used the following scheme successfully with any amount of test users:
1. Generate using beanshell-script (in BeanShell Sampler e.g.) csv-file with test-user details, for example:
testUserName001,testPwd001
testUserName002,testPwd002
. . .
testUserName00N,testPwd00N
with the amount of entries you need for the test-run.
This is done once per "N users test-run", in separate Thread Group, in setUp Thread Group or maybe even in separate jmx-script... makes no difference.
You can please find working beanshell-code below.
2. Create your test users IN TEST APPLICATION using previously created users-list.
If you don't need create in application you may skip this.
Thread Group
Number of Threads = 1
Loop Count = 1
. . .
While Controller
Condition = ${__javaScript("${newUserName}"!="",)} // this will repeat until EOF
CSV Data Set Config
Filename = ${__property(user.dir)}${__BeanShell(File.separator,)}${__P(users-list,)} // path to generated users-list
Variable Names = newUserName,newUserPwd // these are test-users details read from file into pointed variables
Delimiter = '
Recycle on EOF? = False
Stop thread on EOF? = True
Sharing Mode = Current thread group
[CREATE TEST USERS LOGIC HERE] // here are actions to create separate user in application
. . .
3. Perform multi-user logic.
Schema like the given above one but Thread Group executed not for 1 but for N threads.
Thread Group
Number of Threads = ${__P(usersCount,)} // set number of users you need to test
Ramp-Up Period = ${__P(rampUpPeriod,)}
Loop Count = X
. . .
While Controller
Condition = ${__javaScript("${newUserName}"!="",)} // this will repeat until EOF
CSV Data Set Config
Filename = ${__property(user.dir)}${__BeanShell(File.separator,)}${__P(users-list,)} // path to generated users-list
Variable Names = newUserName,newUserPwd // these are test-users details read from file into pointed variables
Delimiter = '
Recycle on EOF? = False
Stop thread on EOF? = True
Sharing Mode = Current thread group
[TEST LOGIC HERE] // here are test actions
. . .
The key idea is in using Thread Group + While Controller + CSV Data Set Config combination:
3.1. CSV Data Set Config reads details for each the test users from generated file:
. . . a. only once - because of "Stop thread on EOF? = True";
. . . b. doesn't block file for further access (in another thread groups, e.g., if there are any) - because of "Sharing Mode = Current thread group";
. . . c. pointed variables - "Variable Names = newUserName,newUserPwd" - you will use in further test-actions;
3.2. While Controller forces CSV Data Set Config to read all the entries from generated file - because of defined condition (until the EOF).
3.3. Thread Group will start all the threads with defined ramp-up - or simultaneously if ramp-up = 0.
You can take here template script for described schema: multiuser.jmx.
Beanshell script to generate test-users details looks like below and takes the following args:
- test-users count
- test-user name template ("TestUser_" in your case)
- test-user name format (e.g. 0 - to get TestUser_1, 00 - to get TestUser_01, 000- for TestUser_001, etc... you can simply hardcode this orexclude at all)
- name of generated file.
import java.text.*;
import java.io.*;
import java.util.*;
String [] params = Parameters.split(",");
int count = Integer.valueOf(params[0]);
String testName = params[1];
String nameFormat = params[2];
String usersList = params[3];
StringBuilder contents = new StringBuilder();
try {
DecimalFormat formatter = new DecimalFormat(nameFormat);
FileOutputStream fos = new FileOutputStream(System.getProperty("user.dir") + File.separator + usersList);
for (int i = 1; i <= count; i++) {
String s = formatter.format(i);
String testUser = testName + s;
contents.append(testUser).append(",").append(testUser);
if (i < count) {
contents.append("\n");
}
}
byte [] buffer = contents.toString().getBytes();
fos.write(buffer);
fos.close();
}
catch (Exception ex) {
IsSuccess = false;
log.error(ex.getMessage());
System.err.println(ex.getMessage());
}
catch (Throwable thex) {
System.err.println(thex.getMessage());
}
All together it will look like:
Sorry if answer is too overloaded.
Hope this helps.
The "User Defined Variables" config element does not pick up the reference variable from the "Counter" config element. I think this is a bug in JMeter. I have verified this behavior in version 3.2.
I added a "BeanShell Sampler" element to work around the issue.
Notice that the reference name of the "Counter" element is INDEX
The RUN_FOLDER variable gets set to a combination of the TESTS_FOLDER variable and the INDEX variable in the "BeanShell Sampler"
The "Debug Sampler" simply gathers a snapshot of the variables so I can see them in the "View Results Tree" listener element. Notice how the RUN_FOLDER variable has the INDEX variable value (5 in this case) appended.

Resources