Public Access
136 lines
4.4 KiB
C#
136 lines
4.4 KiB
C#
using MeetingAssistant.Transcription;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
|
|
namespace MeetingAssistant.Tests;
|
|
|
|
public sealed class SpeechRecognitionPipelineHostedServiceTests
|
|
{
|
|
[Fact]
|
|
public async Task HostedServiceInitializesAndWarmsConfiguredPipelineWithoutBlockingStartup()
|
|
{
|
|
var pipeline = new CapturingSpeechRecognitionPipeline { BlockReadinessUntilCancelled = true };
|
|
var service = new SpeechRecognitionPipelineHostedService(
|
|
new CapturingSpeechRecognitionPipelineFactory(pipeline),
|
|
NullLogger<SpeechRecognitionPipelineHostedService>.Instance);
|
|
|
|
var startTask = service.StartAsync(CancellationToken.None);
|
|
|
|
await startTask.WaitAsync(TimeSpan.FromSeconds(1));
|
|
await pipeline.WaitForInitializeAsync();
|
|
await pipeline.WaitForReadinessAsync();
|
|
|
|
await service.StopAsync(CancellationToken.None);
|
|
|
|
Assert.Equal(1, pipeline.InitializeCount);
|
|
Assert.Equal(1, pipeline.ReadinessCount);
|
|
Assert.True(pipeline.ReadinessCancellationWasObserved);
|
|
Assert.True(pipeline.Disposed);
|
|
}
|
|
|
|
private sealed class CapturingSpeechRecognitionPipelineFactory : ISpeechRecognitionPipelineFactory
|
|
{
|
|
private readonly ISpeechRecognitionPipeline pipeline;
|
|
|
|
public CapturingSpeechRecognitionPipelineFactory(ISpeechRecognitionPipeline pipeline)
|
|
{
|
|
this.pipeline = pipeline;
|
|
}
|
|
|
|
public ISpeechRecognitionPipeline Create()
|
|
{
|
|
return pipeline;
|
|
}
|
|
}
|
|
|
|
private sealed class CapturingSpeechRecognitionPipeline : ISpeechRecognitionPipeline
|
|
{
|
|
private readonly TaskCompletionSource initialized = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
private readonly TaskCompletionSource readinessChecked = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
|
|
public int InitializeCount { get; private set; }
|
|
|
|
public int ReadinessCount { get; private set; }
|
|
|
|
public bool BlockReadinessUntilCancelled { get; init; }
|
|
|
|
public bool ReadinessCancellationWasObserved { get; private set; }
|
|
|
|
public bool Disposed { get; private set; }
|
|
|
|
public Task WaitForInitializeAsync()
|
|
{
|
|
return initialized.Task.WaitAsync(TimeSpan.FromSeconds(5));
|
|
}
|
|
|
|
public Task WaitForReadinessAsync()
|
|
{
|
|
return readinessChecked.Task.WaitAsync(TimeSpan.FromSeconds(5));
|
|
}
|
|
|
|
public Task InitializeAsync(CancellationToken cancellationToken)
|
|
{
|
|
return InitializeAsync(SpeechRecognitionPipelineOptions.Default, cancellationToken);
|
|
}
|
|
|
|
public Task InitializeAsync(
|
|
SpeechRecognitionPipelineOptions options,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
InitializeCount++;
|
|
initialized.TrySetResult();
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public async Task WaitUntilReadyAsync(CancellationToken cancellationToken)
|
|
{
|
|
ReadinessCount++;
|
|
readinessChecked.TrySetResult();
|
|
if (!BlockReadinessUntilCancelled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
await Task.Delay(Timeout.InfiniteTimeSpan, cancellationToken);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
ReadinessCancellationWasObserved = true;
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public ValueTask WriteAsync(MeetingAssistant.Recording.AudioChunk chunk, CancellationToken cancellationToken)
|
|
{
|
|
return ValueTask.CompletedTask;
|
|
}
|
|
|
|
public Task CompleteAsync(CancellationToken cancellationToken)
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public async IAsyncEnumerable<TranscriptionSegment> ReadLiveTranscriptAsync(
|
|
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken)
|
|
{
|
|
await Task.CompletedTask;
|
|
yield break;
|
|
}
|
|
|
|
public Task<IReadOnlyList<TranscriptionSegment>> ReadFinishedTranscriptAsync(
|
|
string audioPath,
|
|
SpeechRecognitionPipelineOptions options,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return Task.FromResult<IReadOnlyList<TranscriptionSegment>>([]);
|
|
}
|
|
|
|
public ValueTask DisposeAsync()
|
|
{
|
|
Disposed = true;
|
|
return ValueTask.CompletedTask;
|
|
}
|
|
}
|
|
}
|