Jmeter, beanshell - how to write exec() output into a string? - jmeter

I have the following code in my beanshell postprocessor that executes a C# program and writes its output into Jmeter's console:
import it.sauronsoftware.base64.Base64;
prev.setDataEncoding("ANSI");
encoded = Base64.encode(prev.getResponseDataAsString());
print (exec("C:\\prog\\prog.exe decode " + encoded));
It works fast enough for me, but I want to pass the output from prog.exe to a string (and then output that string as response data). Is it possible to do it using beanshell postprocessor? If not, what would be the easiest way to do it?

Use OS Process Sampler after each webservice, this sampler will handle the decoding of the response.
Note that this is exactly what you are doing here with the additional cost of Beanshell.
It has been introduced in JMeter 2.7 and allows you to run you C# program and get output as ResponseData.

Related

Non text response data received in Jmeter sampler response

When I running Jmeter in non gui mode Im getting response error in Jmeter
Im using below mentioned settings in the simple data writer in the script
I want to know whether server under test has thrown this Non-text response data error or error is something else and Jmeter is not able to interpret it so it is showing that.
Can someone help me understand this.
Thank you!!!
This error will occur when SampleResult.getDataType() function returns anything other than text
You can try writing the response data using JSR223 Listener and some custom Groovy code, for instance:
if (!prev.isSuccessful()) {
new File('response.bin').bytes = prev.getResponseData()
}
you can amend this response.bin filename to include the current thread number, iteration, name of the sampler and so on

How to save test result as pass and failed in jmeter in csv file

I am new in jmeter , I have created multiple HTTP Request in a single thread group , Now what i am trying is save all the HTTP Request that is http request with response code 200 in csv file as TestCase pass and http request with response code other than 200 as failed. As I want to execute each and every HTTP request one by one and store result in csv file
here is my beanshell PostProcessor
import java.io.*;
import org.apache.jmeter.services.FileServer;
File f=new File("E:\\apache-jmeter-5.2.1\\apache-jmeter-5.2.1\\bin\\JmeterProResult\\testResult.csv");
FileWriter fw=new FileWriter(f);
BufferedWriter bw=new BufferedWriter(fw);
var rc = prev.getResponseCode();
if(rc.equals("200")){
bw.write("test is passed");
}
else{
bw.write("test is failed");
}
bw.close();
fw.close();
which is generating output as show only one result but I run two successful http request
here is mine jmeter structure-- I want to execute each and every HTTP request
here my desired output should look like
Your approach will work only if you have 1 virtual user, any concurrency will lead to a race condition when 2 threads will be writing the same file resulting in concurrent modification and leading to the data loss
Since JMeter 3.1 it's recommended to use JSR223 Test Elements and Groovy language for scripting so you will need to reconsider your "beanshell" approach in any case
So I would recommend using Flexible File Writer plugin which allows you to store various request/response details into a file in a "safe" way.

Restarting a user thread conditionally in JMeter

I know that I can stop a thread conditionally in JMeter.
In my script I'm sending a requests and then I'm extracting their response json to further process it. There are some rare cases, where the parameter response provides some value that I cannot process in further steps.
I could actually detect this valid response by extracting another parameter. Would it be possible to just restart the thread based on condition, instead of stopping it?
Without scripting, you can add Flow Control Action (was: Test Action )
Choose Target: Current Thread and Action: Start Next Thread Loop
It'll skip "damaged" thread and continue to the next thread
For further researchers:
The easy way to start another iteration of a thread based on condition (i.e extracting some data out of json) is to use a BeanShell Sampler in way like described above.
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.threads.JMeterContext;
import org.apache.jmeter.threads.JMeterContext.TestLogicalAction;
String statVar = vars.get("statusVariable"); //getting some data for condition check (statusVariable is a variable that has been set previously in the Jmeter JSON Extractor)
if(statVar.equals("NOK")){ . //checking the condition
SampleResult.setTestLogicalAction(TestLogicalAction.START_NEXT_ITERATION_OF_THRE
AD); //Starting thread again (it starts the thread from the beginning, so we may compare this to restart effect)
}

How to check the response assertion is passed or failed in Jmeter using beanshell

I want to save the request and response of the sample into a text file, if response assertion is failed.
Here I can save the request and response it to a text file. But I am struck where,
how to check the whether response assertion is passed or failed for the respective sample.
How to validate the is current "Http Request" sample is passed or failed?
Thanks In advance.
Add Beanshell Listener as a child of your HTTP Request sampler which has Assertion(s)
Put the following code into "Script" area:
import org.apache.jmeter.assertions.AssertionResult;
for (AssertionResult assertionResult : sampleResult.getAssertionResults()) {
if (assertionResult.isFailure()) {
//do what you need here
}
}
As Listeners are executed after assertions the listener will have information regarding all assertion results therefore you will be able to conditionally store request/response details into a file.
Be aware that starting from JMeter version 3.0 the Groovy scripting engine is being shipped with JMeter so consider switching to JSR223 Listener and replacing all your Beanshell Test Elements with the JSR223 equivalents, performancewise it would be much better.

How do I resend a sampler upon a failed assertion on JMeter?

I am designing a load test in JMeter.
With the current application that we have whenever a HTTP request is sent, the web server will very occasionally send back a page with a message. To get around this we just have to reload the page. This page could come up for literally any HTTP request.
Is there any way to design a test in JMeter where when a sampler fails, the sampler simply retries?
I'm not sure how I can get a Beanshell sampler to resend a HTTP request.
It is possible via additional Beanshell Assertion
You can re-run arbitrary sampler from the Beanshell Assertion as simple as
ctx.getCurrentSampler().sample(null);
Add a Beanshell Assertion after all other assertions. It matters as assertions are being executed upside-down.
Put the following code into Beanshell Assertion's "Script" area (just change "message" to what your server returns on error.
import org.apache.jmeter.samplers.SampleResult;
if (new String(ResponseData).equals("message")) {
SampleResult result = ctx.getCurrentSampler().sample(null);
if (result.getResponseDataAsString().equals("message")) {
Failure = true;
} else {
SampleResult.setSuccessful(true);
}
}
You'll have only one result recorded.
If assertion passes 1st time - it'll be successful
If assertion fails 1st time and passes 2nd time - it'll be successful
If assertion fails 2 times - it'll be recorded as failed.
For extended information on Beanshell scripting check out How to use BeanShell: JMeter's favorite built-in component guide.
Create such hierarchy:
Thread Group (1 user, 1 second ramp-up, forever)
-While Controller (empty condition = forever)
--Counter (start – 1, increment – 1, reference name – counter)
--HTTP request
---Timer (I prefer constant Timer, responseble for pause betwee retrying)
---BeanShell Post Processor
BeanShell Post Processor should contains(pseudo code):
if(Integer.parseInt(vars.get("counter")>5)
{
prev.setSuccessful(false);
prev.setStopTestNow(true);
}
if(successCondition)
{
prev.setStopTest(true);
}
There is no direct way to achieve it, but I think you can use While controller in conjuction with Regex extractor to resend the failed requests.
Logical flow could be,
1. HTTP request
2. Regex extractor post processor - check response contains failure extract value in msg variable, default is success
3. While controller - run till msg=failure, default value of msg is success
Example screenshot,
Let me know if this works.

Resources