using MeetingAssistant; using MeetingAssistant.Speakers; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; namespace MeetingAssistant.Tests; public sealed class ResemblyzerWarmupHostedServiceTests { [Fact] public async Task EnabledWarmupStartsWithoutBlockingApplicationStartup() { var encoder = new BlockingEncoder(); var options = new MeetingAssistantOptions(); options.SpeakerIdentification.Resemblyzer.Enabled = true; var service = new ResemblyzerWarmupHostedService( encoder, Options.Create(options), NullLogger.Instance); await service.StartAsync(CancellationToken.None).WaitAsync(TimeSpan.FromSeconds(1)); await encoder.WaitForWarmupAsync(); await service.StopAsync(CancellationToken.None); Assert.True(encoder.CancellationObserved); } [Fact] public async Task DisabledWarmupDoesNotInvokeEncoder() { var encoder = new BlockingEncoder(); var service = new ResemblyzerWarmupHostedService( encoder, Options.Create(new MeetingAssistantOptions()), NullLogger.Instance); await service.StartAsync(CancellationToken.None); await service.StopAsync(CancellationToken.None); Assert.False(encoder.WarmupStarted); } private sealed class BlockingEncoder : IResemblyzerVoiceEncoder { private readonly TaskCompletionSource started = new(TaskCreationOptions.RunContinuationsAsynchronously); public bool WarmupStarted { get; private set; } public bool CancellationObserved { get; private set; } public Task> EncodeAsync( IReadOnlyList wavSamples, CancellationToken cancellationToken) { return Task.FromResult>([]); } public async Task WarmUpAsync(CancellationToken cancellationToken) { WarmupStarted = true; started.TrySetResult(); try { await Task.Delay(Timeout.InfiniteTimeSpan, cancellationToken); } catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { CancellationObserved = true; } } public Task WaitForWarmupAsync() { return started.Task.WaitAsync(TimeSpan.FromSeconds(1)); } } }