using Microsoft.Extensions.DependencyInjection; using Moq; using System; using AsbCloudInfrastructure.Services.Background; using System.Threading; using System.Threading.Tasks; using Xunit; using Org.BouncyCastle.Asn1.X509.Qualified; namespace AsbCloudWebApi.Tests.ServicesTests { public class BackgroundWorkerServiceTest { private readonly Mock mockServiceProvider; private readonly Mock mockServiceScopeFactory; public BackgroundWorkerServiceTest() { var mockServiceScope = new Mock(); mockServiceScopeFactory = new Mock(); mockServiceProvider = new Mock(); mockServiceScope.SetReturnsDefault(mockServiceProvider.Object); mockServiceProvider.SetReturnsDefault(mockServiceScopeFactory.Object); mockServiceProvider.Setup(s=>s.GetService(It.IsAny())) .Returns(mockServiceScopeFactory.Object); mockServiceScopeFactory.SetReturnsDefault(mockServiceScope.Object); } [Fact] public async Task Push_makes_new_scope_after_start() { mockServiceScopeFactory.Invocations.Clear(); var backgroundService = new BackgroundWorkerService(mockServiceProvider.Object); var work = new WorkBase("", (_, _, _) => Task.CompletedTask ); backgroundService.Push(work); await backgroundService.StartAsync(CancellationToken.None); await Task.Delay(10); mockServiceScopeFactory.Verify(f => f.CreateScope()); } [Fact] public async Task Push_makes_primary_work_done() { var backgroundService = new BackgroundWorkerService(mockServiceProvider.Object); var workDone = false; var work = new WorkBase("", (_, _, _) => { workDone = true; return Task.CompletedTask; }); backgroundService.Push(work); await backgroundService.StartAsync(CancellationToken.None); await Task.Delay(10); Assert.True(workDone); } [Fact] public async Task Push_makes_pperiodic_work_done() { var backgroundService = new BackgroundWorkerService(mockServiceProvider.Object); var workDone = false; var work = new WorkPeriodic("", (_, _, _) => { workDone = true; return Task.CompletedTask; }, TimeSpan.FromMilliseconds(10)); backgroundService.Push(work); await backgroundService.StartAsync(CancellationToken.None); await Task.Delay(10); Assert.True(workDone); } [Fact] public async Task Aborts_long_work() { var backgroundService = new BackgroundWorkerService(mockServiceProvider.Object); var workCanceled = false; var work = new WorkBase("", async(_, _, _) => await Task.Delay(1000000)); work.Timeout = TimeSpan.FromMilliseconds(1); work.OnErrorAsync = async (id, ex, token) => { workCanceled = ex is System.TimeoutException; await Task.CompletedTask; }; backgroundService.Push(work); await backgroundService.StartAsync(CancellationToken.None); await Task.Delay(20*4); Assert.True(workCanceled); } [Fact] public async Task Execution_continues_after_work_exception() { var backgroundService = new BackgroundWorkerService(mockServiceProvider.Object); var work2done = false; var work1 = new WorkBase("1", (_, _, _) => throw new Exception()); var work2 = new WorkBase("2", (_, _, _) => { work2done = true; return Task.CompletedTask; }); backgroundService.Push(work1); backgroundService.Push(work2); await backgroundService.StartAsync(CancellationToken.None); await Task.Delay(2_100); Assert.True(work2done); } } }