abstracta / jmeter-java-dsl

Simple JMeter performance tests API
https://abstracta.github.io/jmeter-java-dsl/
Apache License 2.0
477 stars 59 forks source link

Error in groovy function from jmx2dsl #194

Closed uddirulz closed 1 year ago

uddirulz commented 1 year ago

Hi,

I have a JMX file where there is ${P(Threads,)} for number of threads, ${P(RampUp,)} for ramp up and ${__P(Time,)} for Duration.

On converting the same to dsl using jmx2dsl, I have got: threadGroup() .rampToAndHold("${P(Threads,)}", "${P(RampUp,)}", "${groovy((new org.apache.jmeter.engine.util.CompoundVariable('#{P(Time\,)}'.replace('#'\,'$')).execute() as int) - (new org.apache.jmeter.engine.util.CompoundVariable('#{__P(RampUp\,)}'.replace('#'\,'$')).execute() as int))}") ....

I am running the test via Maven by passing: mvn clean test -DThreads=2 -DRampUp=1 -DTime=30

However getting the below error: [INFO] Running TestRun2 19:04:48.199 [main] ERROR org.apache.jmeter.engine.PreCompiler - invalid variables in node Thread Group org.apache.jmeter.functions.InvalidVariableException: __groovy called with wrong number of parameters. Actual: 5. Expected: >= 1 and <= 2 at org.apache.jmeter.functions.AbstractFunction.checkParameterCount(AbstractFunction.java:93) ~[ApacheJMeter_core-5.5.jar:5.5] at org.apache.jmeter.functions.Groovy.setParameters(Groovy.java:139) ~[ApacheJMeter_functions-5.5.jar:5.5] at org.apache.jmeter.engine.util.FunctionParser.makeFunction(FunctionParser.java:130) ~[ApacheJMeter_core-5.5.jar:5.5] at org.apache.jmeter.engine.util.FunctionParser.compileString(FunctionParser.java:78) ~[ApacheJMeter_core-5.5.jar:5.5] at org.apache.jmeter.engine.util.CompoundVariable.setParameters(CompoundVariable.java:183) ~[ApacheJMeter_core-5.5.jar:5.5] at org.apache.jmeter.engine.util.ReplaceStringWithFunctions.transformValue(ReplaceStringWithFunctions.java:42) ~[ApacheJMeter_core-5.5.jar:5.5] at org.apache.jmeter.engine.util.ValueReplacer.replaceValues(ValueReplacer.java:169) ~[ApacheJMeter_core-5.5.jar:5.5] at org.apache.jmeter.engine.util.ValueReplacer.replaceValues(ValueReplacer.java:79) ~[ApacheJMeter_core-5.5.jar:5.5] at org.apache.jmeter.engine.PreCompiler.addNode(PreCompiler.java:88) ~[ApacheJMeter_core-5.5.jar:5.5] at org.apache.jorphan.collections.HashTree.traverseInto(HashTree.java:993) ~[jorphan-5.5.jar:5.5] at org.apache.jorphan.collections.HashTree.traverse(HashTree.java:976) ~[jorphan-5.5.jar:5.5] at org.apache.jmeter.engine.StandardJMeterEngine.run(StandardJMeterEngine.java:377) ~[ApacheJMeter_core-5.5.jar:5.5] at us.abstracta.jmeter.javadsl.core.engines.EmbeddedJmeterEngine$2.runTest(EmbeddedJmeterEngine.java:162) ~[jmeter-java-dsl-1.12.jar:1.12] at us.abstracta.jmeter.javadsl.core.engines.EmbeddedJmeterEngine$TestRunner.run(EmbeddedJmeterEngine.java:179) ~[jmeter-java-dsl-1.12.jar:1.12] at us.abstracta.jmeter.javadsl.core.engines.EmbeddedJmeterEngine.runInEnv(EmbeddedJmeterEngine.java:129) ~[jmeter-java-dsl-1.12.jar:1.12] at us.abstracta.jmeter.javadsl.core.engines.EmbeddedJmeterEngine.run(EmbeddedJmeterEngine.java:93) ~[jmeter-java-dsl-1.12.jar:1.12] at us.abstracta.jmeter.javadsl.core.DslTestPlan.run(DslTestPlan.java:125) ~[jmeter-java-dsl-1.12.jar:1.12] at TestRun2.testRun2(TestRun2.java:26) ~[test-classes/:?] at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[?:?] at java.lang.reflect.Method.invoke(Method.java:577) ~[?:?] at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727) ~[junit-platform-commons-1.9.2.jar:1.9.2] at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) ~[junit-jupiter-engine-5.9.2.jar:5.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.9.2.jar:1.9.2] at java.util.ArrayList.forEach(ArrayList.java:1511) ~[?:?] at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.9.2.jar:1.9.2] at java.util.ArrayList.forEach(ArrayList.java:1511) ~[?:?] at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) ~[junit-platform-engine-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) ~[junit-platform-launcher-1.9.2.jar:1.9.2] at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:50) ~[surefire-junit-platform-3.0.0.jar:3.0.0] at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:184) ~[surefire-junit-platform-3.0.0.jar:3.0.0] at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:148) ~[surefire-junit-platform-3.0.0.jar:3.0.0] at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:122) ~[surefire-junit-platform-3.0.0.jar:3.0.0] at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385) ~[surefire-booter-3.0.0.jar:3.0.0] at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162) ~[surefire-booter-3.0.0.jar:3.0.0] at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507) ~[surefire-booter-3.0.0.jar:3.0.0] at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495) ~[surefire-booter-3.0.0.jar:3.0.0] = 0 in 00:00:00 = **/s Avg: 0 Min: 9223372036854775807 Max: -9223372036854775808 Err: 0 (0.00%)

