Skip to content

Commit 57284ec

Browse files
committed
wip
Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
1 parent 7d69372 commit 57284ec

File tree

5 files changed

+72
-210
lines changed

5 files changed

+72
-210
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ReconcileUtils.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,13 +372,13 @@ public static <R extends HasMetadata> R resourcePatch(
372372
if (esList.isEmpty()) {
373373
throw new IllegalStateException("No event source found for type: " + resource.getClass());
374374
}
375+
var es = esList.get(0);
375376
if (esList.size() > 1) {
376-
throw new IllegalStateException(
377-
"Multiple event sources found for: "
378-
+ resource.getClass()
379-
+ " please provide the target event source");
377+
log.warn(
378+
"Multiple event source found for type: {}, selecting first with name {}",
379+
resource.getClass(),
380+
log.isWarnEnabled() ? es.name() : null);
380381
}
381-
var es = esList.get(0);
382382
if (es instanceof ManagedInformerEventSource mes) {
383383
return resourcePatch(resource, updateOperation, mes);
384384
} else {

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/ReconcileUtilsTest.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ void resourcePatchThrowsWhenNoEventSourceFound() {
406406
}
407407

408408
@Test
409-
void resourcePatchThrowsWhenMultipleEventSourcesFound() {
409+
void resourcePatchUsesFirstEventSourceIfMultipleEventSourcesPresent() {
410410
var resource = TestUtils.testCustomResource1();
411411
var eventSourceRetriever = mock(EventSourceRetriever.class);
412412
var eventSource1 = mock(ManagedInformerEventSource.class);
@@ -416,13 +416,10 @@ void resourcePatchThrowsWhenMultipleEventSourcesFound() {
416416
when(eventSourceRetriever.getEventSourcesFor(TestCustomResource.class))
417417
.thenReturn(List.of(eventSource1, eventSource2));
418418

419-
var exception =
420-
assertThrows(
421-
IllegalStateException.class,
422-
() -> ReconcileUtils.resourcePatch(context, resource, UnaryOperator.identity()));
419+
ReconcileUtils.resourcePatch(context, resource, UnaryOperator.identity());
423420

424-
assertThat(exception.getMessage()).contains("Multiple event sources found for");
425-
assertThat(exception.getMessage()).contains("please provide the target event source");
421+
verify(eventSource1, times(1))
422+
.eventFilteringUpdateAndCacheResource(any(), any(UnaryOperator.class));
426423
}
427424

428425
@Test

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/latestdistinct/LatestDistinctIT.java

Lines changed: 18 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
3030

3131
import static io.javaoperatorsdk.operator.baseapi.latestdistinct.LatestDistinctTestReconciler.LABEL_KEY;
32-
import static io.javaoperatorsdk.operator.baseapi.latestdistinct.LatestDistinctTestReconciler.LABEL_TYPE_1;
33-
import static io.javaoperatorsdk.operator.baseapi.latestdistinct.LatestDistinctTestReconciler.LABEL_TYPE_2;
3432
import static org.assertj.core.api.Assertions.assertThat;
3533
import static org.awaitility.Awaitility.await;
3634

@@ -47,11 +45,10 @@ class LatestDistinctIT {
4745

4846
public static final String TEST_RESOURCE_NAME = "test-resource";
4947
public static final String CONFIG_MAP_1 = "config-map-1";
50-
public static final String CONFIG_MAP_2 = "config-map-2";
51-
public static final String CONFIG_MAP_3 = "config-map-3";
48+
public static final String DEFAULT_VALUE = "defaultValue";
5249

5350
@RegisterExtension
54-
LocallyRunOperatorExtension operator =
51+
LocallyRunOperatorExtension extension =
5552
LocallyRunOperatorExtension.builder()
5653
.withReconciler(LatestDistinctTestReconciler.class)
5754
.build();
@@ -60,152 +57,61 @@ class LatestDistinctIT {
6057
void testLatestDistinctListWithTwoInformerEventSources() {
6158
// Create the custom resource
6259
var resource = createTestCustomResource();
63-
operator.create(resource);
60+
resource = extension.create(resource);
6461

6562
// Create ConfigMaps with type1 label (watched by first event source)
66-
var cm1 = createConfigMap(CONFIG_MAP_1, LABEL_TYPE_1, resource, "value1");
67-
operator.create(cm1);
68-
69-
var cm2 = createConfigMap(CONFIG_MAP_2, LABEL_TYPE_1, resource, "value2");
70-
operator.create(cm2);
71-
72-
// Create ConfigMap with type2 label (watched by second event source)
73-
var cm3 = createConfigMap(CONFIG_MAP_3, LABEL_TYPE_2, resource, "value3");
74-
operator.create(cm3);
63+
var cm1 = createConfigMap(CONFIG_MAP_1, resource);
64+
extension.create(cm1);
7565

7666
// Wait for reconciliation
77-
var reconciler = operator.getReconcilerOfType(LatestDistinctTestReconciler.class);
67+
var reconciler = extension.getReconcilerOfType(LatestDistinctTestReconciler.class);
7868
await()
7969
.atMost(Duration.ofSeconds(5))
8070
.pollDelay(Duration.ofMillis(300))
8171
.untilAsserted(
8272
() -> {
83-
assertThat(reconciler.getNumberOfExecutions()).isGreaterThanOrEqualTo(1);
8473
var updatedResource =
85-
operator.get(LatestDistinctTestResource.class, TEST_RESOURCE_NAME);
74+
extension.get(LatestDistinctTestResource.class, TEST_RESOURCE_NAME);
8675
assertThat(updatedResource.getStatus()).isNotNull();
8776
// Should see 3 distinct ConfigMaps
88-
assertThat(updatedResource.getStatus().getConfigMapCount()).isEqualTo(3);
89-
assertThat(updatedResource.getStatus().getDataFromConfigMaps())
90-
.isEqualTo("value1,value2,value3");
91-
// Verify ReconcileUtils was used
92-
assertThat(updatedResource.getStatus().isReconcileUtilsCalled()).isTrue();
93-
});
94-
95-
// Verify distinct ConfigMap names
96-
assertThat(reconciler.getDistinctConfigMapNames())
97-
.containsExactlyInAnyOrder(CONFIG_MAP_1, CONFIG_MAP_2, CONFIG_MAP_3);
98-
}
99-
100-
@Test
101-
void testLatestDistinctDeduplication() {
102-
// Create the custom resource
103-
var resource = createTestCustomResource();
104-
operator.create(resource);
105-
106-
// Create a ConfigMap with type1 label
107-
var cm1 = createConfigMap(CONFIG_MAP_1, LABEL_TYPE_1, resource, "initialValue");
108-
operator.create(cm1);
109-
110-
// Wait for initial reconciliation
111-
var reconciler = operator.getReconcilerOfType(LatestDistinctTestReconciler.class);
112-
await()
113-
.atMost(Duration.ofSeconds(5))
114-
.pollDelay(Duration.ofMillis(300))
115-
.untilAsserted(
116-
() -> {
117-
var updatedResource =
118-
operator.get(LatestDistinctTestResource.class, TEST_RESOURCE_NAME);
119-
assertThat(updatedResource.getStatus()).isNotNull();
12077
assertThat(updatedResource.getStatus().getConfigMapCount()).isEqualTo(1);
121-
assertThat(updatedResource.getStatus().getDataFromConfigMaps())
122-
.isEqualTo("initialValue");
78+
assertThat(reconciler.isErrorOccurred()).isFalse();
79+
// note that since there are two event source, and we do the update through one event
80+
// source
81+
// the other will still propagate an event
82+
assertThat(reconciler.getNumberOfExecutions()).isEqualTo(2);
12383
});
124-
125-
int executionsBeforeUpdate = reconciler.getNumberOfExecutions();
126-
127-
// Update the ConfigMap
128-
cm1 = operator.get(ConfigMap.class, CONFIG_MAP_1);
129-
cm1.getData().put("key", "updatedValue");
130-
operator.replace(cm1);
131-
132-
// Wait for reconciliation after update
133-
await()
134-
.atMost(Duration.ofSeconds(5))
135-
.pollDelay(Duration.ofMillis(300))
136-
.untilAsserted(
137-
() -> {
138-
assertThat(reconciler.getNumberOfExecutions()).isGreaterThan(executionsBeforeUpdate);
139-
var updatedResource =
140-
operator.get(LatestDistinctTestResource.class, TEST_RESOURCE_NAME);
141-
assertThat(updatedResource.getStatus()).isNotNull();
142-
// Still should see only 1 distinct ConfigMap (same name, updated version)
143-
assertThat(updatedResource.getStatus().getConfigMapCount()).isEqualTo(1);
144-
assertThat(updatedResource.getStatus().getDataFromConfigMaps())
145-
.isEqualTo("updatedValue");
146-
});
147-
}
148-
149-
@Test
150-
void testReconcileUtilsServerSideApply() {
151-
// Create the custom resource with initial spec value
152-
var resource = createTestCustomResource();
153-
resource.getSpec().setValue("initialSpecValue");
154-
operator.create(resource);
155-
156-
// Create a ConfigMap
157-
var cm1 = createConfigMap(CONFIG_MAP_1, LABEL_TYPE_1, resource, "value1");
158-
operator.create(cm1);
159-
160-
// Wait for reconciliation
161-
var reconciler = operator.getReconcilerOfType(LatestDistinctTestReconciler.class);
162-
await()
163-
.atMost(Duration.ofSeconds(5))
164-
.pollDelay(Duration.ofMillis(300))
165-
.untilAsserted(
166-
() -> {
167-
var updatedResource =
168-
operator.get(LatestDistinctTestResource.class, TEST_RESOURCE_NAME);
169-
assertThat(updatedResource.getStatus()).isNotNull();
170-
assertThat(updatedResource.getStatus().isReconcileUtilsCalled()).isTrue();
171-
// Verify that the status was updated using ReconcileUtils.serverSideApplyStatus
172-
assertThat(updatedResource.getStatus().getConfigMapCount()).isEqualTo(1);
173-
});
174-
175-
// Verify no errors occurred
176-
assertThat(reconciler.isErrorOccurred()).isFalse();
17784
}
17885

17986
private LatestDistinctTestResource createTestCustomResource() {
18087
var resource = new LatestDistinctTestResource();
18188
resource.setMetadata(
18289
new ObjectMetaBuilder()
18390
.withName(TEST_RESOURCE_NAME)
184-
.withNamespace(operator.getNamespace())
91+
.withNamespace(extension.getNamespace())
18592
.build());
18693
resource.setSpec(new LatestDistinctTestResourceSpec());
18794
return resource;
18895
}
18996

190-
private ConfigMap createConfigMap(
191-
String name, String labelValue, LatestDistinctTestResource owner, String dataValue) {
97+
private ConfigMap createConfigMap(String name, LatestDistinctTestResource owner) {
19298
Map<String, String> labels = new HashMap<>();
193-
labels.put(LABEL_KEY, labelValue);
99+
labels.put(LABEL_KEY, "val");
194100

195101
Map<String, String> data = new HashMap<>();
196-
data.put("key", dataValue);
102+
data.put("key", DEFAULT_VALUE);
197103

198104
return new ConfigMapBuilder()
199105
.withMetadata(
200106
new ObjectMetaBuilder()
201107
.withName(name)
202-
.withNamespace(operator.getNamespace())
108+
.withNamespace(extension.getNamespace())
203109
.withLabels(labels)
204110
.build())
205111
.withData(data)
206112
.withNewMetadata()
207113
.withName(name)
208-
.withNamespace(operator.getNamespace())
114+
.withNamespace(extension.getNamespace())
209115
.withLabels(labels)
210116
.addNewOwnerReference()
211117
.withApiVersion(owner.getApiVersion())

0 commit comments

Comments
 (0)