Skip to content

Commit be22a88

Browse files
committed
test: failing test for EventFilterWindow coalesced foreign spec change (#3455)
When a controller's SSA patch merges with a concurrent foreign spec change, the informer can coalesce both events into a single event at the own-write RV. EventFilterWindow sees relatedEvents == ownResourceVersions and silently drops the event, causing the controller to miss the foreign change entirely (stuck until maxReconciliationInterval). The test is @disabled pending a fix — it documents the expected behaviour that events carrying a generation change should propagate even when their RV matches the controller's own write. Assisted-by: Claude claude-opus-4-6 <noreply@anthropic.com> Signed-off-by: Sam Barker <sam@quadrocket.co.uk>
1 parent f1237ba commit be22a88

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/informer/EventFilterWindowTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,38 @@ void reListBetweenTwoUpdates() {
537537
assertThat(eventFilterWindow.canBeRemoved()).isTrue();
538538
}
539539

540+
@Test
541+
@Disabled("EventFilterWindow drops coalesced foreign spec changes — #3455")
542+
void coalescedForeignSpecChangeShouldNotBeFilteredByOwnWriteRV() {
543+
// Reproduces the scenario where a controller's SSA patch merges with a concurrent
544+
// foreign spec change. The informer coalesces both events into one at the own-write RV.
545+
//
546+
// Real-world sequence (from Kroxylicious GHA failure):
547+
// 1. Controller reconciles resource at gen=1
548+
// 2. Foreign actor changes spec → gen=2 → new RV on API server
549+
// 3. Controller's SSA patchResource merges on top → returns RV=5 (gen=2)
550+
// 4. Informer coalesces both events (same resource key) into one at RV=5
551+
// 5. EventFilterWindow sees relatedEvents={5} == ownResourceVersions={5} → drops
552+
// 6. Controller never learns about gen=2 → stuck until maxReconciliationInterval
553+
eventFilterWindow.increaseActiveUpdates();
554+
eventFilterWindow.addToOwnUpdateVersions(s(FIRST_OWN_VERSION));
555+
556+
var resource = testResource(FIRST_OWN_VERSION);
557+
resource.getMetadata().setGeneration(2L);
558+
var previousResource = testResource(FIRST_OWN_VERSION - 1);
559+
previousResource.getMetadata().setGeneration(1L);
560+
eventFilterWindow.addRelatedEvent(
561+
new ExtendedResourceEvent(UPDATED, resource, previousResource, null));
562+
563+
eventFilterWindow.decreaseActiveUpdates();
564+
565+
assertThat(eventFilterWindow.check())
566+
.as(
567+
"Event at own-write RV with generation change (1→2) should propagate:"
568+
+ " a foreign spec change was coalesced with the own-write echo")
569+
.isPresent();
570+
}
571+
540572
@Test
541573
void combinedCaseWithEarlyEvent() {
542574
// Scenario: an own write is in flight (RV recorded), a foreign event with a

0 commit comments

Comments
 (0)