From 204ac34315da628d293dc9411f14c0d3c9ec01fe Mon Sep 17 00:00:00 2001 From: Robert Young Date: Mon, 18 Nov 2024 12:30:43 +1300 Subject: [PATCH 1/4] refactor: add unit tests for DefaultManagedDependentResourceContext Signed-off-by: Robert Young --- ...ltManagedDependentResourceContextTest.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java new file mode 100644 index 0000000000..cd2c0716d1 --- /dev/null +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java @@ -0,0 +1,84 @@ +package io.javaoperatorsdk.operator.api.reconciler.dependent.managed; + +import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowReconcileResult; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DefaultManagedDependentResourceContext.RECONCILE_RESULT_KEY; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class DefaultManagedDependentResourceContextTest { + + private ManagedDependentResourceContext context = new DefaultManagedDependentResourceContext(); + + @Test + void getWhenEmpty() { + Optional actual = context.get("key", String.class); + assertThat(actual).isEmpty(); + } + + @Test + void get() { + context.put("key", "value"); + Optional actual = context.get("key", String.class); + assertThat(actual).contains("value"); + } + + @Test + void putNewValueOverwrites() { + context.put("key", "value"); + context.put("key", "valueB"); + Optional actual = context.get("key", String.class); + assertThat(actual).contains("valueB"); + } + + @Test + void putNewValueReturnsPriorValue() { + context.put("key", "value"); + Optional actual = (Optional) (Object)context.put("key", "valueB"); + assertThat(actual).contains("value"); + } + + @Test + void putNullRemoves() { + context.put("key", "value"); + context.put("key", null); + Optional actual = context.get("key", String.class); + assertThat(actual).isEmpty(); + } + + @Test + void putNullReturnsPriorValue() { + context.put("key", "value"); + Optional actual = context.put("key", null); + assertThat(actual).contains("value"); + } + + @Test + void getMandatory() { + context.put("key", "value"); + String actual = context.getMandatory("key", String.class); + assertThat(actual).isEqualTo("value"); + } + + @Test + void getMandatoryWhenEmpty() { + assertThatThrownBy(() -> { + context.getMandatory("key", String.class); + }).isInstanceOf(IllegalStateException.class) + .hasMessage("Mandatory attribute (key: key, type: java.lang.String) is missing or not of the expected type"); + } + + @Test + void getWorkflowReconcileResult() { + WorkflowReconcileResult result = new WorkflowReconcileResult(List.of(), List.of(), Map.of(), Map.of()); + context.put(RECONCILE_RESULT_KEY, result); + Optional actual = context.getWorkflowReconcileResult(); + assertThat(actual).containsSame(result); + } + +} \ No newline at end of file From d492ff60c39c887d3c7aaebfe6f9a66532e5d8a3 Mon Sep 17 00:00:00 2001 From: Robert Young Date: Tue, 19 Nov 2024 14:27:11 +1300 Subject: [PATCH 2/4] refactor: add putOrRemove to DefaultManagedDependentResourceContext The javadoc of the existing put method states that it returns Optional. The implementation also returns Optional, but the method signature declares it returns T. Meaning the caller has to cast it to Optional to get at the return value. This new method will supercede the existing put method Signed-off-by: Robert Young --- ...efaultManagedDependentResourceContext.java | 9 + .../ManagedDependentResourceContext.java | 15 ++ ...ltManagedDependentResourceContextTest.java | 177 +++++++++++------- 3 files changed, 129 insertions(+), 72 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java index 61414468c8..d1ccb8eb28 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java @@ -28,6 +28,15 @@ public T put(Object key, T value) { return (T) Optional.ofNullable(attributes.put(key, value)); } + @Override + @SuppressWarnings("unchecked") + public Optional putOrRemove(Object key, T value) { + if (value == null) { + return (Optional) Optional.ofNullable(attributes.remove(key)); + } + return (Optional) Optional.ofNullable(attributes.put(key, value)); + } + @Override @SuppressWarnings("unused") public T getMandatory(Object key, Class expectedType) { diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java index 9c5b3dddb1..dde9d5ee4d 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java @@ -40,6 +40,21 @@ public interface ManagedDependentResourceContext { @SuppressWarnings("unchecked") T put(Object key, T value); + /** + * Associates the specified contextual value to the specified key. If the value is {@code null}, + * the semantics of this operation is defined as removing the mapping associated with the + * specified key. + * + * @param object type + * @param key the key identifying which contextual object to add or remove from the context + * @param value the value to add to the context or {@code null} to remove an existing entry + * associated with the specified key + * @return an Optional containing the previous value associated with the key or + * {@link Optional#empty()} if none existed + */ + @SuppressWarnings("unchecked") + Optional putOrRemove(Object key, T value); + /** * Retrieves the value associated with the key or fail with an exception if none exists. * diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java index cd2c0716d1..67c3addd79 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java @@ -1,84 +1,117 @@ package io.javaoperatorsdk.operator.api.reconciler.dependent.managed; -import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowReconcileResult; -import org.junit.jupiter.api.Test; - import java.util.List; import java.util.Map; import java.util.Optional; +import org.junit.jupiter.api.Test; + +import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowReconcileResult; + import static io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DefaultManagedDependentResourceContext.RECONCILE_RESULT_KEY; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; class DefaultManagedDependentResourceContextTest { - private ManagedDependentResourceContext context = new DefaultManagedDependentResourceContext(); - - @Test - void getWhenEmpty() { - Optional actual = context.get("key", String.class); - assertThat(actual).isEmpty(); - } - - @Test - void get() { - context.put("key", "value"); - Optional actual = context.get("key", String.class); - assertThat(actual).contains("value"); - } - - @Test - void putNewValueOverwrites() { - context.put("key", "value"); - context.put("key", "valueB"); - Optional actual = context.get("key", String.class); - assertThat(actual).contains("valueB"); - } - - @Test - void putNewValueReturnsPriorValue() { - context.put("key", "value"); - Optional actual = (Optional) (Object)context.put("key", "valueB"); - assertThat(actual).contains("value"); - } - - @Test - void putNullRemoves() { - context.put("key", "value"); - context.put("key", null); - Optional actual = context.get("key", String.class); - assertThat(actual).isEmpty(); - } - - @Test - void putNullReturnsPriorValue() { - context.put("key", "value"); - Optional actual = context.put("key", null); - assertThat(actual).contains("value"); - } - - @Test - void getMandatory() { - context.put("key", "value"); - String actual = context.getMandatory("key", String.class); - assertThat(actual).isEqualTo("value"); - } - - @Test - void getMandatoryWhenEmpty() { - assertThatThrownBy(() -> { - context.getMandatory("key", String.class); - }).isInstanceOf(IllegalStateException.class) - .hasMessage("Mandatory attribute (key: key, type: java.lang.String) is missing or not of the expected type"); - } - - @Test - void getWorkflowReconcileResult() { - WorkflowReconcileResult result = new WorkflowReconcileResult(List.of(), List.of(), Map.of(), Map.of()); - context.put(RECONCILE_RESULT_KEY, result); - Optional actual = context.getWorkflowReconcileResult(); - assertThat(actual).containsSame(result); - } - -} \ No newline at end of file + private ManagedDependentResourceContext context = new DefaultManagedDependentResourceContext(); + + @Test + void getWhenEmpty() { + Optional actual = context.get("key", String.class); + assertThat(actual).isEmpty(); + } + + @Test + void get() { + context.put("key", "value"); + Optional actual = context.get("key", String.class); + assertThat(actual).contains("value"); + } + + @Test + void putNewValueOverwrites() { + context.put("key", "value"); + context.put("key", "valueB"); + Optional actual = context.get("key", String.class); + assertThat(actual).contains("valueB"); + } + + @Test + void putOrRemoveNewValueOverwrites() { + context.putOrRemove("key", "value"); + context.putOrRemove("key", "valueB"); + Optional actual = context.get("key", String.class); + assertThat(actual).contains("valueB"); + } + + @Test + void putNewValueReturnsPriorValue() { + context.put("key", "value"); + Optional actual = (Optional) (Object) context.put("key", "valueB"); + assertThat(actual).contains("value"); + } + + @Test + void putOrRemoveNewValueReturnsPriorValue() { + context.put("key", "value"); + Optional actual = context.putOrRemove("key", "valueB"); + assertThat(actual).contains("value"); + } + + @Test + void putNullRemoves() { + context.put("key", "value"); + context.put("key", null); + Optional actual = context.get("key", String.class); + assertThat(actual).isEmpty(); + } + + @Test + void putOrRemoveNullRemoves() { + context.putOrRemove("key", "value"); + context.putOrRemove("key", null); + Optional actual = context.get("key", String.class); + assertThat(actual).isEmpty(); + } + + @Test + void putNullReturnsPriorValue() { + context.put("key", "value"); + Optional actual = context.put("key", null); + assertThat(actual).contains("value"); + } + + @Test + void putOrRemoveNullReturnsPriorValue() { + context.putOrRemove("key", "value"); + Optional actual = context.putOrRemove("key", null); + assertThat(actual).contains("value"); + } + + @Test + void getMandatory() { + context.put("key", "value"); + String actual = context.getMandatory("key", String.class); + assertThat(actual).isEqualTo("value"); + } + + @Test + void getMandatoryWhenEmpty() { + assertThatThrownBy(() -> { + context.getMandatory("key", String.class); + }).isInstanceOf(IllegalStateException.class) + .hasMessage( + "Mandatory attribute (key: key, type: java.lang.String) is missing or not of the expected type"); + } + + @Test + void getWorkflowReconcileResult() { + WorkflowReconcileResult result = + new WorkflowReconcileResult(List.of(), List.of(), Map.of(), Map.of()); + context.put(RECONCILE_RESULT_KEY, result); + Optional actual = context.getWorkflowReconcileResult(); + assertThat(actual).containsSame(result); + } + +} From 73688b8e2bd6882a2b78f3841c6b6bbe910b9f82 Mon Sep 17 00:00:00 2001 From: Robert Young Date: Tue, 19 Nov 2024 14:32:29 +1300 Subject: [PATCH 3/4] refactor: deprecate ManagedDependentResourceContext#put The javadoc declares it returns Optional and the implementation returns Optional, but the method declares it returns T. put is replaced by putOrRemove with a consistent signature. Signed-off-by: Robert Young --- .../managed/DefaultManagedDependentResourceContext.java | 6 ++---- .../dependent/managed/ManagedDependentResourceContext.java | 3 ++- .../processing/dependent/workflow/DefaultWorkflow.java | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java index d1ccb8eb28..1f33a13cb1 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java @@ -21,11 +21,9 @@ public Optional get(Object key, Class expectedType) { @Override @SuppressWarnings("unchecked") + @Deprecated(forRemoval = true) public T put(Object key, T value) { - if (value == null) { - return (T) Optional.ofNullable(attributes.remove(key)); - } - return (T) Optional.ofNullable(attributes.put(key, value)); + return (T) putOrRemove(key, value); } @Override diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java index dde9d5ee4d..1a3ad7b4ae 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java @@ -36,8 +36,10 @@ public interface ManagedDependentResourceContext { * associated with the specified key * @return an Optional containing the previous value associated with the key or * {@link Optional#empty()} if none existed + * @deprecated use {@link #putOrRemove(Object, Object)} instead */ @SuppressWarnings("unchecked") + @Deprecated(forRemoval = true) T put(Object key, T value); /** @@ -52,7 +54,6 @@ public interface ManagedDependentResourceContext { * @return an Optional containing the previous value associated with the key or * {@link Optional#empty()} if none existed */ - @SuppressWarnings("unchecked") Optional putOrRemove(Object key, T value); /** diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DefaultWorkflow.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DefaultWorkflow.java index 056b5906a0..6e1f0735a2 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DefaultWorkflow.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DefaultWorkflow.java @@ -93,7 +93,7 @@ public WorkflowReconcileResult reconcile(P primary, Context

context) { new WorkflowReconcileExecutor<>(this, primary, context); var result = workflowReconcileExecutor.reconcile(); context.managedDependentResourceContext() - .put(DefaultManagedDependentResourceContext.RECONCILE_RESULT_KEY, result); + .putOrRemove(DefaultManagedDependentResourceContext.RECONCILE_RESULT_KEY, result); if (throwExceptionAutomatically) { result.throwAggregateExceptionIfErrorsPresent(); } @@ -106,7 +106,7 @@ public WorkflowCleanupResult cleanup(P primary, Context

context) { new WorkflowCleanupExecutor<>(this, primary, context); var result = workflowCleanupExecutor.cleanup(); context.managedDependentResourceContext() - .put(DefaultManagedDependentResourceContext.CLEANUP_RESULT_KEY, result); + .putOrRemove(DefaultManagedDependentResourceContext.CLEANUP_RESULT_KEY, result); if (throwExceptionAutomatically) { result.throwAggregateExceptionIfErrorsPresent(); } From e3929245e253aaf8c9b0d4c8610282d15c1ebf04 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Tue, 19 Nov 2024 16:28:21 +0100 Subject: [PATCH 4/4] fix: implementation of put should return value instead of Optional Signed-off-by: Chris Laprun --- ...efaultManagedDependentResourceContext.java | 32 +++++++---- .../ManagedDependentResourceContext.java | 31 +++++------ .../dependent/workflow/DefaultWorkflow.java | 4 +- ...ltManagedDependentResourceContextTest.java | 53 ++++++++----------- 4 files changed, 58 insertions(+), 62 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java index 1f33a13cb1..84f7cfd03b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContext.java @@ -3,11 +3,16 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowCleanupResult; import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowReconcileResult; @SuppressWarnings("rawtypes") public class DefaultManagedDependentResourceContext implements ManagedDependentResourceContext { + private static final Logger log = + LoggerFactory.getLogger(DefaultManagedDependentResourceContext.class); public static final Object RECONCILE_RESULT_KEY = new Object(); public static final Object CLEANUP_RESULT_KEY = new Object(); private final ConcurrentHashMap attributes = new ConcurrentHashMap(); @@ -21,18 +26,27 @@ public Optional get(Object key, Class expectedType) { @Override @SuppressWarnings("unchecked") - @Deprecated(forRemoval = true) public T put(Object key, T value) { - return (T) putOrRemove(key, value); - } - - @Override - @SuppressWarnings("unchecked") - public Optional putOrRemove(Object key, T value) { + Object previous; if (value == null) { - return (Optional) Optional.ofNullable(attributes.remove(key)); + return (T) attributes.remove(key); + } else { + previous = attributes.put(key, value); } - return (Optional) Optional.ofNullable(attributes.put(key, value)); + + if (previous != null && !previous.getClass().isAssignableFrom(value.getClass())) { + logWarning("Previous value (" + previous + + ") for key (" + key + + ") was not of type " + value.getClass() + + ". This might indicate an issue in your code. If not, use put(" + key + + ", null) first to remove the previous value."); + } + return (T) previous; + } + + // only for testing purposes + void logWarning(String message) { + log.warn(message); } @Override diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java index 1a3ad7b4ae..074f7776f4 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/ManagedDependentResourceContext.java @@ -30,31 +30,24 @@ public interface ManagedDependentResourceContext { * the semantics of this operation is defined as removing the mapping associated with the * specified key. * - * @param object type - * @param key the key identifying which contextual object to add or remove from the context - * @param value the value to add to the context or {@code null} to remove an existing entry - * associated with the specified key - * @return an Optional containing the previous value associated with the key or - * {@link Optional#empty()} if none existed - * @deprecated use {@link #putOrRemove(Object, Object)} instead - */ - @SuppressWarnings("unchecked") - @Deprecated(forRemoval = true) - T put(Object key, T value); - - /** - * Associates the specified contextual value to the specified key. If the value is {@code null}, - * the semantics of this operation is defined as removing the mapping associated with the - * specified key. + *

+ * Note that, while implementations shouldn't throw a {@link ClassCastException} when the new + * value type differs from the type of the existing value, calling sites might encounter such + * exceptions if they bind the return value to a specific type. Users are either expected to + * disregard the return value (most common case) or "reset" the value type associated with the + * specified key by first calling {@code put(key, null)} if they want to ensure some level of type + * safety in their code (where attempting to store values of different types under the same key + * might be indicative of an issue). + *

* * @param object type * @param key the key identifying which contextual object to add or remove from the context * @param value the value to add to the context or {@code null} to remove an existing entry * associated with the specified key - * @return an Optional containing the previous value associated with the key or - * {@link Optional#empty()} if none existed + * @return the previous value if one was associated with the specified key, {@code null} + * otherwise. */ - Optional putOrRemove(Object key, T value); + T put(Object key, T value); /** * Retrieves the value associated with the key or fail with an exception if none exists. diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DefaultWorkflow.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DefaultWorkflow.java index 6e1f0735a2..056b5906a0 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DefaultWorkflow.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/DefaultWorkflow.java @@ -93,7 +93,7 @@ public WorkflowReconcileResult reconcile(P primary, Context

context) { new WorkflowReconcileExecutor<>(this, primary, context); var result = workflowReconcileExecutor.reconcile(); context.managedDependentResourceContext() - .putOrRemove(DefaultManagedDependentResourceContext.RECONCILE_RESULT_KEY, result); + .put(DefaultManagedDependentResourceContext.RECONCILE_RESULT_KEY, result); if (throwExceptionAutomatically) { result.throwAggregateExceptionIfErrorsPresent(); } @@ -106,7 +106,7 @@ public WorkflowCleanupResult cleanup(P primary, Context

context) { new WorkflowCleanupExecutor<>(this, primary, context); var result = workflowCleanupExecutor.cleanup(); context.managedDependentResourceContext() - .putOrRemove(DefaultManagedDependentResourceContext.CLEANUP_RESULT_KEY, result); + .put(DefaultManagedDependentResourceContext.CLEANUP_RESULT_KEY, result); if (throwExceptionAutomatically) { result.throwAggregateExceptionIfErrorsPresent(); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java index 67c3addd79..10e9e029ab 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/dependent/managed/DefaultManagedDependentResourceContextTest.java @@ -14,7 +14,8 @@ class DefaultManagedDependentResourceContextTest { - private ManagedDependentResourceContext context = new DefaultManagedDependentResourceContext(); + private final ManagedDependentResourceContext context = + new DefaultManagedDependentResourceContext(); @Test void getWhenEmpty() { @@ -37,26 +38,29 @@ void putNewValueOverwrites() { assertThat(actual).contains("valueB"); } - @Test - void putOrRemoveNewValueOverwrites() { - context.putOrRemove("key", "value"); - context.putOrRemove("key", "valueB"); - Optional actual = context.get("key", String.class); - assertThat(actual).contains("valueB"); - } - @Test void putNewValueReturnsPriorValue() { - context.put("key", "value"); - Optional actual = (Optional) (Object) context.put("key", "valueB"); - assertThat(actual).contains("value"); + final var prior = "value"; + context.put("key", prior); + String actual = context.put("key", "valueB"); + assertThat(actual).isEqualTo(prior); } @Test - void putOrRemoveNewValueReturnsPriorValue() { - context.put("key", "value"); - Optional actual = context.putOrRemove("key", "valueB"); - assertThat(actual).contains("value"); + void putNewValueThrowsExceptionIfTypesDiffer() { + // to check that we properly log things without setting up a complex fixture + final String[] messages = new String[1]; + var context = new DefaultManagedDependentResourceContext() { + @Override + void logWarning(String message) { + messages[0] = message; + } + }; + final var prior = "value"; + final var key = "key"; + context.put(key, prior); + context.put(key, 10); + assertThat(messages[0]).contains(key).contains(prior).contains("put(" + key + ", null)"); } @Test @@ -67,25 +71,11 @@ void putNullRemoves() { assertThat(actual).isEmpty(); } - @Test - void putOrRemoveNullRemoves() { - context.putOrRemove("key", "value"); - context.putOrRemove("key", null); - Optional actual = context.get("key", String.class); - assertThat(actual).isEmpty(); - } @Test void putNullReturnsPriorValue() { context.put("key", "value"); - Optional actual = context.put("key", null); - assertThat(actual).contains("value"); - } - - @Test - void putOrRemoveNullReturnsPriorValue() { - context.putOrRemove("key", "value"); - Optional actual = context.putOrRemove("key", null); + String actual = context.put("key", null); assertThat(actual).contains("value"); } @@ -113,5 +103,4 @@ void getWorkflowReconcileResult() { Optional actual = context.getWorkflowReconcileResult(); assertThat(actual).containsSame(result); } - }