Skip to content

Commit

Permalink
Add kubernetes and junit5 tweaks for faster and easier testing (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
kornys authored Dec 5, 2023
1 parent 837e276 commit 6664c3f
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/main/java/io/odh/test/framework/ExecutionListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@
public class ExecutionListener implements TestExecutionListener {
static final Logger LOGGER = LoggerFactory.getLogger(TestSeparator.class);

static {
Environment.print();
}

public void testPlanExecutionStarted(TestPlan testPlan) {
LOGGER.info("=======================================================================");
LOGGER.info("=======================================================================");
LOGGER.info(" Test run started");
LOGGER.info("=======================================================================");
LOGGER.info("=======================================================================");
Environment.print();
}

public void testPlanExecutionFinished(TestPlan testPlan) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright Skodjob authors.
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
*/
package io.odh.test.framework;

import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler;
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* jUnit5 specific class which listening on test exception callbacks
*/
public class TestExceptionCallbackListener implements TestExecutionExceptionHandler, LifecycleMethodExecutionExceptionHandler {
static final Logger LOGGER = LoggerFactory.getLogger(TestExceptionCallbackListener.class);

@Override
public void handleTestExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
LOGGER.error("Test failed at {} : {}", "Test execution", throwable.getMessage(), throwable);
//TODO collect proper logs
throw throwable;
}

@Override
public void handleBeforeAllMethodExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
LOGGER.error("Test failed at {} : {}", "Test before all", throwable.getMessage(), throwable);
//TODO collect proper logs
throw throwable;
}

@Override
public void handleBeforeEachMethodExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
LOGGER.error("Test failed at {} : {}", "Test before each", throwable.getMessage(), throwable);
//TODO collect proper logs
throw throwable;
}

@Override
public void handleAfterEachMethodExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
LOGGER.error("Test failed at {} : {}", "Test after each", throwable.getMessage(), throwable);
//TODO collect proper logs
throw throwable;
}

@Override
public void handleAfterAllMethodExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
LOGGER.error("Test failed at {} : {}", "Test after all", throwable.getMessage(), throwable);
//TODO collect proper logs
throw throwable;
}
}
18 changes: 18 additions & 0 deletions src/main/java/io/odh/test/platform/KubeClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package io.odh.test.platform;

import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
import io.fabric8.kubernetes.api.model.LabelSelector;
import io.fabric8.kubernetes.api.model.Namespace;
Expand All @@ -30,7 +31,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class KubeClient {
Expand Down Expand Up @@ -120,6 +124,20 @@ public boolean namespaceExists(String namespace) {
.collect(Collectors.toList()).contains(namespace);
}

// =============================================
// ---------> Create multi-resoruces <---------
// =============================================
public void apply(String namespace, InputStream is, Function<HasMetadata, HasMetadata> modifier) throws IOException {
try (is) {
client.load(is).get().forEach(i -> {
HasMetadata h = modifier.apply(i);
if (h != null) {
client.resource(h).inNamespace(namespace).create();
}
});
}
}

/**
* Gets namespace status
*/
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/io/odh/test/platform/KubeUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,23 @@
*/
package io.odh.test.platform;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.BooleanSupplier;

public class KubeUtils {

static final Logger LOGGER = LoggerFactory.getLogger(KubeUtils.class);

public static io.opendatahub.datasciencecluster.v1.datascienceclusterstatus.Conditions getDscConditionByType(List<io.opendatahub.datasciencecluster.v1.datascienceclusterstatus.Conditions> conditions, String type) {
return conditions.stream().filter(c -> c.getType().equals(type)).findFirst().orElseGet(null);
}
Expand All @@ -16,6 +29,53 @@ public static org.kubeflow.v1.notebookstatus.Conditions getNotebookConditionByTy
return conditions.stream().filter(c -> c.getType().equals(type)).findFirst().orElseGet(null);
}

private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool(new ThreadFactory() {
final ThreadFactory defaultThreadFactory = Executors.defaultThreadFactory();

@Override
public Thread newThread(Runnable r) {
Thread result = defaultThreadFactory.newThread(r);
result.setDaemon(true);
return result;
}
});

public static CompletableFuture<Void> asyncWaitFor(String description, long pollIntervalMs, long timeoutMs, BooleanSupplier ready) {
LOGGER.info("Waiting for {}", description);
long deadline = System.currentTimeMillis() + timeoutMs;
CompletableFuture<Void> future = new CompletableFuture<>();
Executor delayed = CompletableFuture.delayedExecutor(pollIntervalMs, TimeUnit.MILLISECONDS, EXECUTOR);
Runnable r = new Runnable() {
@Override
public void run() {
boolean result;
try {
result = ready.getAsBoolean();
} catch (Exception e) {
future.completeExceptionally(e);
return;
}
long timeLeft = deadline - System.currentTimeMillis();
if (!future.isDone()) {
if (!result) {
if (timeLeft >= 0) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("{} not ready, will try again ({}ms till timeout)", description, timeLeft);
}
delayed.execute(this);
} else {
future.completeExceptionally(new TimeoutException(String.format("Waiting for %s timeout %s exceeded", description, timeoutMs)));
}
} else {
future.complete(null);
}
}
}
};
r.run();
return future;
}

private KubeUtils() {
}
}
6 changes: 6 additions & 0 deletions src/test/java/io/odh/test/e2e/Abstract.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
*/
package io.odh.test.e2e;

import io.odh.test.framework.TestExceptionCallbackListener;
import io.odh.test.platform.KubeClient;
import io.odh.test.TestConstants;
import io.odh.test.framework.TestSeparator;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;

@DisplayNameGeneration(DisplayNameGenerator.IndicativeSentences.class)
@ExtendWith(TestExceptionCallbackListener.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class Abstract implements TestSeparator {
protected KubeClient kubeClient = new KubeClient(TestConstants.ODH_NAMESPACE);
Expand Down

0 comments on commit 6664c3f

Please sign in to comment.