Skip to content

Commit

Permalink
refactor: share more code (#910)
Browse files Browse the repository at this point in the history
  • Loading branch information
metacosm authored Feb 4, 2022
1 parent ff1a44d commit 817f8ca
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@

import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.awaitility.Awaitility;
import org.junit.jupiter.api.extension.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
import io.fabric8.kubernetes.api.model.NamespaceBuilder;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
Expand All @@ -26,7 +32,9 @@ public abstract class AbstractOperatorExtension implements HasKubernetesClient,
AfterAllCallback,
AfterEachCallback {

protected final KubernetesClient kubernetesClient;
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractOperatorExtension.class);

private final KubernetesClient kubernetesClient;
protected final ConfigurationService configurationService;
protected final List<HasMetadata> infrastructure;
protected Duration infrastructureTimeout;
Expand Down Expand Up @@ -55,22 +63,22 @@ protected AbstractOperatorExtension(


@Override
public void beforeAll(ExtensionContext context) throws Exception {
public void beforeAll(ExtensionContext context) {
beforeAllImpl(context);
}

@Override
public void beforeEach(ExtensionContext context) throws Exception {
public void beforeEach(ExtensionContext context) {
beforeEachImpl(context);
}

@Override
public void afterAll(ExtensionContext context) throws Exception {
public void afterAll(ExtensionContext context) {
afterAllImpl(context);
}

@Override
public void afterEach(ExtensionContext context) throws Exception {
public void afterEach(ExtensionContext context) {
afterEachImpl(context);
}

Expand Down Expand Up @@ -100,6 +108,7 @@ public <T extends HasMetadata> T replace(Class<T> type, T resource) {
return kubernetesClient.resources(type).inNamespace(namespace).replace(resource);
}

@SuppressWarnings("unchecked")
public <T extends HasMetadata> boolean delete(Class<T> type, T resource) {
return kubernetesClient.resources(type).inNamespace(namespace).delete(resource);
}
Expand Down Expand Up @@ -130,7 +139,20 @@ protected void beforeEachImpl(ExtensionContext context) {
}
}

protected abstract void before(ExtensionContext context);
protected void before(ExtensionContext context) {
LOGGER.info("Initializing integration test in namespace {}", namespace);

kubernetesClient
.namespaces()
.create(new NamespaceBuilder().withNewMetadata().withName(namespace).endMetadata().build());

kubernetesClient
.resourceList(infrastructure)
.createOrReplace();
kubernetesClient
.resourceList(infrastructure)
.waitUntilReady(infrastructureTimeout.toMillis(), TimeUnit.MILLISECONDS);
}

protected void afterAllImpl(ExtensionContext context) {
if (oneNamespacePerClass) {
Expand All @@ -144,9 +166,32 @@ protected void afterEachImpl(ExtensionContext context) {
}
}

protected abstract void after(ExtensionContext context);
protected void after(ExtensionContext context) {
if (namespace != null) {
if (preserveNamespaceOnError && context.getExecutionException().isPresent()) {
LOGGER.info("Preserving namespace {}", namespace);
} else {
kubernetesClient.resourceList(infrastructure).delete();
deleteOperator();
LOGGER.info("Deleting namespace {} and stopping operator", namespace);
kubernetesClient.namespaces().withName(namespace).delete();
if (waitForNamespaceDeletion) {
LOGGER.info("Waiting for namespace {} to be deleted", namespace);
Awaitility.await("namespace deleted")
.pollInterval(50, TimeUnit.MILLISECONDS)
.atMost(90, TimeUnit.SECONDS)
.until(() -> kubernetesClient.namespaces().withName(namespace).get() == null);
}
}
}
}

protected void deleteOperator() {
// nothing to do by default: only needed if the operator is deployed to the cluster
}

public static abstract class AbstractBuilder {
@SuppressWarnings("unchecked")
public static abstract class AbstractBuilder<T extends AbstractBuilder<T>> {
protected ConfigurationService configurationService;
protected final List<HasMetadata> infrastructure;
protected Duration infrastructureTimeout;
Expand All @@ -172,5 +217,41 @@ protected AbstractBuilder() {
"josdk.it.oneNamespacePerClass",
false);
}

public T preserveNamespaceOnError(boolean value) {
this.preserveNamespaceOnError = value;
return (T) this;
}

public T waitForNamespaceDeletion(boolean value) {
this.waitForNamespaceDeletion = value;
return (T) this;
}

public T oneNamespacePerClass(boolean value) {
this.oneNamespacePerClass = value;
return (T) this;
}

public T withConfigurationService(ConfigurationService value) {
configurationService = value;
return (T) this;
}

public T withInfrastructureTimeout(Duration value) {
infrastructureTimeout = value;
return (T) this;
}

public T withInfrastructure(List<HasMetadata> hm) {
infrastructure.addAll(hm);
return (T) this;
}

public T withInfrastructure(HasMetadata... hms) {
infrastructure.addAll(Arrays.asList(hms));
return (T) this;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
import java.io.InputStream;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.awaitility.Awaitility;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.NamespaceBuilder;
import io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding;
import io.javaoperatorsdk.operator.api.config.ConfigurationService;

Expand Down Expand Up @@ -51,25 +51,15 @@ public static Builder builder() {
return new Builder();
}

@SuppressWarnings("unchecked")
protected void before(ExtensionContext context) {
LOGGER.info("Initializing integration test in namespace {}", namespace);

kubernetesClient
.namespaces()
.create(new NamespaceBuilder().withNewMetadata().withName(namespace).endMetadata().build());

kubernetesClient
.resourceList(infrastructure)
.createOrReplace();
kubernetesClient
.resourceList(infrastructure)
.waitUntilReady(infrastructureTimeout.toMillis(), TimeUnit.MILLISECONDS);
super.before(context);

final var crdPath = "./target/classes/META-INF/fabric8/";
final var crdSuffix = "-v1.yml";

for (var crdFile : new File(crdPath).listFiles((ignored, name) -> name.endsWith(crdSuffix))) {
final var kubernetesClient = getKubernetesClient();
for (var crdFile : Objects
.requireNonNull(new File(crdPath).listFiles((ignored, name) -> name.endsWith(crdSuffix)))) {
try (InputStream is = new FileInputStream(crdFile)) {
final var crd = kubernetesClient.load(is);
crd.createOrReplace();
Expand All @@ -81,7 +71,7 @@ protected void before(ExtensionContext context) {
}

LOGGER.debug("Deploying the operator into Kubernetes");
operatorDeployment.stream().forEach(hm -> {
operatorDeployment.forEach(hm -> {
hm.getMetadata().setNamespace(namespace);
if (hm.getKind().toLowerCase(Locale.ROOT).equals("clusterrolebinding")) {
var crb = (ClusterRoleBinding) hm;
Expand All @@ -100,88 +90,33 @@ protected void before(ExtensionContext context) {
.waitUntilReady(operatorDeploymentTimeout.toMillis(), TimeUnit.MILLISECONDS);
}

protected void after(ExtensionContext context) {
if (namespace != null) {
if (preserveNamespaceOnError && context.getExecutionException().isPresent()) {
LOGGER.info("Preserving namespace {}", namespace);
} else {
kubernetesClient.resourceList(infrastructure).delete();
kubernetesClient.resourceList(operatorDeployment).inNamespace(namespace).delete();
LOGGER.info("Deleting namespace {} and stopping operator", namespace);
kubernetesClient.namespaces().withName(namespace).delete();
if (waitForNamespaceDeletion) {
LOGGER.info("Waiting for namespace {} to be deleted", namespace);
Awaitility.await("namespace deleted")
.pollInterval(50, TimeUnit.MILLISECONDS)
.atMost(90, TimeUnit.SECONDS)
.until(() -> kubernetesClient.namespaces().withName(namespace).get() == null);
}
}
}
@Override
protected void deleteOperator() {
getKubernetesClient().resourceList(operatorDeployment).inNamespace(namespace).delete();
}

@SuppressWarnings("rawtypes")
public static class Builder extends AbstractBuilder {
public static class Builder extends AbstractBuilder<Builder> {
private final List<HasMetadata> operatorDeployment;
private Duration deploymentTimeout;

protected Builder() {
super();;
super();
this.operatorDeployment = new ArrayList<>();
this.deploymentTimeout = Duration.ofMinutes(1);
}

public Builder preserveNamespaceOnError(boolean value) {
this.preserveNamespaceOnError = value;
return this;
}

public Builder waitForNamespaceDeletion(boolean value) {
this.waitForNamespaceDeletion = value;
return this;
}

public Builder oneNamespacePerClass(boolean value) {
this.oneNamespacePerClass = value;
return this;
}

public Builder withConfigurationService(ConfigurationService value) {
configurationService = value;
return this;
}

public Builder withDeploymentTimeout(Duration value) {
deploymentTimeout = value;
return this;
}

public Builder withInfrastructureTimeout(Duration value) {
infrastructureTimeout = value;
return this;
}

public Builder withInfrastructure(List<HasMetadata> hm) {
infrastructure.addAll(hm);
return this;
}

public Builder withInfrastructure(HasMetadata... hms) {
for (HasMetadata hm : hms) {
infrastructure.add(hm);
}
return this;
}

public Builder withOperatorDeployment(List<HasMetadata> hm) {
operatorDeployment.addAll(hm);
return this;
}

public Builder withOperatorDeployment(HasMetadata... hms) {
for (HasMetadata hm : hms) {
operatorDeployment.add(hm);
}
operatorDeployment.addAll(Arrays.asList(hms));
return this;
}

Expand Down
Loading

0 comments on commit 817f8ca

Please sign in to comment.