From 818cb42906e003c67e5c902da5fbedab89412c2b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 07:00:59 +0000 Subject: [PATCH 1/5] Stabilize discrete policy touch tick test Agent-Logs-Url: https://github.com/bitfaster/BitFaster.Caching/sessions/9dea696c-9322-4f51-9c6b-4c54780aee47 Co-authored-by: bitfaster <12851828+bitfaster@users.noreply.github.com> --- BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs b/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs index 1c99c1b9..5440990c 100644 --- a/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs @@ -68,7 +68,13 @@ public async Task TouchUpdatesTicksCount() { var item = this.policy.CreateItem(1, 2); var tc = item.TickCount; - await Task.Delay(TimeSpan.FromMilliseconds(1)); + + // Poll until the underlying tick source advances to avoid 1ms timer granularity issues on Windows CI. + var timeout = DateTime.UtcNow.AddSeconds(1); + while (Duration.SinceEpoch().raw == tc && DateTime.UtcNow < timeout) + { + await Task.Delay(TimeSpan.FromMilliseconds(1)); + } this.policy.ShouldDiscard(item); // set the time in the policy this.policy.Touch(item); From 3561802b80e4c17acced3a6f65a09eabf5ecc373 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 07:03:43 +0000 Subject: [PATCH 2/5] Fix discrete policy polling baseline Agent-Logs-Url: https://github.com/bitfaster/BitFaster.Caching/sessions/9dea696c-9322-4f51-9c6b-4c54780aee47 Co-authored-by: bitfaster <12851828+bitfaster@users.noreply.github.com> --- BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs b/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs index 5440990c..6a57eece 100644 --- a/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs @@ -68,10 +68,11 @@ public async Task TouchUpdatesTicksCount() { var item = this.policy.CreateItem(1, 2); var tc = item.TickCount; + var createdAt = tc - TestExpiryCalculator.DefaultTimeToExpire.raw; // Poll until the underlying tick source advances to avoid 1ms timer granularity issues on Windows CI. var timeout = DateTime.UtcNow.AddSeconds(1); - while (Duration.SinceEpoch().raw == tc && DateTime.UtcNow < timeout) + while (Duration.SinceEpoch().raw == createdAt && DateTime.UtcNow < timeout) { await Task.Delay(TimeSpan.FromMilliseconds(1)); } From 33ccd95fa66e8e9a5eab0eae696fd17566bb08f6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 07:10:14 +0000 Subject: [PATCH 3/5] Assert tick source advances before touch Agent-Logs-Url: https://github.com/bitfaster/BitFaster.Caching/sessions/9dea696c-9322-4f51-9c6b-4c54780aee47 Co-authored-by: bitfaster <12851828+bitfaster@users.noreply.github.com> --- BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs b/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs index 6a57eece..fba808c2 100644 --- a/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs @@ -77,6 +77,8 @@ public async Task TouchUpdatesTicksCount() await Task.Delay(TimeSpan.FromMilliseconds(1)); } + Duration.SinceEpoch().raw.Should().BeGreaterThan(createdAt); + this.policy.ShouldDiscard(item); // set the time in the policy this.policy.Touch(item); From bbe3cf8956445a180557f5a7b14b4a125d80c585 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 07:15:20 +0000 Subject: [PATCH 4/5] Rename discrete policy touch test Agent-Logs-Url: https://github.com/bitfaster/BitFaster.Caching/sessions/9dea696c-9322-4f51-9c6b-4c54780aee47 Co-authored-by: bitfaster <12851828+bitfaster@users.noreply.github.com> --- BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs b/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs index fba808c2..db201e91 100644 --- a/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs @@ -64,7 +64,7 @@ public void TouchUpdatesItemWasAccessed() } [RetryFact] - public async Task TouchUpdatesTicksCount() + public async Task Touch_WhenTickCountAdvances_UpdatesTicksCount() { var item = this.policy.CreateItem(1, 2); var tc = item.TickCount; From bc1d17fa5f1f7d0806b2925e6a2b51a8675ce351 Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Mon, 13 Apr 2026 10:05:48 -0700 Subject: [PATCH 5/5] cleanup --- .../Lru/DiscretePolicyTests.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs b/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs index db201e91..cbd8d8e5 100644 --- a/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/DiscretePolicyTests.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using BitFaster.Caching.Lru; using BitFaster.Caching.UnitTests.Retry; @@ -64,22 +65,19 @@ public void TouchUpdatesItemWasAccessed() } [RetryFact] - public async Task Touch_WhenTickCountAdvances_UpdatesTicksCount() + public async Task TouchUpdatesTicksCount() { var item = this.policy.CreateItem(1, 2); var tc = item.TickCount; - var createdAt = tc - TestExpiryCalculator.DefaultTimeToExpire.raw; - // Poll until the underlying tick source advances to avoid 1ms timer granularity issues on Windows CI. + var createdAt = tc - TestExpiryCalculator.DefaultTimeToExpire.raw; var timeout = DateTime.UtcNow.AddSeconds(1); while (Duration.SinceEpoch().raw == createdAt && DateTime.UtcNow < timeout) { await Task.Delay(TimeSpan.FromMilliseconds(1)); } - Duration.SinceEpoch().raw.Should().BeGreaterThan(createdAt); - - this.policy.ShouldDiscard(item); // set the time in the policy + this.policy.ShouldDiscard(item); // advance time this.policy.Touch(item); item.TickCount.Should().BeGreaterThan(tc); @@ -91,7 +89,12 @@ public async Task UpdateUpdatesTickCount() var item = this.policy.CreateItem(1, 2); var tc = item.TickCount; - await Task.Delay(TimeSpan.FromMilliseconds(20)); + var createdAt = item.TickCount - TestExpiryCalculator.DefaultTimeToExpire.raw; + var timeout = DateTime.UtcNow.AddSeconds(1); + while (Duration.SinceEpoch().raw == createdAt && DateTime.UtcNow < timeout) + { + await Task.Delay(TimeSpan.FromMilliseconds(20)); + } this.policy.Update(item);