Skip to content

Commit

Permalink
Add Redis xUnit Fixtures (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
Confusingboat authored Mar 26, 2024
1 parent c00e815 commit 3a08815
Show file tree
Hide file tree
Showing 29 changed files with 994 additions and 384 deletions.
2 changes: 0 additions & 2 deletions src/Ephemerally.Redis.Xunit/DefaultLocalRedisInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@ public class DefaultLocalRedisInstance


public const string ConnectionString = "localhost:6379,allowAdmin=true";

public static ushort Port => 6379;
}
16 changes: 0 additions & 16 deletions src/Ephemerally.Redis.Xunit/EphemeralRedisDatabasePoolFixture.cs

This file was deleted.

23 changes: 23 additions & 0 deletions src/Ephemerally.Redis.Xunit/EphemeralRedisMultiplexerFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using StackExchange.Redis;

namespace Ephemerally.Redis.Xunit;

public class EphemeralRedisMultiplexerFixture<TEphemeralRedisInstance>()
: EphemeralRedisMultiplexerFixture(new TEphemeralRedisInstance())
where TEphemeralRedisInstance : IRedisInstanceFixture, new();

public class EphemeralRedisMultiplexerFixture : RedisMultiplexerFixture
{
public EphemeralRedisMultiplexerFixture() { }
protected EphemeralRedisMultiplexerFixture(IRedisInstanceFixture redisInstanceFixture)
: base(redisInstanceFixture) { }

protected override async Task<IConnectionMultiplexer> CreateMultiplexerAsync()
{
var implementation = await base.CreateMultiplexerAsync();
return await CreateEphemeralMultiplexerAsync(implementation);
}

protected virtual Task<EphemeralConnectionMultiplexer> CreateEphemeralMultiplexerAsync(IConnectionMultiplexer implementation) =>
Task.FromResult(new EphemeralConnectionMultiplexer(implementation));
}
2 changes: 1 addition & 1 deletion src/Ephemerally.Redis.Xunit/Ephemerally.Redis.Xunit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Nullable>disable</Nullable>
<LangVersion>latest</LangVersion>
<IsTestProject>false</IsTestProject>
<IsPackable>false</IsPackable>
<IsPackable>true</IsPackable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

namespace Ephemerally.Redis.Xunit;

