diff --git a/operator-framework-core/pom.xml b/operator-framework-core/pom.xml
index 8d0515e545..5449e14728 100644
--- a/operator-framework-core/pom.xml
+++ b/operator-framework-core/pom.xml
@@ -88,16 +88,6 @@
test
-
- org.apache.logging.log4j
- log4j-slf4j-impl
- test
-
-
- org.apache.logging.log4j
- log4j-core
- test
-
io.fabric8
kubernetes-server-mock
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 c3a2360be4..b2dfef58dd 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
@@ -3,6 +3,7 @@
import java.io.Closeable;
import java.io.IOException;
import java.net.ConnectException;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
@@ -57,6 +58,10 @@ public ConfigurationService getConfigurationService() {
return configurationService;
}
+ public List getControllers() {
+ return Collections.unmodifiableList(controllers.controllers);
+ }
+
/**
* Finishes the operator startup process. This is mostly used in injection-aware applications
* where there is no obvious entrypoint to the application which can trigger the injection process
@@ -99,6 +104,8 @@ public void close() {
"Operator SDK {} is shutting down...", configurationService.getVersion().getSdkVersion());
controllers.close();
+
+ k8sClient.close();
}
/**
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java
index 6560ef9e55..e85a4e8c4b 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java
@@ -7,14 +7,8 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public abstract class AbstractConfigurationService implements ConfigurationService {
-
- public static final String LOGGER_NAME = "Default ConfigurationService implementation";
- protected static final Logger log = LoggerFactory.getLogger(LOGGER_NAME);
-
private final Map configurations = new ConcurrentHashMap<>();
private final Version version;
@@ -60,12 +54,14 @@ public ControllerConfiguration getConfigurationFor
final var key = keyFor(controller);
final var configuration = configurations.get(key);
if (configuration == null) {
- log.warn(
- "Configuration for controller '{}' was not found. {}", key, getControllersNameMessage());
+ logMissingControllerWarning(key, getControllersNameMessage());
}
return configuration;
}
+ protected abstract void logMissingControllerWarning(String controllerKey,
+ String controllersNameMessage);
+
private String getControllersNameMessage() {
return "Known controllers: "
+ getKnownControllerNames().stream().reduce((s, s2) -> s + ", " + s2).orElse("None")
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java
new file mode 100644
index 0000000000..5715d707a0
--- /dev/null
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/BaseConfigurationService.java
@@ -0,0 +1,28 @@
+package io.javaoperatorsdk.operator.api.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BaseConfigurationService extends AbstractConfigurationService {
+
+ private static final String LOGGER_NAME = "Default ConfigurationService implementation";
+ private static final Logger logger = LoggerFactory.getLogger(LOGGER_NAME);
+
+ public BaseConfigurationService(Version version) {
+ super(version);
+ }
+
+ @Override
+ protected void logMissingControllerWarning(String controllerKey, String controllersNameMessage) {
+ logger.warn("Configuration for controller '{}' was not found. {}", controllerKey,
+ controllersNameMessage);
+ }
+
+ public String getLoggerName() {
+ return LOGGER_NAME;
+ }
+
+ protected Logger getLogger() {
+ return logger;
+ }
+}
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java
index 83a537cedc..ec1b6e3d72 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Utils.java
@@ -37,10 +37,14 @@ public static Version loadFromProperties() {
Date builtTime;
try {
- builtTime =
- // RFC 822 date is the default format used by git-commit-id-plugin
- new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
- .parse(properties.getProperty("git.build.time"));
+ String time = properties.getProperty("git.build.time");
+ if (time != null) {
+ builtTime =
+ // RFC 822 date is the default format used by git-commit-id-plugin
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(time);
+ } else {
+ builtTime = Date.from(Instant.EPOCH);
+ }
} catch (Exception e) {
log.debug("Couldn't parse git.build.time property", e);
builtTime = Date.from(Instant.EPOCH);
diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java
index b939f8e384..6bfb5bb2e5 100644
--- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java
+++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/Version.java
@@ -1,10 +1,13 @@
package io.javaoperatorsdk.operator.api.config;
+import java.time.Instant;
import java.util.Date;
/** A class encapsulating the version information associated with this SDK instance. */
public class Version {
+ public static final Version UNKNOWN = new Version("unknown", "unknown", Date.from(Instant.EPOCH));
+
private final String sdk;
private final String commit;
private final Date builtTime;
diff --git a/operator-framework-junit5/pom.xml b/operator-framework-junit5/pom.xml
new file mode 100644
index 0000000000..926abceadc
--- /dev/null
+++ b/operator-framework-junit5/pom.xml
@@ -0,0 +1,46 @@
+
+
+
+ java-operator-sdk
+ io.javaoperatorsdk
+ 1.9.7-SNAPSHOT
+
+ 4.0.0
+
+ operator-framework-junit-5
+ Operator SDK - Framework - JUnit 5 extension
+
+
+ 11
+ 11
+
+
+
+
+ io.javaoperatorsdk
+ operator-framework-core
+ ${project.version}
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+
+
+ org.assertj
+ assertj-core
+ 3.20.2
+
+
+ org.awaitility
+ awaitility
+ 4.1.0
+
+
+
+
\ No newline at end of file
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
new file mode 100644
index 0000000000..d93032333f
--- /dev/null
+++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/HasKubernetesClient.java
@@ -0,0 +1,7 @@
+package io.javaoperatorsdk.operator.junit;
+
+import io.fabric8.kubernetes.client.KubernetesClient;
+
+public interface HasKubernetesClient {
+ KubernetesClient getKubernetesClient();
+}
diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/KubernetesClientAware.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/KubernetesClientAware.java
new file mode 100644
index 0000000000..8a1a702074
--- /dev/null
+++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/KubernetesClientAware.java
@@ -0,0 +1,7 @@
+package io.javaoperatorsdk.operator.junit;
+
+import io.fabric8.kubernetes.client.KubernetesClient;
+
+public interface KubernetesClientAware extends HasKubernetesClient {
+ void setKubernetesClient(KubernetesClient kubernetesClient);
+}
diff --git a/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/OperatorExtension.java b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/OperatorExtension.java
new file mode 100644
index 0000000000..3a7ce8b0d2
--- /dev/null
+++ b/operator-framework-junit5/src/main/java/io/javaoperatorsdk/operator/junit/OperatorExtension.java
@@ -0,0 +1,275 @@
+package io.javaoperatorsdk.operator.junit;
+
+import static io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider.override;
+
+import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.fabric8.kubernetes.api.model.KubernetesResourceList;
+import io.fabric8.kubernetes.api.model.NamespaceBuilder;
+import io.fabric8.kubernetes.client.DefaultKubernetesClient;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil;
+import io.fabric8.kubernetes.client.utils.Utils;
+import io.javaoperatorsdk.operator.Operator;
+import io.javaoperatorsdk.operator.api.ResourceController;
+import io.javaoperatorsdk.operator.api.config.BaseConfigurationService;
+import io.javaoperatorsdk.operator.api.config.ConfigurationService;
+import io.javaoperatorsdk.operator.api.config.Version;
+import io.javaoperatorsdk.operator.processing.ConfiguredController;
+import io.javaoperatorsdk.operator.processing.retry.Retry;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OperatorExtension
+ implements HasKubernetesClient,
+ BeforeAllCallback,
+ BeforeEachCallback,
+ AfterAllCallback,
+ AfterEachCallback {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(OperatorExtension.class);
+
+ private final KubernetesClient kubernetesClient;
+ private final ConfigurationService configurationService;
+ private final Operator operator;
+ private final List controllers;
+ private final boolean preserveNamespaceOnError;
+ private final boolean waitForNamespaceDeletion;
+
+ private String namespace;
+
+ private OperatorExtension(
+ ConfigurationService configurationService,
+ List controllers,
+ boolean preserveNamespaceOnError,
+ boolean waitForNamespaceDeletion) {
+
+ this.kubernetesClient = new DefaultKubernetesClient();
+ this.configurationService = configurationService;
+ this.controllers = controllers;
+ this.operator = new Operator(this.kubernetesClient, this.configurationService);
+ this.preserveNamespaceOnError = preserveNamespaceOnError;
+ this.waitForNamespaceDeletion = waitForNamespaceDeletion;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public void beforeAll(ExtensionContext context) throws Exception {
+ before(context);
+ }
+
+ @Override
+ public void beforeEach(ExtensionContext context) throws Exception {
+ before(context);
+ }
+
+ @Override
+ public void afterAll(ExtensionContext context) throws Exception {
+ after(context);
+ }
+
+ @Override
+ public void afterEach(ExtensionContext context) throws Exception {
+ after(context);
+ }
+
+ @Override
+ public KubernetesClient getKubernetesClient() {
+ return kubernetesClient;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ @SuppressWarnings({"rawtypes"})
+ public List getControllers() {
+ return operator.getControllers().stream()
+ .map(ConfiguredController::getController)
+ .collect(Collectors.toUnmodifiableList());
+ }
+
+ @SuppressWarnings({"rawtypes"})
+ public T getControllerOfType(Class type) {
+ return operator.getControllers().stream()
+ .map(ConfiguredController::getController)
+ .filter(type::isInstance)
+ .map(type::cast)
+ .findFirst()
+ .orElseThrow(
+ () -> new IllegalArgumentException("Unable to find a controller of type: " + type));
+ }
+
+ public NonNamespaceOperation, Resource> resources(
+ Class type) {
+ return kubernetesClient.resources(type).inNamespace(namespace);
+ }
+
+ public T getNamedResource(Class type, String name) {
+ return kubernetesClient.resources(type).inNamespace(namespace).withName(name).get();
+ }
+
+ public T create(Class type, T resource) {
+ return kubernetesClient.resources(type).inNamespace(namespace).create(resource);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void before(ExtensionContext context) {
+ namespace = context.getRequiredTestClass().getSimpleName();
+ namespace += "-";
+ namespace += context.getRequiredTestMethod().getName();
+ namespace = KubernetesResourceUtil.sanitizeName(namespace).toLowerCase(Locale.US);
+ namespace = namespace.substring(0, Math.min(namespace.length(), 63));
+
+ LOGGER.info("Initializing integration test in namespace {}", namespace);
+
+ kubernetesClient
+ .namespaces()
+ .create(new NamespaceBuilder().withNewMetadata().withName(namespace).endMetadata().build());
+
+
+ for (var ref : controllers) {
+ final var config = configurationService.getConfigurationFor(ref.controller);
+ final var oconfig = override(config).settingNamespace(namespace);
+ final var path = "/META-INF/fabric8/" + config.getCRDName() + "-v1.yml";
+
+ if (ref.retry != null) {
+ oconfig.withRetry(ref.retry);
+ }
+
+ try (InputStream is = getClass().getResourceAsStream(path)) {
+ kubernetesClient.load(is).createOrReplace();
+ } catch (Exception ex) {
+ throw new IllegalStateException("Cannot apply CRD yaml: " + path, ex);
+ }
+
+ if (ref.controller instanceof KubernetesClientAware) {
+ ((KubernetesClientAware) ref.controller).setKubernetesClient(kubernetesClient);
+ }
+
+
+ this.operator.register(ref.controller, oconfig.build());
+ }
+
+ this.operator.start();
+ }
+
+ protected void after(ExtensionContext context) {
+ if (namespace != null) {
+ if (preserveNamespaceOnError && context.getExecutionException().isPresent()) {
+ LOGGER.info("Preserving namespace {}", namespace);
+ } else {
+ LOGGER.info("Deleting namespace {} and stopping operator", namespace);
+ kubernetesClient.namespaces().withName(namespace).delete();
+ if (waitForNamespaceDeletion) {
+ LOGGER.info("Waiting for namespace {} to be deleted", namespace);
+ Awaitility.await("namespace deleted")
+ .pollInterval(50, TimeUnit.MILLISECONDS)
+ .atMost(60, TimeUnit.SECONDS)
+ .until(() -> kubernetesClient.namespaces().withName(namespace).get() == null);
+ }
+ }
+ }
+
+ try {
+ this.operator.close();
+ } catch (Exception e) {
+ // ignored
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ public static class Builder {
+ private final List controllers;
+ private ConfigurationService configurationService;
+ private boolean preserveNamespaceOnError;
+ private boolean waitForNamespaceDeletion;
+
+ protected Builder() {
+ this.configurationService = new BaseConfigurationService(Version.UNKNOWN);
+ this.controllers = new ArrayList<>();
+
+ this.preserveNamespaceOnError = Utils.getSystemPropertyOrEnvVar(
+ "josdk.it.preserveNamespaceOnError",
+ false);
+
+ this.waitForNamespaceDeletion = Utils.getSystemPropertyOrEnvVar(
+ "josdk.it.waitForNamespaceDeletion",
+ true);
+ }
+
+ public Builder preserveNamespaceOnError(boolean value) {
+ this.preserveNamespaceOnError = value;
+ return this;
+ }
+
+ public Builder waitForNamespaceDeletion(boolean value) {
+ this.waitForNamespaceDeletion = value;
+ return this;
+ }
+
+ public Builder withConfigurationService(ConfigurationService value) {
+ configurationService = value;
+ return this;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Builder withController(ResourceController value) {
+ controllers.add(new ControllerSpec(value, null));
+ return this;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Builder withController(ResourceController value, Retry retry) {
+ controllers.add(new ControllerSpec(value, retry));
+ return this;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Builder withController(Class extends ResourceController> value) {
+ try {
+ controllers.add(new ControllerSpec(value.getConstructor().newInstance(), null));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return this;
+ }
+
+ public OperatorExtension build() {
+ return new OperatorExtension(
+ configurationService,
+ controllers,
+ preserveNamespaceOnError,
+ waitForNamespaceDeletion);
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static class ControllerSpec {
+ final ResourceController controller;
+ final Retry retry;
+
+ public ControllerSpec(
+ ResourceController controller,
+ Retry retry) {
+ this.controller = controller;
+ this.retry = retry;
+ }
+ }
+}
diff --git a/operator-framework/pom.xml b/operator-framework/pom.xml
index 1e0a3f826e..90dff4f18d 100644
--- a/operator-framework/pom.xml
+++ b/operator-framework/pom.xml
@@ -79,6 +79,12 @@
test-jar
test
+
+ io.javaoperatorsdk
+ operator-framework-junit-5
+ ${project.version}
+ test
+
\ No newline at end of file
diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java
index 590b9fb746..099754acd1 100644
--- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java
+++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationService.java
@@ -2,11 +2,11 @@
import io.fabric8.kubernetes.client.CustomResource;
import io.javaoperatorsdk.operator.api.ResourceController;
-import io.javaoperatorsdk.operator.api.config.AbstractConfigurationService;
+import io.javaoperatorsdk.operator.api.config.BaseConfigurationService;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.config.Utils;
-public class DefaultConfigurationService extends AbstractConfigurationService {
+public class DefaultConfigurationService extends BaseConfigurationService {
private static final DefaultConfigurationService instance = new DefaultConfigurationService();
@@ -32,7 +32,7 @@ ControllerConfiguration getConfigurationFor(
// create the configuration on demand and register it
config = new AnnotationConfiguration<>(controller);
register(config);
- log.info(
+ getLogger().info(
"Created configuration for controller {} with name {}",
controller.getClass().getName(),
config.getName());
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java
index f8157c648b..bf06bc054a 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java
@@ -4,129 +4,98 @@
import static org.awaitility.Awaitility.await;
import io.fabric8.kubernetes.api.model.ConfigMap;
-import io.fabric8.kubernetes.client.DefaultKubernetesClient;
-import io.fabric8.kubernetes.client.KubernetesClient;
+import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService;
+import io.javaoperatorsdk.operator.junit.OperatorExtension;
import io.javaoperatorsdk.operator.sample.simple.TestCustomResource;
import io.javaoperatorsdk.operator.sample.simple.TestCustomResourceController;
+import io.javaoperatorsdk.operator.support.TestUtils;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.extension.RegisterExtension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class ConcurrencyIT {
-
public static final int NUMBER_OF_RESOURCES_CREATED = 50;
public static final int NUMBER_OF_RESOURCES_DELETED = 30;
public static final int NUMBER_OF_RESOURCES_UPDATED = 20;
- private static final Logger log = LoggerFactory.getLogger(ConcurrencyIT.class);
public static final String UPDATED_SUFFIX = "_updated";
- private IntegrationTestSupport integrationTest = new IntegrationTestSupport();
-
- @BeforeAll
- public void setup() {
- KubernetesClient k8sClient = new DefaultKubernetesClient();
- integrationTest.initialize(k8sClient, new TestCustomResourceController(k8sClient, true));
- }
+ private static final Logger log = LoggerFactory.getLogger(ConcurrencyIT.class);
- @BeforeEach
- public void cleanup() {
- integrationTest.cleanup();
- }
+ @RegisterExtension
+ OperatorExtension operator =
+ OperatorExtension.builder()
+ .withConfigurationService(DefaultConfigurationService.instance())
+ .withController(new TestCustomResourceController(true))
+ .build();
@Test
- public void manyResourcesGetCreatedUpdatedAndDeleted() {
- integrationTest.teardownIfSuccess(
- () -> {
- log.info("Creating {} new resources", NUMBER_OF_RESOURCES_CREATED);
- for (int i = 0; i < NUMBER_OF_RESOURCES_CREATED; i++) {
- TestCustomResource tcr = integrationTest.createTestCustomResource(String.valueOf(i));
- integrationTest
- .getCrOperations()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .create(tcr);
- }
+ public void manyResourcesGetCreatedUpdatedAndDeleted() throws InterruptedException {
+ log.info("Creating {} new resources", NUMBER_OF_RESOURCES_CREATED);
+ for (int i = 0; i < NUMBER_OF_RESOURCES_CREATED; i++) {
+ TestCustomResource tcr = TestUtils.testCustomResourceWithPrefix(String.valueOf(i));
+ operator.resources(TestCustomResource.class).create(tcr);
+ }
- await()
- .atMost(1, TimeUnit.MINUTES)
- .untilAsserted(
- () -> {
- List items =
- integrationTest
- .getK8sClient()
- .configMaps()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .withLabel(
- "managedBy", TestCustomResourceController.class.getSimpleName())
- .list()
- .getItems();
- assertThat(items).hasSize(NUMBER_OF_RESOURCES_CREATED);
- });
+ await()
+ .atMost(1, TimeUnit.MINUTES)
+ .untilAsserted(
+ () -> {
+ List items =
+ operator.resources(ConfigMap.class)
+ .withLabel(
+ "managedBy", TestCustomResourceController.class.getSimpleName())
+ .list()
+ .getItems();
+ assertThat(items).hasSize(NUMBER_OF_RESOURCES_CREATED);
+ });
- log.info("Updating {} resources", NUMBER_OF_RESOURCES_UPDATED);
- // update some resources
- for (int i = 0; i < NUMBER_OF_RESOURCES_UPDATED; i++) {
- TestCustomResource tcr =
- (TestCustomResource) integrationTest
- .getCrOperations()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .withName(IntegrationTestSupport.TEST_CUSTOM_RESOURCE_PREFIX + i)
- .get();
- tcr.getSpec().setValue(i + UPDATED_SUFFIX);
- integrationTest
- .getCrOperations()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .createOrReplace(tcr);
- }
- // sleep for a short time to make variability to the test, so some updates are not
- // executed before delete
- Thread.sleep(300);
+ log.info("Updating {} resources", NUMBER_OF_RESOURCES_UPDATED);
+ // update some resources
+ for (int i = 0; i < NUMBER_OF_RESOURCES_UPDATED; i++) {
+ TestCustomResource tcr =
+ operator.getNamedResource(TestCustomResource.class,
+ TestUtils.TEST_CUSTOM_RESOURCE_PREFIX + i);
+ tcr.getSpec().setValue(i + UPDATED_SUFFIX);
+ operator.resources(TestCustomResource.class)
+ .createOrReplace(tcr);
+ }
+ // sleep for a short time to make variability to the test, so some updates are not
+ // executed before delete
+ Thread.sleep(300);
- log.info("Deleting {} resources", NUMBER_OF_RESOURCES_DELETED);
- for (int i = 0; i < NUMBER_OF_RESOURCES_DELETED; i++) {
- TestCustomResource tcr = integrationTest.createTestCustomResource(String.valueOf(i));
- integrationTest
- .getCrOperations()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .delete(tcr);
- }
+ log.info("Deleting {} resources", NUMBER_OF_RESOURCES_DELETED);
+ for (int i = 0; i < NUMBER_OF_RESOURCES_DELETED; i++) {
+ TestCustomResource tcr = TestUtils.testCustomResourceWithPrefix(String.valueOf(i));
+ operator.resources(TestCustomResource.class).delete(tcr);
+ }
- await()
- .atMost(1, TimeUnit.MINUTES)
- .untilAsserted(
- () -> {
- List items =
- integrationTest
- .getK8sClient()
- .configMaps()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .withLabel(
- "managedBy", TestCustomResourceController.class.getSimpleName())
- .list()
- .getItems();
- // reducing configmaps to names only - better for debugging
- List itemDescs =
- items.stream()
- .map(configMap -> configMap.getMetadata().getName())
- .collect(Collectors.toList());
- assertThat(itemDescs)
- .hasSize(NUMBER_OF_RESOURCES_CREATED - NUMBER_OF_RESOURCES_DELETED);
+ await()
+ .atMost(1, TimeUnit.MINUTES)
+ .untilAsserted(
+ () -> {
+ List items =
+ operator.resources(ConfigMap.class)
+ .withLabel(
+ "managedBy", TestCustomResourceController.class.getSimpleName())
+ .list()
+ .getItems();
+ // reducing configmaps to names only - better for debugging
+ List itemDescs =
+ items.stream()
+ .map(configMap -> configMap.getMetadata().getName())
+ .collect(Collectors.toList());
+ assertThat(itemDescs)
+ .hasSize(NUMBER_OF_RESOURCES_CREATED - NUMBER_OF_RESOURCES_DELETED);
- List crs =
- integrationTest
- .getK8sClient()
- .customResources(TestCustomResource.class)
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .list()
- .getItems();
- assertThat(crs)
- .hasSize(NUMBER_OF_RESOURCES_CREATED - NUMBER_OF_RESOURCES_DELETED);
- });
- });
+ List crs =
+ operator.resources(TestCustomResource.class)
+ .list()
+ .getItems();
+ assertThat(crs)
+ .hasSize(NUMBER_OF_RESOURCES_CREATED - NUMBER_OF_RESOURCES_DELETED);
+ });
}
}
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java
index 843f7a9103..b4bfe376f2 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ControllerExecutionIT.java
@@ -4,59 +4,44 @@
import static org.awaitility.Awaitility.await;
import io.fabric8.kubernetes.api.model.ConfigMap;
-import io.fabric8.kubernetes.client.DefaultKubernetesClient;
-import io.fabric8.kubernetes.client.KubernetesClient;
+import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService;
+import io.javaoperatorsdk.operator.junit.OperatorExtension;
import io.javaoperatorsdk.operator.sample.simple.TestCustomResource;
import io.javaoperatorsdk.operator.sample.simple.TestCustomResourceController;
+import io.javaoperatorsdk.operator.support.TestUtils;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.extension.RegisterExtension;
-@TestInstance(TestInstance.Lifecycle.PER_METHOD)
public class ControllerExecutionIT {
-
- private IntegrationTestSupport integrationTestSupport = new IntegrationTestSupport();
-
- public void initAndCleanup(boolean controllerStatusUpdate) {
- KubernetesClient k8sClient = new DefaultKubernetesClient();
- integrationTestSupport.initialize(
- k8sClient, new TestCustomResourceController(k8sClient, controllerStatusUpdate));
- integrationTestSupport.cleanup();
- }
+ @RegisterExtension
+ OperatorExtension operator =
+ OperatorExtension.builder()
+ .withConfigurationService(DefaultConfigurationService.instance())
+ .withController(new TestCustomResourceController(true))
+ .build();
@Test
public void configMapGetsCreatedForTestCustomResource() {
- initAndCleanup(true);
- integrationTestSupport.teardownIfSuccess(
- () -> {
- TestCustomResource resource = TestUtils.testCustomResource();
+ operator.getControllerOfType(TestCustomResourceController.class).setUpdateStatus(true);
- integrationTestSupport
- .getCrOperations()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .create(resource);
+ TestCustomResource resource = TestUtils.testCustomResource();
+ operator.create(TestCustomResource.class, resource);
- awaitResourcesCreatedOrUpdated();
- awaitStatusUpdated();
- assertThat(integrationTestSupport.numberOfControllerExecutions()).isEqualTo(2);
- });
+ awaitResourcesCreatedOrUpdated();
+ awaitStatusUpdated();
+ assertThat(TestUtils.getNumberOfExecutions(operator)).isEqualTo(2);
}
@Test
public void eventIsSkippedChangedOnMetadataOnlyUpdate() {
- initAndCleanup(false);
- integrationTestSupport.teardownIfSuccess(
- () -> {
- TestCustomResource resource = TestUtils.testCustomResource();
+ operator.getControllerOfType(TestCustomResourceController.class).setUpdateStatus(false);
- integrationTestSupport
- .getCrOperations()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .create(resource);
+ TestCustomResource resource = TestUtils.testCustomResource();
+ operator.create(TestCustomResource.class, resource);
- awaitResourcesCreatedOrUpdated();
- assertThat(integrationTestSupport.numberOfControllerExecutions()).isEqualTo(1);
- });
+ awaitResourcesCreatedOrUpdated();
+ assertThat(TestUtils.getNumberOfExecutions(operator)).isEqualTo(1);
}
void awaitResourcesCreatedOrUpdated() {
@@ -65,12 +50,7 @@ void awaitResourcesCreatedOrUpdated() {
.untilAsserted(
() -> {
ConfigMap configMap =
- integrationTestSupport
- .getK8sClient()
- .configMaps()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .withName("test-config-map")
- .get();
+ operator.getNamedResource(ConfigMap.class, "test-config-map");
assertThat(configMap).isNotNull();
assertThat(configMap.getData().get("test-key")).isEqualTo("test-value");
});
@@ -86,11 +66,8 @@ void awaitStatusUpdated(int timeout) {
.untilAsserted(
() -> {
TestCustomResource cr =
- (TestCustomResource) integrationTestSupport
- .getCrOperations()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .withName(TestUtils.TEST_CUSTOM_RESOURCE_NAME)
- .get();
+ operator.getNamedResource(TestCustomResource.class,
+ TestUtils.TEST_CUSTOM_RESOURCE_NAME);
assertThat(cr).isNotNull();
assertThat(cr.getStatus()).isNotNull();
assertThat(cr.getStatus().getConfigMapStatus()).isEqualTo("ConfigMap Ready");
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventSourceIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventSourceIT.java
index 05a4a3df8f..771c5c763b 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventSourceIT.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/EventSourceIT.java
@@ -1,52 +1,42 @@
package io.javaoperatorsdk.operator;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
-import io.fabric8.kubernetes.client.DefaultKubernetesClient;
-import io.fabric8.kubernetes.client.KubernetesClient;
+import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService;
+import io.javaoperatorsdk.operator.junit.OperatorExtension;
import io.javaoperatorsdk.operator.sample.event.EventSourceTestCustomResource;
import io.javaoperatorsdk.operator.sample.event.EventSourceTestCustomResourceController;
import io.javaoperatorsdk.operator.sample.event.EventSourceTestCustomResourceSpec;
-import org.junit.jupiter.api.BeforeEach;
+import io.javaoperatorsdk.operator.support.TestUtils;
+import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.junit.jupiter.api.extension.RegisterExtension;
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class EventSourceIT {
-
- private static final Logger log = LoggerFactory.getLogger(EventSourceIT.class);
-
- public static final int EXPECTED_TIMER_EVENT_COUNT = 3;
- private final IntegrationTestSupport integrationTestSupport = new IntegrationTestSupport();
-
- @BeforeEach
- public void initAndCleanup() {
- KubernetesClient k8sClient = new DefaultKubernetesClient();
- integrationTestSupport.initialize(k8sClient, new EventSourceTestCustomResourceController());
- integrationTestSupport.cleanup();
- }
+ @RegisterExtension
+ OperatorExtension operator =
+ OperatorExtension.builder()
+ .withConfigurationService(DefaultConfigurationService.instance())
+ .withController(EventSourceTestCustomResourceController.class)
+ .build();
@Test
public void receivingPeriodicEvents() {
- integrationTestSupport.teardownIfSuccess(
- () -> {
- EventSourceTestCustomResource resource = createTestCustomResource("1");
- integrationTestSupport
- .getCrOperations()
- .inNamespace(IntegrationTestSupport.TEST_NAMESPACE)
- .create(resource);
-
- Thread.sleep(
- EventSourceTestCustomResourceController.TIMER_DELAY
- + EXPECTED_TIMER_EVENT_COUNT
- * EventSourceTestCustomResourceController.TIMER_PERIOD);
-
- assertThat(integrationTestSupport.numberOfControllerExecutions())
- .isGreaterThanOrEqualTo(EXPECTED_TIMER_EVENT_COUNT + 1);
- });
+ EventSourceTestCustomResource resource = createTestCustomResource("1");
+
+ operator.create(EventSourceTestCustomResource.class, resource);
+
+ await()
+ .atMost(5, TimeUnit.SECONDS)
+ .pollInterval(
+ EventSourceTestCustomResourceController.TIMER_PERIOD / 2, TimeUnit.MILLISECONDS)
+ .untilAsserted(
+ () -> {
+ assertThat(TestUtils.getNumberOfExecutions(operator))
+ .isGreaterThanOrEqualTo(4);
+ });
}
public EventSourceTestCustomResource createTestCustomResource(String id) {
@@ -54,7 +44,7 @@ public EventSourceTestCustomResource createTestCustomResource(String id) {
resource.setMetadata(
new ObjectMetaBuilder()
.withName("eventsource-" + id)
- .withNamespace(IntegrationTestSupport.TEST_NAMESPACE)
+ .withNamespace(operator.getNamespace())
.withFinalizers(EventSourceTestCustomResourceController.FINALIZER_NAME)
.build());
resource.setKind("Eventsourcesample");
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java
deleted file mode 100644
index 271c50514b..0000000000
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package io.javaoperatorsdk.operator;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.awaitility.Awaitility.await;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.fabric8.kubernetes.api.model.KubernetesResourceList;
-import io.fabric8.kubernetes.api.model.Namespace;
-import io.fabric8.kubernetes.api.model.NamespaceBuilder;
-import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
-import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
-import io.fabric8.kubernetes.client.CustomResource;
-import io.fabric8.kubernetes.client.KubernetesClient;
-import io.fabric8.kubernetes.client.dsl.MixedOperation;
-import io.fabric8.kubernetes.client.dsl.Resource;
-import io.fabric8.kubernetes.client.utils.Serialization;
-import io.javaoperatorsdk.operator.api.ResourceController;
-import io.javaoperatorsdk.operator.api.config.ControllerConfigurationOverrider;
-import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService;
-import io.javaoperatorsdk.operator.processing.retry.Retry;
-import io.javaoperatorsdk.operator.sample.simple.TestCustomResource;
-import io.javaoperatorsdk.operator.sample.simple.TestCustomResourceSpec;
-
-public class IntegrationTestSupport {
-
- public static final String TEST_NAMESPACE = "java-operator-sdk-int-test";
- public static final String TEST_CUSTOM_RESOURCE_PREFIX = "test-custom-resource-";
- private static final Logger log = LoggerFactory.getLogger(IntegrationTestSupport.class);
- private KubernetesClient k8sClient;
- private MixedOperation, Resource> crOperations;
- private Operator operator;
- private ResourceController controller;
-
- public void initialize(KubernetesClient k8sClient, ResourceController controller) {
- initialize(k8sClient, controller, null);
- }
-
- public void initialize(KubernetesClient k8sClient, ResourceController controller, Retry retry) {
- log.info("Initializing integration test in namespace {}", TEST_NAMESPACE);
- this.k8sClient = k8sClient;
- this.controller = controller;
-
- final var configurationService = DefaultConfigurationService.instance();
-
- final var config = configurationService.getConfigurationFor(controller);
- // load generated CRD
- final var crdPath = "/META-INF/fabric8/" + config.getCRDName() + "-v1.yml";
- loadCRDAndApplyToCluster(crdPath);
-
- final var customResourceClass = config.getCustomResourceClass();
- this.crOperations = k8sClient.resources(customResourceClass);
-
- final var namespaces = k8sClient.namespaces();
- if (namespaces.withName(TEST_NAMESPACE).get() == null) {
- namespaces.create(
- new NamespaceBuilder().withNewMetadata().withName(TEST_NAMESPACE).endMetadata().build());
- }
- operator = new Operator(k8sClient, configurationService);
- final var overriddenConfig =
- ControllerConfigurationOverrider.override(config).settingNamespace(TEST_NAMESPACE);
- if (retry != null) {
- overriddenConfig.withRetry(retry);
- }
- operator.register(controller, overriddenConfig.build());
- operator.start();
- log.info("Operator is running with {}", controller.getClass().getCanonicalName());
- }
-
- public void loadCRDAndApplyToCluster(String classPathYaml) {
- var crd = loadYaml(CustomResourceDefinition.class, classPathYaml);
- if ("apiextensions.k8s.io/v1".equals(crd.getApiVersion())) {
- k8sClient.apiextensions().v1().customResourceDefinitions().createOrReplace(crd);
- } else {
- var crd2 =
- loadYaml(
- io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition.class,
- classPathYaml);
- k8sClient.apiextensions().v1beta1().customResourceDefinitions().createOrReplace(crd2);
- }
- }
-
- public void cleanup() {
- log.info("Cleaning up namespace {}", TEST_NAMESPACE);
-
- // we depend on the actual operator from the startup to handle the finalizers and clean up
- // resources from previous test runs
- crOperations.inNamespace(TEST_NAMESPACE).delete(crOperations.list().getItems());
-
- await("all CRs cleaned up")
- .atMost(60, TimeUnit.SECONDS)
- .untilAsserted(
- () -> assertThat(crOperations.inNamespace(TEST_NAMESPACE).list().getItems()).isEmpty());
-
- k8sClient
- .configMaps()
- .inNamespace(TEST_NAMESPACE)
- .withLabel("managedBy", controller.getClass().getSimpleName())
- .delete();
-
- await("all config maps cleaned up")
- .atMost(60, TimeUnit.SECONDS)
- .untilAsserted(
- () -> {
- assertThat(
- k8sClient
- .configMaps()
- .inNamespace(TEST_NAMESPACE)
- .withLabel("managedBy", controller.getClass().getSimpleName())
- .list()
- .getItems()
- .isEmpty());
- });
-
- log.info("Cleaned up namespace " + TEST_NAMESPACE);
- }
-
- /**
- * Use this method to execute the cleanup of the integration test namespace only in case the test
- * was successful. This is useful to keep the Kubernetes resources around to debug a failed test
- * run. Unfortunately I couldn't make this work with standard JUnit methods as the @AfterAll
- * method doesn't know if the tests succeeded or not.
- *
- * @param test The code of the actual test.
- * @throws Exception if the test threw an exception.
- */
- public void teardownIfSuccess(TestRun test) {
- try {
- test.run();
-
- log.info("Deleting namespace {} and stopping operator", TEST_NAMESPACE);
- Namespace namespace = k8sClient.namespaces().withName(TEST_NAMESPACE).get();
- if (namespace.getStatus().getPhase().equals("Active")) {
- k8sClient.namespaces().withName(TEST_NAMESPACE).delete();
- }
- await("namespace deleted")
- .atMost(45, TimeUnit.SECONDS)
- .until(() -> k8sClient.namespaces().withName(TEST_NAMESPACE).get() == null);
- } catch (Exception e) {
- throw new IllegalStateException(e);
- } finally {
- k8sClient.close();
- }
- }
-
- public int numberOfControllerExecutions() {
- return ((TestExecutionInfoProvider) controller).getNumberOfExecutions();
- }
-
- private T loadYaml(Class clazz, String yaml) {
- try (InputStream is = getClass().getResourceAsStream(yaml)) {
- return Serialization.unmarshal(is, clazz);
- } catch (IOException ex) {
- throw new IllegalStateException("Cannot find yaml on classpath: " + yaml);
- }
- }
-
- public TestCustomResource createTestCustomResource(String id) {
- TestCustomResource resource = new TestCustomResource();
- resource.setMetadata(
- new ObjectMetaBuilder()
- .withName(TEST_CUSTOM_RESOURCE_PREFIX + id)
- .withNamespace(TEST_NAMESPACE)
- .build());
- resource.setKind("CustomService");
- resource.setSpec(new TestCustomResourceSpec());
- resource.getSpec().setConfigMapName("test-config-map-" + id);
- resource.getSpec().setKey("test-key");
- resource.getSpec().setValue(id);
- return resource;
- }
-
- public KubernetesClient getK8sClient() {
- return k8sClient;
- }
-
- public MixedOperation, Resource> getCrOperations() {
- return crOperations;
- }
-
- public CustomResource getCustomResource(String name) {
- return getCrOperations().inNamespace(TEST_NAMESPACE).withName(name).get();
- }
-
- public Operator getOperator() {
- return operator;
- }
-
- public interface TestRun {
-
- void run() throws Exception;
- }
-}
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/RetryIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/RetryIT.java
index bdbb5f561c..b3b4be5f95 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/RetryIT.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/RetryIT.java
@@ -1,54 +1,57 @@
package io.javaoperatorsdk.operator;
-import static io.javaoperatorsdk.operator.IntegrationTestSupport.TEST_NAMESPACE;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
-import io.fabric8.kubernetes.client.DefaultKubernetesClient;
-import io.fabric8.kubernetes.client.KubernetesClient;
+import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService;
+import io.javaoperatorsdk.operator.junit.OperatorExtension;
import io.javaoperatorsdk.operator.processing.retry.GenericRetry;
-import io.javaoperatorsdk.operator.processing.retry.Retry;
import io.javaoperatorsdk.operator.sample.retry.RetryTestCustomResource;
import io.javaoperatorsdk.operator.sample.retry.RetryTestCustomResourceController;
import io.javaoperatorsdk.operator.sample.retry.RetryTestCustomResourceSpec;
import io.javaoperatorsdk.operator.sample.retry.RetryTestCustomResourceStatus;
-import org.junit.jupiter.api.BeforeEach;
+import io.javaoperatorsdk.operator.support.TestUtils;
+import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
public class RetryIT {
-
public static final int RETRY_INTERVAL = 150;
- private IntegrationTestSupport integrationTestSupport = new IntegrationTestSupport();
- @BeforeEach
- public void initAndCleanup() {
- Retry retry =
- new GenericRetry().setInitialInterval(RETRY_INTERVAL).withLinearRetry().setMaxAttempts(5);
- KubernetesClient k8sClient = new DefaultKubernetesClient();
- integrationTestSupport.initialize(k8sClient, new RetryTestCustomResourceController(), retry);
- integrationTestSupport.cleanup();
- }
+ @RegisterExtension
+ OperatorExtension operator =
+ OperatorExtension.builder()
+ .withConfigurationService(DefaultConfigurationService.instance())
+ .withController(
+ new RetryTestCustomResourceController(),
+ new GenericRetry().setInitialInterval(RETRY_INTERVAL).withLinearRetry()
+ .setMaxAttempts(5))
+ .build();
+
@Test
public void retryFailedExecution() {
- integrationTestSupport.teardownIfSuccess(
- () -> {
- RetryTestCustomResource resource = createTestCustomResource("1");
- integrationTestSupport.getCrOperations().inNamespace(TEST_NAMESPACE).create(resource);
+ RetryTestCustomResource resource = createTestCustomResource("1");
- Thread.sleep(
- RETRY_INTERVAL * (RetryTestCustomResourceController.NUMBER_FAILED_EXECUTIONS + 2));
+ operator.create(RetryTestCustomResource.class, resource);
- assertThat(integrationTestSupport.numberOfControllerExecutions())
- .isGreaterThanOrEqualTo(
- RetryTestCustomResourceController.NUMBER_FAILED_EXECUTIONS + 1);
+ await("cr status updated")
+ .pollDelay(
+ RETRY_INTERVAL * (RetryTestCustomResourceController.NUMBER_FAILED_EXECUTIONS + 2),
+ TimeUnit.MILLISECONDS)
+ .pollInterval(
+ RETRY_INTERVAL,
+ TimeUnit.MILLISECONDS)
+ .atMost(5, TimeUnit.SECONDS)
+ .untilAsserted(() -> {
+ assertThat(
+ TestUtils.getNumberOfExecutions(operator))
+ .isEqualTo(RetryTestCustomResourceController.NUMBER_FAILED_EXECUTIONS + 1);
RetryTestCustomResource finalResource =
- (RetryTestCustomResource) integrationTestSupport
- .getCrOperations()
- .inNamespace(TEST_NAMESPACE)
- .withName(resource.getMetadata().getName())
- .get();
+ operator.getNamedResource(RetryTestCustomResource.class,
+ resource.getMetadata().getName());
assertThat(finalResource.getStatus().getState())
.isEqualTo(RetryTestCustomResourceStatus.State.SUCCESS);
});
@@ -59,7 +62,6 @@ public RetryTestCustomResource createTestCustomResource(String id) {
resource.setMetadata(
new ObjectMetaBuilder()
.withName("retrysource-" + id)
- .withNamespace(TEST_NAMESPACE)
.withFinalizers(RetryTestCustomResourceController.FINALIZER_NAME)
.build());
resource.setKind("retrysample");
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java
index 0a7cbada4d..ac7fa95c86 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/SubResourceUpdateIT.java
@@ -1,81 +1,73 @@
package io.javaoperatorsdk.operator;
-import static io.javaoperatorsdk.operator.IntegrationTestSupport.TEST_NAMESPACE;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.awaitility.Awaitility.await;
+import io.javaoperatorsdk.operator.support.TestUtils;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
-import io.fabric8.kubernetes.client.DefaultKubernetesClient;
-import io.fabric8.kubernetes.client.KubernetesClient;
+import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService;
+import io.javaoperatorsdk.operator.junit.OperatorExtension;
import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResource;
import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceController;
import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceSpec;
import io.javaoperatorsdk.operator.sample.subresource.SubResourceTestCustomResourceStatus;
-import java.util.Collections;
-import java.util.concurrent.TimeUnit;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class SubResourceUpdateIT {
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
- private IntegrationTestSupport integrationTestSupport = new IntegrationTestSupport();
+public class SubResourceUpdateIT {
- @BeforeEach
- public void initAndCleanup() {
- KubernetesClient k8sClient = new DefaultKubernetesClient();
- integrationTestSupport.initialize(k8sClient, new SubResourceTestCustomResourceController());
- integrationTestSupport.cleanup();
- }
+ @RegisterExtension
+ OperatorExtension operator =
+ OperatorExtension.builder()
+ .withConfigurationService(DefaultConfigurationService.instance())
+ .withController(SubResourceTestCustomResourceController.class)
+ .build();
@Test
public void updatesSubResourceStatus() {
- integrationTestSupport.teardownIfSuccess(
- () -> {
- SubResourceTestCustomResource resource = createTestCustomResource("1");
- integrationTestSupport.getCrOperations().inNamespace(TEST_NAMESPACE).create(resource);
-
- awaitStatusUpdated(resource.getMetadata().getName());
- // wait for sure, there are no more events
- waitXms(200);
- // there is no event on status update processed
- assertThat(integrationTestSupport.numberOfControllerExecutions()).isEqualTo(2);
- });
+ SubResourceTestCustomResource resource = createTestCustomResource("1");
+ operator.create(SubResourceTestCustomResource.class, resource);
+
+ awaitStatusUpdated(resource.getMetadata().getName());
+ // wait for sure, there are no more events
+ waitXms(200);
+ // there is no event on status update processed
+ assertThat(TestUtils.getNumberOfExecutions(operator))
+ .isEqualTo(2);
}
@Test
public void updatesSubResourceStatusNoFinalizer() {
- integrationTestSupport.teardownIfSuccess(
- () -> {
- SubResourceTestCustomResource resource = createTestCustomResource("1");
- resource.getMetadata().setFinalizers(Collections.EMPTY_LIST);
-
- integrationTestSupport.getCrOperations().inNamespace(TEST_NAMESPACE).create(resource);
-
- awaitStatusUpdated(resource.getMetadata().getName());
- // wait for sure, there are no more events
- waitXms(200);
- // there is no event on status update processed
- assertThat(integrationTestSupport.numberOfControllerExecutions()).isEqualTo(2);
- });
+ SubResourceTestCustomResource resource = createTestCustomResource("1");
+ resource.getMetadata().setFinalizers(Collections.emptyList());
+
+ operator.create(SubResourceTestCustomResource.class, resource);
+
+ awaitStatusUpdated(resource.getMetadata().getName());
+ // wait for sure, there are no more events
+ waitXms(200);
+ // there is no event on status update processed
+ assertThat(TestUtils.getNumberOfExecutions(operator))
+ .isEqualTo(2);
}
/** Note that we check on controller impl if there is finalizer on execution. */
@Test
public void ifNoFinalizerPresentFirstAddsTheFinalizerThenExecutesControllerAgain() {
- integrationTestSupport.teardownIfSuccess(
- () -> {
- SubResourceTestCustomResource resource = createTestCustomResource("1");
- resource.getMetadata().getFinalizers().clear();
- integrationTestSupport.getCrOperations().inNamespace(TEST_NAMESPACE).create(resource);
-
- awaitStatusUpdated(resource.getMetadata().getName());
- // wait for sure, there are no more events
- waitXms(200);
- // there is no event on status update processed
- assertThat(integrationTestSupport.numberOfControllerExecutions()).isEqualTo(2);
- });
+ SubResourceTestCustomResource resource = createTestCustomResource("1");
+ resource.getMetadata().getFinalizers().clear();
+ operator.create(SubResourceTestCustomResource.class, resource);
+
+ awaitStatusUpdated(resource.getMetadata().getName());
+ // wait for sure, there are no more events
+ waitXms(200);
+ // there is no event on status update processed
+ assertThat(TestUtils.getNumberOfExecutions(operator))
+ .isEqualTo(2);
}
/**
@@ -86,24 +78,19 @@ public void ifNoFinalizerPresentFirstAddsTheFinalizerThenExecutesControllerAgain
*/
@Test
public void updateCustomResourceAfterSubResourceChange() {
- integrationTestSupport.teardownIfSuccess(
- () -> {
- SubResourceTestCustomResource resource = createTestCustomResource("1");
- integrationTestSupport.getCrOperations().inNamespace(TEST_NAMESPACE).create(resource);
-
- resource.getSpec().setValue("new value");
- integrationTestSupport
- .getCrOperations()
- .inNamespace(TEST_NAMESPACE)
- .createOrReplace(resource);
-
- awaitStatusUpdated(resource.getMetadata().getName());
-
- // wait for sure, there are no more events
- waitXms(200);
- // there is no event on status update processed
- assertThat(integrationTestSupport.numberOfControllerExecutions()).isEqualTo(3);
- });
+ SubResourceTestCustomResource resource = createTestCustomResource("1");
+ operator.create(SubResourceTestCustomResource.class, resource);
+
+ resource.getSpec().setValue("new value");
+ operator.resources(SubResourceTestCustomResource.class).createOrReplace(resource);
+
+ awaitStatusUpdated(resource.getMetadata().getName());
+
+ // wait for sure, there are no more events
+ waitXms(200);
+ // there is no event on status update processed
+ assertThat(TestUtils.getNumberOfExecutions(operator))
+ .isEqualTo(3);
}
void awaitStatusUpdated(String name) {
@@ -112,11 +99,7 @@ void awaitStatusUpdated(String name) {
.untilAsserted(
() -> {
SubResourceTestCustomResource cr =
- (SubResourceTestCustomResource) integrationTestSupport
- .getCrOperations()
- .inNamespace(TEST_NAMESPACE)
- .withName(name)
- .get();
+ operator.getNamedResource(SubResourceTestCustomResource.class, name);
assertThat(cr.getMetadata().getFinalizers()).hasSize(1);
assertThat(cr).isNotNull();
assertThat(cr.getStatus()).isNotNull();
@@ -130,7 +113,6 @@ public SubResourceTestCustomResource createTestCustomResource(String id) {
resource.setMetadata(
new ObjectMetaBuilder()
.withName("subresource-" + id)
- .withNamespace(TEST_NAMESPACE)
.withFinalizers(SubResourceTestCustomResourceController.FINALIZER_NAME)
.build());
resource.setKind("SubresourceSample");
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/UpdatingResAndSubResIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/UpdatingResAndSubResIT.java
index f29fb7c4f9..9d4e0fd30c 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/UpdatingResAndSubResIT.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/UpdatingResAndSubResIT.java
@@ -1,57 +1,54 @@
package io.javaoperatorsdk.operator;
-import static io.javaoperatorsdk.operator.IntegrationTestSupport.TEST_NAMESPACE;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.awaitility.Awaitility.await;
+import io.javaoperatorsdk.operator.support.TestUtils;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
-import io.fabric8.kubernetes.client.DefaultKubernetesClient;
-import io.fabric8.kubernetes.client.KubernetesClient;
+import io.javaoperatorsdk.operator.config.runtime.DefaultConfigurationService;
+import io.javaoperatorsdk.operator.junit.OperatorExtension;
import io.javaoperatorsdk.operator.sample.doubleupdate.DoubleUpdateTestCustomResource;
import io.javaoperatorsdk.operator.sample.doubleupdate.DoubleUpdateTestCustomResourceController;
import io.javaoperatorsdk.operator.sample.doubleupdate.DoubleUpdateTestCustomResourceSpec;
import io.javaoperatorsdk.operator.sample.doubleupdate.DoubleUpdateTestCustomResourceStatus;
-import java.util.concurrent.TimeUnit;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class UpdatingResAndSubResIT {
-
- private IntegrationTestSupport integrationTestSupport = new IntegrationTestSupport();
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
- @BeforeEach
- public void initAndCleanup() {
- KubernetesClient k8sClient = new DefaultKubernetesClient();
- integrationTestSupport.initialize(k8sClient, new DoubleUpdateTestCustomResourceController());
- integrationTestSupport.cleanup();
- }
+public class UpdatingResAndSubResIT {
+ @RegisterExtension
+ OperatorExtension operator =
+ OperatorExtension.builder()
+ .withConfigurationService(DefaultConfigurationService.instance())
+ .withController(DoubleUpdateTestCustomResourceController.class)
+ .build();
@Test
public void updatesSubResourceStatus() {
- integrationTestSupport.teardownIfSuccess(
- () -> {
- DoubleUpdateTestCustomResource resource = createTestCustomResource("1");
- integrationTestSupport.getCrOperations().inNamespace(TEST_NAMESPACE).create(resource);
+ DoubleUpdateTestCustomResource resource = createTestCustomResource("1");
+ operator.create(DoubleUpdateTestCustomResource.class, resource);
+
+ awaitStatusUpdated(resource.getMetadata().getName());
+ // wait for sure, there are no more events
+ TestUtils.waitXms(300);
- awaitStatusUpdated(resource.getMetadata().getName());
- // wait for sure, there are no more events
- TestUtils.waitXms(300);
+ DoubleUpdateTestCustomResource customResource =
+ operator
+ .getNamedResource(DoubleUpdateTestCustomResource.class,
+ resource.getMetadata().getName());
- DoubleUpdateTestCustomResource customResource =
- (DoubleUpdateTestCustomResource) integrationTestSupport
- .getCustomResource(resource.getMetadata().getName());
- assertThat(integrationTestSupport.numberOfControllerExecutions()).isEqualTo(1);
- assertThat(customResource.getStatus().getState())
- .isEqualTo(DoubleUpdateTestCustomResourceStatus.State.SUCCESS);
- assertThat(
- customResource
- .getMetadata()
- .getAnnotations()
- .get(DoubleUpdateTestCustomResourceController.TEST_ANNOTATION))
- .isNotNull();
- });
+ assertThat(TestUtils.getNumberOfExecutions(operator))
+ .isEqualTo(1);
+ assertThat(customResource.getStatus().getState())
+ .isEqualTo(DoubleUpdateTestCustomResourceStatus.State.SUCCESS);
+ assertThat(
+ customResource
+ .getMetadata()
+ .getAnnotations()
+ .get(DoubleUpdateTestCustomResourceController.TEST_ANNOTATION))
+ .isNotNull();
}
void awaitStatusUpdated(String name) {
@@ -60,14 +57,14 @@ void awaitStatusUpdated(String name) {
.untilAsserted(
() -> {
DoubleUpdateTestCustomResource cr =
- (DoubleUpdateTestCustomResource) integrationTestSupport
- .getCrOperations()
- .inNamespace(TEST_NAMESPACE)
- .withName(name)
- .get();
- assertThat(cr.getMetadata().getFinalizers()).hasSize(1);
- assertThat(cr).isNotNull();
- assertThat(cr.getStatus()).isNotNull();
+ operator.getNamedResource(DoubleUpdateTestCustomResource.class, name);
+
+ assertThat(cr)
+ .isNotNull();
+ assertThat(cr.getMetadata().getFinalizers())
+ .hasSize(1);
+ assertThat(cr.getStatus())
+ .isNotNull();
assertThat(cr.getStatus().getState())
.isEqualTo(DoubleUpdateTestCustomResourceStatus.State.SUCCESS);
});
@@ -75,11 +72,7 @@ void awaitStatusUpdated(String name) {
public DoubleUpdateTestCustomResource createTestCustomResource(String id) {
DoubleUpdateTestCustomResource resource = new DoubleUpdateTestCustomResource();
- resource.setMetadata(
- new ObjectMetaBuilder()
- .withName("doubleupdateresource-" + id)
- .withNamespace(TEST_NAMESPACE)
- .build());
+ resource.setMetadata(new ObjectMetaBuilder().withName("doubleupdateresource-" + id).build());
resource.setKind("DoubleUpdateSample");
resource.setSpec(new DoubleUpdateTestCustomResourceSpec());
resource.getSpec().setValue(id);
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java
index b0205bd4ef..0252ae8ac1 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java
@@ -28,6 +28,8 @@ public class DefaultConfigurationServiceTest {
@Test
void attemptingToRetrieveAnUnknownControllerShouldLogWarning() {
+ final var configurationService = DefaultConfigurationService.instance();
+
final LoggerContext context = LoggerContext.getContext(false);
final PatternLayout layout = PatternLayout.createDefaultLayout(context.getConfiguration());
final ListAppender appender = new ListAppender("list", null, layout, false, false);
@@ -37,11 +39,12 @@ void attemptingToRetrieveAnUnknownControllerShouldLogWarning() {
context.getConfiguration().addAppender(appender);
AppenderRef ref = AppenderRef.createAppenderRef("list", null, null);
+ final var loggerName = configurationService.getLoggerName();
LoggerConfig loggerConfig =
LoggerConfig.createLogger(
false,
Level.valueOf("info"),
- AbstractConfigurationService.LOGGER_NAME,
+ loggerName,
"false",
new AppenderRef[] {ref},
null,
@@ -49,12 +52,12 @@ void attemptingToRetrieveAnUnknownControllerShouldLogWarning() {
null);
loggerConfig.addAppender(appender, null, null);
- context.getConfiguration().addLogger(AbstractConfigurationService.LOGGER_NAME, loggerConfig);
+ context.getConfiguration().addLogger(loggerName, loggerConfig);
context.updateLoggers();
try {
final var config =
- DefaultConfigurationService.instance()
+ configurationService
.getConfigurationFor(new NotAutomaticallyCreated(), false);
assertThat(config).isNull();
@@ -64,7 +67,7 @@ void attemptingToRetrieveAnUnknownControllerShouldLogWarning() {
} finally {
appender.stop();
- context.getConfiguration().removeLogger(AbstractConfigurationService.LOGGER_NAME);
+ context.getConfiguration().removeLogger(loggerName);
context.updateLoggers();
}
}
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java
index e3959681d9..37dcec276c 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java
@@ -1,6 +1,6 @@
package io.javaoperatorsdk.operator.sample.doubleupdate;
-import io.javaoperatorsdk.operator.TestExecutionInfoProvider;
+import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider;
import io.javaoperatorsdk.operator.api.*;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java
index 7f42429b5f..394b78bc94 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java
@@ -2,7 +2,7 @@
import io.fabric8.kubernetes.client.CustomResource;
import io.javaoperatorsdk.operator.ControllerUtils;
-import io.javaoperatorsdk.operator.TestExecutionInfoProvider;
+import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider;
import io.javaoperatorsdk.operator.api.Context;
import io.javaoperatorsdk.operator.api.Controller;
import io.javaoperatorsdk.operator.api.ResourceController;
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java
index 512a0a55a4..847f247872 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java
@@ -2,7 +2,7 @@
import io.fabric8.kubernetes.client.CustomResource;
import io.javaoperatorsdk.operator.ControllerUtils;
-import io.javaoperatorsdk.operator.TestExecutionInfoProvider;
+import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider;
import io.javaoperatorsdk.operator.api.Context;
import io.javaoperatorsdk.operator.api.Controller;
import io.javaoperatorsdk.operator.api.ResourceController;
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java
index 0ca5413f31..e26b629a74 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java
@@ -6,12 +6,13 @@
import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.javaoperatorsdk.operator.ControllerUtils;
-import io.javaoperatorsdk.operator.TestExecutionInfoProvider;
+import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider;
import io.javaoperatorsdk.operator.api.Context;
import io.javaoperatorsdk.operator.api.Controller;
import io.javaoperatorsdk.operator.api.DeleteControl;
import io.javaoperatorsdk.operator.api.ResourceController;
import io.javaoperatorsdk.operator.api.UpdateControl;
+import io.javaoperatorsdk.operator.junit.KubernetesClientAware;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
@@ -20,26 +21,44 @@
@Controller(generationAwareEventProcessing = false)
public class TestCustomResourceController
- implements ResourceController, TestExecutionInfoProvider {
+ implements ResourceController, TestExecutionInfoProvider,
+ KubernetesClientAware {
private static final Logger log = LoggerFactory.getLogger(TestCustomResourceController.class);
public static final String FINALIZER_NAME =
ControllerUtils.getDefaultFinalizerName(CustomResource.getCRDName(TestCustomResource.class));
- private final KubernetesClient kubernetesClient;
- private final boolean updateStatus;
private final AtomicInteger numberOfExecutions = new AtomicInteger(0);
+ private KubernetesClient kubernetesClient;
+ private boolean updateStatus;
- public TestCustomResourceController(KubernetesClient kubernetesClient) {
- this(kubernetesClient, true);
+ public TestCustomResourceController() {
+ this(true);
}
- public TestCustomResourceController(KubernetesClient kubernetesClient, boolean updateStatus) {
- this.kubernetesClient = kubernetesClient;
+ public TestCustomResourceController(boolean updateStatus) {
this.updateStatus = updateStatus;
}
+ public boolean isUpdateStatus() {
+ return updateStatus;
+ }
+
+ public void setUpdateStatus(boolean updateStatus) {
+ this.updateStatus = updateStatus;
+ }
+
+ @Override
+ public KubernetesClient getKubernetesClient() {
+ return kubernetesClient;
+ }
+
+ @Override
+ public void setKubernetesClient(KubernetesClient kubernetesClient) {
+ this.kubernetesClient = kubernetesClient;
+ }
+
@Override
public DeleteControl deleteResource(
TestCustomResource resource, Context context) {
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java
index 50f0285b22..8084ad7cfc 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java
@@ -2,7 +2,7 @@
import io.fabric8.kubernetes.client.CustomResource;
import io.javaoperatorsdk.operator.ControllerUtils;
-import io.javaoperatorsdk.operator.TestExecutionInfoProvider;
+import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider;
import io.javaoperatorsdk.operator.api.Context;
import io.javaoperatorsdk.operator.api.Controller;
import io.javaoperatorsdk.operator.api.ResourceController;
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/TestExecutionInfoProvider.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/support/TestExecutionInfoProvider.java
similarity index 64%
rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/TestExecutionInfoProvider.java
rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/support/TestExecutionInfoProvider.java
index caf0211df4..f2f634041d 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/TestExecutionInfoProvider.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/support/TestExecutionInfoProvider.java
@@ -1,4 +1,4 @@
-package io.javaoperatorsdk.operator;
+package io.javaoperatorsdk.operator.support;
public interface TestExecutionInfoProvider {
diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/TestUtils.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/support/TestUtils.java
similarity index 60%
rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/TestUtils.java
rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/support/TestUtils.java
index 2029970f0f..76ae1c4991 100644
--- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/TestUtils.java
+++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/support/TestUtils.java
@@ -1,6 +1,7 @@
-package io.javaoperatorsdk.operator;
+package io.javaoperatorsdk.operator.support;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
+import io.javaoperatorsdk.operator.junit.OperatorExtension;
import io.javaoperatorsdk.operator.sample.simple.TestCustomResource;
import io.javaoperatorsdk.operator.sample.simple.TestCustomResourceSpec;
import java.util.HashMap;
@@ -8,6 +9,7 @@
public class TestUtils {
+ public static final String TEST_CUSTOM_RESOURCE_PREFIX = "test-custom-resource-";
public static final String TEST_CUSTOM_RESOURCE_NAME = "test-custom-resource";
public static final String TEST_NAMESPACE = "java-operator-sdk-int-test";
@@ -22,7 +24,6 @@ public static TestCustomResource testCustomResource(String uid) {
.withName(TEST_CUSTOM_RESOURCE_NAME)
.withUid(uid)
.withGeneration(1L)
- .withNamespace(TEST_NAMESPACE)
.build());
resource.getMetadata().setAnnotations(new HashMap<>());
resource.setKind("CustomService");
@@ -33,6 +34,20 @@ public static TestCustomResource testCustomResource(String uid) {
return resource;
}
+ public static TestCustomResource testCustomResourceWithPrefix(String id) {
+ TestCustomResource resource = new TestCustomResource();
+ resource.setMetadata(
+ new ObjectMetaBuilder()
+ .withName(TEST_CUSTOM_RESOURCE_PREFIX + id)
+ .build());
+ resource.setKind("CustomService");
+ resource.setSpec(new TestCustomResourceSpec());
+ resource.getSpec().setConfigMapName("test-config-map-" + id);
+ resource.getSpec().setKey("test-key");
+ resource.getSpec().setValue(id);
+ return resource;
+ }
+
public static void waitXms(int x) {
try {
Thread.sleep(x);
@@ -40,4 +55,8 @@ public static void waitXms(int x) {
throw new IllegalStateException(e);
}
}
+
+ public static int getNumberOfExecutions(OperatorExtension extension) {
+ return ((TestExecutionInfoProvider) extension.getControllers().get(0)).getNumberOfExecutions();
+ }
}
diff --git a/pom.xml b/pom.xml
index 18914e47c7..901dd73ee4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,6 +74,7 @@
operator-framework-core
+ operator-framework-junit5
operator-framework
samples
@@ -202,6 +203,9 @@
org.apache.maven.plugins
maven-surefire-plugin
${maven-surefire-plugin.version}
+
+ 3
+
org.apache.maven.plugins