From bfbfae0f2dc42ce6cd780b7a68a4658dc08e875b Mon Sep 17 00:00:00 2001 From: heesuk Date: Wed, 17 Nov 2021 22:44:32 +0900 Subject: [PATCH 1/6] test: added `OperatorTest` for register api --- .../operator/OperatorTest.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java new file mode 100644 index 0000000000..6c16646e89 --- /dev/null +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java @@ -0,0 +1,75 @@ +package io.javaoperatorsdk.operator; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.config.ConfigurationService; +import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class OperatorTest { + + private final KubernetesClient kubernetesClient = mock(KubernetesClient.class); + private final ConfigurationService configurationService = mock(ConfigurationService.class); + private final ControllerConfiguration configuration = mock(ControllerConfiguration.class); + + private final Operator operator = new Operator(kubernetesClient, configurationService); + private final FooReconciler fooReconciler = FooReconciler.create(); + + @Test + @DisplayName("should register `Reconciler` to Controller") + public void shouldRegisterReconcilerToController() { + // given + when(configurationService.getConfigurationFor(fooReconciler)).thenReturn(configuration); + when(configuration.watchAllNamespaces()).thenReturn(true); + when(configuration.getName()).thenReturn("FOO"); + when(configuration.getCustomResourceClass()).thenReturn(FooReconciler.class); + + // when + operator.register(fooReconciler); + + // then + verify(configuration).watchAllNamespaces(); + verify(configuration).getName(); + verify(configuration).getCustomResourceClass(); + } + + @Test + @DisplayName("should throw `OperationException` when Configuration is null") + public void shouldThrowOperatorExceptionWhenConfigurationIsNull() { + Assertions.assertThrows(OperatorException.class, () -> operator.register(fooReconciler, null)); + } + + private static class FooCustomResource extends CustomResource { + } + + private static class FooSpec { + } + + private static class FooStatus { + } + + private static class FooReconciler implements Reconciler { + + private FooReconciler() { + } + + public static FooReconciler create() { + return new FooReconciler(); + } + + @Override + public UpdateControl reconcile(FooCustomResource resource, Context context) { + return UpdateControl.updateStatusSubResource(resource); + } + } + +} \ No newline at end of file From a131eb73c06d8c3dfd535124f14a0917f15f5d72 Mon Sep 17 00:00:00 2001 From: heesuk Date: Wed, 17 Nov 2021 23:02:53 +0900 Subject: [PATCH 2/6] refactor: refactored `Operator.register` api --- .../io/javaoperatorsdk/operator/Operator.java | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java index 0ec41a495c..735da4ebf9 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java @@ -110,13 +110,14 @@ public void close() { * Add a registration requests for the specified controller with this operator. The effective * registration of the controller is delayed till the operator is started. * - * @param controller the controller to register + * @param reconciler the controller to register * @param the {@code CustomResource} type associated with the controller * @throws OperatorException if a problem occurred during the registration process */ - public void register(Reconciler controller) + public void register(Reconciler reconciler) throws OperatorException { - register(controller, null); + final var defaultConfiguration = configurationService.getConfigurationFor(reconciler); + register(reconciler, defaultConfiguration); } /** @@ -127,39 +128,34 @@ public void register(Reconciler controller) * controller is delayed till the operator is started. * * @param reconciler part of the controller to register - * @param configuration the configuration with which we want to register the controller, if {@code - * null}, the controller's original configuration is used + * @param configuration the configuration with which we want to register the controller * @param the {@code CustomResource} type associated with the controller * @throws OperatorException if a problem occurred during the registration process */ - public void register( - Reconciler reconciler, ControllerConfiguration configuration) + public void register(Reconciler reconciler, + ControllerConfiguration configuration) throws OperatorException { - final var existing = configurationService.getConfigurationFor(reconciler); - if (existing == null) { + + if (configuration == null) { throw new OperatorException( "Cannot register controller with name " + reconciler.getClass().getCanonicalName() + " controller named " + ControllerUtils.getNameFor(reconciler) + " because its configuration cannot be found.\n" + " Known controllers are: " + configurationService.getKnownControllerNames()); - } else { - if (configuration == null) { - configuration = existing; - } - final var controller = - new Controller<>(reconciler, configuration, kubernetesClient); - controllers.add(controller); - - final var watchedNS = - configuration.watchAllNamespaces() - ? "[all namespaces]" - : configuration.getEffectiveNamespaces(); - log.info( - "Registered Controller: '{}' for CRD: '{}' for namespace(s): {}", - configuration.getName(), - configuration.getResourceClass(), - watchedNS); } + + final var controller = new Controller<>(reconciler, configuration, kubernetesClient); + + controllers.add(controller); + + final var watchedNS = + configuration.watchAllNamespaces() ? "[all namespaces]" : configuration.getEffectiveNamespaces(); + + log.info( + "Registered Controller: '{}' for CRD: '{}' for namespace(s): {}", + configuration.getName(), + configuration.getResourceClass(), + watchedNS); } static class ControllerManager implements LifecycleAware { From 2f493707daaa34052c07739afaf59b26d3f392eb Mon Sep 17 00:00:00 2001 From: heesuk Date: Wed, 17 Nov 2021 23:04:47 +0900 Subject: [PATCH 3/6] refactor: modified deprecated `kubernetesClient.getVersion()` method to `kubernetesClient.getKubernetesVersion()` --- .../src/main/java/io/javaoperatorsdk/operator/Operator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java index 735da4ebf9..2fa1a941e5 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java @@ -70,7 +70,7 @@ public void start() { log.info("Client version: {}", Version.clientVersion()); try { - final var k8sVersion = kubernetesClient.getVersion(); + final var k8sVersion = kubernetesClient.getKubernetesVersion(); if (k8sVersion != null) { log.info("Server version: {}.{}", k8sVersion.getMajor(), k8sVersion.getMinor()); } From e7c4f9192920e0ccd8957930d4e72f3d073e3f84 Mon Sep 17 00:00:00 2001 From: heesuk Date: Thu, 18 Nov 2021 23:10:50 +0900 Subject: [PATCH 4/6] style: fixed code format by maven build --- .../io/javaoperatorsdk/operator/Operator.java | 6 +- .../operator/OperatorTest.java | 104 +++++++++--------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java index 2fa1a941e5..2c14f4da8c 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/Operator.java @@ -133,7 +133,7 @@ public void register(Reconciler reconciler) * @throws OperatorException if a problem occurred during the registration process */ public void register(Reconciler reconciler, - ControllerConfiguration configuration) + ControllerConfiguration configuration) throws OperatorException { if (configuration == null) { @@ -148,8 +148,8 @@ public void register(Reconciler reconciler, controllers.add(controller); - final var watchedNS = - configuration.watchAllNamespaces() ? "[all namespaces]" : configuration.getEffectiveNamespaces(); + final var watchedNS = configuration.watchAllNamespaces() ? "[all namespaces]" + : configuration.getEffectiveNamespaces(); log.info( "Registered Controller: '{}' for CRD: '{}' for namespace(s): {}", diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java index 6c16646e89..cdc80b49e6 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java @@ -1,8 +1,8 @@ package io.javaoperatorsdk.operator; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.KubernetesClient; @@ -11,65 +11,65 @@ import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; class OperatorTest { - private final KubernetesClient kubernetesClient = mock(KubernetesClient.class); - private final ConfigurationService configurationService = mock(ConfigurationService.class); - private final ControllerConfiguration configuration = mock(ControllerConfiguration.class); - - private final Operator operator = new Operator(kubernetesClient, configurationService); - private final FooReconciler fooReconciler = FooReconciler.create(); - - @Test - @DisplayName("should register `Reconciler` to Controller") - public void shouldRegisterReconcilerToController() { - // given - when(configurationService.getConfigurationFor(fooReconciler)).thenReturn(configuration); - when(configuration.watchAllNamespaces()).thenReturn(true); - when(configuration.getName()).thenReturn("FOO"); - when(configuration.getCustomResourceClass()).thenReturn(FooReconciler.class); - - // when - operator.register(fooReconciler); - - // then - verify(configuration).watchAllNamespaces(); - verify(configuration).getName(); - verify(configuration).getCustomResourceClass(); - } + private final KubernetesClient kubernetesClient = mock(KubernetesClient.class); + private final ConfigurationService configurationService = mock(ConfigurationService.class); + private final ControllerConfiguration configuration = mock(ControllerConfiguration.class); - @Test - @DisplayName("should throw `OperationException` when Configuration is null") - public void shouldThrowOperatorExceptionWhenConfigurationIsNull() { - Assertions.assertThrows(OperatorException.class, () -> operator.register(fooReconciler, null)); - } + private final Operator operator = new Operator(kubernetesClient, configurationService); + private final FooReconciler fooReconciler = FooReconciler.create(); - private static class FooCustomResource extends CustomResource { - } + @Test + @DisplayName("should register `Reconciler` to Controller") + public void shouldRegisterReconcilerToController() { + // given + when(configurationService.getConfigurationFor(fooReconciler)).thenReturn(configuration); + when(configuration.watchAllNamespaces()).thenReturn(true); + when(configuration.getName()).thenReturn("FOO"); + when(configuration.getResourceClass()).thenReturn(FooReconciler.class); - private static class FooSpec { - } + // when + operator.register(fooReconciler); - private static class FooStatus { - } + // then + verify(configuration).watchAllNamespaces(); + verify(configuration).getName(); + verify(configuration).getResourceClass(); + } - private static class FooReconciler implements Reconciler { + @Test + @DisplayName("should throw `OperationException` when Configuration is null") + public void shouldThrowOperatorExceptionWhenConfigurationIsNull() { + Assertions.assertThrows(OperatorException.class, () -> operator.register(fooReconciler, null)); + } - private FooReconciler() { - } + private static class FooCustomResource extends CustomResource { + } - public static FooReconciler create() { - return new FooReconciler(); - } + private static class FooSpec { + } + + private static class FooStatus { + } + + private static class FooReconciler implements Reconciler { + + private FooReconciler() {} + + public static FooReconciler create() { + return new FooReconciler(); + } - @Override - public UpdateControl reconcile(FooCustomResource resource, Context context) { - return UpdateControl.updateStatusSubResource(resource); - } + @Override + public UpdateControl reconcile(FooCustomResource resource, Context context) { + return UpdateControl.updateStatusSubResource(resource); } + } -} \ No newline at end of file +} From eb7a56bb574c951d3a3efb9e7b5b5931c757db25 Mon Sep 17 00:00:00 2001 From: heesuk Date: Mon, 22 Nov 2021 22:41:49 +0900 Subject: [PATCH 5/6] test: added code to check controller is registered --- .../test/java/io/javaoperatorsdk/operator/OperatorTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java index cdc80b49e6..51830524f5 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java @@ -12,6 +12,7 @@ import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -41,6 +42,9 @@ public void shouldRegisterReconcilerToController() { verify(configuration).watchAllNamespaces(); verify(configuration).getName(); verify(configuration).getResourceClass(); + + assertThat(operator.getControllers().size()).isEqualTo(1); + assertThat(operator.getControllers().get(0).getReconciler()).isEqualTo(fooReconciler); } @Test From 98d21c7ff323d345d5486a19a993637c01730132 Mon Sep 17 00:00:00 2001 From: heesuk Date: Tue, 23 Nov 2021 17:25:09 +0900 Subject: [PATCH 6/6] test: modify to use `noUpdate` api --- .../src/test/java/io/javaoperatorsdk/operator/OperatorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java index 51830524f5..28a19d1081 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java @@ -72,7 +72,7 @@ public static FooReconciler create() { @Override public UpdateControl reconcile(FooCustomResource resource, Context context) { - return UpdateControl.updateStatusSubResource(resource); + return UpdateControl.noUpdate(); } }