Skip to content

Commit 7be0f93

Browse files
Remove MockTimeProvider
- Remove `MockTimeProvider`. - Simplify `TimeProviderExtensions` to remove code that duplicates what the extensions in `Microsoft.Bcl.TimeProvider` do.
1 parent f7de3f0 commit 7be0f93

File tree

7 files changed

+81
-134
lines changed

7 files changed

+81
-134
lines changed

src/Polly.Core/Utils/TimeProviderExtensions.cs

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,41 +23,23 @@ public static Task DelayAsync(this TimeProvider timeProvider, TimeSpan delay, Re
2323

2424
context.CancellationToken.ThrowIfCancellationRequested();
2525

26-
if (context.IsSynchronous && timeProvider == TimeProvider.System)
26+
if (context.IsSynchronous)
2727
{
28-
// Stryker disable once boolean : no means to test this
29-
if (context.CancellationToken.CanBeCanceled)
30-
{
31-
context.CancellationToken.WaitHandle.WaitOne(delay);
32-
context.CancellationToken.ThrowIfCancellationRequested();
33-
}
34-
else
35-
{
36-
Thread.Sleep(delay);
37-
}
38-
39-
return Task.CompletedTask;
40-
}
41-
else
42-
{
43-
if (context.IsSynchronous)
44-
{
4528
#pragma warning disable CA1849 // For synchronous scenarios we want to return completed task
4629
#if NET8_0_OR_GREATER
47-
Task.Delay(delay, timeProvider, context.CancellationToken).GetAwaiter().GetResult();
30+
Task.Delay(delay, timeProvider, context.CancellationToken).GetAwaiter().GetResult();
4831
#else
49-
timeProvider.Delay(delay, context.CancellationToken).GetAwaiter().GetResult();
32+
timeProvider.Delay(delay, context.CancellationToken).GetAwaiter().GetResult();
5033
#endif
5134
#pragma warning restore CA1849
5235

53-
return Task.CompletedTask;
54-
}
36+
return Task.CompletedTask;
37+
}
5538

5639
#if NET8_0_OR_GREATER
57-
return Task.Delay(delay, timeProvider, context.CancellationToken);
40+
return Task.Delay(delay, timeProvider, context.CancellationToken);
5841
#else
59-
return timeProvider.Delay(delay, context.CancellationToken);
42+
return timeProvider.Delay(delay, context.CancellationToken);
6043
#endif
61-
}
6244
}
6345
}

test/Polly.Core.Tests/Helpers/MockTimeProvider.cs

Lines changed: 0 additions & 52 deletions
This file was deleted.

test/Polly.Core.Tests/Polly.Core.Tests.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="Polly.Contrib.WaitAndRetry" />
1413
<PackageReference Include="Microsoft.Bcl.TimeProvider"/>
14+
<PackageReference Include="Polly.Contrib.WaitAndRetry" />
1515
</ItemGroup>
1616

1717
<ItemGroup>
@@ -20,7 +20,7 @@
2020
</ItemGroup>
2121

2222
<ItemGroup>
23-
<Using Include="Polly.TestUtils" />
2423
<Using Include="Polly.Core.Tests.Helpers" />
24+
<Using Include="Polly.TestUtils" />
2525
</ItemGroup>
2626
</Project>

