jMeter beanshell - How to calculate a number with milliseconds variable - jmeter

I have a javaScript variable says:
${__javaScript(Math.round(new Date().getTime() / 1000 -18000 )*1000)}
My beanshell code is:
start = vars.get ("startTime-5");
newStart = start + 1000;
startTime-5 is the var for the javaScript code.
When I print newStart I expect to get the calculation of start+1000, but instead what I get is adding "1000" as a string.
For example, if start=14456789000 - what I get is 144567890001000 instead of 14456790000

As per Beanshell Intro
BeanShell emulates typed variables and parameters when they are used. This allows you to "seed" your code with strong types where appropriate. You can "shore up" repeatedly used methods as you work on them, migrating them closer to Java. Eventually you may find that you want to compile these methods and maintain them in standard Java. With BeanShell this is easy. BeanShell does not impose a syntactic boundary between your scripts and Java.
So think of Beanshell as of Java.
Something like:
long start = Long.parseLong(vars.get("startTime-5"));
long newStart = start + 1000;
vars.put("newStart", String.valueOf(newStart)); // if you need the JMeter Variable
should do the trick for you.
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for more detailed information on Beanshell scripting in JMeter and for a kind of Beanshell cookbook.

Related

Jmeter - How to loop until certain integer - 'While contoller' nested in the 'Loop contoller'

