From 8c7c91f4071b4ca83e930a41f0076f03c242d27e Mon Sep 17 00:00:00 2001 From: flrnd <659650+flrnd@users.noreply.github.com> Date: Sat, 17 Oct 2026 12:37:15 +0200 Subject: [PATCH] fix(tests): make event correlation timestamps deterministic Replace Thread.sleep(100) with explicit timestamp increments in EventCorrelatorTest. Duplicate events preserve their input timestamps, so advancing those timestamps is sufficient to verify compression. Aggregated events, however, generate their own timestamps using OffsetDateTime.now(). Consecutive calls can return identical values depending on system clock resolution, causing intermittent CI failures on Windows. Following the approach used by the Go client, introduce an injectable timestamp source in EventAggregator using Supplier. Add a corresponding EventCorrelator constructor to pass the supplier through, while preserving the existing constructors and production behaviour with OffsetDateTime::now. Use an incrementing timestamp supplier in the test to control aggregation timestamps independently of the system clock. This preserves the existing timestamp assertions, removes the timing dependency, and avoids changes to EventLogger. --- .../extended/event/legacy/EventAggregator.java | 16 ++++++++++++++-- .../extended/event/legacy/EventCorrelator.java | 11 ++++++++++- .../extended/event/EventCorrelatorTest.java | 11 +++++++---- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/extended/src/main/java/io/kubernetes/client/extended/event/legacy/EventAggregator.java b/extended/src/main/java/io/kubernetes/client/extended/event/legacy/EventAggregator.java index f4bd4f9c76..a231eddc7f 100644 --- a/extended/src/main/java/io/kubernetes/client/extended/event/legacy/EventAggregator.java +++ b/extended/src/main/java/io/kubernetes/client/extended/event/legacy/EventAggregator.java @@ -22,6 +22,8 @@ import java.util.Objects; import java.util.Set; import java.util.function.Function; +import java.util.function.Supplier; + import org.apache.commons.lang3.tuple.MutablePair; public class EventAggregator { @@ -30,10 +32,19 @@ public class EventAggregator { public static final java.time.Duration DEFAULT_EVENT_AGGREGATE_CACHE_EXPIRATION = java.time.Duration.ofSeconds(600); + public EventAggregator( + int maxLRUCacheEntries, + Function> keyFunc, + Function messageFunc) { + this(maxLRUCacheEntries, keyFunc, messageFunc, OffsetDateTime::now); + } + public EventAggregator( int maxLRUCacheEntries, Function> keyFunc, - Function messageFunc) { + Function messageFunc, + Supplier now) { + this.now = now; this.keyFunc = keyFunc; this.messageFunc = messageFunc; this.maxEvents = DEFAULT_MAX_EVENT_LOCAL_KEYS; @@ -47,11 +58,12 @@ public EventAggregator( private Cache spammingCache; private Function> keyFunc; private Function messageFunc; + private final Supplier now; private final int maxEvents; public synchronized MutablePair aggregate(CoreV1Event event) { - OffsetDateTime now = OffsetDateTime.now(); + OffsetDateTime now = this.now.get(); MutablePair aggregatedKeys = keyFunc.apply(event); String aggregatedKey = aggregatedKeys.getLeft(); diff --git a/extended/src/main/java/io/kubernetes/client/extended/event/legacy/EventCorrelator.java b/extended/src/main/java/io/kubernetes/client/extended/event/legacy/EventCorrelator.java index 69d577cb49..9a128ceb0e 100644 --- a/extended/src/main/java/io/kubernetes/client/extended/event/legacy/EventCorrelator.java +++ b/extended/src/main/java/io/kubernetes/client/extended/event/legacy/EventCorrelator.java @@ -14,8 +14,12 @@ import io.kubernetes.client.custom.V1Patch; import io.kubernetes.client.openapi.models.CoreV1Event; + +import java.time.OffsetDateTime; import java.util.Optional; import java.util.function.Predicate; +import java.util.function.Supplier; + import org.apache.commons.lang3.tuple.MutablePair; public class EventCorrelator { @@ -25,6 +29,10 @@ public class EventCorrelator { protected EventLogger logger; public EventCorrelator() { + this(OffsetDateTime::now); + } + + public EventCorrelator(Supplier now) { final int maxLRUCacheEntries = 4096; this.filter = new EventSpamFilter(maxLRUCacheEntries, EventUtils::getSpamKey)::filter; @@ -32,7 +40,8 @@ public EventCorrelator() { new EventAggregator( maxLRUCacheEntries, EventUtils::getAggregatedAndLocalKeyByReason, - EventUtils::getAggregatedMessageByReason); + EventUtils::getAggregatedMessageByReason, + now); this.logger = new EventLogger(maxLRUCacheEntries, EventUtils::getEventKey); } diff --git a/extended/src/test/java/io/kubernetes/client/extended/event/EventCorrelatorTest.java b/extended/src/test/java/io/kubernetes/client/extended/event/EventCorrelatorTest.java index 49309a9fa9..e167cd4bed 100644 --- a/extended/src/test/java/io/kubernetes/client/extended/event/EventCorrelatorTest.java +++ b/extended/src/test/java/io/kubernetes/client/extended/event/EventCorrelatorTest.java @@ -32,6 +32,8 @@ import java.util.Collection; import java.util.List; import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; + import org.apache.commons.lang3.tuple.MutablePair; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -143,9 +145,11 @@ void eventCorrelate( CoreV1Event expectedEvent, Boolean expectedSkip) throws Exception { - EventCorrelator correlator = new EventCorrelator(); + AtomicReference time = + new AtomicReference<>(OffsetDateTime.now()); + EventCorrelator correlator = new EventCorrelator(() -> time.getAndUpdate(t -> t.plusSeconds(1))); + OffsetDateTime now = OffsetDateTime.now(); for (CoreV1Event event : previousEvents) { - OffsetDateTime now = OffsetDateTime.now(); event.setFirstTimestamp(now); event.setLastTimestamp(now); Optional> result = correlator.correlate(event); @@ -153,8 +157,7 @@ void eventCorrelate( correlator.updateState(event); } } - Thread.sleep(100); - OffsetDateTime now = OffsetDateTime.now(); + now = now.plusSeconds(1); newEvent.setFirstTimestamp(now); newEvent.setLastTimestamp(now); Optional> result = correlator.correlate(newEvent);