From af978bc81119e5f537d424f12b46f709719265ae Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Thu, 4 Nov 2021 10:12:53 +0200 Subject: [PATCH] Introduce the ability to run @QuarkusIntegrationTests against remote apps --- .../asciidoc/getting-started-testing.adoc | 18 +++++++ .../quarkus/test/common/TestHostLauncher.java | 51 +++++++++++++++++++ .../QuarkusIntegrationTestExtension.java | 20 +++++--- 3 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 test-framework/common/src/main/java/io/quarkus/test/common/TestHostLauncher.java diff --git a/docs/src/main/asciidoc/getting-started-testing.adoc b/docs/src/main/asciidoc/getting-started-testing.adoc index d1711a546a08a..8361c42c04cd8 100644 --- a/docs/src/main/asciidoc/getting-started-testing.adoc +++ b/docs/src/main/asciidoc/getting-started-testing.adoc @@ -1215,6 +1215,24 @@ As a test annotated with `@QuarkusIntegrationTest` tests the result of the build These tests will **not** work if run in the same phase as `@QuarkusTest` as Quarkus has not yet created the final artifact. ==== +=== Executing against a running application + +[WARNING] +==== +This feature is considered experimental and is likely to change in future versions of Quarkus. +==== + +`@QuarkusIntegrationTest` supports executing tests against an already running instance of the application. This can be achieved by setting the +`quarkus.http.test-host` system property when running the tests. + +An example use of this could be the following Maven command, that forces `@QuarkusIntegrationTest` to execute against that is accessible at `http://1.2.3.4:4321`: + +[source,bash] +---- +./mvnw verify -Dquarkus.http.test-host=1.2.3.4 -Dquarkus.http.test-port=4321 +---- + + == Mixing `@QuarkusTest` with other type of tests Mixing tests annotated with `@QuarkusTest` with tests annotated with either `@QuarkusDevModeTest`, `@QuarkusProdModeTest` or `@QuarkusUnitTest` diff --git a/test-framework/common/src/main/java/io/quarkus/test/common/TestHostLauncher.java b/test-framework/common/src/main/java/io/quarkus/test/common/TestHostLauncher.java new file mode 100644 index 0000000000000..ee9f1d2224802 --- /dev/null +++ b/test-framework/common/src/main/java/io/quarkus/test/common/TestHostLauncher.java @@ -0,0 +1,51 @@ +package io.quarkus.test.common; + +import java.io.IOException; +import java.util.Map; + +/** + * A launcher that simply sets the {@code quarkus.http.host} property based on the value {@code quarkus.http.test-host} + * in order to support the case of running integration tests against an already running application + * using RestAssured without any chances. + * + * This is highly experimental, so changes are to be expected. + */ +@SuppressWarnings("rawtypes") +public class TestHostLauncher implements ArtifactLauncher { + + private String previousHost; + + @Override + public void start() throws IOException { + // set 'quarkus.http.host' to ensure that RestAssured targets the proper host + previousHost = System.setProperty("quarkus.http.host", System.getProperty("quarkus.http.test-host")); + } + + @Override + public void close() throws IOException { + if (previousHost != null) { + System.setProperty("quarkus.http.host", previousHost); + } + } + + @Override + public boolean listensOnSsl() { + return false; + } + + @Override + public void includeAsSysProps(Map systemProps) { + + } + + @Override + public void init(InitContext initContext) { + throw new IllegalStateException("Should not be called"); + } + + @Override + public LaunchResult runToCompletion(String[] args) { + throw new IllegalStateException("Should not be called"); + } + +} diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusIntegrationTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusIntegrationTestExtension.java index 34d6213522ce3..fc4eb27084082 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusIntegrationTestExtension.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusIntegrationTestExtension.java @@ -33,6 +33,7 @@ import io.quarkus.test.common.ArtifactLauncher; import io.quarkus.test.common.DevServicesContext; import io.quarkus.test.common.RestAssuredURLManager; +import io.quarkus.test.common.TestHostLauncher; import io.quarkus.test.common.TestResourceManager; import io.quarkus.test.common.TestScopeManager; import io.quarkus.test.junit.launcher.ArtifactLauncherProvider; @@ -171,13 +172,18 @@ public void close() throws Throwable { additionalProperties.putAll(resourceManagerProps); ArtifactLauncher launcher = null; - ServiceLoader loader = ServiceLoader.load(ArtifactLauncherProvider.class); - for (ArtifactLauncherProvider launcherProvider : loader) { - if (launcherProvider.supportsArtifactType(artifactType)) { - launcher = launcherProvider.create( - new DefaultArtifactLauncherCreateContext(quarkusArtifactProperties, context, requiredTestClass, - devServicesLaunchResult)); - break; + String testHost = System.getProperty("quarkus.http.test-host"); + if ((testHost != null) && !testHost.isEmpty()) { + launcher = new TestHostLauncher(); + } else { + ServiceLoader loader = ServiceLoader.load(ArtifactLauncherProvider.class); + for (ArtifactLauncherProvider launcherProvider : loader) { + if (launcherProvider.supportsArtifactType(artifactType)) { + launcher = launcherProvider.create( + new DefaultArtifactLauncherCreateContext(quarkusArtifactProperties, context, requiredTestClass, + devServicesLaunchResult)); + break; + } } } if (launcher == null) {