JMeter BeanShell Assertion: Getting error when convert String to Long - jmeter

Have a need to change the value from String to Long in BeanShell Assertion to do verification.
First Apporach
long balance_after_credit = Long.parseLong(String.valueOf("${balance_after_credit_from_db}"));
Second Approach
long balance_after_credit = Long.parseLong(vars.get("balance_after_credit_from_db"));
For instance, consider am getting a value as '743432545' for the variable balance_after_credit_from_db.
Error
org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval Sourced file: inline evaluation of: ``long token_balance_after_credit = Long.parseLong(vars.get("token_balance_after_c . . . '' : Typed variable declaration : Method Invocation Long.parseLong
Weird thing is sometimes, I didn't get errors and the script is getting passed.
Can anyone please point out where am doing a mistake. TIA.

Inlining JMeter variables into code-based scripts is not something recommended so go for 2nd approach.
How do you know that exactly String is being returned from the database all the time? It easily can be any other object type, in fact any of described in the Mapping SQL and Java Types article. The way more safe approach will be something like:
if (vars.getObject("balance_after_credit_from_db") instanceof String) {
long balance_after_credit = Long.parseLong(vars.get("balance_after_credit_from_db"));
}
else {
log.error("Unexpected \balance_after_credit_from_db\" variable type");
log.error("Expected: String, Actual: " + vars.getObject("balance_after_credit_from_db").getClass().getName());
throw new Exception("Unexpected variable type");
}
So in case of non-String JDBC query result you will be able to see the relevant message in jmeter.log file
See Debugging JDBC Sampler Results in JMeter article for more information on working with the entities coming from databases in JMeter tests

The second option
long balance_after_credit = Long.parseLong(vars.get("balance_after_credit_from_db"));
should work, provided you have a valid numeric variable value. For instance try to run something like this:
vars.put("x", "743432545");
long balance_after_credit = Long.parseLong(vars.get("x"));
It won't return any exception.
The problem is when the variable is not defined, has empty or non-numeric value. Then Long.parseLong will throw a NumberFormatException, which you shold catch and make use of (treat it as assertion failure):
String rawValue = vars.get("balance_after_credit_from_db");
long balance_after_credit = Long.MAX_VALUE; // initialize with some unrealistic value
try {
balance_after_credit = Long.parseLong(rawValue);
}
catch(NumberFormatException e) {
Failure = true;
FailureMessage = "Variable does not contain a valid long. It was " + rawValue + " instead";
}

Related

Getting issue while comparing one property to another in JMeter

In my JMeter test plan, I want to set a flag in case of failure in every HTTP request. So I created a JSR223 PostProcessor in request with the following snippet:
if (!prev.isSuccessful()) {
int abc = 1
props.put('result', vars.get('abc'))
}
where result is defined as global in the thread.
In teardown I want to exit JMeter by comparing with the value of the flag . So I am doing the following:
if ((props.get('result') as int) == 1) {
System.exit(1);
}
Can anyone help me what wrong I am doing in this? Is there any other way by which I can do this.
This statement vars.get('abc') will return null because you just declare an integer called abc and not writing it to JMeter Variables.
You need to amend your code to something like:
if (!prev.isSuccessful()) {
int abc = 1
props.put('result', abc)
}
also there is no need to cast it to the integer back, it's stored as the object of the given type
if (props.get('result') == 1) {
System.exit(1);
}
More information:
Properties aka props
JMeterVariables aka vars
Top 8 JMeter Java Classes You Should Be Using with Groovy
You may also find AutoStop Listener useful

How to return a value from database in jmeter

I am trying to return a value from MSSQL server database and storing it in a variable inside JSR223 timer script in Jmeter. However I am getting the following error in log -
**WARN o.a.j.t.JSR223Timer: Script did not return a value
**
This is the code which i have written in the script -
try {
def promoName = ${promotionName}; //extracted the value using JSONExtractor
log.info("Promotion Name is " + promoName); //not displaying in the log
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection con = DriverManager.getConnection("jdbc:sqlserver://ServerIP;databaseName="";integratedSecurity=true","<userId>","<password>");
String query ="select query";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
vars.put("promotionInstanceId", rs.getString(1)); //The query returns an instanceId which i need to store in a variable and use it later
log.info("Promotion Instance is " + ${promotionInstanceId});
}
conn.close();
}
catch (Exception e) {
e.printStackTrace();
Can anyone help me in understanding where i might have gone wrong ?
Any reason to use the timer? The warning you're getting is about missing return keyword as the JSR223 Timer is intended to be used for calculation of virtual user think time therefore it should return the value to "sleep" in milliseconds. Given you don't want to introduce the think time it makes sense to go for JSR223 PostProcessor instead.
Don't inline JMeter functions or variables into the scripts as it might cause script misbehavior due to clashing with GString template or the variable will be cached and the same value will be returned for the subsequent calls.
It is recommended to use JMeter's built-in components and avoid scripting where possible, you can use i.e. JDBC PostProcessor in order to extract the interesting value(s) and store it(them) into JMeter Variables. Check out Debugging JDBC Sampler Results in JMeter article to learn how to execute SQL statements and work with results
You should use vars.get to get variable value
vars.put("promotionInstanceId", rs.getString(1)); //The query returns an instanceId which i need to store in a variable and use it later
log.info("Promotion Instance is " + vars.get("promotionInstanceId"));

Writing null values into parquet file with mapper

I am trying to do the following:
String x=null;
Group group = factory.newGroup()
.append("x", x);
context.write(null,group)
With the following scheme:
String writeSchema = "message example {\n" +
"optional binary x;\n" +
"}";<br>
But I get NullPointerException in the append line. Maybe I am missing something in the scheme?
Here the String object itself is null. While writing to the filesystem it tries to get the value of the object which is causing the NullPointerExeception.
String x =null;
System.out.println(x.toString()); // Will cause a NullPointerExeception
Similarly any function call to the object will cause the same.
Try using String x ="null" instead

Jmeter: Typed variable declaration : Method Invocation Double.parseDouble

Hey I'm doing some beanshell scripting for API testing in jmeter. I've written quite a few jmeter scripts with beanshell and it works fine when using Integer.parseInt() method invocation, but I have a value with decimal places where my SQL returns a value of 20.00000 and my Json path extractor gets 20.0 so my test fails when comparing it. Because of this problem I decided to compare this values as double variables instead of Strings but I'm getting the error bellow when using Double.parseDouble on BeanShell.
2016/08/17 12:48:45 ERROR - jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: print("Width Assertion..."); int Total_Printers_SQL = Integer.parseInt(vars.get . . . '' : Typed variable declaration : Method Invocation Double.parseDouble
2016/08/17 12:48:45 WARN - jmeter.assertions.BeanShellAssertion: org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval Sourced file: inline evaluation of: print("Width Assertion..."); int Total_Printers_SQL = Integer.parseInt(vars.get . . . '' : Typed variable declaration : Method Invocation Double.parseDouble
Even with the errors displayed the value of the double variable is printed on Jmeter prompt as you can see below.
If anyone's a beanshell expert and could help me identify the error, that'd be awesome. Thanks!
If the number you get is not a valid Double (1.2s for example, or just null), you will get such exception. The cure is either checking that the value is double by RegEx, or simply trying to parse, and catching exception (note that Beanhell does not pass exceptions properly, so you will have to check for any exception, so it's better to limit it to that one line):
double x = 0.0; // default value
String value = vars.get("myVar");
try
{
x = Double.parseDouble(value);
}
catch(Exception e)
{
log.info("Cannot parse " + value + " as double");
}

Capture time difference between values of two regular expression reference names in Jmeter

I defined regular expressions in my JMeter test plan and I'm able to capture the values in simple variables in user.variables. But I'm trying to calculate the time difference between two variables as follows in Beanshell post processor and I'm not getting any result in my report.
import javax.xml.bind.DatatypeConverter;
vars.put("old_date_submitted", "submittedDate"); // submittedDate, succeeddedDate and runningDates are regular expr. reference names
vars.put("old_date_succeeded", "succeededDate");
vars.put("old_date_running", "runningDate");
Calendar cal_s = DatatypeConverter.parseDateTime(vars.get("old_date_submitted"));
Calendar cal_c = DatatypeConverter.parseDateTime(vars.get("old_date_succeeded"));
Calendar cal_r = DatatypeConverter.parseDateTime(vars.get("old_date_running"));
Date new_date1 = cal_s.getTime(); // submitted Time
Date new_date2 = cal_c.getTime(); // succeeded Time
Date new_date3 = cal_r.getTime(); // running Time
long new_date1_ms = new_date1.getTime(); // submitted Time
long new_date2_ms = new_date2.getTime();
long new_date3_ms = new_date3.getTime();
log.info("Date in milliseconds: " + new_date1_ms);
long delta1 = new_date2_ms - new_date1_ms; //calculate the difference (succeededDate - submittedDate)
long delta2 = new_date3_ms - new_date1_ms; //calculate the difference (runningDate - submittedDate)
vars.put("delta1", String.valueOf("delta1")); // store the result into a JMeter Variable
vars.put("delta2", String.valueOf("delta2")); // store the result into a JMeter Variable
This bit:
vars.put("old_date_submitted", "submittedDate"); // submittedDate, succeeddedDate and runningDates are regular expr. reference names
vars.put("old_date_succeeded", "succeededDate");
vars.put("old_date_running", "runningDate");
seems odd to me. Given:
submittedDate, succeeddedDate and runningDates are regular expr. reference names
My expectation is that you should be using JMeter Variables instead of hardcoded strings there, so you should change your code to look like:
vars.put("old_date_submitted", vars.get("submittedDate")); // submittedDate, succeeddedDate and runningDates are regular expr. reference names
vars.put("old_date_succeeded", vars.get("succeededDate"));
vars.put("old_date_running", vars.get("runningDate"));
So most likely your code is failing at DatatypeConverter.parseDateTime.
Next time you face any problem with your Beanshell scripts consider the following troubleshooting techniques:
Check jmeter.log file - in case of Beanshell script failure the error will be printed there
Add debug(); directive to the very beginning of your Beanshell script - it will trigger debugging output to stdout
Put your Beanshell code in try/catch block like:
try {
//your code here
}
catch (Throwable ex) {
log.error("Something went wrong", ex);
throw ex;
}
This way you get more "human-friendly" stacktrace printed to jmeter.log file.
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for more information on using Beanshell in JMeter tests.

Resources