How to print the response time in JMeter - jmeter

Problem Statement: I want to print the the response time (time taken for a request) on the console using a post processer in JMeter, How to do it ?
I have tried with JSR223 post processer, using the following code.
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.util.EntityUtils;
import org.apache.jmeter.samplers.SampleResult;
log.info("--------------->",sampleResult.getTime())
And I am getting
2021-11-09 15:56:55,632 ERROR o.a.j.e.JSR223PostProcessor: Problem in JSR223 script, JSR223 PostProcessor
javax.script.ScriptException: groovy.lang.MissingPropertyException: No such property: sampleResult for class: Script2
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:320) ~[groovy-jsr223-3.0.3.jar:3.0.3]
at org.codehaus.groovy.jsr223.GroovyCompiledScript.eval(GroovyCompiledScript.java:71) ~[groovy-jsr223-3.0.3.jar:3.0.3]
at javax.script.CompiledScript.eval(Unknown Source) ~[?:1.8.0_251]
at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:222) ~[ApacheJMeter_core.jar:5.3]
at org.apache.jmeter.extractor.JSR223PostProcessor.process(JSR223PostProcessor.java:45) [ApacheJMeter_components.jar:5.3]
at org.apache.jmeter.threads.JMeterThread.runPostProcessors(JMeterThread.java:940) [ApacheJMeter_core.jar:5.3]
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:572) [ApacheJMeter_core.jar:5.3]
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:489) [ApacheJMeter_core.jar:5.3]
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256) [ApacheJMeter_core.jar:5.3]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_251]
Caused by: groovy.lang.MissingPropertyException: No such property: sampleResult for class: Script2
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:65) ~[groovy-3.0.3.jar:3.0.3]
at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:51) ~[groovy-3.0.3.jar:3.0.3]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:341) ~[groovy-3.0.3.jar:3.0.3]
at Script2.run(Script2.groovy:10) ~[?:?]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317) ~[groovy-jsr223-3.0.3.jar:3.0.3]
... 9 more

You don't have sampleResult object in JSR223 PostProcessor
If you want to print the response time of the previous sampler - you need to use prev shorthand for the SampleResult class instance
You need to use string concatenation
So remove all the imports, they're not needed and amend your code to look like:
log.info("---------------> " + prev.getTime())
More information: Top 8 JMeter Java Classes You Should Be Using with Groovy

Related

Jmeter - jsr223 - Error with external library

