Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blank labels in multi-threaded Jmeter tests #5544

Closed
asfimport opened this issue May 27, 2021 · 17 comments
Closed

Blank labels in multi-threaded Jmeter tests #5544

asfimport opened this issue May 27, 2021 · 17 comments

Comments

@asfimport
Copy link
Collaborator

travis.mcginley (Bug 65336):
When running multi-threaded Jmeter tests, some request labels disappear. It seems that once a thread runs the initial request, the subsequent requests no longer have a label. Please see attached screenshot for an example. This affects the data when generating HTML reports as the results consolidate all requests with no label. This issue is reproducible.

Created attachment ResultTree_Blank_Label.PNG: Result Tree with blank labels

Result Tree with blank labels

Severity: major
OS: All

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
Can you supply a minimal test plan to reproduce this?

What do you mean with multi-threaded JMeter tests?

How do you set the labels?

@asfimport
Copy link
Collaborator Author

travis.mcginley (migrated from Bugzilla):
Test plan showing which the requests that have their labels disappearing after some time.

Created attachment Test_Plan.PNG: Test plan

Test plan

@asfimport
Copy link
Collaborator Author

travis.mcginley (migrated from Bugzilla):
Log file from most recent test.

Created attachment MFG_MCF_Load_Test-20Users_20Machines.log: Log File

