From 8083f76b9ad9e0596d62ff850d1e6b28aebe8aea Mon Sep 17 00:00:00 2001 From: pablo gonzalez granados Date: Fri, 26 Mar 2021 16:02:12 +0100 Subject: [PATCH] Deploy in parallel several resources. Deploy in Openshift several resources as additional resources, restAssured setup, deploy test application ...etc --- README.md | 2 + .../common/OpenShiftTestExtension.java | 62 ++++++++++++++++--- .../ParallelAdditionalResourcesEnabled.java | 14 +++++ .../heroes/workshop/HeroesOpenShiftIT.java | 2 + .../heroes/workshop/VillainsOpenShiftIT.java | 2 + .../kafka/AmqStreamsOpenShiftIT.java | 2 + .../kafka/StrimziKafkaAvroOpenShiftIT.java | 2 + 7 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 common/src/main/java/io/quarkus/ts/openshift/common/ParallelAdditionalResourcesEnabled.java diff --git a/README.md b/README.md index 522c38f1..b3431d19 100644 --- a/README.md +++ b/README.md @@ -264,6 +264,8 @@ quarkus.my.property=${KEYCLOAK_HTTP_URL:default_value} Further information about usage of configuration in [here](https://quarkus.io/guides/config-reference#combine-property-env-var). +**Note:** In case that you have several unrelated additional resources as Redis and postgres together in the same application, you can deploy those resources in parallel by adding `@ParallelAdditionalResourcesEnabled` annotation. Note that this label applies to all additional resources of this scenario. + ### Running tests in ephemeral namespaces By default, the test framework expects that the user is logged into an OpenShift project, and that project is used for all tests. diff --git a/common/src/main/java/io/quarkus/ts/openshift/common/OpenShiftTestExtension.java b/common/src/main/java/io/quarkus/ts/openshift/common/OpenShiftTestExtension.java index 237ed990..af8f9adf 100644 --- a/common/src/main/java/io/quarkus/ts/openshift/common/OpenShiftTestExtension.java +++ b/common/src/main/java/io/quarkus/ts/openshift/common/OpenShiftTestExtension.java @@ -14,6 +14,9 @@ import io.quarkus.ts.openshift.common.util.AwaitUtil; import io.quarkus.ts.openshift.common.util.OpenShiftUtil; import io.restassured.RestAssured; +import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.fusesource.jansi.Ansi; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; @@ -39,10 +42,15 @@ import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.ServiceLoader; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; @@ -139,18 +147,13 @@ public void beforeAll(ExtensionContext context) throws Exception { private void doBeforeAll(ExtensionContext context) throws Exception { System.out.println("---------- OpenShiftTest set up ----------"); - createEphemeralNamespaceIfNecessary(context); - - deployAdditionalResources(context); - + CompletableFuture.allOf(deployAdditionalResources(context)).join(); runPublicStaticVoidMethods(CustomizeApplicationDeployment.class, context); Map envVars = resolveEnvVars(context); getDeploymentStrategy(context).deploy(envVars); - setUpRestAssured(context); - getAwaitUtil(context).awaitAppRoute(); } @@ -180,18 +183,40 @@ private void createEphemeralNamespaceIfNecessary(ExtensionContext context) throw } } - private void deployAdditionalResources(ExtensionContext context) throws IOException, InterruptedException { + private CompletableFuture deployAdditionalResources(ExtensionContext context) { + final String actionName = "deployAdditionalResources"; TestsStatus testsStatus = getTestsStatus(context); OpenShiftClient oc = getOpenShiftClient(context); AwaitUtil awaitUtil = getAwaitUtil(context); Optional element = context.getElement(); + List>> additionalResourceStatus = new ArrayList<>(); if (element.isPresent()) { AnnotatedElement annotatedElement = element.get(); AdditionalResources[] annotations = annotatedElement.getAnnotationsByType(AdditionalResources.class); + boolean isParallelDeployment = isParallelDeploymentEnabled(annotatedElement); for (AdditionalResources additionalResources : annotations) { - AdditionalResourcesDeployed deployed = AdditionalResourcesDeployed.deploy(additionalResources, - testsStatus, oc, awaitUtil); + Supplier> deployStatus = applyDeployment(context, testsStatus, oc, awaitUtil, additionalResources); + if (isParallelDeployment) { + additionalResourceStatus.add(CompletableFuture.supplyAsync(() -> deployStatus.get())); + } else { + additionalResourceStatus.add(CompletableFuture.completedFuture(deployStatus.get())); + } + } + } + CompletableFuture[] additionalResources = additionalResourceStatus.toArray(new CompletableFuture[0]); + return CompletableFuture.allOf(additionalResources).thenAccept(next -> printResults(actionName, additionalResourceStatus)); + } + private boolean isParallelDeploymentEnabled(AnnotatedElement annotatedElement){ + return annotatedElement.getAnnotationsByType(ParallelAdditionalResourcesEnabled.class).length > 0; + } + + private Supplier> applyDeployment(ExtensionContext context, TestsStatus testsStatus, OpenShiftClient oc, AwaitUtil awaitUtil, AdditionalResources additionalResources) { + return () -> { + String resourceUrl = additionalResources.value(); + Pair status = MutablePair.of(resourceUrl, true); + try { + AdditionalResourcesDeployed deployed = AdditionalResourcesDeployed.deploy(additionalResources, testsStatus, oc, awaitUtil); if (EphemeralNamespace.isDisabled()) { // when using ephemeral namespaces, we don't delete additional resources because: // - when an ephemeral namespace is dropped, everything is destroyed anyway @@ -199,8 +224,27 @@ private void deployAdditionalResources(ExtensionContext context) throws IOExcept // everything in the ephemeral namespace must be kept intact getStore(context).put(new Object(), deployed); } + return status; + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + status.setValue(false); + return status; + } + }; + } + + private void printResults(String title, List>> results) { + System.out.println(ansi().a(String.format("--- Summary: %s ---", title))); + for (CompletableFuture> result : results) { + try { + Ansi content = ansi().a(result.get().getKey() + " "); + content = result.get().getValue() ? content.fgGreen().a("\u2713") : content.fgRed().a("\u2717"); + System.out.println(content.reset()); + } catch (InterruptedException | ExecutionException e) { + System.err.println(e.getMessage()); } } + System.out.println(ansi().a("--- end ---")); } private void setUpRestAssured(ExtensionContext context) throws Exception { diff --git a/common/src/main/java/io/quarkus/ts/openshift/common/ParallelAdditionalResourcesEnabled.java b/common/src/main/java/io/quarkus/ts/openshift/common/ParallelAdditionalResourcesEnabled.java new file mode 100644 index 00000000..5bc174f5 --- /dev/null +++ b/common/src/main/java/io/quarkus/ts/openshift/common/ParallelAdditionalResourcesEnabled.java @@ -0,0 +1,14 @@ +package io.quarkus.ts.openshift.common; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Allow you to deploy several additional resources at once. + * */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface ParallelAdditionalResourcesEnabled { +} diff --git a/external-applications/quarkus-workshop-super-heroes/src/test/java/io/quarkus/ts/openshift/heroes/workshop/HeroesOpenShiftIT.java b/external-applications/quarkus-workshop-super-heroes/src/test/java/io/quarkus/ts/openshift/heroes/workshop/HeroesOpenShiftIT.java index 4aed28f6..04402ebf 100644 --- a/external-applications/quarkus-workshop-super-heroes/src/test/java/io/quarkus/ts/openshift/heroes/workshop/HeroesOpenShiftIT.java +++ b/external-applications/quarkus-workshop-super-heroes/src/test/java/io/quarkus/ts/openshift/heroes/workshop/HeroesOpenShiftIT.java @@ -4,6 +4,7 @@ import io.quarkus.ts.openshift.common.CustomAppMetadata; import io.quarkus.ts.openshift.common.OnlyIfConfigured; import io.quarkus.ts.openshift.common.OpenShiftTest; +import io.quarkus.ts.openshift.common.ParallelAdditionalResourcesEnabled; import io.quarkus.ts.openshift.common.deploy.ManualDeploymentStrategy; import io.quarkus.ts.openshift.common.injection.TestResource; import org.junit.jupiter.api.MethodOrderer; @@ -33,6 +34,7 @@ @AdditionalResources("classpath:hero.yaml") @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @OnlyIfConfigured("ts.authenticated-registry") +@ParallelAdditionalResourcesEnabled public class HeroesOpenShiftIT { @TestResource diff --git a/external-applications/quarkus-workshop-super-heroes/src/test/java/io/quarkus/ts/openshift/heroes/workshop/VillainsOpenShiftIT.java b/external-applications/quarkus-workshop-super-heroes/src/test/java/io/quarkus/ts/openshift/heroes/workshop/VillainsOpenShiftIT.java index 9131371a..99a1a867 100644 --- a/external-applications/quarkus-workshop-super-heroes/src/test/java/io/quarkus/ts/openshift/heroes/workshop/VillainsOpenShiftIT.java +++ b/external-applications/quarkus-workshop-super-heroes/src/test/java/io/quarkus/ts/openshift/heroes/workshop/VillainsOpenShiftIT.java @@ -4,6 +4,7 @@ import io.quarkus.ts.openshift.common.CustomAppMetadata; import io.quarkus.ts.openshift.common.OnlyIfConfigured; import io.quarkus.ts.openshift.common.OpenShiftTest; +import io.quarkus.ts.openshift.common.ParallelAdditionalResourcesEnabled; import io.quarkus.ts.openshift.common.deploy.ManualDeploymentStrategy; import io.quarkus.ts.openshift.common.injection.TestResource; import org.hamcrest.core.Is; @@ -34,6 +35,7 @@ @AdditionalResources("classpath:villain.yaml") @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @OnlyIfConfigured("ts.authenticated-registry") +@ParallelAdditionalResourcesEnabled public class VillainsOpenShiftIT { @TestResource diff --git a/messaging/kafka-avro-reactive-messaging/src/test/java/io/quarkus/ts/openshift/messaging/kafka/AmqStreamsOpenShiftIT.java b/messaging/kafka-avro-reactive-messaging/src/test/java/io/quarkus/ts/openshift/messaging/kafka/AmqStreamsOpenShiftIT.java index da814588..19fa22ac 100644 --- a/messaging/kafka-avro-reactive-messaging/src/test/java/io/quarkus/ts/openshift/messaging/kafka/AmqStreamsOpenShiftIT.java +++ b/messaging/kafka-avro-reactive-messaging/src/test/java/io/quarkus/ts/openshift/messaging/kafka/AmqStreamsOpenShiftIT.java @@ -3,10 +3,12 @@ import io.quarkus.ts.openshift.common.AdditionalResources; import io.quarkus.ts.openshift.common.OnlyIfConfigured; import io.quarkus.ts.openshift.common.OpenShiftTest; +import io.quarkus.ts.openshift.common.ParallelAdditionalResourcesEnabled; @OpenShiftTest @AdditionalResources("classpath:deployments/kafka/amq-streams.yaml") @AdditionalResources("classpath:deployments/kafka/apicurio.yaml") @OnlyIfConfigured("ts.authenticated-registry") +@ParallelAdditionalResourcesEnabled public class AmqStreamsOpenShiftIT extends AbstractKafkaTest{ } diff --git a/messaging/kafka-avro-reactive-messaging/src/test/java/io/quarkus/ts/openshift/messaging/kafka/StrimziKafkaAvroOpenShiftIT.java b/messaging/kafka-avro-reactive-messaging/src/test/java/io/quarkus/ts/openshift/messaging/kafka/StrimziKafkaAvroOpenShiftIT.java index 9cd04c15..646fcc23 100644 --- a/messaging/kafka-avro-reactive-messaging/src/test/java/io/quarkus/ts/openshift/messaging/kafka/StrimziKafkaAvroOpenShiftIT.java +++ b/messaging/kafka-avro-reactive-messaging/src/test/java/io/quarkus/ts/openshift/messaging/kafka/StrimziKafkaAvroOpenShiftIT.java @@ -2,9 +2,11 @@ import io.quarkus.ts.openshift.common.AdditionalResources; import io.quarkus.ts.openshift.common.OpenShiftTest; +import io.quarkus.ts.openshift.common.ParallelAdditionalResourcesEnabled; @OpenShiftTest @AdditionalResources("classpath:deployments/kafka/strimzi.yaml") @AdditionalResources("classpath:deployments/kafka/apicurio.yaml") +@ParallelAdditionalResourcesEnabled public class StrimziKafkaAvroOpenShiftIT extends AbstractKafkaTest{ }