DD.WellWorkover.Cloud/AsbCloudInfrastructure.Tests/Background/PeriodicBackgroundWorkerTest.cs

99 lines
3.3 KiB
C#
Raw Normal View History

using System;
2023-11-07 14:19:13 +05:00
using System.Diagnostics;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
2023-11-27 17:47:27 +05:00
using AsbCloudInfrastructure.Background;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
2023-11-07 14:19:13 +05:00
using Xunit;
2024-08-19 10:57:31 +05:00
namespace AsbCloudInfrastructure.Tests.Background;
2023-11-07 14:19:13 +05:00
2023-11-27 17:47:27 +05:00
//TODO: нужно поправить тесты, иногда они не проходят
2023-11-07 14:19:13 +05:00
public class PeriodicBackgroundWorkerTest
{
private IServiceProvider provider;
private PeriodicBackgroundWorker service;
public PeriodicBackgroundWorkerTest()
{
provider = Substitute.For<IServiceProvider, ISupportRequiredService>();
var serviceScope = Substitute.For<IServiceScope>();
var serviceScopeFactory = Substitute.For<IServiceScopeFactory>();
serviceScopeFactory.CreateScope().Returns(serviceScope);
((ISupportRequiredService)provider).GetRequiredService(typeof(IServiceScopeFactory)).Returns(serviceScopeFactory);
service = new PeriodicBackgroundWorker(provider);
typeof(PeriodicBackgroundWorker)
.GetField("minDelay", BindingFlags.NonPublic | BindingFlags.Instance)?
.SetValue(service, TimeSpan.FromMilliseconds(1));
typeof(PeriodicBackgroundWorker)
.GetField("executePeriod", BindingFlags.NonPublic | BindingFlags.Instance)?
.SetValue(service, TimeSpan.FromMilliseconds(1));
}
[Fact]
2023-11-27 17:47:27 +05:00
public async Task WorkRunsTwice_ShouldReturn_WorkCount()
2023-11-07 14:19:13 +05:00
{
2023-11-27 17:47:27 +05:00
const int workCount = 2;
const double periodMs = 100d;
2023-11-07 14:19:13 +05:00
var period = TimeSpan.FromMilliseconds(periodMs);
var result = 0;
Task workAction(string id, IServiceProvider services, Action<string, double?> callback, CancellationToken token)
{
result++;
return Task.CompletedTask;
}
//act
var work = Work.CreateByDelegate("", workAction);
var stopwatch = Stopwatch.StartNew();
service.Add(work, period);
2024-08-19 10:57:31 +05:00
var delay = periodMs / 20 + periodMs * workCount - stopwatch.ElapsedMilliseconds;
2023-11-07 14:19:13 +05:00
await Task.Delay(TimeSpan.FromMilliseconds(delay));
//assert
Assert.True(workCount <= result);
2023-11-07 14:19:13 +05:00
}
[Fact]
2023-11-27 17:47:27 +05:00
public async Task Enqueue_Continues_AfterExceptions()
2023-11-07 14:19:13 +05:00
{
var expectadResult = 42;
var result = 0;
using var semaphore = new SemaphoreSlim(0, 1);
2023-11-07 14:19:13 +05:00
Task workAction(string id, IServiceProvider services, Action<string, double?> callback, CancellationToken token)
{
result = expectadResult;
semaphore.Release();
2023-11-07 14:19:13 +05:00
return Task.CompletedTask;
}
var goodWork = Work.CreateByDelegate("", workAction);
Task failAction(string id, IServiceProvider services, Action<string, double?> callback, CancellationToken token)
=> throw new Exception();
var badWork = Work.CreateByDelegate("", failAction);
badWork.OnErrorAsync = (id, exception, token) => throw new Exception();
//act
service.Add(badWork, TimeSpan.FromSeconds(2));
service.Add(goodWork, TimeSpan.FromSeconds(2));
await semaphore.WaitAsync(4_100);
2023-11-07 14:19:13 +05:00
//assert
Assert.Equal(1, badWork.CountErrors);
Assert.Equal(1, goodWork.CountComplete);
Assert.Equal(1, goodWork.CountStart);
Assert.Equal(expectadResult, result);
2023-11-07 14:19:13 +05:00
}
}