Exception for Java-based tests
chbndrhnns opened this issue · 15 comments
My expectation was that I can specify the required paramters (es.host
, es.index
) and use your backend listener in a Java-based test script. As I end up with NumberFormatException
doing it that way and succeeding when configuring the test via the JMeter GUI, I assume that maybe getDefaultParameters()
is not getting called in the Java case?
Here is the exception:
java.lang.IllegalStateException: Failed calling setupTest
at org.apache.jmeter.visualizers.backend.BackendListener.testStarted(BackendListener.java:339)
at org.apache.jmeter.visualizers.backend.BackendListener.testStarted(BackendListener.java:292)
at org.apache.jmeter.engine.StandardJMeterEngine.notifyTestListenersOfStart(StandardJMeterEngine.java:206)
at org.apache.jmeter.engine.StandardJMeterEngine.run(StandardJMeterEngine.java:381)
at pannet.jmeter.PerformanceTest.execute(PerformanceTest.java:148)
at step_definitions.JMeter2.userCreateSoakRequests(JMeter2.java:259)
[...]
Caused by: java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:542)
at java.lang.Integer.parseInt(Integer.java:615)
at io.github.delirius325.jmeter.backendlistener.elasticsearch.ElasticsearchBackendClient.setupTest(ElasticsearchBackendClient.java:81)
... 47 more
This is my setup code:
private BackendListener getBackendListener() {
backendListener = new BackendListener();
backendListener.setProperty(BackendListener.TEST_CLASS, BackendListener.class.getName());
backendListener.setProperty(BackendListener.GUI_CLASS, BackendListenerGui.class.getName());
Arguments listenerArgs = new Arguments();
listenerArgs.addArgument("es.host", "localhost", "=");
listenerArgs.addArgument("es.index", "poc-reporting-elk.perf", "=");
backendListener.setArguments(listenerArgs);
backendListener
.setClassname("io.github.delirius325.jmeter.backendlistener.elasticsearch.ElasticsearchBackendClient");
return backendListener;
}
After trying to put all arguments in Java, I still see the exception and cannot get it to work. Is there something else I am missing here?
Indeed there seems to be an issue with getDefaultParameter()
in that case as your stack trace is returning an error on line 81 of the ElasticSearchBackendClient class. That specific line does the following: this.bulkSize = Integer.parseInt(context.getParameter(ES_BULK_SIZE));
and throws a null exception.
I'll make a SNAPSHOT release with an explicit call to getDefaultParameters()
in the setupTest()
method.
@chbndrhnns SNAPSHOT is currently being deployed to maven-central repository. If you don't want to wait for it to be available on Maven. Please add the following JAR to your lib/ext
folder (while deleting the old version).
I see that you are calling getDefaultParameters()
now but you are not using the returned values...
So I found out that I get it working if i really specify ALL possible parameters like this:
private BackendListener getBackendListener() {
backendListener = new BackendListener();
backendListener.setProperty(BackendListener.TEST_CLASS, BackendListener.class.getName());
backendListener.setProperty(BackendListener.GUI_CLASS, BackendListenerGui.class.getName());
Arguments listenerArgs = new Arguments();
listenerArgs.addArgument("es.scheme", "http", "=");
listenerArgs.addArgument("es.host", "localhost");
listenerArgs.addArgument("es.port", "9200", "=");
listenerArgs.addArgument("es.index", "poc-reporting-elk.perf", "=");
listenerArgs.addArgument("es.timestamp", "yyyy-MM-dd'T'HH:mm:ss.SSSZZ", "=");
listenerArgs.addArgument("es.bulk.size", "100", "=");
listenerArgs.addArgument("es.timeout.ms", "200", "=");
listenerArgs.addArgument("es.sample.filter", "", "=");
listenerArgs.addArgument("es.test.mode", "info", "=");
listenerArgs.addArgument("es.xpack.user", "abc", "=");
listenerArgs.addArgument("es.xpack.password", "abc", "=");
listenerArgs.addArgument("es.parse.req.headers", "false", "=");
listenerArgs.addArgument("es.parse.res.headers", "false", "=");
listenerArgs.addArgument("es.aws.endpoint", "", "=");
listenerArgs.addArgument("es.aws.region", "", "=");
backendListener.setArguments(listenerArgs);
backendListener
.setClassname("io.github.delirius325.jmeter.backendlistener.elasticsearch.ElasticsearchBackendClient");
return backendListener;
}
@chbndrhnns Oh yes, my bad I tried to push it out in a hurry 😆 ! Let me actually use the values of getDefaultParameters
.
@chbndrhnns I have uploaded a new JAR this time it is recreating the context (since the context parameters is a private Map and cannot be explicitly reassigned) by doing this: context = new BackendListenerContext(getDefaultParameters());
.
Tell me if it works!
https://github.com/delirius325/jmeter-elasticsearch-backend-listener/releases/tag/2.6.3-SNAPSHOT
Hey, with that snapshot, I get
Caused by: java.lang.IllegalArgumentException: Host name may not be empty
at org.apache.http.util.Args.containsNoBlanks(Args.java:84)
at org.apache.http.HttpHost.<init>(HttpHost.java:80)
at io.github.delirius325.jmeter.backendlistener.elasticsearch.ElasticsearchBackendClient.setupTest(ElasticsearchBackendClient.java:87)
I assume this is because the existing context is overwritten. Shouldn't it be done like this?
First, create default context.
Second, overwrite the parameters that are passed in from the outside
It seems like I am not able to set any parameters now.
Yeah, I understand what you mean.. And frankly, I see it that way as well. But I can't seem to find a solution to access and change/add the parameters that are coming from an external source. As I mentioned in an earlier comment, the parameters in context
are stored in a private Map
which I cannot explicitly change as there is no setParameters()
method.
Wouldn't it be easier if I provided a static method in my plugin, say getDefaultValues()
, which would return an Arguments
and you could then modify it as you see fit?
I am looking at the influxdb code to understand what they did.
Without fully understanding it as of now, can specify the parameters I want and the rest is taken from the default but the test does not just fail.
Implementing this static method would work but it would make it harder to switch between the influxdb and elasticsearch backend listener as there way of usage differs then.
They did
@Override
public Arguments getDefaultParameters() {
Arguments arguments = new Arguments();
DEFAULT_ARGS.forEach(arguments::addArgument);
return arguments;
}
DEFAULT_ARGS
being a private static final Map<String, String> DEFAULT_ARGS
I'll implement a similar structure in the next SNAPSHOT
Hey @chbndrhnns,
So I just switched the parameters declaration to the style they're using in the InfluxDB Backend Listener, let me know if that helps!
Thanks,
Hey, there is still a NullPointerException:
Caused by: java.lang.NullPointerException
at io.github.delirius325.jmeter.backendlistener.elasticsearch.ElasticsearchBackendClient.setupTest(ElasticsearchBackendClient.java:90)
... 47 more
I see that context.getParameter()
returns null
if a parameter is not specified which is the base issue here: I would like to be able to leave out parameters I do not need :)
I am having issues understanding how the new way of adding the parameters is causing a NullExceptionPointer. I am basically looping through the static
parameters and adding them all to the listener.
private static final Map<String, String> DEFAULT_ARGS = new LinkedHashMap<>();
static {
DEFAULT_ARGS.put(ES_SCHEME, "http");
DEFAULT_ARGS.put(ES_HOST, null);
DEFAULT_ARGS.put(ES_PORT, "9200");
DEFAULT_ARGS.put(ES_INDEX, null);
DEFAULT_ARGS.put(ES_TIMESTAMP, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ");
DEFAULT_ARGS.put(ES_BULK_SIZE, "100");
DEFAULT_ARGS.put(ES_TIMEOUT_MS, Long.toString(DEFAULT_TIMEOUT_MS));
DEFAULT_ARGS.put(ES_SAMPLE_FILTER, null);
DEFAULT_ARGS.put(ES_TEST_MODE, "info");
DEFAULT_ARGS.put(ES_AUTH_USER, "");
DEFAULT_ARGS.put(ES_AUTH_PWD, "");
DEFAULT_ARGS.put(ES_PARSE_REQ_HEADERS, "false");
DEFAULT_ARGS.put(ES_PARSE_RES_HEADERS, "false");
DEFAULT_ARGS.put(ES_AWS_ENDPOINT, "");
DEFAULT_ARGS.put(ES_AWS_REGION, "");
}
@Override
public Arguments getDefaultParameters() {
Arguments arguments = new Arguments();
DEFAULT_ARGS.forEach(arguments::addArgument);
return arguments;
}
It's as if making a JMeter test-plan from code isn't calling the same methods...
Going through the InfluxDB listener and I noticed that my BackendClient was missing a constructor. Not sure if that's the cause of the issue or not, but could be a possible factor. Still investigating.
Taking a look at https://jmeter.apache.org/api/org/apache/jmeter/visualizers/backend/BackendListenerContext.html#getParameter-java.lang.String-java.lang.String- indicates that the desired default parameter needs to be passed to the getParameter
call or null is returned otherwise, or am I wrong?
That is correct 😄, which is why I'm trying to fix the issue where the default parameters are not automatically set when creating a test plan from code (as you're doing).