rabelenda commented 1 year ago

Hello, thank you for reporting this!

It seems to be a problem with comma scaping, try with something like this:

threadGroup()
  .rampToAndHold("${__P(Threads,)}", "${__P(RampUp,)}", 
      "${__groovy((new org.apache.jmeter.engine.util.CompoundVariable('#{__P(Time\\\\,)}'.replace('#'\\\\,'$')).execute() as int) - (new org.apache.jmeter.engine.util.CompoundVariable('#{__P(RampUp\\\\,)}'.replace('#'\\\\,'$')).execute() as int))}")

We will work on fixing this for the next release.

As a side note: you might want to consider tuning the script after conversion, to make it simpler or easer to maintain. Consider jmx2dsl as an accelerator to get started with jmeter DSL, but always review generated script and consider further optimizing it, and if you find general ways of optimize the generated scripts, let us know and we can improve jmx2dsl conversion further! :).

For example, in provided script you might want to use something like this instead which is simpler:

threadGroup()
  .rampToAndHold("${__P(Threads,)}", "${__P(RampUp,)}",  "${__P(Time,)}'")

And when setting the Time parameter consider that rampup time should not be counted as part of Time variable. We implemented jmx2dsl conversion with such groovy logic to keep the semmantics intact, but resulting script is not as simple as it could be just taking that into consideration. We might change this decision in the future if community agrees, and just add a comment in generated code, pointing to that particular semmantic detail.

uddirulz commented 1 year ago

Hi,

Thanks for your reply.

I was doing the same as suggested by you: threadGroup() .rampToAndHold("${P(Threads,)}", "${P(RampUp,)}", "${__P(Time,)}'")

Actually we have a big suite of JMX files where we are passing threads, rampup, time and host as jmeter properties from cmd. And as using jmx2dsl threw this error, though worth pointing this out which I am sure the brilliant team will fix in the next release.

Also a quick food for thought - Can we have something like the Web driver config/sampler where in JMETER GUI we can run selenium scripts for RUM/synthetic monitoring. This can help in CI integration along with the rest of the dsl test pack.

Thanks & Regards, Uddipan

On Tue, Jun 20, 2023 at 9:32 PM rabelenda @.***> wrote:

Hello, thank you for reporting this!

It seems to be a problem with comma scaping, try with something like this:

threadGroup() .rampToAndHold("${P(Threads,)}", "${P(RampUp,)}", "${groovy((new org.apache.jmeter.engine.util.CompoundVariable('#{P(Time\\,)}'.replace('#'\\,'$')).execute() as int) - (new org.apache.jmeter.engine.util.CompoundVariable('#{__P(RampUp\\,)}'.replace('#'\\,'$')).execute() as int))}")

We will work on fixing this for the next release.

As a side note: you might want to consider tuning the script after conversion, to make it simpler or easer to maintain. Consider jmx2dsl as an accelerator to get started with jmeter DSL, but always review generated script and consider further optimizing it, and if you find general ways of optimize the generated scripts, let us know and we can improve jmx2dsl conversion further! :).

For example, in provided script you might want to use something like this instead which is simpler:

threadGroup() .rampToAndHold("${P(Threads,)}", "${P(RampUp,)}", "${__P(Time,)}'")

And when setting the Time parameter consider that rampup time should not be counted as part of Time variable. We implemented jmx2dsl conversion with such groovy logic to keep the semmantics intact, but resulting script is not as simple as it could be just taking that into consideration. We might change this decision in the future if community agrees, and just add a comment in generated code, pointing to that particular semmantic detail.

— Reply to this email directly, view it on GitHub https://github.com/abstracta/jmeter-java-dsl/issues/194#issuecomment-1599456054, or unsubscribe https://github.com/notifications/unsubscribe-auth/AW2XHGACLZ63D6O7ATWNU7DXMICFRANCNFSM6AAAAAAZNU2ADA . You are receiving this because you authored the thread.Message ID: @.***>

rabelenda commented 1 year ago

Hello, thank you for the valuable feedback, taking time to point out the issue and the idea!

I think is a good idea, can you post it in a separate issue so we can keep better track of it and the community can have more visibility on it as well? :)

uddirulz commented 1 year ago

Thank you. As suggested I have created a new issue.

rabelenda commented 1 year ago

We have fixed the issue related to the problem you reported and simplified the conversion for such scenarios as well. Here is the release.

Regards

rabelenda commented 1 year ago

I am closing this issue due to mentioned release.