diff --git a/src/components/src/main/java/org/apache/jmeter/config/CSVDataSet.java b/src/components/src/main/java/org/apache/jmeter/config/CSVDataSet.java index 05f5f8f6f05..3f95f85e127 100644 --- a/src/components/src/main/java/org/apache/jmeter/config/CSVDataSet.java +++ b/src/components/src/main/java/org/apache/jmeter/config/CSVDataSet.java @@ -26,9 +26,12 @@ import org.apache.jmeter.gui.TestElementMetadata; import org.apache.jmeter.save.CSVSaveService; import org.apache.jmeter.services.FileServer; +import org.apache.jmeter.testbeans.PropertyBackedTestBean; import org.apache.jmeter.testbeans.TestBean; import org.apache.jmeter.testbeans.gui.GenericTestBeanCustomizer; import org.apache.jmeter.testelement.property.JMeterProperty; +import org.apache.jmeter.testelement.property.StringProperty; +import org.apache.jmeter.testelement.schema.PropertiesAccessor; import org.apache.jmeter.threads.JMeterContext; import org.apache.jmeter.threads.JMeterVariables; import org.apache.jmeter.util.JMeterUtils; @@ -68,7 +71,7 @@ @GUIMenuSortOrder(1) @TestElementMetadata(labelResource = "displayName") public class CSVDataSet extends ConfigTestElement - implements TestBean, LoopIterationListener, NoConfigMerge { + implements TestBean, PropertyBackedTestBean, LoopIterationListener, NoConfigMerge { public enum ShareMode { ALL("shareMode.all"), @@ -94,33 +97,20 @@ public String toString() { private static final String EOFVALUE = // value to return at EOF JMeterUtils.getPropDefault("csvdataset.eofstring", ""); //$NON-NLS-1$ //$NON-NLS-2$ - private transient String filename; - - private transient String fileEncoding; - - private transient String variableNames; - - private transient String delimiter; - - private transient boolean quoted; - - private transient boolean recycle = true; - - private transient boolean stopThread; - private transient String[] vars; private transient String alias; - private transient String shareMode; - private boolean firstLineIsNames = false; - private boolean ignoreFirstLine = false; + @Override + public CSVDataSetSchema getSchema() { + return CSVDataSetSchema.INSTANCE; + } - private Object readResolve(){ - recycle = true; - return this; + @Override + public PropertiesAccessor getProps() { + return new PropertiesAccessor<>(this, getSchema()); } /** @@ -137,7 +127,14 @@ private Object readResolve(){ @Override public void setProperty(JMeterProperty property) { String propName = property.getName(); - if ("shareMode".equals(propName)) { + if (getSchema().getShareMode().getName().equals(propName)) { + if (property instanceof StringProperty stringProperty) { + String stringValue = stringProperty.getStringValue(); + if (stringValue == null || !stringValue.contains(" ")) { + super.setProperty(property); + return; + } + } JMeterProperty shareMode = GenericTestBeanCustomizer.normalizeEnumProperty(getClass(), ShareMode.class, property); if (shareMode != null) { @@ -164,6 +161,8 @@ public void iterationStart(LoopIterationEvent iterEvent) { initVars(server, context, delim); } + boolean recycle = getRecycle(); + boolean ignoreFirstLine = isIgnoreFirstLine(); // TODO: fetch this once as per vars above? JMeterVariables threadVars = context.getVariables(); String[] lineValues = {}; @@ -206,7 +205,7 @@ private void initVars(FileServer server, final JMeterContext context, String del throw new IllegalArgumentException("Could not split CSV header line from file:" + fileName,e); } } else { - server.reserveFile(fileName, getFileEncoding(), alias, ignoreFirstLine); + server.reserveFile(fileName, getFileEncoding(), alias, isIgnoreFirstLine()); vars = JOrphanUtils.split(names, ","); // $NON-NLS-1$ } trimVarNames(vars); @@ -239,7 +238,7 @@ private static void trimVarNames(String[] varsNames) { * @return Returns the filename. */ public String getFilename() { - return filename; + return get(getSchema().getFilename()); } /** @@ -247,14 +246,14 @@ public String getFilename() { * The filename to set. */ public void setFilename(String filename) { - this.filename = filename; + set(getSchema().getFilename(), filename); } /** * @return Returns the file encoding. */ public String getFileEncoding() { - return fileEncoding; + return get(getSchema().getFileEncoding()); } /** @@ -262,14 +261,14 @@ public String getFileEncoding() { * The fileEncoding to set. */ public void setFileEncoding(String fileEncoding) { - this.fileEncoding = fileEncoding; + set(getSchema().getFileEncoding(), fileEncoding); } /** * @return Returns the variableNames. */ public String getVariableNames() { - return variableNames; + return get(getSchema().getVariableNames()); } /** @@ -277,43 +276,43 @@ public String getVariableNames() { * The variableNames to set. */ public void setVariableNames(String variableNames) { - this.variableNames = variableNames; + set(getSchema().getVariableNames(), variableNames); } public String getDelimiter() { - return delimiter; + return get(getSchema().getDelimiter()); } public void setDelimiter(String delimiter) { - this.delimiter = delimiter; + set(getSchema().getDelimiter(), delimiter); } public boolean getQuotedData() { - return quoted; + return get(getSchema().getQuotedData()); } public void setQuotedData(boolean quoted) { - this.quoted = quoted; + set(getSchema().getQuotedData(), quoted); } public boolean getRecycle() { - return recycle; + return get(getSchema().getRecycle()); } public void setRecycle(boolean recycle) { - this.recycle = recycle; + set(getSchema().getRecycle(), recycle); } public boolean getStopThread() { - return stopThread; + return get(getSchema().getStopThread()); } public void setStopThread(boolean value) { - this.stopThread = value; + set(getSchema().getStopThread(), value); } public String getShareMode() { - return shareMode; + return get(getSchema().getShareMode()); } @Nullable ShareMode getShareModeAsEnum() { @@ -325,20 +324,20 @@ public String getShareMode() { } public void setShareMode(String value) { - this.shareMode = value; + set(getSchema().getShareMode(), value); } /** * @return the ignoreFirstLine */ public boolean isIgnoreFirstLine() { - return ignoreFirstLine; + return get(getSchema().getIgnoreFirstLine()); } /** * @param ignoreFirstLine the ignoreFirstLine to set */ public void setIgnoreFirstLine(boolean ignoreFirstLine) { - this.ignoreFirstLine = ignoreFirstLine; + set(getSchema().getIgnoreFirstLine(), ignoreFirstLine); } } diff --git a/src/components/src/main/java/org/apache/jmeter/config/CSVDataSetBeanInfo.java b/src/components/src/main/java/org/apache/jmeter/config/CSVDataSetBeanInfo.java index 15c27b60b43..a1cea36f36a 100644 --- a/src/components/src/main/java/org/apache/jmeter/config/CSVDataSetBeanInfo.java +++ b/src/components/src/main/java/org/apache/jmeter/config/CSVDataSetBeanInfo.java @@ -28,16 +28,7 @@ public class CSVDataSetBeanInfo extends BeanInfoSupport { - // These names must agree case-wise with the variable and property names - private static final String FILENAME = "filename"; //$NON-NLS-1$ - private static final String FILE_ENCODING = "fileEncoding"; //$NON-NLS-1$ - private static final String VARIABLE_NAMES = "variableNames"; //$NON-NLS-1$ - private static final String IGNORE_FIRST_LINE = "ignoreFirstLine"; //$NON-NLS-1$ - private static final String DELIMITER = "delimiter"; //$NON-NLS-1$ - private static final String RECYCLE = "recycle"; //$NON-NLS-1$ - private static final String STOPTHREAD = "stopThread"; //$NON-NLS-1$ - private static final String QUOTED_DATA = "quotedData"; //$NON-NLS-1$ - private static final String SHAREMODE = "shareMode"; //$NON-NLS-1$ + private static final CSVDataSetSchema SCHEMA = CSVDataSetSchema.INSTANCE; private static final String[] SHARE_TAGS = new String[3]; static final int SHARE_ALL = 0; @@ -55,51 +46,53 @@ public CSVDataSetBeanInfo() { super(CSVDataSet.class); createPropertyGroup("csv_data", //$NON-NLS-1$ - new String[] { FILENAME, FILE_ENCODING, VARIABLE_NAMES, - IGNORE_FIRST_LINE, DELIMITER, QUOTED_DATA, - RECYCLE, STOPTHREAD, SHAREMODE }); + new String[] { SCHEMA.getFilename().getName(), SCHEMA.getFileEncoding().getName(), + SCHEMA.getVariableNames().getName(), SCHEMA.getIgnoreFirstLine().getName(), + SCHEMA.getDelimiter().getName(), SCHEMA.getQuotedData().getName(), + SCHEMA.getRecycle().getName(), SCHEMA.getStopThread().getName(), + SCHEMA.getShareMode().getName() }); - PropertyDescriptor p = property(FILENAME); + PropertyDescriptor p = property(SCHEMA.getFilename().getName()); p.setValue(NOT_UNDEFINED, true); - p.setValue(DEFAULT, ""); //$NON-NLS-1$ + p.setValue(DEFAULT, SCHEMA.getFilename().getDefaultValue()); p.setValue(NOT_EXPRESSION, true); p.setPropertyEditorClass(FileEditor.class); - p = property(FILE_ENCODING, TypeEditor.ComboStringEditor); + p = property(SCHEMA.getFileEncoding().getName(), TypeEditor.ComboStringEditor); p.setValue(NOT_UNDEFINED, true); - p.setValue(DEFAULT, ""); //$NON-NLS-1$ + p.setValue(DEFAULT, SCHEMA.getFileEncoding().getDefaultValue()); p.setValue(TAGS, getListFileEncoding()); - p = property(VARIABLE_NAMES); + p = property(SCHEMA.getVariableNames().getName()); p.setValue(NOT_UNDEFINED, true); - p.setValue(DEFAULT, ""); //$NON-NLS-1$ + p.setValue(DEFAULT, SCHEMA.getVariableNames().getDefaultValue()); p.setValue(NOT_EXPRESSION, true); - p = property(IGNORE_FIRST_LINE); + p = property(SCHEMA.getIgnoreFirstLine().getName()); p.setValue(NOT_UNDEFINED, true); - p.setValue(DEFAULT, false); + p.setValue(DEFAULT, SCHEMA.getIgnoreFirstLine().getDefaultValue()); - p = property(DELIMITER); + p = property(SCHEMA.getDelimiter().getName()); p.setValue(NOT_UNDEFINED, true); - p.setValue(DEFAULT, ","); //$NON-NLS-1$ + p.setValue(DEFAULT, SCHEMA.getDelimiter().getDefaultValue()); p.setValue(NOT_EXPRESSION, true); - p = property(QUOTED_DATA); + p = property(SCHEMA.getQuotedData().getName()); p.setValue(NOT_UNDEFINED, true); - p.setValue(DEFAULT, false); + p.setValue(DEFAULT, SCHEMA.getQuotedData().getDefaultValue()); - p = property(RECYCLE); + p = property(SCHEMA.getRecycle().getName()); p.setValue(NOT_UNDEFINED, true); - p.setValue(DEFAULT, true); + p.setValue(DEFAULT, SCHEMA.getRecycle().getDefaultValue()); - p = property(STOPTHREAD); + p = property(SCHEMA.getStopThread().getName()); p.setValue(NOT_UNDEFINED, true); - p.setValue(DEFAULT, false); + p.setValue(DEFAULT, SCHEMA.getStopThread().getDefaultValue()); - p = property(SHAREMODE, TypeEditor.ComboStringEditor); + p = property(SCHEMA.getShareMode().getName(), TypeEditor.ComboStringEditor); p.setValue(RESOURCE_BUNDLE, getBeanDescriptor().getValue(RESOURCE_BUNDLE)); p.setValue(NOT_UNDEFINED, true); - p.setValue(DEFAULT, SHARE_TAGS[SHARE_ALL]); + p.setValue(DEFAULT, SCHEMA.getShareMode().getDefaultValue()); p.setValue(NOT_OTHER, false); p.setValue(NOT_EXPRESSION, false); p.setValue(TAGS, SHARE_TAGS); diff --git a/src/components/src/main/kotlin/org/apache/jmeter/config/CSVDataSetSchema.kt b/src/components/src/main/kotlin/org/apache/jmeter/config/CSVDataSetSchema.kt new file mode 100644 index 00000000000..7e63ac4ad91 --- /dev/null +++ b/src/components/src/main/kotlin/org/apache/jmeter/config/CSVDataSetSchema.kt @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jmeter.config + +import org.apache.jmeter.testelement.schema.BooleanPropertyDescriptor +import org.apache.jmeter.testelement.schema.StringPropertyDescriptor +import org.apiguardian.api.API + +/** + * Lists properties of a [CSVDataSet]. + * @since 6.0 + */ +@API(status = API.Status.EXPERIMENTAL, since = "6.0.0") +public abstract class CSVDataSetSchema : ConfigTestElementSchema() { + public companion object INSTANCE : CSVDataSetSchema() + + public val filename: StringPropertyDescriptor + by string("filename", default = "") + + public val fileEncoding: StringPropertyDescriptor + by string("fileEncoding", default = "") + + public val variableNames: StringPropertyDescriptor + by string("variableNames", default = "") + + public val ignoreFirstLine: BooleanPropertyDescriptor + by boolean("ignoreFirstLine", default = false) + + public val delimiter: StringPropertyDescriptor + by string("delimiter", default = ",") + + public val quotedData: BooleanPropertyDescriptor + by boolean("quotedData", default = false) + + public val recycle: BooleanPropertyDescriptor + by boolean("recycle", default = true) + + public val stopThread: BooleanPropertyDescriptor + by boolean("stopThread", default = false) + + public val shareMode: StringPropertyDescriptor + by string("shareMode", default = "shareMode.all") +} diff --git a/src/components/src/test/java/org/apache/jmeter/config/TestCVSDataSet.java b/src/components/src/test/java/org/apache/jmeter/config/TestCVSDataSet.java index 174a02aa50b..010a94379b5 100644 --- a/src/components/src/test/java/org/apache/jmeter/config/TestCVSDataSet.java +++ b/src/components/src/test/java/org/apache/jmeter/config/TestCVSDataSet.java @@ -18,16 +18,30 @@ package org.apache.jmeter.config; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import org.apache.jmeter.engine.util.CompoundVariable; import org.apache.jmeter.junit.JMeterTestCase; +import org.apache.jmeter.save.SaveService; import org.apache.jmeter.services.FileServer; +import org.apache.jmeter.testbeans.TestBeanHelper; +import org.apache.jmeter.testelement.property.FunctionProperty; import org.apache.jmeter.threads.JMeterContext; import org.apache.jmeter.threads.JMeterContextService; import org.apache.jmeter.threads.JMeterVariables; +import org.apache.jorphan.collections.HashTree; +import org.apache.jorphan.collections.SearchByClass; import org.apache.jorphan.test.JMeterSerialTest; import org.apache.jorphan.util.JMeterStopThreadException; import org.junit.jupiter.api.AfterEach; @@ -138,7 +152,7 @@ public void testHeaderOpen(){ CSVDataSet csv = new CSVDataSet(); csv.setFilename(findTestPath("testfiles/testheader.csv")); csv.setDelimiter("|"); - assertNull(csv.getVariableNames()); + assertEquals("", csv.getVariableNames()); csv.iterationStart(null); assertNull(threadVars.get("a")); assertEquals("a1", threadVars.get("A")); @@ -160,7 +174,7 @@ public void testHeaderOpenAndRecycle(){ csv.setFilename(findTestPath("testfiles/testheader.csv")); csv.setDelimiter("|"); csv.setRecycle(true); - assertNull(csv.getVariableNames()); // read 1st line + assertEquals("", csv.getVariableNames()); // read 1st line // read 5 lines + restart to file begin csv.iterationStart(null); // line 2 csv.iterationStart(null); // line 3 @@ -182,7 +196,7 @@ public void testHeaderQuotes(){ csv.setQuotedData(true); csv.setRecycle(false); csv.setStopThread(true); - assertNull(csv.getVariableNames()); + assertEquals("", csv.getVariableNames()); csv.iterationStart(null); assertNull(threadVars.get("a")); assertEquals("a1", threadVars.get("A")); @@ -216,13 +230,149 @@ private static CSVDataSet initCSV(){ return csv; } + @Test + public void testGettersAfterLoadingTestPlan() throws Exception { + Path testPlan = Files.createTempFile("csv-dataset", ".jmx"); + Path csvFile = Files.createTempFile("csv-dataset", ".csv"); + Files.write(csvFile, "ignored\n\"a1\"|\"b1\"|\"c1\"\n".getBytes(StandardCharsets.UTF_8)); + String csvFileName = csvFile.toString().replace("&", "&"); + String jmx = "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " |\n" + + " UTF-8\n" + + " " + csvFileName + "\n" + + " true\n" + + " true\n" + + " false\n" + + " shareMode.thread\n" + + " true\n" + + " a,b,c\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + Files.write(testPlan, jmx.getBytes(StandardCharsets.UTF_8)); + + try { + SaveService.loadProperties(); + HashTree tree = SaveService.loadTree(testPlan.toFile()); + SearchByClass searcher = new SearchByClass<>(CSVDataSet.class); + tree.traverse(searcher); + + assertEquals(1, searcher.getSearchResults().size()); + CSVDataSet csvDataSet = searcher.getSearchResults().iterator().next(); + assertEquals(csvFile.toString(), csvDataSet.getPropertyAsString("filename")); + assertEquals(csvFile.toString(), csvDataSet.getFilename()); + assertEquals("UTF-8", csvDataSet.getFileEncoding()); + assertEquals("a,b,c", csvDataSet.getVariableNames()); + assertEquals("|", csvDataSet.getDelimiter()); + assertTrue(csvDataSet.getQuotedData()); + assertFalse(csvDataSet.getRecycle()); + assertEquals("shareMode.thread", csvDataSet.getShareMode()); + assertTrue(csvDataSet.getStopThread()); + assertTrue(csvDataSet.isIgnoreFirstLine()); + + csvDataSet.iterationStart(null); + assertEquals("a1", threadVars.get("a")); + assertEquals("b1", threadVars.get("b")); + assertEquals("c1", threadVars.get("c")); + assertThrows(JMeterStopThreadException.class, () -> csvDataSet.iterationStart(null)); + } finally { + Files.deleteIfExists(testPlan); + Files.deleteIfExists(csvFile); + } + } + + @Test + public void testSetFilenameIsSavedAfterLoadingTestPlan() throws Exception { + Path testPlan = Files.createTempFile("csv-dataset", ".jmx"); + Path savedTestPlan = Files.createTempFile("csv-dataset-saved", ".jmx"); + String jmx = "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " old.csv\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + Files.write(testPlan, jmx.getBytes(StandardCharsets.UTF_8)); + + try { + SaveService.loadProperties(); + HashTree tree = SaveService.loadTree(testPlan.toFile()); + CSVDataSet csvDataSet = findCsvDataSet(tree); + csvDataSet.setFilename("new.csv"); + + try (OutputStream out = Files.newOutputStream(savedTestPlan)) { + SaveService.saveTree(tree, out); + } + HashTree reloadedTree = SaveService.loadTree(savedTestPlan.toFile()); + CSVDataSet reloadedCsvDataSet = findCsvDataSet(reloadedTree); + + assertEquals("new.csv", reloadedCsvDataSet.getFilename()); + } finally { + Files.deleteIfExists(testPlan); + Files.deleteIfExists(savedTestPlan); + } + } + + @Test + public void testSchemaDefaults() { + CSVDataSet csvDataSet = new CSVDataSet(); + + assertEquals("", csvDataSet.getFilename()); + assertEquals("", csvDataSet.getFileEncoding()); + assertEquals("", csvDataSet.getVariableNames()); + assertEquals(",", csvDataSet.getDelimiter()); + assertFalse(csvDataSet.getQuotedData()); + assertTrue(csvDataSet.getRecycle()); + assertEquals("shareMode.all", csvDataSet.getShareMode()); + assertFalse(csvDataSet.getStopThread()); + assertFalse(csvDataSet.isIgnoreFirstLine()); + } + + @Test + public void testFilenameFunctionPropertyReturnsRawValueBeforeRunningVersion() { + CSVDataSet csvDataSet = new CSVDataSet(); + FunctionProperty property = new FunctionProperty( + csvDataSet.getSchema().getFilename().getName(), new CompoundVariable("${__P(csv)}")); + csvDataSet.setProperty(property); + + assertSame(property, csvDataSet.getProperty(csvDataSet.getSchema().getFilename().getName())); + assertEquals("${__P(csv)}", csvDataSet.getFilename()); + + TestBeanHelper.prepare(csvDataSet); + + assertSame(property, csvDataSet.getProperty(csvDataSet.getSchema().getFilename().getName())); + assertEquals("${__P(csv)}", csvDataSet.getFilename()); + } + @Test public void testShareMode(){ new CSVDataSetBeanInfo(); // needs to be initialised CSVDataSet csv0 = initCSV(); CSVDataSet csv1 = initCSV(); - assertNull(csv1.getShareMode()); + assertEquals("shareMode.all", csv1.getShareMode()); csv1.setShareMode("abc"); assertEquals("abc", csv1.getShareMode()); csv1.iterationStart(null); @@ -239,4 +389,11 @@ public void testShareMode(){ csv1.iterationStart(null); assertEquals("a4", threadVars.get("a")); } + + private static CSVDataSet findCsvDataSet(HashTree tree) { + SearchByClass searcher = new SearchByClass<>(CSVDataSet.class); + tree.traverse(searcher); + assertEquals(1, searcher.getSearchResults().size()); + return searcher.getSearchResults().iterator().next(); + } } diff --git a/src/core/src/main/java/org/apache/jmeter/testbeans/PropertyBackedTestBean.java b/src/core/src/main/java/org/apache/jmeter/testbeans/PropertyBackedTestBean.java new file mode 100644 index 00000000000..1cee98601ae --- /dev/null +++ b/src/core/src/main/java/org/apache/jmeter/testbeans/PropertyBackedTestBean.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jmeter.testbeans; + +/** + * Marker for {@link TestBean} implementations that store their configuration + * directly in the test element property map. + */ +public interface PropertyBackedTestBean { +} diff --git a/src/core/src/main/java/org/apache/jmeter/testbeans/TestBeanHelper.java b/src/core/src/main/java/org/apache/jmeter/testbeans/TestBeanHelper.java index 7abffe197de..0b187c56c06 100644 --- a/src/core/src/main/java/org/apache/jmeter/testbeans/TestBeanHelper.java +++ b/src/core/src/main/java/org/apache/jmeter/testbeans/TestBeanHelper.java @@ -126,7 +126,7 @@ protected List computeValue(Class type) { * @param el the TestElement to be prepared */ public static void prepare(TestElement el) { - if (!(el instanceof TestBean)) { + if (!(el instanceof TestBean) || el instanceof PropertyBackedTestBean) { return; } // Avoid allocating array for every method call diff --git a/xdocs/changes.xml b/xdocs/changes.xml index 988377c81b1..a4a0429a782 100644 --- a/xdocs/changes.xml +++ b/xdocs/changes.xml @@ -115,6 +115,7 @@ Summary
  • 5937Remove deprecated Log4j package scanning and configure plugin metadata processing to improve startup time and avoid deprecation warnings. Contributed by Piotr P. Karwasz (github.com/piotrgithub)
  • 6620Fix report generation paths so dashboard output files are created in the correct location after internal refactoring.
  • 6456Handle malformed percent-encoded URLs gracefully when recording HTTP traffic, logging a warning instead of failing the recording.
  • +
  • 67266451Fix CSVDataSet configuration getters returning field defaults right after loading a test plan via SaveService.loadTree(). Contributed by Sadovoi Grigorii (github.com/e345ee)
  • @@ -127,6 +128,7 @@ Summary
  • Gabriele Coletta (github.com/gdmg92)
  • Patrick Uiterwijk (patrick at puiterwijk.org)
  • Piotr P. Karwasz (github.com/piotrgithub)
  • +
  • Sadovoi Grigorii (github.com/e345ee)
  • We also thank bug reporters who helped us improve JMeter.