diff --git a/docs/src/main/asciidoc/getting-started-testing.adoc b/docs/src/main/asciidoc/getting-started-testing.adoc index 8361c42c04cd8..9c9ba7b36afa3 100644 --- a/docs/src/main/asciidoc/getting-started-testing.adoc +++ b/docs/src/main/asciidoc/getting-started-testing.adoc @@ -1336,3 +1336,10 @@ a utility class. `QuarkusTestResourceLifecycleManager` implementations can also implement `ContextAware` to get access to these properties, which allows you to setup the resource before Quarkus starts (e.g. configure a KeyCloak instance, add data to a database etc). + +[NOTE] +==== +For `@QuarkusIntegrationTest` tests that result in launcher the application as a container, `io.quarkus.test.common.DevServicesContext` also provides access to the id of the container network on which the application container was launched (via the `containerNetworkId` method). +This can be used by `QuarkusTestResourceLifecycleManager` that need to launch additional containers that the application will communicate with. +==== + diff --git a/integration-tests/container-image/maven-invoker-way/src/it/container-build-jib-with-mongo/src/test/java/org/acme/DummyResource.java b/integration-tests/container-image/maven-invoker-way/src/it/container-build-jib-with-mongo/src/test/java/org/acme/DummyResource.java new file mode 100644 index 0000000000000..a42f77ee106a5 --- /dev/null +++ b/integration-tests/container-image/maven-invoker-way/src/it/container-build-jib-with-mongo/src/test/java/org/acme/DummyResource.java @@ -0,0 +1,30 @@ +package org.acme; + +import io.quarkus.test.common.DevServicesContext; +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; + +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; + +public class DummyResource implements QuarkusTestResourceLifecycleManager, DevServicesContext.ContextAware { + + public static final AtomicReference> CONTAINER_NETWORK_ID = new AtomicReference<>(null); + + @Override + public Map start() { + return Collections.emptyMap(); + } + + @Override + public void stop() { + + } + + + @Override + public void setIntegrationTestContext(DevServicesContext context) { + CONTAINER_NETWORK_ID.set(context.containerNetworkId()); + } +} diff --git a/integration-tests/container-image/maven-invoker-way/src/it/container-build-jib-with-mongo/src/test/java/org/acme/FruitsEndpointIT.java b/integration-tests/container-image/maven-invoker-way/src/it/container-build-jib-with-mongo/src/test/java/org/acme/FruitsEndpointIT.java index 7a216d072c664..8caacd967910b 100644 --- a/integration-tests/container-image/maven-invoker-way/src/it/container-build-jib-with-mongo/src/test/java/org/acme/FruitsEndpointIT.java +++ b/integration-tests/container-image/maven-invoker-way/src/it/container-build-jib-with-mongo/src/test/java/org/acme/FruitsEndpointIT.java @@ -1,9 +1,22 @@ package org.acme; +import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.junit.jupiter.api.Test; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; @QuarkusIntegrationTest +@QuarkusTestResource(DummyResource.class) public class FruitsEndpointIT extends FruitsEndpointTest { - + @Test + public void containerNetworkIdSet() { + Optional optional = DummyResource.CONTAINER_NETWORK_ID.get(); + assertNotNull(optional); + assertTrue(optional.isPresent()); + } } diff --git a/test-framework/common/src/main/java/io/quarkus/test/common/DevServicesContext.java b/test-framework/common/src/main/java/io/quarkus/test/common/DevServicesContext.java index d975ef80e38b8..503b79876fdad 100644 --- a/test-framework/common/src/main/java/io/quarkus/test/common/DevServicesContext.java +++ b/test-framework/common/src/main/java/io/quarkus/test/common/DevServicesContext.java @@ -1,6 +1,7 @@ package io.quarkus.test.common; import java.util.Map; +import java.util.Optional; /** * Interface that can be used to get properties from DevServices for {@link QuarkusTest} and {@link QuarkusIntegrationTest} @@ -18,6 +19,12 @@ public interface DevServicesContext { */ Map devServicesProperties(); + /** + * If the application is going to be launched in a container, this method returns the id of container network + * it will be launched on. + */ + Optional containerNetworkId(); + /** * Interface that can be implemented to allow automatic injection of the context. * diff --git a/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java b/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java index 745c7ca11ead2..ed4767a4f575d 100644 --- a/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java +++ b/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.ServiceLoader; import java.util.Set; import java.util.concurrent.CancellationException; @@ -47,11 +48,13 @@ public TestResourceManager(Class testClass) { public TestResourceManager(Class testClass, Class profileClass, List additionalTestResources, boolean disableGlobalTestResources) { - this(testClass, profileClass, additionalTestResources, disableGlobalTestResources, Collections.emptyMap()); + this(testClass, profileClass, additionalTestResources, disableGlobalTestResources, Collections.emptyMap(), + Optional.empty()); } public TestResourceManager(Class testClass, Class profileClass, List additionalTestResources, - boolean disableGlobalTestResources, Map devServicesProperties) { + boolean disableGlobalTestResources, Map devServicesProperties, + Optional containerNetworkId) { this.parallelTestResourceEntries = new ArrayList<>(); this.sequentialTestResourceEntries = new ArrayList<>(); @@ -73,6 +76,11 @@ public TestResourceManager(Class testClass, Class profileClass, List devServicesProperties() { return devServicesProperties; } + + @Override + public Optional containerNetworkId() { + return containerNetworkId; + } }; for (var i : allTestResourceEntries) { if (i.getTestResource() instanceof DevServicesContext.ContextAware) { 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 fc4eb27084082..b39eeb19cc18b 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 @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Properties; import java.util.ServiceLoader; import java.util.function.Function; @@ -53,6 +54,7 @@ public class QuarkusIntegrationTestExtension private static boolean hasPerTestResources; private static Map devServicesProps; + private static String containerNetworkId; @Override public void afterEach(ExtensionContext context) throws Exception { @@ -124,7 +126,8 @@ private IntegrationTestExtensionState doProcessStart(Properties quarkusArtifactP ArtifactLauncher.InitContext.DevServicesLaunchResult devServicesLaunchResult = handleDevServices(context, isDockerLaunch); - QuarkusIntegrationTestExtension.devServicesProps = devServicesLaunchResult.properties(); + devServicesProps = devServicesLaunchResult.properties(); + containerNetworkId = devServicesLaunchResult.networkId(); quarkusTestProfile = profile; currentJUnitTestClass = context.getRequiredTestClass(); TestResourceManager testResourceManager = null; @@ -139,7 +142,7 @@ private IntegrationTestExtensionState doProcessStart(Properties quarkusArtifactP context.getRequiredTestClass().getClassLoader()), testProfileAndProperties.testProfile != null && testProfileAndProperties.testProfile.disableGlobalTestResources(), - devServicesProps); + devServicesProps, containerNetworkId == null ? Optional.empty() : Optional.of(containerNetworkId)); testResourceManager.init(); hasPerTestResources = testResourceManager.hasPerTestResources(); @@ -251,7 +254,8 @@ private void injectTestContext(Object testInstance) { private DevServicesContext createTestContext() { Map devServicesPropsCopy = devServicesProps.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(devServicesProps); - return new DefaultQuarkusIntegrationTestContext(devServicesPropsCopy); + return new DefaultQuarkusIntegrationTestContext(devServicesPropsCopy, + containerNetworkId == null ? Optional.empty() : Optional.of(containerNetworkId)); } private void throwBootFailureException() { @@ -301,15 +305,23 @@ public ArtifactLauncher.InitContext.DevServicesLaunchResult devServicesLaunchRes private static class DefaultQuarkusIntegrationTestContext implements DevServicesContext { - private final Map map; + private final Map devServicesProperties; + private final Optional containerNetworkId; - private DefaultQuarkusIntegrationTestContext(Map map) { - this.map = map; + private DefaultQuarkusIntegrationTestContext(Map devServicesProperties, + Optional containerNetworkId) { + this.devServicesProperties = devServicesProperties; + this.containerNetworkId = containerNetworkId; } @Override public Map devServicesProperties() { - return map; + return devServicesProperties; + } + + @Override + public Optional containerNetworkId() { + return containerNetworkId; } } } diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusMainTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusMainTestExtension.java index ea6c67cf5fddf..d7609c833f1b0 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusMainTestExtension.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusMainTestExtension.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.LinkedBlockingDeque; import org.junit.jupiter.api.Assertions; @@ -142,12 +143,12 @@ private int doJavaStart(ExtensionContext context, Class properties = (Map) testResourceManager.getClass().getMethod("start") .invoke(testResourceManager); diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java index 7cfe2b3b3e8a7..71144ae873dce 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java @@ -221,12 +221,12 @@ public Thread newThread(Runnable r) { //must be done after the TCCL has been set testResourceManager = (Closeable) startupAction.getClassLoader().loadClass(TestResourceManager.class.getName()) - .getConstructor(Class.class, Class.class, List.class, boolean.class, Map.class) + .getConstructor(Class.class, Class.class, List.class, boolean.class, Map.class, Optional.class) .newInstance(requiredTestClass, profile != null ? profile : null, getAdditionalTestResources(profileInstance, startupAction.getClassLoader()), profileInstance != null && profileInstance.disableGlobalTestResources(), - startupAction.getDevServicesProperties()); + startupAction.getDevServicesProperties(), Optional.empty()); testResourceManager.getClass().getMethod("init").invoke(testResourceManager); Map properties = (Map) testResourceManager.getClass().getMethod("start") .invoke(testResourceManager);