How to log an error when a JDBC request returns no data from DB in Jmeter? - jdbc

I need to know how to log an error when a JDBC request returns no data from DB in Jmeter.
I have got:
JDBC request
Query:
SELECT names
FROM customers
Variable names:
namesCustomers
Then I have got a BeanShell postProcessor with script:
import org.apache.jmeter.util.JMeterUtils;
JMeterUtils.setProperty("namesCustomer", vars.get("namesCustomer_1"));
And finally a simple controller called "set variables" which calls an external file with the following code:
vars.put("namesCustomer",JMeterUtils.getProperty("namesCustomer"));
The problem is that in another SOAP request I am using the variable namesCustomer_1, and if no data is returned from DB this request fails. I need to log an error when the JDBC returns no data.
If I add to the post processor:
log.error("Error example");
I see the error logged in jmeter.log when this request is ran. I need something like:
if(JMeterUtils.setProperty("namesCustomer", vars.get("namesCustomer_1")).toString().length()==0){
log.error("DB returned no results")
}
Any Ideas on how to log an error when the JDBC request returns no data?

It can be done a little bit easier. If JMeter Variable is not set, it'll be null, not empty string.
So I would suggest amending your code as follows:
String namesCustomer = vars.get("namesCustomer_1");
if (namesCustomer == null) {
log.error("namesCustomer_1 variable is not set");
} else {
props.put("namesCustomer", namesCustomer);
}
props is a shorthand to access current set of JMeter Properties, there is no need to use JMeterUtils.setProperty() method.
See How to use BeanShell: JMeter's favorite built-in component guide for more details on Beanshell scripting in Apache JMeter and a kind of Beanshell cookbook.

Related

JMETER: Need to send all entries in a CSV file to HTTP request body in 'one' request

I'm trying to solve a test data issue in Jmeter. Can anyone of you have a look at below problem statement and advise here please ?
Requirement: Need to send all entries in a CSV file to HTTP request body in 'one' request to the end point.
Example CSV File:
"adsfas123wsf00000wqefqwe52145t10000",
"fdfrgvergq120947r0000dwsfqwaef237sadf",
"wfrqwef7865034r78tkahsefjh6985r7asfdaf",
"qefqwe52145t10000adsfas123wsf00000w",
"wsfqwaef237sadffdfrgvergq120947r0000d"
HTTP Request Body:
["${data}"}]
When the data is substituted, I should be able to get below output.
[
"adsfas123wsf00000wqefqwe52145t10000",
"fdfrgvergq120947r0000dwsfqwaef237sadf",
"wfrqwef7865034r78tkahsefjh6985r7asfdaf",
"qefqwe52145t10000adsfas123wsf00000w",
"wsfqwaef237sadffdfrgvergq120947r0000d"
]
Problem Statement: When I use CSV data set config. file, I'm unable to concatenate all entries into one single request body. My understanding is, CSV data set config. the file is not the right option here.
Did some search in StackOverflow and followed a method to achieve above using JSR223 PreProcessor' and the link is, How to send multiple json body using jmeter?.
Followed the above link and tried added below custom code provided.
def builder = new StringBuilder()
new File('/path/to/plans.csv').readLines().each { line ->
builder.append(new File(line).text).append(System.getProperty('line.separator'))
}
sampler.getArguments().removeAllArguments()
sampler.addNonEncodedArgument('', builder.toString(), '')
sampler.setPostBodyRaw(true)
Upon running, I get below error message,
Caused by: java.io.FileNotFoundException,
"adsfas123wsf00000wqefqwe52145t10000",
"fdfrgvergq120947r0000dwsfqwaef237sadf",
"wfrqwef7865034r78tkahsefjh6985r7asfdaf",
"qefqwe52145t10000adsfas123wsf00000w",
"wsfqwaef237sadffdfrgvergq120947r0000d" (The filename, directory name, or volume label syntax is incorrect)
If the file is not found, then how come the entries are read and displayed in the log viewer?
Also, how do I link the output of custom code to the request body? Or is it taken care of by the custom code itself?
You have an error in your code, change this line:
builder.append(new File(line).text).append(System.getProperty('line.separator'))
to this one:
builder.append(line).append(System.getProperty('line.separator'))
If you want to send the full contents of the file you don't even need to go for scripting, you can use __FileToString() function right in the "Body data" tab of the HTTP Request sampler:
${__FileToString(/path/to/plans.csv,,)}
And last but not the least if you need to generate JSON from the plain text it might be a better idea to go for JsonBuilder class, see Apache Groovy - Why and How You Should Use It and Apache Groovy - Parsing and producing JSON
Two steps:
Add a User Parameter Pre-processor before the HTTP request:
Name: DATA
User_1: ${__FileToString(/path/to/plans.csv,,)}
Add the following to request body:
${DATA}