Jmeter - jsr223 - Error with external library
My java code with import org.web3j, run as expected, no error
package test;
import java.nio.charset.StandardCharsets;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.Sign;
import org.web3j.utils.Numeric;
public class test2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String privateAccountKey = "privateAccountKey ";
Credentials credentials = Credentials.create(privateAccountKey);
String message="messageABC";
byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
Sign.SignatureData signature = Sign.signPrefixedMessage(messageBytes, credentials.getEcKeyPair());
byte[] value = new byte[65];
System.arraycopy(signature.getR(), 0, value, 0, 32);
System.arraycopy(signature.getS(), 0, value, 32, 32);
System.arraycopy(signature.getV(), 0, value, 64, 1);
System.out.println("signature: " + Numeric.toHexString(value));
}
}
In jmeter, I use JSR223 PostProcessor
I have added core-5.0.0.jar to folder apache-jmeter-5.5\lib\ext (Download from https://mvnrepository.com/artifact/org.web3j/core/5.0.0) and restart jmeter
After run, error is shown javax.script.ScriptException: Sourced file: inline evaluation of: import java.nio.charset.StandardCharsets; import org.web3j.crypto.Credentials; i . . . '' : Typed variable declaration : Class: Credentials not found in namespace : at Line: 7 : in file: inline evaluation of: import java.nio.charset.StandardCharsets; import org.web3j.crypto.Credentials; i . . . '' : Credentials
in inline evaluation of: ``import java.nio.charset.StandardCharsets; import org.web3j.crypto.Credentials; i . . . '' at line number 7
Please advise
Many thanks
You should place any 3rd-party .jar libraries to lib folder. lib/ext is for JMeter Plugins. See JMeter Classpath user manual entry for more details.
org.web3j.core library doesn't contain org.web3j.crypto.Credentials class, you will need to add this library to JMeter's lib folder
Since JMeter 3.1 you're supposed to be using Groovy language for scripting especially when it comes to resource intensive cryptographic operations, see Beanshell vs. JSR223 vs. Java For JMeter: Complete Showdown for more details so consider switching the language to groovy because java is not real Java, it's Beanshell interpreter

JMeter ConcurrencyThreadGroup object creation throws java.lang.ExceptionInInitializerError error

I am trying to upgrade my JMeter DSL implementation to the latest JMeter version(5.4.3). But I got an issue with ConcurrencyThreadGroup object creation, it throws an exception. See the below exception
Using following versions
JMeter 5.4.3
jmeter-plugins-standard 1.4.0
Method implementation
public ConcurrencyThreadGroup getConcurrencyThreadGroup(String name, String targetConcurrency,
String rampUpTime, String rampUpStepCount, String timeUnit, String holdTargetTime,
boolean setEnabled
) {
ConcurrencyThreadGroup concurrencyThreadGroup = new ConcurrencyThreadGroup();
concurrencyThreadGroup.setName(name);
concurrencyThreadGroup.setTargetLevel(targetConcurrency);
concurrencyThreadGroup.setRampUp(rampUpTime);
concurrencyThreadGroup.setSteps(rampUpStepCount);
concurrencyThreadGroup.setUnit(timeUnit);
concurrencyThreadGroup.setHold(holdTargetTime);
concurrencyThreadGroup.setEnabled(setEnabled);
concurrencyThreadGroup.setProperty("TestElement.test_class", ConcurrencyThreadGroup.class.getName());
concurrencyThreadGroup.setProperty("TestElement.gui_class", ConcurrencyThreadGroupGui.class.getName());
return concurrencyThreadGroup;
}
Observing below exception when try to execute
at org.apache.jmeter.reporters.ResultCollector.<init>(ResultCollector.java:167)
at org.apache.jmeter.reporters.ResultCollector.<init>(ResultCollector.java:157)
at com.blazemeter.jmeter.reporters.FlushingResultCollector.<init>(FlushingResultCollector.java:7)
at com.blazemeter.jmeter.threads.AbstractDynamicThreadGroupModel.<init>(AbstractDynamicThreadGroupModel.java:28)
at com.blazemeter.jmeter.threads.AbstractDynamicThreadGroup.<init>(AbstractDynamicThreadGroup.java:23)
at com.blazemeter.jmeter.threads.concurrency.ConcurrencyThreadGroup.<init>(ConcurrencyThreadGroup.java:11)
at org.qa.perf.jmeter.api.threadgroups.QADSLThreadGroup.getConcurrencyThreadGroup(QADSLThreadGroup.java:136)
at org.qa.perf.jmeter.dsl.QADSLJMeterDSL.concurrencyThreadGroup(QADSLJMeterDSL.java:93)
at org.qa.perf.dsl.sample.threadgroup.ConcurrencyThreadGroupSampleTest$1.prepareJMeterTestPlan(ConcurrencyThreadGroupSampleTest.java:20)
at org.qa.perf.jmeter.engine.QADSLPerfTestClient.executeTest(QADSLPerfTestClient.java:29)
at org.qa.perf.dsl.sample.threadgroup.ConcurrencyThreadGroupSampleTest.testConcurrencyThreadGroupSampleTest(ConcurrencyThreadGroupSampleTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:132)
at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:599)
at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:174)
at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:822)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:147)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.testng.TestRunner.privateRun(TestRunner.java:764)
at org.testng.TestRunner.run(TestRunner.java:585)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:384)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:378)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:337)
at org.testng.SuiteRunner.run(SuiteRunner.java:286)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1218)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1140)
at org.testng.TestNG.runSuites(TestNG.java:1069)
at org.testng.TestNG.run(TestNG.java:1037)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
Caused by: java.lang.NullPointerException
at org.apache.jmeter.samplers.SampleSaveConfiguration.<clinit>(SampleSaveConfiguration.java:287)
... 38 more
Appreciate any clue or solution to solve this issue.
You're supposed to show your full code and full stacktrace as the partials unfortunately don't tell the full story.
Most probably you didn't load JMeter Properties which are responsible for the Results File Configuration so my expectation is that you need to call the following function somewhere in the beginning of your code:
org.apache.jmeter.util.JMeterUtils.loadJMeterProperties("/path/to/your/jmeter.properties")
More information:
JMeter API
Five Ways To Launch a JMeter Test without Using the JMeter GUI
jmeter-from-code example project

How to get the immediate parent name for a sampler in Jmeter

