Nested Parameter substitution problems in jmeter - jmeter

I am trying to create a jmx to test some database entries. The exact queries are not known beforehand and need to be picked from one of many sets of queries, that I have declared in separate pre-processor units.
For eg. one of the set of queries is:
String[][] animals = new String[][]{
{"VLS_CATS_ASSOC","CAT_ID_AS = '${CAT_ID_AS}'"},
{"VLS_DOGS_EXCH","DOG_ID_ST = '${DOG_ID_ST}' and DOG_TXT_REF = '${DOG_TXT_REF}'"},
};
The 2D array has two entries, the 'table name' and the 'where clause'
So, the jdbc request is select * from ${table_name} where ${where_clause}
I've set up a loop controller for iterating through the tables one by one, and as a child i have jdbc sampler, that has the csv table config which will contain data for CAT_ID_AS, DOG_ID_ST, DOG_TXT_REF.
Currently, when i see my requests through a results listener, i see that the queries sent are:
select * from VLS_CATS_ASSOC where DOG_ID_ST = '${DOG_ID_ST}' and DOG_TXT_REF = '${DOG_TXT_REF}'
It is clear from the output that the first level of substitution has worked, but not the second one.
Can anybody please help me on this?
Edit: Adding an image of the test plan. Jmeter Test Plan

