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 e6a060dd7fb..7f2127c48e1 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.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 Map getArgumentsAsMap() { // 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 PropertyIterator iterator() { 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 getEnabledArguments() { + return () -> new FilterIterator<>(iterator(), property -> { + Object value = property.getObjectValue(); + return value instanceof Argument && ((Argument) value).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 00000000000..650456f4f1b --- /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 1a1dc805aeb..bcbc6cf0458 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 bb0ce92879e..ece7f2168cc 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 @@ private static String computePostBody(Arguments arguments) { */ 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 1f4af2befa2..02c68ee973f 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 @@ /** * 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 static boolean testFunctors(){ @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 d705ae726cb..2a5fe624bc7 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 @@ private String setConnectionHeaders(URL url, String host, String method) 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 bc4478eecb3..e12800b8abe 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 @@ -159,7 +159,6 @@ 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; @@ -1571,7 +1570,7 @@ protected String setupHttpEntityEnclosingRequestData(HttpEntityEnclosingRequestB } // 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)) { @@ -1653,7 +1652,7 @@ else if(ADD_CONTENT_TYPE_TO_POST_IF_MISSING) { // 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)); } @@ -1796,10 +1795,9 @@ else if(getSendParameterValuesAsPostBody()) { 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 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 3b3b37d0141..7f45aedeedb 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 @@ -81,7 +81,6 @@ 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; @@ -409,7 +408,7 @@ public boolean getSendParameterValuesAsPostBody() { 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()) { @@ -1155,9 +1154,10 @@ public String getQueryString() { */ public String getQueryString(final String contentEncoding) { - CollectionProperty arguments = getArguments().getArguments(); + Arguments args = getArguments(); + Iterator iter = args.getEnabledArguments().iterator(); // Optimisation : avoid building useless objects if empty arguments - if(arguments.isEmpty()) { + if (!iter.hasNext()) { return ""; } String lContentEncoding = contentEncoding; @@ -1167,8 +1167,7 @@ public String getQueryString(final String contentEncoding) { 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 60d01217525..447a65f1073 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 @@ -190,7 +190,7 @@ public void setHeaders(URLConnection connection, HTTPSamplerBase sampler) throws 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)) { @@ -299,7 +299,7 @@ public void setHeaders(URLConnection connection, HTTPSamplerBase sampler) throws // 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 d6f5c87cd59..66a79b6b4e7 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 @@ -84,7 +84,7 @@ else if(sampler.getSendParameterValuesAsPostBody()) { // 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 00000000000..80c54d0f2ae --- /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 fb82fe4adf6..180bbb42b6a 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 00000000000..bc9c8500d80 --- /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 00000000000..b64fa9563ec --- /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 = 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 = Action {}) { + configure((getProperty(HTTPSamplerBaseSchema.arguments.name) as TestElementProperty).element as Arguments) +}