MFG_MCF_Load_Test-20Users_20Machines.log
2021-05-27 12:37:19,126 INFO o.a.j.u.JMeterUtils: Setting Locale to en_EN
2021-05-27 12:37:19,136 INFO o.a.j.JMeter: Loading user properties from: user.properties
2021-05-27 12:37:19,136 INFO o.a.j.JMeter: Loading system properties from: C:\Users\mcginltr\apache-jmeter-5.4.1\bin\system.properties
2021-05-27 12:37:19,143 INFO o.a.j.JMeter: Copyright (c) 1998-2021 The Apache Software Foundation
2021-05-27 12:37:19,143 INFO o.a.j.JMeter: Version 5.4.1
2021-05-27 12:37:19,143 INFO o.a.j.JMeter: java.version=1.8.0_281
2021-05-27 12:37:19,143 INFO o.a.j.JMeter: java.vm.name=Java HotSpot(TM) 64-Bit Server VM
2021-05-27 12:37:19,143 INFO o.a.j.JMeter: os.name=Windows 10
2021-05-27 12:37:19,143 INFO o.a.j.JMeter: os.arch=amd64
2021-05-27 12:37:19,144 INFO o.a.j.JMeter: os.version=10.0
2021-05-27 12:37:19,144 INFO o.a.j.JMeter: file.encoding=Cp1252
2021-05-27 12:37:19,144 INFO o.a.j.JMeter: java.awt.headless=null
2021-05-27 12:37:19,144 INFO o.a.j.JMeter: Max memory     =1073741824
2021-05-27 12:37:19,144 INFO o.a.j.JMeter: Available Processors =12
2021-05-27 12:37:19,147 INFO o.a.j.JMeter: Default Locale=English (EN)
2021-05-27 12:37:19,148 INFO o.a.j.JMeter: JMeter  Locale=English (EN)
2021-05-27 12:37:19,148 INFO o.a.j.JMeter: JMeterHome=C:\Users\mcginltr\apache-jmeter-5.4.1
2021-05-27 12:37:19,148 INFO o.a.j.JMeter: user.dir  =C:\Users\mcginltr\OneDrive - AGCO Corp\Documents\Development\Jmeter Load Testing\MFG_MCF_Load_Test\TEST-20Users_20Machines
2021-05-27 12:37:19,149 INFO o.a.j.JMeter: PWD       =C:\Users\mcginltr\OneDrive - AGCO Corp\Documents\Development\Jmeter Load Testing\MFG_MCF_Load_Test\TEST-20Users_20Machines
2021-05-27 12:37:19,152 INFO o.a.j.JMeter: IP: 10.3.215.17 Name: NAGTCMIS61MT1X2 FullName: NAGTCMIS61MT1X2.atlanta.agcocorp.com
2021-05-27 12:37:19,221 INFO o.a.j.JMeter: Setting LAF to: com.github.weisj.darklaf.DarkLaf:com.github.weisj.darklaf.theme.SolarizedLightTheme
2021-05-27 12:37:19,543 INFO o.a.j.JMeter: Loaded icon properties from org/apache/jmeter/images/icon.properties
2021-05-27 12:37:20,586 INFO o.a.j.JMeter: Loading file: MFG_MCF_Load_Test-20Users_20Machines.jmx
2021-05-27 12:37:20,587 INFO o.a.j.s.FileServer: Default base='C:\Users\mcginltr\OneDrive - AGCO Corp\Documents\Development\Jmeter Load Testing\MFG_MCF_Load_Test\TEST-20Users_20Machines'
2021-05-27 12:37:20,588 INFO o.a.j.s.FileServer: Set new base='C:\Users\mcginltr\OneDrive - AGCO Corp\Documents\Development\Jmeter Load Testing\MFG_MCF_Load_Test\TEST-20Users_20Machines'
2021-05-27 12:37:20,704 INFO o.a.j.s.SaveService: Testplan (JMX) version: 2.2. Testlog (JTL) version: 2.2
2021-05-27 12:37:20,715 INFO o.a.j.s.SaveService: Using SaveService properties file encoding UTF-8
2021-05-27 12:37:20,716 INFO o.a.j.s.SaveService: Using SaveService properties version 5.0
2021-05-27 12:37:20,719 INFO o.a.j.s.SaveService: Loading file: MFG_MCF_Load_Test-20Users_20Machines.jmx
2021-05-27 12:37:20,735 INFO o.a.j.p.h.c.CookieManager: Settings: Delete null: true Check: true Allow variable: true Save: false Prefix: COOKIE_
2021-05-27 12:37:20,738 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/html is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2021-05-27 12:37:20,739 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for application/xhtml+xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2021-05-27 12:37:20,739 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for application/xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2021-05-27 12:37:20,739 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2021-05-27 12:37:20,739 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/vnd.wap.wml is org.apache.jmeter.protocol.http.parser.RegexpHTMLParser
2021-05-27 12:37:20,739 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/css is org.apache.jmeter.protocol.http.parser.CssParser
2021-05-27 12:37:20,769 INFO o.a.j.s.FileServer: Set new base='C:\Users\mcginltr\OneDrive - AGCO Corp\Documents\Development\Jmeter Load Testing\MFG_MCF_Load_Test\TEST-20Users_20Machines'
2021-05-27 12:37:21,001 INFO o.a.j.s.SampleResult: Note: Sample TimeStamps are START times
2021-05-27 12:37:21,001 INFO o.a.j.s.SampleResult: sampleresult.default.encoding is set to ISO-8859-1
2021-05-27 12:37:21,001 INFO o.a.j.s.SampleResult: sampleresult.useNanoTime=true
2021-05-27 12:37:21,002 INFO o.a.j.s.SampleResult: sampleresult.nanoThreadSleep=5000

@asfimport
Copy link
Collaborator Author

travis.mcginley (migrated from Bugzilla):
(In reply to Felix Schumacher from comment 1)

Can you supply a minimal test plan to reproduce this?

What do you mean with multi-threaded JMeter tests?

How do you set the labels?

Hi Felix, thanks for reaching out. I attached additional images and files to help assist with the problem.

One image shows the test plan that is executed. What this shows is a thread group "Load" that has an initial request "access_token" that runs only once per thread. The thread group is comprised of 20 users and runs for 900 seconds with a ramp time of 100 seconds. Once the initial 20 threads are created, the portion of the group that loops is "Mfg feature-check", "Mfg send MCF", and "Mfg verify MCF". The first set of requests of these 3 have labels while the subsequent iterations are blank.