How to get the immediate parent name for a sampler in Jmeter. I have many transaction controllers. I am using Jmeter 5.3
I have a beanshell script for the same which is as below, but it always prints the very first controller name.
import org.apache.jmeter.control.GenericController;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.SearchByClass;
import java.lang.reflect.Field;
import java.util.Collection;
StandardJMeterEngine engine = ctx.getEngine();
Field test = engine.getClass().getDeclaredField("test");
test.setAccessible(true);
HashTree testPlanTree = (HashTree) test.get(engine);
SearchByClass simpleCtrlSearch= new SearchByClass(GenericController.class);
testPlanTree.traverse(simpleCtrlSearch);
Collection simpleControllers = simpleCtrlSearch.getSearchResults();
for (Object simpleController : simpleControllers) {
log.info(((GenericController) simpleController).getName());
}
In general this is either not possible or not too simple.
For particular your case if you need to determine the name of the Transaction Controller for the particular Sampler you can go for JSR223 Listener and the following code:
if (sampleEvent.isTransactionSampleEvent()) {
log.info("Transaction Controller name: " + sampleEvent.result.getSampleLabel())
}
Demo:
More information: Apache Groovy - Why and How You Should Use It

Beanshell PostProcessor Error: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import java.util.Arrays; import java.util.List;