Don't use ${CAT_ID_AS} notation in (I presume) the BeanShell strings: while it is generally working, that's an undocumented and error-prone feature.
The legit way is vars.get("CAT_ID_AS")
vars is a pre-defined object available in any BeanShell piece inside your test plan
So your code would be looking like
String[][] animals = new String[][]{ {"VLS_CATS_ASSOC","CAT_ID_AS = '" + vars.get("CAT_ID_AS") + "'"}, ... etc

Related

Parallel executions of dynamic URL's coming from for each controller

I have a requirement to load the dynamic assets(Images) parallelly which got extracted from the for each loop as there is only one sampler with variable passed. I cant use the parallel controller here, also I don't know the exact number of assets loaded to pass in parallel sampler.
As suggested by you in one of similar issues I have used that approach(add pre sampler) below script and try to execute it in, It is able to pick the values but the child element is always only one(Parallel requests are not happening) however I see the URL's passed main request has multiple passed.
Pre-Processor script used:
String var2 = vars.get("tokens");
String var3 = vars.get("Token");
vars.put("var3", "https://stagingassets.ovid.com"+"/"+var2+"/t/width-150-png?"+var3);
urlsList = vars.get("var3").tokenize(",")
for (int i = 0; i < urlsList.size(); i++) {
def row = new org.apache.jmeter.testelement.property.CollectionProperty()
row.addItem(urlsList[i])
sampler.data.addItem(row)
log.info("ROWS ${row}")
}
variables are coming from CSV where values are saved into a file from each loop using a Flexible File Writer.
please suggest , My requirement is to execute the images parallelly as it happens in the browser.
[JMeter script image][1]
Use Parallel Sampler, the URLs can be added dynamically via JSR223 PreProcessor using the following code snippet:
sampler.addURL('your-first-url')
sampler.addURL('your-second-url')
If you want to mimic browser-like behaviour you need to put the Parallel Sampler under the Loop Controller and set the number of loops to the number of your URLs / 6

Jmeter - Calling javascript using JSR223 Post processor

I capture 6 elements using a regular expression. say
Variable : UserDetails
Regular Expression : loadHeadWorkFlow\('(.+?)','(.+?)','(.+?)','(.+?)','(.+?)','(.+?)','/I
Template : $1$$2$$3$$4$$5$$6$
Now I could access these values via UserDetails_g1, UserDetails_g2.....UserDetails_g6
Next, these 6 values need to be encrypted using a javascript file. The file contains the logic.
How should my code be using JSR223 post processor?
The steps that I followed:
1.
load('Encryption.js');
var result = encrypt("${UserDetails_g1}","password");
log.info("encrypted value is "+result);
vars.put("LoginDataString",result);
var result1 = encrypt("${UserDetails_g2}","password1");
vars.put("UserId",result1);
var result2 = encrypt("${UserDetails_g3}","password2");
vars.put("RoleId",result2);
First value is encrypted correctly. But the other values aren't correct. If I add individual post processors for every variable. All the encrypted values show correctly.
Is there a way where I could use a single post processor to perform all the 6 encryptions. Thanks in advance
Regards,
Ajith
Use vars instead of ${} syntax
var result = encrypt(vars.get("UserDetails_g1"),"password");
log.info("encrypted value is "+result);
vars.put("LoginDataString",result);
var result1 = encrypt(vars.get("UserDetails_g2"),"password1");
vars.put("UserId",result1);
var result2 = encrypt(vars.get("UserDetails_g3"),"password2");
vars.put("RoleId",result2);
From JMeter perspective there is no problems, just check that your UserDetails_g2 variable has anticipated value using Debug Sampler and View Results Tree listener combination., the you might want to check this encrypt() function implementation.
Another possible reason is this JavaScript language selection itself, the Nashorn engine performance is a big question mark when it comes to the load, according to JMeter Best Practices it's recommended to use Groovy language for scripting so you might want to consider re-writing the function in Groovy

Jmeter - Break down huge JDBC query into multiple JDBC queries

I want to perform jdbc query which returns 700K+ rows, then build my logic based on that, but when try to execute response time is too long, so i need to break down on multiple queries, each returning ex:1000 results.
My architecture is like:
001_1 JDBC max_value - Defines the maximum value, of that 700K, which is increasing all the time.
001_1 JDBC MAIN - This JDBC i want to break down into multiple JDBC requests.
InIt counter = vars.put("counter","1");
offset_value - counter element
While controller - ${__javaScript(parseInt(vars.get("counter"))<=700)}
If i put hard-code value into the While controller, everything works fine, and my script is working; But when data-base increase the records size, then i need manually to amend the number of the while controller 700, so can cover the next records.
Based on my understanding here i have 3 variables:
max_value = 714K
counter = 1
offset_value = 0
If i try: ${__javaScript(parseInt(vars.get("offset_value")<=parseInt(vars.get("max_value")))== true)}
as a while controller statement, offset_value is still not evaluated, and while controller is not working properly.
How can i compare offset_value vs. max_value, so i can drive my While controller?
Any help is appreciated!
If your parseInt(vars.get("offset_value")) expression is being executed against not-initialised variable it will return NaN so comparing it with a number doesn't make a lot of sense, you need to amend it to something like parseInt(vars.get("offset_value")) || 0 so it would return zero on first iteration.
Also be aware that starting from JMeter 3.1 you should be using JSR223 Test Elements for scripting and correspondingly __groovy() function in the While Controller. More information: Apache Groovy - Why and How You Should Use It
Thanks for the help #Dmitri T; However solution for me was:
1. Initialize the compare value as: JRS233 sample -> vars.put("offset_value","0");
2. ${__javaScript(parseInt(vars.get("offset_value"))<=parseInt(vars.get("max_value_1")),)} -> inside while controller.
3. Counter: Track counter & Reset counter: must me checked both

Jmeter while controller doesn't seem to evaluate variables as numbers

I am writing a jmeter script that keeps loading data until a table reaches a specified size. I have a while loop, in which I have one HTTP Sampler to loads the data, then another HTTP Sampler with an XPath Post-processor to check the table size (they call two different APIs). The reference variable of the XPath Post Processor is currentSize and I have a user defined variable maxSize, but using ${currentSize} < ${maxSize} as the condition for the while loop creates an infinite loop.
Thinking maybe the problem is that the output of XPath is a string, I've tried doing various things in beanshell to coerce it to a number, but I'm a beanshell noob, so I haven't been successful with that either. Can anyone guide me about how to get jmeter to recognize a variable as a number? (Preferably a decimal, but if I have to round to an int, I can live with that.)
Thanks!
I think using __javascript(parseInt()) should suffice for you to check the condition.
e.g.
${__javaScript(parseInt(${time_elapsed_string}) < parseInt(${duration}))}
Assuming that you have following variables:
currentSize
maxSize
continue
where continue is set via User Defined Variables and has the value of true
You can use following Beanshell code to check if current size is equal or greater than maximum size:
import java.math.BigDecimal;
String currentSize = vars.get("currentSize");
String maxSize = vars.get("maxSize");
BigDecimal currentSizeNumber = new BigDecimal(currentSize);
BigDecimal maxSizeNumber = new BigDecimal(maxSize);
if (currentSizeNumber.compareTo(maxSizeNumber) > -1){
vars.put("continue", "false");
}
Make sure that following criteria are met:
Your While Controller has ${continue} as a condition
Beanshell Sampler, Pre / Post Processor or Assertion with the code above is added as a child of the While Controller
See How to use BeanShell guide for more details and kind of Beanshell cookbook.
Everything should work this way.
Hope this helps.

JMeter set variable to random option

I've been using JMeter and I'm aware of the __Random and __RandomString functions. I need to pick a random option and store it in a variable because it will be used as part of a parameter path for multiple calls. For example:
http://www.example.com/pets/{random option such as: cat, dog, parakeet}/
I've tried doing simple like this, where I set the variable ${query} to one, two, or three using a random controller with userdefined variables as children. This seems like it should work, however I always get ${query} set to three.
Any insight or ideas are will be well recieved. Thanks to all in advance.
You can use Beanshell Pre Processor to generate random value
String[] query = new String[]{"cat", "dog", "parakeet"};
Random random = new Random();
int i = random.nextInt(query.length);
vars.put("randomOption",query[i]);
After that in your HTTP Request
http://www.example.com/pets/${randomOption}
As an alternative to String[] query = new String[]{"cat", "dog", "parakeet"}; you can use Beanshell pre-defined Parameters stanza.
Random random = new Random();
int i = random.nextInt(query.length);
vars.put("randomOption",bsh.args[i]);
I know this is an old post and there is a new function available:
__RandomFromMultipleVars(animalCat|animalDog|animalParakeet, query)
somewhere you need to define the variables:
animalCat=cat
animalDog=dog
animalParakeet=parakeet
It looks like this is not a feature of Jmeter natively. I'm using a plugin that accomplishes this goal. http://jmeter-plugins.org/wiki/Functions/ implements a new function that lets you choose a random string from a list of strings. From their website:
${__chooseRandom(red,green,blue,orange,violet,magenta,randomColor)}
See also:
Get random values from an array
This however requires writing some code in a PreProcessor.

Resources