From ea1f6808cc3bbe45bc1ed1de50bf074a2905eb08 Mon Sep 17 00:00:00 2001 From: shuke <37901441+shuke987@users.noreply.github.com> Date: Wed, 22 Jul 2026 14:39:17 +0800 Subject: [PATCH 1/2] [test](fe) Stabilize async cache refresh test ### What problem does this PR solve?\n\nIssue Number: None\n\nThe test used a fixed 2.5 second sleep to wait for a two-second asynchronous refresh, which can observe a legal in-flight refresh under CI scheduling delay. Wait for the existing counter oracle with a bounded timeout instead.\n\n### Release note\n\nNone\n\n### Check List\n\n- [x] Test-only change\n- [x] Target test repeated 10 times\n- [x] Full CacheFactoryTest repeated twice --- .../test/java/org/apache/doris/common/CacheFactoryTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/common/CacheFactoryTest.java b/fe/fe-core/src/test/java/org/apache/doris/common/CacheFactoryTest.java index 090dad2978ec36..f4950ffd147c3d 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/common/CacheFactoryTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/common/CacheFactoryTest.java @@ -23,6 +23,7 @@ import com.github.benmanes.caffeine.cache.LoadingCache; import com.google.common.collect.Lists; import com.google.common.testing.FakeTicker; +import org.awaitility.Awaitility; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -237,8 +238,8 @@ public void testAsyncLoadingCacheWithExpireAfterWrite() throws InterruptedExcept // refresh in background, so still get value1 Assertions.assertTrue(futureValue.isDone()); Assertions.assertEquals("value1", futureValue.get().get().getValue()); - // sleep longer to wait for refresh - Thread.sleep(2500); + // Wait for the refresh triggered above instead of relying on executor scheduling time. + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> counter.get() == 2); futureValue = loadingCache.get(1); Assertions.assertEquals("value1", futureValue.get().get().getValue()); // refreshed, so counter +1 From 25e9e9a117be2cfdc254bcec754209c7d51c5374 Mon Sep 17 00:00:00 2001 From: shuke <37901441+shuke987@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:41:32 +0800 Subject: [PATCH 2/2] [test](fe) Wait for async cache refresh publication ### What problem does this PR solve?\n\nIssue Number: None\n\nThe review identified that the loader counter can advance before the refreshed future is published to Caffeine. Wait until the cache exposes a different completed future before advancing fake time.\n\n### Release note\n\nNone\n\n### Check List\n\n- [x] Target test repeated 10 times\n- [x] Full CacheFactoryTest repeated twice --- .../java/org/apache/doris/common/CacheFactoryTest.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/common/CacheFactoryTest.java b/fe/fe-core/src/test/java/org/apache/doris/common/CacheFactoryTest.java index f4950ffd147c3d..ebc66cf8cf41dd 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/common/CacheFactoryTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/common/CacheFactoryTest.java @@ -231,6 +231,7 @@ public void testAsyncLoadingCacheWithExpireAfterWrite() throws InterruptedExcept Assertions.assertTrue(futureValue.isDone()); Assertions.assertEquals("value1", futureValue.get().get().getValue()); Assertions.assertEquals(1, counter.get()); + CompletableFuture> cachedFuture = futureValue; // advance 11 seconds to pass the refreshAfterWrite ticker.advance(11, TimeUnit.SECONDS); // trigger refresh @@ -238,8 +239,11 @@ public void testAsyncLoadingCacheWithExpireAfterWrite() throws InterruptedExcept // refresh in background, so still get value1 Assertions.assertTrue(futureValue.isDone()); Assertions.assertEquals("value1", futureValue.get().get().getValue()); - // Wait for the refresh triggered above instead of relying on executor scheduling time. - Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> counter.get() == 2); + // Wait until the refresh is published to the cache instead of observing loader-side progress. + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> { + CompletableFuture> refreshedFuture = loadingCache.get(1); + return refreshedFuture != cachedFuture && refreshedFuture.isDone(); + }); futureValue = loadingCache.get(1); Assertions.assertEquals("value1", futureValue.get().get().getValue()); // refreshed, so counter +1