You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by vl...@apache.org on 2023/05/12 04:23:34 UTC
[jmeter] 01/02: fix: disable FunctionProperty caching
This is an automated email from the ASF dual-hosted git repository.
vladimirsitnikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jmeter.git
commit d0bdbafd7bbedb5e9fc32855740b52cda4282638
Author: Vladimir Sitnikov <si...@gmail.com>
AuthorDate: Thu Mar 2 11:14:47 2023 +0300
fix: disable FunctionProperty caching
Previously it cached the values based on iteration number only
which triggered wrong results on concurrent executions.
The previous behavior can be temporary restored with
function.cache.per.iteration=true property.
---
bin/jmeter.properties | 7 +++++++
.../jmeter/testelement/property/FunctionProperty.java | 19 +++++++++++++++++--
xdocs/changes.xml | 4 ++++
xdocs/usermanual/properties_reference.xml | 9 +++++++++
4 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/bin/jmeter.properties b/bin/jmeter.properties
index 69b77d46bd..410ae16819 100644
--- a/bin/jmeter.properties
+++ b/bin/jmeter.properties
@@ -1055,6 +1055,13 @@ csvdataset.file.encoding_list=UTF-8|UTF-16|ISO-8859-15|US-ASCII
# ORO PatternCacheLRU size
#oro.patterncache.size=1000
+# Cache function execution during test execution
+# By default, JMeter caches function properties, however, it might cause unexpected results
+# when the component is shared across threads and the expression depends on the thread variables.
+# The caching behaviour would likely change in the upcoming versions
+# Deprecation notice: the setting will likely disappear, so if you need it, consider raising an issue with the use-case.
+#function.cache.per.iteration=false
+
#TestBeanGui
#
#propertyEditorSearchPath=null
diff --git a/src/core/src/main/java/org/apache/jmeter/testelement/property/FunctionProperty.java b/src/core/src/main/java/org/apache/jmeter/testelement/property/FunctionProperty.java
index a4adf02774..238ec0184f 100644
--- a/src/core/src/main/java/org/apache/jmeter/testelement/property/FunctionProperty.java
+++ b/src/core/src/main/java/org/apache/jmeter/testelement/property/FunctionProperty.java
@@ -21,19 +21,28 @@ import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.threads.JMeterContext;
import org.apache.jmeter.threads.JMeterContextService;
+import org.apache.jmeter.util.JMeterUtils;
/**
* Class that implements the Function property
*/
public class FunctionProperty extends AbstractProperty {
private static final long serialVersionUID = 233L;
+ private static final boolean FUNCTION_CACHE_PER_ITERATION =
+ JMeterUtils.getPropDefault("function.cache.per.iteration", false);
private transient CompoundVariable function;
private int testIteration = -1;
+ /**
+ * The cache will be removed in the subsequent releases.
+ * For now, it is kept for backward compatibility.
+ */
private String cacheValue;
+ private String overrideValue;
+
public FunctionProperty(String name, CompoundVariable func) {
super(name);
function = func;
@@ -48,7 +57,7 @@ public class FunctionProperty extends AbstractProperty {
if (v instanceof CompoundVariable && !isRunningVersion()) {
function = (CompoundVariable) v;
} else {
- cacheValue = v.toString();
+ overrideValue = v.toString();
}
}
@@ -87,7 +96,11 @@ public class FunctionProperty extends AbstractProperty {
log.debug("Not running version, return raw function string");
return function.getRawParameters();
}
- if(!ctx.isSamplingStarted()) {
+ String overrideValue = this.overrideValue;
+ if (overrideValue != null) {
+ return overrideValue;
+ }
+ if (!FUNCTION_CACHE_PER_ITERATION || !ctx.isSamplingStarted()) {
return function.execute();
}
log.debug("Running version, executing function");
@@ -115,6 +128,7 @@ public class FunctionProperty extends AbstractProperty {
public FunctionProperty clone() {
FunctionProperty prop = (FunctionProperty) super.clone();
prop.cacheValue = cacheValue;
+ prop.overrideValue = overrideValue;
prop.testIteration = testIteration;
prop.function = function;
return prop;
@@ -126,5 +140,6 @@ public class FunctionProperty extends AbstractProperty {
@Override
public void recoverRunningVersion(TestElement owner) {
cacheValue = null;
+ overrideValue = null;
}
}
diff --git a/xdocs/changes.xml b/xdocs/changes.xml
index f212ecfbf5..449fa8f481 100644
--- a/xdocs/changes.xml
+++ b/xdocs/changes.xml
@@ -104,6 +104,10 @@ Summary
<li><pr>5899</pr>Speed up CPU-bound tests by skipping <code>recoverRunningVersion</code> for elements that are shared between threads (the ones that implement <code>NoThreadClone</code>)</li>
<li><pr>5914</pr>Use <code>Locale.ROOT</code> instead of default locale for <code>toUpperCase</code>, and <code>toLowerCase</code> to avoid surprises with dotless I in <code>tr_TR</code> locale</li>
<li><pr>5885</pr>Use Java's <code>ServiceLoader</code> for loading plugins instead of classpath scanning. It enables faster startup</li>
+ <li><pr>5788</pr><code>FunctionProperty</code> no longer caches the value.
+ Previously it cached the values based on iteration number only which triggered wrong results on concurrent executions.
+ The previous behavior can be temporary restored with <code>function.cache.per.iteration</code> property.
+ </li>
</ul>
<ch_section>Non-functional changes</ch_section>
diff --git a/xdocs/usermanual/properties_reference.xml b/xdocs/usermanual/properties_reference.xml
index 68441b1bb8..cb32afcefa 100644
--- a/xdocs/usermanual/properties_reference.xml
+++ b/xdocs/usermanual/properties_reference.xml
@@ -1339,6 +1339,15 @@ JMETER-SERVER</source>
ORO PatternCacheLRU size.<br/>
Defaults to: <code>1000</code>
</property>
+<property name="function.cache.per.iteration">
+ <p>Cache function execution during test execution.</p>
+ <p>By default, JMeter caches function properties during a test iteration, however,
+ it might cause unexpected results when a component is shared across threads and the expression depends on
+ the thread variables.</p>
+ <note>The property will likely be removed in an upcoming version, so if you need it consider raising
+ an issue with your use-case.</note>
+ Defaults to: <code>false</code>
+</property>
<property name="propertyEditorSearchPath">
TestBeanGui<br/>
Defaults to: <code>null</code>