Skip to content

Commit 773d49b

Browse files
committed
fix: delete CRD only after all tests in the class pass
Signed-off-by: xstefank <xstefank122@gmail.com>
1 parent 62e09c5 commit 773d49b

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
4343
import io.fabric8.kubernetes.client.CustomResource;
4444
import io.fabric8.kubernetes.client.KubernetesClient;
45+
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
4546
import io.fabric8.kubernetes.client.LocalPortForward;
4647
import io.javaoperatorsdk.operator.Operator;
4748
import io.javaoperatorsdk.operator.ReconcilerUtilsInternal;
@@ -349,6 +350,13 @@ protected void before(ExtensionContext context) {
349350
beforeStartHook.accept(this);
350351
}
351352

353+
// ExtensionContext.Store.CloseableResource registered in the class-level (parent) context
354+
// is invoked by JUnit when the class scope closes
355+
var classContext = oneNamespacePerClass ? context : context.getParent().orElse(context);
356+
classContext
357+
.getStore(ExtensionContext.Namespace.create(LocallyRunOperatorExtension.class))
358+
.computeIfAbsent(CrdCleanup.class, ignored -> new CrdCleanup());
359+
352360
LOGGER.debug("Starting the operator locally");
353361
this.operator.start();
354362
}
@@ -357,18 +365,12 @@ protected void before(ExtensionContext context) {
357365
protected void after(ExtensionContext context) {
358366
super.after(context);
359367

360-
var kubernetesClient = getInfrastructureKubernetesClient();
361-
362-
var iterator = appliedCRDs.iterator();
363-
while (iterator.hasNext()) {
364-
deleteCrd(iterator.next(), kubernetesClient);
365-
iterator.remove();
366-
}
368+
var infrastructureKubernetesClient = getInfrastructureKubernetesClient();
367369

368370
// if the client is used for infra client, we should not close it
369371
// either test or operator should close this client
370-
if (getKubernetesClient() != getInfrastructureKubernetesClient()) {
371-
kubernetesClient.close();
372+
if (getKubernetesClient() != infrastructureKubernetesClient) {
373+
infrastructureKubernetesClient.close();
372374
}
373375

374376
try {
@@ -387,12 +389,27 @@ protected void after(ExtensionContext context) {
387389
localPortForwards.clear();
388390
}
389391

390-
private void deleteCrd(AppliedCRD appliedCRD, KubernetesClient client) {
391-
if (!deleteCRDs) {
392-
LOGGER.debug("Skipping deleting CRD because of configuration: {}", appliedCRD);
393-
return;
392+
private static class CrdCleanup implements ExtensionContext.Store.CloseableResource {
393+
@Override
394+
public void close() {
395+
// Create a fresh client for cleanup since operator clients may already be closed.
396+
try (var client = new KubernetesClientBuilder().build()) {
397+
var iterator = appliedCRDs.iterator();
398+
while (iterator.hasNext()) {
399+
var appliedCRD = iterator.next();
400+
iterator.remove();
401+
if (!deleteCRDs) {
402+
LOGGER.debug("Skipping deleting CRD because of configuration: {}", appliedCRD);
403+
continue;
404+
}
405+
try {
406+
appliedCRD.delete(client);
407+
} catch (Exception e) {
408+
LOGGER.warn("Failed to delete CRD: {}. Continuing with remaining CRDs.", appliedCRD, e);
409+
}
410+
}
411+
}
394412
}
395-
appliedCRD.delete(client);
396413
}
397414

398415
private sealed interface AppliedCRD permits AppliedCRD.FileCRD, AppliedCRD.InstanceCRD {

0 commit comments

Comments
 (0)