diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java index 773bb0332f..e437d58a27 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java @@ -149,7 +149,10 @@ protected void doRun(DependentResourceNode<R, P> dependentResourceNode, DependentResource<R, P> dependentResource) { var deletePostCondition = dependentResourceNode.getDeletePostcondition(); - if (dependentResource.isDeletable()) { + // GarbageCollected status is irrelevant here, as this method is only called when a + // precondition does not hold, + // a deleter should be deleted even if it is otherwise garbage collected + if (dependentResource instanceof Deleter) { ((Deleter<P>) dependentResource).delete(primary, context); } boolean deletePostConditionMet = isConditionMet(deletePostCondition, dependentResource); diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/AbstractWorkflowExecutorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/AbstractWorkflowExecutorTest.java index 467820940d..e8b26184c4 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/AbstractWorkflowExecutorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/AbstractWorkflowExecutorTest.java @@ -22,6 +22,7 @@ public class AbstractWorkflowExecutorTest { protected TestDeleterDependent drDeleter = new TestDeleterDependent("DR_DELETER"); protected TestErrorDependent drError = new TestErrorDependent("ERROR_1"); protected TestErrorDeleterDependent errorDD = new TestErrorDeleterDependent("ERROR_DELETER"); + protected GarbageCollectedDeleter gcDeleter = new GarbageCollectedDeleter("GC_DELETER"); @SuppressWarnings("rawtypes") protected final Condition noMetDeletePostCondition = (primary, secondary, context) -> false; diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutorTest.java index 9aa2fb07e9..a8e46fc258 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowCleanupExecutorTest.java @@ -117,15 +117,14 @@ void cleanupConditionDiamondWorkflow() { @Test void dontDeleteIfGarbageCollected() { - GarbageCollectedDeleter gcDel = new GarbageCollectedDeleter("GC_DELETER"); var workflow = new WorkflowBuilder<TestCustomResource>() - .addDependentResource(gcDel) + .addDependentResource(gcDeleter) .build(); var res = workflow.cleanup(new TestCustomResource(), null); assertThat(executionHistory) - .notReconciled(gcDel); + .notReconciled(gcDeleter); Assertions.assertThat(res.getDeleteCalledOnDependents()).isEmpty(); } diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutorTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutorTest.java index a445dc783f..96de59ce5b 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutorTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutorTest.java @@ -453,4 +453,29 @@ void diamondShareWithReadyCondition() { Assertions.assertThat(res.getNotReadyDependents()).containsExactlyInAnyOrder(dr2); } + @Test + void garbageCollectedResourceIsDeletedIfReconcilePreconditionDoesNotHold() { + var workflow = new WorkflowBuilder<TestCustomResource>() + .addDependentResource(gcDeleter).withReconcilePrecondition(not_met_reconcile_condition) + .build(); + + var res = workflow.reconcile(new TestCustomResource(), mockContext); + + Assertions.assertThat(res.getErroredDependents()).isEmpty(); + assertThat(executionHistory).deleted(gcDeleter); + } + + @Test + void garbageCollectedDeepResourceIsDeletedIfReconcilePreconditionDoesNotHold() { + var workflow = new WorkflowBuilder<TestCustomResource>() + .addDependentResource(dr1).withReconcilePrecondition(not_met_reconcile_condition) + .addDependentResource(gcDeleter).dependsOn(dr1) + .build(); + + var res = workflow.reconcile(new TestCustomResource(), mockContext); + + Assertions.assertThat(res.getErroredDependents()).isEmpty(); + assertThat(executionHistory).deleted(gcDeleter); + } + }