From c0cdf2ab131738b65c69457c3e95fb32ca053a61 Mon Sep 17 00:00:00 2001 From: Prateek Gupta Date: Wed, 3 Jun 2026 16:42:29 +0530 Subject: [PATCH 1/3] feat: add resetOnEachIteration option to DslCounter --- docs/guide/request-generation/counter.md | 2 +- .../javadsl/core/configs/DslCounter.java | 20 +++++++++++++++++++ .../javadsl/core/configs/DslCounterTest.java | 18 +++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/guide/request-generation/counter.md b/docs/guide/request-generation/counter.md index 8abb1ae4..c48f8f3c 100644 --- a/docs/guide/request-generation/counter.md +++ b/docs/guide/request-generation/counter.md @@ -13,5 +13,5 @@ testPlan( ) ).run(); ``` - +You can also use `.resetOnEachIteration(true)` if you need the counter to reset to its starting value at the beginning of each new Thread Group iteration. Check [DslCounter](/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java) for more details. diff --git a/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java b/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java index 7f53844d..82ed42a4 100644 --- a/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java +++ b/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java @@ -24,6 +24,7 @@ public class DslCounter extends BaseConfigElement { private long increment = 1; private long max = Long.MAX_VALUE; private boolean perThread = false; + private boolean resetOnEachIteration = false; public DslCounter(String varName) { super(varName, CounterConfigGui.class); @@ -98,6 +99,23 @@ public DslCounter perThread(boolean perThread) { return this; } + /** + * Specifies whether to reset the counter value at the beginning of each thread group iteration. + * + * @param resetOnEachIteration specifies to reset the counter when a new thread group iteration + * starts. When not specified (set to false), the counter persists its + * value across different iterations. By default, it is set to false. + * @return the counter for further configuration and usage. + * @since 2.3 + */ + public DslCounter resetOnEachIteration(boolean resetOnEachIteration) { + this.resetOnEachIteration = resetOnEachIteration; + if (resetOnEachIteration) { + this.perThread = true; + } + return this; + } + @Override protected TestElement buildTestElement() { CounterConfig ret = new CounterConfig(); @@ -106,6 +124,7 @@ protected TestElement buildTestElement() { ret.setIncrement(increment); ret.setEnd(max); ret.setIsPerUser(perThread); + ret.setResetOnThreadGroupIteration(resetOnEachIteration); return ret; } @@ -124,6 +143,7 @@ protected MethodCall buildMethodCall(CounterConfig testElement, MethodCallContex ret.chain("increment", paramBuilder.longParam("incr", 1L)); ret.chain("maximumValue", paramBuilder.longParam("end", Long.MAX_VALUE)); ret.chain("perThread", paramBuilder.boolParam("per_user", false)); + ret.chain("resetOnEachIteration", paramBuilder.boolParam("reset_on_each_iteration", false)); return ret; } diff --git a/jmeter-java-dsl/src/test/java/us/abstracta/jmeter/javadsl/core/configs/DslCounterTest.java b/jmeter-java-dsl/src/test/java/us/abstracta/jmeter/javadsl/core/configs/DslCounterTest.java index 7800defa..c9c60f6a 100644 --- a/jmeter-java-dsl/src/test/java/us/abstracta/jmeter/javadsl/core/configs/DslCounterTest.java +++ b/jmeter-java-dsl/src/test/java/us/abstracta/jmeter/javadsl/core/configs/DslCounterTest.java @@ -50,6 +50,24 @@ public void shouldUseIncrementalValuesInRequestWhenCounterInRequest() throws Exc verify(threads, getRequestedFor(urlEqualTo("/" + (startingValue + increment)))); } + @Test + public void shouldResetCounterOnEachIterationWhenResetOptionIsEnabled() throws Exception { + int startingValue = 1; + int increment = 1; + int threads = 1; + testPlan( + threadGroup(threads, 2, + counter("MY_COUNTER") + .startingValue(startingValue) + .increment(increment) + .resetOnEachIteration(true), + httpSampler(wiremockUri + "/${MY_COUNTER}") + ) + ).run(); + verify(2, getRequestedFor(urlEqualTo("/1"))); + verify(0, getRequestedFor(urlEqualTo("/2"))); + } + @Nested public class CodeBuilderTest extends MethodCallBuilderTest { From e6f3ae3eac17899ce73bdca143c008108d07a7b3 Mon Sep 17 00:00:00 2001 From: Prateek Gupta Date: Wed, 3 Jun 2026 18:27:37 +0530 Subject: [PATCH 2/3] fix: use correct JMX property key in CodeBuilder --- .../us/abstracta/jmeter/javadsl/core/configs/DslCounter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java b/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java index 82ed42a4..316d032f 100644 --- a/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java +++ b/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java @@ -143,7 +143,7 @@ protected MethodCall buildMethodCall(CounterConfig testElement, MethodCallContex ret.chain("increment", paramBuilder.longParam("incr", 1L)); ret.chain("maximumValue", paramBuilder.longParam("end", Long.MAX_VALUE)); ret.chain("perThread", paramBuilder.boolParam("per_user", false)); - ret.chain("resetOnEachIteration", paramBuilder.boolParam("reset_on_each_iteration", false)); + ret.chain("resetOnEachIteration", paramBuilder.boolParam("reset_on_tg_iteration", false)); return ret; } From 34707a315e4dea49a074abb2e1dee0ef71707c6c Mon Sep 17 00:00:00 2001 From: Prateek Gupta Date: Thu, 11 Jun 2026 15:56:36 +0530 Subject: [PATCH 3/3] implemented if condition in the buildTestElement --- .../jmeter/javadsl/core/configs/DslCounter.java | 9 ++++++--- .../jmeter/javadsl/core/configs/DslCounterTest.java | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java b/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java index 316d032f..f69b7953 100644 --- a/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java +++ b/jmeter-java-dsl/src/main/java/us/abstracta/jmeter/javadsl/core/configs/DslCounter.java @@ -110,14 +110,17 @@ public DslCounter perThread(boolean perThread) { */ public DslCounter resetOnEachIteration(boolean resetOnEachIteration) { this.resetOnEachIteration = resetOnEachIteration; - if (resetOnEachIteration) { - this.perThread = true; - } return this; } @Override protected TestElement buildTestElement() { + if (resetOnEachIteration && !perThread) { + throw new IllegalStateException( + "Invalid counter configuration: resetOnEachIteration(true) only works with perThread(true). A shared " + + "counter (perThread=false) has no per-thread state, so it cannot reset on each iteration." + ); + } CounterConfig ret = new CounterConfig(); ret.setVarName(varName); ret.setStart(start); diff --git a/jmeter-java-dsl/src/test/java/us/abstracta/jmeter/javadsl/core/configs/DslCounterTest.java b/jmeter-java-dsl/src/test/java/us/abstracta/jmeter/javadsl/core/configs/DslCounterTest.java index c9c60f6a..7bf1db5a 100644 --- a/jmeter-java-dsl/src/test/java/us/abstracta/jmeter/javadsl/core/configs/DslCounterTest.java +++ b/jmeter-java-dsl/src/test/java/us/abstracta/jmeter/javadsl/core/configs/DslCounterTest.java @@ -60,6 +60,7 @@ public void shouldResetCounterOnEachIterationWhenResetOptionIsEnabled() throws E counter("MY_COUNTER") .startingValue(startingValue) .increment(increment) + .perThread(true) .resetOnEachIteration(true), httpSampler(wiremockUri + "/${MY_COUNTER}") )