test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using FluentAssertions.Execution;
12
using Microsoft.Extensions.Time.Testing;
23
using Moq;
34
using Polly.Retry;
@@ -158,40 +159,76 @@ public void Retry_Infinite_Respected()
158159
[Fact]
159160
public async Task RetryDelayGenerator_Respected()
160161
{
161-
int calls = 0;
162-
_options.OnRetry = _ => { calls++; return default; };
162+
int retries = 0;
163+
int generatedValues = 0;
164+
165+
var delay = TimeSpan.FromMilliseconds(120);
166+
var provider = TimeProvider.System;
167+
163168
_options.ShouldHandle = _ => PredicateResult.True;
164169
_options.RetryCount = 3;
165170
_options.BackoffType = RetryBackoffType.Constant;
166-
_options.RetryDelayGenerator = _ => new ValueTask<TimeSpan>(TimeSpan.FromMilliseconds(123));
167-
var provider = new MockTimeProvider();
168-
provider.SetupCreateTimer(TimeSpan.FromMilliseconds(123));
169-
provider.Setup(p => p.GetTimestamp()).Returns(0);
170-
provider.Setup(p => p.TimestampFrequency).Returns(10000);
171171

172-
var sut = CreateSut(provider.Object);
172+
_options.OnRetry = _ =>
173+
{
174+
retries++;
175+
return default;
176+
};
177+
_options.RetryDelayGenerator = _ =>
178+
{
179+
generatedValues++;
180+
return new ValueTask<TimeSpan>(delay);
181+
};
182+
183+
var before = provider.GetUtcNow();
184+
185+
var sut = CreateSut(provider);
173186
await sut.ExecuteAsync(_ => default);
174187

175-
provider.VerifyAll();
188+
retries.Should().Be(3);
189+
generatedValues.Should().Be(3);
190+
191+
var after = provider.GetUtcNow();
192+
(after - before).Should().BeGreaterThanOrEqualTo(delay.Add(delay).Add(delay));
176193
}
177194

178195
[Fact]
179196
public async Task RetryDelayGenerator_ZeroDelay_NoTimeProviderCalls()
180197
{
181-
int calls = 0;
182-
_options.OnRetry = _ => { calls++; return default; };
198+
int retries = 0;
199+
int generatedValues = 0;
200+
201+
var delay = TimeSpan.Zero;
202+
var provider = new ThrowingFakeTimeProvider();
203+
183204
_options.ShouldHandle = _ => PredicateResult.True;
184-
_options.RetryCount = 1;
185-
_options.RetryDelayGenerator = _ => new ValueTask<TimeSpan>(TimeSpan.FromMilliseconds(0));
186-
var provider = new MockTimeProvider();
187-
provider.Setup(p => p.GetTimestamp()).Returns(0);
188-
provider.Setup(p => p.TimestampFrequency).Returns(10000);
205+
_options.RetryCount = 3;
206+
_options.BackoffType = RetryBackoffType.Constant;
189207

190-
var sut = CreateSut(provider.Object);
208+
_options.OnRetry = _ =>
209+
{
210+
retries++;
211+
return default;
212+
};
213+
_options.RetryDelayGenerator = _ =>
214+
{
215+
generatedValues++;
216+
return new ValueTask<TimeSpan>(delay);
217+
};
218+
219+
var sut = CreateSut(provider);
191220
await sut.ExecuteAsync(_ => default);
192221

193-
provider.VerifyAll();
194-
provider.VerifyNoOtherCalls();
222+
retries.Should().Be(3);
223+
generatedValues.Should().Be(3);
224+
}
225+
226+
private sealed class ThrowingFakeTimeProvider : FakeTimeProvider
227+
{
228+
public override DateTimeOffset GetUtcNow() => throw new AssertionFailedException("TimeProvider should not be used.");
229+
230+
public override ITimer CreateTimer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period)
231+
=> throw new AssertionFailedException("TimeProvider should not be used.");
195232
}
196233

197234
[Fact]

test/Polly.Core.Tests/Utils/TimeProviderExtensionsTests.cs

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,27 @@ namespace Polly.Core.Tests.Utils;
44

55
public class TimeProviderExtensionsTests
66
{
7-
[InlineData(false, false, false)]
8-
[InlineData(false, false, true)]
9-
[InlineData(false, true, true)]
10-
[InlineData(false, true, false)]
11-
[InlineData(true, false, false)]
12-
[InlineData(true, false, true)]
13-
[InlineData(true, true, true)]
14-
[InlineData(true, true, false)]
7+
[InlineData(false, false)]
8+
[InlineData(false, true)]
9+
[InlineData(true, false)]
10+
[InlineData(true, true)]
1511
[Theory]
16-
public async Task DelayAsync_System_Ok(bool synchronous, bool mocked, bool hasCancellation)
12+
public async Task DelayAsync_System_Ok(bool synchronous, bool hasCancellation)
1713
{
1814
using var tcs = new CancellationTokenSource();
1915
var token = hasCancellation ? tcs.Token : default;
2016
var delay = TimeSpan.FromMilliseconds(10);
21-
var mock = new MockTimeProvider();
22-
var timeProvider = mocked ? mock.Object : TimeProvider.System;
17+
var timeProvider = TimeProvider.System;
2318
var context = ResilienceContext.Get();
2419
context.Initialize<VoidResult>(isSynchronous: synchronous);
2520
context.CancellationToken = token;
26-
mock.SetupCreateTimer(delay);
2721

2822
await TestUtilities.AssertWithTimeoutAsync(async () =>
2923
{
3024
var task = timeProvider.DelayAsync(delay, context);
31-
task.IsCompleted.Should().Be(synchronous || mocked);
25+
task.IsCompleted.Should().Be(synchronous);
3226
await task;
3327
});
34-
35-
if (mocked)
36-
{
37-
mock.VerifyAll();
38-
}
3928
}
4029

4130
[Fact]
@@ -72,46 +61,38 @@ await TimeProvider.System
7261
});
7362
}
7463

