As part of my jMeter scenario, I got gzipped xml from server.
I've tried to add header Accept-encoding: gzip,deflate,sdch but it seems to have no effect.
How can I deflate it in order to use XPath extractor on it?
Thanks
If your question is about how to convert gzip-compressed response to plain XML, it can be done using Beanshell PostProcessor
Beanshell PostProcessor execution time is not included into parent sampler response time. It is executed after sampler and in your case can be used to decompress response and substitute parent sampler's response body with decompressed XML.
Sample code for the Beanshell PostProcessor:
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
ByteArrayInputStream bis = new ByteArrayInputStream(data);
GZIPInputStream gis = new GZIPInputStream(bis);
InputStreamReader reader = new InputStreamReader(gis);
BufferedReader in = new BufferedReader(reader);
byte[] decompressed = IOUtils.toByteArray(in);
prev.setResponseData(decompressed);
where
data - is a shorthand to byte array containing parent sampler response body
prev - represents SampleResult instance access, SampleResult provides read/write access to information recorded during sampler execution.
See How to use BeanShell: JMeter's favorite built-in component guide for more information on Beanshell scripting in Apache JMeter, detailed explanation of pre-defined variables like "data" or "prev" and some useful examples.
Related
I have a web-service which return the encoded pdf but when i try to extract the data in it by using regular expression extractor(JMeter) it does not extract. I check the value of variable, it shows null value. I googled various sites but didn't succeed. After extracting the data i will save this in to one file.
I googled and refer various sites but didn't succeed. Below here are some references:
https://dzone.com/articles/how-to-read-a-pdf-file-in-apache-jmeter
https://www.blazemeter.com/blog/what-every-performance-tester-should-know-about-extracting-data-files-jmeter/
i got nothing in my variable when i see in debug sampler.
If you want to extract text from the PDF file into a JMeter Variable the only way of doing this is using JSR223 PostProcessor and PDFBox
Download tika-app.jar and put it to JMeter Classpath
Restart JMeter to pick the .jar up
Add JSR223 PostProcessor as a child of the request which returns the PDF
Put the following code into "Script" area:
def handler = new org.apache.tika.sax.BodyContentHandler();
def metadata = new org.apache.tika.metadata.Metadata();
def inputstream = new ByteArrayInputStream(prev.getResponseData());
def context = new org.apache.tika.parser.ParseContext();
def pdfparser = new org.apache.tika.parser.pdf.PDFParser();
pdfparser.parse(inputstream, handler, metadata, context);
vars.put('pdfText', handler.toString())
That's it, you should have the text from the PDF file as ${pdfText} JMeter Variable
More information:
PDFBox Examples
Apache Groovy - Why and How You Should Use It
I can successfully create a summary report in jmeter but in the label column i need the full get request along with parameters passed.I am not getting the parameters passed in the url.
You can get it automatically populated with the help of Beanshell scripting.
Example:
Add Beanshell PostProcessor as a child of HTTP Request
Put the following code into the PostProcessor's "Script" area:
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.testelement.property.PropertyIterator;
import org.apache.jmeter.testelement.property.JMeterProperty;
HTTPSamplerProxy sampler = (HTTPSamplerProxy) ctx.getCurrentSampler();
StringBuilder builder = new StringBuilder();
builder.append(sampler.getUrl());
Arguments args = sampler.getArguments();
PropertyIterator iter = args.iterator();
while (iter.hasNext()) {
builder.append (iter.next().getStringValue());
}
prev.setSampleLabel(builder.toString());
Run your test.
The code fetches URL and all parameters along with their values and updates parent sampler name with these values:
As you can see HTTP Request became http://example.com/foo=bar
You can place the PostProcessor at the same level as HTTP Request samplers to avoid copy-pasting it multiple times or use i.e. Beanshell Listener or Beanshell Assertion instead.
See How to use BeanShell: JMeter's favorite built-in component guide for comprehensive information on using scripting in JMeter and to learn what all these things like ctx and prev mean.
I am load testing an API using Jmeter. The Header of the request has an authentication request which needs me to Base64 the url+Nonce+Unix timestamp and SHA256 the resultant value with a secret key.
The above needs to be passed in header along with Nonce and timestamp.
For the above scenario should I create a custom function or use any preprocessor ?
You can do it via Beanshell PreProcessor as follows:
Add a HTTP Header Manager as a child of your HTTP Request sampler
Add aforementioned Beanshell PreProcessor the same way
Put the following code into the PreProcessor's "Script" area:
import org.apache.commons.httpclient.auth.DigestScheme; // necessary imports
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.jmeter.protocol.http.control.Header;
String url = sampler.getUrl().toString(); // get URL
String nonce = DigestScheme.createCnonce(); // get nonce
long timestamp = System.currentTimeMillis() / 1000L;
String combined = url + nonce + timestamp; // put everything together
byte[] base64 = Base64.encodeBase64(combined.getBytes()); // encode as Base64
String headerValue = DigestUtils.sha256Hex(base64); // encode SHA256
sampler.getHeaderManager().add(new Header("headerName", headerValue)); // add generated header to request
sampler here is a shorthand reference to parent HTTP Request Sampler class which I believe is HTTPSamplerProxy so its methods are used to get URL and add generated header value.
methods to generate MD5 hash and SHA256 hex are from Apache Commons libraries which are widely used under JMeter's hood.
See How to use BeanShell: JMeter's favorite built-in component guide for more information on using Beanshell scripting in JMeter tests.
Your best bet is to use a BSF Pre-Processor in JavaScript mode to do everything the client normally would. You'll have to take the client JS and modify it to work without FORM data.
You can build the entire header in JS exactly like a client would. BSF Pre-Processor allows you to access jmeter run-time variables, so you would create a new one to store the SHA256 hash value, and use that in a HTTP Header Manager of the sample that needs the authorization.
-Addled
Downloaded eclipse.
Wrote a custom jmeter package.
Exported it as a .jar from eclipse to jmeter lib/ext folder.
Called the package function in beanshell sampler
Thanks for your answers
#dmitrit's answer is helpful but I needed to do some tweaks to the code to get it to work. Here is what I did:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
String apiKey = vars.get("ApiKey");
String apiSecret = vars.get("ApiSecret");
long timestamp = System.currentTimeMillis() / 1000L;
String combined = apiKey + apiSecret + timestamp;
String generatedSignature = DigestUtils.sha256Hex(combined);
vars.put("GeneratedSignature", generatedSignature);
Note the main differences are:
Most important: DigestUtils.sha256Hex takes a String instead of a byte array. Converting first to bytes screwed up the hash, I think due to padding.
I added the resulting value to vars so it can be used later in Jmeter in the usual way (${GeneratedSignature}).
ApiKey and ApiSecret are defined elsewhere in a Jmeter User Defined Variables element.
With this I was able to make the following work with Mashery in accordance with their authentication instructions posted here.
Has anyone used BSF pre-processor in JMeter? What is the difference in the working between pre-processor and sampler? What is the difference between Beanshell processor and BSF processor?
My requirement is that I have a sample XML that I need to use to generate as many XMLs for the HTTP request I am going to load test. For this, I was planning to use BSF pre-processor to create an XML string using XSLT transformation of the template XML, within a loop (as many number of requests I want to generate). I would then use the string variable pointing to the created XML in each iteration of the loop for the corresponding HTTP request. So the questions in earlier paragraph are to validate this approach.
IF this approach is OK, I could not figure out how to use XSLT BSF pre-processor? I wrote as well as tried specifying the XSL in the script section, but could not figure out how to pass input XML? What does the String parameter input mean? It was throwing a NullPointerException for that parameter? IS that the way to specify input XML? If yes, please give an example.
Anybody who has worked in this, please share whatever inputs you can.
Thanks,
Paddy
Kindly find answers below:
What is the difference in the working between pre-processor and sampler
PreProcessor is executed before sampler. Pre- and PostProcessor execution time is not recorded so they're handy to use i.e. to prepare test data or do something with it after sampler end.
What is the difference between Beanshell processor and BSF processor?
Beanshell test elements support only Beanshell language while BSF supports JavaScript, jexl, jacl, jml, etc.
For lightweight scripting it's better to use Beanshell as engine initialization time is less, however if your script is doing "heavy" operations it's better to use JSR223 Sampler and Groovy as a language. See Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! for scripting extension engines benchmark and details on how to install Groovy language support.
how to pass input XML
It can be done via Parameters section which accepts any string.
If you have your XML file as JMeter variable you can access it from the script as:
String xml = vars.get("myVar");
UPDATE: Example PreProcessor Code
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
TransformerFactory factory = TransformerFactory.newInstance();
Source xslt = new StreamSource(new File("/path/to/your/xsl/file.xsl"));
Transformer transformer = factory.newTransformer(xslt);
Source xml = new StreamSource(new File("/path/to/your/source/xml/file.xml"));
transformer.transform(xml, new StreamResult(new File("/path/to/result/xml_or_html/file")));
I'm sending websocket requests(json) and get some responses from server.
Than I'm saving in variables some parameters' values from derived response(using Regular Expression Extractor).
How can I save values of this variables in file for each sampler?
Add a Beanshell PostProcessor after Regular Expression Extractor.
Put the following code into PostProcessor's "Script" area
import org.apache.commons.io.FileUtils;
String sampleName = prev.getSampleLabel();
String var = vars.get("myVar");
FileUtils.writeStringToFile(new File(sampleName + ".txt"), vars.get("myVar"));
Where:
prev - stands for parent SampleResult
vars - JMEterVariables instance for current thread group
FileUtils - org.apache.commons.io.FileUtils class instance
See How to use BeanShell: JMeter's favorite built-in component guide for more details on Beanshell scripting in Apache JMeter.