2023-11-27 17:47:27 +05:00
|
|
|
|
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-01-21 13:43:15 +05:00
|
|
|
|
namespace AsbCloudWebApi.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-01-22 12:55:48 +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.Equal(workCount, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[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;
|
|
|
|
|
|
|
|
|
|
Task workAction(string id, IServiceProvider services, Action<string, double?> callback, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
result = expectadResult;
|
|
|
|
|
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));
|
|
|
|
|
|
2024-01-21 13:43:15 +05:00
|
|
|
|
await Task.Delay(TimeSpan.FromMilliseconds(256));
|
2023-11-07 14:19:13 +05:00
|
|
|
|
|
|
|
|
|
//assert
|
|
|
|
|
Assert.Equal(expectadResult, result);
|
|
|
|
|
Assert.Equal(1, badWork.CountErrors);
|
|
|
|
|
Assert.Equal(1, goodWork.CountComplete);
|
|
|
|
|
Assert.Equal(1, goodWork.CountStart);
|
|
|
|
|
}
|
|
|
|
|
}
|