Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to switch ResoruceManager between async and sequential deletion mode #194

Merged
merged 2 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,11 @@
* @return enable/disable cleaner
*/
boolean cleanResources() default true;

/**
* Enables async deletion of resources
*
* @return enable/disable async cleaning
*/
boolean asyncDeletion() default true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public void afterEach(ExtensionContext extensionContext) {

if (annotation.isPresent() && annotation.get().cleanResources()) {
KubeResourceManager.setTestContext(extensionContext);
KubeResourceManager.getInstance().deleteResources();
KubeResourceManager.getInstance().deleteResources(annotation.get().asyncDeletion());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -400,23 +400,29 @@ private <T extends HasMetadata> void createOrUpdateResource(boolean async,
*/
@SafeVarargs
public final <T extends HasMetadata> void deleteResource(T... resources) {
deleteResource(true, resources);
}

/**
* Deletes resources.
*
* @param async Enables async deletion
* @param resources The resources to delete.
* @param <T> The type of the resources.
*/
@SafeVarargs
public final <T extends HasMetadata> void deleteResource(boolean async, T... resources) {
List<CompletableFuture<Void>> waitExecutors = new LinkedList<>();
for (T resource : resources) {
ResourceType<T> type = findResourceType(resource);
LoggerUtils.logResource("Deleting", resource);
try {
if (type == null) {
client.getClient().resource(resource).delete();
waitExecutors.add(CompletableFuture.runAsync(() ->
assertTrue(waitResourceCondition(resource, ResourceCondition.deletion()),
String.format("Timed out deleting %s/%s in %s", resource.getKind(),
resource.getMetadata().getName(), resource.getMetadata().getNamespace()))));
decideDeleteWaitAsync(waitExecutors, async, resource);
} else {
type.delete(resource);
waitExecutors.add(CompletableFuture.runAsync(() ->
assertTrue(waitResourceCondition(resource, ResourceCondition.deletion()),
String.format("Timed out deleting %s/%s in %s", resource.getKind(),
resource.getMetadata().getName(), resource.getMetadata().getNamespace()))));
decideDeleteWaitAsync(waitExecutors, async, resource);
}
} catch (Exception e) {
if (resource.getMetadata().getNamespace() == null) {
Expand Down Expand Up @@ -485,6 +491,15 @@ public final <T extends HasMetadata> boolean waitResourceCondition(T resource, R
* Deletes all stored resources.
*/
public void deleteResources() {
deleteResources(true);
}

/**
* Deletes all stored resources.
*
* @param async sets async or sequential deletion
*/
public void deleteResources(boolean async) {
LoggerUtils.logSeparator();
if (!STORED_RESOURCES.containsKey(getTestContext().getDisplayName())
|| STORED_RESOURCES.get(getTestContext().getDisplayName()).isEmpty()) {
Expand All @@ -505,13 +520,18 @@ public void deleteResources() {
ResourceItem<?> resourceItem = s.pop();

try {
waitExecutors.add(CompletableFuture.runAsync(() -> {
CompletableFuture<Void> c = CompletableFuture.runAsync(() -> {
try {
resourceItem.throwableRunner().run();
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
});
if (async) {
waitExecutors.add(c);
} else {
CompletableFuture.allOf(c).join();
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
Expand Down Expand Up @@ -585,4 +605,17 @@ private void writeResourceAsYaml(HasMetadata resource) {
throw new RuntimeException(e);
}
}

private <T extends HasMetadata> void decideDeleteWaitAsync(List<CompletableFuture<Void>> waitExecutors,
boolean async, T resource) {
CompletableFuture<Void> c = CompletableFuture.runAsync(() ->
assertTrue(waitResourceCondition(resource, ResourceCondition.deletion()),
String.format("Timed out deleting %s/%s in %s", resource.getKind(),
resource.getMetadata().getName(), resource.getMetadata().getNamespace())));
if (async) {
waitExecutors.add(c);
} else {
CompletableFuture.allOf(c).join();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Namespace;
import io.fabric8.kubernetes.api.model.NamespaceBuilder;
import io.skodjob.testframe.annotations.ResourceManager;
import io.skodjob.testframe.clients.KubeClusterException;
import io.skodjob.testframe.resources.KubeResourceManager;
import org.junit.jupiter.api.AfterAll;
Expand All @@ -25,6 +26,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ResourceManager(asyncDeletion = false)
public final class KubeResourceManagerCleanerIT extends AbstractIT {

@BeforeAll
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void createResource() {
new NamespaceBuilder().withNewMetadata().withName("test2").endMetadata().build());
assertNotNull(KubeResourceManager.getKubeClient().getClient().namespaces().withName(nsName1).get());
assertNotNull(KubeResourceManager.getKubeClient().getClient().namespaces().withName(nsName2).get());
KubeResourceManager.getInstance().deleteResource(ns1);
KubeResourceManager.getInstance().deleteResource(false, ns1);
assertTrue(isDeleteHandlerCalled.get());
}
}