-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Comments
@FSchumacher (migrated from Bugzilla): What do you mean with multi-threaded JMeter tests? How do you set the labels? |
travis.mcginley (migrated from Bugzilla): Created attachment Test_Plan.PNG: Test plan |
travis.mcginley (migrated from Bugzilla): Created attachment MFG_MCF_Load_Test-20Users_20Machines.log: Log File MFG_MCF_Load_Test-20Users_20Machines.log
|
travis.mcginley (migrated from Bugzilla):
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. |
@FSchumacher (migrated from Bugzilla): 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) |
travis.mcginley (migrated from Bugzilla): Created attachment MFG_MCF_Load_Test-20Users_20Machines.jmx.html: Test Schematic |
travis.mcginley (migrated from Bugzilla):
I will try the test plan you attached. In the mean time, I attached the schematic you requested, for your review. |
travis.mcginley (migrated from Bugzilla):
Hi Felix, I was not able to reproduce the problem with the test file you provided. |
@FSchumacher (migrated from Bugzilla): 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? |
travis.mcginley (migrated from Bugzilla):
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. |
@FSchumacher (migrated from Bugzilla): 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> |
@FSchumacher (migrated from Bugzilla): |
@FSchumacher (migrated from Bugzilla): 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.patchFrom 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
|
@FSchumacher (migrated from Bugzilla): 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.patchFrom 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
|
@FSchumacher (migrated from Bugzilla): commit 3128163
.../jmeter/testelement/AbstractTestElement.java | 10 ++- |
@FSchumacher (migrated from Bugzilla):
xdocs/changes.xml | 1 + |
@FSchumacher (migrated from Bugzilla): |
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
Severity: major
OS: All
The text was updated successfully, but these errors were encountered: