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
The following commit(s) were added to refs/heads/master by this push:
new 8cf1e4a186 feat: allow to enable/disable individual arguments in HTTP
Sampler
8cf1e4a186 is described below
commit 8cf1e4a1868199dcd1d1261866f22fa43be31767
Author: pochopsp <[email protected]>
AuthorDate: Tue Jun 11 23:55:33 2024 +0200
feat: allow to enable/disable individual arguments in HTTP Sampler
This property is set by the user for each HTTP parameter by
clicking on the "Enable" column put on the very left of each
parameter row.
Fixes https://github.com/apache/jmeter/issues/5466
Co-authored-by: Vladimir Sitnikov <[email protected]>
---
.../java/org/apache/jmeter/config/Arguments.java | 16 +-
.../jmeter/treebuilder/TreeBuilderExtensions.kt | 34 ++++
.../jmeter/timers/ConstantThroughputTimerKtTest.kt | 17 +-
.../protocol/http/config/gui/UrlConfigGui.java | 2 +-
.../protocol/http/gui/HTTPArgumentsPanel.java | 12 +-
.../jmeter/protocol/http/sampler/AjpSampler.java | 2 +-
.../jmeter/protocol/http/sampler/HTTPHC4Impl.java | 10 +-
.../protocol/http/sampler/HTTPSamplerBase.java | 11 +-
.../jmeter/protocol/http/sampler/PostWriter.java | 4 +-
.../jmeter/protocol/http/sampler/PutWriter.java | 2 +-
.../sampler/HttpSamplerDisableArgumentsTest.kt | 174 +++++++++++++++++++++
.../protocol/http/sampler/HttpSamplerTest.kt | 38 +----
.../http/sampler/HttpSamplerTestingUtils.kt | 40 +++++
.../http/control/HttpRequestDefaultsExtensions.kt | 53 +++++++
14 files changed, 342 insertions(+), 73 deletions(-)
diff --git a/src/core/src/main/java/org/apache/jmeter/config/Arguments.java
b/src/core/src/main/java/org/apache/jmeter/config/Arguments.java
index e6a060dd7f..0301eb5862 100644
--- a/src/core/src/main/java/org/apache/jmeter/config/Arguments.java
+++ b/src/core/src/main/java/org/apache/jmeter/config/Arguments.java
@@ -23,11 +23,13 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import org.apache.commons.collections4.iterators.FilterIterator;
import org.apache.jmeter.testelement.property.CollectionProperty;
import org.apache.jmeter.testelement.property.JMeterProperty;
import org.apache.jmeter.testelement.property.PropertyIterator;
import org.apache.jmeter.testelement.property.TestElementProperty;
import org.apache.jmeter.testelement.schema.PropertiesAccessor;
+import org.apiguardian.api.API;
/**
* A set of Argument objects.
@@ -100,7 +102,7 @@ public class Arguments extends ConfigTestElement implements
Serializable, Iterab
// that this element's values prevail over defaults provided by
// configuration
// elements:
- if (!argMap.containsKey(arg.getName())) {
+ if (!argMap.containsKey(arg.getName()) && arg.isEnabled()) {
argMap.put(arg.getName(), arg.getValue());
}
}
@@ -173,6 +175,18 @@ public class Arguments extends ConfigTestElement
implements Serializable, Iterab
return getArguments().iterator();
}
+ /**
+ * Returns the list of enabled arguments.
+ * @return the list of enabled arguments
+ */
+ @API(since = "5.6", status = API.Status.EXPERIMENTAL)
+ public Iterable<JMeterProperty> getEnabledArguments() {
+ return () -> new FilterIterator<>(iterator(), property -> {
+ Object value = property.getObjectValue();
+ return value instanceof Argument argument && argument.isEnabled();
+ });
+ }
+
/**
* Create a string representation of the arguments.
*
diff --git
a/src/core/src/testFixtures/kotlin/org/apache/jmeter/treebuilder/TreeBuilderExtensions.kt
b/src/core/src/testFixtures/kotlin/org/apache/jmeter/treebuilder/TreeBuilderExtensions.kt
new file mode 100644
index 0000000000..650456f4f1
--- /dev/null
+++
b/src/core/src/testFixtures/kotlin/org/apache/jmeter/treebuilder/TreeBuilderExtensions.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.treebuilder
+
+import org.apache.jmeter.control.LoopController
+import org.apache.jmeter.threads.ThreadGroup
+
+fun TreeBuilder.oneRequest(body: ThreadGroup.() -> Unit) {
+ ThreadGroup::class {
+ numThreads = 1
+ rampUp = 0
+ setSamplerController(
+ LoopController().apply {
+ loops = 1
+ }
+ )
+ body()
+ }
+}
diff --git
a/src/functions/src/test/kotlin/org/apache/jmeter/timers/ConstantThroughputTimerKtTest.kt
b/src/functions/src/test/kotlin/org/apache/jmeter/timers/ConstantThroughputTimerKtTest.kt
index 1a1dc805ae..bcbc6cf045 100644
---
a/src/functions/src/test/kotlin/org/apache/jmeter/timers/ConstantThroughputTimerKtTest.kt
+++
b/src/functions/src/test/kotlin/org/apache/jmeter/timers/ConstantThroughputTimerKtTest.kt
@@ -17,30 +17,15 @@
package org.apache.jmeter.timers
-import org.apache.jmeter.control.LoopController
import org.apache.jmeter.junit.JMeterTestCase
import org.apache.jmeter.sampler.DebugSampler
import org.apache.jmeter.test.assertions.executePlanAndCollectEvents
-import org.apache.jmeter.threads.ThreadGroup
-import org.apache.jmeter.treebuilder.TreeBuilder
+import org.apache.jmeter.treebuilder.oneRequest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import kotlin.time.Duration.Companion.seconds
class ConstantThroughputTimerKtTest : JMeterTestCase() {
- fun TreeBuilder.oneRequest(body: ThreadGroup.() -> Unit) {
- ThreadGroup::class {
- numThreads = 1
- rampUp = 0
- setSamplerController(
- LoopController().apply {
- loops = 1
- }
- )
- body()
- }
- }
-
@Test
fun `throughput as variable`() {
val events = executePlanAndCollectEvents(5.seconds) {
diff --git
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/config/gui/UrlConfigGui.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/config/gui/UrlConfigGui.java
index 593d54a782..2cb82f654c 100644
---
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/config/gui/UrlConfigGui.java
+++
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/config/gui/UrlConfigGui.java
@@ -261,7 +261,7 @@ public class UrlConfigGui extends JPanel implements
ChangeListener {
*/
private static String computePostBody(Arguments arguments, boolean
crlfToLF) {
StringBuilder postBody = new StringBuilder();
- for (JMeterProperty argument : arguments) {
+ for (JMeterProperty argument : arguments.getEnabledArguments()) {
HTTPArgument arg = (HTTPArgument) argument.getObjectValue();
String value = arg.getValue();
if (crlfToLF) {
diff --git
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/gui/HTTPArgumentsPanel.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/gui/HTTPArgumentsPanel.java
index d350dc2666..7e58144621 100644
---
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/gui/HTTPArgumentsPanel.java
+++
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/gui/HTTPArgumentsPanel.java
@@ -39,12 +39,15 @@ import org.apache.jorphan.util.StringUtilities;
/**
* A GUI panel allowing the user to enter HTTP Parameters.
* These have names and values, as well as check-boxes to determine whether or
not to
- * include the "=" sign in the output and whether or not to encode the output.
+ * include the "=" sign in the output and whether or not to encode the output
and
+ * whether or not to enable them.
*/
public class HTTPArgumentsPanel extends ArgumentsPanel {
private static final long serialVersionUID = 240L;
+ private static final String ENABLE = "enable"; //$NON-NLS-1$
+
private static final String ENCODE_OR_NOT = "encode?"; //$NON-NLS-1$
private static final String INCLUDE_EQUALS = "include_equals";
//$NON-NLS-1$
@@ -60,21 +63,23 @@ public class HTTPArgumentsPanel extends ArgumentsPanel {
@Override
protected void initializeTableModel() {
tableModel = new ObjectTableModel(new String[] {
- ArgumentsPanel.COLUMN_RESOURCE_NAMES_0,
ArgumentsPanel.COLUMN_RESOURCE_NAMES_1, ENCODE_OR_NOT, CONTENT_TYPE,
INCLUDE_EQUALS },
+ ENABLE, ArgumentsPanel.COLUMN_RESOURCE_NAMES_0,
ArgumentsPanel.COLUMN_RESOURCE_NAMES_1, ENCODE_OR_NOT, CONTENT_TYPE,
INCLUDE_EQUALS },
HTTPArgument.class,
new Functor[] {
+ new Functor("isEnabled"), //$NON-NLS-1$
new Functor("getName"), //$NON-NLS-1$
new Functor("getValue"), //$NON-NLS-1$
new Functor("isAlwaysEncoded"), //$NON-NLS-1$
new Functor("getContentType"), //$NON-NLS-1$
new Functor("isUseEquals") }, //$NON-NLS-1$
new Functor[] {
+ new Functor("setEnabled"), //$NON-NLS-1$
new Functor("setName"), //$NON-NLS-1$
new Functor("setValue"), //$NON-NLS-1$
new Functor("setAlwaysEncoded"), //$NON-NLS-1$
new Functor("setContentType"),
new Functor("setUseEquals")}, //$NON-NLS-1$
- new Class[] {String.class, String.class, Boolean.class,
String.class, Boolean.class });
+ new Class[] {Boolean.class, String.class, String.class,
Boolean.class, String.class, Boolean.class });
}
public static boolean testFunctors(){
@@ -85,6 +90,7 @@ public class HTTPArgumentsPanel extends ArgumentsPanel {
@Override
protected void sizeColumns(JTable table) {
+ GuiUtils.fixSize(table.getColumn(ENABLE), table);
GuiUtils.fixSize(table.getColumn(INCLUDE_EQUALS), table);
GuiUtils.fixSize(table.getColumn(ENCODE_OR_NOT), table);
}
diff --git
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/AjpSampler.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/AjpSampler.java
index d705ae726c..2a5fe624bc 100644
---
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/AjpSampler.java
+++
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/AjpSampler.java
@@ -279,7 +279,7 @@ public class AjpSampler extends HTTPSamplerBase implements
Interruptible {
setString(HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
StringBuilder sb = new StringBuilder();
boolean first = true;
- for (JMeterProperty arg : getArguments()) {
+ for (JMeterProperty arg :
getArguments().getEnabledArguments()) {
if (first) {
first = false;
} else {
diff --git
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
index 2e68cb2226..569bb164b6 100644
---
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
+++
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
@@ -158,7 +158,6 @@ import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.services.FileServer;
import org.apache.jmeter.testelement.property.CollectionProperty;
import org.apache.jmeter.testelement.property.JMeterProperty;
-import org.apache.jmeter.testelement.property.PropertyIterator;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.JMeterVariables;
import org.apache.jmeter.util.JMeterUtils;
@@ -1562,7 +1561,7 @@ public class HTTPHC4Impl extends HTTPHCAbstractImpl {
}
// Create the parts
// Add any parameters
- for (JMeterProperty jMeterProperty : getArguments()) {
+ for (JMeterProperty jMeterProperty :
getArguments().getEnabledArguments()) {
HTTPArgument arg = (HTTPArgument)
jMeterProperty.getObjectValue();
String parameterName = arg.getName();
if (arg.isSkippable(parameterName)) {
@@ -1644,7 +1643,7 @@ public class HTTPHC4Impl extends HTTPHCAbstractImpl {
// Just append all the parameter values, and use that as
the post body
StringBuilder postBody = new StringBuilder();
- for (JMeterProperty jMeterProperty : getArguments()) {
+ for (JMeterProperty jMeterProperty :
getArguments().getEnabledArguments()) {
HTTPArgument arg = (HTTPArgument)
jMeterProperty.getObjectValue();
postBody.append(arg.getEncodedValue(contentEncoding));
}
@@ -1787,10 +1786,9 @@ public class HTTPHC4Impl extends HTTPHCAbstractImpl {
private UrlEncodedFormEntity createUrlEncodedFormEntity(final String
urlContentEncoding) throws UnsupportedEncodingException {
// It is a normal request, with parameter names and values
// Add the parameters
- PropertyIterator args = getArguments().iterator();
List<NameValuePair> nvps = new ArrayList<>();
- while (args.hasNext()) {
- HTTPArgument arg = (HTTPArgument) args.next().getObjectValue();
+ for (JMeterProperty jMeterProperty:
getArguments().getEnabledArguments()) {
+ HTTPArgument arg = (HTTPArgument) jMeterProperty.getObjectValue();
// The HTTPClient always urlencodes both name and value,
// so if the argument is already encoded, we have to decode
// it before adding it to the post request
diff --git
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
index ccaf33d1e6..45628aeed2 100644
---
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
+++
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
@@ -79,7 +79,6 @@ import org.apache.jmeter.testelement.TestStateListener;
import org.apache.jmeter.testelement.ThreadListener;
import org.apache.jmeter.testelement.property.CollectionProperty;
import org.apache.jmeter.testelement.property.JMeterProperty;
-import org.apache.jmeter.testelement.property.PropertyIterator;
import org.apache.jmeter.testelement.schema.PropertiesAccessor;
import org.apache.jmeter.testelement.schema.PropertyDescriptor;
import org.apache.jmeter.threads.JMeterContext;
@@ -410,7 +409,7 @@ public abstract class HTTPSamplerBase extends
AbstractSampler
return true;
} else {
boolean hasArguments = false;
- for (JMeterProperty jMeterProperty : getArguments()) {
+ for (JMeterProperty jMeterProperty :
getArguments().getEnabledArguments()) {
hasArguments = true;
HTTPArgument arg = (HTTPArgument)
jMeterProperty.getObjectValue();
if (arg.getName() != null && !arg.getName().isEmpty()) {
@@ -1156,9 +1155,10 @@ public abstract class HTTPSamplerBase extends
AbstractSampler
*/
public String getQueryString(final String contentEncoding) {
- CollectionProperty arguments = getArguments().getArguments();
+ Arguments args = getArguments();
+ Iterator<JMeterProperty> iter = args.getEnabledArguments().iterator();
// Optimisation : avoid building useless objects if empty arguments
- if(arguments.isEmpty()) {
+ if (!iter.hasNext()) {
return "";
}
String lContentEncoding = contentEncoding;
@@ -1168,8 +1168,7 @@ public abstract class HTTPSamplerBase extends
AbstractSampler
lContentEncoding = EncoderCache.URL_ARGUMENT_ENCODING;
}
- StringBuilder buf = new StringBuilder(arguments.size() * 15);
- PropertyIterator iter = arguments.iterator();
+ StringBuilder buf = new StringBuilder(args.getArgumentCount() * 15);
boolean first = true;
while (iter.hasNext()) {
HTTPArgument item = null;
diff --git
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/PostWriter.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/PostWriter.java
index c34d430829..8cc29d8cdd 100644
---
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/PostWriter.java
+++
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/PostWriter.java
@@ -191,7 +191,7 @@ public class PostWriter {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(bos,
contentEncoding);
// Add any parameters
- for (JMeterProperty jMeterProperty : sampler.getArguments()) {
+ for (JMeterProperty jMeterProperty :
sampler.getArguments().getEnabledArguments()) {
HTTPArgument arg = (HTTPArgument)
jMeterProperty.getObjectValue();
String parameterName = arg.getName();
if (arg.isSkippable(parameterName)) {
@@ -300,7 +300,7 @@ public class PostWriter {
// Just append all the parameter values, and use that as
the post body
StringBuilder postBodyBuffer = new StringBuilder();
- for (JMeterProperty jMeterProperty :
sampler.getArguments()) {
+ for (JMeterProperty jMeterProperty :
sampler.getArguments().getEnabledArguments()) {
HTTPArgument arg = (HTTPArgument)
jMeterProperty.getObjectValue();
postBodyBuffer.append(arg.getEncodedValue(contentEncoding));
}
diff --git
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/PutWriter.java
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/PutWriter.java
index 5a020662f7..488495d44c 100644
---
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/PutWriter.java
+++
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/PutWriter.java
@@ -85,7 +85,7 @@ public class PutWriter extends PostWriter {
// Just append all the parameter values, and use that as the put
body
StringBuilder putBodyBuffer = new StringBuilder();
- for (JMeterProperty jMeterProperty : sampler.getArguments()) {
+ for (JMeterProperty jMeterProperty :
sampler.getArguments().getEnabledArguments()) {
HTTPArgument arg = (HTTPArgument)
jMeterProperty.getObjectValue();
putBodyBuffer.append(arg.getEncodedValue(contentEncoding));
}
diff --git
a/src/protocol/http/src/test/kotlin/org/apache/jmeter/protocol/http/sampler/HttpSamplerDisableArgumentsTest.kt
b/src/protocol/http/src/test/kotlin/org/apache/jmeter/protocol/http/sampler/HttpSamplerDisableArgumentsTest.kt
new file mode 100644
index 0000000000..80c54d0f2a
--- /dev/null
+++
b/src/protocol/http/src/test/kotlin/org/apache/jmeter/protocol/http/sampler/HttpSamplerDisableArgumentsTest.kt
@@ -0,0 +1,174 @@
+/*
+ * 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.protocol.http.sampler
+
+import com.github.tomakehurst.wiremock.client.WireMock.aMultipart
+import com.github.tomakehurst.wiremock.client.WireMock.aResponse
+import com.github.tomakehurst.wiremock.client.WireMock.equalTo
+import com.github.tomakehurst.wiremock.client.WireMock.get
+import com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor
+import com.github.tomakehurst.wiremock.client.WireMock.post
+import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor
+import com.github.tomakehurst.wiremock.client.WireMock.put
+import com.github.tomakehurst.wiremock.client.WireMock.putRequestedFor
+import com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo
+import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo
+import com.github.tomakehurst.wiremock.junit5.WireMockTest
+import org.apache.jmeter.junit.JMeterTestCase
+import org.apache.jmeter.protocol.http.control.arguments
+import org.apache.jmeter.protocol.http.control.httpRequestDefaults
+import org.apache.jmeter.protocol.http.util.HTTPArgument
+import org.apache.jmeter.test.assertions.executePlanAndCollectEvents
+import org.apache.jmeter.treebuilder.TreeBuilder
+import org.apache.jmeter.treebuilder.oneRequest
+import org.junit.jupiter.params.ParameterizedTest
+import org.junit.jupiter.params.provider.ValueSource
+import kotlin.time.Duration.Companion.seconds
+
+@WireMockTest
+class HttpSamplerDisableArgumentsTest : JMeterTestCase() {
+
+ fun TreeBuilder.httpRequest(body: HTTPSamplerProxy.() -> Unit) {
+ HTTPSamplerProxy::class {
+ name = "Test disabled params"
+ method = "GET"
+ domain = "localhost"
+ path = "/test"
+ body()
+ }
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = ["Java", "HttpClient4"])
+ fun `GET disable param1 should send enabled param2`(httpImplementation:
String, server: WireMockRuntimeInfo) {
+ server.wireMock.register(
+ get("/test").willReturn(aResponse().withStatus(200))
+ )
+
+ executePlanAndCollectEvents(10.seconds) {
+ oneRequest {
+ httpRequest {
+ method = "GET"
+ implementation = httpImplementation
+ port = server.httpPort
+ addArgument("param1", "value1")
+ arguments.getArgument(0).isEnabled = false
+ addArgument("param2", "value2")
+ }
+ }
+ }
+
+ server.wireMock.verifyThat(
+ 1,
+ getRequestedFor(urlEqualTo("/test?param2=value2"))
+ )
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = ["Java", "HttpClient4"])
+ fun `PUT disable param2 should send enabled param1 and
param3`(httpImplementation: String, server: WireMockRuntimeInfo) {
+ server.wireMock.register(
+ put("/test").willReturn(aResponse().withStatus(200))
+ )
+
+ executePlanAndCollectEvents(1000.seconds) {
+ oneRequest {
+ httpRequest {
+ method = "PUT"
+ implementation = httpImplementation
+ port = server.httpPort
+ postBodyRaw = true
+ addArgument("param1", "value1")
+ addArgument("param2", "value2")
+ arguments.getArgument(1).isEnabled = false
+ addArgument("param3", "value3")
+ }
+ }
+ }
+
+ server.wireMock.verifyThat(
+ 1,
+ putRequestedFor(urlEqualTo("/test"))
+ .withRequestBody(equalTo("value1value3"))
+ )
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = ["Java", "HttpClient4"])
+ fun `POST disable default and non-default param should send the only
enabled non-default param`(httpImplementation: String, server:
WireMockRuntimeInfo) {
+ server.wireMock.register(
+ post("/test").willReturn(aResponse().withStatus(200))
+ )
+
+ executePlanAndCollectEvents(10.seconds) {
+ oneRequest {
+ httpRequestDefaults {
+ arguments {
+ addArgument(
+ HTTPArgument("param0", "value0").apply {
+ isEnabled = false
+ }
+ )
+ addArgument(
+ HTTPArgument("param4", "value4")
+ )
+ }
+ }
+ httpRequest {
+ method = "POST"
+ doMultipart = true
+ implementation = httpImplementation
+ port = server.httpPort
+ addArgument("param1", "value1")
+ arguments.getArgument(0).isEnabled = false
+ addArgument("param2", "value2")
+ }
+ }
+ }
+
+ server.wireMock.verifyThat(
+ 1,
+ postRequestedFor(urlEqualTo("/test"))
+ .withRequestBodyPart(
+ aMultipart("param2").withBody(equalTo("value2")).build()
+ )
+ .withRequestBodyPart(
+ aMultipart("param4").withBody(equalTo("value4")).build()
+ )
+ .withRequestBody(
+ httpImplementation,
+ """
+ -----------------------------7d159c1302d0y0
+ Content-Disposition: form-data; name="param2"
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
+
+ value2
+ -----------------------------7d159c1302d0y0
+ Content-Disposition: form-data; name="param4"
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
+
+ value4
+ -----------------------------7d159c1302d0y0--
+
+ """.trimIndent()
+ )
+ )
+ }
+}
diff --git
a/src/protocol/http/src/test/kotlin/org/apache/jmeter/protocol/http/sampler/HttpSamplerTest.kt
b/src/protocol/http/src/test/kotlin/org/apache/jmeter/protocol/http/sampler/HttpSamplerTest.kt
index fb82fe4adf..180bbb42b6 100644
---
a/src/protocol/http/src/test/kotlin/org/apache/jmeter/protocol/http/sampler/HttpSamplerTest.kt
+++
b/src/protocol/http/src/test/kotlin/org/apache/jmeter/protocol/http/sampler/HttpSamplerTest.kt
@@ -21,20 +21,17 @@ import
com.github.tomakehurst.wiremock.client.WireMock.aMultipart
import com.github.tomakehurst.wiremock.client.WireMock.aResponse
import com.github.tomakehurst.wiremock.client.WireMock.containing
import com.github.tomakehurst.wiremock.client.WireMock.equalTo
-import com.github.tomakehurst.wiremock.client.WireMock.matching
import com.github.tomakehurst.wiremock.client.WireMock.post
import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor
import com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo
import com.github.tomakehurst.wiremock.junit5.WireMockTest
-import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder
-import org.apache.jmeter.control.LoopController
import org.apache.jmeter.junit.JMeterTestCase
import org.apache.jmeter.protocol.http.control.Header
import org.apache.jmeter.protocol.http.util.HTTPFileArg
import org.apache.jmeter.test.assertions.executePlanAndCollectEvents
-import org.apache.jmeter.threads.ThreadGroup
import org.apache.jmeter.treebuilder.TreeBuilder
+import org.apache.jmeter.treebuilder.oneRequest
import org.junit.jupiter.api.Assumptions.assumeTrue
import org.junit.jupiter.api.io.TempDir
import org.junit.jupiter.params.ParameterizedTest
@@ -51,21 +48,8 @@ class HttpSamplerTest : JMeterTestCase() {
@TempDir
lateinit var dir: Path
- fun TreeBuilder.oneRequest(body: ThreadGroup.() -> Unit) {
- ThreadGroup::class {
- numThreads = 1
- rampUp = 0
- setSamplerController(
- LoopController().apply {
- loops = 1
- }
- )
- body()
- }
- }
-
fun TreeBuilder.httpPost(body: HTTPSamplerProxy.() -> Unit) {
- org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy::class {
+ HTTPSamplerProxy::class {
name = "Upload file"
method = "POST"
domain = "localhost"
@@ -137,24 +121,6 @@ class HttpSamplerTest : JMeterTestCase() {
)
}
- fun RequestPatternBuilder.withRequestBody(
- httpImplementation: String,
- body: String
- ) = apply {
- // normalize line endings to CRLF
- val normalizedBody = body.replace("\r\n", "\n").replace("\n", "\r\n")
- withRequestBody(
- if (httpImplementation == "Java") {
- equalTo(normalizedBody)
- } else {
- matching(
- normalizedBody
- .replace(PostWriter.BOUNDARY, "[^ \\n\\r]{1,69}?")
- )
- }
- )
- }
-
@ParameterizedTest
@ValueSource(strings = ["Java", "HttpClient4"])
fun `one parameter`(httpImplementation: String, server:
WireMockRuntimeInfo) {
diff --git
a/src/protocol/http/src/test/kotlin/org/apache/jmeter/protocol/http/sampler/HttpSamplerTestingUtils.kt
b/src/protocol/http/src/test/kotlin/org/apache/jmeter/protocol/http/sampler/HttpSamplerTestingUtils.kt
new file mode 100644
index 0000000000..bc9c8500d8
--- /dev/null
+++
b/src/protocol/http/src/test/kotlin/org/apache/jmeter/protocol/http/sampler/HttpSamplerTestingUtils.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.protocol.http.sampler
+
+import com.github.tomakehurst.wiremock.client.WireMock.equalTo
+import com.github.tomakehurst.wiremock.client.WireMock.matching
+import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder
+
+fun RequestPatternBuilder.withRequestBody(
+ httpImplementation: String,
+ body: String
+) = apply {
+ // normalize line endings to CRLF
+ val normalizedBody = body.replace("\r\n", "\n").replace("\n", "\r\n")
+ withRequestBody(
+ if (httpImplementation == "Java") {
+ equalTo(normalizedBody)
+ } else {
+ matching(
+ normalizedBody
+ .replace(PostWriter.BOUNDARY, "[^ \\n\\r]{1,69}?")
+ )
+ }
+ )
+}
diff --git
a/src/protocol/http/src/testFixtures/kotlin/org/apache/jmeter/protocol/http/control/HttpRequestDefaultsExtensions.kt
b/src/protocol/http/src/testFixtures/kotlin/org/apache/jmeter/protocol/http/control/HttpRequestDefaultsExtensions.kt
new file mode 100644
index 0000000000..b64fa9563e
--- /dev/null
+++
b/src/protocol/http/src/testFixtures/kotlin/org/apache/jmeter/protocol/http/control/HttpRequestDefaultsExtensions.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.protocol.http.control
+
+import org.apache.jmeter.config.Arguments
+import org.apache.jmeter.config.ConfigTestElement
+import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBaseSchema
+import org.apache.jmeter.testelement.property.TestElementProperty
+import org.apache.jmeter.treebuilder.Action
+import org.apache.jmeter.treebuilder.TreeBuilder
+
+fun TreeBuilder.httpRequestDefaults(configure: Action<ConfigTestElement> =
Action {}) {
+ ConfigTestElement::class {
+ props {
+ it[name] = "HTTP Request Defaults"
+ it[guiClass] =
"org.apache.jmeter.protocol.http.config.gui.HttpDefaultsGui"
+ }
+ setProperty(
+ TestElementProperty(
+ HTTPSamplerBaseSchema.arguments.name,
+ Arguments().apply {
+ props {
+ it[guiClass] =
"org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel"
+ it[testClass] = "org.apache.jmeter.config.Arguments"
+ }
+ }
+ )
+ )
+ configure(this)
+ }
+}
+
+val ConfigTestElement.arguments: Arguments
+ get() = getProperty(HTTPSamplerBaseSchema.arguments.name) as Arguments
+
+fun ConfigTestElement.arguments(configure: Action<Arguments> = Action {}) {
+ configure((getProperty(HTTPSamplerBaseSchema.arguments.name) as
TestElementProperty).element as Arguments)
+}