My Architecture is like this:
From JsonPath I extract all the programID's like:
When Executed is like this:
The question is: How to tell the while controller is loop until programId 80?
What I tried is:
Any help is appreciated
I think correct __groovy() function would be something like:
${__groovy((vars.get('programId_' + vars.get('Counter')) as int) > 80,)}
in general I wouldn't recommend inlining JMeter Functions or Variables into Groovy scripts as it's bad for performance and may cause issues, go for code-based equivalents instead, in the above example vars stands for JMeterVariables class instance, see Top 8 JMeter Java Classes You Should Be Using with Groovy
A better option would be amending your JSONPath query to return IDs which are above 80, see Filter Operators
Thanks Dmitri T for your direction.
The honey for me in this case was the alteration the JSON path expression to:
$..pageItems[?(#.programId>80)].programId
Like this I was able to filter all the programId higher than 80.

unable to print Beanshell response in log file and cmd

I am trying to print the below code in Beanshell PostProcessor
but i am getting
Code : log.info(ctx.getPreviousResult.getTime());
Error Message: Cannot access field: getPreviousResult
JMeterContext.getPreviousResult() is a function, not field, you need to add parentheses after it
You cannot print a Long value to jmeter.log directly, you need to cast it to String first
There is prev shorthand which stands for parent SampleResult so you can actually shorten your code
Assuming all above amend your code to:
log.info(prev.getTime().toString());
Also be aware that starting from JMeter 3.1 it's recommended to use JSR223 Test Elements and Groovy language mostly because Groovy has much better performance comparing to Beanshell so consider migrating to JSR223 PostProcessor on next available opportunity, you will not have to change the code.
getPreviousResult is a method so syntax is:
ctx.getPreviousResult().getTime()
So you code should be:
log.info("{}", ctx.getPreviousResult().getTime());

Jmeter. __base64Encode function doesn't encode in JSR223 Sampler

Every time I need to achieve something in Jmeter, I ask a question in SO...
To make a story short: my goal is to read Base64 encoded values from csv file line by line and save them into separate variables. According to this page (in order to decode them), there are functions ${__base64Encode} and ${__base64Decode}. I installed Custom Jmeter Functions Plugin and restarted the Jmeter. Another referral to this answer, there is an advisory to use JSR223 PostProcessor / Sampler, verbatim:
it is recommended to use Groovy for any form of scripting to consider
migrating to JSR223 PostProcessor
so I decided to give it a try. Below is my script to read csv files:
def csvFileLocation = new File("C://JohnDoe//MyWork//sensitive_data.csv")
def lines = csvFileLocation.readLines()
lines.eachWithIndex {line, idx ->
vars.put("Id_value_" + idx, line)
}
${__base64Decode(${Id_value_0}, first_variable)}
${__base64Decode(${Id_value_1}, second_variable)}
${__base64Decode(${Id_value_2}, third_variable)}
Then I saw something interesting:
2018-01-01 12:30:60,767 ERROR o.a.j.p.j.s.JSR223Sampler: Problem in
JSR223 script JSR223 Sampler, message: javax.script.ScriptException:
org.codehaus.groovy.control.MultipleCompilationErrorsException:
startup failed: Script10.groovy: 8: unexpected token: ! # line 8,
column 1. !ßïj[žÿ
I simply decided to test it on https://www.base64encode.org/ with a string this is the test of base64 encoding
However, Jmeter _base64Encode function produces completely different result:
vars.put("jmeter_variable", "this is the test of base64 encoding");
${__base64Encode(${jmeter_variable}, my_variable)}
log.info(${my_variable});
OUTPUT:
JHtqbWV0ZXJfdmFyaWFibGV9
My question: what type of encoding algorithm Jmeter uses? Should I be able to save already encoded values into the csv file and retrieve them to the original value with the help of __base64Decode function? Thanks for the help...
You need to replace these lines:
${__base64Decode(${Id_value_0}, first_variable)}
${__base64Decode(${Id_value_1}, second_variable)}
${__base64Decode(${Id_value_2}, third_variable)}
With these ones:
vars.put('first_variable', vars.get('Id_value_0').decodeBase64() as String())
vars.put('second_variable', vars.get('Id_value_2').decodeBase64() as String())
vars.put('third_variable', vars.get('Id_value_2').decodeBase64() as String())
vars is a shorthand for JMeterVariables class instance, it provides read/write access to JMeter Variables in current test element's scope.
As per JSR223 Sampler documentation you should avoid inlining JMeter Functions and/or variables into Groovy scripts as they may resolve into something which can cause your script compilation failure (like in your case) or unexpected behaviour. Moreover it does not align with Groovy's compilation caching feature therefore performance of your Groovy script even if everything will be fine from syntax perspective will be a big question mark.
So the most "natural" way from Groovy perspective will be using String.decodeBase64() function like demonstrated above. See The Groovy Templates Cheat Sheet for JMeter article to learn what else could be done with Groovy and how.

Jmeter : random number with beanshell

I want to add 2 kind of parameters to a post request.
From an http request I extract 2 list of variables:
Order_id = input type="hidden" name="(drag.+?)" value="(\d+?)"
Weight_id = class="draggableviews-weight form-select" id=".+?" name="(drag.+?)"
In the Post Request that follows, I need to repost all this variables. I use a BeanShell PreProcessor for this. The first list is no problem, since this get the same value. The second list should get a new random value between -50 and 50. I also want a different random value for each iteration.
How should I do this ?
If I use Random Variabele Config Element I get the same random int for each variabele. I want a different one for each iteration.
enter image description here
I would recommend using ThreadLocalRandom.nextInt() method like
sampler.addArgument(name2, String.valueOf(java.util.concurrent.ThreadLocalRandom.current().nextInt(-50, 51)));
Don't inline JMeter Functions into Beanshell scripts, either pass them via "Parameters" section and refer via Parameters or args shorthands or use appropriate code-based substitutions.
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for more information on Beanshell scripting in JMeter tests.
To retrieve multiple values from single Regular Expression Extractor, we use Templates as follows:
then refer groups as follows:
In the image, you can see that link is Reference Name and there is only match found with the regular expression.
number of matches is : link_matchNr
first group value : link_1_g1
second group value : link_1_g2
Note: The regular expression I tried on is google.com, you can also simulate the same as follows:
Use Random function as follows:
value2 = ${__Random(-50,50)};
log.info("valuee2 " + value2);
Use Random Variable:
then, refer Output Variable in Beanshell Preprocessor as follows:
value2 = vars.get("randomInt");

JMeter unescapeHtml on a variable value

If I have a BeanShell PostProcessor with the following script:
vars.put("avar", ${__unescapeHtml("<escele>esceleValue</escele>")});
vars.put("bvar", "<escele>esceleValue</escele>");
vars.put("cvar", ${__unescapeHtml(vars.get("bvar"))});
I get the following in the Debug PostProcessor:
avar=<escele>esceleValue</escele>
bvar=<escele>esceleValue</escele>
cvar=<escele>esceleValue</escele>
I would expect cvar's value to match avar's value. Is there a way to do this?
Ultimately I am trying to get a statement like the following to work with escaped XML in the response data. In the process I tried PostProcessor extractors that successfully put all the response data in a variable and then tried to unescape the variable as in the above test case. I assume the issue is the same using a variable or using "prev.getResponseDataAsString()".
vars.put("avar", ${__unescapeHtml(prev.getResponseDataAsString())});
I would recommend stop inlining JMeter Functions and/or Variables into scripting-enabled test elements as it may cause unexpected behaviour w.r.t ValueReplacer and in case of JSR223 Sampler and Groovy language will definitely lead to performance degradation as scripts containing variables and functions references cannot be compiled into bytecode.
Given you:
Already using Beanshell
Know that __unescapeHtml() function is using StringEscapeUtils under the hood according to the function documentation
Why just not to call code directly like:
import org.apache.commons.lang3.StringEscapeUtils;
vars.put("avar", ${__unescapeHtml("<escele>esceleValue</escele>")});
vars.put("bvar", "<escele>esceleValue</escele>");
vars.put("cvar", ${__unescapeHtml(vars.get("bvar"))});
vars.put("dvar", StringEscapeUtils.unescapeHtml4(vars.get("bvar")));
log.info(vars.get("dvar"));

Resources