I set the labels via the "Name" second of the HTTP Request block.

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
Travis, I tried to re-create a plan, that would let me re-produce this, but I failed. Can you try the attached plan and look for differences to yours and may be make it fail, too? (you have to start the mirror server in the test plan)

Instead of pictures of a test plan, it would be way better to attach a real test plan, or use the schematic view from the tools menu.

Created attachment simple-plan.jmx: Simple plan (that doesn't show this)

@asfimport
Copy link
Collaborator Author

travis.mcginley (migrated from Bugzilla):
Schematic of test plan

Created attachment MFG_MCF_Load_Test-20Users_20Machines.jmx.html: Test Schematic

@asfimport
Copy link
Collaborator Author

travis.mcginley (migrated from Bugzilla):
(In reply to Felix Schumacher from comment 5)

Created attachment 37882 [details]
Simple plan (that doesn't show this)

Travis, I tried to re-create a plan, that would let me re-produce this, but
I failed. Can you try the attached plan and look for differences to yours
and may be make it fail, too? (you have to start the mirror server in the
test plan)

Instead of pictures of a test plan, it would be way better to attach a real
test plan, or use the schematic view from the tools menu.

I will try the test plan you attached. In the mean time, I attached the schematic you requested, for your review.

@asfimport
Copy link
Collaborator Author

travis.mcginley (migrated from Bugzilla):
(In reply to travis.mcginley from comment 7)

(In reply to Felix Schumacher from comment 5)
> Created attachment 37882 [details]
> Simple plan (that doesn't show this)
>
> Travis, I tried to re-create a plan, that would let me re-produce this, but
> I failed. Can you try the attached plan and look for differences to yours
> and may be make it fail, too? (you have to start the mirror server in the
> test plan)
>
> Instead of pictures of a test plan, it would be way better to attach a real
> test plan, or use the schematic view from the tools menu.

I will try the test plan you attached. In the mean time, I attached the
schematic you requested, for your review.

Hi Felix, I was not able to reproduce the problem with the test file you provided.

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
I can find no real differences rom the attached schematic plan to my attached working plan.

Is the problem reproducible with one thread (simulated user)?

Can you show the results (in the Results Tree View) of the request before the missing label and the one with the missing label?

@asfimport
Copy link
Collaborator Author

travis.mcginley (migrated from Bugzilla):
(In reply to Felix Schumacher from comment 9)

I can find no real differences rom the attached schematic plan to my
attached working plan.

Is the problem reproducible with one thread (simulated user)?

Can you show the results (in the Results Tree View) of the request before
the missing label and the one with the missing label?

Hi Felix, I apologize for the late response as I was on vacation. We were able to figure out what was causing the issue. When the HTTP Header Manager has the exact same name of its HTTP Request, this causes the titles of the subsequent threads to appear blank. We are unsure why this is the cause; upon making the Header Manager's name different, the problem no longer occurs.

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
Thanks for the further information. I can now reproduce the problem and will investigate further.

Created attachment minimal-bug-65336-missing-labels.jmx: Minimal plan to reproduce

minimal-bug-65336-missing-labels.jmx
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.5-SNAPSHOT fbad523">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
      <stringProp name="TestPlan.comments"></stringProp>
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <stringProp name="TestPlan.user_define_classpath"></stringProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <stringProp name="LoopController.loops">2</stringProp>
        </elementProp>
        <stringProp name="ThreadGroup.num_threads">1</stringProp>
        <stringProp name="ThreadGroup.ramp_time">1</stringProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
        <stringProp name="ThreadGroup.duration"></stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
        <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
      </ThreadGroup>
      <hashTree>
        <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
          <boolProp name="ResultCollector.error_logging">false</boolProp>
          <objProp>
            <name>saveConfig</name>
            <value class="SampleSaveConfiguration">
              <time>true</time>
              <latency>true</latency>
              <timestamp>true</timestamp>
              <success>true</success>
              <label>true</label>
              <code>true</code>
              <message>true</message>
              <threadName>true</threadName>
              <dataType>true</dataType>
              <encoding>false</encoding>
              <assertions>true</assertions>
              <subresults>true</subresults>
              <responseData>false</responseData>
              <samplerData>false</samplerData>
              <xml>false</xml>
              <fieldNames>true</fieldNames>
              <responseHeaders>false</responseHeaders>
              <requestHeaders>false</requestHeaders>
              <responseDataOnError>false</responseDataOnError>
              <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
              <assertionsResultsToSave>0</assertionsResultsToSave>
              <bytes>true</bytes>
              <sentBytes>true</sentBytes>
              <url>true</url>
              <threadCounts>true</threadCounts>
              <idleTime>true</idleTime>
              <connectTime>true</connectTime>
            </value>
          </objProp>
          <stringProp name="filename"></stringProp>
        </ResultCollector>
        <hashTree/>
        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Mfg send MCF" enabled="true">
          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
            <collectionProp name="Arguments.arguments"/>
          </elementProp>
          <stringProp name="HTTPSampler.domain">localhost</stringProp>
          <stringProp name="HTTPSampler.port">8081</stringProp>
          <stringProp name="HTTPSampler.protocol"></stringProp>
          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
          <stringProp name="HTTPSampler.path"></stringProp>
          <stringProp name="HTTPSampler.method">POST</stringProp>
          <boolProp name="HTTPSampler.follow_redirects">false</boolProp>
          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
          <boolProp name="HTTPSampler.use_keepalive">false</boolProp>
          <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
          <stringProp name="HTTPSampler.response_timeout"></stringProp>
        </HTTPSamplerProxy>
        <hashTree>
          <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="Mfg send MCF" enabled="true">
            <collectionProp name="HeaderManager.headers"/>
          </HeaderManager>
          <hashTree/>
        </hashTree>
      </hashTree>
      <HttpMirrorControl guiclass="HttpMirrorControlGui" testclass="HttpMirrorControl" testname="HTTP Mirror Server" enabled="true">
        <stringProp name="HttpMirrorControlGui.port">8081</stringProp>
        <stringProp name="HttpMirrorControlGui.maxPoolSize">0</stringProp>
        <stringProp name="HttpMirrorControlGui.maxQueueSize">25</stringProp>
      </HttpMirrorControl>
      <hashTree/>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
The problem seems to stem from the HeaderManager (and others like the CookieManager) to register their names under the same key in the properties and marking the prop as temporary. Those temporary properties are removed when the testplan is 'pack'ed.

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
After further investigations, it seems this is a regression introduced in Bug 2003 by commit 73ac1ed.

If a JMeterProperty is marked as temporary and it is a MultiProperty, every property of that MultiProperty is marked as temporary in a global Set. This is problematic at least in the case we see here, where one property is the StringProperty with the same key (AbstractTestElement.NAME) and value ("Mfg send MFC").

A simple (but probably not correct) fix would be to skip marking StringProperties with key AbstractTestElement.NAME. That way the plan in this issue works without problems. But we might miss marking properties, that should be cleaned up.

I think about adding some kind of scope to the props of MultiProperties, that would allow us to correctly identify the inner props, that are temporary and those, that are not.

So, I am glad, that you found a workaround and can hopefully live with it for a while. Changes here should probably not be taken lightly.

Created attachment 0001-Skip-NAME-when-marking-temporary-props.patch: Skip NAME when marking temporar props

0001-Skip-NAME-when-marking-temporary-props.patch
From 7e6e657c118af0d5e0642146c5e2ad393eb706a9 Mon Sep 17 00:00:00 2001
From: Felix Schumacher <felix.schumacher@internetallee.de>
Date: Thu, 3 Jun 2021 15:25:05 +0200
Subject: [PATCH] Skip NAME when marking temporary props

---
 .../org/apache/jmeter/testelement/AbstractTestElement.java    | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/core/src/main/java/org/apache/jmeter/testelement/AbstractTestElement.java b/src/core/src/main/java/org/apache/jmeter/testelement/AbstractTestElement.java
index 94364f26b9..8c4c4690b6 100644
--- a/src/core/src/main/java/org/apache/jmeter/testelement/AbstractTestElement.java
+++ b/src/core/src/main/java/org/apache/jmeter/testelement/AbstractTestElement.java
@@ -548,6 +548,10 @@ public abstract class AbstractTestElement implements TestElement, Serializable,
         temporaryProperties.add(property);
         if (property instanceof MultiProperty) {
             for (JMeterProperty jMeterProperty : (MultiProperty) property) {
+                if (NAME.equals(jMeterProperty.getName())) {
+                    log.debug("Skip marking NAME ({}) as temporary property", jMeterProperty);
+                    continue;
+                }
                 setTemporary(jMeterProperty);
             }
         }
-- 
2.25.1

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
The inner properties of a MultiProperty are marked as temporary by
the AbstractTestElement setTemporary implementation. This is needed,
since the MultiProperty default implementation of mergeIn is recursive
on MultiProperties. The TestElementProperty does not implement this
method recursively and therefore must not have marked the enclosed
properties as temporary.

Created attachment 0001-Don-t-mark-enclosed-properties-of-TestElementPropert.patch: Don't mark enclosed properties of TestElementProperty as temporary

0001-Don-t-mark-enclosed-properties-of-TestElementPropert.patch
From 43346579b4cd799e832114a0c2e069412617c911 Mon Sep 17 00:00:00 2001
From: Felix Schumacher <felix.schumacher@internetallee.de>
Date: Sun, 6 Jun 2021 13:22:37 +0200
Subject: [PATCH] Don't mark enclosed properties of TestElementProperty as
 temporary

The inner properties of a MultiProperty are marked as temporary by
the AbstractTestElement setTemporary implementation. This is needed,
since the MultiProperty default implementation of mergeIn is recursive
on MultiProperties. The TestElementProperty does not implement this
method recursively and therefore must not have marked the enclosed
properties as temporary.
---
 .../testelement/AbstractTestElement.java      | 10 +-
 .../AbstractTestElementSpec.groovy            | 99 +++++++++++++++++++
 2 files changed, 108 insertions(+), 1 deletion(-)
 create mode 100644 src/core/src/test/groovy/org/apache/jmeter/testelement/AbstractTestElementSpec.groovy

diff --git a/src/core/src/main/java/org/apache/jmeter/testelement/AbstractTestElement.java b/src/core/src/main/java/org/apache/jmeter/testelement/AbstractTestElement.java
index 94364f26b9..93f8369515 100644
--- a/src/core/src/main/java/org/apache/jmeter/testelement/AbstractTestElement.java
+++ b/src/core/src/main/java/org/apache/jmeter/testelement/AbstractTestElement.java
@@ -546,13 +546,21 @@ public abstract class AbstractTestElement implements TestElement, Serializable,
             temporaryProperties = new LinkedHashSet<>();
         }
         temporaryProperties.add(property);
-        if (property instanceof MultiProperty) {
+        if (isMergingEnclosedProperties(property)) {
             for (JMeterProperty jMeterProperty : (MultiProperty) property) {
                 setTemporary(jMeterProperty);
             }
         }
     }
 
+    // While TestElementProperty is implementing MultiProperty, it works differently.
+    // It doesn't merge the inner properties one by one as MultiProperty would do.
+    // Therefore we must not mark the enclosed properties of TestElementProperty as
+    // temporary (Bug 65336)
+    private boolean isMergingEnclosedProperties(JMeterProperty property) {
+        return property instanceof MultiProperty && !(property instanceof TestElementProperty);
+    }
+
     /**
      * @return Returns the threadContext.
      */
diff --git a/src/core/src/test/groovy/org/apache/jmeter/testelement/AbstractTestElementSpec.groovy b/src/core/src/test/groovy/org/apache/jmeter/testelement/AbstractTestElementSpec.groovy
new file mode 100644
index 0000000000..c258cc3633
--- /dev/null
+++ b/src/core/src/test/groovy/org/apache/jmeter/testelement/AbstractTestElementSpec.groovy
@@ -0,0 +1,99 @@
+/*
+ * 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.testelement
+
+import org.apache.jmeter.junit.spock.JMeterSpec
+import org.apache.jmeter.testelement.property.JMeterProperty
+import org.apache.jmeter.testelement.property.MultiProperty
+import org.apache.jmeter.testelement.property.PropertyIterator
+import org.apache.jmeter.testelement.property.TestElementProperty
+
+import spock.lang.Unroll
+import sun.reflect.generics.reflectiveObjects.NotImplementedException
+
+@Unroll
+class AbstractTestElementSpec extends JMeterSpec {
+
+    def "set outer properties as temporary when using a TestElementProperty"() {
+        given:
+            AbstractTestElement sut = Spy(AbstractTestElement.class)
+            def outerElement = Mock(TestElement.class)
+            def innerElement = Mock(TestElement.class)
+            def outerProp = new TestElementProperty("outerProp", outerElement)
+            def innerProp = new TestElementProperty("innerProp", innerElement)
+            outerProp.addProperty(innerProp)
+        when:
+            sut.setTemporary(outerProp)
+        then:
+            sut.isTemporary(outerProp)
+            !sut.isTemporary(innerProp)
+    }
+
+    def "set all properties as temporary when using a MultiProperty"() {
+        given:
+            AbstractTestElement sut = Spy(AbstractTestElement.class)
+            def outerProp = new MinimalMultiProperty()
+            def innerProp = new MinimalMultiProperty()
+            outerProp.addProperty(innerProp)
+        when:
+            sut.setTemporary(outerProp)
+        then:
+            sut.isTemporary(outerProp)
+            sut.isTemporary(innerProp)
+    }
+
+    private class MinimalMultiProperty extends MultiProperty {
+
+        Set<JMeterProperty> props = new HashSet<>()
+
+        @Override
+        void recoverRunningVersion(TestElement owner) {
+            throw new NotImplementedException()
+        }
+
+        @Override
+        String getStringValue() {
+            throw new NotImplementedException()
+        }
+
+        @Override
+        Object getObjectValue() {
+            return null
+        }
+
+        @Override
+        void setObjectValue(Object value) {
+            throw new NotImplementedException()
+        }
+
+        @Override
+        PropertyIterator iterator() {
+            return props.iterator() as PropertyIterator
+        }
+
+        @Override
+        void addProperty(JMeterProperty prop) {
+            props.add(prop)
+        }
+
+        @Override
+        void clear() {
+            props.clear()
+        }
+    }
+}
-- 
2.25.1

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
Hi Travis,
could you test the next nightly build and check, if it works for your use case?

commit 3128163
AuthorDate: Sun Jun 6 13:22:37 2021 +0200

Don't mark enclosed properties of TestElementProperty as temporary

The inner properties of a MultiProperty are marked as temporary by
the AbstractTestElement setTemporary implementation. This is needed,
since the MultiProperty default implementation of mergeIn is recursive
on MultiProperties. The TestElementProperty does not implement this
method recursively and therefore must not have marked the enclosed
properties as temporary.

https://github.com/apache/jmeter/issues/5544

.../jmeter/testelement/AbstractTestElement.java | 10 ++-
.../testelement/AbstractTestElementSpec.groovy | 99 ++++++++++++++++++++++
2 files changed, 108 insertions(+), 1 deletion(-)

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
commit ece6161
AuthorDate: Sun Aug 29 11:04:36 2021 +0200

Missing changes entry for https://github.com/apache/jmeter/issues/5544

xdocs/changes.xml | 1 +
1 file changed, 1 insertion(+)

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
Closing, as no feedback probably means, it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant