From 8187e8ed07f4bcb07e66565389bf3e1587e91552 Mon Sep 17 00:00:00 2001 From: Marc Nuri Date: Thu, 22 Jul 2021 12:06:15 +0200 Subject: [PATCH] feat: Introduced @WithOpenShiftTestServer annotation Allows to easily run QuarkusTests with OpenShiftMockserver Signed-off-by: Marc Nuri --- docs/src/main/asciidoc/kubernetes-client.adoc | 14 ++++ .../client/runtime/KubernetesClientUtils.java | 1 + .../runtime/OpenShiftClientProducer.java | 6 +- integration-tests/kubernetes-client/pom.xml | 5 ++ .../client/OpenShiftTestServerTest.java | 41 ++++++++++++ .../AbstractKubernetesTestResource.java | 7 +- .../KubernetesMockServerTestResource.java | 6 +- .../client/KubernetesServerTestResource.java | 5 +- .../client/WithKubernetesTestServer.java | 4 +- .../OpenShiftMockServerTestResource.java | 4 ++ .../client/OpenShiftServerTestResource.java | 67 +++++++++++++++++++ .../client/OpenShiftTestServer.java | 17 +++++ .../client/WithOpenShiftTestServer.java | 41 ++++++++++++ 13 files changed, 209 insertions(+), 9 deletions(-) create mode 100644 integration-tests/kubernetes-client/src/test/java/io/quarkus/it/kubernetes/client/OpenShiftTestServerTest.java create mode 100644 test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftServerTestResource.java create mode 100644 test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftTestServer.java create mode 100644 test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/WithOpenShiftTestServer.java diff --git a/docs/src/main/asciidoc/kubernetes-client.adoc b/docs/src/main/asciidoc/kubernetes-client.adoc index 3e1a6f4ea9f45e..add54d4d93560f 100644 --- a/docs/src/main/asciidoc/kubernetes-client.adoc +++ b/docs/src/main/asciidoc/kubernetes-client.adoc @@ -384,6 +384,20 @@ public class OpenShiftClientTest { ... ---- +Or by using the `@WithOpenShiftTestServer` similar to the `@WithKubernetesTestServer` explained in the +previous section: + +[source, java] +---- +@WithOpenShiftTestServer +@QuarkusTest +public class OpenShiftClientTest { + + @OpenShiftTestServer + private OpenShiftServer mockOpenShiftServer; +... +---- + To use this feature, you have to add a dependency on `quarkus-test-openshift-client`: [source,xml] diff --git a/extensions/kubernetes-client/runtime-internal/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientUtils.java b/extensions/kubernetes-client/runtime-internal/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientUtils.java index ed908c62b17f6e..fc33ef3dfb81b6 100644 --- a/extensions/kubernetes-client/runtime-internal/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientUtils.java +++ b/extensions/kubernetes-client/runtime-internal/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesClientUtils.java @@ -42,6 +42,7 @@ public static Config createConfig(KubernetesClientBuildConfig buildConfig, TlsCo .withProxyUsername(buildConfig.proxyUsername.orElse(base.getProxyUsername())) .withProxyPassword(buildConfig.proxyPassword.orElse(base.getProxyPassword())) .withNoProxy(buildConfig.noProxy.orElse(base.getNoProxy())) + .withHttp2Disable(base.isHttp2Disable()) .build(); } diff --git a/extensions/openshift-client/runtime/src/main/java/io/quarkus/it/openshift/client/runtime/OpenShiftClientProducer.java b/extensions/openshift-client/runtime/src/main/java/io/quarkus/it/openshift/client/runtime/OpenShiftClientProducer.java index fca00d44e4ee9c..1f6ee8918c8f1e 100644 --- a/extensions/openshift-client/runtime/src/main/java/io/quarkus/it/openshift/client/runtime/OpenShiftClientProducer.java +++ b/extensions/openshift-client/runtime/src/main/java/io/quarkus/it/openshift/client/runtime/OpenShiftClientProducer.java @@ -9,6 +9,7 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.openshift.client.DefaultOpenShiftClient; import io.fabric8.openshift.client.OpenShiftClient; +import io.fabric8.openshift.client.OpenShiftConfig; import io.quarkus.arc.DefaultBean; @Singleton @@ -22,7 +23,10 @@ public class OpenShiftClientProducer { @Singleton @Produces public OpenShiftClient openShiftClient(Config config) { - client = new DefaultOpenShiftClient(config); + // TODO - Temporary fix for https://github.com/fabric8io/kubernetes-client/pull/3347 + WithOpenShiftTestServer + final OpenShiftConfig openShiftConfig = new OpenShiftConfig(config); + openShiftConfig.setHttp2Disable(config.isHttp2Disable()); + client = new DefaultOpenShiftClient(openShiftConfig); return client; } diff --git a/integration-tests/kubernetes-client/pom.xml b/integration-tests/kubernetes-client/pom.xml index ea2df355473871..553a8d9bb2c1a8 100644 --- a/integration-tests/kubernetes-client/pom.xml +++ b/integration-tests/kubernetes-client/pom.xml @@ -42,6 +42,11 @@ quarkus-test-kubernetes-client test + + io.quarkus + quarkus-test-openshift-client + test + org.assertj assertj-core diff --git a/integration-tests/kubernetes-client/src/test/java/io/quarkus/it/kubernetes/client/OpenShiftTestServerTest.java b/integration-tests/kubernetes-client/src/test/java/io/quarkus/it/kubernetes/client/OpenShiftTestServerTest.java new file mode 100644 index 00000000000000..c9d54efaa138d3 --- /dev/null +++ b/integration-tests/kubernetes-client/src/test/java/io/quarkus/it/kubernetes/client/OpenShiftTestServerTest.java @@ -0,0 +1,41 @@ +package io.quarkus.it.kubernetes.client; + +import static org.assertj.core.api.Assertions.assertThat; + +import javax.inject.Inject; + +import org.junit.jupiter.api.Test; + +import io.fabric8.openshift.api.model.ProjectBuilder; +import io.fabric8.openshift.client.OpenShiftClient; +import io.fabric8.openshift.client.server.mock.OpenShiftServer; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.kubernetes.client.OpenShiftTestServer; +import io.quarkus.test.kubernetes.client.WithOpenShiftTestServer; + +@WithOpenShiftTestServer +@QuarkusTest +class OpenShiftTestServerTest { + + @OpenShiftTestServer + private OpenShiftServer mockServer; + + @Inject + OpenShiftClient client; + + @Test + void testInjectionDefaultsToCrud() { + mockServer.getOpenshiftClient().projects() + .createOrReplace(new ProjectBuilder() + .withNewMetadata() + .withName("example-project") + .addToLabels("project", "crud-is-true") + .endMetadata() + .build()); + assertThat(client) + .isNotSameAs(mockServer.getOpenshiftClient()) + .isNotSameAs(mockServer.getOpenshiftClient()) + .returns("crud-is-true", + c -> c.projects().withName("example-project").get().getMetadata().getLabels().get("project")); + } +} diff --git a/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/AbstractKubernetesTestResource.java b/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/AbstractKubernetesTestResource.java index 14898cf3c4ac79..819ca8e08256e3 100644 --- a/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/AbstractKubernetesTestResource.java +++ b/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/AbstractKubernetesTestResource.java @@ -6,15 +6,18 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.GenericKubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClient; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; -public abstract class AbstractKubernetesTestResource implements QuarkusTestResourceLifecycleManager { +public abstract class AbstractKubernetesTestResource + implements QuarkusTestResourceLifecycleManager { protected T server; @Override public Map start() { final Map systemProps = new HashMap<>(); systemProps.put(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true"); + systemProps.put("quarkus.tls.trust-all", "true"); systemProps.put(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false"); systemProps.put(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); systemProps.put(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test"); @@ -37,7 +40,7 @@ public Map start() { return systemProps; } - protected abstract GenericKubernetesClient getClient(); + protected abstract GenericKubernetesClient getClient(); /** * Can be used by subclasses in order to diff --git a/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/KubernetesMockServerTestResource.java b/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/KubernetesMockServerTestResource.java index 94102685abe58e..fd4b3f96e74a7e 100644 --- a/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/KubernetesMockServerTestResource.java +++ b/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/KubernetesMockServerTestResource.java @@ -3,16 +3,18 @@ import java.lang.annotation.Annotation; import io.fabric8.kubernetes.client.GenericKubernetesClient; +import io.fabric8.kubernetes.client.NamespacedKubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; /** * @deprecated use {@link KubernetesServerTestResource} */ @Deprecated -public class KubernetesMockServerTestResource extends AbstractKubernetesTestResource { +public class KubernetesMockServerTestResource + extends AbstractKubernetesTestResource { @Override - protected GenericKubernetesClient getClient() { + protected GenericKubernetesClient getClient() { return server.createClient(); } diff --git a/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/KubernetesServerTestResource.java b/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/KubernetesServerTestResource.java index 99b0d893e68009..ff465acad6d157 100644 --- a/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/KubernetesServerTestResource.java +++ b/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/KubernetesServerTestResource.java @@ -6,10 +6,11 @@ import java.util.function.Consumer; import io.fabric8.kubernetes.client.GenericKubernetesClient; +import io.fabric8.kubernetes.client.NamespacedKubernetesClient; import io.fabric8.kubernetes.client.server.mock.KubernetesServer; import io.quarkus.test.common.QuarkusTestResourceConfigurableLifecycleManager; -public class KubernetesServerTestResource extends AbstractKubernetesTestResource +public class KubernetesServerTestResource extends AbstractKubernetesTestResource implements QuarkusTestResourceConfigurableLifecycleManager { private boolean https = false; @@ -30,7 +31,7 @@ public void init(WithKubernetesTestServer annotation) { } @Override - protected GenericKubernetesClient getClient() { + protected GenericKubernetesClient getClient() { return server.getClient(); } diff --git a/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/WithKubernetesTestServer.java b/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/WithKubernetesTestServer.java index c0bf14f1cebece..a9dc203a100efd 100644 --- a/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/WithKubernetesTestServer.java +++ b/test-framework/kubernetes-client/src/main/java/io/quarkus/test/kubernetes/client/WithKubernetesTestServer.java @@ -38,9 +38,9 @@ */ Class> setup() default NO_SETUP.class; - static class NO_SETUP implements Consumer { + class NO_SETUP implements Consumer { @Override public void accept(KubernetesServer t) { } - }; + } } diff --git a/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftMockServerTestResource.java b/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftMockServerTestResource.java index e5a2477a6604b6..6cbadc2e46dc50 100644 --- a/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftMockServerTestResource.java +++ b/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftMockServerTestResource.java @@ -2,6 +2,10 @@ import io.fabric8.openshift.client.server.mock.OpenShiftMockServer; +/** + * @deprecated use {@link OpenShiftServerTestResource} + */ +@Deprecated public class OpenShiftMockServerTestResource extends KubernetesMockServerTestResource { protected OpenShiftMockServer createMockServer() { diff --git a/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftServerTestResource.java b/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftServerTestResource.java new file mode 100644 index 00000000000000..720e3c6d646edb --- /dev/null +++ b/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftServerTestResource.java @@ -0,0 +1,67 @@ +package io.quarkus.test.kubernetes.client; + +import java.lang.annotation.Annotation; +import java.util.function.Consumer; + +import io.fabric8.kubernetes.client.GenericKubernetesClient; +import io.fabric8.openshift.client.NamespacedOpenShiftClient; +import io.fabric8.openshift.client.server.mock.OpenShiftServer; +import io.quarkus.test.common.QuarkusTestResourceConfigurableLifecycleManager; + +public class OpenShiftServerTestResource extends AbstractKubernetesTestResource + implements QuarkusTestResourceConfigurableLifecycleManager { + + private boolean https = false; + private boolean crud = true; + private Consumer setup; + + @Override + public void init(WithOpenShiftTestServer annotation) { + this.https = annotation.https(); + this.crud = annotation.crud(); + try { + this.setup = annotation.setup().getDeclaredConstructor().newInstance(); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + @Override + protected GenericKubernetesClient getClient() { + return server.getOpenshiftClient(); + } + + @Override + protected void initServer() { + server.before(); + } + + @Override + protected void configureServer() { + if (setup != null) + setup.accept(server); + } + + @Override + protected OpenShiftServer createServer() { + return new OpenShiftServer(https, crud); + } + + @Override + public void stop() { + if (server != null) { + server.after(); + server = null; + } + } + + @Override + protected Class getInjectedClass() { + return OpenShiftServer.class; + } + + @Override + protected Class getInjectionAnnotation() { + return OpenShiftTestServer.class; + } +} diff --git a/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftTestServer.java b/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftTestServer.java new file mode 100644 index 00000000000000..6f855547c96458 --- /dev/null +++ b/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/OpenShiftTestServer.java @@ -0,0 +1,17 @@ +package io.quarkus.test.kubernetes.client; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import io.fabric8.openshift.client.server.mock.OpenShiftServer; + +/** + * Used to specify that the field should be injected with the mock OpenShift API server + * Can only be used on type {@link OpenShiftServer} + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface OpenShiftTestServer { +} diff --git a/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/WithOpenShiftTestServer.java b/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/WithOpenShiftTestServer.java new file mode 100644 index 00000000000000..9d978bdd8c0a94 --- /dev/null +++ b/test-framework/openshift-client/src/main/java/io/quarkus/test/kubernetes/client/WithOpenShiftTestServer.java @@ -0,0 +1,41 @@ +package io.quarkus.test.kubernetes.client; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.function.Consumer; + +import io.fabric8.openshift.client.server.mock.OpenShiftServer; +import io.quarkus.test.common.QuarkusTestResource; + +/** + * Use on your test resource to get a mock {@link OpenShiftServer} spawn up, and injectable with {@link OpenShiftTestServer}. + * This annotation is only active when used on a test class, and only for this test class. + */ +@QuarkusTestResource(value = OpenShiftServerTestResource.class, restrictToAnnotatedClass = true) +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface WithOpenShiftTestServer { + + /** + * Start it with HTTPS + */ + boolean https() default false; + + /** + * Start it in CRUD mode + */ + boolean crud() default true; + + /** + * Setup class to call after the mock server is created, for custom setup. + */ + Class> setup() default NO_SETUP.class; + + class NO_SETUP implements Consumer { + @Override + public void accept(OpenShiftServer t) { + } + } +}