You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by vl...@apache.org on 2019/09/27 07:55:52 UTC
[jmeter] branch master updated: Refactor HttpMetricsSenderTest to
WireMock
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 b6fc9b4 Refactor HttpMetricsSenderTest to WireMock
b6fc9b4 is described below
commit b6fc9b4724a7c63d499c87ac0c4f4e17893fcbbf
Author: Vladimir Sitnikov <si...@gmail.com>
AuthorDate: Fri Sep 27 10:55:27 2019 +0300
Refactor HttpMetricsSenderTest to WireMock
This improves error reporting and allows to start the server just once per test.
---
settings.gradle.kts | 1 +
src/build.gradle.kts | 3 +-
src/components/build.gradle.kts | 1 +
.../jmeter/extractor/TestXPathExtractor.java | 12 +-
.../backend/influxdb/HttpMetricsSenderTest.java | 136 ++++++++-------------
.../org/apache/jorphan/exec/TestKeyToolUtils.java | 41 +++----
src/protocol/build.gradle.kts | 1 +
src/testkit-wiremock/build.gradle.kts | 29 +++++
.../apache/jmeter/wiremock/RequestCountDown.java | 39 ++++++
.../apache/jmeter/wiremock/WireMockExtension.java | 12 +-
10 files changed, 157 insertions(+), 118 deletions(-)
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 764a9c7..b04ae53 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -46,6 +46,7 @@ include(
"src:protocol:tcp",
"src:release",
"src:testkit",
+ "src:testkit-wiremock",
"src:dist",
"src:dist-check")
diff --git a/src/build.gradle.kts b/src/build.gradle.kts
index 3cbb3ae..549b737 100644
--- a/src/build.gradle.kts
+++ b/src/build.gradle.kts
@@ -25,7 +25,8 @@ val skipMavenPublication = setOf(
":src:licenses",
":src:protocol",
":src:release",
- ":src:testkit"
+ ":src:testkit",
+ ":src:testkit-wiremock"
)
subprojects {
diff --git a/src/components/build.gradle.kts b/src/components/build.gradle.kts
index eebc4ed..ec467a8 100644
--- a/src/components/build.gradle.kts
+++ b/src/components/build.gradle.kts
@@ -71,6 +71,7 @@ dependencies {
testRuntimeOnly("org.bouncycastle:bcpkix-jdk15on")
testRuntimeOnly("org.bouncycastle:bcprov-jdk15on")
testImplementation("nl.jqno.equalsverifier:equalsverifier")
+ testImplementation(testFixtures(project(":src:testkit-wiremock")))
}
fun String?.toBool(nullAs: Boolean, blankAs: Boolean, default: Boolean) =
diff --git a/src/components/src/test/java/org/apache/jmeter/extractor/TestXPathExtractor.java b/src/components/src/test/java/org/apache/jmeter/extractor/TestXPathExtractor.java
index a7968d2..614cf37 100644
--- a/src/components/src/test/java/org/apache/jmeter/extractor/TestXPathExtractor.java
+++ b/src/components/src/test/java/org/apache/jmeter/extractor/TestXPathExtractor.java
@@ -19,6 +19,8 @@
package org.apache.jmeter.extractor;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@@ -26,11 +28,11 @@ import java.io.UnsupportedEncodingException;
import java.util.Locale;
import org.apache.commons.lang3.StringUtils;
+import org.apache.jmeter.assertions.AssertionResult;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.threads.JMeterContext;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.JMeterVariables;
-import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -281,9 +283,9 @@ public class TestXPathExtractor {
extractor.setXPathQuery("<");
extractor.process();
assertEquals(1, result.getAssertionResults().length);
- assertEquals(extractor.getName(), result.getAssertionResults()[0].getName());
- Assert.assertTrue(result.getAssertionResults()[0].
- getFailureMessage().contains("A location path was expected, but the following token was encountered"));
+ AssertionResult firstResult = result.getAssertionResults()[0];
+ assertEquals(extractor.getName(), firstResult.getName());
+ assertThat(firstResult.getFailureMessage(), containsString("A location path was expected, but the following token was encountered"));
assertEquals("Default", vars.get(VAL_NAME));
assertEquals("0", vars.get(VAL_NAME_NR));
} finally {
@@ -312,7 +314,7 @@ public class TestXPathExtractor {
assertEquals(1, result.getAssertionResults().length);
assertEquals(extractor.getName(), result.getAssertionResults()[0].getName());
org.junit.Assert.assertThat(result.getAssertionResults()[0].
- getFailureMessage(), CoreMatchers.containsString("XML document structures must start and end within the same entity"));
+ getFailureMessage(), containsString("XML document structures must start and end within the same entity"));
assertEquals("Default", vars.get(VAL_NAME));
assertEquals("0", vars.get(VAL_NAME_NR));
diff --git a/src/components/src/test/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSenderTest.java b/src/components/src/test/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSenderTest.java
index 9737df0..26e4d37 100644
--- a/src/components/src/test/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSenderTest.java
+++ b/src/components/src/test/java/org/apache/jmeter/visualizers/backend/influxdb/HttpMetricsSenderTest.java
@@ -18,98 +18,66 @@
package org.apache.jmeter.visualizers.backend.influxdb;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
-import java.io.IOException;
-import java.util.Objects;
-import java.util.concurrent.BlockingDeque;
-import java.util.concurrent.LinkedBlockingDeque;
+import java.net.HttpURLConnection;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import java.util.stream.IntStream;
-
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpStatus;
-import org.apache.http.impl.bootstrap.HttpServer;
-import org.apache.http.impl.bootstrap.ServerBootstrap;
-import org.apache.http.protocol.HttpRequestHandler;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
+import org.apache.jmeter.wiremock.WireMockExtension;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.MappingBuilder;
+import com.github.tomakehurst.wiremock.client.WireMock;
+import com.github.tomakehurst.wiremock.extension.Parameters;
+import com.github.tomakehurst.wiremock.http.RequestMethod;
+import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder;
+import com.github.tomakehurst.wiremock.matching.StringValuePattern;
+
+@ExtendWith(WireMockExtension.class)
public class HttpMetricsSenderTest {
-
- private HttpServer server;
- private BlockingDeque<HttpRequest> resultQueue = new LinkedBlockingDeque<>();
-
- @Before
- public void startServer() {
-
- HttpRequestHandler requestHandler = (request, response, context) -> {
- HttpMetricsSenderTest.this.resultQueue.add(request);
- response.setStatusCode(HttpStatus.SC_NO_CONTENT);
- };
-
- // Start HttpServer on free port
- server = IntStream
- .range(8183, 8283)
- .mapToObj(port -> {
- HttpServer httpServer = ServerBootstrap.bootstrap()
- .setListenerPort(port)
- .registerHandler("*", requestHandler)
- .create();
- try {
- httpServer.start();
- return httpServer;
- } catch (IOException e) {
- return null;
- }
- })
- .filter(Objects::nonNull)
- .findFirst()
- .orElseThrow(() -> new AssertionError("Cannot start HttpServer"));
- }
-
- @After
- public void stopServer() {
- server.shutdown(1, TimeUnit.SECONDS);
+ private static final String API_URL = "/api/v2/write";
+
+ private MappingBuilder influxRequest(CountDownLatch latch) {
+ return WireMock.post(API_URL)
+ .willReturn(
+ WireMock.aResponse().withStatus(HttpURLConnection.HTTP_NO_CONTENT)
+ )
+ .withPostServeAction("countdown", Parameters.one("latch", latch));
}
- @Test
- public void checkTokenDoesNotPresentInHeader() throws Exception {
- String influxdbUrl = getInfluxDbUrl();
- setupSenderAndSendMetric(influxdbUrl, null);
-
- assertNoAuthHeader(resultQueue.take());
+ static Collection<Arguments> emptyTokens() {
+ return Arrays.asList(arguments((String) null), arguments(""), arguments(" "));
}
+ @ParameterizedTest(name = "[{index}] token=\"{0}\"")
+ @MethodSource("emptyTokens")
+ public void emptyTokenIsNotSentAsAuthorizedHeader(String token, WireMockServer server) throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ server.stubFor(influxRequest(latch));
- @Test
- public void checkEmptyTokenDoesNotPresentInHeader() throws Exception {
- String influxdbUrl = getInfluxDbUrl();
- setupSenderAndSendMetric(influxdbUrl, "");
+ setupSenderAndSendMetric(server.url(API_URL), token);
- assertNoAuthHeader(resultQueue.take());
+ latch.await(2, TimeUnit.SECONDS);
+ assertAuthHeader(server, WireMock.absent());
}
@Test
- public void checkEmptyOnlyWhitespaceTokenDoesNotPresentInHeader() throws Exception {
- String influxdbUrl = getInfluxDbUrl();
- setupSenderAndSendMetric(influxdbUrl, " ");
+ public void checkTokenPresentInHeader(WireMockServer server) throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ server.stubFor(influxRequest(latch));
- assertNoAuthHeader(resultQueue.take());
- }
+ setupSenderAndSendMetric(server.url(API_URL), "my-token");
- @Test
- public void checkTokenPresentInHeader() throws Exception {
- String influxdbUrl = getInfluxDbUrl();
- setupSenderAndSendMetric(influxdbUrl, "my-token");
-
- HttpRequest request = resultQueue.take();
- assertEquals(
- "The authorization header should be: 'Token my-token'",
- "Token my-token",
- request.getFirstHeader("Authorization").getValue());
+ latch.await(2, TimeUnit.SECONDS);
+ assertAuthHeader(server, WireMock.equalTo("Token my-token"));
}
private void setupSenderAndSendMetric(String influxdbUrl, String influxDBToken) throws Exception {
@@ -119,14 +87,10 @@ public class HttpMetricsSenderTest {
metricsSender.writeAndSendMetrics();
}
- private void assertNoAuthHeader(HttpRequest request) {
- assertNull(
- "The authorization header shouldn't be defined.",
- request.getFirstHeader("Authorization"));
+ private void assertAuthHeader(WireMockServer server, StringValuePattern authHeader) {
+ server.verify(1, RequestPatternBuilder
+ .newRequestPattern(RequestMethod.POST, WireMock.urlEqualTo(API_URL))
+ .withRequestBody(WireMock.matching("measurementlocation=west size=10 \\d{19}\\s*"))
+ .withHeader("Authorization", authHeader));
}
-
- private String getInfluxDbUrl() {
- return String.format("http://localhost:%s/api/v2/write", Integer.valueOf(server.getLocalPort()));
- }
-
}
diff --git a/src/jorphan/src/test/java/org/apache/jorphan/exec/TestKeyToolUtils.java b/src/jorphan/src/test/java/org/apache/jorphan/exec/TestKeyToolUtils.java
index c2f4140..9c111d6 100644
--- a/src/jorphan/src/test/java/org/apache/jorphan/exec/TestKeyToolUtils.java
+++ b/src/jorphan/src/test/java/org/apache/jorphan/exec/TestKeyToolUtils.java
@@ -22,34 +22,32 @@ import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import org.apache.jorphan.util.JOrphanUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.api.parallel.Execution;
+import org.junit.jupiter.api.parallel.ExecutionMode;
+@Execution(ExecutionMode.CONCURRENT)
public class TestKeyToolUtils {
- private File keystore;
- private String password = JOrphanUtils.generateRandomAlphanumericPassword(32);
- private int validity = 1;
+ private static File keystore;
+ private static String password;
+ private static final int validity = 1;
- @Before
- public void setup() throws IOException {
- keystore = File.createTempFile("dummy-keystore", "jks");
- keystore.deleteOnExit();
+ @BeforeAll
+ public static void setup(@TempDir Path keystoreDir) throws IOException {
+ keystore = keystoreDir.resolve("dummy-keystore.jks").toFile();
+ password = JOrphanUtils.generateRandomAlphanumericPassword(32);
KeyToolUtils.generateProxyCA(keystore, password, validity );
}
- @After
- public void cleanup() {
- if (keystore.exists()) {
- keystore.delete();
- }
- }
-
/*
* Check the assumption that a missing executable will generate
* either an IOException or status which is neither 0 nor 1
@@ -60,13 +58,12 @@ public class TestKeyToolUtils {
SystemCommand sc = new SystemCommand(null, null);
List<String> arguments = new ArrayList<>();
arguments.add("xyzqwas"); // should not exist
- try {
+ Assertions.assertThrows(IOException.class, () -> {
int status = sc.run(arguments);
- if (status == 0 || status ==1) {
- fail("Unexpected status " + status);
+ if (status == 0 || status == 1) {
+ fail("Missing executable should produce exit code of 0 or 1. Actual code is " + status);
}
- } catch (IOException expected) {
- }
+ });
}
@Test
diff --git a/src/protocol/build.gradle.kts b/src/protocol/build.gradle.kts
index 860b732..b589b3d 100644
--- a/src/protocol/build.gradle.kts
+++ b/src/protocol/build.gradle.kts
@@ -75,6 +75,7 @@ project("http") {
implementation("dnsjava:dnsjava:2.1.8")
implementation("org.apache.httpcomponents:httpmime:4.5.8")
implementation("org.brotli:dec:0.1.2")
+ testImplementation(testFixtures(project(":src:testkit-wiremock")))
testImplementation("com.github.tomakehurst:wiremock-jre8")
}
diff --git a/src/testkit-wiremock/build.gradle.kts b/src/testkit-wiremock/build.gradle.kts
new file mode 100644
index 0000000..b6b79ef
--- /dev/null
+++ b/src/testkit-wiremock/build.gradle.kts
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ *
+ */
+
+plugins {
+ `java-test-fixtures`
+}
+
+dependencies {
+ api("com.github.tomakehurst:wiremock-jre8")
+ api("org.junit.jupiter:junit-jupiter-api")
+}
+
+// test-fixtures enable to share code across test modules
+// See https://docs.gradle.org/5.6/userguide/java_testing.html#sec:java_test_fixtures
diff --git a/src/testkit-wiremock/src/main/java/org/apache/jmeter/wiremock/RequestCountDown.java b/src/testkit-wiremock/src/main/java/org/apache/jmeter/wiremock/RequestCountDown.java
new file mode 100644
index 0000000..e272093
--- /dev/null
+++ b/src/testkit-wiremock/src/main/java/org/apache/jmeter/wiremock/RequestCountDown.java
@@ -0,0 +1,39 @@
+/*
+ * 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.wiremock;
+
+import java.util.concurrent.CountDownLatch;
+
+import com.github.tomakehurst.wiremock.core.Admin;
+import com.github.tomakehurst.wiremock.extension.Parameters;
+import com.github.tomakehurst.wiremock.extension.PostServeAction;
+import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
+
+public class RequestCountDown extends PostServeAction {
+ @Override
+ public String getName() {
+ return "countdown";
+ }
+
+ @Override
+ public void doAction(ServeEvent serveEvent, Admin admin, Parameters parameters) {
+ CountDownLatch latch = (CountDownLatch) parameters.get("latch");
+ latch.countDown();
+ }
+}
diff --git a/src/protocol/http/src/test/java/org/apache/jmeter/wiremock/WireMockExtension.java b/src/testkit-wiremock/src/main/java/org/apache/jmeter/wiremock/WireMockExtension.java
similarity index 88%
rename from src/protocol/http/src/test/java/org/apache/jmeter/wiremock/WireMockExtension.java
rename to src/testkit-wiremock/src/main/java/org/apache/jmeter/wiremock/WireMockExtension.java
index 4c106c7..bc48ff2 100644
--- a/src/protocol/http/src/test/java/org/apache/jmeter/wiremock/WireMockExtension.java
+++ b/src/testkit-wiremock/src/main/java/org/apache/jmeter/wiremock/WireMockExtension.java
@@ -34,10 +34,10 @@ public class WireMockExtension implements BeforeEachCallback, BeforeAllCallback,
ExtensionContext.Namespace.create(WireMockExtension.class);
@Override
- public void beforeEach(ExtensionContext context) throws Exception {
+ public void beforeEach(ExtensionContext context) {
WireMockServer server = getServer(context);
if (server != null) {
- server.resetScenarios();
+ server.resetAll();
}
}
@@ -60,8 +60,12 @@ public class WireMockExtension implements BeforeEachCallback, BeforeAllCallback,
}
@Override
- public void beforeAll(ExtensionContext context) throws Exception {
- WireMockServer server = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort());
+ public void beforeAll(ExtensionContext context) {
+ WireMockServer server = new WireMockServer(
+ WireMockConfiguration.wireMockConfig()
+ .dynamicPort()
+ .extensions(new RequestCountDown())
+ );
server.start();
getStore(context).put("server", server);
}