using Microsoft.Extensions.Hosting; using Moq; using OwnerNumberMigration.Migrations; using OwnerNumberMigrationTest.TestDataFactories; namespace OwnerNumberMigrationTest.Migrations; public class MigrationManagerTest { private readonly IMigrationManager _manager; private readonly Mock _lifetime = new(); public MigrationManagerTest() { _manager = new MigrationManager(_lifetime.Object); } [SetUp] public void SetUp() { _lifetime.Reset(); } [Test] public async Task Start_OneTaskThatFinishes_EndsApplication() { var applicationStopped = new SemaphoreSlim(0); _lifetime .Setup(l => l.StopApplication()) .Callback(() => applicationStopped.Release()); var task = Task.CompletedTask; _manager.Start(task); await applicationStopped.WaitAsync(TimeSpan.FromMilliseconds(50)); _lifetime.Verify(l => l.StopApplication(), Times.AtLeastOnce); } [Test] public async Task Start_OneTaskThatCancels_EndsApplication() { var applicationStopped = new SemaphoreSlim(0); _lifetime .Setup(l => l.StopApplication()) .Callback(() => applicationStopped.Release()); var task = Task.FromCanceled(new CancellationToken(true)); _manager.Start(task); await applicationStopped.WaitAsync(TimeSpan.FromMilliseconds(50)); _lifetime.Verify(l => l.StopApplication(), Times.AtLeastOnce); } [Test] public async Task Start_OneTaskThatErrors_EndsApplication() { var applicationStopped = new SemaphoreSlim(0); _lifetime .Setup(l => l.StopApplication()) .Callback(() => applicationStopped.Release()); _lifetime .Setup(l => l.StopApplication()) .Callback(() => applicationStopped.Release()); var task = Task.FromException(new Exception()); _manager.Start(task); await applicationStopped.WaitAsync(TimeSpan.FromMilliseconds(50)); _lifetime.Verify(l => l.StopApplication(), Times.AtLeastOnce); } [Test] public async Task Start_MultipleTasksThatFinish_EndsApplicationAfterAll() { var applicationStopped = new SemaphoreSlim(0); _lifetime .Setup(l => l.StopApplication()) .Callback(() => applicationStopped.Release()); var semaphores = EnumerableDataSeriesFactory .CreateSeries(() => new SemaphoreSlim(0), 5) .ToArray(); var tasks = semaphores .Select(s => Task.Run(async () => await s.WaitAsync())) .ToArray(); foreach(var task in tasks) _manager.Start(task); _lifetime.Verify(l => l.StopApplication(), Times.Never); foreach (var semaphore in semaphores[..^1]) { semaphore.Release(); _lifetime.Verify(l => l.StopApplication(), Times.Never); } foreach (var semaphore in semaphores[^1..]) { semaphore.Release(); } await applicationStopped.WaitAsync(TimeSpan.FromMilliseconds(50)); _lifetime.Verify(l => l.StopApplication(), Times.AtLeastOnce); } }