Skip to content

Commit 9203295

Browse files
authored
feat: integration test for cross reference dependent resource (#1203)
1 parent 51d4ec1 commit 9203295

File tree

5 files changed

+171
-3
lines changed

5 files changed

+171
-3
lines changed

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/config/ControllerConfigurationOverriderTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void overridingNSShouldPreserveUntouchedDependents() {
3636
// override the NS
3737
final var namespace = "some-ns";
3838
final var externalDRName =
39-
DependentResource.defaultNameFor(NamedDependentReconciler.ExternalDependendResource.class);
39+
DependentResource.defaultNameFor(NamedDependentReconciler.ExternalDependentResource.class);
4040
final var stringConfig = "some String configuration";
4141
configuration = ControllerConfigurationOverrider.override(configuration)
4242
.settingNamespace(namespace)
@@ -54,7 +54,7 @@ void overridingNSShouldPreserveUntouchedDependents() {
5454

5555
@ControllerConfiguration(dependents = {
5656
@Dependent(type = NamedDependentReconciler.NamedDependentResource.class),
57-
@Dependent(type = NamedDependentReconciler.ExternalDependendResource.class)
57+
@Dependent(type = NamedDependentReconciler.ExternalDependentResource.class)
5858
})
5959
private static class NamedDependentReconciler implements Reconciler<ConfigMap> {
6060

@@ -72,7 +72,7 @@ public NamedDependentResource() {
7272
}
7373
}
7474

75-
private static class ExternalDependendResource implements DependentResource<Object, ConfigMap> {
75+
private static class ExternalDependentResource implements DependentResource<Object, ConfigMap> {
7676

7777
@Override
7878
public ReconcileResult<Object> reconcile(ConfigMap primary, Context<ConfigMap> context) {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package io.javaoperatorsdk.operator;
2+
3+
import java.time.Duration;
4+
5+
import org.junit.jupiter.api.Test;
6+
import org.junit.jupiter.api.extension.RegisterExtension;
7+
8+
import io.fabric8.kubernetes.api.model.ConfigMap;
9+
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
10+
import io.fabric8.kubernetes.api.model.Secret;
11+
import io.javaoperatorsdk.operator.junit.LocalOperatorExtension;
12+
import io.javaoperatorsdk.operator.sample.dependentresourcecrossref.DependentResourceCrossRefReconciler;
13+
import io.javaoperatorsdk.operator.sample.dependentresourcecrossref.DependentResourceCrossRefResource;
14+
15+
import static org.assertj.core.api.Assertions.assertThat;
16+
import static org.awaitility.Awaitility.await;
17+
18+
class DependentResourceCrossRefIT {
19+
20+
public static final String TEST_RESOURCE_NAME = "test";
21+
public static final int EXECUTION_NUMBER = 50;
22+
23+
@RegisterExtension
24+
LocalOperatorExtension operator =
25+
LocalOperatorExtension.builder()
26+
.withReconciler(new DependentResourceCrossRefReconciler())
27+
.build();
28+
29+
@Test
30+
void dependentResourceCanReferenceEachOther() {
31+
for (int i = 0; i < EXECUTION_NUMBER; i++) {
32+
operator.create(DependentResourceCrossRefResource.class, testResource(i));
33+
}
34+
await()
35+
.pollDelay(Duration.ofMillis(150))
36+
.untilAsserted(
37+
() -> {
38+
assertThat(operator
39+
.getReconcilerOfType(DependentResourceCrossRefReconciler.class)
40+
.isErrorHappened()).isFalse();
41+
for (int i = 0; i < EXECUTION_NUMBER; i++) {
42+
assertThat(operator.get(ConfigMap.class, TEST_RESOURCE_NAME + i)).isNotNull();
43+
assertThat(operator.get(Secret.class, TEST_RESOURCE_NAME + i)).isNotNull();
44+
}
45+
});
46+
}
47+
48+
DependentResourceCrossRefResource testResource(int n) {
49+
var res = new DependentResourceCrossRefResource();
50+
res.setMetadata(new ObjectMetaBuilder().withName(TEST_RESOURCE_NAME + n).build());
51+
return res;
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package io.javaoperatorsdk.operator.sample.dependentresourcecrossref;
2+
3+
import java.util.ArrayList;
4+
import java.util.Base64;
5+
import java.util.Map;
6+
import java.util.concurrent.atomic.AtomicInteger;
7+
8+
import io.fabric8.kubernetes.api.model.ConfigMap;
9+
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
10+
import io.fabric8.kubernetes.api.model.Secret;
11+
import io.javaoperatorsdk.operator.api.reconciler.*;
12+
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
13+
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUKubernetesDependentResource;
14+
15+
@ControllerConfiguration(dependents = {
16+
@Dependent(type = DependentResourceCrossRefReconciler.SecretDependentResource.class),
17+
@Dependent(type = DependentResourceCrossRefReconciler.ConfigMapDependentResource.class)})
18+
public class DependentResourceCrossRefReconciler
19+
implements Reconciler<DependentResourceCrossRefResource>,
20+
ErrorStatusHandler<DependentResourceCrossRefResource> {
21+
22+
private final AtomicInteger numberOfExecutions = new AtomicInteger(0);
23+
private volatile boolean errorHappened = false;
24+
25+
@Override
26+
public UpdateControl<DependentResourceCrossRefResource> reconcile(
27+
DependentResourceCrossRefResource resource,
28+
Context<DependentResourceCrossRefResource> context) {
29+
numberOfExecutions.addAndGet(1);
30+
return UpdateControl.noUpdate();
31+
}
32+
33+
public int getNumberOfExecutions() {
34+
return numberOfExecutions.get();
35+
}
36+
37+
@Override
38+
public ErrorStatusUpdateControl<DependentResourceCrossRefResource> updateErrorStatus(
39+
DependentResourceCrossRefResource resource,
40+
Context<DependentResourceCrossRefResource> context, Exception e) {
41+
errorHappened = true;
42+
return ErrorStatusUpdateControl.noStatusUpdate();
43+
}
44+
45+
public boolean isErrorHappened() {
46+
return errorHappened;
47+
}
48+
49+
public static class SecretDependentResource extends
50+
CRUKubernetesDependentResource<Secret, DependentResourceCrossRefResource> {
51+
52+
public SecretDependentResource() {
53+
super(Secret.class);
54+
}
55+
56+
@Override
57+
protected Secret desired(DependentResourceCrossRefResource primary,
58+
Context<DependentResourceCrossRefResource> context) {
59+
Secret secret = new Secret();
60+
secret.setMetadata(new ObjectMetaBuilder()
61+
.withName(primary.getMetadata().getName())
62+
.withNamespace(primary.getMetadata().getNamespace())
63+
.build());
64+
secret.setData(Map.of("key", Base64.getEncoder().encodeToString("secretData".getBytes())));
65+
return secret;
66+
}
67+
}
68+
69+
public static class ConfigMapDependentResource extends
70+
CRUKubernetesDependentResource<ConfigMap, DependentResourceCrossRefResource> {
71+
72+
73+
public ConfigMapDependentResource() {
74+
super(ConfigMap.class);
75+
}
76+
77+
@Override
78+
protected ConfigMap desired(DependentResourceCrossRefResource primary,
79+
Context<DependentResourceCrossRefResource> context) {
80+
var secret = context.getSecondaryResource(Secret.class);
81+
if (secret.isEmpty()) {
82+
throw new IllegalStateException("Secret is empty");
83+
}
84+
ConfigMap configMap = new ConfigMap();
85+
configMap.setMetadata(new ObjectMetaBuilder()
86+
.withName(primary.getMetadata().getName())
87+
.withNamespace(primary.getMetadata().getNamespace())
88+
.build());
89+
configMap
90+
.setData(Map.of("secretKey", new ArrayList<>(secret.get().getData().keySet()).get(0)));
91+
return configMap;
92+
}
93+
}
94+
95+
96+
97+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.javaoperatorsdk.operator.sample.dependentresourcecrossref;
2+
3+
import io.fabric8.kubernetes.api.model.Namespaced;
4+
import io.fabric8.kubernetes.client.CustomResource;
5+
import io.fabric8.kubernetes.model.annotation.Group;
6+
import io.fabric8.kubernetes.model.annotation.Version;
7+
8+
@Group("sample.javaoperatorsdk")
9+
@Version("v1")
10+
public class DependentResourceCrossRefResource
11+
extends CustomResource<Void, DependentResourceCrossRefResourceStatus>
12+
implements Namespaced {
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package io.javaoperatorsdk.operator.sample.dependentresourcecrossref;
2+
3+
public class DependentResourceCrossRefResourceStatus {
4+
5+
}

0 commit comments

Comments
 (0)