Skip to content

Commit

Permalink
Add support for Notebooks to create them in tests
Browse files Browse the repository at this point in the history
Signed-off-by: Jakub Stejskal <[email protected]>
  • Loading branch information
Frawless committed Dec 5, 2023
1 parent 3978997 commit 673213d
Show file tree
Hide file tree
Showing 15 changed files with 573 additions and 24 deletions.
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<checkstyle.version>10.12.5</checkstyle.version>
<maven.checkstyle.version>3.3.1</maven.checkstyle.version>
<maven.download.plugin.version>1.7.1</maven.download.plugin.version>
<commons.io.version>2.15.1</commons.io.version>
</properties>

<repositories>
Expand Down Expand Up @@ -161,6 +162,13 @@
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/io/odh/test/Environment.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
package io.odh.test;

import io.odh.test.install.InstallTypes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -44,6 +45,7 @@ public class Environment {
private static final String OLM_APP_BUNDLE_PREFIX_ENV = "OLM_APP_BUNDLE_PREFIX";
private static final String OLM_OPERATOR_VERSION_ENV = "OLM_OPERATOR_VERSION";
private static final String OLM_OPERATOR_CHANNEL_ENV = "OLM_OPERATOR_CHANNEL";
private static final String OPERATOR_INSTALL_TYPE_ENV = "OPERATOR_INSTALL_TYPE";

/**
* Defaults
Expand Down Expand Up @@ -78,6 +80,9 @@ public class Environment {
public static final String OLM_APP_BUNDLE_PREFIX = getOrDefault(OLM_APP_BUNDLE_PREFIX_ENV, OLM_APP_BUNDLE_PREFIX_DEFAULT);
public static final String OLM_OPERATOR_CHANNEL = getOrDefault(OLM_OPERATOR_CHANNEL_ENV, OLM_OPERATOR_CHANNEL_DEFAULT);
public static final String OLM_OPERATOR_VERSION = getOrDefault(OLM_OPERATOR_VERSION_ENV, OLM_OPERATOR_VERSION_DEFAULT);

public static final String OPERATOR_INSTALL_TYPE = getOrDefault(OPERATOR_INSTALL_TYPE_ENV, InstallTypes.OLM.toString());

private Environment() { }

static {
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/io/odh/test/OdhAnnotationsLabels.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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;

public class OdhAnnotationsLabels {
public static final String OPENSHIFT_DOMAIN = "openshift.io/";
public static final String ODH_DOMAIN = "opendatahub.io/";

public static final String LABEL_DASHBOARD = ODH_DOMAIN + "dashboard";
public static final String LABEL_ODH_MANAGED = ODH_DOMAIN + "odh-managed";
public static final String LABEL_SIDECAR_ISTIO_INJECT = "sidecar.istio.io/inject";

public static final String ANNO_SERVICE_MESH = ODH_DOMAIN + "service-mesh";
public static final String ANNO_NTB_INJECT_OAUTH = "notebooks." + ODH_DOMAIN + "inject-oauth";

}
15 changes: 15 additions & 0 deletions src/main/java/io/odh/test/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
*/
package io.odh.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import io.odh.test.framework.WaitException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
Expand Down Expand Up @@ -174,4 +178,15 @@ public static InputStream getFileFromResourceAsStream(String fileName) {
}

}