internal class EphemeralRedisDatabaseFixture : EphemeralRedisDatabasePoolFixture
internal class PooledEphemeralRedisDatabaseFixture : PooledEphemeralRedisMultiplexerFixture
{
private readonly Lazy<Task<IEphemeralRedisDatabase>> _database;

public IEphemeralRedisDatabase Database => _database.Value.Result;

public EphemeralRedisDatabaseFixture()
public PooledEphemeralRedisDatabaseFixture()
{
_database = new(CreateDatabaseAsync);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using StackExchange.Redis;

namespace Ephemerally.Redis.Xunit;

public class PooledEphemeralRedisMultiplexerFixture<TEphemeralRedisInstance>()
: PooledEphemeralRedisMultiplexerFixture(new TEphemeralRedisInstance())
where TEphemeralRedisInstance : IRedisInstanceFixture, new();

public class PooledEphemeralRedisMultiplexerFixture : EphemeralRedisMultiplexerFixture
{
public PooledEphemeralRedisMultiplexerFixture() { }
protected PooledEphemeralRedisMultiplexerFixture(IRedisInstanceFixture redisInstanceFixture)
: base(redisInstanceFixture) { }

protected override async Task<IConnectionMultiplexer> CreateMultiplexerAsync()
{
var implementation = await base.CreateMultiplexerAsync();
return await CreatePooledMultiplexerAsync(implementation);
}

protected virtual Task<PooledConnectionMultiplexer> CreatePooledMultiplexerAsync(IConnectionMultiplexer implementation) =>
Task.FromResult(new PooledConnectionMultiplexer(implementation));
}
13 changes: 13 additions & 0 deletions src/Ephemerally.Redis.Xunit/PublicExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Ephemerally.Redis.Xunit;
using StackExchange.Redis;

namespace Ephemerally;

public static class PublicExtensions
{
public static ConnectionMultiplexer GetMultiplexer(this IRedisInstanceFixture fixture) =>
ConnectionMultiplexer.Connect(fixture.ConnectionString);

public static Task<ConnectionMultiplexer> GetMultiplexerAsync(this IRedisInstanceFixture fixture) =>
ConnectionMultiplexer.ConnectAsync(fixture.ConnectionString);
}
24 changes: 24 additions & 0 deletions src/Ephemerally.Redis.Xunit/RedisInstance.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Xunit;

namespace Ephemerally.Redis.Xunit;

public interface IRedisInstance
{
string ConnectionString { get; }
}

public interface IRedisInstanceFixture : IRedisInstance, IAsyncLifetime { }

public sealed class UnmanagedDefaultLocalRedisInstanceFixture : IRedisInstanceFixture
{
private static readonly Lazy<UnmanagedDefaultLocalRedisInstanceFixture> _instance = new(() => new UnmanagedDefaultLocalRedisInstanceFixture());

public static UnmanagedDefaultLocalRedisInstanceFixture DefaultLocalRedisInstanceFixture => _instance.Value;

private UnmanagedDefaultLocalRedisInstanceFixture() { }

public string ConnectionString => DefaultLocalRedisInstance.ConnectionString;
public Task InitializeAsync() => Task.CompletedTask;

public Task DisposeAsync() => Task.CompletedTask;
}
36 changes: 24 additions & 12 deletions src/Ephemerally.Redis.Xunit/RedisMultiplexerFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,54 @@

namespace Ephemerally.Redis.Xunit;

public class RedisMultiplexerFixture<TRedisTestContainerFixture>()
: RedisMultiplexerFixture(new TRedisTestContainerFixture())
where TRedisTestContainerFixture : IRedisTestContainerFixture, new();
public class RedisMultiplexerFixture<TEphemeralRedisInstance>()
: RedisMultiplexerFixture(new TEphemeralRedisInstance())
where TEphemeralRedisInstance : IRedisInstanceFixture, new();

public class RedisMultiplexerFixture : IAsyncLifetime
public class RedisMultiplexerFixture : IAsyncLifetime, IAsyncDisposable
{
private readonly IRedisTestContainerFixture _containerFixture;
private bool _disposed;

private readonly IRedisInstanceFixture _redisInstanceFixture;
private readonly Lazy<Task<IConnectionMultiplexer>> _multiplexer;

public IConnectionMultiplexer Multiplexer => _multiplexer.Value.Result;

protected Task<IConnectionMultiplexer> GetMultiplexer() => _multiplexer.Value;

public RedisMultiplexerFixture() : this(UnmanagedTestContainerFixture.Instance) { }
public RedisMultiplexerFixture() : this(UnmanagedDefaultLocalRedisInstanceFixture.DefaultLocalRedisInstanceFixture) { }

protected RedisMultiplexerFixture(IRedisTestContainerFixture containerFixture)
protected RedisMultiplexerFixture(IRedisInstanceFixture redisInstanceFixture)
{
_containerFixture = containerFixture;
_redisInstanceFixture = redisInstanceFixture;
_multiplexer = new Lazy<Task<IConnectionMultiplexer>>(CreateMultiplexerAsync);
}

protected virtual async Task<IConnectionMultiplexer> CreateMultiplexerAsync() =>
await ConnectionMultiplexer.ConnectAsync(_containerFixture.ConnectionString);
await ConnectionMultiplexer.ConnectAsync(_redisInstanceFixture.ConnectionString);

public virtual async Task InitializeAsync()
{
await _containerFixture.InitializeAsync();
await _multiplexer.Value;
await _redisInstanceFixture.InitializeAsync();
}

public virtual async Task DisposeAsync()
{
if (_disposed) return;
_disposed = true;

if (!_multiplexer.IsValueCreated) return;

var multiplexer = await GetMultiplexer();
await multiplexer.DisposeAsync();
await _containerFixture.DisposeAsync();
await _redisInstanceFixture.DisposeAsync();
}

async ValueTask IAsyncDisposable.DisposeAsync()
{
if (_disposed) return;
_disposed = true;

await DisposeAsync();
}
}
24 changes: 0 additions & 24 deletions src/Ephemerally.Redis.Xunit/RedisTestContainerFixture.cs

This file was deleted.

Loading

0 comments on commit 3a08815

Please sign in to comment.