Jmeter JSR223 Unable to read data from CSV file - performance

Requirement is ItemID should be read from external CSV file and passed in the JSR223 preprocessor script. This is the groovy code in JSR223 and it is working as expected in the grrovy executer.
def items = []
List<String> lines = new File("C:\\Users\\854986\\itemid.csv").readLines()
def itemNo = RandomUtils.nextInt(5, 10)
1.upto(itemNo) { index ->
def item = [:]
def lineFromCsv = lines.get(index as int)
item.put('itemId', lineFromCsv)
But it jmeter it is throwing error and below is the error message.
"2022-11-15 12:34:14,398 ERROR o.a.j.m.JSR223PreProcessor: Problem in JSR223 script, JSR223 PreProcessor 3
javax.script.ScriptException: org.apache.commons.jexl2.JexlException$Parsing: JsonBuilder#1:20 parsing error near '... ment, miss ...'
at org.apache.commons.jexl2.scripting.JexlScriptEngine.compile(JexlScriptEngine.java:237)"./
I have java 19.0.1, Jmeter 5.4.3 and groovy 4.0.2.

You're talking about "groovy code". Any reason to use jexl2 language in the JSR223 PreProcessor?
Make sure to choose groovy as the language and at least this error should go away. Groovy is the recommended scripting option since JMeter 3.1 mainly because Groovy provides maximum performance comparing to other engines

Related

Jmeter : validating a log viewer result with sampler

I am executing a jp#gc - WebDriver Sampler script in which console - log view i am getting a result in text for example check the below image INFO c.g.j.p.w.s.WebDriverSampler: Result1:Image not present
I need to validate the webdriver sample from that result . Any suggestion pls
If you really want to read jmeter.log file and look for the specific message in there you could do something like:
def log = org.apache.commons.io.FileUtils.readFileToString(new File('jmeter.log'), 'UTF-8')
if (org.apache.commons.lang3.StringUtils.containsIgnoreCase('Banner not present', log)) {
WDS.sampleResult.setSuccessful(false)
WDS.sampleResult.setResponseMessage('Failed to locate message "Banner not present" in the log')
}
where WDS.sampleResult stands for SampleResult implementation and you can amend response code, message, mark the sampler as passed or failed and so on.
however it's better to do it on Groovy variable level, i.e.
if (!k) {
WDS.sampleResult.setSuccessful(false)
}
you can also consider relying on Groovy Truth, there is no need to declare booleans
More information on Groovy scripting in JMeter: Apache Groovy: What Is Groovy Used For?

How to pass a 2-D array from one thread to another thread in Jmeter

So I am using a bean shell post processor and towards the end I am storing the result in a 2-D array. Result is stored this way.
testArray[0][0] = "1"
testArray[0][1] = "Test"
testArray[1][0] = "2"
testArray[1][1] = "STG"
My requirement is that I need to pass this 2-D array to the next thread. How am I supposed to proceed ?
First of all since JMeter 3.1 you're supposed to be using JSR223 Test Elements and Groovy language for scripting so consider migrating to Groovy.
Coming back to your question just use props shorthand like:
In first thread:
props.put("testArray", testArray);
in the other thread:
testArray = props.get("testArray");
you might also want to add the current thread number as the prefix/postfix so different threads could have different arrays with separate values like:
props.put("testArray_" + ctx.getThreadNum(), testArray);
where ctx stand for JMeterContext class instance
More information on these ctx, props and other JMeter API shortcuts available for JSR223 Test elements: Top 8 JMeter Java Classes You Should Be Using with Groovy

JMeter - groovy MultipleCompilationErrorsException in JSR223 Sampler

I'm using groovy for JMeter JSR223 sampler . Below code is working fine from JMeter GUI.
String user = vars.get("username"); # abc.com\user1
String domainVal = ""
String userVal = ""
System.out.println(user)
if(user.contains("\\")){
String[] arrOfStr = user.split("\\\\", 2);
domainVal =arrOfStr[0]
userVal = arrOfStr[1]
}else{
userVal = user
}
System.out.println(domainVal)
System.out.println(userVal)
But same script I'm trying from JMeter headless is giving me error
Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script8.groovy: 20: Missing ')' # line 20, column 18.
if(user.contains("\")){
^
1 error
I am clueless , what is causing the issue .
Update
I found the root cause it is caused by , if I remove below line (Jmeter thread number) it's working fine. Not a groovy issue, JMeter issue for sure.
int thread_count = ${__threadNum};
Don't use JMeter function in JSR223 script, replacement for __threadNum:
int threadNum = ctx.getThreadNum()
The function returns a number between one and the max number of running threads. Note that if you're using JSR223 code with JMeterContext object (ctx variable), the below code returns a number between zero and (max number of running threads minus one)
ctx.getThreadNum()
I cannot reproduce your issue:
with regards to your int thread_count = ${__threadNum}; piece of "code", you shouldn't be inlining JMeter Functions or Variables into Groovy scripts because:
The syntax conflicts with Groovy's GString Template Engine
The values will be cached and re-used on next occurrence
So you should either use "Parameters" section or code-based equivalents
More information: JSR223 Sampler Documentation
where ctx stands for JMeterContext class, see Top 8 JMeter Java Classes You Should Be Using with Groovy article for more details on this and other JMeter API shorthands available for JSR223 Test Elements

Jmeter Debug Sampler | How to save all variable values to CSV

I am able to extract values for many variables and are showing in Debug Sampler.
Is there any way to save these all variable values to a CSV file?
I found a solution (using BeanShell script) to save multiple Jmeter variable to CSV but I want all variables values to a single CSV, so that I can use the CSV file for next thread run.
Here is the snapshot of one of the Debug Sampler:
enterCompanyname=APITENANT
CreateTenant_Status=Success
CreateTenant_Status_matchNr=1
Current_UTC_Time=2018-03-07T01:53:18.310Z
DB_DataSource=dev4574857
DB_Password=1234
DB_UserName=web
DeviceCount=19
DevicesPerUser=94
EXCELPATH=X:\QualityAssurance\XLSX_3 columns_1000 rows.xlsx
Email=apitenant#apitenant.com
EndDate=2018-12-31
Exist=false
Exist_matchNr=1
FirstName=API
JMeterThread.last_sample_ok=true
JMeterThread.pack=org.apache.jmeter.threads.SamplePackage#69ab73cf
LastName=TENANT
LicensePlan=Pro
LicenseType=Device
MaxUsers=11
Password=Password
Protocol=http
RandomNumber=10
Add JSR223 Sampler to your Test Plan (where you want variables to be saved)
Put the following code into "Script" area:
def csv = new File('vars.csv')
vars.entrySet().each {var ->
csv << var.key + '=' + var.value + System.getProperty('line.separator')
}
That's it, you will have vars.csv file created in JMeter's "bin" folder having all variables listed. You might also want to replace = with , for better CSV Data Set Config compatibility.
vars is a shorthand to JMeterVariables class instance, it provides read/write access to all JMeter Variables.
Also be aware that starting from JMeter 3.1 users are encouraged to switch to JSR223 Test Elements and Groovy language so consider migrating to Groovy as soon as it will be possible. See Apache Groovy - Why and How You Should Use It for more details.

How to create simple counter using Beanshell?

I'm trying to create a simple counter that will print the iteration number to the log.
the problem is that I didn't find a way to initialize the int value of i to 0.
if I'll do it inside the Beanshell script it will keep initializing, I need it to run only once at the beginning of the test.
My code:
int i=0;
log.info(string.valueOf(i));
i=i+1;
Add Once Only Controller, under it JSR223 Sampler with the initialization
vars.putObject("i", 0);
Then you can increment it after it (not under the Controller) with other JSR223 Sampler:
myI = vars.getObject("i")
log.info(String.valueOf(myI));
vars.putObject("i", ((Integer)myI+1));
It is recommended to avoid scripting where possible, and if you cannot live without scripting you should be using the most performing option which is JSR223 Test Elements and Groovy language.
Particularly your case can be implemented without any scripting, you can use the following JMeter Functions:
__log() - which prints an arbitrary message to jmeter.log file
__iterationNum() - which returns the number of current iteration
So if you use the statement like: ${__log(Current iteration is: ${__iterationNum},,,)} JMeter will return it where the function is called and additionally print the corresponding message to the log file.
Demo:
You can install __iterationNum() function as a part of Custom JMeter Functions bundle using JMeter Plugins Manager

Resources