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

chore(tests): add multiple versions CRs to CRD generation tests #971

Merged
merged 1 commit into from
Oct 4, 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
@@ -1,40 +1,68 @@
package io.quarkiverse.operatorsdk.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionVersion;
import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.client.utils.KubernetesSerialization;
import io.quarkiverse.operatorsdk.test.sources.*;
import io.quarkus.test.ProdBuildResults;
import io.quarkus.test.ProdModeTestResults;
import io.quarkus.test.QuarkusProdModeTest;

public class AllCRDGenerationTest {

public static final String V1_CRD_SUFFIX = "-v1.yml";
// Start unit test with your extension loaded
@RegisterExtension
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
.setApplicationName("test")
.withApplicationRoot(
(jar) -> jar.addClasses(SimpleReconciler.class, SimpleCR.class, SimpleSpec.class, SimpleStatus.class,
External.class))
External.class, ExternalV1.class, SimpleReconcilerV2.class, SimpleCRV2.class))
.overrideConfigKey("quarkus.operator-sdk.crd.generate-all", "true");

@ProdBuildResults
private ProdModeTestResults prodModeTestResults;

private static final KubernetesSerialization serializer = new KubernetesSerialization();

@Test
public void shouldGenerateAllCRDs() throws IOException {
final var kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
final var kubeManifest = kubernetesDir.resolve("kubernetes.yml");
Assertions.assertTrue(Files.exists(kubeManifest));

// checks that CRDs are all generated
Assertions.assertTrue(Files.exists(kubernetesDir.resolve(CustomResource.getCRDName(SimpleCR.class) + "-v1.yml")));
Assertions.assertTrue(Files.exists(kubernetesDir.resolve(CustomResource.getCRDName(External.class) + "-v1.yml")));
Assertions.assertEquals(2, Files.list(kubernetesDir)
.filter(path -> path.getFileName().toFile().getName().endsWith(V1_CRD_SUFFIX))
.count());

checkCRD(kubernetesDir.resolve(getV1CRDFileName(SimpleCR.class)), SimpleCR.VERSION, SimpleCRV2.VERSION);
checkCRD(kubernetesDir.resolve(getV1CRDFileName(External.class)), External.VERSION, ExternalV1.VERSION);
}

private static void checkCRD(Path crdPath, String version1, String version2) throws FileNotFoundException {
Assertions.assertTrue(Files.exists(crdPath));
final var simpleCRDIS = new FileInputStream(crdPath.toFile());
final var simpleCRD = (CustomResourceDefinition) serializer.unmarshal(simpleCRDIS);
final List<CustomResourceDefinitionVersion> versions = simpleCRD.getSpec().getVersions().stream().toList();
Assertions.assertEquals(2, versions.size());
Assertions.assertTrue(versions.stream().anyMatch(v -> v.getName().equals(version1)));
Assertions.assertTrue(versions.stream().anyMatch(v -> v.getName().equals(version2)));
}

private static String getV1CRDFileName(Class<? extends CustomResource<?, ?>> crClass) {
return CustomResource.getCRDName(crClass) + V1_CRD_SUFFIX;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import io.fabric8.kubernetes.api.model.rbac.PolicyRule;
import io.fabric8.kubernetes.api.model.rbac.RoleBinding;
import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.kubernetes.client.utils.KubernetesSerialization;
import io.quarkiverse.operatorsdk.annotations.RBACRule;
import io.quarkiverse.operatorsdk.annotations.RBACVerbs;
import io.quarkiverse.operatorsdk.deployment.AddClusterRolesDecorator;
Expand Down Expand Up @@ -86,9 +86,9 @@ public void shouldCreateRolesAndRoleBindings() throws IOException {
final var kubeManifest = kubernetesDir.resolve("kubernetes.yml");
Assertions.assertTrue(Files.exists(kubeManifest));
final var kubeIS = new FileInputStream(kubeManifest.toFile());
// use unmarshall version with parameters map to ensure code goes through the proper processing wrt multiple documents
final var serializer = new KubernetesSerialization();
@SuppressWarnings("unchecked")
final var kubeResources = (List<HasMetadata>) Serialization.unmarshal(kubeIS);
final var kubeResources = (List<HasMetadata>) serializer.unmarshal(kubeIS);

// check cluster role for TestReconciler
final var testReconcilerRoleName = AddClusterRolesDecorator.getClusterRoleName(TestReconciler.NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Kind;
import io.fabric8.kubernetes.model.annotation.Version;

@Group("halkyon.io")
@Version("v1alpha1")
@Version(value = External.VERSION, storage = false)
@Kind(External.KIND)
public class External extends CustomResource<Void, Void> {

public static final String DISPLAY_NAME = "External display name";
public static final String DESCRIPTION = "External description";
public static final String VERSION = "v1alpha1";
public static final String KIND = "External";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.quarkiverse.operatorsdk.test.sources;

import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Kind;
import io.fabric8.kubernetes.model.annotation.Version;

@Group("halkyon.io")
@Version(ExternalV1.VERSION)
@Kind(External.KIND)
public class ExternalV1 extends CustomResource<Void, Void> {
public static final String VERSION = "v1";
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Kind;
import io.fabric8.kubernetes.model.annotation.Version;

@Group("example.com")
@Version("v1")
@Version(value = SimpleCR.VERSION, storage = false)
@Kind(SimpleCR.KIND)
public class SimpleCR extends CustomResource<SimpleSpec, SimpleStatus> {

public static final String VERSION = "v1";
public static final String KIND = "SimpleCR";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.quarkiverse.operatorsdk.test.sources;

import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Kind;
import io.fabric8.kubernetes.model.annotation.Version;

@Group("example.com")
@Version(SimpleCRV2.VERSION)
@Kind(SimpleCR.KIND)
public class SimpleCRV2 extends CustomResource<SimpleSpecV2, SimpleStatus> {
public static final String VERSION = "v2";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.quarkiverse.operatorsdk.test.sources;

import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;

public class SimpleReconcilerV2 implements Reconciler<SimpleCRV2> {
@Override
public UpdateControl<SimpleCRV2> reconcile(SimpleCRV2 simpleCRV2, Context<SimpleCRV2> context) throws Exception {
return UpdateControl.noUpdate();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.quarkiverse.operatorsdk.test.sources;

public class SimpleSpecV2 {
public String value;
public int number;
}