feat(templateMatcher): Для синхронизации негруппированных работ добавлены метрики для мониторинга основных этапов.
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using PARR.Core.Common.Interfaces;
|
||||
using PARR.Core.Repositories.Interfaces.Job;
|
||||
using PARR.Core.Repositories.Interfaces.Unit;
|
||||
using PARR.Core.Services.UnitFilterService;
|
||||
using PARR.Core.Services.UnitFilterService.Matchers.Interfaces;
|
||||
using PARR.Core.Services.UnitFilterService.Models;
|
||||
using PARR.Core.Services.UnitService.Interfaces;
|
||||
using PARR.DAL.Context;
|
||||
using PARR.Domain.Cache.Models;
|
||||
using PARR.Domain.Entities.Job;
|
||||
@@ -98,6 +101,13 @@ public class UnitFilterServiceTests
|
||||
public Mock<IUnitFieldRepository> UnitField { get; set; }
|
||||
public Mock<IJobRepository> Job { get; set; }
|
||||
public Mock<IRedisCacheService> Cache { get; set; }
|
||||
// Новые зависимости после рефакторинга
|
||||
public Mock<IUnitService> UnitService { get; set; }
|
||||
public Mock<IUnitFieldMatcher> FieldMatcher { get; set; }
|
||||
public Mock<IUnitRelationshipMatcher> RelationshipMatcher { get; set; }
|
||||
public Mock<IUmbrellaFilter> UmbrellaFilter { get; set; }
|
||||
public Mock<IUnitFilterResultLoader> ResultLoader { get; set; }
|
||||
public Mock<IUnitNameResolver> NameResolver { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -137,6 +147,56 @@ public class UnitFilterServiceTests
|
||||
cacheMock.Setup(r => r.GetCachedDataAsync<UnitFilterIds>(It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.ReturnsAsync((UnitFilterIds)null!);
|
||||
|
||||
var unitServiceMock = new Mock<IUnitService>();
|
||||
var fieldMatcherMock = new Mock<IUnitFieldMatcher>();
|
||||
var relationshipMatcherMock = new Mock<IUnitRelationshipMatcher>();
|
||||
var umbrellaFilterMock = new Mock<IUmbrellaFilter>();
|
||||
var resultLoaderMock = new Mock<IUnitFilterResultLoader>();
|
||||
var nameResolverMock = new Mock<IUnitNameResolver>();
|
||||
|
||||
// Настройка NameResolver: возвращаем все ID юнитов из контекста (эмуляция кэш-промаха + БД)
|
||||
nameResolverMock.Setup(r => r.ResolveAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((string mask, CancellationToken ct) =>
|
||||
context.Units.Select(u => u.Id).ToList());
|
||||
|
||||
// Настройка FieldMatcher: эмуляция SQL-фильтрации через InMemory-контекст
|
||||
fieldMatcherMock.Setup(r => r.MatchAsync(It.IsAny<IReadOnlyList<Guid>>(), It.IsAny<IEnumerable<JobFieldFilter>>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((IReadOnlyList<Guid> ids, IEnumerable<JobFieldFilter> filters, CancellationToken ct) =>
|
||||
ids.ToList());
|
||||
|
||||
// Настройка RelationshipMatcher: возвращаем контексты без изменений
|
||||
relationshipMatcherMock.Setup(r => r.MatchAsync(It.IsAny<IReadOnlyList<Guid>>(), It.IsAny<IEnumerable<JobRelationshipFilter>>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((IReadOnlyList<Guid> ids, IEnumerable<JobRelationshipFilter> filters, CancellationToken ct) =>
|
||||
ids.Select(id => new UnitFilterMatchResult { UnitId = id }).ToList());
|
||||
|
||||
// Настройка UmbrellaFilter: пропускаем без изменений
|
||||
umbrellaFilterMock.Setup(r => r.Apply(It.IsAny<List<UnitFilterMatchResult>>(), It.IsAny<Job>()))
|
||||
.Returns((List<UnitFilterMatchResult> ctx, Job j) => ctx);
|
||||
|
||||
// Настройка ResultLoader: формируем DTO из контекста
|
||||
resultLoaderMock.Setup(r => r.LoadAsync(It.IsAny<List<UnitFilterMatchResult>>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((List<UnitFilterMatchResult> contexts, CancellationToken ct) =>
|
||||
{
|
||||
var unitIds = contexts.Select(c => c.UnitId).ToHashSet();
|
||||
var units = context.Units.Where(u => unitIds.Contains(u.Id)).ToList();
|
||||
return units.Select(u => new UnitFilterResultDto
|
||||
{
|
||||
Id = u.Id,
|
||||
Name = u.Name,
|
||||
Values = u.UnitValues?.Select(v => new UnitValueDto
|
||||
{
|
||||
FieldId = v.FieldId,
|
||||
Value = v.Value?.Value
|
||||
}).ToList() ?? new List<UnitValueDto>(),
|
||||
Parents = contexts.First(c => c.UnitId == u.Id).ValidParentIds
|
||||
.Select(pid => new RelatedUnitDto { UnitId = pid })
|
||||
.ToList(),
|
||||
Children = contexts.First(c => c.UnitId == u.Id).ValidChildIds
|
||||
.Select(cid => new RelatedUnitDto { UnitId = cid })
|
||||
.ToList()
|
||||
}).ToList();
|
||||
});
|
||||
|
||||
return new RepositoryMocks
|
||||
{
|
||||
Unit = unitRepoMock,
|
||||
@@ -144,7 +204,13 @@ public class UnitFilterServiceTests
|
||||
UnitInValue = unitInValueRepoMock,
|
||||
UnitField = unitFieldRepoMock,
|
||||
Job = jobRepoMock,
|
||||
Cache = cacheMock
|
||||
Cache = cacheMock,
|
||||
UnitService = unitServiceMock,
|
||||
FieldMatcher = fieldMatcherMock,
|
||||
RelationshipMatcher = relationshipMatcherMock,
|
||||
UmbrellaFilter = umbrellaFilterMock,
|
||||
ResultLoader = resultLoaderMock,
|
||||
NameResolver = nameResolverMock
|
||||
};
|
||||
}
|
||||
|
||||
@@ -154,12 +220,10 @@ public class UnitFilterServiceTests
|
||||
/// </summary>
|
||||
/// <param name="mocks">Подготовленные моки репозиториев</param>
|
||||
/// <param name="logger">Экземпляр логгера для сервиса</param>
|
||||
private static PARR.Core.Services.UnitFilterService.UnitFilterService CreateSut(
|
||||
private static Core.Services.UnitFilterService.UnitFilterService CreateSut(
|
||||
RepositoryMocks mocks,
|
||||
ILogger<PARR.Core.Services.UnitFilterService.UnitFilterService> logger)
|
||||
ILogger<Core.Services.UnitFilterService.UnitFilterService> logger)
|
||||
{
|
||||
var serviceOptions = Options.Create(new PARR.Core.Services.UnitFilterService.Models.UnitFilterServiceOptions { LoadBatchSize = 100 });
|
||||
|
||||
return new PARR.Core.Services.UnitFilterService.UnitFilterService(
|
||||
logger,
|
||||
mocks.Job.Object,
|
||||
@@ -167,8 +231,13 @@ public class UnitFilterServiceTests
|
||||
mocks.UnitInUnit.Object,
|
||||
mocks.UnitInValue.Object,
|
||||
mocks.Cache.Object,
|
||||
serviceOptions,
|
||||
mocks.UnitField.Object
|
||||
mocks.UnitField.Object,
|
||||
mocks.UnitService.Object,
|
||||
mocks.FieldMatcher.Object,
|
||||
mocks.RelationshipMatcher.Object,
|
||||
mocks.UmbrellaFilter.Object,
|
||||
mocks.ResultLoader.Object,
|
||||
mocks.NameResolver.Object
|
||||
);
|
||||
}
|
||||
|
||||
@@ -264,7 +333,7 @@ public class UnitFilterServiceTests
|
||||
mocks.UnitInValue.Setup(r => r.GetMatchingTargetIds(fieldId, It.IsAny<string>()))
|
||||
.Returns(context.Units.Where(u => u.Id == validParentId).Select(u => u.Id).AsQueryable());
|
||||
|
||||
var logger = NullLoggerFactory.Instance.CreateLogger<PARR.Core.Services.UnitFilterService.UnitFilterService>();
|
||||
var logger = NullLoggerFactory.Instance.CreateLogger<Core.Services.UnitFilterService.UnitFilterService>();
|
||||
var service = CreateSut(mocks, logger);
|
||||
|
||||
// === Act ===
|
||||
@@ -376,7 +445,7 @@ public class UnitFilterServiceTests
|
||||
.Distinct()
|
||||
.AsQueryable());
|
||||
|
||||
var logger = NullLoggerFactory.Instance.CreateLogger<PARR.Core.Services.UnitFilterService.UnitFilterService>();
|
||||
var logger = NullLoggerFactory.Instance.CreateLogger<Core.Services.UnitFilterService.UnitFilterService>();
|
||||
var service = CreateSut(mocks, logger);
|
||||
|
||||
// === Act ===
|
||||
@@ -481,7 +550,7 @@ public class UnitFilterServiceTests
|
||||
.Distinct()
|
||||
.AsQueryable());
|
||||
|
||||
var logger = NullLoggerFactory.Instance.CreateLogger<PARR.Core.Services.UnitFilterService.UnitFilterService>();
|
||||
var logger = NullLoggerFactory.Instance.CreateLogger<Core.Services.UnitFilterService.UnitFilterService>();
|
||||
var service = CreateSut(mocks, logger);
|
||||
|
||||
// === Act ===
|
||||
@@ -593,7 +662,7 @@ public class UnitFilterServiceTests
|
||||
.Distinct()
|
||||
.AsQueryable());
|
||||
|
||||
var logger = NullLoggerFactory.Instance.CreateLogger<PARR.Core.Services.UnitFilterService.UnitFilterService>();
|
||||
var logger = NullLoggerFactory.Instance.CreateLogger<Core.Services.UnitFilterService.UnitFilterService>();
|
||||
var service = CreateSut(mocks, logger);
|
||||
|
||||
// === Act ===
|
||||
|
||||
Reference in New Issue
Block a user