using System; using System.Threading.Tasks; using StackExchange.Redis; using Testcontainers.Redis; namespace Jellyfin.Server.Tests.HighAvailability; /// /// Hands out a valkey/Redis server for the tests that need one. A server named by /// JELLYFIN_TEST_REDIS is used as is, so CI can run one in the step instead of a docker daemon /// of its own; without it a container is started through testcontainers. /// public sealed class RedisTestServer : IAsyncDisposable { /// /// The connection string of an already running server. /// public const string ConnectionStringVariable = "JELLYFIN_TEST_REDIS"; private readonly RedisContainer? _container; private RedisTestServer(RedisContainer? container, string connectionString) { _container = container; ConnectionString = connectionString; } /// /// Gets the connection string of the running server. /// public string ConnectionString { get; } /// /// Starts or attaches to a server and connects to it. /// /// The running server. public static async Task StartAsync() { var provided = Environment.GetEnvironmentVariable(ConnectionStringVariable); if (!string.IsNullOrWhiteSpace(provided)) { return new RedisTestServer(null, provided); } var container = new RedisBuilder("valkey/valkey:8-alpine").Build(); await container.StartAsync().ConfigureAwait(false); return new RedisTestServer(container, container.GetConnectionString()); } /// /// Opens a connection to the server. /// /// The connection. public async Task ConnectAsync() => await ConnectionMultiplexer.ConnectAsync(ConnectionString).ConfigureAwait(false); /// public async ValueTask DisposeAsync() { if (_container is not null) { await _container.DisposeAsync().ConfigureAwait(false); } } }