public static <T> T configFromYaml(String yamlFile, Class<T> c) {
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
try {
return mapper.readValue(yamlFile, c);
} catch (InvalidFormatException e) {
throw new IllegalArgumentException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
34 changes: 12 additions & 22 deletions src/main/java/io/odh/test/framework/manager/ResourceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.admissionregistration.v1.ValidatingWebhookConfiguration;
import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.api.model.rbac.ClusterRole;
import io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding;
import io.odh.test.TestConstants;
import io.odh.test.TestUtils;
import io.odh.test.framework.manager.resources.DataScienceClusterResource;
import io.odh.test.framework.manager.resources.NotebookResource;
import io.odh.test.framework.manager.resources.OperatorGroupResource;
import io.odh.test.framework.manager.resources.SubscriptionResource;
import io.odh.test.platform.KubeClient;
import io.odh.test.utils.DeploymentUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -48,6 +48,8 @@ public static KubeClient getClient() {
private final ResourceType<?>[] resourceTypes = new ResourceType[]{
new SubscriptionResource(),
new OperatorGroupResource(),
new DataScienceClusterResource(),
new NotebookResource(),
};

@SafeVarargs
Expand All @@ -74,18 +76,10 @@ private <T extends HasMetadata> void createResource(boolean waitReady, T... reso
}

if (type == null) {
if (resource instanceof Deployment) {
Deployment deployment = (Deployment) resource;
client.getClient().apps().deployments().resource(deployment).create();
if (waitReady) {
DeploymentUtils.waitForDeploymentReady(resource.getMetadata().getNamespace(), resource.getMetadata().getName());
}
continue;
} else {
LOGGER.error("Invalid resource {} {}/{}. Please implement it in ResourceManager",
resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName());
continue;
}
// Dealing with default Kubernetes objects
client.getClient().resource(resource).create();
LOGGER.info("Crating resource {} {}/{}.",
resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName());
} else {
type.create(resource);
if (waitReady) {
Expand All @@ -109,14 +103,10 @@ public final <T extends HasMetadata> void deleteResource(T... resources) {
for (T resource : resources) {
ResourceType<T> type = findResourceType(resource);
if (type == null) {
if (resource instanceof Deployment) {
Deployment deployment = (Deployment) resource;
client.getClient().apps().deployments().resource(deployment).delete();
DeploymentUtils.waitForDeploymentDeletion(resource.getMetadata().getNamespace(), resource.getMetadata().getName());
} else {
LOGGER.error("Invalid resource {} {}/{}. Please implement it in ResourceManager",
resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName());
}
// Dealing with default Kubernetes objects
client.getClient().resource(resource).delete();
LOGGER.info("Deleting resource {} {}/{}.",
resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName());
} else {
if (resource.getMetadata().getNamespace() == null) {
LOGGER.info("Deleting of {} {}",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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.manager.resources;

import io.fabric8.kubernetes.api.model.KubernetesResourceList;
import io.fabric8.kubernetes.client.dsl.MixedOperation;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.odh.test.framework.manager.ResourceManager;
import io.odh.test.framework.manager.ResourceType;
import io.opendatahub.datasciencecluster.v1.DataScienceCluster;

public class DataScienceClusterResource implements ResourceType<DataScienceCluster> {
@Override
public String getKind() {
return "DataScienceCluster";
}

@Override
public DataScienceCluster get(String namespace, String name) {
return dataScienceCLusterClient().inNamespace(namespace).withName(name).get();
}

@Override
public void create(DataScienceCluster resource) {
dataScienceCLusterClient().inNamespace(resource.getMetadata().getNamespace()).resource(resource).create();
}

@Override
public void delete(DataScienceCluster resource) {
dataScienceCLusterClient().inNamespace(resource.getMetadata().getNamespace()).withName(resource.getMetadata().getName()).delete();
}

@Override
public void update(DataScienceCluster resource) {
dataScienceCLusterClient().inNamespace(resource.getMetadata().getNamespace()).resource(resource).update();
}

@Override
public boolean waitForReadiness(DataScienceCluster resource) {
return resource != null;
}

public static MixedOperation<DataScienceCluster, KubernetesResourceList<DataScienceCluster>, Resource<DataScienceCluster>> dataScienceCLusterClient() {
return ResourceManager.getClient().getClient().resources(DataScienceCluster.class);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* 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.manager.resources;

import io.fabric8.kubernetes.api.model.KubernetesResourceList;
import io.fabric8.kubernetes.client.dsl.MixedOperation;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.odh.test.TestUtils;
import io.odh.test.framework.manager.ResourceManager;
import io.odh.test.framework.manager.ResourceType;
import org.kubeflow.v1.Notebook;

import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;


public class NotebookResource implements ResourceType<Notebook> {

private static final String NOTEBOOK_TEMPLATE_PATH = "notebook.yaml";
@Override
public String getKind() {
return "Notebook";
}

@Override
public Notebook get(String namespace, String name) {
return notebookClient().inNamespace(namespace).withName(name).get();
}

@Override
public void create(Notebook resource) {
notebookClient().inNamespace(resource.getMetadata().getNamespace()).resource(resource).create();
}

@Override
public void delete(Notebook resource) {
notebookClient().inNamespace(resource.getMetadata().getNamespace()).withName(resource.getMetadata().getName()).delete();
}

@Override
public void update(Notebook resource) {
notebookClient().inNamespace(resource.getMetadata().getNamespace()).resource(resource).update();
}

@Override
public boolean waitForReadiness(Notebook resource) {
return resource != null;
}

public static MixedOperation<Notebook, KubernetesResourceList<Notebook>, Resource<Notebook>> notebookClient() {
return ResourceManager.getClient().getClient().resources(Notebook.class);
}

public static Notebook loadDefaultNotebook(String namespace, String name) throws IOException {
InputStream is = TestUtils.getFileFromResourceAsStream(NOTEBOOK_TEMPLATE_PATH);
String notebookString = IOUtils.toString(is, "UTF-8");
notebookString = notebookString.replace("my-project", namespace).replace("my-workbench", name);
return TestUtils.configFromYaml(notebookString, Notebook.class);
}
}
10 changes: 10 additions & 0 deletions src/main/java/io/odh/test/install/InstallTypes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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.install;

public enum InstallTypes {
OLM,
BUNDLE
}
2 changes: 0 additions & 2 deletions src/main/java/io/odh/test/install/OlmInstall.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ private void createAndModifySubscription() {
Subscription subscription = prepareSubscription();

ResourceManager.getInstance().createResourceWithWait(subscription);
// ResourceManager.RESOURCE_STACK.push(new ResourceItem(this::deleteCSV));

}
public void updateSubscription() {
Subscription subscription = prepareSubscription();
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/io/odh/test/platform/KubeClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ public List<Pod> listPods(String namespaceName) {
return client.pods().inNamespace(namespaceName).list().getItems();
}

public List<Pod> listPods(String namespaceName, LabelSelector selector) {
return client.pods().inNamespace(namespaceName).withLabelSelector(selector).list().getItems();
}

/**
* Returns list of pods by prefix in pod name
*
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/io/odh/test/utils/NamespaceUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.utils;

import io.odh.test.TestConstants;
import io.odh.test.TestUtils;
import io.odh.test.framework.manager.ResourceManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;

public class NamespaceUtils {

private static final Logger LOGGER = LoggerFactory.getLogger(NamespaceUtils.class);
private static final long DELETION_TIMEOUT = Duration.ofMinutes(2).toMillis();

private NamespaceUtils() { }

public static void waitForNamespaceReadiness(String name) {
LOGGER.info("Waiting for Namespace: {} readiness", name);

TestUtils.waitFor("Namespace: " + name, TestConstants.GLOBAL_POLL_INTERVAL_SHORT, DELETION_TIMEOUT,
() -> ResourceManager.getClient().getNamespace(name) != null);
LOGGER.info("Namespace: {} is ready", name);
}

public static void waitForNamespaceDeletion(String name) {
LOGGER.info("Waiting for Namespace: {} deletion", name);

TestUtils.waitFor("Namespace: " + name, TestConstants.GLOBAL_POLL_INTERVAL_SHORT, DELETION_TIMEOUT,
() -> ResourceManager.getClient().getNamespace(name) == null);
LOGGER.info("Namespace: {} was deleted", name);
}
}
Loading

0 comments on commit 673213d

Please sign in to comment.