From 436560419d6f3f7f2b930b5ab7d3636e3797383b Mon Sep 17 00:00:00 2001 From: Stephan Schroevers Date: Fri, 27 Dec 2024 06:18:47 +0100 Subject: [PATCH] Fix flaky `SlidingWindowTest` (#1242) Fixes issue #956. Signed-off-by: Stephan Schroevers --- .../metrics/core/metrics/SlidingWindow.java | 16 ++++++++++++++-- .../metrics/core/metrics/SlidingWindowTest.java | 8 ++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java index c9586e179..5360e3349 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java @@ -26,7 +26,7 @@ public class SlidingWindow { private int currentBucket; private long lastRotateTimestampMillis; private final long durationBetweenRotatesMillis; - LongSupplier currentTimeMillis = System::currentTimeMillis; // to be replaced in unit tests + private final LongSupplier currentTimeMillis; /** * Example: If the {@code maxAgeSeconds} is 60 and {@code ageBuckets} is 3, then 3 instances of @@ -39,13 +39,24 @@ public class SlidingWindow { * @param maxAgeSeconds after this amount of time an instance of T gets evicted. * @param ageBuckets number of age buckets. */ - @SuppressWarnings("unchecked") public SlidingWindow( Class clazz, Supplier constructor, ObjDoubleConsumer observeFunction, long maxAgeSeconds, int ageBuckets) { + this(clazz, constructor, observeFunction, maxAgeSeconds, ageBuckets, System::currentTimeMillis); + } + + // VisibleForTesting + @SuppressWarnings("unchecked") + SlidingWindow( + Class clazz, + Supplier constructor, + ObjDoubleConsumer observeFunction, + long maxAgeSeconds, + int ageBuckets, + LongSupplier currentTimeMillis) { this.constructor = constructor; this.observeFunction = observeFunction; this.ringBuffer = (T[]) Array.newInstance(clazz, ageBuckets); @@ -55,6 +66,7 @@ public SlidingWindow( this.currentBucket = 0; this.lastRotateTimestampMillis = currentTimeMillis.getAsLong(); this.durationBetweenRotatesMillis = TimeUnit.SECONDS.toMillis(maxAgeSeconds) / ageBuckets; + this.currentTimeMillis = currentTimeMillis; } /** Get the currently active instance of {@code T}. */ diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java index 334724a81..d85e5637c 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java @@ -48,8 +48,12 @@ public void setUp() { currentTimeMillis.set(startTime); ringBuffer = new SlidingWindow<>( - Observer.class, Observer::new, Observer::observe, maxAgeSeconds, ageBuckets); - ringBuffer.currentTimeMillis = currentTimeMillis::get; + Observer.class, + Observer::new, + Observer::observe, + maxAgeSeconds, + ageBuckets, + currentTimeMillis::get); } @Test