Skip to content

Commit bca6bb1

Browse files
committed
feat: allow expressions for TestElement.enabled property
Fixes #6006
1 parent 3c2a66e commit bca6bb1

File tree

3 files changed

+81
-5
lines changed

3 files changed

+81
-5
lines changed

src/core/src/main/java/org/apache/jmeter/threads/JMeterThread.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,10 @@ public void run() {
264264
iterationListener = initRun(threadContext);
265265
while (running) {
266266
Sampler sam = threadGroupLoopController.next();
267-
while (running && sam != null) {
267+
for (; running && sam != null; sam = threadGroupLoopController.next()) {
268+
if (!sam.isEnabled()) {
269+
continue;
270+
}
268271
processSampler(sam, null, threadContext);
269272
threadContext.cleanAfterSample();
270273

@@ -296,11 +299,8 @@ public void run() {
296299
}
297300
}
298301
threadContext.setTestLogicalAction(TestLogicalAction.CONTINUE);
299-
sam = null;
300302
setLastSampleOk(threadContext.getVariables(), true);
301-
}
302-
else {
303-
sam = threadGroupLoopController.next();
303+
break;
304304
}
305305
}
306306

@@ -898,6 +898,9 @@ private void stopThread() {
898898

899899
private static void checkAssertions(List<? extends Assertion> assertions, SampleResult parent, JMeterContext threadContext) {
900900
for (Assertion assertion : assertions) {
901+
if (!((TestElement) assertion).isEnabled()) {
902+
continue;
903+
}
901904
TestBeanHelper.prepare((TestElement) assertion);
902905
if (assertion instanceof AbstractScopedAssertion scopedAssertion) {
903906
String scope = scopedAssertion.fetchScope();
@@ -965,13 +968,19 @@ private static void processAssertion(SampleResult result, Assertion assertion) {
965968

966969
private static void runPostProcessors(List<? extends PostProcessor> extractors) {
967970
for (PostProcessor ex : extractors) {
971+
if (!((TestElement) ex).isEnabled()) {
972+
continue;
973+
}
968974
TestBeanHelper.prepare((TestElement) ex);
969975
ex.process();
970976
}
971977
}
972978

973979
private static void runPreProcessors(List<? extends PreProcessor> preProcessors) {
974980
for (PreProcessor ex : preProcessors) {
981+
if (!((TestElement) ex).isEnabled()) {
982+
continue;
983+
}
975984
if (log.isDebugEnabled()) {
976985
log.debug("Running preprocessor: {}", ((AbstractTestElement) ex).getName());
977986
}
@@ -992,6 +1001,9 @@ private static void runPreProcessors(List<? extends PreProcessor> preProcessors)
9921001
private void delay(List<? extends Timer> timers) {
9931002
long totalDelay = 0;
9941003
for (Timer timer : timers) {
1004+
if (!((TestElement) timer).isEnabled()) {
1005+
continue;
1006+
}
9951007
TestBeanHelper.prepare((TestElement) timer);
9961008
long delay = timer.delay();
9971009
if (APPLY_TIMER_FACTOR && timer.isModifiable()) {

src/core/src/main/java/org/apache/jmeter/threads/ListenerNotifier.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ public class ListenerNotifier implements Serializable {
5454
public void notifyListeners(SampleEvent res, List<SampleListener> listeners) {
5555
for (SampleListener sampleListener : listeners) {
5656
try {
57+
if (!((TestElement) sampleListener).isEnabled()) {
58+
continue;
59+
}
5760
TestBeanHelper.prepare((TestElement) sampleListener);
5861
sampleListener.sampleOccurred(res);
5962
} catch (RuntimeException e) {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.jmeter.control
19+
20+
import org.apache.jmeter.junit.JMeterTestCase
21+
import org.apache.jmeter.sampler.DebugSampler
22+
import org.apache.jmeter.test.assertions.executePlanAndCollectEvents
23+
import org.apache.jmeter.threads.ThreadGroup
24+
import org.apache.jmeter.treebuilder.TreeBuilder
25+
import org.junit.jupiter.api.Assertions
26+
import org.junit.jupiter.api.Test
27+
import kotlin.time.Duration.Companion.seconds
28+
29+
class EnabledWithVariablesTest : JMeterTestCase() {
30+
fun TreeBuilder.oneThread(loops: Int, body: ThreadGroup.() -> Unit) {
31+
ThreadGroup::class {
32+
numThreads = 1
33+
rampUp = 0
34+
setSamplerController(
35+
LoopController().apply {
36+
this.loops = loops
37+
}
38+
)
39+
body()
40+
}
41+
}
42+
43+
@Test
44+
fun `sampler with conditional enable function`() {
45+
val events = executePlanAndCollectEvents(5.seconds) {
46+
oneThread(loops = 4) {
47+
DebugSampler::class {
48+
name = "Conditionally enabled: \${__jm____idx}"
49+
props {
50+
it[enabled] = "\${__javaScript(vars.get('__jm____idx')%2==1)}"
51+
}
52+
}
53+
}
54+
}
55+
Assertions.assertEquals(
56+
"[Conditionally enabled: 1, Conditionally enabled: 3]",
57+
events.map { it.result.sampleLabel }.toString(),
58+
"Test should complete within reasonable time, and the test has 2 debug samplers, so we expect 2 events"
59+
)
60+
}
61+
}

0 commit comments

Comments
 (0)