From a19eb3d3b9e6ee2cdffb3e344e3bcf6f73767ad9 Mon Sep 17 00:00:00 2001 From: xstefank Date: Fri, 11 Apr 2025 16:48:06 +0200 Subject: [PATCH 1/3] feat: allow to override test infrastructure kube client separately Signed-off-by: xstefank --- .../junit/AbstractOperatorExtension.java | 26 ++++++++++++++----- .../ClusterDeployedOperatorExtension.java | 6 +++++ .../operator/junit/HasKubernetesClient.java | 2 ++ .../junit/LocallyRunOperatorExtension.java | 10 +++++++ 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java index 00bf7e8380..fdd0e69a18 100644 --- a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java +++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java @@ -38,6 +38,7 @@ public abstract class AbstractOperatorExtension public static final int DEFAULT_NAMESPACE_DELETE_TIMEOUT = 90; private final KubernetesClient kubernetesClient; + private final KubernetesClient infrastructureKubernetesClient; protected final List infrastructure; protected Duration infrastructureTimeout; protected final boolean oneNamespacePerClass; @@ -56,10 +57,15 @@ protected AbstractOperatorExtension( boolean preserveNamespaceOnError, boolean waitForNamespaceDeletion, KubernetesClient kubernetesClient, + KubernetesClient infrastructureKubernetesClient, Function namespaceNameSupplier, Function perClassNamespaceNameSupplier) { this.kubernetesClient = kubernetesClient != null ? kubernetesClient : new KubernetesClientBuilder().build(); + this.infrastructureKubernetesClient = + infrastructureKubernetesClient != null + ? infrastructureKubernetesClient + : new KubernetesClientBuilder().build(); this.infrastructure = infrastructure; this.infrastructureTimeout = infrastructureTimeout; this.oneNamespacePerClass = oneNamespacePerClass; @@ -94,6 +100,11 @@ public KubernetesClient getKubernetesClient() { return kubernetesClient; } + @Override + public KubernetesClient getInfrastructureKubernetesClient() { + return infrastructureKubernetesClient; + } + public String getNamespace() { return namespace; } @@ -137,7 +148,7 @@ protected void beforeEachImpl(ExtensionContext context) { protected void before(ExtensionContext context) { LOGGER.info("Initializing integration test in namespace {}", namespace); - kubernetesClient + infrastructureKubernetesClient .namespaces() .resource( new NamespaceBuilder() @@ -145,8 +156,8 @@ protected void before(ExtensionContext context) { .build()) .serverSideApply(); - kubernetesClient.resourceList(infrastructure).serverSideApply(); - kubernetesClient + infrastructureKubernetesClient.resourceList(infrastructure).serverSideApply(); + infrastructureKubernetesClient .resourceList(infrastructure) .waitUntilReady(infrastructureTimeout.toMillis(), TimeUnit.MILLISECONDS); } @@ -168,16 +179,19 @@ protected void after(ExtensionContext context) { if (preserveNamespaceOnError && context.getExecutionException().isPresent()) { LOGGER.info("Preserving namespace {}", namespace); } else { - kubernetesClient.resourceList(infrastructure).delete(); + infrastructureKubernetesClient.resourceList(infrastructure).delete(); deleteOperator(); LOGGER.info("Deleting namespace {} and stopping operator", namespace); - kubernetesClient.namespaces().withName(namespace).delete(); + infrastructureKubernetesClient.namespaces().withName(namespace).delete(); if (waitForNamespaceDeletion) { LOGGER.info("Waiting for namespace {} to be deleted", namespace); Awaitility.await("namespace deleted") .pollInterval(50, TimeUnit.MILLISECONDS) .atMost(namespaceDeleteTimeout, TimeUnit.SECONDS) - .until(() -> kubernetesClient.namespaces().withName(namespace).get() == null); + .until( + () -> + infrastructureKubernetesClient.namespaces().withName(namespace).get() + == null); } } } diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java index 3fc49d4575..07ac9e81ab 100644 --- a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java +++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java @@ -39,6 +39,7 @@ private ClusterDeployedOperatorExtension( boolean waitForNamespaceDeletion, boolean oneNamespacePerClass, KubernetesClient kubernetesClient, + KubernetesClient infrastructureKubernetesClient, Function namespaceNameSupplier, Function perClassNamespaceNameSupplier) { super( @@ -48,6 +49,7 @@ private ClusterDeployedOperatorExtension( preserveNamespaceOnError, waitForNamespaceDeletion, kubernetesClient, + infrastructureKubernetesClient, namespaceNameSupplier, perClassNamespaceNameSupplier); this.operatorDeployment = operatorDeployment; @@ -114,6 +116,7 @@ public static class Builder extends AbstractBuilder { private final List operatorDeployment; private Duration deploymentTimeout; private KubernetesClient kubernetesClient; + private KubernetesClient infrastructureKubernetesClient; protected Builder() { super(); @@ -160,6 +163,9 @@ public ClusterDeployedOperatorExtension build() { waitForNamespaceDeletion, oneNamespacePerClass, kubernetesClient != null ? kubernetesClient : new KubernetesClientBuilder().build(), + infrastructureKubernetesClient != null + ? infrastructureKubernetesClient + : new KubernetesClientBuilder().build(), namespaceNameSupplier, perClassNamespaceNameSupplier); } diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/HasKubernetesClient.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/HasKubernetesClient.java index d93032333f..683e9e03fc 100644 --- a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/HasKubernetesClient.java +++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/HasKubernetesClient.java @@ -4,4 +4,6 @@ public interface HasKubernetesClient { KubernetesClient getKubernetesClient(); + + KubernetesClient getInfrastructureKubernetesClient(); } diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java index 3e6ad35e52..304f2b4ac0 100644 --- a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java +++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java @@ -65,6 +65,7 @@ private LocallyRunOperatorExtension( boolean waitForNamespaceDeletion, boolean oneNamespacePerClass, KubernetesClient kubernetesClient, + KubernetesClient infrastructureKubernetesClient, Consumer configurationServiceOverrider, Function namespaceNameSupplier, Function perClassNamespaceNameSupplier, @@ -76,6 +77,7 @@ private LocallyRunOperatorExtension( preserveNamespaceOnError, waitForNamespaceDeletion, kubernetesClient, + infrastructureKubernetesClient, namespaceNameSupplier, perClassNamespaceNameSupplier); this.reconcilers = reconcilers; @@ -357,6 +359,7 @@ public static class Builder extends AbstractBuilder { private final List> additionalCustomResourceDefinitions; private final List additionalCRDs = new ArrayList<>(); private KubernetesClient kubernetesClient; + private KubernetesClient infrastructureKubernetesClient; protected Builder() { super(); @@ -411,6 +414,12 @@ public Builder withKubernetesClient(KubernetesClient kubernetesClient) { return this; } + public Builder withInfrastructureKubernetesClient( + KubernetesClient infrastructureKubernetesClient) { + this.infrastructureKubernetesClient = infrastructureKubernetesClient; + return this; + } + public Builder withAdditionalCustomResourceDefinition( Class customResource) { additionalCustomResourceDefinitions.add(customResource); @@ -435,6 +444,7 @@ public LocallyRunOperatorExtension build() { waitForNamespaceDeletion, oneNamespacePerClass, kubernetesClient, + infrastructureKubernetesClient, configurationServiceOverrider, namespaceNameSupplier, perClassNamespaceNameSupplier, From c534518daa9640b00605344046a1f3498de1e7e3 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 16 Apr 2025 18:28:37 +0200 Subject: [PATCH 2/3] fix: use infrastructure client for tests set up & tear down Signed-off-by: Chris Laprun --- .../operator/junit/ClusterDeployedOperatorExtension.java | 7 +++++-- .../operator/junit/LocallyRunOperatorExtension.java | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java index 07ac9e81ab..db4018cb4b 100644 --- a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java +++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java @@ -71,7 +71,7 @@ protected void before(ExtensionContext context) { final var crdPath = "./target/classes/META-INF/fabric8/"; final var crdSuffix = "-v1.yml"; - final var kubernetesClient = getKubernetesClient(); + final var kubernetesClient = getInfrastructureKubernetesClient(); for (var crdFile : Objects.requireNonNull( new File(crdPath).listFiles((ignored, name) -> name.endsWith(crdSuffix)))) { @@ -109,7 +109,10 @@ protected void before(ExtensionContext context) { @Override protected void deleteOperator() { - getKubernetesClient().resourceList(operatorDeployment).inNamespace(namespace).delete(); + getInfrastructureKubernetesClient() + .resourceList(operatorDeployment) + .inNamespace(namespace) + .delete(); } public static class Builder extends AbstractBuilder { diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java index 304f2b4ac0..1b5dd07a06 100644 --- a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java +++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java @@ -239,7 +239,7 @@ public Operator getOperator() { protected void before(ExtensionContext context) { super.before(context); - final var kubernetesClient = getKubernetesClient(); + final var kubernetesClient = getInfrastructureKubernetesClient(); for (var ref : portForwards) { String podName = @@ -308,7 +308,7 @@ protected void before(ExtensionContext context) { protected void after(ExtensionContext context) { super.after(context); - var kubernetesClient = getKubernetesClient(); + var kubernetesClient = getInfrastructureKubernetesClient(); var iterator = appliedCRDs.iterator(); while (iterator.hasNext()) { From bf116d597e62b5bca3659ac391b0a04c1557957c Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Wed, 16 Apr 2025 18:29:05 +0200 Subject: [PATCH 3/3] fix: use infrastructure client if no operator client is set up Signed-off-by: Chris Laprun --- .../operator/junit/AbstractOperatorExtension.java | 4 ++-- .../junit/ClusterDeployedOperatorExtension.java | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java index fdd0e69a18..392327cdde 100644 --- a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java +++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java @@ -60,12 +60,12 @@ protected AbstractOperatorExtension( KubernetesClient infrastructureKubernetesClient, Function namespaceNameSupplier, Function perClassNamespaceNameSupplier) { - this.kubernetesClient = - kubernetesClient != null ? kubernetesClient : new KubernetesClientBuilder().build(); this.infrastructureKubernetesClient = infrastructureKubernetesClient != null ? infrastructureKubernetesClient : new KubernetesClientBuilder().build(); + this.kubernetesClient = + kubernetesClient != null ? kubernetesClient : this.infrastructureKubernetesClient; this.infrastructure = infrastructure; this.infrastructureTimeout = infrastructureTimeout; this.oneNamespacePerClass = oneNamespacePerClass; diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java index db4018cb4b..577dd8dae0 100644 --- a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java +++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java @@ -157,6 +157,12 @@ public Builder withKubernetesClient(KubernetesClient kubernetesClient) { } public ClusterDeployedOperatorExtension build() { + infrastructureKubernetesClient = + infrastructureKubernetesClient != null + ? infrastructureKubernetesClient + : new KubernetesClientBuilder().build(); + kubernetesClient = + kubernetesClient != null ? kubernetesClient : infrastructureKubernetesClient; return new ClusterDeployedOperatorExtension( operatorDeployment, deploymentTimeout, @@ -165,10 +171,8 @@ public ClusterDeployedOperatorExtension build() { preserveNamespaceOnError, waitForNamespaceDeletion, oneNamespacePerClass, - kubernetesClient != null ? kubernetesClient : new KubernetesClientBuilder().build(), - infrastructureKubernetesClient != null - ? infrastructureKubernetesClient - : new KubernetesClientBuilder().build(), + kubernetesClient, + infrastructureKubernetesClient, namespaceNameSupplier, perClassNamespaceNameSupplier); }