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")
 }

Reply via email to