using System; using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.MediaEncoding; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Moq; using StackExchange.Redis; using Xunit; namespace Jellyfin.Server.Tests.HighAvailability; /// /// A Redis store that cannot be reached degrades silently: the client is configured not to abort the /// connection and every call site swallows failures. The probe is the only startup signal, so both of /// its outcomes are pinned here. /// public sealed class TranscodeStoreConnectivityProbeTests { [Fact] public async Task StartAsync_Should_Log_Information_When_Reachable() { var database = new Mock(); database.Setup(db => db.PingAsync(It.IsAny())).ReturnsAsync(TimeSpan.FromMilliseconds(3)); var (logger, probe) = CreateProbe(database.Object); await probe.StartAsync(CancellationToken.None); Assert.True(logger.HasEntry(LogLevel.Information, "reachable")); Assert.DoesNotContain(logger.Entries, entry => entry.Level >= LogLevel.Warning); } [Fact] public async Task StartAsync_Should_Log_Error_When_Unreachable() { var database = new Mock(); database.Setup(db => db.PingAsync(It.IsAny())) .ThrowsAsync(new RedisConnectionException(ConnectionFailureType.UnableToConnect, "no route to host")); var (logger, probe) = CreateProbe(database.Object); await probe.StartAsync(CancellationToken.None); Assert.True(logger.HasEntry(LogLevel.Error, "UNREACHABLE")); } [Fact] public async Task StartAsync_Should_Log_Error_Instead_Of_Aborting_Startup() { var services = new ServiceCollection(); services.AddSingleton(_ => throw new RedisConnectionException(ConnectionFailureType.UnableToConnect, "no route to host")); using var provider = services.BuildServiceProvider(); var logger = new RecordingLogger(); var probe = new TranscodeStoreConnectivityProbe(provider, logger); await probe.StartAsync(CancellationToken.None); Assert.True(logger.HasEntry(LogLevel.Error, "UNREACHABLE")); } private static (RecordingLogger Logger, TranscodeStoreConnectivityProbe Probe) CreateProbe(IDatabase database) { var multiplexer = new Mock(); multiplexer.Setup(redis => redis.GetDatabase(It.IsAny(), It.IsAny())).Returns(database); var services = new ServiceCollection(); services.AddSingleton(multiplexer.Object); var provider = services.BuildServiceProvider(); var logger = new RecordingLogger(); return (logger, new TranscodeStoreConnectivityProbe(provider, logger)); } }