Skip to content

Commit a579c66

Browse files
authored
Fix flakey Tests (#129)
* Make sure we are unsubscribed from the channel. Use async unsubscribe with a bounded timeout to prevent hanging * Improves Redis unsubscribe reliability Uses fire and forget unsubscribe to prevent potential hanging issues. Adds unique topic names to Redis tests to prevent interference between tests. * Handles exceptions during Redis unsubscribe Adds try-catch blocks when unsubscribing from Redis topics to prevent potential unhandled exceptions from causing issues, particularly in test environments where flaky behavior might occur. Logs any exceptions encountered during the unsubscribe process for better debugging. * Added trace logging to failing test * Updated timeout
1 parent 406e8d5 commit a579c66

File tree

6 files changed

+20
-8
lines changed

6 files changed

+20
-8
lines changed

src/Foundatio.Redis/Foundatio.Redis.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<Import Project="..\..\build\common.props" />
33
<ItemGroup>
4-
<PackageReference Include="Foundatio" Version="12.0.1-preview.0.42" Condition="'$(ReferenceFoundatioSource)' == '' OR '$(ReferenceFoundatioSource)' == 'false'" />
4+
<PackageReference Include="Foundatio" Version="12.0.1-preview.0.44" Condition="'$(ReferenceFoundatioSource)' == '' OR '$(ReferenceFoundatioSource)' == 'false'" />
55
<ProjectReference Include="..\..\..\Foundatio\src\Foundatio\Foundatio.csproj" Condition="'$(ReferenceFoundatioSource)' == 'true'" />
66

77
<PackageReference Include="StackExchange.Redis" Version="2.10.1" />

src/Foundatio.Redis/Queues/RedisQueue.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,14 @@ public override void Dispose()
778778
if (_isSubscribed)
779779
{
780780
_logger.LogTrace("Unsubscribing from topic {Topic}", GetTopicName());
781-
_subscriber.Unsubscribe(RedisChannel.Literal(GetTopicName()), OnTopicMessage, CommandFlags.FireAndForget);
781+
try
782+
{
783+
_subscriber.Unsubscribe(RedisChannel.Literal(GetTopicName()), OnTopicMessage, CommandFlags.FireAndForget);
784+
}
785+
catch (Exception ex)
786+
{
787+
_logger.LogError(ex, "Error unsubscribing from topic {Topic}: {Message}", GetTopicName(), ex.Message);
788+
}
782789
_isSubscribed = false;
783790
_logger.LogTrace("Unsubscribed from topic {Topic}", GetTopicName());
784791
}

tests/Foundatio.Redis.Tests/Foundatio.Redis.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
99
<PackageReference Include="GitHubActionsTestLogger" Version="3.0.1" PrivateAssets="All" />
1010

11-
<PackageReference Include="Foundatio.TestHarness" Version="12.0.1-preview.0.42" Condition="'$(ReferenceFoundatioSource)' == '' OR '$(ReferenceFoundatioSource)' == 'false'" />
11+
<PackageReference Include="Foundatio.TestHarness" Version="12.0.1-preview.0.44" Condition="'$(ReferenceFoundatioSource)' == '' OR '$(ReferenceFoundatioSource)' == 'false'" />
1212
<ProjectReference Include="..\..\..\Foundatio\src\Foundatio.TestHarness\Foundatio.TestHarness.csproj" Condition="'$(ReferenceFoundatioSource)' == 'true'" />
1313
</ItemGroup>
1414
<ItemGroup>

tests/Foundatio.Redis.Tests/Locks/RedisLockTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ namespace Foundatio.Redis.Tests.Locks;
1212

1313
public class RedisLockTests : LockTestBase, IDisposable, IAsyncLifetime
1414
{
15+
private readonly string _topic = $"test-lock-{Guid.NewGuid().ToString("N")[..10]}";
1516
private readonly ICacheClient _cache;
1617
private readonly IMessageBus _messageBus;
1718

1819
public RedisLockTests(ITestOutputHelper output) : base(output)
1920
{
2021
var muxer = SharedConnection.GetMuxer(Log);
2122
_cache = new RedisCacheClient(o => o.ConnectionMultiplexer(muxer).LoggerFactory(Log));
22-
_messageBus = new RedisMessageBus(o => o.Subscriber(muxer.GetSubscriber()).Topic("test-lock").LoggerFactory(Log));
23+
_messageBus = new RedisMessageBus(o => o.Subscriber(muxer.GetSubscriber()).Topic(_topic).LoggerFactory(Log));
2324
}
2425

2526
protected override ILockProvider GetThrottlingLockProvider(int maxHits, TimeSpan period)

tests/Foundatio.Redis.Tests/Messaging/RedisMessageBusTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace Foundatio.Redis.Tests.Messaging;
1616

1717
public class RedisMessageBusTests : MessageBusTestBase, IAsyncLifetime
1818
{
19+
private readonly string _topic = $"test-messages-{Guid.NewGuid().ToString("N")[..10]}";
20+
1921
public RedisMessageBusTests(ITestOutputHelper output) : base(output)
2022
{
2123
}
@@ -25,7 +27,7 @@ protected override IMessageBus GetMessageBus(Func<SharedMessageBusOptions, Share
2527
return new RedisMessageBus(o =>
2628
{
2729
o.Subscriber(SharedConnection.GetMuxer(Log).GetSubscriber());
28-
o.Topic("test-messages");
30+
o.Topic(_topic);
2931
o.LoggerFactory(Log);
3032
if (config != null)
3133
config(o.Target);
@@ -152,7 +154,7 @@ public override Task CanHandlePoisonedMessageAsync()
152154
public async Task CanDisposeCacheAndQueueAndReceiveSubscribedMessages()
153155
{
154156
var muxer = SharedConnection.GetMuxer(Log);
155-
var messageBus1 = new RedisMessageBus(new RedisMessageBusOptions { Subscriber = muxer.GetSubscriber(), Topic = "test-messages", LoggerFactory = Log });
157+
var messageBus1 = new RedisMessageBus(new RedisMessageBusOptions { Subscriber = muxer.GetSubscriber(), Topic = _topic, LoggerFactory = Log });
156158

157159
var cache = new RedisCacheClient(new RedisCacheClientOptions { ConnectionMultiplexer = muxer });
158160
Assert.NotNull(cache);

tests/Foundatio.Redis.Tests/Queues/RedisQueueTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ namespace Foundatio.Redis.Tests.Queues;
2525

2626
public class RedisQueueTests : QueueTestBase, IAsyncLifetime
2727
{
28+
private readonly string _topic = $"test-queue-{Guid.NewGuid().ToString("N")[..10]}";
29+
2830
public RedisQueueTests(ITestOutputHelper output) : base(output)
2931
{
3032
}
@@ -185,7 +187,7 @@ public override async Task CanDequeueWithLockingAsync()
185187
{
186188
var muxer = SharedConnection.GetMuxer(Log);
187189
using var cache = new RedisCacheClient(new RedisCacheClientOptions { ConnectionMultiplexer = muxer, LoggerFactory = Log });
188-
using var messageBus = new RedisMessageBus(new RedisMessageBusOptions { Subscriber = muxer.GetSubscriber(), Topic = "test-queue", LoggerFactory = Log });
190+
using var messageBus = new RedisMessageBus(new RedisMessageBusOptions { Subscriber = muxer.GetSubscriber(), Topic = _topic, LoggerFactory = Log });
189191
var distributedLock = new CacheLockProvider(cache, messageBus, null, Log);
190192
await CanDequeueWithLockingImpAsync(distributedLock);
191193
}
@@ -195,7 +197,7 @@ public override async Task CanHaveMultipleQueueInstancesWithLockingAsync()
195197
{
196198
var muxer = SharedConnection.GetMuxer(Log);
197199
using var cache = new RedisCacheClient(new RedisCacheClientOptions { ConnectionMultiplexer = muxer, LoggerFactory = Log });
198-
using var messageBus = new RedisMessageBus(new RedisMessageBusOptions { Subscriber = muxer.GetSubscriber(), Topic = "test-queue", LoggerFactory = Log });
200+
using var messageBus = new RedisMessageBus(new RedisMessageBusOptions { Subscriber = muxer.GetSubscriber(), Topic = _topic, LoggerFactory = Log });
199201
var distributedLock = new CacheLockProvider(cache, messageBus, null, Log);
200202
await CanHaveMultipleQueueInstancesWithLockingImplAsync(distributedLock);
201203
}

0 commit comments

Comments
 (0)