Using JMETER GUI JDBC Request with Callable Statement – how do I getResultSet/MetaData?

I’ve got a call to my database working as a SQL select statement. But I am working to call a stored procedure using JMeter for further testing. I’m strictly working off of the JMX files and do not have JMETER integrated into our main Java project at this time.
I’ve setup the JMETER GUI with the JDBC Connection Configuration and the JDBC Request. I’ve made a successful call to my database with my callable statement with my string INPUT and get the string OUTPUT parameter string.
The OUTPUT parameter string only contains information about the call (user,system, success, etc…), but none of the values/data from the table -- which are found in the ResultSet/MetaData. But I cannot figure out how to get the ResultSet or the Metadata using the JDBC Request in JMETER.
In Java, I know I use the statement and just call statement.getResultSet() and perform a loop while resultSet.next() exists. How do I do this in JMETER?
I've tried adding an additional out parameter but then my statement rejects the call, because there is only one in-parameter. I've tried a variety of JMeter Assertions - but because the main call is only returning the out parameter, I cannot grab additional data.
Query: call XXXXX.readUser(?)
Parameter Values: ${inputJSONString}
Parameter Types: INOUT VARCHAR
Variable Names: ouputJSONString
Result Variable Name: ouputJSONString
View Results Tree: Response code: 200, Response message: OK, Output variables by position: Contains the whole JSON out parameter string with user, system, and success. Returns the table column headers but no values.
I do not have errors - the call is being made successfully. I just cannot figure out how to access the Result Set from JMETER.
Don't use the same reference name for the Variable Names and the Result Variable Name as the latter one will be overwritten.
So
Change ouputJSONString to i.e. ouputJSONStringObject
Add JSR223 PostProcessor as the child of the request
You will be able to access the JMeter's representation of the ResultSet as vars.getObject('ouputJSONStringObject') (basically ArrayList of HashMaps
See Debugging JDBC Sampler Results in JMeter article for more details.
Unfortunately you cannot access the normal ResultSet as it is not exposed anywhere and being converted via private function

How to modify HTTP request before sending in JMeter through Beanshell pre processor?

I have test case in my csv file. The request URL has a custom variable.
Sample URL : .../abc/$id
I need to replace this id by the id that we get in response from the previous request. I used json extractor to fetch the id from the response. Now I need to update this id in the next test case request. Fetched the Request URL from jmeter context using below code:
String path = ctx.getCurrentSampler().toString();
path.replaceAll("$id", id);
I am not able to set this updated URL in jmeter context (ctx)
You need to assign new path value to path variable
You need to set sampler path to the new value using sampler.setPath() method
So you need to amend your code like:
String path = ctx.getCurrentSampler().toString();
path = path.replaceAll("$id", id);
sampler.setPath(path);
Demo:
Also consider switching to JSR223 PreProcessor and Groovy language as Groovy performance is much higher, it better supports new Java features and provides some extra "syntax sugar" on top. See Groovy is the New Black article for details.
Try to avoid the pre / post processors if possible.
Your requirement is very simple and straight forward.
Directly use this in the path - assuming id is the name of variable which has the value.
/abc/${id}

Using BeanShell Assertion for saving failed response

