DD.WellWorkover.Cloud/AsbCloudWebApi.Tests/Services/WorkTest.cs
2023-11-07 14:19:13 +05:00

127 lines
4.6 KiB
C#

using AsbCloudInfrastructure.Background;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using System;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace AsbCloudWebApi.Tests.Services
{
public class WorkTest
{
private IServiceProvider provider;
public WorkTest()
{
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);
}
[Fact]
public async Task Work_done_with_success()
{
Task workAction(string id, IServiceProvider services, Action<string, double?> callback, CancellationToken token)
=> Task.CompletedTask;
var work = Work.CreateByDelegate("", workAction);
//act
var begin = DateTime.Now;
await work.Start(provider, CancellationToken.None);
var done = DateTime.Now;
var executionTime = done - begin;
//assert
Assert.Equal(1, work.CountComplete);
Assert.Equal(1, work.CountStart);
Assert.Equal(0, work.CountErrors);
Assert.Null(work.CurrentState);
Assert.Null(work.LastError);
var lastState = work.LastComplete;
Assert.NotNull(lastState);
Assert.InRange(lastState.Start, begin, done - 0.5 * executionTime);
Assert.InRange(lastState.End, done - 0.5 * executionTime, done);
Assert.InRange(lastState.ExecutionTime, TimeSpan.Zero, executionTime);
}
[Fact]
public async Task Work_calls_callback()
{
var expectedState = "42";
var expectedProgress = 42d;
var timeout = TimeSpan.FromMilliseconds(40);
Task workAction(string id, IServiceProvider services, Action<string, double?> callback, CancellationToken token)
{
callback.Invoke(expectedState, expectedProgress);
return Task.Delay(timeout);
}
var work = Work.CreateByDelegate("", workAction);
//act
var begin = DateTime.Now;
_ = work.Start(provider, CancellationToken.None);
await Task.Delay(timeout/3);
//assert
Assert.Equal(0, work.CountComplete);
Assert.Equal(1, work.CountStart);
Assert.Equal(0, work.CountErrors);
Assert.NotNull(work.CurrentState);
Assert.Null(work.LastComplete);
Assert.Null(work.LastError);
var currentState = work.CurrentState;
Assert.NotNull(currentState);
Assert.InRange(currentState.Start, begin, begin + timeout);
Assert.InRange(currentState.StateUpdate, begin, begin + timeout);
Assert.Equal(expectedState, currentState.State);
Assert.Equal(expectedProgress, currentState.Progress);
}
[Fact]
public async Task Work_fails_with_info()
{
var expectedState = "41";
var expectedErrorText = "42";
var minWorkTime = TimeSpan.FromMilliseconds(10);
async Task workAction(string id, IServiceProvider services, Action<string, double?> callback, CancellationToken token)
{
await Task.Delay(minWorkTime);
callback(expectedState, 0);
throw new Exception(expectedErrorText);
}
var work = Work.CreateByDelegate("", workAction);
//act
var begin = DateTime.Now;
await work.Start(provider, CancellationToken.None);
//assert
Assert.Equal(0, work.CountComplete);
Assert.Equal(1, work.CountStart);
Assert.Equal(1, work.CountErrors);
Assert.Null(work.CurrentState);
Assert.Null(work.LastComplete);
var error = work.LastError;
Assert.NotNull(error);
Assert.InRange(error.Start, begin, DateTime.Now);
Assert.InRange(error.End, begin, DateTime.Now);
Assert.InRange(error.ExecutionTime, minWorkTime, DateTime.Now - begin);
Assert.Contains(expectedErrorText, error.ErrorText, StringComparison.InvariantCultureIgnoreCase);
Assert.Equal(expectedState, error.State);
}
}
}