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 ff63439527ece9b1d8347e19bc289e97ae1923d5 Author: Vladimir Sitnikov <[email protected]> AuthorDate: Mon Jan 1 17:18:17 2024 +0300 fix: store ThreadGroup.scheduler fields This fixes a regression in 278247608b66adf92e06e1444e0229a663e54618 --- .../apache/jmeter/control/IncludeController.java | 17 +- .../jmeter/control/gui/IncludeControllerGui.java | 32 +--- .../jmeter/control/IncludeControllerSchema.kt | 33 ++++ .../jmeter/threads/gui/AbstractThreadGroupGui.java | 23 ++- .../apache/jmeter/threads/gui/ThreadGroupGui.java | 15 +- .../org/apache/jmeter/gui/JTextComponentBinding.kt | 42 ++++- .../java/org/apache/jmeter/junit/JMeterTest.java | 180 +++++++++++++++++---- .../protocol/java/sampler/BeanShellSampler.java | 2 +- .../java/sampler/BeanShellSamplerSchema.kt | 3 - 9 files changed, 270 insertions(+), 77 deletions(-) diff --git a/src/components/src/main/java/org/apache/jmeter/control/IncludeController.java b/src/components/src/main/java/org/apache/jmeter/control/IncludeController.java index 388dcf269e..4913bd7eb1 100644 --- a/src/components/src/main/java/org/apache/jmeter/control/IncludeController.java +++ b/src/components/src/main/java/org/apache/jmeter/control/IncludeController.java @@ -27,6 +27,7 @@ import org.apache.jmeter.save.SaveService; import org.apache.jmeter.services.FileServer; import org.apache.jmeter.testelement.TestElement; import org.apache.jmeter.testelement.TestPlan; +import org.apache.jmeter.testelement.schema.PropertiesAccessor; import org.apache.jmeter.util.JMeterUtils; import org.apache.jorphan.collections.HashTree; import org.slf4j.Logger; @@ -37,8 +38,6 @@ public class IncludeController extends GenericController implements ReplaceableC private static final long serialVersionUID = 241L; - private static final String INCLUDE_PATH = "IncludeController.includepath"; //$NON-NLS-1$ - private static final String PREFIX = JMeterUtils.getPropDefault( "includecontroller.prefix", //$NON-NLS-1$ @@ -56,6 +55,16 @@ public class IncludeController extends GenericController implements ReplaceableC super(); } + @Override + public IncludeControllerSchema getSchema() { + return IncludeControllerSchema.INSTANCE; + } + + @Override + public PropertiesAccessor<? extends IncludeController, ? extends IncludeControllerSchema> getProps() { + return new PropertiesAccessor<>(this, getSchema()); + } + @Override public Object clone() { // TODO - fix so that this is only called once per test, instead of at every clone @@ -81,7 +90,7 @@ public class IncludeController extends GenericController implements ReplaceableC * @param jmxfile The path to the JMX test plan to include */ public void setIncludePath(String jmxfile) { - this.setProperty(INCLUDE_PATH,jmxfile); + set(getSchema().getIncludePath(), jmxfile); } /** @@ -89,7 +98,7 @@ public class IncludeController extends GenericController implements ReplaceableC * @return the JMX file path */ public String getIncludePath() { - return this.getPropertyAsString(INCLUDE_PATH); + return get(getSchema().getIncludePath()); } /** diff --git a/src/components/src/main/java/org/apache/jmeter/control/gui/IncludeControllerGui.java b/src/components/src/main/java/org/apache/jmeter/control/gui/IncludeControllerGui.java index 72fb0a7549..4dc41e625b 100644 --- a/src/components/src/main/java/org/apache/jmeter/control/gui/IncludeControllerGui.java +++ b/src/components/src/main/java/org/apache/jmeter/control/gui/IncludeControllerGui.java @@ -20,6 +20,8 @@ package org.apache.jmeter.control.gui; import javax.swing.JPopupMenu; import org.apache.jmeter.control.IncludeController; +import org.apache.jmeter.control.IncludeControllerSchema; +import org.apache.jmeter.gui.FilePanelEntryBinding; import org.apache.jmeter.gui.TestElementMetadata; import org.apache.jmeter.gui.util.FilePanel; import org.apache.jmeter.gui.util.MenuFactory; @@ -41,6 +43,7 @@ public class IncludeControllerGui extends AbstractControllerGui */ public IncludeControllerGui() { init(); + bindingGroup.add(new FilePanelEntryBinding(includePanel, IncludeControllerSchema.INSTANCE.getIncludePath())); } @Override @@ -48,34 +51,9 @@ public class IncludeControllerGui extends AbstractControllerGui return "include_controller";//$NON-NLS-1$ } - /** - * {@inheritDoc} - */ - @Override - public void configure(TestElement el) { - super.configure(el); - IncludeController controller = (IncludeController) el; - this.includePanel.setFilename(controller.getIncludePath()); - } - - /** - * {@inheritDoc} - */ - @Override - public TestElement createTestElement() { - IncludeController mc = new IncludeController(); - configureTestElement(mc); - return mc; - } - - /** - * {@inheritDoc} - */ @Override - public void modifyTestElement(TestElement element) { - configureTestElement(element); - IncludeController controller = (IncludeController)element; - controller.setIncludePath(this.includePanel.getFilename()); + public TestElement makeTestElement() { + return new IncludeController(); } /** diff --git a/src/components/src/main/kotlin/org/apache/jmeter/control/IncludeControllerSchema.kt b/src/components/src/main/kotlin/org/apache/jmeter/control/IncludeControllerSchema.kt new file mode 100644 index 0000000000..9881ef0ad0 --- /dev/null +++ b/src/components/src/main/kotlin/org/apache/jmeter/control/IncludeControllerSchema.kt @@ -0,0 +1,33 @@ +/* + * 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.control + +import org.apache.jmeter.testelement.schema.StringPropertyDescriptor +import org.apiguardian.api.API + +/** + * Lists properties of a [IncludeController]. + * @since 5.6 + */ +@API(status = API.Status.EXPERIMENTAL, since = "5.6") +public abstract class IncludeControllerSchema : GenericControllerSchema() { + public companion object INSTANCE : IncludeControllerSchema() + + public val includePath: StringPropertyDescriptor<IncludeControllerSchema> + by string("IncludeController.includepath") +} diff --git a/src/core/src/main/java/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java b/src/core/src/main/java/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java index 7abf48fa68..05ced0f6f5 100644 --- a/src/core/src/main/java/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java +++ b/src/core/src/main/java/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java @@ -39,6 +39,7 @@ import org.apache.jmeter.testelement.TestElement; import org.apache.jmeter.threads.AbstractThreadGroup; import org.apache.jmeter.threads.AbstractThreadGroupSchema; import org.apache.jmeter.util.JMeterUtils; +import org.apiguardian.api.API; import net.miginfocom.swing.MigLayout; @@ -203,16 +204,34 @@ public abstract class AbstractThreadGroupGui extends AbstractJMeterGuiComponent return AbstractThreadGroup.ON_SAMPLE_ERROR_CONTINUE; } - @Override + @Override + public void assignDefaultValues(TestElement element) { + super.assignDefaultValues(element); + element.set(AbstractThreadGroupSchema.INSTANCE.getOnSampleError(), AbstractThreadGroup.ON_SAMPLE_ERROR_CONTINUE); + } + + @Override public void configure(TestElement tg) { super.configure(tg); setSampleErrorBoxes((AbstractThreadGroup) tg); } + @Override + public void modifyTestElement(TestElement element) { + super.modifyTestElement(element); + element.set(AbstractThreadGroupSchema.INSTANCE.getOnSampleError(), onSampleError()); + } + + /** + * {@inheritDoc} + * @deprecated Override {@link #modifyTestElement(TestElement)} instead + * @param tg the TestElement being configured. + */ @Override + @Deprecated + @API(status = API.Status.DEPRECATED, since = "5.6.3") protected void configureTestElement(TestElement tg) { super.configureTestElement(tg); tg.set(AbstractThreadGroupSchema.INSTANCE.getOnSampleError(), onSampleError()); } - } diff --git a/src/core/src/main/java/org/apache/jmeter/threads/gui/ThreadGroupGui.java b/src/core/src/main/java/org/apache/jmeter/threads/gui/ThreadGroupGui.java index 4dd33c2f58..468381563f 100644 --- a/src/core/src/main/java/org/apache/jmeter/threads/gui/ThreadGroupGui.java +++ b/src/core/src/main/java/org/apache/jmeter/threads/gui/ThreadGroupGui.java @@ -107,20 +107,13 @@ public class ThreadGroupGui extends AbstractThreadGroupGui implements ItemListen return new ThreadGroup(); } - @Override - public TestElement createTestElement() { - TestElement tg = makeTestElement(); - // modifyTestElement is here for backward compatibility - modifyTestElement(tg); - assignDefaultValues(tg); - return tg; - } - @Override public void assignDefaultValues(TestElement element) { super.assignDefaultValues(element); element.set(ThreadGroupSchema.INSTANCE.getNumThreads(), 1); element.set(ThreadGroupSchema.INSTANCE.getRampTime(), 1); + element.set(AbstractThreadGroupSchema.INSTANCE.getSameUserOnNextIteration(), true); + ((AbstractThreadGroup) element).setSamplerController((LoopController) loopPanel.createTestElement()); } /** @@ -130,17 +123,17 @@ public class ThreadGroupGui extends AbstractThreadGroupGui implements ItemListen */ @Override public void modifyTestElement(TestElement tg) { - super.configureTestElement(tg); + super.modifyTestElement(tg); if (tg instanceof AbstractThreadGroup) { ((AbstractThreadGroup) tg).setSamplerController((LoopController) loopPanel.createTestElement()); } - toggleSchedulerFields(); } @Override public void configure(TestElement tg) { super.configure(tg); loopPanel.configure((TestElement) tg.getProperty(AbstractThreadGroup.MAIN_CONTROLLER).getObjectValue()); + toggleSchedulerFields(); } @Override diff --git a/src/core/src/main/kotlin/org/apache/jmeter/gui/JTextComponentBinding.kt b/src/core/src/main/kotlin/org/apache/jmeter/gui/JTextComponentBinding.kt index 69bd883d9f..9e8a6310fd 100644 --- a/src/core/src/main/kotlin/org/apache/jmeter/gui/JTextComponentBinding.kt +++ b/src/core/src/main/kotlin/org/apache/jmeter/gui/JTextComponentBinding.kt @@ -18,6 +18,11 @@ package org.apache.jmeter.gui import org.apache.jmeter.testelement.TestElement +import org.apache.jmeter.testelement.schema.BooleanPropertyDescriptor +import org.apache.jmeter.testelement.schema.DoublePropertyDescriptor +import org.apache.jmeter.testelement.schema.FloatPropertyDescriptor +import org.apache.jmeter.testelement.schema.IntegerPropertyDescriptor +import org.apache.jmeter.testelement.schema.LongPropertyDescriptor import org.apache.jmeter.testelement.schema.PropertyDescriptor import org.apiguardian.api.API import javax.swing.JPasswordField @@ -38,7 +43,42 @@ public class JTextComponentBinding( is JPasswordField -> String(component.password) else -> component.text } - testElement[propertyDescriptor] = text.takeIf { it.isNotEmpty() } + if (text.isEmpty()) { + testElement.removeProperty(propertyDescriptor) + return + } + when (propertyDescriptor) { + is IntegerPropertyDescriptor<*> -> + text.toIntOrNull()?.let { + testElement[propertyDescriptor] = it + return + } + + is LongPropertyDescriptor<*> -> + text.toLongOrNull()?.let { + testElement[propertyDescriptor] = it + return + } + + is FloatPropertyDescriptor<*> -> + text.toFloatOrNull()?.let { + testElement[propertyDescriptor] = it + return + } + + is DoublePropertyDescriptor<*> -> + text.toDoubleOrNull()?.let { + testElement[propertyDescriptor] = it + return + } + + is BooleanPropertyDescriptor<*> -> + text.toBooleanStrictOrNull()?.let { + testElement[propertyDescriptor] = it + return + } + } + testElement[propertyDescriptor] = text } override fun updateUi(testElement: TestElement) { diff --git a/src/dist-check/src/test/java/org/apache/jmeter/junit/JMeterTest.java b/src/dist-check/src/test/java/org/apache/jmeter/junit/JMeterTest.java index 8fae00c2d3..d9cbe40b42 100644 --- a/src/dist-check/src/test/java/org/apache/jmeter/junit/JMeterTest.java +++ b/src/dist-check/src/test/java/org/apache/jmeter/junit/JMeterTest.java @@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeFalse; import java.awt.Component; import java.io.ByteArrayInputStream; @@ -38,12 +39,15 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Properties; +import java.util.Set; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -54,24 +58,39 @@ import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.lang3.StringUtils; import org.apache.jmeter.config.gui.ObsoleteGui; +import org.apache.jmeter.control.IfControllerSchema; +import org.apache.jmeter.control.LoopControllerSchema; import org.apache.jmeter.control.gui.TestFragmentControllerGui; import org.apache.jmeter.dsl.DslPrinterTraverser; +import org.apache.jmeter.extractor.RegexExtractorSchema; import org.apache.jmeter.gui.GuiComponentHolder; import org.apache.jmeter.gui.JMeterGUIComponent; +import org.apache.jmeter.gui.NamePanel; import org.apache.jmeter.gui.UnsharedComponent; import org.apache.jmeter.gui.tree.JMeterTreeNode; import org.apache.jmeter.loadsave.IsEnabledNormalizer; +import org.apache.jmeter.protocol.http.control.gui.AjpSamplerGui; import org.apache.jmeter.protocol.http.control.gui.GraphQLHTTPSamplerGui; import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBaseSchema; import org.apache.jmeter.protocol.java.config.gui.JavaConfigGui; import org.apache.jmeter.protocol.java.control.gui.JUnitTestSamplerGui; import org.apache.jmeter.protocol.java.control.gui.JavaTestSamplerGui; +import org.apache.jmeter.protocol.jms.control.gui.JMSSamplerGui; import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testbeans.TestBean; import org.apache.jmeter.testbeans.gui.TestBeanGUI; +import org.apache.jmeter.testelement.AbstractScopedTestElementSchema; import org.apache.jmeter.testelement.TestElement; +import org.apache.jmeter.testelement.TestElementSchema; import org.apache.jmeter.testelement.property.JMeterProperty; import org.apache.jmeter.testelement.property.PropertyIterator; +import org.apache.jmeter.testelement.schema.CollectionPropertyDescriptor; +import org.apache.jmeter.testelement.schema.PropertyDescriptor; +import org.apache.jmeter.testelement.schema.TestElementPropertyDescriptor; +import org.apache.jmeter.threads.ThreadGroupSchema; +import org.apache.jmeter.threads.gui.PostThreadGroupGui; +import org.apache.jmeter.threads.gui.SetupThreadGroupGui; +import org.apache.jmeter.threads.openmodel.gui.OpenModelThreadGroupGui; import org.apache.jmeter.util.JMeterUtils; import org.apache.jmeter.visualizers.backend.BackendListenerGui; import org.apache.jorphan.reflect.ClassFinder; @@ -213,12 +232,8 @@ public class JMeterTest extends JMeterTestCase { + System.getProperty("java.awt.headless") + "'"); } - /* - * Test GUI elements - create the suite of tests - */ - static Collection<GuiComponentHolder> guiComponents() throws Throwable { + static Collection<GuiComponentHolder> customGuiComponents() throws Throwable { List<GuiComponentHolder> components = new ArrayList<>(); - for (Object o : getObjects(JMeterGUIComponent.class)) { JMeterGUIComponent item = (JMeterGUIComponent) o; if (item.getClass() == TestBeanGUI.class) { @@ -233,6 +248,14 @@ public class JMeterTest extends JMeterTestCase { } components.add(new GuiComponentHolder(item)); } + return components; + } + + /* + * Test GUI elements - create the suite of tests + */ + static Collection<GuiComponentHolder> guiComponents() throws Throwable { + List<GuiComponentHolder> components = new ArrayList<>(customGuiComponents()); for (Object o : getObjects(TestBean.class)) { Class<?> c = o.getClass(); JMeterGUIComponent item = new TestBeanGUI(c); @@ -342,6 +365,101 @@ public class JMeterTest extends JMeterTestCase { assertEquals("hey, new name!:", el2.getName(), () -> "Modify Test: Failed on " + name); } + private static final Set<PropertyDescriptor<?, ?>> IGNORED_PROPERTIES = new HashSet<>(); + + static { + IGNORED_PROPERTIES.add(TestElementSchema.INSTANCE.getGuiClass()); + IGNORED_PROPERTIES.add(TestElementSchema.INSTANCE.getTestClass()); + // TODO: support variables in TestElement.enabled property + IGNORED_PROPERTIES.add(TestElementSchema.INSTANCE.getEnabled()); + IGNORED_PROPERTIES.add(AbstractScopedTestElementSchema.INSTANCE.getScope()); + IGNORED_PROPERTIES.add(ThreadGroupSchema.INSTANCE.getOnSampleError()); + // TODO: migrate to editable checkboxes + IGNORED_PROPERTIES.add(IfControllerSchema.INSTANCE.getEvaluateAll()); + IGNORED_PROPERTIES.add(IfControllerSchema.INSTANCE.getUseExpression()); + IGNORED_PROPERTIES.add(HTTPSamplerBaseSchema.INSTANCE.getPostBodyRaw()); + // TODO: LoopControlPanel does not set continueForever properly + IGNORED_PROPERTIES.add(LoopControllerSchema.INSTANCE.getContinueForever()); + IGNORED_PROPERTIES.add(RegexExtractorSchema.INSTANCE.getMatchTarget()); + IGNORED_PROPERTIES.add(RegexExtractorSchema.INSTANCE.getDefaultIsEmpty()); + // TODO: support expressions? + IGNORED_PROPERTIES.add(HTTPSamplerBaseSchema.INSTANCE.getIpSourceType()); + IGNORED_PROPERTIES.add(HTTPSamplerBaseSchema.INSTANCE.getImplementation()); + // TODO: support expressions in UrlConfigGui + IGNORED_PROPERTIES.add(HTTPSamplerBaseSchema.INSTANCE.getFollowRedirects()); + IGNORED_PROPERTIES.add(HTTPSamplerBaseSchema.INSTANCE.getAutoRedirects()); + + } + + /** + * Assign simple expression value to every property of the element, and verify if the property is get back correctly + * from the UI. + */ + @ParameterizedTest + @MethodSource("customGuiComponents") + public void allPropertiesAreStoredInUI(GuiComponentHolder componentHolder) { + JMeterGUIComponent guiItem = componentHolder.getComponent(); + assumeFalse( + improperlyUsesUiPlaceholders(guiItem.getClass()), + () -> "UI " + componentHolder + " does not use placeholders properly, so the test is skipped"); + assumeFalse(guiItem.getClass() == JMSSamplerGui.class, + "JMSSamplerGui does not seem to use default values vs placeholders properly"); + assumeFalse(guiItem.getClass() == AjpSamplerGui.class, + "AjpSamplerGui hides some fields from HTTP (e.g. proxy), so we skip testing AJP"); + TestElement el = guiItem.createTestElement(); + TestElementSchema schema = el.getSchema(); + // UI might set properties in a different order which makes it harder to compare + Collection<PropertyDescriptor<?, ?>> properties = schema.getProperties().values(); + for (PropertyDescriptor<?, ?> property : properties) { + if (IGNORED_PROPERTIES.contains(property)) { + continue; + } + if (property instanceof CollectionPropertyDescriptor || property instanceof TestElementPropertyDescriptor) { + continue; + } + if (guiItem.getClass() == NamePanel.class && property.equals(TestElementSchema.INSTANCE.getComments())) { + // NamePanel does not configure description + continue; + } + if ((guiItem.getClass() == SetupThreadGroupGui.class || guiItem.getClass() == PostThreadGroupGui.class) && + property.equals(ThreadGroupSchema.INSTANCE.getDelayedStart())) { + // Setup and Post thread groups do not show "delay thread creation" checkbox + continue; + } + if (guiItem.getClass() == OpenModelThreadGroupGui.class && ( + property.equals(ThreadGroupSchema.INSTANCE.getNumThreads()) || + property.equals(ThreadGroupSchema.INSTANCE.getSameUserOnNextIteration()))) { + continue; + } + el.set(property, "${test_" + property.getName() + "}"); + } + // Configure UI with the modified properties + guiItem.configure(el); + // Assign the values from the UI to another element + TestElement el2 = guiItem.createTestElement(); + guiItem.modifyTestElement(el2); + + // Remove all ignored properties + for (PropertyDescriptor<?, ?> property : IGNORED_PROPERTIES) { + if (property.equals(TestElementSchema.INSTANCE.getGuiClass())) { + continue; + } + el.removeProperty(property); + el2.removeProperty(property); + } + if (guiItem.getClass() == GraphQLHTTPSamplerGui.class) { + el.removeProperty(HTTPSamplerBaseSchema.INSTANCE.getArguments()); + el2.removeProperty(HTTPSamplerBaseSchema.INSTANCE.getArguments()); + el.removeProperty(HTTPSamplerBaseSchema.INSTANCE.getUseBrowserCompatibleMultipart()); + el2.removeProperty(HTTPSamplerBaseSchema.INSTANCE.getUseBrowserCompatibleMultipart()); + el.removeProperty(HTTPSamplerBaseSchema.INSTANCE.getUseMultipartPost()); + el2.removeProperty(HTTPSamplerBaseSchema.INSTANCE.getUseMultipartPost()); + } + + compareAllProperties(el, el2, + () -> "GUI element " + componentHolder + " be able to pass all the properties to a different TestElement"); + } + @ParameterizedTest @MethodSource("guiComponents") public void propertiesShouldNotBeInitializedToNullValues(GuiComponentHolder componentHolder) { @@ -394,17 +512,7 @@ public class JMeterTest extends JMeterTestCase { actual.removeProperty(HTTPSamplerBaseSchema.INSTANCE.getArguments()); } if (!Objects.equals(expected, actual)) { - if (guiItem.getClass() == JavaConfigGui.class || guiItem.getClass() == JavaTestSamplerGui.class) { - // TODO: JavaConfigGui modifies UI when classname combobox changes, and it causes inconsistency between the - // element state and the UI state. We ignore the discrepancy for now - return; - } - if (guiItem.getClass() == JUnitTestSamplerGui.class) { - // TODO: fix org.apache.jmeter.protocol.java.control.gui.JUnitTestSamplerGui.configure to use placeholders - return; - } - if (guiItem.getClass() == BackendListenerGui.class) { - // TODO: fix handling of default arguments in org.apache.jmeter.visualizers.backend.BackendListenerGui.actionPerformed + if (improperlyUsesUiPlaceholders(guiItem.getClass())) { return; } boolean breakpointForDebugging = Objects.equals(expected, actual); @@ -418,6 +526,23 @@ public class JMeterTest extends JMeterTestCase { } } + private static boolean improperlyUsesUiPlaceholders(Class<? extends JMeterGUIComponent> klass) { + if (klass == JavaConfigGui.class || klass == JavaTestSamplerGui.class) { + // TODO: JavaConfigGui modifies UI when classname combobox changes, and it causes inconsistency between the + // element state and the UI state. We ignore the discrepancy for now + return true; + } + if (klass == JUnitTestSamplerGui.class) { + // TODO: fix org.apache.jmeter.protocol.java.control.gui.JUnitTestSamplerGui.configure to use placeholders + return true; + } + if (klass == BackendListenerGui.class) { + // TODO: fix handling of default arguments in org.apache.jmeter.visualizers.backend.BackendListenerGui.actionPerformed + return true; + } + return false; + } + @ParameterizedTest @MethodSource("guiComponents") public void saveLoadShouldKeepElementIntact(GuiComponentHolder componentHolder) throws IOException { @@ -427,10 +552,13 @@ public class JMeterTest extends JMeterTestCase { SaveService.saveElement(expected, bos); byte[] serializedBytes = bos.toByteArray(); TestElement actual = (TestElement) SaveService.loadElement(new ByteArrayInputStream(serializedBytes)); - compareAllProperties(expected, actual, serializedBytes); + compareAllProperties(expected, actual, + () -> "TestElement after 'save+load' should match the one created in GUI\n" + + "JMX is " + new String(serializedBytes, StandardCharsets.UTF_8)); } - private static void compareAllProperties(TestElement expected, TestElement actual, byte[] serializedBytes) { + private static void compareAllProperties(TestElement expected, TestElement actual, + Supplier<String> message) { expected.traverse(IsEnabledNormalizer.INSTANCE); actual.traverse(IsEnabledNormalizer.INSTANCE); @@ -440,17 +568,13 @@ public class JMeterTest extends JMeterTestCase { assertEquals( expectedStr, new DslPrinterTraverser(DslPrinterTraverser.DetailLevel.ALL).append(actual).toString(), - "TestElement after 'save+load' should match the one created in GUI\n" + - "JMX is " + new String(serializedBytes, StandardCharsets.UTF_8)); - fail("TestElement after 'save+load' should match the one created in GUI. " + - "DSL representation is the same, however TestElement#equals says the elements are different. " + - "DSL is " + expectedStr + "\n" + - "JMX is " + new String(serializedBytes, StandardCharsets.UTF_8)); + message.get()); + fail("DSL representation is the same, however TestElement#equals says the elements are different. " + message.get()); } - assertEquals(expected.hashCode(), actual.hashCode(), "TestElement.hashCode after 'save+load' should match the one created in GUI. " + - "DSL representation is the same, however TestElement#hashCode says the elements are different. " + - "DSL is " + expectedStr + "\n" + - "JMX is " + new String(serializedBytes, StandardCharsets.UTF_8)); + assertEquals(expected.hashCode(), actual.hashCode(), + "TestElement.hashCode after 'save+load' should match the one created in GUI. " + + "DSL representation is the same, however TestElement#hashCode says the elements are different. " + + message.get()); } static Stream<Serializable> serializableObjects() throws Throwable { diff --git a/src/protocol/java/src/main/java/org/apache/jmeter/protocol/java/sampler/BeanShellSampler.java b/src/protocol/java/src/main/java/org/apache/jmeter/protocol/java/sampler/BeanShellSampler.java index 0039237c7f..3607a55692 100644 --- a/src/protocol/java/src/main/java/org/apache/jmeter/protocol/java/sampler/BeanShellSampler.java +++ b/src/protocol/java/src/main/java/org/apache/jmeter/protocol/java/sampler/BeanShellSampler.java @@ -74,7 +74,7 @@ public class BeanShellSampler extends BeanShellTestElement implements Sampler, I @Override protected String getInitFileProperty() { - return BeanShellSamplerSchema.INSTANCE.getInitFile().getName(); + return INIT_FILE; } @Override diff --git a/src/protocol/java/src/main/kotlin/org/apache/jmeter/protocol/java/sampler/BeanShellSamplerSchema.kt b/src/protocol/java/src/main/kotlin/org/apache/jmeter/protocol/java/sampler/BeanShellSamplerSchema.kt index 33b506d469..e4552fc433 100644 --- a/src/protocol/java/src/main/kotlin/org/apache/jmeter/protocol/java/sampler/BeanShellSamplerSchema.kt +++ b/src/protocol/java/src/main/kotlin/org/apache/jmeter/protocol/java/sampler/BeanShellSamplerSchema.kt @@ -40,9 +40,6 @@ public abstract class BeanShellSamplerSchema : TestElementSchema() { public val parameters: StringPropertyDescriptor<BeanShellSamplerSchema> by string("BeanShellSampler.parameters") - public val initFile: StringPropertyDescriptor<BeanShellSamplerSchema> - by string("beanshell.sampler.init") - public val filename: StringPropertyDescriptor<BeanShellSamplerSchema> by string("BeanShellSampler.filename") }