I'm trying to save the response of failed requests into log but unsuccessfully.
I have HTTP requests which each one has its own Response assertion, and once in a while through my load test a response doesn't meet the requirements of the Response Assertion, so I want to fail it.
I tried to add this code to the BeanShell Assertion following this post:
if (Boolean.valueOf(vars.get("DEBUG"))) {
for (a: SampleResult.getAssertionResults()) {
if (a.isError() || a.isFailure()) {
log.error(Thread.currentThread().getName()+": "+SampleLabel+": Assertion failed for response: " + new String((byte[]) ResponseData));
}
}
}
The Test plan itself looks like this:
In user defined variables I've added the following:
Name: DEBUG
Value: (none)
I ran this program through the non GUI mode - cmd and on purpose made a response fail (response assertion failed it) but I did not get any error response logged to my log file.
What am I doing wrong?
thanks
First of all if your goal is to just save failed responses, together with assertion results, you don't need any custom code. You can add Simple Data Writer configured like this:
Option 2: If you want to write responses into the log file, then you need custom script. But in that case I'd suggest using BeanShell Listener (unlike assertions and other objects, there's only 1 instance of listener for all threads, so it's more economical, and less chance to create a bottleneck at log writing).
Also according to your script, the value of DEBUG must be true, but as you mentioned, you did not set it to true (empty string will be resolved to false by Java's valueOf). So change it to
Name: DEBUG
Value: true
Here's how such BeanShell Listener's script looks:
if (Boolean.valueOf(vars.get("DEBUG"))) {
for (a: sampleResult.getAssertionResults()) {
if (a.isError() || a.isFailure()) {
log.error(sampleResult.getThreadName() + ": "
+ sampleResult.getSampleLabel() + ": Assertion failed for response: "
+ sampleResult.getResponseDataAsString());
}
}
}
Option 3 is to stay with your original solution, then you need to fix the variable assignment (as I mentioned before).
I would rather let JMeter do this automatically, it is the matter of a couple of properties, to wit:
First of all, you need to tell JMeter to store its results in XML format:
jmeter.save.saveservice.output_format=xml
Second, you can amend the following property values to configure JMeter to store assertion failure message and data into .jtl results file
jmeter.save.saveservice.assertion_results_failure_message=true
jmeter.save.saveservice.assertion_results=all
Probably the most useful option: simply save response data for failed samplers:
jmeter.save.saveservice.response_data.on_error=true
The above properties can be either put into user.properties file (located in JMeter's "bin" folder, JMeter restart is required to pick the changes up) or you can pass them via -J command line argument like:
jmeter -Jjmeter.save.saveservice.output_format=xml -Jjmeter.save.saveservice.response_data.on_error=true ....
See Apache JMeter Properties Customization Guide for more information on working with JMeter Properties to tune various aspects of JMeter configuration

Extracting value from jmeter post request

I want to extract value of the parameter sent through post request in jmeter.
I know the use of regular expression for extracting response value or request URL but here I would like to extract the value of post request.
I've been thorough how to extract value from request in Jmeter but it didn't worked.
Not sure why do you need it as given you sending "something" you should already have that "something" hence you don't need to extract it, however here you go:
In order to save 1st parameter value (or the whole post data if you use "Body Data" mode):
Add Beanshell PostProcessor as a child of the HTTP Request.
Put the following code into the PostProcessor's "Script" area:
String request = ctx.getCurrentSampler().getArguments().getArgument(0).getValue();
vars.put("request", request);
You will be able to access extracted value as ${request} where required.
Clarifications:
ctx - shorthand for JMeterContext class instance
getCurrentSampler() - in case of HTTP Request sampler stands for HTTPSamplerProxy
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for more information on using JMeter and Java API from Beanshell test elements in your JMeter test.
I added a Beanshell PostProcessor in my http request with following code.
import org.apache.jmeter.config.Argument;
import org.apache.jmeter.config.Arguments;
Arguments argz = ctx.getCurrentSampler().getArguments();
for (int i = 0; i < argz.getArgumentCount(); i++) {
Argument arg = argz.getArgument(i);
String a = arg.getValue();
vars.put("EMAIL",a);
}
Explanation: I get a my request as a json and put it in EMAIL. Now I can use EMAIL as a variable in my other request.
Then, I added a jp#gc Json Path Extractor and I applied it to a Jmeter Varaible.
Now, Email will be used as variable, which contains my json request and I can extract using jsonPath Extractor.
An easy way to do this is using the JSON Path Extractor.
There are just
For the example you gave
{ "data" : { "name" : "john_doe", } }
'Variable Name: YourNewVar'
'JSON Path: $.data.name'
Should work, but you may need to do some experimenting.
You may want to add a "debug sampler" (its one of the standard samplers) and put in its title $YourNewVar so you can see what is being extracted.
Beanshell and "Regular Expression Extractor" will work, of course, but may be a little harder to use if you are not familiar with them.

Resources