I am getting error message
Error invoking bsh method: eval Sourced file: inline evaluation of:
``import java.util.Arrays; import java.util.List; import
java.util.concurrent.Time . . . '' : Typed variable declaration :
Error in method invocation: Static method create( java.lang.String )
not found in class'com.couchbase.client.java.CouchbaseCluster'
when I execute jmeter script with Beanshell Post Processor. Any thoughts on why I am seeing this error?
Here is the sample code:
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.document.Document;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.document.json.JsonObject;
Cluster cluster = CouchbaseCluster.create("dev-int-couchbase1.aeg.cloud");
Bucket bucket = cluster.openBucket("source-image ",100, TimeUnit.MINUTES);
Document<JsonObject> loadedFromDoc = bucket.get("0292ofcfh4516");
if(loadedFromDoc == null)
return "Document Not found";
bucket.remove(“0292ofcfh4516");
log.info("In bean shell processor");
System.out.println("In bean shell processor");
cluster.disconnect();
return "Document Removed";
Instead of using create(String... varargs) method, suggest using create(List<String> nodes) method.
replace the following code
Cluster cluster = CouchbaseCluster.create("dev-int-couchbase1.aeg.cloud");
With:
nodes = new ArrayList();
nodes.add("dev-int-couchbase1.aeg.cloud");
Cluster cluster = CouchbaseCluster.create(nodes);
Note: I am not sure how to fix the issue related to varargs, so suggesting another one. I tried suggested method here, but did not work for varargs.
Reference:
http://docs.couchbase.com/sdk-api/couchbase-java-client-2.0.0/index.html?com/couchbase/client/java/CouchbaseCluster.html
I suggest use JSR223 Post Processor instead of BeanShell postprocessor. Just copy paste the code from BeanShell to JSR223 and select the language as Java under script language drop-down available in the JSR223 post processor.
This gives more flexibility in debugging (prints complete stack trace of the error/exception in the logs).
Coming to the error, it says that Static method create( java.lang.String ) not found in class'com.couchbase.client.java.CouchbaseCluster. I checked in the official docs here, which says there is a create method which takes String Varargs. I ma not sure whether that is causing the issue. so, try it out in JSR223 PostProcessor and debug the issue.
References:
https://www.blazemeter.com/blog/beanshell-vs-jsr223-vs-java-jmeter-scripting-its-performance

Trying to generate JMeter Test Plan (jmx) With JMeter API : Mismatch between jmeter jmx file created from code and the one created by JMeter

I am trying to create a jmeter jmx file using the jmeter java api. This is what I have done,
gui.jmx
Use the jmeter gui application to create a reference jmx file against which I can compare. To the test plan, I only add a thread group and a java sampler within the thread group. All values are default.
code.jmx
Using the jmeter java api, I create a jmx file containing a test plan, thread group and java sampler. All values are set as per the case 1.
After creating the jmx file from code, I note the following differences,
1) The nodes in gui.jmx is replaced by the following in code.jmx
<org.apache.jorphan.collections.HashTree>
Though this is not an issue, is it possible to somehow generate the following tag as the GUI saves it
<hashTree>
2) Test element nodes contain the attributes 'guiClass' and 'testClass' in gui.jmx e.g.
These attributes are not generated in code.jmx and neither did I find any API to explicitly set them -> Due to this the generated code.jmx does not open in the jmeter gui console. Which probably means that the generated jmx can be used in no console mode only. Is this by design? Is there some way by which these attributes can be added via code using the jmeter apis? (not using DOM as a hack)
3) The xml structure of gui.jmx is as follows,
<hashTree>
<TestPlan ...>
...
</TestPlan>
<hashTree>
<ThreadGroup ...>
...
</ThreadGroup>
**<hashTree/>**
</hashTree>
</hashTree>
Note the nesting of the HashTree elements. When this opens up in the JMeter GUI, the elements are nested within each other.
The xml structure of code.jmx is as follows,
<org.apache.jorphan.collections.HashTree>
<TestPlan ...>
...
</TestPlan>
**<org.apache.jorphan.collections.HashTree/>**
<ThreadGroup ...>
...
</ThreadGroup>
**<org.apache.jorphan.collections.HashTree/>**
</org.apache.jorphan.collections.HashTree>
Note the difference in placement of tags. There is no nesting. They are all at the same level. Why does this happen. What is the proper way to add test elements using jmx api so that the hash tree elements are nested within each other as in the first case?
Finally after looking into the jmeter source code, I figured that in addition to what I was doing, I needed to explicitly set the guiClass and testClass parameters
testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
similarly for other test elements like ThreadGroup, JavaSampler etc.
The full code is as follows,
package com.test;
import java.io.FileOutputStream;
import org.apache.jmeter.control.LoopController;
import org.apache.jmeter.control.gui.LoopControlPanel;
import org.apache.jmeter.control.gui.TestPlanGui;
import org.apache.jmeter.protocol.java.control.gui.JavaTestSamplerGui;
import org.apache.jmeter.protocol.java.sampler.JavaSampler;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jmeter.threads.gui.ThreadGroupGui;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.collections.HashTree;
public class JMXCreator {
public static void main(String[] argv) throws Exception {
// Initialize the configuration variables
String jmeterHome = "D:\\apache-jmeter-2.11";
JMeterUtils.setJMeterHome(jmeterHome);
JMeterUtils.loadJMeterProperties(JMeterUtils.getJMeterBinDir()
+ "\\jmeter.properties");
JMeterUtils.initLogging();
JMeterUtils.initLocale();
// TestPlan
TestPlan testPlan = new TestPlan();
testPlan.setName("Test Plan");
testPlan.setEnabled(true);
testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
// ThreadGroup controller
LoopController loopController = new LoopController();
loopController.setEnabled(true);
loopController.setLoops(5);
loopController.setProperty(TestElement.TEST_CLASS,
LoopController.class.getName());
loopController.setProperty(TestElement.GUI_CLASS,
LoopControlPanel.class.getName());
// ThreadGroup
ThreadGroup threadGroup = new ThreadGroup();
threadGroup.setName("Thread Group");
threadGroup.setEnabled(true);
threadGroup.setSamplerController(loopController);
threadGroup.setNumThreads(5);
threadGroup.setRampUp(10);
threadGroup.setProperty(TestElement.TEST_CLASS,
ThreadGroup.class.getName());
threadGroup.setProperty(TestElement.GUI_CLASS,
ThreadGroupGui.class.getName());
// JavaSampler
JavaSampler javaSampler = new JavaSampler();
javaSampler.setClassname("my.example.sampler");
javaSampler.setEnabled(true);
javaSampler.setProperty(TestElement.TEST_CLASS,
JavaSampler.class.getName());
javaSampler.setProperty(TestElement.GUI_CLASS,
JavaTestSamplerGui.class.getName());
// Create TestPlan hash tree
HashTree testPlanHashTree = new HashTree();
testPlanHashTree.add(testPlan);
// Add ThreadGroup to TestPlan hash tree
HashTree threadGroupHashTree = new HashTree();
threadGroupHashTree = testPlanHashTree.add(testPlan, threadGroup);
// Add Java Sampler to ThreadGroup hash tree
HashTree javaSamplerHashTree = new HashTree();
javaSamplerHashTree = threadGroupHashTree.add(javaSampler);
// Save to jmx file
SaveService.saveTree(testPlanHashTree, new FileOutputStream(
"d:\\test.jmx"));
}
}
Just a comment regarding
<org.apache.jorphan.collections.HashTree>
if you set in saveservice.properties file:
hashTree=org.apache.jorphan.collections.HashTree
instead of:
hashTree=org.apache.jorphan.collections.ListedHashTree
you will get
<hashTree>
Creating JMeter test from Java Api is not really supported method and you expose your test plan to changes in JMeter.
I would not do it.
I seems you are doing this to dynamically create test scripts based on some chosen variables, this is not the right way to do it.
I JMeter to do what you want you use:
User Defined Variables
Property function which enables you to pass properties on command line
Also have a look at Jenkins and Maven for examples :
http://anttikoivisto.blogspot.fi/2014/04/real-world-jmeter-03-running-with-jenkins.html
http://www.stevefenton.co.uk/Content/Blog/Date/201408/Blog/Switching-JMeter-Between-Integration-And-Load-Testing/

Resources