diff --git a/src/Snippets/Docs/Testing.cs b/src/Snippets/Docs/Testing.cs index 472e5b4e2d9..8dbbf4ebc11 100644 --- a/src/Snippets/Docs/Testing.cs +++ b/src/Snippets/Docs/Testing.cs @@ -82,6 +82,7 @@ public static void PipelineProviderProviderMocking() } } +#pragma warning disable IDE0290 #region testing-resilience-pipeline-provider-usage // Represents an arbitrary API that needs resilience support @@ -124,3 +125,4 @@ public static IServiceCollection AddMyApi(this IServiceCollection services) } #endregion +#pragma warning restore IDE0290 diff --git a/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs b/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs index 70f9dc128bc..06f53ec8fad 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs @@ -54,7 +54,7 @@ public void Ctor_Message_RetryAfter_InnerException_Ok() exception.RetryAfter.Should().Be(TestRetryAfter); } -#if !NETCOREAPP +#if NETFRAMEWORK [Fact] public void BinarySerialization_NonNullRetryAfter_Ok() { diff --git a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerManualControlTests.cs b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerManualControlTests.cs index c809dc5a56b..0f8531dd2fb 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerManualControlTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerManualControlTests.cs @@ -29,11 +29,12 @@ public void Ctor_Isolated(bool isolated) [Theory] public async Task IsolateAsync_NotInitialized_Ok(bool closedAfter) { + var cancellationToken = CancellationToken.None; var control = new CircuitBreakerManualControl(); - await control.IsolateAsync(); + await control.IsolateAsync(cancellationToken); if (closedAfter) { - await control.CloseAsync(); + await control.CloseAsync(cancellationToken); } var isolated = false; @@ -56,7 +57,7 @@ public async Task ResetAsync_NotInitialized_Ok() var control = new CircuitBreakerManualControl(); await control - .Invoking(c => c.CloseAsync(CancellationToken.None)) + .Invoking(c => c.CloseAsync()) .Should() .NotThrowAsync(); } @@ -65,12 +66,13 @@ await control public async Task Initialize_Twice_Ok() { int called = 0; + var cancellationToken = CancellationToken.None; var control = new CircuitBreakerManualControl(); control.Initialize(_ => Task.CompletedTask, _ => Task.CompletedTask); control.Initialize(_ => { called++; return Task.CompletedTask; }, _ => { called++; return Task.CompletedTask; }); - await control.IsolateAsync(); - await control.CloseAsync(); + await control.IsolateAsync(cancellationToken); + await control.CloseAsync(cancellationToken); called.Should().Be(2); } @@ -79,16 +81,17 @@ public async Task Initialize_Twice_Ok() public async Task Initialize_DisposeRegistration_ShuldBeCancelled() { int called = 0; + var cancellationToken = CancellationToken.None; var control = new CircuitBreakerManualControl(); var reg = control.Initialize(_ => { called++; return Task.CompletedTask; }, _ => { called++; return Task.CompletedTask; }); - await control.IsolateAsync(); - await control.CloseAsync(); + await control.IsolateAsync(cancellationToken); + await control.CloseAsync(cancellationToken); reg.Dispose(); - await control.IsolateAsync(); - await control.CloseAsync(); + await control.IsolateAsync(cancellationToken); + await control.CloseAsync(cancellationToken); called.Should().Be(2); } @@ -96,6 +99,7 @@ public async Task Initialize_DisposeRegistration_ShuldBeCancelled() [Fact] public async Task Initialize_Ok() { + var cancellationToken = CancellationToken.None; var control = new CircuitBreakerManualControl(); var isolateCalled = false; var resetCalled = false; @@ -116,8 +120,8 @@ public async Task Initialize_Ok() return Task.CompletedTask; }); - await control.IsolateAsync(CancellationToken.None); - await control.CloseAsync(CancellationToken.None); + await control.IsolateAsync(cancellationToken); + await control.CloseAsync(cancellationToken); isolateCalled.Should().BeTrue(); resetCalled.Should().BeTrue(); diff --git a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerPredicateArgumentsTests.cs b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerPredicateArgumentsTests.cs index 8f2a25b23b0..91e2f66c206 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerPredicateArgumentsTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerPredicateArgumentsTests.cs @@ -2,12 +2,14 @@ namespace Polly.Core.Tests.CircuitBreaker; -public class CircuitBreakerPredicateArgumentsTests +public static class CircuitBreakerPredicateArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new CircuitBreakerPredicateArguments(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1)); + var args = new CircuitBreakerPredicateArguments( + ResilienceContextPool.Shared.Get(CancellationToken.None), + Outcome.FromResult(1)); args.Context.Should().NotBeNull(); args.Outcome.Result.Should().Be(1); diff --git a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs index c5c1c809a83..2db44c34080 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs @@ -64,6 +64,7 @@ public void AddCircuitBreaker_Validation() [Fact] public void AddCircuitBreaker_IntegrationTest() { + var cancellationToken = CancellationToken.None; int opened = 0; int closed = 0; int halfOpened = 0; @@ -88,14 +89,14 @@ public void AddCircuitBreaker_IntegrationTest() for (int i = 0; i < 10; i++) { - strategy.Execute(_ => -1); + strategy.Execute(_ => -1, cancellationToken); } // Circuit opened opened.Should().Be(1); halfOpened.Should().Be(0); closed.Should().Be(0); - BrokenCircuitException exception = Assert.Throws(() => strategy.Execute(_ => 0)); + BrokenCircuitException exception = Assert.Throws(() => strategy.Execute(_ => 0, cancellationToken)); exception.RetryAfter.Should().Be(breakDuration); // Circuit still open after some time @@ -103,13 +104,13 @@ public void AddCircuitBreaker_IntegrationTest() opened.Should().Be(1); halfOpened.Should().Be(0); closed.Should().Be(0); - exception = Assert.Throws(() => strategy.Execute(_ => 0)); + exception = Assert.Throws(() => strategy.Execute(_ => 0, cancellationToken)); exception.RetryAfter.Should().Be(halfBreakDuration); // Circuit Half Opened timeProvider.Advance(halfBreakDuration); - strategy.Execute(_ => -1); - exception = Assert.Throws(() => strategy.Execute(_ => 0)); + strategy.Execute(_ => -1, cancellationToken); + exception = Assert.Throws(() => strategy.Execute(_ => 0, cancellationToken)); opened.Should().Be(2); halfOpened.Should().Be(1); closed.Should().Be(0); @@ -117,7 +118,7 @@ public void AddCircuitBreaker_IntegrationTest() // Now close it timeProvider.Advance(breakDuration); - strategy.Execute(_ => 0); + strategy.Execute(_ => 0, cancellationToken); opened.Should().Be(2); halfOpened.Should().Be(2); closed.Should().Be(1); @@ -126,6 +127,7 @@ public void AddCircuitBreaker_IntegrationTest() [Fact] public void AddCircuitBreaker_IntegrationTest_WithBreakDurationGenerator() { + var cancellationToken = CancellationToken.None; int opened = 0; int closed = 0; int halfOpened = 0; @@ -151,14 +153,14 @@ public void AddCircuitBreaker_IntegrationTest_WithBreakDurationGenerator() for (int i = 0; i < 10; i++) { - strategy.Execute(_ => -1); + strategy.Execute(_ => -1, cancellationToken); } // Circuit opened opened.Should().Be(1); halfOpened.Should().Be(0); closed.Should().Be(0); - BrokenCircuitException exception = Assert.Throws(() => strategy.Execute(_ => 0)); + BrokenCircuitException exception = Assert.Throws(() => strategy.Execute(_ => 0, cancellationToken)); exception.RetryAfter.Should().Be(breakDuration); // Circuit still open after some time @@ -166,13 +168,13 @@ public void AddCircuitBreaker_IntegrationTest_WithBreakDurationGenerator() opened.Should().Be(1); halfOpened.Should().Be(0); closed.Should().Be(0); - exception = Assert.Throws(() => strategy.Execute(_ => 0)); + exception = Assert.Throws(() => strategy.Execute(_ => 0, cancellationToken)); exception.RetryAfter.Should().Be(halfBreakDuration); // Circuit Half Opened timeProvider.Advance(halfBreakDuration); - strategy.Execute(_ => -1); - exception = Assert.Throws(() => strategy.Execute(_ => 0)); + strategy.Execute(_ => -1, cancellationToken); + exception = Assert.Throws(() => strategy.Execute(_ => 0, cancellationToken)); opened.Should().Be(2); halfOpened.Should().Be(1); closed.Should().Be(0); @@ -180,7 +182,7 @@ public void AddCircuitBreaker_IntegrationTest_WithBreakDurationGenerator() // Now close it timeProvider.Advance(breakDuration); - strategy.Execute(_ => 0); + strategy.Execute(_ => 0, cancellationToken); opened.Should().Be(2); halfOpened.Should().Be(2); closed.Should().Be(1); @@ -189,8 +191,9 @@ public void AddCircuitBreaker_IntegrationTest_WithBreakDurationGenerator() [Fact] public async Task AddCircuitBreakers_WithIsolatedManualControl_ShouldBeIsolated() { + var cancellationToken = CancellationToken.None; var manualControl = new CircuitBreakerManualControl(); - await manualControl.IsolateAsync(); + await manualControl.IsolateAsync(cancellationToken); var strategy1 = new ResiliencePipelineBuilder() .AddCircuitBreaker(new() { ManualControl = manualControl }) @@ -203,7 +206,7 @@ public async Task AddCircuitBreakers_WithIsolatedManualControl_ShouldBeIsolated( strategy1.Invoking(s => s.Execute(() => { })).Should().Throw().Where(e => e.RetryAfter == null); strategy2.Invoking(s => s.Execute(() => { })).Should().Throw().Where(e => e.RetryAfter == null); - await manualControl.CloseAsync(); + await manualControl.CloseAsync(cancellationToken); strategy1.Execute(() => { }); strategy2.Execute(() => { }); diff --git a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs index 7a0748683d5..7756582d06b 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs @@ -30,6 +30,8 @@ public CircuitBreakerResilienceStrategyTests() null); } + private static CancellationToken CancellationToken => CancellationToken.None; + [Fact] public void Ctor_Ok() => this.Invoking(_ => Create()).Should().NotThrow(); @@ -52,10 +54,10 @@ public async Task Ctor_ManualControl_EnsureAttached() _options.ManualControl = new CircuitBreakerManualControl(); var strategy = Create(); - await _options.ManualControl.IsolateAsync(CancellationToken.None); + await _options.ManualControl.IsolateAsync(CancellationToken); strategy.Invoking(s => s.Execute(_ => 0)).Should().Throw().Where(e => e.RetryAfter == null); - await _options.ManualControl.CloseAsync(CancellationToken.None); + await _options.ManualControl.CloseAsync(CancellationToken); strategy.Invoking(s => s.Execute(_ => 0)).Should().NotThrow(); @@ -73,7 +75,7 @@ public void Execute_HandledResult_OnFailureCalled() _behavior.When(v => v.OnActionFailure(CircuitState.Closed, out Arg.Any())) .Do(x => x[1] = shouldBreak); - strategy.Execute(_ => -1).Should().Be(-1); + strategy.Execute(_ => -1, CancellationToken).Should().Be(-1); _behavior.Received().OnActionFailure(CircuitState.Closed, out Arg.Any()); } @@ -84,7 +86,7 @@ public void Execute_UnhandledResult_OnActionSuccess() _options.ShouldHandle = args => new ValueTask(args.Outcome.Result is -1); var strategy = Create(); - strategy.Execute(_ => 0).Should().Be(0); + strategy.Execute(_ => 0, CancellationToken).Should().Be(0); _behavior.Received(1).OnActionSuccess(CircuitState.Closed); } diff --git a/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs b/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs index 091de464e3e..bee56e9bb76 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs @@ -26,13 +26,14 @@ public void Ctor_EnsureDefaults() public async Task IsolateAsync_Ok() { // arrange + var cancellationToken = CancellationToken.None; bool called = false; _options.OnOpened = args => { args.BreakDuration.Should().Be(TimeSpan.MaxValue); args.Context.IsSynchronous.Should().BeFalse(); args.Context.IsVoid.Should().BeFalse(); - args.Context.ResultType.Should().Be(typeof(int)); + args.Context.ResultType.Should().Be(); args.IsManual.Should().BeTrue(); args.Outcome.IsVoidResult.Should().BeFalse(); args.Outcome.Result.Should().Be(0); @@ -42,7 +43,7 @@ public async Task IsolateAsync_Ok() _timeProvider.Advance(TimeSpan.FromSeconds(1)); using var controller = CreateController(); - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(cancellationToken); // act await controller.IsolateCircuitAsync(context); @@ -51,14 +52,14 @@ public async Task IsolateAsync_Ok() controller.CircuitState.Should().Be(CircuitState.Isolated); called.Should().BeTrue(); - var outcome = await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); + var outcome = await controller.OnActionPreExecuteAsync(context); var exception = outcome.Value.Exception.Should().BeOfType().Subject; exception.RetryAfter.Should().BeNull(); exception.TelemetrySource.Should().NotBeNull(); // now close it - await controller.CloseCircuitAsync(ResilienceContextPool.Shared.Get()); - await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); + await controller.CloseCircuitAsync(context); + await controller.OnActionPreExecuteAsync(context); _circuitBehavior.Received().OnCircuitClosed(); _telemetryListener.GetArgs>().Should().NotBeEmpty(); @@ -68,12 +69,13 @@ public async Task IsolateAsync_Ok() public async Task BreakAsync_Ok() { // arrange + var cancellationToken = CancellationToken.None; bool called = false; _options.OnClosed = args => { args.Context.IsSynchronous.Should().BeFalse(); args.Context.IsVoid.Should().BeFalse(); - args.Context.ResultType.Should().Be(typeof(int)); + args.Context.ResultType.Should().Be(); args.IsManual.Should().BeTrue(); args.Outcome.IsVoidResult.Should().BeFalse(); args.Outcome.Result.Should().Be(0); @@ -83,8 +85,8 @@ public async Task BreakAsync_Ok() _timeProvider.Advance(TimeSpan.FromSeconds(1)); using var controller = CreateController(); - await controller.IsolateCircuitAsync(ResilienceContextPool.Shared.Get()); - var context = ResilienceContextPool.Shared.Get(); + await controller.IsolateCircuitAsync(ResilienceContextPool.Shared.Get(cancellationToken)); + var context = ResilienceContextPool.Shared.Get(cancellationToken); // act await controller.CloseCircuitAsync(context); @@ -92,7 +94,7 @@ public async Task BreakAsync_Ok() // assert called.Should().BeTrue(); - await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); + await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get(cancellationToken)); _circuitBehavior.Received().OnCircuitClosed(); _telemetryListener.GetArgs>().Should().NotBeEmpty(); } @@ -100,6 +102,8 @@ public async Task BreakAsync_Ok() [Fact] public async Task Disposed_EnsureThrows() { + var context = ResilienceContextPool.Shared.Get(); + var controller = CreateController(); controller.Dispose(); @@ -107,20 +111,21 @@ public async Task Disposed_EnsureThrows() Assert.Throws(() => controller.LastException); Assert.Throws(() => controller.LastHandledOutcome); - await Assert.ThrowsAsync(async () => await controller.CloseCircuitAsync(ResilienceContextPool.Shared.Get())); - await Assert.ThrowsAsync(async () => await controller.IsolateCircuitAsync(ResilienceContextPool.Shared.Get())); - await Assert.ThrowsAsync(async () => await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get())); - await Assert.ThrowsAsync(async () => await controller.OnUnhandledOutcomeAsync(Outcome.FromResult(10), ResilienceContextPool.Shared.Get())); - await Assert.ThrowsAsync(async () => await controller.OnHandledOutcomeAsync(Outcome.FromResult(10), ResilienceContextPool.Shared.Get())); + await Assert.ThrowsAsync(async () => await controller.CloseCircuitAsync(context)); + await Assert.ThrowsAsync(async () => await controller.IsolateCircuitAsync(context)); + await Assert.ThrowsAsync(async () => await controller.OnActionPreExecuteAsync(context)); + await Assert.ThrowsAsync(async () => await controller.OnUnhandledOutcomeAsync(Outcome.FromResult(10), context)); + await Assert.ThrowsAsync(async () => await controller.OnHandledOutcomeAsync(Outcome.FromResult(10), context)); } [Fact] public async Task OnActionPreExecute_CircuitOpenedByValue() { + var context = ResilienceContextPool.Shared.Get(); using var controller = CreateController(); await OpenCircuit(controller, Outcome.FromResult(99)); - var exception = (BrokenCircuitException)(await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get())).Value.Exception!; + var exception = (BrokenCircuitException)(await controller.OnActionPreExecuteAsync(context)).Value.Exception!; exception.RetryAfter.Should().NotBeNull(); exception.TelemetrySource.Should().NotBeNull(); @@ -170,9 +175,10 @@ await OpenCircuit( [Fact] public async Task HalfOpen_EnsureBreakDuration() { + var context = ResilienceContextPool.Shared.Get(); using var controller = CreateController(); - await TransitionToState(controller, CircuitState.HalfOpen); + await TransitionToState(controller, CircuitState.HalfOpen, context); GetBlockedTill(controller).Should().Be(_timeProvider.GetUtcNow() + _options.BreakDuration); } @@ -181,13 +187,14 @@ public async Task HalfOpen_EnsureBreakDuration() [Theory] public async Task HalfOpen_EnsureCorrectStateTransitionAfterExecution(bool success) { + var context = ResilienceContextPool.Shared.Get(); using var controller = CreateController(); - await TransitionToState(controller, CircuitState.HalfOpen); + await TransitionToState(controller, CircuitState.HalfOpen, context); if (success) { - await controller.OnUnhandledOutcomeAsync(Outcome.FromResult(0), ResilienceContextPool.Shared.Get()); + await controller.OnUnhandledOutcomeAsync(Outcome.FromResult(0), context); controller.CircuitState.Should().Be(CircuitState.Closed); _circuitBehavior.Received().OnActionSuccess(CircuitState.HalfOpen); @@ -195,7 +202,7 @@ public async Task HalfOpen_EnsureCorrectStateTransitionAfterExecution(bool succe } else { - await controller.OnHandledOutcomeAsync(Outcome.FromResult(0), ResilienceContextPool.Shared.Get()); + await controller.OnHandledOutcomeAsync(Outcome.FromResult(0), context); controller.CircuitState.Should().Be(CircuitState.Open); _circuitBehavior.DidNotReceiveWithAnyArgs().OnActionSuccess(default); @@ -206,10 +213,11 @@ public async Task HalfOpen_EnsureCorrectStateTransitionAfterExecution(bool succe [Fact] public async Task OnActionPreExecute_CircuitOpenedByException() { + var context = ResilienceContextPool.Shared.Get(); using var controller = CreateController(); await OpenCircuit(controller, Outcome.FromException(new InvalidOperationException())); - var exception = (BrokenCircuitException)(await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get())).Value.Exception!; + var exception = (BrokenCircuitException)(await controller.OnActionPreExecuteAsync(context)).Value.Exception!; exception.InnerException.Should().BeOfType(); exception.RetryAfter.Should().NotBeNull(); exception.TelemetrySource.Should().NotBeNull(); @@ -219,6 +227,9 @@ public async Task OnActionPreExecute_CircuitOpenedByException() public async Task OnActionFailure_EnsureLock() { // arrange + var cancellationToken = CancellationToken.None; + var context = ResilienceContextPool.Shared.Get(cancellationToken); + using var executing = new ManualResetEvent(false); using var verified = new ManualResetEvent(false); @@ -233,13 +244,13 @@ public async Task OnActionFailure_EnsureLock() using var controller = CreateController(); // act - var executeAction = Task.Run(() => controller.OnHandledOutcomeAsync(Outcome.FromResult(0), ResilienceContextPool.Shared.Get())); + var executeAction = Task.Run(() => controller.OnHandledOutcomeAsync(Outcome.FromResult(0), context)); executing.WaitOne(); - var executeAction2 = Task.Run(() => controller.OnHandledOutcomeAsync(Outcome.FromResult(0), ResilienceContextPool.Shared.Get())); + var executeAction2 = Task.Run(() => controller.OnHandledOutcomeAsync(Outcome.FromResult(0), context)); // assert #pragma warning disable xUnit1031 // Do not use blocking task operations in test method - executeAction.Wait(50).Should().BeFalse(); + executeAction.Wait(50, cancellationToken).Should().BeFalse(); #pragma warning restore xUnit1031 // Do not use blocking task operations in test method verified.Set(); await executeAction; @@ -250,6 +261,7 @@ public async Task OnActionFailure_EnsureLock() public async Task OnActionPreExecute_HalfOpen() { // arrange + var context = ResilienceContextPool.Shared.Get(); var called = false; _options.OnHalfOpened = _ => { @@ -263,8 +275,8 @@ public async Task OnActionPreExecute_HalfOpen() AdvanceTime(_options.BreakDuration); // act - await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); - var error = (await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get())).Value.Exception; + await controller.OnActionPreExecuteAsync(context); + var error = (await controller.OnActionPreExecuteAsync(context)).Value.Exception; // assert var exception = error.Should().BeOfType().Subject; @@ -281,6 +293,7 @@ public async Task OnActionPreExecute_HalfOpen() public async Task OnActionSuccess_EnsureCorrectBehavior(CircuitState state, CircuitState expectedState) { // arrange + var context = ResilienceContextPool.Shared.Get(); var called = false; _options.OnClosed = args => { @@ -291,10 +304,10 @@ public async Task OnActionSuccess_EnsureCorrectBehavior(CircuitState state, Circ using var controller = CreateController(); - await TransitionToState(controller, state); + await TransitionToState(controller, state, context); // act - await controller.OnUnhandledOutcomeAsync(Outcome.FromResult(10), ResilienceContextPool.Shared.Get()); + await controller.OnUnhandledOutcomeAsync(Outcome.FromResult(10), context); // assert controller.CircuitState.Should().Be(expectedState); @@ -316,6 +329,7 @@ public async Task OnActionSuccess_EnsureCorrectBehavior(CircuitState state, Circ public async Task OnActionFailureAsync_EnsureCorrectBehavior(CircuitState state, CircuitState expectedState, bool shouldBreak) { // arrange + var context = ResilienceContextPool.Shared.Get(); var called = false; _options.OnOpened = args => { @@ -333,13 +347,13 @@ public async Task OnActionFailureAsync_EnsureCorrectBehavior(CircuitState state, }; using var controller = CreateController(); - await TransitionToState(controller, state); + await TransitionToState(controller, state, context); _circuitBehavior.When(x => x.OnActionFailure(state, out Arg.Any())) .Do(x => x[1] = shouldBreak); // act - await controller.OnHandledOutcomeAsync(Outcome.FromResult(99), ResilienceContextPool.Shared.Get()); + await controller.OnHandledOutcomeAsync(Outcome.FromResult(99), context); // assert controller.LastHandledOutcome!.Value.Result.Should().Be(99); @@ -356,6 +370,7 @@ public async Task OnActionFailureAsync_EnsureCorrectBehavior(CircuitState state, public async Task OnActionFailureAsync_EnsureBreakDurationGeneration() { // arrange + var context = ResilienceContextPool.Shared.Get(); _options.BreakDurationGenerator = static args => { args.FailureCount.Should().Be(1); @@ -365,7 +380,7 @@ public async Task OnActionFailureAsync_EnsureBreakDurationGeneration() using var controller = CreateController(); - await TransitionToState(controller, CircuitState.Closed); + await TransitionToState(controller, CircuitState.Closed, context); var utcNow = new DateTimeOffset(2023, 12, 12, 12, 34, 56, TimeSpan.Zero); _timeProvider.SetUtcNow(utcNow); @@ -376,7 +391,7 @@ public async Task OnActionFailureAsync_EnsureBreakDurationGeneration() .Do(x => x[1] = true); // act - await controller.OnHandledOutcomeAsync(Outcome.FromResult(99), ResilienceContextPool.Shared.Get()); + await controller.OnHandledOutcomeAsync(Outcome.FromResult(99), context); // assert var blockedTill = GetBlockedTill(controller); @@ -387,6 +402,7 @@ public async Task OnActionFailureAsync_EnsureBreakDurationGeneration() public async Task BreakDurationGenerator_EnsureHalfOpenAttempts() { // arrange + var context = ResilienceContextPool.Shared.Get(); var halfOpenAttempts = new List(); _options.BreakDurationGenerator = args => @@ -398,20 +414,20 @@ public async Task BreakDurationGenerator_EnsureHalfOpenAttempts() using var controller = CreateController(); // act - await TransitionToState(controller, CircuitState.Closed); + await TransitionToState(controller, CircuitState.Closed, context); for (int i = 0; i < 5; i++) { - await TransitionToState(controller, CircuitState.Open); - await TransitionToState(controller, CircuitState.HalfOpen); + await TransitionToState(controller, CircuitState.Open, context); + await TransitionToState(controller, CircuitState.HalfOpen, context); } - await TransitionToState(controller, CircuitState.Closed); + await TransitionToState(controller, CircuitState.Closed, context); for (int i = 0; i < 3; i++) { - await TransitionToState(controller, CircuitState.Open); - await TransitionToState(controller, CircuitState.HalfOpen); + await TransitionToState(controller, CircuitState.Open, context); + await TransitionToState(controller, CircuitState.HalfOpen, context); } // assert @@ -424,9 +440,10 @@ public async Task BreakDurationGenerator_EnsureHalfOpenAttempts() public async Task OnActionFailureAsync_EnsureBreakDurationNotOverflow(bool overflow) { // arrange + var context = ResilienceContextPool.Shared.Get(); using var controller = CreateController(); var shouldBreak = true; - await TransitionToState(controller, CircuitState.HalfOpen); + await TransitionToState(controller, CircuitState.HalfOpen, context); var utcNow = DateTimeOffset.MaxValue - _options.BreakDuration; if (overflow) { @@ -439,7 +456,7 @@ public async Task OnActionFailureAsync_EnsureBreakDurationNotOverflow(bool overf .Do(x => x[1] = shouldBreak); // act - await controller.OnHandledOutcomeAsync(Outcome.FromResult(99), ResilienceContextPool.Shared.Get()); + await controller.OnHandledOutcomeAsync(Outcome.FromResult(99), context); // assert var blockedTill = GetBlockedTill(controller); @@ -458,19 +475,20 @@ public async Task OnActionFailureAsync_EnsureBreakDurationNotOverflow(bool overf public async Task OnActionFailureAsync_VoidResult_EnsureBreakingExceptionNotSet() { // arrange + var context = ResilienceContextPool.Shared.Get(); using var controller = CreateController(); bool shouldBreak = true; - await TransitionToState(controller, CircuitState.Open); + await TransitionToState(controller, CircuitState.Open, context); _circuitBehavior.When(v => v.OnActionFailure(CircuitState.Open, out Arg.Any())) .Do(x => x[1] = shouldBreak); // act - await controller.OnHandledOutcomeAsync(Outcome.FromResult(99), ResilienceContextPool.Shared.Get()); + await controller.OnHandledOutcomeAsync(Outcome.FromResult(99), context); // assert controller.LastException.Should().BeNull(); - var outcome = await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); + var outcome = await controller.OnActionPreExecuteAsync(context); var exception = outcome.Value.Exception.Should().BeOfType().Subject; exception.RetryAfter.Should().NotBeNull(); exception.TelemetrySource.Should().NotBeNull(); @@ -479,11 +497,12 @@ public async Task OnActionFailureAsync_VoidResult_EnsureBreakingExceptionNotSet( [Fact] public async Task Flow_Closed_HalfOpen_Closed() { + var context = ResilienceContextPool.Shared.Get(); using var controller = CreateController(); - await TransitionToState(controller, CircuitState.HalfOpen); + await TransitionToState(controller, CircuitState.HalfOpen, context); - await controller.OnUnhandledOutcomeAsync(Outcome.FromResult(0), ResilienceContextPool.Shared.Get()); + await controller.OnUnhandledOutcomeAsync(Outcome.FromResult(0), context); controller.CircuitState.Should().Be(CircuitState.Closed); _circuitBehavior.Received().OnActionSuccess(CircuitState.HalfOpen); @@ -493,11 +512,13 @@ public async Task Flow_Closed_HalfOpen_Closed() [Fact] public async Task Flow_Closed_HalfOpen_Open_HalfOpen_Closed() { - var context = ResilienceContextPool.Shared.Get(); + var cancellationToken = CancellationToken.None; + var context = ResilienceContextPool.Shared.Get(cancellationToken); + using var controller = CreateController(); bool shouldBreak = true; - await TransitionToState(controller, CircuitState.HalfOpen); + await TransitionToState(controller, CircuitState.HalfOpen, context); _circuitBehavior.When(v => v.OnActionFailure(CircuitState.HalfOpen, out Arg.Any())) .Do(x => x[1] = shouldBreak); @@ -508,7 +529,7 @@ public async Task Flow_Closed_HalfOpen_Open_HalfOpen_Closed() // execution rejected TimeSpan advanceTimeRejected = TimeSpan.FromMilliseconds(1); AdvanceTime(advanceTimeRejected); - var outcome = await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); + var outcome = await controller.OnActionPreExecuteAsync(context); var exception = outcome.Value.Exception.Should().BeOfType().Subject; exception.RetryAfter.Should().Be(_options.BreakDuration - advanceTimeRejected); exception.TelemetrySource.Should().NotBeNull(); @@ -519,7 +540,7 @@ public async Task Flow_Closed_HalfOpen_Open_HalfOpen_Closed() controller.CircuitState.Should().Be(CircuitState.HalfOpen); // close circuit - await controller.OnUnhandledOutcomeAsync(Outcome.FromResult(0), ResilienceContextPool.Shared.Get()); + await controller.OnUnhandledOutcomeAsync(Outcome.FromResult(0), context); controller.CircuitState.Should().Be(CircuitState.Closed); _circuitBehavior.Received().OnActionSuccess(CircuitState.HalfOpen); @@ -529,11 +550,14 @@ public async Task Flow_Closed_HalfOpen_Open_HalfOpen_Closed() [Fact] public async Task ExecuteScheduledTask_Async_Ok() { + var cancellationToken = CancellationToken.None; + var context = ResilienceContextPool.Shared.Get(cancellationToken); + var source = new TaskCompletionSource(); - var task = CircuitStateController.ExecuteScheduledTaskAsync(source.Task, ResilienceContextPool.Shared.Get().Initialize(isSynchronous: false)).AsTask(); + var task = CircuitStateController.ExecuteScheduledTaskAsync(source.Task, context.Initialize(isSynchronous: false)).AsTask(); #pragma warning disable xUnit1031 // Do not use blocking task operations in test method - task.Wait(3).Should().BeFalse(); + task.Wait(3, cancellationToken).Should().BeFalse(); #pragma warning restore xUnit1031 // Do not use blocking task operations in test method task.IsCompleted.Should().BeFalse(); @@ -546,12 +570,15 @@ public async Task ExecuteScheduledTask_Async_Ok() private static DateTimeOffset? GetBlockedTill(CircuitStateController controller) => (DateTimeOffset?)controller.GetType().GetField("_blockedUntil", BindingFlags.Instance | BindingFlags.NonPublic)!.GetValue(controller)!; - private async Task TransitionToState(CircuitStateController controller, CircuitState state) + private async Task TransitionToState( + CircuitStateController controller, + CircuitState state, + ResilienceContext context) { switch (state) { case CircuitState.Closed: - await controller.CloseCircuitAsync(ResilienceContextPool.Shared.Get()); + await controller.CloseCircuitAsync(context); break; case CircuitState.Open: await OpenCircuit(controller); @@ -559,10 +586,10 @@ private async Task TransitionToState(CircuitStateController controller, Cir case CircuitState.HalfOpen: await OpenCircuit(controller); AdvanceTime(_options.BreakDuration); - await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); + await controller.OnActionPreExecuteAsync(context); break; case CircuitState.Isolated: - await controller.IsolateCircuitAsync(ResilienceContextPool.Shared.Get()); + await controller.IsolateCircuitAsync(context); break; } @@ -576,7 +603,9 @@ private async Task OpenCircuit(CircuitStateController controller, Outcome v.OnActionFailure(CircuitState.Closed, out Arg.Any())) .Do(x => x[1] = breakCircuit); - await controller.OnHandledOutcomeAsync(outcome ?? Outcome.FromResult(10), ResilienceContextPool.Shared.Get().Initialize(true)); + await controller.OnHandledOutcomeAsync( + outcome ?? Outcome.FromResult(10), + ResilienceContextPool.Shared.Get().Initialize(true)); } private void AdvanceTime(TimeSpan timespan) => _timeProvider.Advance(timespan); diff --git a/test/Polly.Core.Tests/CircuitBreaker/Controller/ScheduledTaskExecutorTests.cs b/test/Polly.Core.Tests/CircuitBreaker/Controller/ScheduledTaskExecutorTests.cs index f24b8791324..f26dff53203 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/Controller/ScheduledTaskExecutorTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/Controller/ScheduledTaskExecutorTests.cs @@ -4,6 +4,8 @@ namespace Polly.Core.Tests.CircuitBreaker.Controller; public class ScheduledTaskExecutorTests { + private static CancellationToken CancellationToken => CancellationToken.None; + [Fact] public async Task ScheduleTask_Success_EnsureExecuted() { @@ -15,7 +17,7 @@ public async Task ScheduleTask_Success_EnsureExecuted() executed = true; return Task.CompletedTask; }, - ResilienceContextPool.Shared.Get(), + ResilienceContextPool.Shared.Get(CancellationToken), out var task); await task; @@ -29,7 +31,7 @@ public async Task ScheduleTask_OperationCanceledException_EnsureExecuted() using var scheduler = new ScheduledTaskExecutor(); scheduler.ScheduleTask( () => throw new OperationCanceledException(), - ResilienceContextPool.Shared.Get(), + ResilienceContextPool.Shared.Get(CancellationToken), out var task); await task.Invoking(async t => await task).Should().ThrowAsync(); @@ -41,7 +43,7 @@ public async Task ScheduleTask_Exception_EnsureExecuted() using var scheduler = new ScheduledTaskExecutor(); scheduler.ScheduleTask( () => throw new InvalidOperationException(), - ResilienceContextPool.Shared.Get(), + ResilienceContextPool.Shared.Get(CancellationToken), out var task); await task.Invoking(async t => await task).Should().ThrowAsync(); @@ -61,13 +63,16 @@ public async Task ScheduleTask_Multiple_EnsureExecutionSerialized() verified.WaitOne(); return Task.CompletedTask; }, - ResilienceContextPool.Shared.Get(), + ResilienceContextPool.Shared.Get(CancellationToken), out var task); executing.WaitOne(); - scheduler.ScheduleTask(() => Task.CompletedTask, ResilienceContextPool.Shared.Get(), out var otherTask); - otherTask.Wait(50).Should().BeFalse(); + scheduler.ScheduleTask(() => Task.CompletedTask, ResilienceContextPool.Shared.Get(CancellationToken), out var otherTask); + +#pragma warning disable xUnit1031 // Do not use blocking task operations in test method + otherTask.Wait(50, CancellationToken).Should().BeFalse(); +#pragma warning restore xUnit1031 // Do not use blocking task operations in test method verified.Set(); @@ -89,11 +94,11 @@ public async Task Dispose_ScheduledTaskCancelled() verified.WaitOne(); return Task.CompletedTask; }, - ResilienceContextPool.Shared.Get(), + ResilienceContextPool.Shared.Get(CancellationToken), out var task); executing.WaitOne(); - scheduler.ScheduleTask(() => Task.CompletedTask, ResilienceContextPool.Shared.Get(), out var otherTask); + scheduler.ScheduleTask(() => Task.CompletedTask, ResilienceContextPool.Shared.Get(CancellationToken), out var otherTask); scheduler.Dispose(); verified.Set(); await task; @@ -101,7 +106,7 @@ public async Task Dispose_ScheduledTaskCancelled() await otherTask.Invoking(t => otherTask).Should().ThrowAsync(); scheduler - .Invoking(s => s.ScheduleTask(() => Task.CompletedTask, ResilienceContextPool.Shared.Get(), out _)) + .Invoking(s => s.ScheduleTask(() => Task.CompletedTask, ResilienceContextPool.Shared.Get(CancellationToken), out _)) .Should() .Throw(); } @@ -109,6 +114,8 @@ public async Task Dispose_ScheduledTaskCancelled() [Fact] public void Dispose_WhenScheduledTaskExecuting() { + var timeout = TimeSpan.FromSeconds(10); + using var disposed = new ManualResetEvent(false); using var ready = new ManualResetEvent(false); @@ -120,21 +127,27 @@ public void Dispose_WhenScheduledTaskExecuting() disposed.WaitOne(); return Task.CompletedTask; }, - ResilienceContextPool.Shared.Get(), + ResilienceContextPool.Shared.Get(CancellationToken), out var task); - ready.WaitOne(TimeSpan.FromSeconds(10)).Should().BeTrue(); + ready.WaitOne(timeout).Should().BeTrue(); scheduler.Dispose(); disposed.Set(); - scheduler.ProcessingTask.Wait(TimeSpan.FromSeconds(10)).Should().BeTrue(); +#pragma warning disable xUnit1031 +#if NET + scheduler.ProcessingTask.Wait(timeout, CancellationToken).Should().BeTrue(); +#else + scheduler.ProcessingTask.Wait(timeout).Should().BeTrue(); +#endif +#pragma warning restore xUnit1031 } [Fact] public async Task Dispose_EnsureNoBackgroundProcessing() { var scheduler = new ScheduledTaskExecutor(); - scheduler.ScheduleTask(() => Task.CompletedTask, ResilienceContextPool.Shared.Get(), out var otherTask); + scheduler.ScheduleTask(() => Task.CompletedTask, ResilienceContextPool.Shared.Get(CancellationToken), out var otherTask); await otherTask; scheduler.Dispose(); #pragma warning disable S3966 // Objects should not be disposed more than once diff --git a/test/Polly.Core.Tests/CircuitBreaker/IsolatedCircuitExceptionTests.cs b/test/Polly.Core.Tests/CircuitBreaker/IsolatedCircuitExceptionTests.cs index 7a76a623229..20ea110851a 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/IsolatedCircuitExceptionTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/IsolatedCircuitExceptionTests.cs @@ -29,7 +29,7 @@ public void Ctor_Message_InnerException_Ok() exception.RetryAfter.Should().BeNull(); } -#if !NETCOREAPP +#if NETFRAMEWORK [Fact] public void BinarySerialization_Ok() { diff --git a/test/Polly.Core.Tests/CircuitBreaker/OnCircuitClosedArgumentsTests.cs b/test/Polly.Core.Tests/CircuitBreaker/OnCircuitClosedArgumentsTests.cs index 3b3653a3d2b..074db32181e 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/OnCircuitClosedArgumentsTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/OnCircuitClosedArgumentsTests.cs @@ -2,14 +2,19 @@ namespace Polly.Core.Tests.CircuitBreaker; -public class OnCircuitClosedArgumentsTests +public static class OnCircuitClosedArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new OnCircuitClosedArguments(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1), true); + // Arrange + var context = ResilienceContextPool.Shared.Get(); - args.Context.Should().NotBeNull(); + // Act + var args = new OnCircuitClosedArguments(context, Outcome.FromResult(1), true); + + // Assert + args.Context.Should().Be(context); args.Outcome.Result.Should().Be(1); args.IsManual.Should().BeTrue(); } diff --git a/test/Polly.Core.Tests/CircuitBreaker/OnCircuitHalfOpenedArgumentsTests.cs b/test/Polly.Core.Tests/CircuitBreaker/OnCircuitHalfOpenedArgumentsTests.cs index 795d6427329..cffb551f5f6 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/OnCircuitHalfOpenedArgumentsTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/OnCircuitHalfOpenedArgumentsTests.cs @@ -2,9 +2,18 @@ namespace Polly.Core.Tests.CircuitBreaker; -public class OnCircuitHalfOpenedArgumentsTests +public static class OnCircuitHalfOpenedArgumentsTests { [Fact] - public void Ctor_Ok() => - new OnCircuitHalfOpenedArguments(ResilienceContextPool.Shared.Get()).Context.Should().NotBeNull(); + public static void Ctor_Ok() + { + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var target = new OnCircuitHalfOpenedArguments(context); + + // Assert + target.Context.Should().Be(context); + } } diff --git a/test/Polly.Core.Tests/CircuitBreaker/OnCircuitOpenedArgumentsTests.cs b/test/Polly.Core.Tests/CircuitBreaker/OnCircuitOpenedArgumentsTests.cs index 760d4674b97..1d8709326b6 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/OnCircuitOpenedArgumentsTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/OnCircuitOpenedArgumentsTests.cs @@ -2,14 +2,19 @@ namespace Polly.Core.Tests.CircuitBreaker; -public class OnCircuitOpenedArgumentsTests +public static class OnCircuitOpenedArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new OnCircuitOpenedArguments(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1), TimeSpan.FromSeconds(2), true); + // Arrange + var context = ResilienceContextPool.Shared.Get(); - args.Context.Should().NotBeNull(); + // Act + var args = new OnCircuitOpenedArguments(context, Outcome.FromResult(1), TimeSpan.FromSeconds(2), true); + + // Assert + args.Context.Should().Be(context); args.Outcome.Result.Should().Be(1); args.BreakDuration.Should().Be(TimeSpan.FromSeconds(2)); args.IsManual.Should().BeTrue(); diff --git a/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs b/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs index 33f077a4277..51dbb462c3f 100644 --- a/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs +++ b/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs @@ -27,7 +27,7 @@ public void AddFallback_Generic_Ok(Action> config var builder = new ResiliencePipelineBuilder(); configure(builder); - builder.Build().GetPipelineDescriptor().FirstStrategy.StrategyInstance.Should().BeOfType(typeof(FallbackResilienceStrategy)); + builder.Build().GetPipelineDescriptor().FirstStrategy.StrategyInstance.Should().BeOfType>(); } [Fact] diff --git a/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs b/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs index e31fffc15b1..d1cb47706a9 100644 --- a/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs +++ b/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs @@ -7,13 +7,14 @@ public class HedgingControllerTests [Fact] public async Task Pooling_Ok() { + var context = ResilienceContextPool.Shared.Get(); var telemetry = TestUtilities.CreateResilienceTelemetry(_ => { }); var controller = new HedgingController(telemetry, new HedgingTimeProvider(), HedgingHelper.CreateHandler(_ => false, args => null), 3); - var context1 = controller.GetContext(ResilienceContextPool.Shared.Get()); + var context1 = controller.GetContext(context); await PrepareAsync(context1); - var context2 = controller.GetContext(ResilienceContextPool.Shared.Get()); + var context2 = controller.GetContext(context); await PrepareAsync(context2); controller.RentedContexts.Should().Be(2); diff --git a/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs b/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs index cba6da27d9d..4f15b05c58f 100644 --- a/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs +++ b/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs @@ -33,8 +33,7 @@ public HedgingExecutionContextTests() _ => false }, args => Generator(args)); - _resilienceContext = ResilienceContextPool.Shared.Get().Initialize(false); - _resilienceContext.CancellationToken = _cts.Token; + _resilienceContext = ResilienceContextPool.Shared.Get(_cts.Token).Initialize(false); _resilienceContext.Properties.Set(_myKey, "dummy"); // HedgingExecutionContext has some Debug.Assert pieces which trigger failures in Debug mode diff --git a/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs b/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs index f460df4b6c4..36415bdbb1f 100644 --- a/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs +++ b/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs @@ -15,7 +15,7 @@ public class TaskExecutionTests : IDisposable private readonly HedgingTimeProvider _timeProvider; private readonly ResilienceStrategyTelemetry _telemetry; private readonly List _args = []; - private ResilienceContext _primaryContext = ResilienceContextPool.Shared.Get(); + private ResilienceContext _primaryContext; public TaskExecutionTests() { @@ -29,6 +29,7 @@ public TaskExecutionTests() _timeProvider = new HedgingTimeProvider(); _cts = new CancellationTokenSource(); + _primaryContext = ResilienceContextPool.Shared.Get(_cts.Token); _hedgingHandler = HedgingHelper.CreateHandler(outcome => outcome switch { { Exception: ApplicationException } => true, @@ -238,7 +239,7 @@ public async Task ResetAsync_Ok(bool accept) execution.IsHandled.Should().BeFalse(); context.Properties.Options.Should().HaveCount(0); execution.Invoking(e => e.Context).Should().Throw(); -#if !NETCOREAPP +#if NETFRAMEWORK token.Invoking(t => t.WaitHandle).Should().Throw(); #endif if (accept) diff --git a/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs index 8de0f80fd97..ff029e9ae32 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs @@ -2,15 +2,22 @@ namespace Polly.Core.Tests.Hedging; -public class HedgingActionGeneratorArgumentsTests +public static class HedgingActionGeneratorArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new HedgingActionGeneratorArguments(ResilienceContextPool.Shared.Get(), ResilienceContextPool.Shared.Get(), 5, _ => Outcome.FromResultAsValueTask("dummy")); + // Arrange + var cancellationToken = CancellationToken.None; + var primaryContext = ResilienceContextPool.Shared.Get(cancellationToken); + var actionContext = ResilienceContextPool.Shared.Get(cancellationToken); - args.PrimaryContext.Should().NotBeNull(); - args.ActionContext.Should().NotBeNull(); + // Act + var args = new HedgingActionGeneratorArguments(primaryContext, actionContext, 5, _ => Outcome.FromResultAsValueTask("dummy")); + + // Assert + args.PrimaryContext.Should().Be(primaryContext); + args.ActionContext.Should().Be(actionContext); args.AttemptNumber.Should().Be(5); args.Callback.Should().NotBeNull(); } diff --git a/test/Polly.Core.Tests/Hedging/HedgingDelayGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Hedging/HedgingDelayGeneratorArgumentsTests.cs index 9142d3cf8ba..ccbd82be944 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingDelayGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingDelayGeneratorArgumentsTests.cs @@ -2,14 +2,19 @@ namespace Polly.Core.Tests.Hedging; -public class HedgingDelayGeneratorArgumentsTests +public static class HedgingDelayGeneratorArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new HedgingDelayGeneratorArguments(ResilienceContextPool.Shared.Get(), 5); + // Arrange + var context = ResilienceContextPool.Shared.Get(); - args.Context.Should().NotBeNull(); + // Act + var args = new HedgingDelayGeneratorArguments(context, 5); + + // Assert + args.Context.Should().Be(context); args.AttemptNumber.Should().Be(5); } } diff --git a/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs b/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs index 5955c8058db..80804040715 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs @@ -3,11 +3,14 @@ namespace Polly.Core.Tests.Hedging; -public class HedgingHandlerTests +public static class HedgingHandlerTests { [Fact] - public async Task GenerateAction_Generic_Ok() + public static async Task GenerateAction_Generic_Ok() { + // Arrange + var context = ResilienceContextPool.Shared.Get(); + var handler = new HedgingHandler( args => PredicateResult.True(), args => () => Outcome.FromResultAsValueTask("ok"), @@ -16,12 +19,15 @@ public async Task GenerateAction_Generic_Ok() handler.OnHedging.Should().NotBeNull(); var action = handler.GenerateAction(new HedgingActionGeneratorArguments( - ResilienceContextPool.Shared.Get(), - ResilienceContextPool.Shared.Get(), + context, + context, 0, _ => Outcome.FromResultAsValueTask("primary")))!; + + // Act var res = await action(); + // Assert res.Result.Should().Be("ok"); } } diff --git a/test/Polly.Core.Tests/Hedging/HedgingPredicateArgumentsTests.cs b/test/Polly.Core.Tests/Hedging/HedgingPredicateArgumentsTests.cs index 6ef1677994f..8df7094a681 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingPredicateArgumentsTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingPredicateArgumentsTests.cs @@ -2,14 +2,19 @@ namespace Polly.Core.Tests.Hedging; -public class HedgingPredicateArgumentsTests +public static class HedgingPredicateArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new HedgingPredicateArguments(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1)); + // Arrange + var context = ResilienceContextPool.Shared.Get(); - args.Context.Should().NotBeNull(); + // Act + var args = new HedgingPredicateArguments(context, Outcome.FromResult(1)); + + // Assert + args.Context.Should().Be(context); args.Outcome.Result.Should().Be(1); } } diff --git a/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs b/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs index 26583198e2a..c17e91cae1a 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs @@ -36,6 +36,8 @@ public HedgingResilienceStrategyTests(ITestOutputHelper testOutput) _testOutput = testOutput; } + private CancellationToken CancellationToken => _cts.Token; + public void Dispose() { _cts.Dispose(); @@ -61,7 +63,7 @@ public async Task Execute_CancellationRequested_Throws() var strategy = (HedgingResilienceStrategy)Create().GetPipelineDescriptor().FirstStrategy.StrategyInstance; _cts.Cancel(); - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(CancellationToken); context.CancellationToken = _cts.Token; var outcome = await strategy.ExecuteCore((_, _) => Outcome.FromResultAsValueTask("dummy"), context, "state"); @@ -82,7 +84,7 @@ public void ExecutePrimaryAndSecondary_EnsureAttemptReported() ConfigureHedging(_ => true, args => () => Outcome.FromResultAsValueTask("any")); var strategy = Create(); - strategy.Execute(_ => "dummy"); + strategy.Execute(_ => "dummy", CancellationToken); var attempts = _events.Select(v => v.Arguments).OfType().ToArray(); @@ -112,7 +114,7 @@ public async Task ExecutePrimary_Cancelled_SecondaryShouldBeExecuted() return new ValueTask("primary"); }, - ResilienceContextPool.Shared.Get()); + ResilienceContextPool.Shared.Get(CancellationToken)); result.Should().Be("secondary"); } @@ -129,7 +131,7 @@ public async Task GetHedgingDelayAsync_GeneratorSet_EnsureCorrectGeneratedValue( var strategy = (HedgingResilienceStrategy)Create().GetPipelineDescriptor().FirstStrategy.StrategyInstance; - var result = await strategy.GetHedgingDelayAsync(ResilienceContextPool.Shared.Get(), 0); + var result = await strategy.GetHedgingDelayAsync(ResilienceContextPool.Shared.Get(CancellationToken), 0); result.Should().Be(TimeSpan.FromSeconds(seconds)); } @@ -141,7 +143,7 @@ public async Task GetHedgingDelayAsync_NoGeneratorSet_EnsureCorrectValue() var strategy = (HedgingResilienceStrategy)Create().GetPipelineDescriptor().FirstStrategy.StrategyInstance; - var result = await strategy.GetHedgingDelayAsync(ResilienceContextPool.Shared.Get(), 0); + var result = await strategy.GetHedgingDelayAsync(ResilienceContextPool.Shared.Get(CancellationToken), 0); result.Should().Be(TimeSpan.FromMilliseconds(123)); } @@ -152,7 +154,7 @@ public async Task ExecuteAsync_ShouldReturnAnyPossibleResult() ConfigureHedging(); var strategy = Create(); - var result = await strategy.ExecuteAsync(_primaryTasks.SlowTask); + var result = await strategy.ExecuteAsync(_primaryTasks.SlowTask, CancellationToken); result.Should().NotBeNull(); #if NET8_0_OR_GREATER @@ -166,7 +168,7 @@ public async Task ExecuteAsync_ShouldReturnAnyPossibleResult() [Fact] public async Task ExecuteAsync_EnsurePrimaryContextFlows() { - var primaryContext = ResilienceContextPool.Shared.Get(); + var primaryContext = ResilienceContextPool.Shared.Get(CancellationToken); var attempts = 0; var key = new ResiliencePropertyKey("primary-key"); @@ -236,13 +238,13 @@ public async Task ExecuteAsync_EnsureHedgedTasksCancelled_Ok() { await _timeProvider.Delay(TimeSpan.FromHours(1), token); return Success; - }); + }, CancellationToken); // assert _timeProvider.Advance(_options.Delay); - await Task.Delay(20); + await Task.Delay(20, CancellationToken); _timeProvider.Advance(_options.Delay); - await Task.Delay(20); + await Task.Delay(20, CancellationToken); _timeProvider.Advance(TimeSpan.FromHours(1)); (await result).Should().Be(Success); @@ -275,7 +277,7 @@ public async Task ExecuteAsync_EnsurePrimaryTaskCancelled_Ok() } return Success; - }); + }, CancellationToken); // assert _timeProvider.Advance(TimeSpan.FromHours(2)); @@ -312,7 +314,7 @@ public async Task ExecuteAsync_EnsureDiscardedResultDisposed() await _timeProvider.Delay(LongDelay); #pragma warning restore CA2016 // Forward the 'CancellationToken' parameter to methods return primaryResult; - }); + }, CancellationToken); // assert _timeProvider.Advance(LongDelay); @@ -332,7 +334,7 @@ public async Task ExecuteAsync_EveryHedgedTaskShouldHaveDifferentContexts() var beforeKey = new ResiliencePropertyKey("before"); var afterKey = new ResiliencePropertyKey("after"); - var primaryContext = ResilienceContextPool.Shared.Get(); + var primaryContext = ResilienceContextPool.Shared.Get(CancellationToken); primaryContext.Properties.Set(beforeKey, "before"); var contexts = new List(); var tokenHashCodes = new List(); @@ -380,7 +382,7 @@ public async Task ExecuteAsync_EnsureOriginalCancellationTokenRestored() { // arrange using var cancellationSource = new CancellationTokenSource(); - var primaryContext = ResilienceContextPool.Shared.Get(); + var primaryContext = ResilienceContextPool.Shared.Get(CancellationToken); primaryContext.CancellationToken = cancellationSource.Token; ConfigureHedging(TimeSpan.Zero); var strategy = Create(); @@ -400,7 +402,7 @@ public async Task ExecuteAsync_EnsurePropertiesConsistency(bool primaryFails) // arrange _options.MaxHedgedAttempts = 1; var attempts = _options.MaxHedgedAttempts; - var primaryContext = ResilienceContextPool.Shared.Get(); + var primaryContext = ResilienceContextPool.Shared.Get(CancellationToken); var storedProps = primaryContext.Properties; var contexts = new List(); var primaryKey = new ResiliencePropertyKey("primary-key"); @@ -460,7 +462,7 @@ public async Task ExecuteAsync_Primary_CustomPropertiesAvailable() var key = new ResiliencePropertyKey("my-key"); var key2 = new ResiliencePropertyKey("my-key-2"); using var cancellationSource = new CancellationTokenSource(); - var primaryContext = ResilienceContextPool.Shared.Get(); + var primaryContext = ResilienceContextPool.Shared.Get(CancellationToken); primaryContext.Properties.Set(key2, "my-value-2"); primaryContext.CancellationToken = cancellationSource.Token; var props = primaryContext.Properties; @@ -490,7 +492,7 @@ public async Task ExecuteAsync_Secondary_CustomPropertiesAvailable() // arrange var key = new ResiliencePropertyKey("my-key"); var key2 = new ResiliencePropertyKey("my-key-2"); - var primaryContext = ResilienceContextPool.Shared.Get(); + var primaryContext = ResilienceContextPool.Shared.Get(CancellationToken); var storedProps = primaryContext.Properties; primaryContext.Properties.Set(key2, "my-value-2"); ConfigureHedging(args => @@ -571,7 +573,7 @@ public async Task ExecuteAsync_CancellationLinking_Ok() using var primaryCancelled = new ManualResetEvent(false); using var secondaryCancelled = new ManualResetEvent(false); using var cancellationSource = new CancellationTokenSource(); - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(CancellationToken); context.CancellationToken = cancellationSource.Token; ConfigureHedging(async context => @@ -667,7 +669,7 @@ public async Task ExecuteAsync_ZeroHedgingDelay_EnsureAllTasksSpawnedAtOnce() _options.Delay = TimeSpan.Zero; // act - var task = Create().ExecuteAsync(async c => (await Execute(c)).Result!, default); + var task = Create().ExecuteAsync(async c => (await Execute(c)).Result!, CancellationToken); // assert allExecutionsReached.WaitOne(AssertTimeout).Should().BeTrue(); @@ -843,7 +845,7 @@ public async Task ExecuteAsync_ExceptionsHandled_ShouldReturnLastResult() }); var strategy = Create(); - var result = await strategy.ExecuteAsync(_ => throw new InvalidCastException()); + var result = await strategy.ExecuteAsync(_ => throw new InvalidCastException(), CancellationToken); result.Should().Be(Success); } @@ -860,7 +862,7 @@ public async Task ExecuteAsync_EnsureHedgingDelayGeneratorRespected() { await _timeProvider.Delay(TimeSpan.FromDays(1), token); throw new InvalidCastException(); - }); + }, CancellationToken); _timeProvider.Advance(TimeSpan.FromHours(5)); (await task).Should().Be(Success); @@ -885,7 +887,7 @@ public async Task ExecuteAsync_EnsureExceptionStackTracePreserved() [Fact] public async Task ExecuteAsync_EnsureOnHedgingCalled() { - var primaryContext = ResilienceContextPool.Shared.Get(); + var primaryContext = ResilienceContextPool.Shared.Get(CancellationToken); var key = new ResiliencePropertyKey("my-key"); primaryContext.Properties.Set(key, "my-value"); @@ -919,7 +921,7 @@ public async Task ExecuteAsync_EnsureOnHedgingCalled() [Fact] public async Task ExecuteAsync_EnsureOnHedgingTelemetry() { - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(CancellationToken); ConfigureHedging(res => res.Result == Failure, args => () => Outcome.FromResultAsValueTask(Failure)); diff --git a/test/Polly.Core.Tests/Hedging/OnHedgingArgumentsTests.cs b/test/Polly.Core.Tests/Hedging/OnHedgingArgumentsTests.cs index 75e44c5967b..cd362ae2396 100644 --- a/test/Polly.Core.Tests/Hedging/OnHedgingArgumentsTests.cs +++ b/test/Polly.Core.Tests/Hedging/OnHedgingArgumentsTests.cs @@ -2,15 +2,22 @@ namespace Polly.Core.Tests.Hedging; -public class OnHedgingArgumentsTests +public static class OnHedgingArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new OnHedgingArguments(ResilienceContextPool.Shared.Get(), ResilienceContextPool.Shared.Get(), 1); + // Arrange + var cancellationToken = CancellationToken.None; + var primaryContext = ResilienceContextPool.Shared.Get(cancellationToken); + var actionContext = ResilienceContextPool.Shared.Get(cancellationToken); - args.PrimaryContext.Should().NotBeNull(); - args.ActionContext.Should().NotBeNull(); + // Act + var args = new OnHedgingArguments(primaryContext, actionContext, 1); + + // Assert + args.PrimaryContext.Should().Be(primaryContext); + args.ActionContext.Should().Be(actionContext); args.AttemptNumber.Should().Be(1); } } diff --git a/test/Polly.Core.Tests/Issues/IssuesTests.CircuitBreakerStateSharing_959.cs b/test/Polly.Core.Tests/Issues/IssuesTests.CircuitBreakerStateSharing_959.cs index 71627207b7b..d4172531b74 100644 --- a/test/Polly.Core.Tests/Issues/IssuesTests.CircuitBreakerStateSharing_959.cs +++ b/test/Polly.Core.Tests/Issues/IssuesTests.CircuitBreakerStateSharing_959.cs @@ -7,6 +7,7 @@ public partial class IssuesTests [Fact] public void CircuitBreakerStateSharing_959() { + var cancellationToken = CancellationToken.None; var options = new CircuitBreakerStrategyOptions { FailureRatio = 1, @@ -28,8 +29,8 @@ public void CircuitBreakerStateSharing_959() // now trigger the circuit breaker by evaluating multiple result types for (int i = 0; i < 5; i++) { - strategy.Execute(_ => -1); - strategy.Execute(_ => "error"); + strategy.Execute(_ => -1, cancellationToken); + strategy.Execute(_ => "error", cancellationToken); } // now the circuit breaker should be open @@ -40,7 +41,7 @@ public void CircuitBreakerStateSharing_959() TimeProvider.Advance(options.BreakDuration); // OK, circuit is closed now - strategy.Execute(_ => 0); - strategy.Execute(_ => "valid-result"); + strategy.Execute(_ => 0, cancellationToken); + strategy.Execute(_ => "valid-result", cancellationToken); } } diff --git a/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs b/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs index 9dfc01af8b2..eb0914f1332 100644 --- a/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs +++ b/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs @@ -7,6 +7,7 @@ public partial class IssuesTests [Fact] public void HandleMultipleResults_898() { + var cancellationToken = CancellationToken.None; var isRetryKey = new ResiliencePropertyKey("is-retry"); var options = new RetryStrategyOptions { @@ -44,7 +45,7 @@ public void HandleMultipleResults_898() isRetry = true; return -1; - }).Should().Be(0); + }, cancellationToken).Should().Be(0); // check that string-based results is retried isRetry = false; @@ -57,6 +58,6 @@ public void HandleMultipleResults_898() isRetry = true; return "error"; - }).Should().Be("no-error"); + }, cancellationToken).Should().Be("no-error"); } } diff --git a/test/Polly.Core.Tests/PredicateBuilderTests.cs b/test/Polly.Core.Tests/PredicateBuilderTests.cs index 1a4876cf7f9..ecbae739f6b 100644 --- a/test/Polly.Core.Tests/PredicateBuilderTests.cs +++ b/test/Polly.Core.Tests/PredicateBuilderTests.cs @@ -59,8 +59,10 @@ public void Ctor_Ok() new PredicateBuilder().Should().NotBeNull(); } - [MemberData(nameof(HandleResultData))] [Theory] +#pragma warning disable xUnit1044 // Avoid using TheoryData type arguments that are not serializable + [MemberData(nameof(HandleResultData))] +#pragma warning restore xUnit1044 // Avoid using TheoryData type arguments that are not serializable public void HandleResult_Ok(Action> configure, Outcome value, bool handled) { var predicate = new PredicateBuilder(); @@ -84,12 +86,13 @@ public void CreatePredicate_NotConfigured_Throws() [Fact] public async Task Operator_RetryStrategyOptions_Ok() { + var context = ResilienceContextPool.Shared.Get(); var options = new RetryStrategyOptions { ShouldHandle = new PredicateBuilder().HandleResult("error") }; - var handled = await options.ShouldHandle(new RetryPredicateArguments(ResilienceContextPool.Shared.Get(), CreateOutcome("error"), 0)); + var handled = await options.ShouldHandle(new RetryPredicateArguments(context, CreateOutcome("error"), 0)); handled.Should().BeTrue(); } @@ -97,12 +100,13 @@ public async Task Operator_RetryStrategyOptions_Ok() [Fact] public async Task Operator_FallbackStrategyOptions_Ok() { + var context = ResilienceContextPool.Shared.Get(); var options = new FallbackStrategyOptions { ShouldHandle = new PredicateBuilder().HandleResult("error") }; - var handled = await options.ShouldHandle(new(ResilienceContextPool.Shared.Get(), CreateOutcome("error"))); + var handled = await options.ShouldHandle(new(context, CreateOutcome("error"))); handled.Should().BeTrue(); } @@ -110,12 +114,13 @@ public async Task Operator_FallbackStrategyOptions_Ok() [Fact] public async Task Operator_HedgingStrategyOptions_Ok() { + var context = ResilienceContextPool.Shared.Get(); var options = new HedgingStrategyOptions { ShouldHandle = new PredicateBuilder().HandleResult("error") }; - var handled = await options.ShouldHandle(new(ResilienceContextPool.Shared.Get(), CreateOutcome("error"))); + var handled = await options.ShouldHandle(new(context, CreateOutcome("error"))); handled.Should().BeTrue(); } @@ -123,12 +128,13 @@ public async Task Operator_HedgingStrategyOptions_Ok() [Fact] public async Task Operator_AdvancedCircuitBreakerStrategyOptions_Ok() { + var context = ResilienceContextPool.Shared.Get(); var options = new CircuitBreakerStrategyOptions { ShouldHandle = new PredicateBuilder().HandleResult("error") }; - var handled = await options.ShouldHandle(new(ResilienceContextPool.Shared.Get(), CreateOutcome("error"))); + var handled = await options.ShouldHandle(new(context, CreateOutcome("error"))); handled.Should().BeTrue(); } diff --git a/test/Polly.Core.Tests/Registry/ConfigureBuilderContextTests.cs b/test/Polly.Core.Tests/Registry/ConfigureBuilderContextTests.cs index 72c78d10143..1d88a44383b 100644 --- a/test/Polly.Core.Tests/Registry/ConfigureBuilderContextTests.cs +++ b/test/Polly.Core.Tests/Registry/ConfigureBuilderContextTests.cs @@ -2,10 +2,10 @@ namespace Polly.Core.Tests.Registry; -public class ConfigureBuilderContextTests +public static class ConfigureBuilderContextTests { [Fact] - public void AddReloadToken_Ok() + public static void AddReloadToken_Ok() { var context = new ConfigureBuilderContext(0, "dummy", "dummy"); using var source = new CancellationTokenSource(); diff --git a/test/Polly.Core.Tests/ResilienceContextPoolTests.cs b/test/Polly.Core.Tests/ResilienceContextPoolTests.cs index b5be828a606..604fdeb1369 100644 --- a/test/Polly.Core.Tests/ResilienceContextPoolTests.cs +++ b/test/Polly.Core.Tests/ResilienceContextPoolTests.cs @@ -17,9 +17,10 @@ public void Get_EnsureNotNull() => [Fact] public void Get_EnsureDefaults() { - var context = ResilienceContextPool.Shared.Get(); + var cancellationToken = CancellationToken.None; + var context = ResilienceContextPool.Shared.Get(cancellationToken); - AssertDefaults(context); + AssertDefaults(context, cancellationToken); } [Fact] @@ -79,11 +80,11 @@ public void Get_OperationKeyAndCancellationToken_Ok(string? key) public async Task Get_EnsurePooled() => await TestUtilities.AssertWithTimeoutAsync(() => { - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(default(CancellationToken)); ResilienceContextPool.Shared.Return(context); - ResilienceContextPool.Shared.Get().Should().BeSameAs(context); + ResilienceContextPool.Shared.Get(default(CancellationToken)).Should().BeSameAs(context); }); [Fact] @@ -95,24 +96,24 @@ public async Task Return_EnsureDefaults() => await TestUtilities.AssertWithTimeoutAsync(() => { using var cts = new CancellationTokenSource(); - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(CancellationToken.None); context.CancellationToken = cts.Token; context.Initialize(true); context.CancellationToken.Should().Be(cts.Token); context.Properties.Set(new ResiliencePropertyKey("abc"), 10); ResilienceContextPool.Shared.Return(context); - AssertDefaults(context); + AssertDefaults(context, CancellationToken.None); }); - private static void AssertDefaults(ResilienceContext context) + private static void AssertDefaults(ResilienceContext context, CancellationToken expectedToken) { context.IsInitialized.Should().BeFalse(); context.ContinueOnCapturedContext.Should().BeFalse(); context.IsVoid.Should().BeFalse(); context.ResultType.Name.Should().Be("UnknownResult"); context.IsSynchronous.Should().BeFalse(); - context.CancellationToken.Should().Be(CancellationToken.None); + context.CancellationToken.Should().Be(expectedToken); context.Properties.Options.Should().BeEmpty(); context.OperationKey.Should().BeNull(); } diff --git a/test/Polly.Core.Tests/ResilienceContextTests.cs b/test/Polly.Core.Tests/ResilienceContextTests.cs index 31dfc6f5337..1e33b9e224d 100644 --- a/test/Polly.Core.Tests/ResilienceContextTests.cs +++ b/test/Polly.Core.Tests/ResilienceContextTests.cs @@ -2,35 +2,36 @@ namespace Polly.Core.Tests; public class ResilienceContextTests { + [Theory] [InlineData(true)] [InlineData(false)] - [Theory] public void Initialize_Typed_Ok(bool synchronous) { var context = ResilienceContextPool.Shared.Get(); context.Initialize(synchronous); - context.ResultType.Should().Be(typeof(bool)); + context.ResultType.Should().Be(); context.IsVoid.Should().BeFalse(); context.IsInitialized.Should().BeTrue(); context.IsSynchronous.Should().Be(synchronous); context.ContinueOnCapturedContext.Should().BeFalse(); } + [Theory] [InlineData(true)] [InlineData(false)] - [Theory] public void Initialize_From_Ok(bool synchronous) { - var context = ResilienceContextPool.Shared.Get("some-key"); + var cancellationToken = CancellationToken.None; + var context = ResilienceContextPool.Shared.Get("some-key", cancellationToken); context.Initialize(synchronous); context.ContinueOnCapturedContext = true; context.Properties.Set(new ResiliencePropertyKey("A"), "B"); using var cancellation = new CancellationTokenSource(); - var other = ResilienceContextPool.Shared.Get(); + var other = ResilienceContextPool.Shared.Get(cancellationToken); other.InitializeFrom(context, cancellation.Token); - other.ResultType.Should().Be(typeof(bool)); + other.ResultType.Should().Be(); other.IsVoid.Should().BeFalse(); other.IsInitialized.Should().BeTrue(); other.IsSynchronous.Should().Be(synchronous); @@ -48,7 +49,7 @@ public void Initialize_Void_Ok(bool synchronous) var context = ResilienceContextPool.Shared.Get(); context.Initialize(synchronous); - context.ResultType.Should().Be(typeof(VoidResult)); + context.ResultType.Should().Be(); context.IsVoid.Should().BeTrue(); context.IsInitialized.Should().BeTrue(); context.IsSynchronous.Should().Be(synchronous); diff --git a/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs b/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs index c22471a427d..b16ed015daa 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs @@ -34,7 +34,7 @@ public partial class ResiliencePipelineTests async strategy => { - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(CancellationToken); context.CancellationToken = CancellationToken; (await strategy.ExecuteAsync( (context, state) => @@ -49,7 +49,7 @@ public partial class ResiliencePipelineTests async strategy => { - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(CancellationToken); context.CancellationToken = CancellationToken; (await strategy.ExecuteAsync( (context) => @@ -62,8 +62,10 @@ public partial class ResiliencePipelineTests }; #pragma warning restore IDE0028 - [MemberData(nameof(ExecuteAsyncGenericStrategyData))] [Theory] +#pragma warning disable xUnit1044 // Avoid using TheoryData type arguments that are not serializable + [MemberData(nameof(ExecuteAsyncGenericStrategyData))] +#pragma warning restore xUnit1044 // Avoid using TheoryData type arguments that are not serializable public async Task ExecuteAsync_GenericStrategy_Ok(Func, ValueTask> execute) { var pipeline = new ResiliencePipeline(PipelineComponentFactory.FromStrategy(new TestResilienceStrategy @@ -71,7 +73,7 @@ public async Task ExecuteAsync_GenericStrategy_Ok(Func { c.IsSynchronous.Should().BeFalse(); - c.ResultType.Should().Be(typeof(string)); + c.ResultType.Should().Be(); c.CancellationToken.CanBeCanceled.Should().BeTrue(); }, }), DisposeBehavior.Allow, null); @@ -86,10 +88,10 @@ public async Task ExecuteOutcomeAsync_GenericStrategy_Ok() { state.Should().Be("state"); context.IsSynchronous.Should().BeFalse(); - context.ResultType.Should().Be(typeof(int)); + context.ResultType.Should().Be(); return Outcome.FromResultAsValueTask(12345); }, - ResilienceContextPool.Shared.Get(), + ResilienceContextPool.Shared.Get(CancellationToken), "state"); result.Result.Should().Be(12345); diff --git a/test/Polly.Core.Tests/ResiliencePipelineTTests.Sync.cs b/test/Polly.Core.Tests/ResiliencePipelineTTests.Sync.cs index d242e3aa62a..ee75b6fa049 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTTests.Sync.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTTests.Sync.cs @@ -49,7 +49,7 @@ public partial class ResiliencePipelineTests strategy => { - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(CancellationToken); context.CancellationToken = CancellationToken; strategy.Execute( (context, state) => @@ -65,7 +65,7 @@ public partial class ResiliencePipelineTests strategy => { - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(CancellationToken); context.CancellationToken = CancellationToken; strategy.Execute( (context) => @@ -87,7 +87,7 @@ public void Execute_GenericStrategy_Ok(Action> execut Before = (c, _) => { c.IsSynchronous.Should().BeTrue(); - c.ResultType.Should().Be(typeof(string)); + c.ResultType.Should().Be(); }, }), DisposeBehavior.Allow, null); diff --git a/test/Polly.Core.Tests/ResiliencePipelineTests.Async.cs b/test/Polly.Core.Tests/ResiliencePipelineTests.Async.cs index ea351c78a1f..acec79cb417 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTests.Async.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTests.Async.cs @@ -87,9 +87,11 @@ public async Task ExecuteAsync_Ok(ExecuteParameters parameters) [Fact] public async Task ExecuteAsync_EnsureCallStackPreserved() { + var context = ResilienceContextPool.Shared.Get(); + await AssertStackTrace(s => s.ExecuteAsync(_ => MyThrowingMethod())); - await AssertStackTrace(s => s.ExecuteAsync(_ => MyThrowingMethod(), ResilienceContextPool.Shared.Get())); - await AssertStackTrace(s => s.ExecuteAsync((_, _) => MyThrowingMethod(), ResilienceContextPool.Shared.Get(), "state")); + await AssertStackTrace(s => s.ExecuteAsync(_ => MyThrowingMethod(), context)); + await AssertStackTrace(s => s.ExecuteAsync((_, _) => MyThrowingMethod(), context, "state")); await AssertStackTrace(s => s.ExecuteAsync((_, _) => MyThrowingMethod(), "state")); static async ValueTask AssertStackTrace(Func execute) diff --git a/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs b/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs index cc8ea3c25ea..36b96689a1a 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs @@ -52,7 +52,7 @@ static void AssertResilienceContext(ResilienceContext context) { context.IsSynchronous.Should().BeFalse(); context.IsVoid.Should().BeFalse(); - context.ResultType.Should().Be(typeof(long)); + context.ResultType.Should().Be(); context.ContinueOnCapturedContext.Should().BeFalse(); } @@ -65,8 +65,10 @@ static void AssertResilienceContextAndToken(ResilienceContext context) static void AssertContextInitialized(ResilienceContext context) => context.IsInitialized.Should().BeTrue(); } - [MemberData(nameof(ExecuteAsyncT_EnsureCorrectBehavior_Data))] [Theory] +#pragma warning disable xUnit1042 // The member referenced by the MemberData attribute returns untyped data rows + [MemberData(nameof(ExecuteAsyncT_EnsureCorrectBehavior_Data))] +#pragma warning restore xUnit1042 // The member referenced by the MemberData attribute returns untyped data rows public async Task ExecuteAsyncT_Ok(ExecuteParameters parameters) { ResilienceContext? context = null; @@ -89,9 +91,11 @@ public async Task ExecuteAsyncT_Ok(ExecuteParameters parameters) [Fact] public async Task ExecuteAsync_T_EnsureCallStackPreserved() { + var context = ResilienceContextPool.Shared.Get(); + await AssertStackTrace(s => s.ExecuteAsync(_ => MyThrowingMethod())); - await AssertStackTrace(s => s.ExecuteAsync(_ => MyThrowingMethod(), ResilienceContextPool.Shared.Get())); - await AssertStackTrace(s => s.ExecuteAsync((_, _) => MyThrowingMethod(), ResilienceContextPool.Shared.Get(), "state")); + await AssertStackTrace(s => s.ExecuteAsync(_ => MyThrowingMethod(), context)); + await AssertStackTrace(s => s.ExecuteAsync((_, _) => MyThrowingMethod(), context, "state")); await AssertStackTrace(s => s.ExecuteAsync((_, _) => MyThrowingMethod(), "state")); static async ValueTask AssertStackTrace(Func> execute) @@ -119,7 +123,7 @@ public async Task ExecuteOutcomeAsync_Ok() { state.Should().Be("state"); context.IsSynchronous.Should().BeFalse(); - context.ResultType.Should().Be(typeof(int)); + context.ResultType.Should().Be(); return Outcome.FromResultAsValueTask(12345); }, ResilienceContextPool.Shared.Get(), diff --git a/test/Polly.Core.Tests/ResiliencePipelineTests.Sync.cs b/test/Polly.Core.Tests/ResiliencePipelineTests.Sync.cs index 867705583be..77662a39545 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTests.Sync.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTests.Sync.cs @@ -37,14 +37,14 @@ private static IEnumerable Execute_EnsureCorrectBehavior_Exec AssertContext = AssertResilienceContext, }; - yield return new ExecuteParameters(r => r.Execute(context => { }, ResilienceContextPool.Shared.Get())) + yield return new ExecuteParameters(r => r.Execute(context => { }, ResilienceContextPool.Shared.Get(CancellationToken))) { Caption = "ResilienceContext", AssertContext = AssertResilienceContext, AssertContextAfter = AssertContextInitialized, }; - yield return new ExecuteParameters(r => r.Execute((_, s) => { s.Should().Be("dummy-state"); }, ResilienceContextPool.Shared.Get(), "dummy-state")) + yield return new ExecuteParameters(r => r.Execute((_, s) => { s.Should().Be("dummy-state"); }, ResilienceContextPool.Shared.Get(CancellationToken), "dummy-state")) { Caption = "Execute_ResilienceContextAndState", AssertContext = AssertResilienceContext, @@ -91,11 +91,13 @@ public async Task Execute_Ok(ExecuteParameters parameters) [Fact] public void Execute_EnsureCallStackPreserved() { + var context = ResilienceContextPool.Shared.Get(CancellationToken); + AssertStackTrace(s => s.Execute(() => MyThrowingMethod())); AssertStackTrace(s => s.Execute(_ => MyThrowingMethod())); - AssertStackTrace(s => s.Execute((_) => MyThrowingMethod(), ResilienceContextPool.Shared.Get())); - AssertStackTrace(s => s.Execute((_, _) => MyThrowingMethod(), ResilienceContextPool.Shared.Get())); - AssertStackTrace(s => s.Execute((_, _) => MyThrowingMethod(), ResilienceContextPool.Shared.Get(), "state")); + AssertStackTrace(s => s.Execute((_) => MyThrowingMethod(), context)); + AssertStackTrace(s => s.Execute((_, _) => MyThrowingMethod(), context)); + AssertStackTrace(s => s.Execute((_, _) => MyThrowingMethod(), context, "state")); AssertStackTrace(s => s.Execute((_, _) => MyThrowingMethod(), "state")); AssertStackTrace(s => s.Execute((_) => MyThrowingMethod(), "state")); diff --git a/test/Polly.Core.Tests/ResiliencePipelineTests.SyncT.cs b/test/Polly.Core.Tests/ResiliencePipelineTests.SyncT.cs index 89ba6bc754d..af641f4fd34 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTests.SyncT.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTests.SyncT.cs @@ -33,14 +33,14 @@ private static IEnumerable ExecuteT_EnsureCorrectBehavior_Exe AssertContext = AssertResilienceContext, }; - yield return new ExecuteParameters(r => r.Execute(_ => result, ResilienceContextPool.Shared.Get()), result) + yield return new ExecuteParameters(r => r.Execute(_ => result, ResilienceContextPool.Shared.Get(CancellationToken)), result) { Caption = "ExecuteT_ResilienceContext", AssertContext = AssertResilienceContext, AssertContextAfter = AssertContextInitialized }; - yield return new ExecuteParameters(r => r.Execute((_, s) => { s.Should().Be("dummy-state"); return result; }, ResilienceContextPool.Shared.Get(), "dummy-state"), result) + yield return new ExecuteParameters(r => r.Execute((_, s) => { s.Should().Be("dummy-state"); return result; }, ResilienceContextPool.Shared.Get(CancellationToken), "dummy-state"), result) { Caption = "ExecuteT_ResilienceContext", AssertContext = AssertResilienceContext, @@ -56,7 +56,7 @@ static void AssertResilienceContext(ResilienceContext context) { context.IsSynchronous.Should().BeTrue(); context.IsVoid.Should().BeFalse(); - context.ResultType.Should().Be(typeof(long)); + context.ResultType.Should().Be(); context.ContinueOnCapturedContext.Should().BeFalse(); } @@ -69,8 +69,10 @@ static void AssertResilienceContextAndToken(ResilienceContext context) static void AssertContextInitialized(ResilienceContext context) => context.IsInitialized.Should().BeTrue(); } - [MemberData(nameof(ExecuteT_EnsureCorrectBehavior_Data))] [Theory] +#pragma warning disable xUnit1042 // The member referenced by the MemberData attribute returns untyped data rows + [MemberData(nameof(ExecuteT_EnsureCorrectBehavior_Data))] +#pragma warning restore xUnit1042 // The member referenced by the MemberData attribute returns untyped data rows public async Task ExecuteT_Ok(ExecuteParameters parameters) { ResilienceContext? context = null; @@ -93,11 +95,13 @@ public async Task ExecuteT_Ok(ExecuteParameters parameters) [Fact] public void Execute_T_EnsureCallStackPreserved() { + var context = ResilienceContextPool.Shared.Get(CancellationToken); + AssertStackTrace(s => s.Execute(() => MyThrowingMethod())); AssertStackTrace(s => s.Execute(_ => MyThrowingMethod())); - AssertStackTrace(s => s.Execute((_, _) => MyThrowingMethod(), ResilienceContextPool.Shared.Get())); - AssertStackTrace(s => s.Execute((_) => MyThrowingMethod(), ResilienceContextPool.Shared.Get())); - AssertStackTrace(s => s.Execute((_, _) => MyThrowingMethod(), ResilienceContextPool.Shared.Get(), "state")); + AssertStackTrace(s => s.Execute((_, _) => MyThrowingMethod(), context)); + AssertStackTrace(s => s.Execute((_) => MyThrowingMethod(), context)); + AssertStackTrace(s => s.Execute((_, _) => MyThrowingMethod(), context, "state")); AssertStackTrace(s => s.Execute((_, _) => MyThrowingMethod(), "state")); AssertStackTrace(s => s.Execute((_) => MyThrowingMethod(), "state")); diff --git a/test/Polly.Core.Tests/ResiliencePipelineTests.cs b/test/Polly.Core.Tests/ResiliencePipelineTests.cs index f12ae724c32..4bccb35349c 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTests.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTests.cs @@ -69,11 +69,11 @@ public void Null_Ok() [Fact] public async Task DebuggerProxy_Ok() { - await using var pipeline = (CompositeComponent)PipelineComponentFactory.CreateComposite(new[] - { + await using var pipeline = (CompositeComponent)PipelineComponentFactory.CreateComposite( + [ Substitute.For(), Substitute.For(), - }, null!, null!); + ], null!, null!); new CompositeComponentDebuggerProxy(pipeline).Strategies.Should().HaveCount(2); } diff --git a/test/Polly.Core.Tests/Retry/OnRetryArgumentsTests.cs b/test/Polly.Core.Tests/Retry/OnRetryArgumentsTests.cs index 4bd781a2e99..fe3f3cf9696 100644 --- a/test/Polly.Core.Tests/Retry/OnRetryArgumentsTests.cs +++ b/test/Polly.Core.Tests/Retry/OnRetryArgumentsTests.cs @@ -2,14 +2,19 @@ namespace Polly.Core.Tests.Retry; -public class OnRetryArgumentsTests +public static class OnRetryArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new OnRetryArguments(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1), 2, TimeSpan.FromSeconds(3), TimeSpan.MaxValue); + // Arrange + var context = ResilienceContextPool.Shared.Get(); - args.Context.Should().NotBeNull(); + // Act + var args = new OnRetryArguments(context, Outcome.FromResult(1), 2, TimeSpan.FromSeconds(3), TimeSpan.MaxValue); + + // Assert + args.Context.Should().Be(context); args.Outcome.Result.Should().Be(1); args.AttemptNumber.Should().Be(2); args.RetryDelay.Should().Be(TimeSpan.FromSeconds(3)); diff --git a/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs index 5fb9dee6276..a42c3fb104e 100644 --- a/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs @@ -2,14 +2,19 @@ namespace Polly.Core.Tests.Retry; -public class RetryDelayGeneratorArgumentsTests +public static class RetryDelayGeneratorArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new RetryDelayGeneratorArguments(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1), 2); + // Arrange + var context = ResilienceContextPool.Shared.Get(); - args.Context.Should().NotBeNull(); + // Act + var args = new RetryDelayGeneratorArguments(context, Outcome.FromResult(1), 2); + + // Assert + args.Context.Should().Be(context); args.Outcome.Result.Should().Be(1); args.AttemptNumber.Should().Be(2); } diff --git a/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs b/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs index c389351329b..ce6a488e3d8 100644 --- a/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs +++ b/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs @@ -35,10 +35,9 @@ public async Task ExecuteAsync_CancellationRequested_EnsureNotRetried() { SetupNoDelay(); var sut = CreateSut(); - using var cancellationToken = new CancellationTokenSource(); - cancellationToken.Cancel(); - var context = ResilienceContextPool.Shared.Get(); - context.CancellationToken = cancellationToken.Token; + using var cts = new CancellationTokenSource(); + cts.Cancel(); + var context = ResilienceContextPool.Shared.Get(cts.Token); var executed = false; var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsValueTask("dummy"); }, context, "state"); @@ -49,18 +48,17 @@ public async Task ExecuteAsync_CancellationRequested_EnsureNotRetried() [Fact] public async Task ExecuteAsync_CancellationRequestedAfterCallback_EnsureNotRetried() { - using var cancellationToken = new CancellationTokenSource(); + using var cts = new CancellationTokenSource(); _options.ShouldHandle = _ => PredicateResult.True(); _options.OnRetry = _ => { - cancellationToken.Cancel(); + cts.Cancel(); return default; }; var sut = CreateSut(TimeProvider.System); - var context = ResilienceContextPool.Shared.Get(); - context.CancellationToken = cancellationToken.Token; + var context = ResilienceContextPool.Shared.Get(cts.Token); var executed = false; var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsValueTask("dummy"); }, context, "state"); @@ -154,7 +152,7 @@ public void RetryDelayGenerator_Respected() return new ValueTask(delay); }; - CreateSut(TimeProvider.System).Execute(_ => "dummy"); + CreateSut(TimeProvider.System).Execute(_ => "dummy"); retries.Should().Be(3); generatedValues.Should().Be(3); diff --git a/test/Polly.Core.Tests/Retry/ShouldRetryArgumentsTests.cs b/test/Polly.Core.Tests/Retry/ShouldRetryArgumentsTests.cs index adcfaaa37bf..ee88dacfc71 100644 --- a/test/Polly.Core.Tests/Retry/ShouldRetryArgumentsTests.cs +++ b/test/Polly.Core.Tests/Retry/ShouldRetryArgumentsTests.cs @@ -2,13 +2,19 @@ namespace Polly.Core.Tests.Retry; -public class ShouldRetryArgumentsTests +public static class ShouldRetryArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new RetryPredicateArguments(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1), 2); - args.Context.Should().NotBeNull(); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var args = new RetryPredicateArguments(context, Outcome.FromResult(1), 2); + + // Assert + args.Context.Should().Be(context); args.Outcome.Result.Should().Be(1); args.AttemptNumber.Should().Be(2); } diff --git a/test/Polly.Core.Tests/Simmy/Behavior/BehaviorGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Simmy/Behavior/BehaviorGeneratorArgumentsTests.cs index 687491b82ab..0c01057a3e3 100644 --- a/test/Polly.Core.Tests/Simmy/Behavior/BehaviorGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Simmy/Behavior/BehaviorGeneratorArgumentsTests.cs @@ -2,12 +2,18 @@ namespace Polly.Core.Tests.Simmy.Behavior; -public class BehaviorGeneratorArgumentsTests +public static class BehaviorGeneratorArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new BehaviorGeneratorArguments(ResilienceContextPool.Shared.Get()); - args.Context.Should().NotBeNull(); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var args = new BehaviorGeneratorArguments(context); + + // Assert + args.Context.Should().Be(context); } } diff --git a/test/Polly.Core.Tests/Simmy/Behavior/OnBehaviorInjectedArgumentsTests.cs b/test/Polly.Core.Tests/Simmy/Behavior/OnBehaviorInjectedArgumentsTests.cs index d4ea4001855..7248cc71e36 100644 --- a/test/Polly.Core.Tests/Simmy/Behavior/OnBehaviorInjectedArgumentsTests.cs +++ b/test/Polly.Core.Tests/Simmy/Behavior/OnBehaviorInjectedArgumentsTests.cs @@ -2,12 +2,18 @@ namespace Polly.Core.Tests.Simmy.Behavior; -public class OnBehaviorInjectedArgumentsTests +public static class OnBehaviorInjectedArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new OnBehaviorInjectedArguments(ResilienceContextPool.Shared.Get()); - args.Context.Should().NotBeNull(); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var args = new OnBehaviorInjectedArguments(context); + + // Assert + args.Context.Should().Be(context); } } diff --git a/test/Polly.Core.Tests/Simmy/EnabledGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Simmy/EnabledGeneratorArgumentsTests.cs index 78825a85ba1..e581e11242d 100644 --- a/test/Polly.Core.Tests/Simmy/EnabledGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Simmy/EnabledGeneratorArgumentsTests.cs @@ -2,12 +2,18 @@ namespace Polly.Core.Tests.Simmy.Outcomes; -public class EnabledGeneratorArgumentsTests +public static class EnabledGeneratorArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new EnabledGeneratorArguments(ResilienceContextPool.Shared.Get()); - args.Context.Should().NotBeNull(); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var args = new EnabledGeneratorArguments(context); + + // Assert + args.Context.Should().Be(context); } } diff --git a/test/Polly.Core.Tests/Simmy/Fault/ChaosFaultPipelineBuilderExtensionsTests.cs b/test/Polly.Core.Tests/Simmy/Fault/ChaosFaultPipelineBuilderExtensionsTests.cs index d11b4e5fdc3..0acc37e1bf7 100644 --- a/test/Polly.Core.Tests/Simmy/Fault/ChaosFaultPipelineBuilderExtensionsTests.cs +++ b/test/Polly.Core.Tests/Simmy/Fault/ChaosFaultPipelineBuilderExtensionsTests.cs @@ -32,7 +32,7 @@ private static void AssertFaultStrategy(ResiliencePipelineBuilder strategy.EnabledGenerator.Invoke(new(context)).Preserve().GetAwaiter().GetResult().Should().Be(enabled); strategy.InjectionRateGenerator.Invoke(new(context)).Preserve().GetAwaiter().GetResult().Should().Be(injectionRate); - strategy.FaultGenerator!.Invoke(new(context)).Preserve().GetAwaiter().GetResult().Should().BeOfType(typeof(TException)); + strategy.FaultGenerator!.Invoke(new(context)).Preserve().GetAwaiter().GetResult().Should().BeOfType(); } private static ChaosFaultStrategy AssertFaultStrategy(ResiliencePipelineBuilder builder, bool enabled, double injectionRate) @@ -43,7 +43,7 @@ private static ChaosFaultStrategy AssertFaultStrategy(ResiliencePipe strategy.EnabledGenerator.Invoke(new(context)).Preserve().GetAwaiter().GetResult().Should().Be(enabled); strategy.InjectionRateGenerator.Invoke(new(context)).Preserve().GetAwaiter().GetResult().Should().Be(injectionRate); - strategy.FaultGenerator!.Invoke(new(context)).Preserve().GetAwaiter().GetResult().Should().BeOfType(typeof(TException)); + strategy.FaultGenerator!.Invoke(new(context)).Preserve().GetAwaiter().GetResult().Should().BeOfType(); return strategy; } diff --git a/test/Polly.Core.Tests/Simmy/Fault/ChaosFaultStrategyTests.cs b/test/Polly.Core.Tests/Simmy/Fault/ChaosFaultStrategyTests.cs index 4c305482c9d..8711168a975 100644 --- a/test/Polly.Core.Tests/Simmy/Fault/ChaosFaultStrategyTests.cs +++ b/test/Polly.Core.Tests/Simmy/Fault/ChaosFaultStrategyTests.cs @@ -46,7 +46,7 @@ public void FaultInvalidCtor(object options, string expectedMessage, Type expect catch (Exception ex) { Assert.IsType(expectedException, ex); -#if !NET481 +#if NET Assert.Equal(expectedMessage, ex.Message); #endif } diff --git a/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorArgumentsTests.cs index 0c7b8e63a36..73e29211af6 100644 --- a/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorArgumentsTests.cs @@ -2,12 +2,18 @@ namespace Polly.Core.Tests.Simmy.Fault; -public class FaultGeneratorArgumentsTests +public static class FaultGeneratorArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new FaultGeneratorArguments(ResilienceContextPool.Shared.Get()); - args.Context.Should().NotBeNull(); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var args = new FaultGeneratorArguments(context); + + // Assert + args.Context.Should().Be(context); } } diff --git a/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorTests.cs b/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorTests.cs index 0ffe3c121cf..1889a03b315 100644 --- a/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorTests.cs +++ b/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorTests.cs @@ -1,5 +1,4 @@ -using System; -using Polly.Simmy.Fault; +using Polly.Simmy.Fault; namespace Polly.Core.Tests.Simmy.Fault; @@ -44,6 +43,8 @@ public void AddException_FactoryWithResilienceContext_Ok() { Func> func = generator; - return func(new FaultGeneratorArguments(ResilienceContextPool.Shared.Get())).AsTask().Result; + return func( + new FaultGeneratorArguments( + ResilienceContextPool.Shared.Get())).AsTask().Result; } } diff --git a/test/Polly.Core.Tests/Simmy/Fault/OnFaultInjectedArgumentsTests.cs b/test/Polly.Core.Tests/Simmy/Fault/OnFaultInjectedArgumentsTests.cs index 4c9d9325740..4919c4b5673 100644 --- a/test/Polly.Core.Tests/Simmy/Fault/OnFaultInjectedArgumentsTests.cs +++ b/test/Polly.Core.Tests/Simmy/Fault/OnFaultInjectedArgumentsTests.cs @@ -2,13 +2,20 @@ namespace Polly.Core.Tests.Simmy.Fault; -public class OnFaultInjectedArgumentsTests +public static class OnFaultInjectedArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new OnFaultInjectedArguments(ResilienceContextPool.Shared.Get(), new InvalidCastException()); - args.Context.Should().NotBeNull(); - args.Fault.Should().NotBeNull(); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + var fault = new InvalidCastException(); + + // Act + var args = new OnFaultInjectedArguments(context, fault); + + // Assert + args.Context.Should().Be(context); + args.Fault.Should().Be(fault); } } diff --git a/test/Polly.Core.Tests/Simmy/InjectionRateGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Simmy/InjectionRateGeneratorArgumentsTests.cs index e5202f2115a..1e609650564 100644 --- a/test/Polly.Core.Tests/Simmy/InjectionRateGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Simmy/InjectionRateGeneratorArgumentsTests.cs @@ -2,12 +2,18 @@ namespace Polly.Core.Tests.Simmy.Outcomes; -public class InjectionRateGeneratorArgumentsTests +public static class InjectionRateGeneratorArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new InjectionRateGeneratorArguments(ResilienceContextPool.Shared.Get()); - args.Context.Should().NotBeNull(); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var args = new InjectionRateGeneratorArguments(context); + + // Assert + args.Context.Should().Be(context); } } diff --git a/test/Polly.Core.Tests/Simmy/Latency/LatencyGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Simmy/Latency/LatencyGeneratorArgumentsTests.cs index 4220a57459a..fe205ab7e25 100644 --- a/test/Polly.Core.Tests/Simmy/Latency/LatencyGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Simmy/Latency/LatencyGeneratorArgumentsTests.cs @@ -2,12 +2,18 @@ namespace Polly.Core.Tests.Simmy.Latency; -public class LatencyGeneratorArgumentsTests +public static class LatencyGeneratorArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new LatencyGeneratorArguments(ResilienceContextPool.Shared.Get()); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var args = new LatencyGeneratorArguments(context); + + // Assert args.Context.Should().NotBeNull(); } } diff --git a/test/Polly.Core.Tests/Simmy/Latency/OnLatencyInjectedArgumentsTests.cs b/test/Polly.Core.Tests/Simmy/Latency/OnLatencyInjectedArgumentsTests.cs index 838ea641690..663f62f0cb7 100644 --- a/test/Polly.Core.Tests/Simmy/Latency/OnLatencyInjectedArgumentsTests.cs +++ b/test/Polly.Core.Tests/Simmy/Latency/OnLatencyInjectedArgumentsTests.cs @@ -2,13 +2,19 @@ namespace Polly.Core.Tests.Simmy.Latency; -public class OnLatencyInjectedArgumentsTests +public static class OnLatencyInjectedArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new OnLatencyInjectedArguments(ResilienceContextPool.Shared.Get(), TimeSpan.FromSeconds(10)); - args.Context.Should().NotBeNull(); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var args = new OnLatencyInjectedArguments(context, TimeSpan.FromSeconds(10)); + + // Assert + args.Context.Should().Be(context); args.Latency.Should().Be(TimeSpan.FromSeconds(10)); } } diff --git a/test/Polly.Core.Tests/Simmy/Outcomes/ChaosOutcomePipelineBuilderExtensionsTests.cs b/test/Polly.Core.Tests/Simmy/Outcomes/ChaosOutcomePipelineBuilderExtensionsTests.cs index 192948c5506..20ada2e269b 100644 --- a/test/Polly.Core.Tests/Simmy/Outcomes/ChaosOutcomePipelineBuilderExtensionsTests.cs +++ b/test/Polly.Core.Tests/Simmy/Outcomes/ChaosOutcomePipelineBuilderExtensionsTests.cs @@ -35,8 +35,10 @@ private static void AssertResultStrategy(ResiliencePipelineBuilder builder options.OutcomeGenerator!.Invoke(new(context)).Preserve().GetAwaiter().GetResult().Should().Be(outcome); } - [MemberData(nameof(ResultStrategy))] [Theory] +#pragma warning disable xUnit1044 // Avoid using TheoryData type arguments that are not serializable + [MemberData(nameof(ResultStrategy))] +#pragma warning restore xUnit1044 // Avoid using TheoryData type arguments that are not serializable internal void AddResult_Options_Ok(Action> configure) { var builder = new ResiliencePipelineBuilder(); diff --git a/test/Polly.Core.Tests/Simmy/Outcomes/ChaosOutcomeStrategyTests.cs b/test/Polly.Core.Tests/Simmy/Outcomes/ChaosOutcomeStrategyTests.cs index e3aa3101714..cafdf65329f 100644 --- a/test/Polly.Core.Tests/Simmy/Outcomes/ChaosOutcomeStrategyTests.cs +++ b/test/Polly.Core.Tests/Simmy/Outcomes/ChaosOutcomeStrategyTests.cs @@ -30,8 +30,12 @@ public ChaosOutcomeStrategyTests() ], ]; + private static CancellationToken CancellationToken => CancellationToken.None; + [Theory] +#pragma warning disable xUnit1042 // The member referenced by the MemberData attribute returns untyped data rows [MemberData(nameof(ResultCtorTestCases))] +#pragma warning restore xUnit1042 // The member referenced by the MemberData attribute returns untyped data rows #pragma warning disable xUnit1026 // Theory methods should use all of their parameters public void ResultInvalidCtor(object options, string expectedMessage, Type expectedException) #pragma warning restore xUnit1026 // Theory methods should use all of their parameters @@ -44,7 +48,7 @@ public void ResultInvalidCtor(object options, string expectedMessage, Type expec catch (Exception ex) { Assert.IsType(expectedException, ex); -#if !NET481 +#if NET Assert.Equal(expectedMessage, ex.Message); #endif } @@ -96,7 +100,7 @@ public async Task Given_enabled_and_randomly_within_threshold_should_inject_resu { _userDelegateExecuted = true; return new ValueTask(HttpStatusCode.OK); - }); + }, CancellationToken); response.Should().Be(fakeResult); _userDelegateExecuted.Should().BeFalse(); @@ -125,7 +129,7 @@ public void Given_enabled_and_randomly_not_within_threshold_should_not_inject_re { _userDelegateExecuted = true; return HttpStatusCode.OK; - }); + }, CancellationToken); response.Should().Be(HttpStatusCode.OK); _userDelegateExecuted.Should().BeTrue(); @@ -148,7 +152,7 @@ public async Task Given_enabled_and_randomly_within_threshold_should_inject_resu { _userDelegateExecuted = true; return new ValueTask(HttpStatusCode.OK); - }); + }, CancellationToken); response.Should().Be(null); _userDelegateExecuted.Should().BeFalse(); @@ -176,7 +180,7 @@ public async Task Given_enabled_and_randomly_within_threshold_should_not_inject_ { _userDelegateExecuted = true; return new ValueTask(42); - }); + }, CancellationToken); response.Should().Be(42); _userDelegateExecuted.Should().BeTrue(); @@ -206,7 +210,7 @@ await sut.Invoking(s => s.ExecuteAsync(_ => { _userDelegateExecuted = true; return new ValueTask(42); - }, CancellationToken.None) + }, CancellationToken) .AsTask()) .Should() .ThrowAsync(); diff --git a/test/Polly.Core.Tests/Simmy/Outcomes/OnOutcomeInjectedArgumentsTests.cs b/test/Polly.Core.Tests/Simmy/Outcomes/OnOutcomeInjectedArgumentsTests.cs index c2a4bef4549..792dbdcc91b 100644 --- a/test/Polly.Core.Tests/Simmy/Outcomes/OnOutcomeInjectedArgumentsTests.cs +++ b/test/Polly.Core.Tests/Simmy/Outcomes/OnOutcomeInjectedArgumentsTests.cs @@ -2,13 +2,19 @@ namespace Polly.Core.Tests.Simmy.Outcomes; -public class OnOutcomeInjectedArgumentsTests +public static class OnOutcomeInjectedArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new OnOutcomeInjectedArguments(ResilienceContextPool.Shared.Get(), new(200)); - args.Context.Should().NotBeNull(); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var args = new OnOutcomeInjectedArguments(context, new(200)); + + // Assert + args.Context.Should().Be(context); args.Outcome.Should().NotBeNull(); } } diff --git a/test/Polly.Core.Tests/Simmy/Outcomes/OutcomeGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Simmy/Outcomes/OutcomeGeneratorArgumentsTests.cs index 0f8873eceae..18b7bdb8198 100644 --- a/test/Polly.Core.Tests/Simmy/Outcomes/OutcomeGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Simmy/Outcomes/OutcomeGeneratorArgumentsTests.cs @@ -2,12 +2,18 @@ namespace Polly.Core.Tests.Simmy.Outcomes; -public class OutcomeGeneratorArgumentsTests +public static class OutcomeGeneratorArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new OutcomeGeneratorArguments(ResilienceContextPool.Shared.Get()); + // Arrange + var context = ResilienceContextPool.Shared.Get(); + + // Act + var args = new OutcomeGeneratorArguments(context); + + // Assert args.Context.Should().NotBeNull(); } } diff --git a/test/Polly.Core.Tests/Simmy/Outcomes/OutcomeGeneratorTests.cs b/test/Polly.Core.Tests/Simmy/Outcomes/OutcomeGeneratorTests.cs index 924de797690..4ffffc1a07b 100644 --- a/test/Polly.Core.Tests/Simmy/Outcomes/OutcomeGeneratorTests.cs +++ b/test/Polly.Core.Tests/Simmy/Outcomes/OutcomeGeneratorTests.cs @@ -1,5 +1,4 @@ -using System; -using Polly.Simmy.Outcomes; +using Polly.Simmy.Outcomes; namespace Polly.Core.Tests.Simmy.Outcomes; @@ -72,6 +71,8 @@ public void AddResult_FactoryWithResilienceContext_Ok() { Func?>> func = generator; - return func(new OutcomeGeneratorArguments(ResilienceContextPool.Shared.Get())).AsTask().Result; + return func( + new OutcomeGeneratorArguments( + ResilienceContextPool.Shared.Get())).AsTask().Result; } } diff --git a/test/Polly.Core.Tests/Simmy/Utils/GeneratorHelperTests.cs b/test/Polly.Core.Tests/Simmy/Utils/GeneratorHelperTests.cs index 258124cec77..4989e866930 100644 --- a/test/Polly.Core.Tests/Simmy/Utils/GeneratorHelperTests.cs +++ b/test/Polly.Core.Tests/Simmy/Utils/GeneratorHelperTests.cs @@ -1,5 +1,4 @@ -using System; -using Polly.Simmy.Utils; +using Polly.Simmy.Utils; namespace Polly.Core.Tests.Simmy.Utils; diff --git a/test/Polly.Core.Tests/Telemetry/ResilienceStrategyTelemetryTests.cs b/test/Polly.Core.Tests/Telemetry/ResilienceStrategyTelemetryTests.cs index 743271b6c07..36a95a190a3 100644 --- a/test/Polly.Core.Tests/Telemetry/ResilienceStrategyTelemetryTests.cs +++ b/test/Polly.Core.Tests/Telemetry/ResilienceStrategyTelemetryTests.cs @@ -29,7 +29,9 @@ public void Enabled_Ok() [Fact] public void Report_NoOutcome_OK() { - _sut.Report(new(ResilienceEventSeverity.Warning, "dummy-event"), ResilienceContextPool.Shared.Get(), new TestArguments()); + var context = ResilienceContextPool.Shared.Get(); + + _sut.Report(new(ResilienceEventSeverity.Warning, "dummy-event"), context, new TestArguments()); _args.Should().HaveCount(1); var args = _args.Single(); @@ -39,7 +41,7 @@ public void Report_NoOutcome_OK() args.Source.StrategyName.Should().Be("strategy_name"); args.Arguments.Should().BeOfType(); args.Outcome.Should().BeNull(); - args.Context.Should().NotBeNull(); + args.Context.Should().Be(context); } [Fact] @@ -75,7 +77,7 @@ public void Report_SeverityNone_Skipped() { var context = ResilienceContextPool.Shared.Get(); _sut.Report(new(ResilienceEventSeverity.None, "dummy-event"), context, Outcome.FromResult(99), new TestArguments()); - _sut.Report(new(ResilienceEventSeverity.None, "dummy-event"), ResilienceContextPool.Shared.Get(), new TestArguments()); + _sut.Report(new(ResilienceEventSeverity.None, "dummy-event"), context, new TestArguments()); _args.Should().BeEmpty(); } @@ -91,7 +93,7 @@ public void Report_NoListener_ShouldNotThrow() .Should() .NotThrow(); - sut.Invoking(s => s.Report(new(ResilienceEventSeverity.None, "dummy-event"), ResilienceContextPool.Shared.Get(), new TestArguments())) + sut.Invoking(s => s.Report(new(ResilienceEventSeverity.None, "dummy-event"), context, new TestArguments())) .Should() .NotThrow(); } diff --git a/test/Polly.Core.Tests/Telemetry/TelemetryUtilTests.cs b/test/Polly.Core.Tests/Telemetry/TelemetryUtilTests.cs index d43fc891443..ae509051921 100644 --- a/test/Polly.Core.Tests/Telemetry/TelemetryUtilTests.cs +++ b/test/Polly.Core.Tests/Telemetry/TelemetryUtilTests.cs @@ -2,37 +2,39 @@ namespace Polly.Core.Tests.Telemetry; -public class TelemetryUtilTests +public static class TelemetryUtilTests { + [Theory] [InlineData(true, ResilienceEventSeverity.Warning)] [InlineData(false, ResilienceEventSeverity.Information)] - [Theory] - public void ReportExecutionAttempt_Ok(bool handled, ResilienceEventSeverity severity) + public static void ReportExecutionAttempt_Ok(bool handled, ResilienceEventSeverity severity) { var asserted = false; + var context = ResilienceContextPool.Shared.Get(); var listener = TestUtilities.CreateResilienceTelemetry(args => { args.Event.Severity.Should().Be(severity); asserted = true; }); - TelemetryUtil.ReportExecutionAttempt(listener, ResilienceContextPool.Shared.Get(), Outcome.FromResult("dummy"), 0, TimeSpan.Zero, handled); + TelemetryUtil.ReportExecutionAttempt(listener, context, Outcome.FromResult("dummy"), 0, TimeSpan.Zero, handled); asserted.Should().BeTrue(); } + [Theory] [InlineData(true, ResilienceEventSeverity.Error)] [InlineData(false, ResilienceEventSeverity.Information)] - [Theory] - public void ReportFinalExecutionAttempt_Ok(bool handled, ResilienceEventSeverity severity) + public static void ReportFinalExecutionAttempt_Ok(bool handled, ResilienceEventSeverity severity) { var asserted = false; + var context = ResilienceContextPool.Shared.Get(); var listener = TestUtilities.CreateResilienceTelemetry(args => { args.Event.Severity.Should().Be(severity); asserted = true; }); - TelemetryUtil.ReportFinalExecutionAttempt(listener, ResilienceContextPool.Shared.Get(), Outcome.FromResult("dummy"), 1, TimeSpan.Zero, handled); + TelemetryUtil.ReportFinalExecutionAttempt(listener, context, Outcome.FromResult("dummy"), 1, TimeSpan.Zero, handled); asserted.Should().BeTrue(); } } diff --git a/test/Polly.Core.Tests/Timeout/TimeoutRejectedExceptionTests.cs b/test/Polly.Core.Tests/Timeout/TimeoutRejectedExceptionTests.cs index d8ec8b1eb5e..510865e12d9 100644 --- a/test/Polly.Core.Tests/Timeout/TimeoutRejectedExceptionTests.cs +++ b/test/Polly.Core.Tests/Timeout/TimeoutRejectedExceptionTests.cs @@ -18,7 +18,7 @@ public void Ctor_Ok() new TimeoutRejectedException("dummy", delay, new InvalidOperationException()).Timeout.Should().Be(delay); } -#if !NETCOREAPP +#if NETFRAMEWORK [Fact] public void BinaryDeserialization_Ok() { diff --git a/test/Polly.Core.Tests/Timeout/TimeoutResiliencePipelineBuilderExtensionsTests.cs b/test/Polly.Core.Tests/Timeout/TimeoutResiliencePipelineBuilderExtensionsTests.cs index eee680993c8..3969432be31 100644 --- a/test/Polly.Core.Tests/Timeout/TimeoutResiliencePipelineBuilderExtensionsTests.cs +++ b/test/Polly.Core.Tests/Timeout/TimeoutResiliencePipelineBuilderExtensionsTests.cs @@ -17,8 +17,8 @@ public static IEnumerable AddTimeout_Ok_Data() }; } - [MemberData(nameof(TimeoutTestUtils.InvalidTimeouts), MemberType = typeof(TimeoutTestUtils))] [Theory] + [MemberData(nameof(TimeoutTestUtils.InvalidTimeouts), MemberType = typeof(TimeoutTestUtils))] public void AddTimeout_InvalidTimeout_EnsureValidated(TimeSpan timeout) { var builder = new ResiliencePipelineBuilder(); @@ -26,8 +26,10 @@ public void AddTimeout_InvalidTimeout_EnsureValidated(TimeSpan timeout) Assert.Throws(() => builder.AddTimeout(timeout)); } - [MemberData(nameof(AddTimeout_Ok_Data))] [Theory] +#pragma warning disable xUnit1042 // The member referenced by the MemberData attribute returns untyped data rows + [MemberData(nameof(AddTimeout_Ok_Data))] +#pragma warning restore xUnit1042 // The member referenced by the MemberData attribute returns untyped data rows internal void AddTimeout_Ok(TimeSpan timeout, Action> configure, Action assert) { var builder = new ResiliencePipelineBuilder(); @@ -60,6 +62,8 @@ private static TimeSpan GetTimeout(TimeoutResilienceStrategy strategy) return strategy.DefaultTimeout; } - return strategy.TimeoutGenerator(new TimeoutGeneratorArguments(ResilienceContextPool.Shared.Get())).Preserve().GetAwaiter().GetResult(); + return strategy.TimeoutGenerator( + new TimeoutGeneratorArguments( + ResilienceContextPool.Shared.Get())).Preserve().GetAwaiter().GetResult(); } } diff --git a/test/Polly.Core.Tests/Timeout/TimeoutResilienceStrategyTests.cs b/test/Polly.Core.Tests/Timeout/TimeoutResilienceStrategyTests.cs index 1d6c8e0a8ae..ba76fcc76ea 100644 --- a/test/Polly.Core.Tests/Timeout/TimeoutResilienceStrategyTests.cs +++ b/test/Polly.Core.Tests/Timeout/TimeoutResilienceStrategyTests.cs @@ -140,7 +140,7 @@ await sut _timeProvider.Advance(timeout); await delay; }, - CancellationToken.None) + _cancellationSource.Token) .AsTask()) .Should().ThrowAsync(); @@ -162,7 +162,7 @@ public async Task Execute_Timeout_EnsureStackTrace() return Outcome.FromResult("dummy"); }, - ResilienceContextPool.Shared.Get(), + ResilienceContextPool.Shared.Get(_cancellationSource.Token), "state"); outcome.Exception.Should().BeOfType(); @@ -188,7 +188,7 @@ public async Task Execute_Timeout_EnsureTelemetrySource() return Outcome.FromResult("dummy"); }, - ResilienceContextPool.Shared.Get(), + ResilienceContextPool.Shared.Get(_cancellationSource.Token), "state"); outcome.Exception.Should().BeOfType().Subject.TelemetrySource.Should().NotBeNull(); @@ -236,8 +236,7 @@ public async Task Execute_NoTimeoutOrCancellation_EnsureCancellationTokenRestore var sut = CreateSut(); - var context = ResilienceContextPool.Shared.Get(); - context.CancellationToken = cts.Token; + var context = ResilienceContextPool.Shared.Get(cts.Token); await sut.ExecuteAsync( (r, _) => diff --git a/test/Polly.Core.Tests/Timeout/TimeoutTestUtils.cs b/test/Polly.Core.Tests/Timeout/TimeoutTestUtils.cs index 7f886ab38bf..2b10a5f4843 100644 --- a/test/Polly.Core.Tests/Timeout/TimeoutTestUtils.cs +++ b/test/Polly.Core.Tests/Timeout/TimeoutTestUtils.cs @@ -4,9 +4,11 @@ namespace Polly.Core.Tests.Timeout; public static class TimeoutTestUtils { - public static OnTimeoutArguments OnTimeoutArguments() => new(ResilienceContextPool.Shared.Get(), TimeSpan.FromSeconds(1)); + public static OnTimeoutArguments OnTimeoutArguments() + => new(ResilienceContextPool.Shared.Get(), TimeSpan.FromSeconds(1)); - public static TimeoutGeneratorArguments TimeoutGeneratorArguments() => new(ResilienceContextPool.Shared.Get()); + public static TimeoutGeneratorArguments TimeoutGeneratorArguments() + => new(ResilienceContextPool.Shared.Get()); #pragma warning disable IDE0028 public static readonly TheoryData InvalidTimeouts = new() diff --git a/test/Polly.Core.Tests/Utils/Pipeline/BridgePipelineComponentTests.cs b/test/Polly.Core.Tests/Utils/Pipeline/BridgePipelineComponentTests.cs index d1f2b92c671..f981831c2aa 100644 --- a/test/Polly.Core.Tests/Utils/Pipeline/BridgePipelineComponentTests.cs +++ b/test/Polly.Core.Tests/Utils/Pipeline/BridgePipelineComponentTests.cs @@ -13,6 +13,7 @@ public void Ctor_Ok() => [Fact] public void Execute_NonGeneric_Ok() { + var cancellationToken = CancellationToken.None; var values = new List(); var pipeline = new ResiliencePipeline(PipelineComponentFactory.FromStrategy(new Strategy(outcome => @@ -20,10 +21,10 @@ public void Execute_NonGeneric_Ok() values.Add(outcome.Result); })), DisposeBehavior.Allow, null); - pipeline.Execute(args => "dummy"); - pipeline.Execute(args => 0); - pipeline.Execute(args => null); - pipeline.Execute(args => true); + pipeline.Execute(args => "dummy", cancellationToken); + pipeline.Execute(args => 0, cancellationToken); + pipeline.Execute(args => null, cancellationToken); + pipeline.Execute(args => true, cancellationToken); values[0].Should().Be("dummy"); values[1].Should().Be(0); @@ -92,16 +93,12 @@ public async Task Dispose_Generic_EnsureStrategyDisposed() private static async Task Dispose(PipelineComponent component) => await component.DisposeAsync(); - private class Strategy : ResilienceStrategy + private class Strategy(Action> onOutcome) : ResilienceStrategy { - private readonly Action> _onOutcome; - - public Strategy(Action> onOutcome) => _onOutcome = onOutcome; - protected internal override async ValueTask> ExecuteCore(Func>> callback, ResilienceContext context, TState state) { var outcome = await callback(context, state); - _onOutcome(outcome); + onOutcome(outcome); return outcome; } } diff --git a/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs b/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs index f5e9bb69ea6..435f9c50e81 100644 --- a/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs +++ b/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs @@ -40,6 +40,7 @@ public void Create_EnsureOriginalStrategiesPreserved() [Fact] public async Task Create_EnsureExceptionsNotWrapped() { + var context = ResilienceContextPool.Shared.Get(); var components = new[] { PipelineComponentFactory.FromStrategy(new TestResilienceStrategy { Before = (_, _) => throw new NotSupportedException() }), @@ -48,7 +49,7 @@ public async Task Create_EnsureExceptionsNotWrapped() var pipeline = CreateSut(components); await pipeline - .Invoking(p => p.ExecuteCore((_, _) => Outcome.FromResultAsValueTask(10), ResilienceContextPool.Shared.Get(), "state").AsTask()) + .Invoking(p => p.ExecuteCore((_, _) => Outcome.FromResultAsValueTask(10), context, "state").AsTask()) .Should() .ThrowAsync(); } @@ -66,9 +67,9 @@ public void Create_EnsurePipelineReusableAcrossDifferentPipelines() var pipeline = CreateSut(components); - CreateSut(new PipelineComponent[] { PipelineComponent.Empty, pipeline }); + CreateSut([PipelineComponent.Empty, pipeline]); - this.Invoking(_ => CreateSut(new PipelineComponent[] { PipelineComponent.Empty, pipeline })) + this.Invoking(_ => CreateSut([PipelineComponent.Empty, pipeline])) .Should() .NotThrow(); } @@ -116,7 +117,7 @@ public void ExecutePipeline_EnsureTelemetryArgumentsReported() { var timeProvider = new FakeTimeProvider(); - var pipeline = new ResiliencePipeline(CreateSut(new[] { Substitute.For() }, timeProvider), DisposeBehavior.Allow, null); + var pipeline = new ResiliencePipeline(CreateSut([Substitute.For()], timeProvider), DisposeBehavior.Allow, null); pipeline.Execute(() => { timeProvider.Advance(TimeSpan.FromHours(1)); }); _listener.Events.Should().HaveCount(2); @@ -130,7 +131,7 @@ public async Task DisposeAsync_EnsureInnerComponentsDisposed() var a = Substitute.For(); var b = Substitute.For(); - var composite = CreateSut(new[] { a, b }); + var composite = CreateSut([a, b]); await composite.FirstComponent.DisposeAsync(); await composite.DisposeAsync(); diff --git a/test/Polly.Core.Tests/Utils/Pipeline/PipelineComponentFactoryTests.cs b/test/Polly.Core.Tests/Utils/Pipeline/PipelineComponentFactoryTests.cs index 1a23c41ec23..cc2449e1d0a 100644 --- a/test/Polly.Core.Tests/Utils/Pipeline/PipelineComponentFactoryTests.cs +++ b/test/Polly.Core.Tests/Utils/Pipeline/PipelineComponentFactoryTests.cs @@ -23,7 +23,9 @@ public class PipelineComponentFactoryTests #pragma warning restore IDE0028 [Theory] +#pragma warning disable xUnit1045 [MemberData(nameof(EmptyCallbacks))] +#pragma warning restore xUnit1045 public void WithDisposableCallbacks_NoCallbacks_ReturnsOriginalComponent(IEnumerable callbacks) { var component = Substitute.For(); @@ -32,7 +34,9 @@ public void WithDisposableCallbacks_NoCallbacks_ReturnsOriginalComponent(IEnumer } [Theory] +#pragma warning disable xUnit1045 [MemberData(nameof(NonEmptyCallbacks))] +#pragma warning restore xUnit1045 public void PipelineComponentFactory_Should_Return_WrapperComponent_With_Callbacks(IEnumerable callbacks) { var component = Substitute.For(); diff --git a/test/Polly.Core.Tests/Utils/StrategyHelperTests.cs b/test/Polly.Core.Tests/Utils/StrategyHelperTests.cs index d08aa6ee77f..2a30f4e558a 100644 --- a/test/Polly.Core.Tests/Utils/StrategyHelperTests.cs +++ b/test/Polly.Core.Tests/Utils/StrategyHelperTests.cs @@ -2,10 +2,10 @@ namespace Polly.Core.Tests.Utils; -public class StrategyHelperTests +public static class StrategyHelperTests { [Fact] - public async Task ExecuteCallbackSafeAsync_Cancelled_EnsureOperationCanceledException() + public static async Task ExecuteCallbackSafeAsync_Cancelled_EnsureOperationCanceledException() { using var token = new CancellationTokenSource(); token.Cancel(); @@ -18,10 +18,10 @@ public async Task ExecuteCallbackSafeAsync_Cancelled_EnsureOperationCanceledExce outcome.Exception.Should().BeOfType(); } + [Theory] [InlineData(true)] [InlineData(false)] - [Theory] - public async Task ExecuteCallbackSafeAsync_CallbackThrows_EnsureExceptionWrapped(bool isAsync) => + public static async Task ExecuteCallbackSafeAsync_CallbackThrows_EnsureExceptionWrapped(bool isAsync) => await TestUtilities.AssertWithTimeoutAsync(async () => { var outcome = await StrategyHelper.ExecuteCallbackSafeAsync( @@ -40,13 +40,13 @@ await TestUtilities.AssertWithTimeoutAsync(async () => outcome.Exception.Should().BeOfType(); }); + [Theory] [InlineData(true)] [InlineData(false)] - [Theory] - public async Task ExecuteCallbackSafeAsync_AsyncCallback_CompletedOk(bool isAsync) => + public static async Task ExecuteCallbackSafeAsync_AsyncCallback_CompletedOk(bool isAsync) => await TestUtilities.AssertWithTimeoutAsync(async () => { - var outcomeTask = StrategyHelper.ExecuteCallbackSafeAsync( + var outcomeTask = StrategyHelper.ExecuteCallbackSafeAsync( async (_, _) => { if (isAsync) diff --git a/test/Polly.Core.Tests/Utils/TimeProviderExtensionsTests.cs b/test/Polly.Core.Tests/Utils/TimeProviderExtensionsTests.cs index 82deb0fd4d8..713e246a391 100644 --- a/test/Polly.Core.Tests/Utils/TimeProviderExtensionsTests.cs +++ b/test/Polly.Core.Tests/Utils/TimeProviderExtensionsTests.cs @@ -4,20 +4,19 @@ namespace Polly.Core.Tests.Utils; public class TimeProviderExtensionsTests { + [Theory] [InlineData(false, false)] [InlineData(false, true)] [InlineData(true, false)] [InlineData(true, true)] - [Theory] public async Task DelayAsync_System_Ok(bool synchronous, bool hasCancellation) { using var tcs = new CancellationTokenSource(); var token = hasCancellation ? tcs.Token : default; var delay = TimeSpan.FromMilliseconds(10); var timeProvider = TimeProvider.System; - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(token); context.Initialize(isSynchronous: synchronous); - context.CancellationToken = token; await TestUtilities.AssertWithTimeoutAsync(async () => { @@ -48,9 +47,8 @@ public async Task DelayAsync_SystemSynchronousWhenCancelled_Ok() { using var cts = new CancellationTokenSource(5); var delay = TimeSpan.FromMilliseconds(10); - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(cts.Token); context.Initialize(isSynchronous: true); - context.CancellationToken = cts.Token; await TestUtilities.AssertWithTimeoutAsync(async () => { @@ -61,19 +59,17 @@ await TimeProvider.System }); } + [Theory] [InlineData(false)] [InlineData(true)] - [Theory] public async Task DelayAsync_CancellationRequestedBefore_Throws(bool synchronous) { - using var tcs = new CancellationTokenSource(); - tcs.Cancel(); - var token = tcs.Token; + using var cts = new CancellationTokenSource(); + cts.Cancel(); var delay = TimeSpan.FromMilliseconds(10); var timeProvider = TimeProvider.System; - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(cts.Token); context.Initialize(isSynchronous: synchronous); - context.CancellationToken = token; await Assert.ThrowsAsync(() => timeProvider.DelayAsync(delay, context)); } @@ -88,11 +84,9 @@ public async Task DelayAsync_CancellationAfter_Throws(bool synchronous) await TestUtilities.AssertWithTimeoutAsync(async () => { using var tcs = new CancellationTokenSource(); - var token = tcs.Token; var timeProvider = TimeProvider.System; - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(tcs.Token); context.Initialize(isSynchronous: synchronous); - context.CancellationToken = token; tcs.CancelAfter(TimeSpan.FromMilliseconds(5)); @@ -107,16 +101,15 @@ public async Task DelayAsync_MaxTimeSpan_DoesNotThrow() await TestUtilities.AssertWithTimeoutAsync(async () => { - using var cancellation = new CancellationTokenSource(); + using var cts = new CancellationTokenSource(); var timeProvider = TimeProvider.System; - var context = ResilienceContextPool.Shared.Get(); + var context = ResilienceContextPool.Shared.Get(cts.Token); context.Initialize(isSynchronous: false); - context.CancellationToken = cancellation.Token; var delayTask = timeProvider.DelayAsync(delay, context); delayTask.Wait(TimeSpan.FromMilliseconds(10)).Should().BeFalse(); - cancellation.Cancel(); + cts.Cancel(); await delayTask.Invoking(t => t).Should().ThrowAsync(); }); diff --git a/test/Polly.Extensions.Tests/Issues/IssuesTests.PartitionedRateLimiter_1365.cs b/test/Polly.Extensions.Tests/Issues/IssuesTests.PartitionedRateLimiter_1365.cs index 9f77b2f3e09..c7828ed2cbc 100644 --- a/test/Polly.Extensions.Tests/Issues/IssuesTests.PartitionedRateLimiter_1365.cs +++ b/test/Polly.Extensions.Tests/Issues/IssuesTests.PartitionedRateLimiter_1365.cs @@ -5,12 +5,12 @@ namespace Polly.Extensions.Tests.Issues; +#pragma warning disable xUnit1031 + public partial class IssuesTests { - /// - /// This test demonstrates how to use to rate-limit the individual users. - /// Additionally, it also shows how to disable rate limiting for admin users. - /// + //// This test demonstrates how to use PartitionedRateLimiter to rate-limit the individual users. + //// Additionally, it also shows how to disable rate limiting for admin users. [Fact] public async Task PartitionedRateLimiter_EnsureUserLimited_1365() { diff --git a/test/Polly.RateLimiting.Tests/OnRateLimiterRejectedArgumentsTests.cs b/test/Polly.RateLimiting.Tests/OnRateLimiterRejectedArgumentsTests.cs index dd55ea9249b..79e5ca692fa 100644 --- a/test/Polly.RateLimiting.Tests/OnRateLimiterRejectedArgumentsTests.cs +++ b/test/Polly.RateLimiting.Tests/OnRateLimiterRejectedArgumentsTests.cs @@ -3,12 +3,14 @@ namespace Polly.RateLimiting.Tests; -public class OnRateLimiterRejectedArgumentsTests +public static class OnRateLimiterRejectedArgumentsTests { [Fact] - public void Ctor_Ok() + public static void Ctor_Ok() { - var args = new OnRateLimiterRejectedArguments(ResilienceContextPool.Shared.Get(), Substitute.For()); + var args = new OnRateLimiterRejectedArguments( + ResilienceContextPool.Shared.Get(CancellationToken.None), + Substitute.For()); args.Context.Should().NotBeNull(); args.Lease.Should().NotBeNull(); diff --git a/test/Polly.RateLimiting.Tests/RateLimiterRejectedExceptionTests.cs b/test/Polly.RateLimiting.Tests/RateLimiterRejectedExceptionTests.cs index 4239db541ca..b1a3b39dbff 100644 --- a/test/Polly.RateLimiting.Tests/RateLimiterRejectedExceptionTests.cs +++ b/test/Polly.RateLimiting.Tests/RateLimiterRejectedExceptionTests.cs @@ -67,7 +67,7 @@ public void Ctor_Message_RetryAfter_InnerException_Ok() exception.TelemetrySource.Should().BeNull(); } -#if !NETCOREAPP +#if NETFRAMEWORK [Fact] public void BinaryDeserialization_Ok() { diff --git a/test/Polly.RateLimiting.Tests/RateLimiterResiliencePipelineBuilderExtensionsTests.cs b/test/Polly.RateLimiting.Tests/RateLimiterResiliencePipelineBuilderExtensionsTests.cs index a37c31eb7c4..a9b6839f19e 100644 --- a/test/Polly.RateLimiting.Tests/RateLimiterResiliencePipelineBuilderExtensionsTests.cs +++ b/test/Polly.RateLimiting.Tests/RateLimiterResiliencePipelineBuilderExtensionsTests.cs @@ -44,8 +44,10 @@ public class RateLimiterResiliencePipelineBuilderExtensionsTests }; #pragma warning restore IDE0028 - [MemberData(nameof(Data))] [Theory(Skip = "https://github.com/stryker-mutator/stryker-net/issues/2144")] +#pragma warning disable xUnit1045 + [MemberData(nameof(Data))] +#pragma warning restore xUnit1045 public void AddRateLimiter_Extensions_Ok(Action configure) { var builder = new ResiliencePipelineBuilder(); @@ -70,7 +72,7 @@ public void AddConcurrencyLimiter_InvalidOptions_Throws() => [Fact] public void AddRateLimiter_AllExtensions_Ok() { - foreach (var configure in Data) + foreach (Action configure in Data) { var builder = new ResiliencePipelineBuilder(); diff --git a/test/Polly.Specs/Bulkhead/BulkheadAsyncSpecs.cs b/test/Polly.Specs/Bulkhead/BulkheadAsyncSpecs.cs index 80a84ae62db..1ae18c9dbb0 100644 --- a/test/Polly.Specs/Bulkhead/BulkheadAsyncSpecs.cs +++ b/test/Polly.Specs/Bulkhead/BulkheadAsyncSpecs.cs @@ -25,7 +25,7 @@ public void Should_throw_when_action_is_null() var methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task`1" }); var generic = methodInfo.MakeGenericMethod(typeof(EmptyStruct)); - var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken.None, false]); + var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken, false]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -90,14 +90,19 @@ public async Task Should_call_onBulkheadRejected_with_passed_context() TaskCompletionSource tcs = new TaskCompletionSource(); using (var cancellationSource = new CancellationTokenSource()) { - _ = Task.Run(() => { bulkhead.ExecuteAsync(async () => { await tcs.Task; }); }); + _ = Task.Run(() => { bulkhead.ExecuteAsync(async () => { await tcs.Task; }); }, CancellationToken); Within(CohesionTimeLimit, () => Expect(0, () => bulkhead.BulkheadAvailableCount, nameof(bulkhead.BulkheadAvailableCount))); await bulkhead.Awaiting(b => b.ExecuteAsync(_ => TaskHelper.EmptyTask, contextPassedToExecute)).Should().ThrowAsync(); cancellationSource.Cancel(); + +#if NET + tcs.SetCanceled(CancellationToken); +#else tcs.SetCanceled(); +#endif } contextPassedToOnRejected!.Should().NotBeNull(); diff --git a/test/Polly.Specs/Bulkhead/BulkheadSpecs.cs b/test/Polly.Specs/Bulkhead/BulkheadSpecs.cs index 95bd0b6dbc7..ca443a94669 100644 --- a/test/Polly.Specs/Bulkhead/BulkheadSpecs.cs +++ b/test/Polly.Specs/Bulkhead/BulkheadSpecs.cs @@ -30,7 +30,7 @@ public void Should_throw_when_action_is_null() var methodInfo = methods.First(method => method is { Name: "Implementation", ReturnType.Name: "TResult" }); var generic = methodInfo.MakeGenericMethod(typeof(EmptyStruct)); - var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken.None]); + var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -94,7 +94,7 @@ public void Should_call_onBulkheadRejected_with_passed_context() using BulkheadPolicy bulkhead = Policy.Bulkhead(1, onRejected); TaskCompletionSource tcs = new TaskCompletionSource(); - Task.Run(() => { bulkhead.Execute(() => { tcs.Task.Wait(); }); }); + Task.Run(() => { bulkhead.Execute(() => { tcs.Task.Wait(); }); }, CancellationToken); // Time for the other thread to kick up and take the bulkhead. Within(CohesionTimeLimit, () => Expect(0, () => bulkhead.BulkheadAvailableCount, nameof(bulkhead.BulkheadAvailableCount))); @@ -102,7 +102,11 @@ public void Should_call_onBulkheadRejected_with_passed_context() bulkhead.Invoking(b => b.Execute(_ => { }, contextPassedToExecute)).Should() .Throw(); +#if NET + tcs.SetCanceled(CancellationToken); +#else tcs.SetCanceled(); +#endif contextPassedToOnRejected!.Should().NotBeNull(); contextPassedToOnRejected!.OperationKey.Should().Be(operationKey); diff --git a/test/Polly.Specs/Bulkhead/BulkheadSpecsBase.cs b/test/Polly.Specs/Bulkhead/BulkheadSpecsBase.cs index da185b38fa2..d8b02442383 100644 --- a/test/Polly.Specs/Bulkhead/BulkheadSpecsBase.cs +++ b/test/Polly.Specs/Bulkhead/BulkheadSpecsBase.cs @@ -15,17 +15,18 @@ public abstract class BulkheadSpecsBase : IDisposable protected readonly TimeSpan CohesionTimeLimit = TimeSpan.FromMilliseconds(1000); // Consider increasing CohesionTimeLimit if bulkhead specs fail transiently in slower build environments. #endregion + + protected static CancellationToken CancellationToken => CancellationToken.None; + protected BulkheadSpecsBase(ITestOutputHelper testOutputHelper) { -#if !DEBUG - TestOutputHelper = new SilentOutputHelper(); -#else +#if DEBUG TestOutputHelper = new AnnotatedOutputHelper(testOutputHelper); +#else + TestOutputHelper = new SilentOutputHelper(); #endif -#if !NETCOREAPP1_1 ThreadPool.SetMinThreads(50, 20); -#endif } #region Operating variables diff --git a/test/Polly.Specs/Bulkhead/BulkheadTResultAsyncSpecs.cs b/test/Polly.Specs/Bulkhead/BulkheadTResultAsyncSpecs.cs index 8c155ecccc8..5a0110f16d7 100644 --- a/test/Polly.Specs/Bulkhead/BulkheadTResultAsyncSpecs.cs +++ b/test/Polly.Specs/Bulkhead/BulkheadTResultAsyncSpecs.cs @@ -29,7 +29,7 @@ public void Should_throw_when_action_is_null() var methods = instanceType.GetMethods(flags); var methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task`1" }); - var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken.None, false]); + var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken, false]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -101,14 +101,19 @@ public async Task Should_call_onBulkheadRejected_with_passed_context() await tcs.Task; return 0; }); - }); + }, CancellationToken); Within(CohesionTimeLimit, () => Expect(0, () => bulkhead.BulkheadAvailableCount, nameof(bulkhead.BulkheadAvailableCount))); await bulkhead.Awaiting(b => b.ExecuteAsync(_ => Task.FromResult(1), contextPassedToExecute)).Should().ThrowAsync(); cancellationSource.Cancel(); + +#if NET + tcs.SetCanceled(CancellationToken); +#else tcs.SetCanceled(); +#endif } contextPassedToOnRejected!.Should().NotBeNull(); diff --git a/test/Polly.Specs/Bulkhead/BulkheadTResultSpecs.cs b/test/Polly.Specs/Bulkhead/BulkheadTResultSpecs.cs index 197a1e46feb..1ec23064c7a 100644 --- a/test/Polly.Specs/Bulkhead/BulkheadTResultSpecs.cs +++ b/test/Polly.Specs/Bulkhead/BulkheadTResultSpecs.cs @@ -29,7 +29,7 @@ public void Should_throw_when_action_is_null() var methods = instanceType.GetMethods(flags); var methodInfo = methods.First(method => method is { Name: "Implementation", ReturnType.Name: "EmptyStruct" }); - var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken.None]); + var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -101,14 +101,19 @@ public void Should_call_onBulkheadRejected_with_passed_context() tcs.Task.Wait(); return 0; }); - }); + }, CancellationToken.None); Within(CohesionTimeLimit, () => Expect(0, () => bulkhead.BulkheadAvailableCount, nameof(bulkhead.BulkheadAvailableCount))); bulkhead.Invoking(b => b.Execute(_ => 1, contextPassedToExecute)).Should().Throw(); cancellationSource.Cancel(); + +#if NET + tcs.SetCanceled(CancellationToken.None); +#else tcs.SetCanceled(); +#endif } contextPassedToOnRejected!.Should().NotBeNull(); diff --git a/test/Polly.Specs/Caching/AsyncSerializingCacheProviderSpecs.cs b/test/Polly.Specs/Caching/AsyncSerializingCacheProviderSpecs.cs index e6c26cbe571..00d606f5cc6 100644 --- a/test/Polly.Specs/Caching/AsyncSerializingCacheProviderSpecs.cs +++ b/test/Polly.Specs/Caching/AsyncSerializingCacheProviderSpecs.cs @@ -4,6 +4,8 @@ public class AsyncSerializingCacheProviderSpecs { #region Object-to-TSerialized serializer + private static CancellationToken CancellationToken => CancellationToken.None; + [Fact] public void Single_generic_constructor_should_throw_on_no_wrapped_cache_provider() { @@ -47,11 +49,11 @@ public async Task Single_generic_SerializingCacheProvider_should_serialize_on_pu string key = "some key"; AsyncSerializingCacheProvider serializingCacheProvider = new AsyncSerializingCacheProvider(stubCacheProvider.AsyncFor(), stubSerializer); - await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); + await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); serializeInvoked.Should().BeTrue(); - (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(key, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeTrue(); fromCache.Should().BeOfType() @@ -70,7 +72,7 @@ public async Task Single_generic_SerializingCacheProvider_should_serialize_on_pu string key = "some key"; AsyncSerializingCacheProvider serializingCacheProvider = new AsyncSerializingCacheProvider(stubCacheProvider.AsyncFor(), stubSerializer); - await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); + await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); serializeInvoked.Should().BeTrue(); @@ -93,10 +95,10 @@ public async Task Single_generic_SerializingCacheProvider_should_deserialize_on_ object objectToCache = new(); string key = "some key"; - await stubCacheProvider.PutAsync(key, new StubSerialized(objectToCache), new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); + await stubCacheProvider.PutAsync(key, new StubSerialized(objectToCache), new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); AsyncSerializingCacheProvider serializingCacheProvider = new AsyncSerializingCacheProvider(stubCacheProvider.AsyncFor(), stubSerializer); - (bool cacheHit, object? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeTrue(); deserializeInvoked.Should().BeTrue(); @@ -116,7 +118,7 @@ public async Task Single_generic_SerializingCacheProvider_should_not_deserialize stubCacheProvider.TryGet(key).Item1.Should().BeFalse(); AsyncSerializingCacheProvider serializingCacheProvider = new AsyncSerializingCacheProvider(stubCacheProvider.AsyncFor(), stubSerializer); - (bool cacheHit, object? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeFalse(); deserializeInvoked.Should().BeFalse(); @@ -135,11 +137,11 @@ public async Task Single_generic_SerializingCacheProvider_from_extension_syntax_ string key = "some key"; AsyncSerializingCacheProvider serializingCacheProvider = stubCacheProvider.AsyncFor().WithSerializer(stubSerializer); - await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); + await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); serializeInvoked.Should().BeTrue(); - (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(key, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeTrue(); fromCache.Should().BeOfType() @@ -158,7 +160,7 @@ public async Task Single_generic_SerializingCacheProvider_from_extension_syntax_ string key = "some key"; AsyncSerializingCacheProvider serializingCacheProvider = stubCacheProvider.AsyncFor().WithSerializer(stubSerializer); - await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); + await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); serializeInvoked.Should().BeTrue(); @@ -172,6 +174,7 @@ public async Task Single_generic_SerializingCacheProvider_from_extension_syntax_ [Fact] public async Task Single_generic_SerializingCacheProvider_from_extension_syntax_should_deserialize_on_get() { + var cancellationToken = CancellationToken; bool deserializeInvoked = false; StubSerializer stubSerializer = new StubSerializer( serialize: o => new StubSerialized(o), @@ -180,10 +183,10 @@ public async Task Single_generic_SerializingCacheProvider_from_extension_syntax_ object objectToCache = new(); string key = "some key"; - await stubCacheProvider.PutAsync(key, new StubSerialized(objectToCache), new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); + await stubCacheProvider.PutAsync(key, new StubSerialized(objectToCache), new Ttl(TimeSpan.FromMinutes(1)), cancellationToken, false); AsyncSerializingCacheProvider serializingCacheProvider = stubCacheProvider.AsyncFor().WithSerializer(stubSerializer); - (bool cacheHit, object? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await serializingCacheProvider.TryGetAsync(key, cancellationToken, false); cacheHit.Should().BeTrue(); deserializeInvoked.Should().BeTrue(); @@ -203,7 +206,7 @@ public async Task Single_generic_SerializingCacheProvider_from_extension_syntax_ stubCacheProvider.TryGet(key).Item1.Should().BeFalse(); AsyncSerializingCacheProvider serializingCacheProvider = stubCacheProvider.AsyncFor().WithSerializer(stubSerializer); - (bool cacheHit, object? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeFalse(); deserializeInvoked.Should().BeFalse(); @@ -257,11 +260,11 @@ public async Task Double_generic_SerializingCacheProvider_should_serialize_on_pu string key = "some key"; AsyncSerializingCacheProvider> serializingCacheProvider = new AsyncSerializingCacheProvider>(stubCacheProvider.AsyncFor>(), stubTResultSerializer); - await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); + await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); serializeInvoked.Should().BeTrue(); - (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(key, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeTrue(); fromCache.Should().BeOfType>() @@ -280,7 +283,7 @@ public async Task Double_generic_SerializingCacheProvider_should_serialize_on_pu string key = "some key"; AsyncSerializingCacheProvider> serializingCacheProvider = new AsyncSerializingCacheProvider>(stubCacheProvider.AsyncFor>(), stubTResultSerializer); - await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); + await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); serializeInvoked.Should().BeTrue(); @@ -304,8 +307,8 @@ public async Task Double_generic_SerializingCacheProvider_should_deserialize_on_ AsyncSerializingCacheProvider> serializingCacheProvider = new AsyncSerializingCacheProvider>(stubCacheProvider.AsyncFor>(), stubTResultSerializer); - await stubCacheProvider.PutAsync(key, new StubSerialized(objectToCache), new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); - (bool cacheHit, object? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken.None, false); + await stubCacheProvider.PutAsync(key, new StubSerialized(objectToCache), new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); + (bool cacheHit, object? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeTrue(); deserializeInvoked.Should().BeTrue(); @@ -325,7 +328,7 @@ public async Task Double_generic_SerializingCacheProvider_should_not_deserialize stubCacheProvider.TryGet(key).Item1.Should().BeFalse(); AsyncSerializingCacheProvider> serializingCacheProvider = new AsyncSerializingCacheProvider>(stubCacheProvider.AsyncFor>(), stubTResultSerializer); - (bool cacheHit, ResultPrimitive? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken.None, false); + (bool cacheHit, ResultPrimitive? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeFalse(); deserializeInvoked.Should().BeFalse(); @@ -345,11 +348,11 @@ public async Task Double_generic_SerializingCacheProvider_from_extension_syntax_ AsyncSerializingCacheProvider> serializingCacheProvider = stubCacheProvider.AsyncFor>().WithSerializer(stubTResultSerializer); - await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); + await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); serializeInvoked.Should().BeTrue(); - (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(key, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeTrue(); fromCache.Should().BeOfType>() .Which.Original.Should().Be(objectToCache); @@ -368,7 +371,7 @@ public async Task Double_generic_SerializingCacheProvider_from_extension_syntax_ AsyncSerializingCacheProvider> serializingCacheProvider = stubCacheProvider.AsyncFor>().WithSerializer(stubTResultSerializer); - await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); + await serializingCacheProvider.PutAsync(key, objectToCache, new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); serializeInvoked.Should().BeTrue(); @@ -393,8 +396,8 @@ public async Task Double_generic_SerializingCacheProvider_from_extension_syntax_ AsyncSerializingCacheProvider> serializingCacheProvider = stubCacheProvider.AsyncFor>().WithSerializer(stubTResultSerializer); - await stubCacheProvider.PutAsync(key, new StubSerialized(objectToCache), new Ttl(TimeSpan.FromMinutes(1)), CancellationToken.None, false); - (bool cacheHit, ResultPrimitive? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken.None, false); + await stubCacheProvider.PutAsync(key, new StubSerialized(objectToCache), new Ttl(TimeSpan.FromMinutes(1)), CancellationToken, false); + (bool cacheHit, ResultPrimitive? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeTrue(); deserializeInvoked.Should().BeTrue(); @@ -415,7 +418,7 @@ public async Task Double_generic_SerializingCacheProvider_from_extension_syntax_ AsyncSerializingCacheProvider> serializingCacheProvider = stubCacheProvider.AsyncFor>().WithSerializer(stubTResultSerializer); - (bool cacheHit, ResultPrimitive? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken.None, false); + (bool cacheHit, ResultPrimitive? fromCache) = await serializingCacheProvider.TryGetAsync(key, CancellationToken, false); cacheHit.Should().BeFalse(); deserializeInvoked.Should().BeFalse(); diff --git a/test/Polly.Specs/Caching/CacheAsyncSpecs.cs b/test/Polly.Specs/Caching/CacheAsyncSpecs.cs index 5ff243e7998..578b2a572aa 100644 --- a/test/Polly.Specs/Caching/CacheAsyncSpecs.cs +++ b/test/Polly.Specs/Caching/CacheAsyncSpecs.cs @@ -5,6 +5,8 @@ public class CacheAsyncSpecs : IDisposable { #region Configuration + private static CancellationToken CancellationToken => CancellationToken.None; + [Fact] public void Should_throw_when_action_is_null() { @@ -41,7 +43,7 @@ public void Should_throw_when_action_is_null() var methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task`1" }); var generic = methodInfo.MakeGenericMethod(typeof(EmptyStruct)); - var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken.None, false]); + var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken, false]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -50,7 +52,7 @@ public void Should_throw_when_action_is_null() methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task" }); - func = () => methodInfo.Invoke(instance, [actionVoid, new Context(), CancellationToken.None, false]); + func = () => methodInfo.Invoke(instance, [actionVoid, new Context(), CancellationToken, false]); exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -327,7 +329,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -351,13 +353,13 @@ public async Task Should_execute_delegate_and_put_value_in_cache_if_cache_does_n IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); (await cache.ExecuteAsync(async _ => { await TaskHelper.EmptyTask; return ValueToReturn; }, new Context(OperationKey))).Should().Be(ValueToReturn); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeTrue(); fromCache2.Should().Be(ValueToReturn); } @@ -372,7 +374,7 @@ public async Task Should_execute_delegate_and_put_value_in_cache_but_when_it_exp TimeSpan ttl = TimeSpan.FromMinutes(30); var cache = Policy.CacheAsync(stubCacheProvider, ttl); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); @@ -390,7 +392,7 @@ public async Task Should_execute_delegate_and_put_value_in_cache_but_when_it_exp // First execution should execute delegate and put result in the cache. (await cache.ExecuteAsync(func, new Context(OperationKey))).Should().Be(ValueToReturn); delegateInvocations.Should().Be(1); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeTrue(); fromCache2.Should().Be(ValueToReturn); @@ -417,13 +419,13 @@ public async Task Should_execute_delegate_but_not_put_value_in_cache_if_cache_do IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.Zero); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); (await cache.ExecuteAsync(async _ => { await TaskHelper.EmptyTask; return ValueToReturn; }, new Context(OperationKey))).Should().Be(ValueToReturn); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeFalse(); fromCache2.Should().BeNull(); } @@ -461,9 +463,9 @@ public async Task Should_allow_custom_FuncCacheKeyStrategy() var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue, context => context.OperationKey + context["id"]); object person1 = new(); - await stubCacheProvider.PutAsync("person1", person1, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync("person1", person1, new Ttl(TimeSpan.MaxValue), CancellationToken, false); object person2 = new(); - await stubCacheProvider.PutAsync("person2", person2, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync("person2", person2, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool funcExecuted = false; Func> func = async _ => { funcExecuted = true; await TaskHelper.EmptyTask; return new object(); }; @@ -486,9 +488,9 @@ public async Task Should_allow_custom_ICacheKeyStrategy() var cache = Policy.CacheAsync(stubCacheProvider, new RelativeTtl(TimeSpan.MaxValue), cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, noErrorHandling, noErrorHandling); object person1 = new(); - await stubCacheProvider.PutAsync("person1", person1, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync("person1", person1, new Ttl(TimeSpan.MaxValue), CancellationToken, false); object person2 = new(); - await stubCacheProvider.PutAsync("person2", person2, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync("person2", person2, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool funcExecuted = false; Func> func = async _ => { funcExecuted = true; await TaskHelper.EmptyTask; return new object(); }; @@ -513,13 +515,13 @@ public async Task Should_execute_delegate_and_put_value_in_cache_if_cache_does_n IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); (await cache.ExecuteAsync(async _ => { await TaskHelper.EmptyTask; return valueToReturn; }, new Context(OperationKey))).Should().Be(valueToReturn); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeTrue(); fromCache2.Should().Be(valueToReturn); } @@ -533,7 +535,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - await stubCacheProvider.PutAsync(OperationKey, valueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, valueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -557,13 +559,13 @@ public async Task Should_execute_delegate_and_put_value_in_cache_if_cache_does_n IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); (await cache.ExecuteAsync(async _ => { await TaskHelper.EmptyTask; return valueToReturn; }, new Context(OperationKey))).Should().Be(valueToReturn); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeTrue(); fromCache2.Should().Be(valueToReturn); } @@ -578,7 +580,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - await stubCacheProvider.PutAsync(OperationKey, valueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, valueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -609,7 +611,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac var noop = Policy.NoOpAsync(); var wrap = Policy.WrapAsync(cache, noop); - await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -636,7 +638,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac var noop = Policy.NoOpAsync(); var wrap = Policy.WrapAsync(noop, cache); - await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -663,7 +665,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac var noop = Policy.NoOpAsync(); var wrap = Policy.WrapAsync(noop, cache, noop); - await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -780,7 +782,7 @@ public async Task Should_honour_cancellation_during_delegate_execution_and_not_p .Should().ThrowAsync(); } - (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit.Should().BeFalse(); fromCache.Should().BeNull(); } @@ -805,7 +807,7 @@ public async Task Should_call_onError_delegate_if_cache_get_errors() var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue, onError); - await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -839,7 +841,7 @@ public async Task Should_call_onError_delegate_if_cache_put_errors() var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue, onError); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); @@ -849,7 +851,7 @@ public async Task Should_call_onError_delegate_if_cache_put_errors() exceptionFromCacheProvider.Should().Be(ex); // failed to put it in the cache - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeFalse(); fromCache2.Should().BeNull(); } @@ -872,7 +874,7 @@ public async Task Should_execute_oncacheget_after_got_from_cache() IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, new RelativeTtl(TimeSpan.MaxValue), DefaultCacheKeyStrategy.Instance, onCacheAction, emptyDelegate, emptyDelegate, noErrorHandling, noErrorHandling); - await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; (await cache.ExecuteAsync(async _ => @@ -909,13 +911,13 @@ public async Task Should_execute_oncachemiss_and_oncacheput_if_cache_does_not_ho IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, new RelativeTtl(TimeSpan.MaxValue), DefaultCacheKeyStrategy.Instance, emptyDelegate, onCacheMiss, onCachePut, noErrorHandling, noErrorHandling); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); (await cache.ExecuteAsync(async _ => { await TaskHelper.EmptyTask; return ValueToReturn; }, contextToExecute)).Should().Be(ValueToReturn); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeTrue(); fromCache2.Should().Be(ValueToReturn); @@ -946,7 +948,7 @@ public async Task Should_execute_oncachemiss_but_not_oncacheput_if_cache_does_no IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, new RelativeTtl(TimeSpan.Zero), DefaultCacheKeyStrategy.Instance, emptyDelegate, onCacheMiss, onCachePut, noErrorHandling, noErrorHandling); - (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit.Should().BeFalse(); fromCache.Should().BeNull(); diff --git a/test/Polly.Specs/Caching/CacheSpecs.cs b/test/Polly.Specs/Caching/CacheSpecs.cs index 9392cc2d51f..69aabd8b2c7 100644 --- a/test/Polly.Specs/Caching/CacheSpecs.cs +++ b/test/Polly.Specs/Caching/CacheSpecs.cs @@ -8,6 +8,7 @@ public class CacheSpecs : IDisposable [Fact] public void Should_throw_when_action_is_null() { + var cancellationToken = CancellationToken.None; var flags = BindingFlags.NonPublic | BindingFlags.Instance; Func action = null!; Action actionVoid = null!; @@ -41,7 +42,7 @@ public void Should_throw_when_action_is_null() var methodInfo = methods.First(method => method is { Name: "Implementation", ReturnType.Name: "TResult" }); var generic = methodInfo.MakeGenericMethod(typeof(EmptyStruct)); - var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken.None]); + var func = () => generic.Invoke(instance, [action, new Context(), cancellationToken]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -50,7 +51,7 @@ public void Should_throw_when_action_is_null() methodInfo = methods.First(method => method is { Name: "Implementation", ReturnType.Name: "Void" }); - func = () => methodInfo.Invoke(instance, [actionVoid, new Context(), CancellationToken.None]); + func = () => methodInfo.Invoke(instance, [actionVoid, new Context(), cancellationToken]); exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); diff --git a/test/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs b/test/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs index 675642fd96e..2588fa3b97c 100644 --- a/test/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs +++ b/test/Polly.Specs/Caching/CacheTResultAsyncSpecs.cs @@ -5,6 +5,8 @@ public class CacheTResultAsyncSpecs : IDisposable { #region Configuration + private static CancellationToken CancellationToken => CancellationToken.None; + [Fact] public void Should_throw_when_action_is_null() { @@ -39,7 +41,7 @@ public void Should_throw_when_action_is_null() var methods = instanceType.GetMethods(flags); var methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task`1" }); - var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken.None, false]); + var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken, false]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -185,13 +187,13 @@ public async Task Should_execute_delegate_and_put_value_in_cache_if_cache_does_n IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); (await cache.ExecuteAsync(async _ => { await TaskHelper.EmptyTask; return ValueToReturn; }, new Context(OperationKey))).Should().Be(ValueToReturn); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeTrue(); fromCache2.Should().Be(ValueToReturn); } @@ -206,7 +208,7 @@ public async Task Should_execute_delegate_and_put_value_in_cache_but_when_it_exp TimeSpan ttl = TimeSpan.FromMinutes(30); var cache = Policy.CacheAsync(stubCacheProvider, ttl); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); @@ -225,7 +227,7 @@ public async Task Should_execute_delegate_and_put_value_in_cache_but_when_it_exp (await cache.ExecuteAsync(func, new Context(OperationKey))).Should().Be(ValueToReturn); delegateInvocations.Should().Be(1); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeTrue(); fromCache2.Should().Be(ValueToReturn); @@ -252,13 +254,13 @@ public async Task Should_execute_delegate_but_not_put_value_in_cache_if_cache_do IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.Zero); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); (await cache.ExecuteAsync(async _ => { await TaskHelper.EmptyTask; return ValueToReturn; }, new Context(OperationKey))).Should().Be(ValueToReturn); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeFalse(); fromCache2.Should().BeNull(); } @@ -296,9 +298,9 @@ public async Task Should_allow_custom_FuncCacheKeyStrategy() var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue, context => context.OperationKey + context["id"]); object person1 = new ResultClass(ResultPrimitive.Good, "person1"); - await stubCacheProvider.PutAsync("person1", person1, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync("person1", person1, new Ttl(TimeSpan.MaxValue), CancellationToken, false); object person2 = new ResultClass(ResultPrimitive.Good, "person2"); - await stubCacheProvider.PutAsync("person2", person2, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync("person2", person2, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool funcExecuted = false; Func> func = async _ => { funcExecuted = true; await TaskHelper.EmptyTask; return new ResultClass(ResultPrimitive.Fault, "should never return this one"); }; @@ -322,9 +324,9 @@ public async Task Should_allow_custom_ICacheKeyStrategy() var cache = Policy.CacheAsync(stubCacheProvider.AsyncFor(), new RelativeTtl(TimeSpan.MaxValue), cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, noErrorHandling, noErrorHandling); object person1 = new ResultClass(ResultPrimitive.Good, "person1"); - await stubCacheProvider.PutAsync("person1", person1, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync("person1", person1, new Ttl(TimeSpan.MaxValue), CancellationToken, false); object person2 = new ResultClass(ResultPrimitive.Good, "person2"); - await stubCacheProvider.PutAsync("person2", person2, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync("person2", person2, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool funcExecuted = false; Func> func = async _ => { funcExecuted = true; await TaskHelper.EmptyTask; return new ResultClass(ResultPrimitive.Fault, "should never return this one"); }; @@ -349,13 +351,13 @@ public async Task Should_execute_delegate_and_put_value_in_cache_if_cache_does_n IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); (await cache.ExecuteAsync(async _ => { await TaskHelper.EmptyTask; return valueToReturn; }, new Context(OperationKey))).Should().Be(valueToReturn); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeTrue(); fromCache2.Should().Be(valueToReturn); } @@ -369,7 +371,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - await stubCacheProvider.PutAsync(OperationKey, valueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, valueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -393,13 +395,13 @@ public async Task Should_execute_delegate_and_put_value_in_cache_if_cache_does_n IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); (await cache.ExecuteAsync(async _ => { await TaskHelper.EmptyTask; return valueToReturn; }, new Context(OperationKey))).Should().Be(valueToReturn); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit2.Should().BeTrue(); fromCache2.Should().Be(valueToReturn); } @@ -414,7 +416,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - await stubCacheProvider.PutAsync(OperationKey, valueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, valueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -445,7 +447,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac var noop = Policy.NoOpAsync(); var wrap = cache.WrapAsync(noop); - await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -472,7 +474,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac var noop = Policy.NoOpAsync(); var wrap = noop.WrapAsync(cache); - await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -499,7 +501,7 @@ public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cac var noop = Policy.NoOpAsync(); var wrap = Policy.WrapAsync(noop, cache, noop); - await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false); + await stubCacheProvider.PutAsync(OperationKey, ValueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken, false); bool delegateExecuted = false; @@ -599,7 +601,7 @@ public async Task Should_honour_cancellation_during_delegate_execution_and_not_p .Should().ThrowAsync(); } - (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit, object? fromCache) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken, false); cacheHit.Should().BeFalse(); fromCache.Should().BeNull(); } diff --git a/test/Polly.Specs/Caching/GenericCacheProviderAsyncSpecs.cs b/test/Polly.Specs/Caching/GenericCacheProviderAsyncSpecs.cs index 3eb93b50402..c6fc3b8952b 100644 --- a/test/Polly.Specs/Caching/GenericCacheProviderAsyncSpecs.cs +++ b/test/Polly.Specs/Caching/GenericCacheProviderAsyncSpecs.cs @@ -33,10 +33,11 @@ public async Task Should_execute_delegate_and_put_value_in_cache_for_non_nullabl const ResultPrimitive ValueToReturn = ResultPrimitive.Substitute; const string OperationKey = "SomeOperationKey"; + var cancellationToken = CancellationToken.None; IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); var cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); - (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit1, object? fromCache1) = await stubCacheProvider.TryGetAsync(OperationKey, cancellationToken, false); cacheHit1.Should().BeFalse(); fromCache1.Should().BeNull(); @@ -46,7 +47,7 @@ public async Task Should_execute_delegate_and_put_value_in_cache_for_non_nullabl return ResultPrimitive.Substitute; }, new Context(OperationKey))).Should().Be(ValueToReturn); - (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, CancellationToken.None, false); + (bool cacheHit2, object? fromCache2) = await stubCacheProvider.TryGetAsync(OperationKey, cancellationToken, false); cacheHit2.Should().BeTrue(); fromCache2.Should().Be(ValueToReturn); } diff --git a/test/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerAsyncSpecs.cs b/test/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerAsyncSpecs.cs index a44849d0904..52b46b76a36 100644 --- a/test/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerAsyncSpecs.cs +++ b/test/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerAsyncSpecs.cs @@ -2040,7 +2040,12 @@ await breaker.Awaiting(x => x.RaiseExceptionAsync()) permitLongRunningExecutionToReturnItsFailure.Set(); // Graceful cleanup: allow executions time to end naturally; timeout if any deadlocks; expose any execution faults. This validates the test ran as expected (and background delegates are complete) before we assert on outcomes. +#if NET + longRunningExecution.Wait(testTimeoutToExposeDeadlocks, CancellationToken.None).Should().BeTrue(); +#else longRunningExecution.Wait(testTimeoutToExposeDeadlocks).Should().BeTrue(); +#endif + if (longRunningExecution.IsFaulted) { throw longRunningExecution!.Exception!; diff --git a/test/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerSpecs.cs b/test/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerSpecs.cs index db3ddcf8c1c..30609cb9c48 100644 --- a/test/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerSpecs.cs +++ b/test/Polly.Specs/CircuitBreaker/AdvancedCircuitBreakerSpecs.cs @@ -2042,7 +2042,11 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub // Graceful cleanup: allow executions time to end naturally; timeout if any deadlocks; expose any execution faults. This validates the test ran as expected (and background delegates are complete) before we assert on outcomes. #pragma warning disable xUnit1031 // Do not use blocking task operations in test method +#if NET + longRunningExecution.Wait(testTimeoutToExposeDeadlocks, CancellationToken.None).Should().BeTrue(); +#else longRunningExecution.Wait(testTimeoutToExposeDeadlocks).Should().BeTrue(); +#endif #pragma warning restore xUnit1031 // Do not use blocking task operations in test method if (longRunningExecution.IsFaulted) diff --git a/test/Polly.Specs/CircuitBreaker/CircuitBreakerAsyncSpecs.cs b/test/Polly.Specs/CircuitBreaker/CircuitBreakerAsyncSpecs.cs index 8eb173ec0ef..d40eeb63dc6 100644 --- a/test/Polly.Specs/CircuitBreaker/CircuitBreakerAsyncSpecs.cs +++ b/test/Polly.Specs/CircuitBreaker/CircuitBreakerAsyncSpecs.cs @@ -832,7 +832,12 @@ await breaker.Awaiting(x => x.RaiseExceptionAsync()) permitLongRunningExecutionToReturnItsFailure.Set(); // Graceful cleanup: allow executions time to end naturally; timeout if any deadlocks; expose any execution faults. This validates the test ran as expected (and background delegates are complete) before we assert on outcomes. +#if NET + longRunningExecution.Wait(testTimeoutToExposeDeadlocks, CancellationToken.None).Should().BeTrue(); +#else longRunningExecution.Wait(testTimeoutToExposeDeadlocks).Should().BeTrue(); +#endif + if (longRunningExecution.IsFaulted) { throw longRunningExecution!.Exception!; diff --git a/test/Polly.Specs/CircuitBreaker/CircuitBreakerSpecs.cs b/test/Polly.Specs/CircuitBreaker/CircuitBreakerSpecs.cs index f109dab089f..9636acf5caa 100644 --- a/test/Polly.Specs/CircuitBreaker/CircuitBreakerSpecs.cs +++ b/test/Polly.Specs/CircuitBreaker/CircuitBreakerSpecs.cs @@ -823,7 +823,11 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub permitLongRunningExecutionToReturnItsFailure.Set(); // Graceful cleanup: allow executions time to end naturally; timeout if any deadlocks; expose any execution faults. This validates the test ran as expected (and background delegates are complete) before we assert on outcomes. +#if NET + longRunningExecution.Wait(testTimeoutToExposeDeadlocks, CancellationToken.None).Should().BeTrue(); +#else longRunningExecution.Wait(testTimeoutToExposeDeadlocks).Should().BeTrue(); +#endif if (longRunningExecution.IsFaulted) { throw longRunningExecution!.Exception!; diff --git a/test/Polly.Specs/CircuitBreaker/CircuitBreakerTResultAsyncSpecs.cs b/test/Polly.Specs/CircuitBreaker/CircuitBreakerTResultAsyncSpecs.cs index c48f9ffd756..6f99f0f4574 100644 --- a/test/Polly.Specs/CircuitBreaker/CircuitBreakerTResultAsyncSpecs.cs +++ b/test/Polly.Specs/CircuitBreaker/CircuitBreakerTResultAsyncSpecs.cs @@ -949,7 +949,11 @@ public async Task Should_call_onbreak_when_breaking_circuit_first_time_but_not_f #pragma warning disable xUnit1031 // Graceful cleanup: allow executions time to end naturally; timeout if any deadlocks; expose any execution faults. This validates the test ran as expected (and background delegates are complete) before we assert on outcomes. +#if NET + longRunningExecution.Wait(testTimeoutToExposeDeadlocks, CancellationToken.None).Should().BeTrue(); +#else longRunningExecution.Wait(testTimeoutToExposeDeadlocks).Should().BeTrue(); +#endif #pragma warning restore xUnit1031 if (longRunningExecution.IsFaulted) diff --git a/test/Polly.Specs/CircuitBreaker/CircuitBreakerTResultSpecs.cs b/test/Polly.Specs/CircuitBreaker/CircuitBreakerTResultSpecs.cs index 0464f4ff57d..ce2e45bda75 100644 --- a/test/Polly.Specs/CircuitBreaker/CircuitBreakerTResultSpecs.cs +++ b/test/Polly.Specs/CircuitBreaker/CircuitBreakerTResultSpecs.cs @@ -932,7 +932,12 @@ public void Should_call_onbreak_when_breaking_circuit_first_time_but_not_for_sub permitLongRunningExecutionToReturnItsFailure.Set(); // Graceful cleanup: allow executions time to end naturally; timeout if any deadlocks; expose any execution faults. This validates the test ran as expected (and background delegates are complete) before we assert on outcomes. +#if NET + longRunningExecution.Wait(testTimeoutToExposeDeadlocks, CancellationToken.None).Should().BeTrue(); +#else longRunningExecution.Wait(testTimeoutToExposeDeadlocks).Should().BeTrue(); +#endif + if (longRunningExecution.IsFaulted) { throw longRunningExecution!.Exception!; diff --git a/test/Polly.Specs/Fallback/FallbackAsyncSpecs.cs b/test/Polly.Specs/Fallback/FallbackAsyncSpecs.cs index df724354f8d..23796ffd6cf 100644 --- a/test/Polly.Specs/Fallback/FallbackAsyncSpecs.cs +++ b/test/Polly.Specs/Fallback/FallbackAsyncSpecs.cs @@ -493,7 +493,7 @@ public async Task Should_call_fallbackAction_with_the_exception_when_execute_and .Should().NotThrowAsync(); fallbackException.Should().NotBeNull() - .And.BeOfType(typeof(ArgumentNullException)); + .And.BeOfType(); } [Fact] diff --git a/test/Polly.Specs/Fallback/FallbackSpecs.cs b/test/Polly.Specs/Fallback/FallbackSpecs.cs index de3b5ea4955..428af9c28f4 100644 --- a/test/Polly.Specs/Fallback/FallbackSpecs.cs +++ b/test/Polly.Specs/Fallback/FallbackSpecs.cs @@ -949,7 +949,7 @@ public void Should_call_fallbackAction_with_the_exception_when_execute_and_captu .Should().NotThrow(); fallbackException.Should().NotBeNull() - .And.BeOfType(typeof(ArgumentNullException)); + .And.BeOfType(); } [Fact] diff --git a/test/Polly.Specs/Helpers/Bulkhead/AnnotatedOutputHelper.cs b/test/Polly.Specs/Helpers/Bulkhead/AnnotatedOutputHelper.cs index 4392069181e..fa61f84806e 100644 --- a/test/Polly.Specs/Helpers/Bulkhead/AnnotatedOutputHelper.cs +++ b/test/Polly.Specs/Helpers/Bulkhead/AnnotatedOutputHelper.cs @@ -49,4 +49,8 @@ public void WriteLine(string message) => public void WriteLine(string format, params object[] args) => _items.TryAdd(Guid.NewGuid(), new Item(format ?? string.Empty, args == null || args.Length == 0 ? _noArgs : args)); + + public void Write(string message) => throw new NotSupportedException(); + + public void Write(string format, params object[] args) => throw new NotSupportedException(); } diff --git a/test/Polly.Specs/RateLimit/AsyncRateLimitPolicySpecs.cs b/test/Polly.Specs/RateLimit/AsyncRateLimitPolicySpecs.cs index cf1321d244c..1f4f6f80a04 100644 --- a/test/Polly.Specs/RateLimit/AsyncRateLimitPolicySpecs.cs +++ b/test/Polly.Specs/RateLimit/AsyncRateLimitPolicySpecs.cs @@ -50,7 +50,7 @@ public void Should_throw_when_action_is_null() var methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task`1" }); var generic = methodInfo.MakeGenericMethod(typeof(EmptyStruct)); - var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken.None, false]); + var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken, false]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); diff --git a/test/Polly.Specs/RateLimit/AsyncRateLimitPolicyTResultSpecs.cs b/test/Polly.Specs/RateLimit/AsyncRateLimitPolicyTResultSpecs.cs index 2fc2250fe4d..65fa2ddbfe0 100644 --- a/test/Polly.Specs/RateLimit/AsyncRateLimitPolicyTResultSpecs.cs +++ b/test/Polly.Specs/RateLimit/AsyncRateLimitPolicyTResultSpecs.cs @@ -66,7 +66,7 @@ public void Should_throw_when_action_is_null() var methods = instanceType.GetMethods(flags); var methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task`1" }); - var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken.None, false]); + var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken, false]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); diff --git a/test/Polly.Specs/RateLimit/RateLimitPolicySpecs.cs b/test/Polly.Specs/RateLimit/RateLimitPolicySpecs.cs index d5b7a25ed63..63ee1dbf589 100644 --- a/test/Polly.Specs/RateLimit/RateLimitPolicySpecs.cs +++ b/test/Polly.Specs/RateLimit/RateLimitPolicySpecs.cs @@ -50,7 +50,7 @@ public void Should_throw_when_action_is_null() var methodInfo = methods.First(method => method is { Name: "Implementation", ReturnType.Name: "TResult" }); var generic = methodInfo.MakeGenericMethod(typeof(EmptyStruct)); - var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken.None]); + var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); diff --git a/test/Polly.Specs/RateLimit/RateLimitPolicySpecsBase.cs b/test/Polly.Specs/RateLimit/RateLimitPolicySpecsBase.cs index 14e322f9fea..2c25b4beff2 100644 --- a/test/Polly.Specs/RateLimit/RateLimitPolicySpecsBase.cs +++ b/test/Polly.Specs/RateLimit/RateLimitPolicySpecsBase.cs @@ -2,6 +2,8 @@ public abstract class RateLimitPolicySpecsBase : RateLimitSpecsBase { + protected static CancellationToken CancellationToken => CancellationToken.None; + protected abstract IRateLimitPolicy GetPolicyViaSyntax( int numberOfExecutions, TimeSpan perTimeSpan); @@ -282,7 +284,7 @@ public void Given_immediate_parallel_contention_ratelimiter_still_only_permits_o // Arrange - parallel tasks all waiting on a manual reset event. using var gate = new ManualResetEventSlim(); - Task<(bool PermitExecution, TimeSpan RetryAfter)>[] tasks = new Task<(bool, TimeSpan)>[parallelContention]; + var tasks = new Task<(bool PermitExecution, TimeSpan RetryAfter)>[parallelContention]; for (int i = 0; i < parallelContention; i++) { tasks[i] = Task.Run(() => @@ -294,7 +296,9 @@ public void Given_immediate_parallel_contention_ratelimiter_still_only_permits_o // Act - release gate. gate.Set(); - Within(TimeSpan.FromSeconds(10 /* high to allow for slow-running on time-slicing CI servers */), () => tasks.ToList().TrueForAll(t => t.IsCompleted).Should().BeTrue()); + Within( + TimeSpan.FromSeconds(10 /* high to allow for slow-running on time-slicing CI servers */), + () => Assert.All(tasks, (t) => Assert.True(t.IsCompleted))); // Assert - one should have permitted execution, n-1 not. var results = tasks.Select(t => t.Result).ToList(); diff --git a/test/Polly.Specs/RateLimit/RateLimitSpecsBase.cs b/test/Polly.Specs/RateLimit/RateLimitSpecsBase.cs index 54c4865247c..51a9b79516b 100644 --- a/test/Polly.Specs/RateLimit/RateLimitSpecsBase.cs +++ b/test/Polly.Specs/RateLimit/RateLimitSpecsBase.cs @@ -12,7 +12,9 @@ protected static void Within(TimeSpan timeSpan, Action actionContainingAssertion TimeSpan retryInterval = TimeSpan.FromSeconds(0.2); Stopwatch watch = Stopwatch.StartNew(); - while (true) + var token = CancellationToken.None; + + while (!token.IsCancellationRequested) { try { @@ -21,7 +23,7 @@ protected static void Within(TimeSpan timeSpan, Action actionContainingAssertion } catch (Exception e) { - if (!(e is AssertionFailedException || e is XunitException)) + if (e is not AssertionFailedException and not IAssertionException) { throw; } @@ -34,6 +36,8 @@ protected static void Within(TimeSpan timeSpan, Action actionContainingAssertion Thread.Sleep(retryInterval); } } + + token.ThrowIfCancellationRequested(); } protected static void FixClock() diff --git a/test/Polly.Specs/RateLimit/TokenBucketRateLimiterTestsBase.cs b/test/Polly.Specs/RateLimit/TokenBucketRateLimiterTestsBase.cs index 153571b62ec..08a9b1d8e22 100644 --- a/test/Polly.Specs/RateLimit/TokenBucketRateLimiterTestsBase.cs +++ b/test/Polly.Specs/RateLimit/TokenBucketRateLimiterTestsBase.cs @@ -181,7 +181,7 @@ public void Given_immediate_parallel_contention_ratelimiter_still_only_permits_o // Arrange - parallel tasks all waiting on a manual reset event. using var gate = new ManualResetEventSlim(); - Task<(bool PermitExecution, TimeSpan RetryAfter)>[] tasks = new Task<(bool, TimeSpan)>[parallelContention]; + var tasks = new Task<(bool PermitExecution, TimeSpan RetryAfter)>[parallelContention]; for (int i = 0; i < parallelContention; i++) { tasks[i] = Task.Run(() => @@ -193,7 +193,10 @@ public void Given_immediate_parallel_contention_ratelimiter_still_only_permits_o // Act - release gate. gate.Set(); - Within(TimeSpan.FromSeconds(10 /* high to allow for slow-running on time-slicing CI servers */), () => tasks.ToList().TrueForAll(t => t.IsCompleted).Should().BeTrue()); + + Within( + TimeSpan.FromSeconds(10 /* high to allow for slow-running on time-slicing CI servers */), + () => Assert.All(tasks, (t) => Assert.True(t.IsCompleted))); // Assert - one should have permitted execution, n-1 not. var results = tasks.Select(t => t.Result).ToList(); diff --git a/test/Polly.Specs/Timeout/TimeoutAsyncSpecs.cs b/test/Polly.Specs/Timeout/TimeoutAsyncSpecs.cs index 2bc95235431..3c68f7000df 100644 --- a/test/Polly.Specs/Timeout/TimeoutAsyncSpecs.cs +++ b/test/Polly.Specs/Timeout/TimeoutAsyncSpecs.cs @@ -27,7 +27,7 @@ public void Should_throw_when_action_is_null() var methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task`1" }); var generic = methodInfo.MakeGenericMethod(typeof(EmptyStruct)); - var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken.None, false]); + var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken, false]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -227,7 +227,7 @@ public async Task Should_throw_when_timeout_is_less_than_execution_duration__pes await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); })).Should().ThrowAsync(); } @@ -261,7 +261,7 @@ public async Task Should_throw_timeout_after_correct_duration__pessimistic() watch.Start(); await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(10), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(10), CancellationToken); })) .Should().ThrowAsync(); @@ -294,7 +294,7 @@ public async Task Should_cancel_downstream_token_on_timeout__pessimistic() { combinedToken.Register(() => isCancelled = true); await SystemClock.SleepAsync(TimeSpan.FromMilliseconds(1000), combinedToken); - }, CancellationToken.None); + }, CancellationToken); await act.Should().ThrowAsync(); @@ -311,7 +311,7 @@ public async Task Should_throw_when_timeout_is_less_than_execution_duration__opt TimeSpan timeout = TimeSpan.FromMilliseconds(50); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async ct => { @@ -326,7 +326,7 @@ public void Should_not_throw_when_timeout_is_greater_than_execution_duration__op { var policy = Policy.TimeoutAsync(TimeSpan.FromSeconds(1), TimeoutStrategy.Optimistic); var result = ResultPrimitive.Undefined; - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; Func act = async () => { @@ -348,7 +348,7 @@ public async Task Should_throw_timeout_after_correct_duration__optimistic() TimeSpan timeout = TimeSpan.FromSeconds(1); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; TimeSpan tolerance = TimeSpan.FromSeconds(3); // Consider increasing tolerance, if test fails transiently in different test/build environments. @@ -387,7 +387,7 @@ await policy.Awaiting(p => p.ExecuteAsync(async { userTokenSource.Cancel(); // User token cancels in the middle of execution ... await SystemClock.SleepAsync(TimeSpan.FromSeconds(timeout * 2), - CancellationToken.None); // ... but if the executed delegate does not observe it + CancellationToken); // ... but if the executed delegate does not observe it }, userTokenSource.Token)).Should().ThrowAsync(); // ... it's still the timeout we expect. } @@ -467,7 +467,7 @@ public async Task Should_not_mask_user_exception_if_user_exception_overlaps_with { try { - await SystemClock.SleepAsync(shimTimeSpan + shimTimeSpan, CancellationToken.None); + await SystemClock.SleepAsync(shimTimeSpan + shimTimeSpan, CancellationToken); } catch { @@ -480,7 +480,7 @@ public async Task Should_not_mask_user_exception_if_user_exception_overlaps_with throw new InvalidOperationException("This exception should not be thrown. Test should throw for timeout earlier."); - }, CancellationToken.None)) + }, CancellationToken)) .Should() .ThrowAsync(); @@ -510,7 +510,7 @@ public async Task Should_call_ontimeout_with_configured_timeout__pessimistic() await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); })) .Should().ThrowAsync(); @@ -535,7 +535,7 @@ public async Task Should_call_ontimeout_with_passed_context__pessimistic() await policy.Awaiting(p => p.ExecuteAsync(async _ => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); }, contextPassedToExecute)) .Should().ThrowAsync(); @@ -563,7 +563,7 @@ public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); })) .Should().ThrowAsync(); @@ -592,7 +592,7 @@ public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each await policy.Awaiting(p => p.ExecuteAsync(async _ => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); }, context)) .Should().ThrowAsync(); @@ -614,7 +614,7 @@ public async Task Should_call_ontimeout_with_task_wrapping_abandoned_action__pes await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); })) .Should().ThrowAsync(); @@ -644,12 +644,12 @@ public async Task Should_call_ontimeout_with_task_wrapping_abandoned_action_allo await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken.None); + await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken); throw exceptionToThrow; })) .Should().ThrowAsync(); - await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken.None); + await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken); exceptionObservedFromTaskPassedToOnTimeout.Should().NotBeNull(); exceptionObservedFromTaskPassedToOnTimeout.Should().Be(exceptionToThrow); @@ -671,12 +671,12 @@ public async Task Should_call_ontimeout_with_timing_out_exception__pessimistic() await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); })) .Should().ThrowAsync(); exceptionPassedToOnTimeout.Should().NotBeNull(); - exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); + exceptionPassedToOnTimeout.Should().BeOfType(); } #endregion @@ -696,7 +696,7 @@ public async Task Should_call_ontimeout_with_configured_timeout__optimistic() }; var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async ct => { @@ -722,7 +722,7 @@ public async Task Should_call_ontimeout_with_passed_context__optimistic() TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async (_, ct) => { @@ -751,7 +751,7 @@ public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each }; var policy = Policy.TimeoutAsync(timeoutFunc, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async ct => { @@ -778,7 +778,7 @@ public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each }; var policy = Policy.TimeoutAsync(timeoutProvider, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; // Supply a programatically-controlled timeout, via the execution context. Context context = new Context("SomeOperationKey") @@ -808,7 +808,7 @@ public async Task Should_call_ontimeout_but_not_with_task_wrapping_abandoned_act TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async ct => { @@ -832,7 +832,7 @@ public async Task Should_call_ontimeout_with_timing_out_exception__optimistic() }; var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async ct => { @@ -841,7 +841,7 @@ await policy.Awaiting(p => p.ExecuteAsync(async ct => .Should().ThrowAsync(); exceptionPassedToOnTimeout.Should().NotBeNull(); - exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); + exceptionPassedToOnTimeout.Should().BeOfType(); } #endregion diff --git a/test/Polly.Specs/Timeout/TimeoutSpecs.cs b/test/Polly.Specs/Timeout/TimeoutSpecs.cs index 76e1cdf5d55..c0b74e92a29 100644 --- a/test/Polly.Specs/Timeout/TimeoutSpecs.cs +++ b/test/Polly.Specs/Timeout/TimeoutSpecs.cs @@ -25,7 +25,7 @@ public void Should_throw_when_action_is_null() var methodInfo = methods.First(method => method is { Name: "Implementation", ReturnType.Name: "TResult" }); var generic = methodInfo.MakeGenericMethod(typeof(EmptyStruct)); - var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken.None]); + var func = () => generic.Invoke(instance, [action, new Context(), CancellationToken]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -239,7 +239,7 @@ public void Should_throw_when_timeout_is_less_than_execution_duration__pessimist { var policy = Policy.Timeout(TimeSpan.FromMilliseconds(50), TimeoutStrategy.Pessimistic); - policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None))) + policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken))) .Should().Throw(); } @@ -249,7 +249,7 @@ public void Should_not_throw_when_timeout_is_greater_than_execution_duration__pe var policy = Policy.Timeout(TimeSpan.FromSeconds(1), TimeoutStrategy.Pessimistic); var result = ResultPrimitive.Undefined; - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; Action act = () => { @@ -275,7 +275,7 @@ public void Should_throw_timeout_after_correct_duration__pessimistic() TimeSpan tolerance = TimeSpan.FromSeconds(3); // Consider increasing tolerance, if test fails transiently in different test/build environments. watch.Start(); - policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(10), CancellationToken.None))) + policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(10), CancellationToken))) .Should().Throw(); watch.Stop(); @@ -379,7 +379,7 @@ public void Should_rethrow_aggregate_exception_with_another_example_cause_of_mul public void Should_throw_when_timeout_is_less_than_execution_duration__optimistic() { var policy = Policy.Timeout(TimeSpan.FromMilliseconds(50), TimeoutStrategy.Optimistic); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute(ct => SystemClock.Sleep(TimeSpan.FromSeconds(3), ct), userCancellationToken)) // Delegate observes cancellation token, so permitting optimistic cancellation. .Should().Throw(); @@ -390,7 +390,7 @@ public void Should_not_throw_when_timeout_is_greater_than_execution_duration__op { var policy = Policy.Timeout(TimeSpan.FromSeconds(1), TimeoutStrategy.Optimistic); var result = ResultPrimitive.Undefined; - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; Action act = () => { @@ -412,7 +412,7 @@ public void Should_throw_timeout_after_correct_duration__optimistic() TimeSpan timeout = TimeSpan.FromSeconds(1); var policy = Policy.Timeout(timeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; TimeSpan tolerance = TimeSpan.FromSeconds(3); // Consider increasing tolerance, if test fails transiently in different test/build environments. @@ -449,7 +449,7 @@ public void Should_not_be_able_to_cancel_with_unobserved_user_cancellation_token { userTokenSource.Cancel(); // User token cancels in the middle of execution ... SystemClock.Sleep(TimeSpan.FromSeconds(timeout * 2), - CancellationToken.None); // ... but if the executed delegate does not observe it + CancellationToken); // ... but if the executed delegate does not observe it }, userTokenSource.Token)).Should().Throw(); // ... it's still the timeout we expect. } @@ -518,7 +518,7 @@ public void Should_not_mask_user_exception_if_user_exception_overlaps_with_timeo { try { - SystemClock.Sleep(shimTimeSpan + shimTimeSpan, CancellationToken.None); + SystemClock.Sleep(shimTimeSpan + shimTimeSpan, CancellationToken); } catch { @@ -531,7 +531,7 @@ public void Should_not_mask_user_exception_if_user_exception_overlaps_with_timeo throw new InvalidOperationException("This exception should not be thrown. Test should throw for timeout earlier."); - }, CancellationToken.None)) + }, CancellationToken)) .Should() .Throw() .Which; @@ -556,7 +556,7 @@ public void Should_call_ontimeout_with_configured_timeout__pessimistic() var policy = Policy.Timeout(timeoutPassedToConfiguration, TimeoutStrategy.Pessimistic, onTimeout); - policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None))) + policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken))) .Should().Throw(); timeoutPassedToOnTimeout.Should().Be(timeoutPassedToConfiguration); @@ -574,7 +574,7 @@ public void Should_call_ontimeout_with_passed_context__pessimistic() TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.Timeout(timeout, TimeoutStrategy.Pessimistic, onTimeout); - policy.Invoking(p => p.Execute(_ => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None), contextPassedToExecute)) + policy.Invoking(p => p.Execute(_ => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken), contextPassedToExecute)) .Should().Throw(); contextPassedToOnTimeout!.Should().NotBeNull(); @@ -595,7 +595,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu var policy = Policy.Timeout(timeoutFunc, TimeoutStrategy.Pessimistic, onTimeout); - policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None))) + policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken))) .Should().Throw(); timeoutPassedToOnTimeout.Should().Be(timeoutFunc()); @@ -616,7 +616,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu // Supply a programatically-controlled timeout, via the execution context. Context context = new Context("SomeOperationKey") { ["timeout"] = TimeSpan.FromMilliseconds(25 * programaticallyControlledDelay) }; - policy.Invoking(p => p.Execute(_ => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None), context)) + policy.Invoking(p => p.Execute(_ => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken), context)) .Should().Throw(); timeoutPassedToOnTimeout.Should().Be(timeoutProvider(context)); @@ -631,7 +631,7 @@ public void Should_call_ontimeout_with_task_wrapping_abandoned_action__pessimist TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.Timeout(timeout, TimeoutStrategy.Pessimistic, onTimeout); - policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None))) + policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken))) .Should().Throw(); taskPassedToOnTimeout.Should().NotBeNull(); @@ -659,12 +659,12 @@ public void Should_call_ontimeout_with_task_wrapping_abandoned_action_allowing_c policy.Invoking(p => p.Execute(() => { - SystemClock.Sleep(thriceShimTimeSpan, CancellationToken.None); + SystemClock.Sleep(thriceShimTimeSpan, CancellationToken); throw exceptionToThrow; })) .Should().Throw(); - SystemClock.Sleep(thriceShimTimeSpan, CancellationToken.None); + SystemClock.Sleep(thriceShimTimeSpan, CancellationToken); exceptionObservedFromTaskPassedToOnTimeout.Should().NotBeNull(); exceptionObservedFromTaskPassedToOnTimeout.Should().Be(exceptionToThrow); @@ -680,11 +680,11 @@ public void Should_call_ontimeout_with_timing_out_exception__pessimistic() var policy = Policy.Timeout(timeoutPassedToConfiguration, TimeoutStrategy.Pessimistic, onTimeout); - policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None))) + policy.Invoking(p => p.Execute(() => SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken))) .Should().Throw(); exceptionPassedToOnTimeout.Should().NotBeNull(); - exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); + exceptionPassedToOnTimeout.Should().BeOfType(); } #endregion @@ -700,7 +700,7 @@ public void Should_call_ontimeout_with_configured_timeout__optimistic() Action onTimeout = (_, span, _) => { timeoutPassedToOnTimeout = span; }; var policy = Policy.Timeout(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute(ct => SystemClock.Sleep(TimeSpan.FromSeconds(1), ct), userCancellationToken)) .Should().Throw(); @@ -719,7 +719,7 @@ public void Should_call_ontimeout_with_passed_context__optimistic() TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.Timeout(timeout, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute((_, ct) => SystemClock.Sleep(TimeSpan.FromSeconds(3), ct), contextPassedToExecute, userCancellationToken)) .Should().Throw(); @@ -741,7 +741,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu Action onTimeout = (_, span, _) => { timeoutPassedToOnTimeout = span; }; var policy = Policy.Timeout(timeoutFunc, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute(ct => SystemClock.Sleep(TimeSpan.FromSeconds(3), ct), userCancellationToken)) .Should().Throw(); @@ -761,7 +761,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu Action onTimeout = (_, span, _) => { timeoutPassedToOnTimeout = span; }; var policy = Policy.Timeout(timeoutProvider, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; // Supply a programatically-controlled timeout, via the execution context. Context context = new Context("SomeOperationKey") @@ -783,7 +783,7 @@ public void Should_call_ontimeout_but_not_with_task_wrapping_abandoned_action__o TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.Timeout(timeout, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute(ct => SystemClock.Sleep(TimeSpan.FromSeconds(3), ct), userCancellationToken)) .Should().Throw(); @@ -800,13 +800,13 @@ public void Should_call_ontimeout_with_timing_out_exception__optimistic() Action onTimeout = (_, _, _, exception) => { exceptionPassedToOnTimeout = exception; }; var policy = Policy.Timeout(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute(ct => SystemClock.Sleep(TimeSpan.FromSeconds(1), ct), userCancellationToken)) .Should().Throw(); exceptionPassedToOnTimeout.Should().NotBeNull(); - exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); + exceptionPassedToOnTimeout.Should().BeOfType(); } #endregion diff --git a/test/Polly.Specs/Timeout/TimeoutSpecsBase.cs b/test/Polly.Specs/Timeout/TimeoutSpecsBase.cs index afa8eb6b94e..305d5a309ed 100644 --- a/test/Polly.Specs/Timeout/TimeoutSpecsBase.cs +++ b/test/Polly.Specs/Timeout/TimeoutSpecsBase.cs @@ -19,6 +19,8 @@ public abstract class TimeoutSpecsBase : IDisposable private DateTimeOffset _offsetUtcNow = DateTimeOffset.UtcNow; private DateTime _utcNow = DateTime.UtcNow; + protected static CancellationToken CancellationToken => CancellationToken.None; + protected TimeoutSpecsBase() { // Override the SystemClock, to return time stored in variables we manipulate. @@ -38,7 +40,7 @@ protected TimeoutSpecsBase() DateTimeOffset newCancelAt = _offsetUtcNow.Add(timespan); _cancelAt = newCancelAt < _cancelAt ? newCancelAt : _cancelAt; - SystemClock.Sleep(TimeSpan.Zero, CancellationToken.None); // Invoke our custom definition of sleep, to check for immediate cancellation. + SystemClock.Sleep(TimeSpan.Zero, CancellationToken); // Invoke our custom definition of sleep, to check for immediate cancellation. }; // Override SystemClock.Sleep, to manipulate our artificial clock. And - if it means sleeping beyond the time when a tracked token should cancel - cancel it! diff --git a/test/Polly.Specs/Timeout/TimeoutTResultAsyncSpecs.cs b/test/Polly.Specs/Timeout/TimeoutTResultAsyncSpecs.cs index 40ffb703dfe..8ede3c5cab1 100644 --- a/test/Polly.Specs/Timeout/TimeoutTResultAsyncSpecs.cs +++ b/test/Polly.Specs/Timeout/TimeoutTResultAsyncSpecs.cs @@ -24,7 +24,7 @@ public void Should_throw_when_action_is_null() var methods = instanceType.GetMethods(flags); var methodInfo = methods.First(method => method is { Name: "ImplementationAsync", ReturnType.Name: "Task`1" }); - var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken.None, false]); + var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken, false]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -224,7 +224,7 @@ public async Task Should_throw_when_timeout_is_less_than_execution_duration__pes await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; })).Should().ThrowAsync(); } @@ -255,7 +255,7 @@ public async Task Should_throw_timeout_after_correct_duration__pessimistic() watch.Start(); await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(10), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(10), CancellationToken); return ResultPrimitive.WhateverButTooLate; })) .Should().ThrowAsync(); @@ -280,7 +280,7 @@ public async Task Should_rethrow_exception_from_inside_delegate__pessimistic() public async Task Should_throw_when_timeout_is_less_than_execution_duration__optimistic() { var policy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(50), TimeoutStrategy.Optimistic); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async ct => { @@ -295,7 +295,7 @@ public void Should_not_throw_when_timeout_is_greater_than_execution_duration__op var policy = Policy.TimeoutAsync(TimeSpan.FromSeconds(1), TimeoutStrategy.Optimistic); ResultPrimitive result = ResultPrimitive.Undefined; - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; Func act = async () => result = await policy.ExecuteAsync(_ => Task.FromResult(ResultPrimitive.Good), userCancellationToken); @@ -310,7 +310,7 @@ public async Task Should_throw_timeout_after_correct_duration__optimistic() TimeSpan timeout = TimeSpan.FromSeconds(1); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; TimeSpan tolerance = TimeSpan.FromSeconds(3); // Consider increasing tolerance, if test fails transiently in different test/build environments. @@ -350,7 +350,7 @@ await policy.Awaiting(p => p.ExecuteAsync(async { userTokenSource.Cancel(); // User token cancels in the middle of execution ... await SystemClock.SleepAsync(TimeSpan.FromSeconds(timeout * 2), - CancellationToken.None); // ... but if the executed delegate does not observe it + CancellationToken); // ... but if the executed delegate does not observe it return ResultPrimitive.WhateverButTooLate; }, userTokenSource.Token)).Should().ThrowAsync(); // ... it's still the timeout we expect. } @@ -441,7 +441,7 @@ public async Task Should_call_ontimeout_with_configured_timeout__pessimistic() await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; })) .Should().ThrowAsync(); @@ -467,7 +467,7 @@ public async Task Should_call_ontimeout_with_passed_context__pessimistic() await policy.Awaiting(p => p.ExecuteAsync(async _ => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; }, contextPassedToExecute)) .Should().ThrowAsync(); @@ -496,7 +496,7 @@ public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; })) .Should().ThrowAsync(); @@ -526,7 +526,7 @@ public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each await policy.Awaiting(p => p.ExecuteAsync(async _ => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; }, context)) .Should().ThrowAsync(); @@ -549,7 +549,7 @@ public async Task Should_call_ontimeout_with_task_wrapping_abandoned_action__pes await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; })) .Should().ThrowAsync(); @@ -580,12 +580,12 @@ public async Task Should_call_ontimeout_with_task_wrapping_abandoned_action_allo await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken.None); + await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken); throw exceptionToThrow; })) .Should().ThrowAsync(); - await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken.None); + await SystemClock.SleepAsync(thriceShimTimeSpan, CancellationToken); exceptionObservedFromTaskPassedToOnTimeout.Should().NotBeNull(); exceptionObservedFromTaskPassedToOnTimeout.Should().Be(exceptionToThrow); @@ -607,13 +607,13 @@ public async Task Should_call_ontimeout_with_timing_out_exception__pessimistic() await policy.Awaiting(p => p.ExecuteAsync(async () => { - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken.None); + await SystemClock.SleepAsync(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; })) .Should().ThrowAsync(); exceptionPassedToOnTimeout.Should().NotBeNull(); - exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); + exceptionPassedToOnTimeout.Should().BeOfType(); } #endregion @@ -633,7 +633,7 @@ public async Task Should_call_ontimeout_with_configured_timeout__optimistic() }; var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async ct => { @@ -660,7 +660,7 @@ public async Task Should_call_ontimeout_with_passed_context__optimistic() TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async (_, ct) => { @@ -690,7 +690,7 @@ public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each }; var policy = Policy.TimeoutAsync(timeoutFunc, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async ct => { @@ -718,7 +718,7 @@ public async Task Should_call_ontimeout_with_timeout_supplied_different_for_each }; var policy = Policy.TimeoutAsync(timeoutProvider, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; // Supply a programatically-controlled timeout, via the execution context. Context context = new Context("SomeOperationKey") @@ -748,7 +748,7 @@ public async Task Should_call_ontimeout_but_not_with_task_wrapping_abandoned_act TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.TimeoutAsync(timeout, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async ct => { @@ -773,7 +773,7 @@ public async Task Should_call_ontimeout_with_timing_out_exception__optimistic() }; var policy = Policy.TimeoutAsync(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeoutAsync); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; await policy.Awaiting(p => p.ExecuteAsync(async ct => { @@ -783,7 +783,7 @@ await policy.Awaiting(p => p.ExecuteAsync(async ct => .Should().ThrowAsync(); exceptionPassedToOnTimeout.Should().NotBeNull(); - exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); + exceptionPassedToOnTimeout.Should().BeOfType(); } #endregion diff --git a/test/Polly.Specs/Timeout/TimeoutTResultSpecs.cs b/test/Polly.Specs/Timeout/TimeoutTResultSpecs.cs index 18330810f67..369b4cd5acf 100644 --- a/test/Polly.Specs/Timeout/TimeoutTResultSpecs.cs +++ b/test/Polly.Specs/Timeout/TimeoutTResultSpecs.cs @@ -24,7 +24,7 @@ public void Should_throw_when_action_is_null() var methods = instanceType.GetMethods(flags); var methodInfo = methods.First(method => method is { Name: "Implementation", ReturnType.Name: "EmptyStruct" }); - var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken.None]); + var func = () => methodInfo.Invoke(instance, [action, new Context(), CancellationToken]); var exceptionAssertions = func.Should().Throw(); exceptionAssertions.And.Message.Should().Be("Exception has been thrown by the target of an invocation."); @@ -224,7 +224,7 @@ public void Should_throw_when_timeout_is_less_than_execution_duration__pessimist policy.Invoking(p => p.Execute(() => { - SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None); + SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; })).Should().Throw(); } @@ -235,7 +235,7 @@ public void Should_not_throw_when_timeout_is_greater_than_execution_duration__pe var policy = Policy.Timeout(TimeSpan.FromSeconds(1), TimeoutStrategy.Pessimistic); var result = ResultPrimitive.Undefined; - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; Action act = () => { @@ -263,7 +263,7 @@ public void Should_throw_timeout_after_correct_duration__pessimistic() watch.Start(); policy.Invoking(p => p.Execute(() => { - SystemClock.Sleep(TimeSpan.FromSeconds(10), CancellationToken.None); + SystemClock.Sleep(TimeSpan.FromSeconds(10), CancellationToken); return ResultPrimitive.WhateverButTooLate; })) .Should().Throw(); @@ -371,7 +371,7 @@ public void Should_rethrow_aggregate_exception_with_another_example_cause_of_mul public void Should_throw_when_timeout_is_less_than_execution_duration__optimistic() { var policy = Policy.Timeout(TimeSpan.FromMilliseconds(50), TimeoutStrategy.Optimistic); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute(ct => { @@ -386,7 +386,7 @@ public void Should_not_throw_when_timeout_is_greater_than_execution_duration__op { var policy = Policy.Timeout(TimeSpan.FromSeconds(1), TimeoutStrategy.Optimistic); var result = ResultPrimitive.Undefined; - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; Action act = () => { @@ -408,7 +408,7 @@ public void Should_throw_timeout_after_correct_duration__optimistic() TimeSpan timeout = TimeSpan.FromSeconds(1); var policy = Policy.Timeout(timeout, TimeoutStrategy.Optimistic); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; TimeSpan tolerance = TimeSpan.FromSeconds(3); // Consider increasing tolerance, if test fails transiently in different test/build environments. @@ -448,7 +448,7 @@ public void Should_not_be_able_to_cancel_with_unobserved_user_cancellation_token { userTokenSource.Cancel(); // User token cancels in the middle of execution ... SystemClock.Sleep(TimeSpan.FromSeconds(timeout * 2), - CancellationToken.None); // ... but if the executed delegate does not observe it + CancellationToken); // ... but if the executed delegate does not observe it return ResultPrimitive.WhateverButTooLate; }, userTokenSource.Token)).Should().Throw(); // ... it's still the timeout we expect. } @@ -533,7 +533,7 @@ public void Should_call_ontimeout_with_configured_timeout__pessimistic() policy.Invoking(p => p.Execute(() => { - SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None); + SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; })) .Should().Throw(); @@ -555,7 +555,7 @@ public void Should_call_ontimeout_with_passed_context__pessimistic() policy.Invoking(p => p.Execute(_ => { - SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None); + SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; }, contextPassedToExecute)) .Should().Throw(); @@ -580,7 +580,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu policy.Invoking(p => p.Execute(() => { - SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None); + SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; })) .Should().Throw(); @@ -606,7 +606,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu policy.Invoking(p => p.Execute(_ => { - SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None); + SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; }, context)) .Should().Throw(); @@ -625,7 +625,7 @@ public void Should_call_ontimeout_with_task_wrapping_abandoned_action__pessimist policy.Invoking(p => p.Execute(() => { - SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None); + SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; })) .Should().Throw(); @@ -655,12 +655,12 @@ public void Should_call_ontimeout_with_task_wrapping_abandoned_action_allowing_c policy.Invoking(p => p.Execute(() => { - SystemClock.Sleep(thriceShimTimeSpan, CancellationToken.None); + SystemClock.Sleep(thriceShimTimeSpan, CancellationToken); throw exceptionToThrow; })) .Should().Throw(); - SystemClock.Sleep(thriceShimTimeSpan, CancellationToken.None); + SystemClock.Sleep(thriceShimTimeSpan, CancellationToken); exceptionObservedFromTaskPassedToOnTimeout.Should().NotBeNull(); exceptionObservedFromTaskPassedToOnTimeout.Should().Be(exceptionToThrow); @@ -678,13 +678,13 @@ public void Should_call_ontimeout_with_timing_out_exception__pessimistic() policy.Invoking(p => p.Execute(() => { - SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken.None); + SystemClock.Sleep(TimeSpan.FromSeconds(3), CancellationToken); return ResultPrimitive.WhateverButTooLate; })) .Should().Throw(); exceptionPassedToOnTimeout.Should().NotBeNull(); - exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); + exceptionPassedToOnTimeout.Should().BeOfType(); } #endregion @@ -700,7 +700,7 @@ public void Should_call_ontimeout_with_configured_timeout__optimistic() Action onTimeout = (_, span, _) => { timeoutPassedToOnTimeout = span; }; var policy = Policy.Timeout(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute(ct => { @@ -723,7 +723,7 @@ public void Should_call_ontimeout_with_passed_context__optimistic() TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.Timeout(timeout, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute((_, ct) => { @@ -749,7 +749,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu Action onTimeout = (_, span, _) => { timeoutPassedToOnTimeout = span; }; var policy = Policy.Timeout(timeoutFunc, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute(ct => { @@ -772,7 +772,7 @@ public void Should_call_ontimeout_with_timeout_supplied_different_for_each_execu TimeSpan? timeoutPassedToOnTimeout = null; Action onTimeout = (_, span, _) => { timeoutPassedToOnTimeout = span; }; var policy = Policy.Timeout(timeoutProvider, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; // Supply a programatically-controlled timeout, via the execution context. Context context = new Context("SomeOperationKey") @@ -798,7 +798,7 @@ public void Should_call_ontimeout_but_not_with_task_wrapping_abandoned_action__o TimeSpan timeout = TimeSpan.FromMilliseconds(250); var policy = Policy.Timeout(timeout, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute(ct => { @@ -819,7 +819,7 @@ public void Should_call_ontimeout_with_timing_out_exception__optimistic() Action onTimeout = (_, _, _, exception) => { exceptionPassedToOnTimeout = exception; }; var policy = Policy.Timeout(timeoutPassedToConfiguration, TimeoutStrategy.Optimistic, onTimeout); - var userCancellationToken = CancellationToken.None; + var userCancellationToken = CancellationToken; policy.Invoking(p => p.Execute(ct => { @@ -829,7 +829,7 @@ public void Should_call_ontimeout_with_timing_out_exception__optimistic() .Should().Throw(); exceptionPassedToOnTimeout.Should().NotBeNull(); - exceptionPassedToOnTimeout.Should().BeOfType(typeof(OperationCanceledException)); + exceptionPassedToOnTimeout.Should().BeOfType(); } #endregion diff --git a/test/Polly.TestUtils/BinarySerializationUtil.cs b/test/Polly.TestUtils/BinarySerializationUtil.cs index 8a5ca183460..e8fa66fb36c 100644 --- a/test/Polly.TestUtils/BinarySerializationUtil.cs +++ b/test/Polly.TestUtils/BinarySerializationUtil.cs @@ -1,4 +1,4 @@ -#if !NETCOREAPP +#if NETFRAMEWORK using System; diff --git a/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs b/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs index 900e35d3261..c54e0540c0b 100644 --- a/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs +++ b/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs @@ -53,7 +53,7 @@ public void GetPipelineDescriptor_Generic_Ok() descriptor.Strategies[4].StrategyInstance.GetType().FullName.Should().Contain("Hedging"); descriptor.Strategies[5].Options.Should().BeOfType(); descriptor.Strategies[5].StrategyInstance.GetType().FullName.Should().Contain("RateLimiter"); - descriptor.Strategies[6].StrategyInstance.GetType().Should().Be(typeof(CustomStrategy)); + descriptor.Strategies[6].StrategyInstance.GetType().Should().Be(); } [Fact] @@ -88,7 +88,7 @@ public void GetPipelineDescriptor_NonGeneric_Ok() descriptor.Strategies[3].Options.Should().BeOfType(); descriptor.Strategies[3].StrategyInstance.GetType().FullName.Should().Contain("RateLimiter"); - descriptor.Strategies[4].StrategyInstance.GetType().Should().Be(typeof(CustomStrategy)); + descriptor.Strategies[4].StrategyInstance.GetType().Should().Be(); } [Fact] @@ -131,7 +131,7 @@ public async Task GetPipelineDescriptor_Reloadable_Ok() descriptor.IsReloadable.Should().BeTrue(); descriptor.Strategies.Should().HaveCount(2); descriptor.Strategies[0].Options.Should().BeOfType(); - descriptor.Strategies[1].StrategyInstance.GetType().Should().Be(typeof(CustomStrategy)); + descriptor.Strategies[1].StrategyInstance.GetType().Should().Be(); } [Fact]