From 67d72b0721027c908afa1ca87768e17acfb286df Mon Sep 17 00:00:00 2001 From: martintmk <103487740+martintmk@users.noreply.github.com> Date: Tue, 27 Jun 2023 07:55:37 +0200 Subject: [PATCH] Fix race conditions in tests (#1358) --- .../Hedging/HedgingResilienceStrategyTests.cs | 4 ++-- test/Polly.Core.Tests/Hedging/HedgingTimeProvider.cs | 4 ++-- test/Polly.TestUtils/TestUtilities.cs | 7 ++++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs b/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs index 95e725f1300..c3ef4868e90 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs @@ -15,7 +15,7 @@ public class HedgingResilienceStrategyTests : IDisposable private static readonly TimeSpan AssertTimeout = TimeSpan.FromSeconds(15); private readonly HedgingStrategyOptions _options = new(); - private readonly List _events = new(); + private readonly ConcurrentQueue _events = new(); private readonly ResilienceStrategyTelemetry _telemetry; private readonly HedgingTimeProvider _timeProvider; private readonly HedgingActions _actions; @@ -27,7 +27,7 @@ public class HedgingResilienceStrategyTests : IDisposable public HedgingResilienceStrategyTests(ITestOutputHelper testOutput) { - _telemetry = TestUtilities.CreateResilienceTelemetry(_events.Add); + _telemetry = TestUtilities.CreateResilienceTelemetry(_events.Enqueue); _timeProvider = new HedgingTimeProvider { AutoAdvance = _options.HedgingDelay }; _actions = new HedgingActions(_timeProvider); _primaryTasks = new PrimaryStringTasks(_timeProvider); diff --git a/test/Polly.Core.Tests/Hedging/HedgingTimeProvider.cs b/test/Polly.Core.Tests/Hedging/HedgingTimeProvider.cs index 97d630c60be..babb0998755 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingTimeProvider.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingTimeProvider.cs @@ -20,14 +20,14 @@ public void Advance(TimeSpan diff) public Func TimeStampProvider { get; set; } = () => 0; - public List TimerEntries { get; } = new List(); + public ConcurrentQueue TimerEntries { get; } = new(); public override DateTimeOffset GetUtcNow() => _utcNow; public override ITimer CreateTimer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period) { var entry = new TimerEntry(dueTime, new TaskCompletionSource(), _utcNow.Add(dueTime), () => callback(state)); - TimerEntries.Add(entry); + TimerEntries.Enqueue(entry); Advance(AutoAdvance); diff --git a/test/Polly.TestUtils/TestUtilities.cs b/test/Polly.TestUtils/TestUtilities.cs index f4d8f5cbefc..097de46aabd 100644 --- a/test/Polly.TestUtils/TestUtilities.cs +++ b/test/Polly.TestUtils/TestUtilities.cs @@ -105,6 +105,7 @@ public static ResilienceContext WithResultType(this ResilienceContext context private sealed class CallbackDiagnosticSource : DiagnosticSource { private readonly Action _callback; + private readonly object _syncRoot = new(); public CallbackDiagnosticSource(Action callback) => _callback = callback; @@ -122,7 +123,11 @@ public override void Write(string name, object? value) // copy the args because these are pooled and in tests we want to preserve them args = TelemetryEventArguments.Get(args.Source, args.EventName, args.Context, args.Outcome, arguments); - _callback(args); + + lock (_syncRoot) + { + _callback(args); + } } } }