Skip to content

improve: Integration test for dependent in different namespace #1924

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

Merged
merged 3 commits into from
May 31, 2023
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
@@ -0,0 +1,71 @@
package io.javaoperatorsdk.operator;

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

import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.ConfigMapDependentResource;
import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.DependentDifferentNamespaceCustomResource;
import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.DependentDifferentNamespaceReconciler;
import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.DependentDifferentNamespaceSpec;

import static io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.ConfigMapDependentResource.KEY;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;

class DependentDifferentNamespaceIT {

public static final String TEST_1 = "different-ns-test1";
public static final String INITIAL_VALUE = "initial_value";
public static final String CHANGED_VALUE = "changed_value";

@RegisterExtension
LocallyRunOperatorExtension extension =
LocallyRunOperatorExtension.builder()
.withReconciler(DependentDifferentNamespaceReconciler.class)
.build();

@Test
void managesCRUDOperationsForDependentInDifferentNamespace() {
var resource = extension.create(testResource());

await().untilAsserted(() -> {
var cm = getDependentConfigMap();
assertThat(cm).isNotNull();
assertThat(cm.getData()).containsEntry(KEY, INITIAL_VALUE);
});

resource.getSpec().setValue(CHANGED_VALUE);
resource = extension.replace(resource);

await().untilAsserted(() -> {
var cm = getDependentConfigMap();
assertThat(cm.getData()).containsEntry(KEY, CHANGED_VALUE);
});

extension.delete(resource);
await().untilAsserted(() -> {
var cm = getDependentConfigMap();
assertThat(cm).isNull();
});
}

private ConfigMap getDependentConfigMap() {
return extension.getKubernetesClient().configMaps()
.inNamespace(ConfigMapDependentResource.NAMESPACE)
.withName(TEST_1).get();
}

DependentDifferentNamespaceCustomResource testResource() {
var res = new DependentDifferentNamespaceCustomResource();
res.setMetadata(new ObjectMetaBuilder()
.withName(TEST_1)
.build());
res.setSpec(new DependentDifferentNamespaceSpec());
res.getSpec().setValue(INITIAL_VALUE);
return res;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace;

import java.util.HashMap;

import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDNoGCKubernetesDependentResource;

public class ConfigMapDependentResource extends
CRUDNoGCKubernetesDependentResource<ConfigMap, DependentDifferentNamespaceCustomResource> {

public static final String KEY = "key";

public static final String NAMESPACE = "default";

public ConfigMapDependentResource() {
super(ConfigMap.class);
}

@Override
protected ConfigMap desired(DependentDifferentNamespaceCustomResource primary,
Context<DependentDifferentNamespaceCustomResource> context) {

ConfigMap configMap = new ConfigMap();
configMap.setMetadata(new ObjectMeta());
configMap.getMetadata().setName(primary.getMetadata().getName());
configMap.getMetadata().setNamespace(NAMESPACE);
HashMap<String, String> data = new HashMap<>();
data.put(KEY, primary.getSpec().getValue());
configMap.setData(data);
return configMap;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace;

import io.fabric8.kubernetes.api.model.Namespaced;
import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.ShortNames;
import io.fabric8.kubernetes.model.annotation.Version;

@Group("sample.javaoperatorsdk")
@Version("v1")
@ShortNames("ddn")
public class DependentDifferentNamespaceCustomResource
extends CustomResource<DependentDifferentNamespaceSpec, Void>
implements Namespaced {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace;

import java.util.concurrent.atomic.AtomicInteger;

import io.javaoperatorsdk.operator.api.reconciler.*;
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider;

@ControllerConfiguration(
dependents = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this should be made more explicit by making the reconciler only watch 2 namespaces: the one where the primary resources are deployed and the one where the dependents are supposed to be? It feels like we're somehow "cheating" by having the reconciler watch all namespaces… 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that would require a change to the extension, if you insist can do that, I don't see it that important, on the other hand would be little nicer I agree.

@Dependent(type = ConfigMapDependentResource.class),
})
public class DependentDifferentNamespaceReconciler
implements Reconciler<DependentDifferentNamespaceCustomResource>,
TestExecutionInfoProvider {

private final AtomicInteger numberOfExecutions = new AtomicInteger(0);

@Override
public UpdateControl<DependentDifferentNamespaceCustomResource> reconcile(
DependentDifferentNamespaceCustomResource resource,
Context<DependentDifferentNamespaceCustomResource> context) {
numberOfExecutions.addAndGet(1);
return UpdateControl.noUpdate();
}

public int getNumberOfExecutions() {
return numberOfExecutions.get();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace;

public class DependentDifferentNamespaceSpec {

private String value;

public String getValue() {
return value;
}

public DependentDifferentNamespaceSpec setValue(String value) {
this.value = value;
return this;
}
}