75-
[InlineData(false, false)]
76-
[InlineData(false, true)]
77-
[InlineData(true, false)]
78-
[InlineData(true, true)]
64+
[InlineData(false)]
65+
[InlineData(true)]
7966
[Theory]
80-
public async Task DelayAsync_CancellationRequestedBefore_Throws(bool synchronous, bool mocked)
67+
public async Task DelayAsync_CancellationRequestedBefore_Throws(bool synchronous)
8168
{
8269
using var tcs = new CancellationTokenSource();
8370
tcs.Cancel();
8471
var token = tcs.Token;
8572
var delay = TimeSpan.FromMilliseconds(10);
86-
var mock = new MockTimeProvider();
87-
var timeProvider = mocked ? mock.Object : TimeProvider.System;
73+
var timeProvider = TimeProvider.System;
8874
var context = ResilienceContext.Get();
8975
context.Initialize<VoidResult>(isSynchronous: synchronous);
9076
context.CancellationToken = token;
91-
mock.SetupCreateTimer(delay);
9277

9378
await Assert.ThrowsAsync<OperationCanceledException>(() => timeProvider.DelayAsync(delay, context));
9479
}
9580

96-
[InlineData(false, false)]
97-
[InlineData(false, true)]
98-
[InlineData(true, false)]
99-
[InlineData(true, true)]
81+
[InlineData(false)]
82+
[InlineData(true)]
10083
[Theory]
101-
public async Task DelayAsync_CancellationAfter_Throws(bool synchronous, bool mocked)
84+
public async Task DelayAsync_CancellationAfter_Throws(bool synchronous)
10285
{
10386
var delay = TimeSpan.FromMilliseconds(20);
10487

10588
await TestUtilities.AssertWithTimeoutAsync(async () =>
10689
{
107-
var mock = new MockTimeProvider();
10890
using var tcs = new CancellationTokenSource();
10991
var token = tcs.Token;
110-
var timeProvider = mocked ? mock.Object : TimeProvider.System;
92+
var timeProvider = TimeProvider.System;
11193
var context = ResilienceContext.Get();
11294
context.Initialize<VoidResult>(isSynchronous: synchronous);
11395
context.CancellationToken = token;
114-
mock.SetupCreateTimerException(delay, new OperationCanceledException());
11596

11697
tcs.CancelAfter(TimeSpan.FromMilliseconds(5));
11798

test/Polly.Extensions.Tests/Polly.Extensions.Tests.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<Compile Include="..\Polly.Core.Tests\Helpers\MockTimeProvider.cs" Link="Utils\MockTimeProvider.cs" />
1413
<Compile Include="..\Polly.Core.Tests\Utils\ObjectPoolTests.cs" Link="Utils\ObjectPoolTests.cs" />
1514
</ItemGroup>
1615

test/Polly.TestUtils/Polly.TestUtils.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<ItemGroup>
1212
<Using Remove="System.Net.Http" />
1313
<ProjectReference Include="..\..\src\Polly.Core\Polly.Core.csproj" />
14-
<PackageReference Include="Moq" />
1514
<PackageReference Include="Microsoft.Extensions.Logging" />
15+
<PackageReference Include="Moq" />
1616
</ItemGroup>
1717
</Project>

0 commit comments

Comments
 (0)