- 添加HNSW向量索引提升检索性能 - 实现Hybrid检索模式支持向量和关键词双路召回 - 采用RRF算法融合多路召回结果 - 支持ParentChild分块模式的上下文回填 - 优化向量写入采用批量SQL操作提升性能 - 添加RAG PostgreSQL连接字符串配置 - 更新部署脚本增加PGVector集成测试 - 修正表名引用从document_chunks到b_document_chunks - 重构RagRetrievalService实现完整的检索流程 - 增加重排策略支持关键词和LLM重排 - 修改服务器部署地址配置
120 lines
4.4 KiB
C#
120 lines
4.4 KiB
C#
using System.Runtime.CompilerServices;
|
||
using BuildFlow.Shared.Domain.Errors;
|
||
using BuildFlow.Shared.Domain.Exceptions;
|
||
using FluentAssertions;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Monitoring.Application.ExternalSystems.Commands;
|
||
using Monitoring.Application.ExternalSystems.Handlers;
|
||
using Monitoring.Application.Reports.Handlers;
|
||
using Monitoring.Application.Reports.Queries;
|
||
using Monitoring.Domain.Entities.SyncedRecord;
|
||
using Monitoring.Domain.Entities.SyncJob;
|
||
using Monitoring.Domain.Enums;
|
||
using Monitoring.Domain.Values;
|
||
using Monitoring.Infrastructure.Persistence;
|
||
|
||
namespace BuildFlow.Monitoring.Tests;
|
||
|
||
/// <summary>
|
||
/// [SOP-MONITORING] Reports 子域 Handler 测试(GetDailyTrend / GetSyncSummary)。
|
||
/// 两者均为纯 DbContext 查询,不依赖 SyncProcessor/外部连接器,可用 InMemory 直接覆盖。
|
||
/// </summary>
|
||
public class ReportsHandlerTests
|
||
{
|
||
private static MonitoringDbContext Db([CallerMemberName] string name = "")
|
||
=> MonitoringTestDb.Create(name);
|
||
|
||
private static async Task<Guid> SeedSystem(MonitoringDbContext db, string name = "u号租")
|
||
{
|
||
var created = await new CreateExternalSystemCommandHandler(db).Handle(
|
||
new CreateExternalSystemCommand(name, 1, "https://x", 60, null),
|
||
CancellationToken.None);
|
||
return created.Id;
|
||
}
|
||
|
||
#region GetDailyTrend
|
||
|
||
[Fact]
|
||
public async Task GetDailyTrend_Empty_ReturnsEmpty()
|
||
{
|
||
await using var db = Db();
|
||
var sysId = await SeedSystem(db);
|
||
var result = await new GetDailyTrendQueryHandler(db)
|
||
.Handle(new GetDailyTrendQuery(sysId, 14), CancellationToken.None);
|
||
result.Should().BeEmpty();
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetDailyTrend_GroupsByDay()
|
||
{
|
||
await using var db = Db();
|
||
var sysId = await SeedSystem(db);
|
||
var today = DateTime.UtcNow.Date;
|
||
db.SyncedRecords.Add(new SyncedRecordEntity
|
||
{
|
||
ExternalSystemId = sysId, SyncJobId = Guid.NewGuid(), ExternalId = "o1",
|
||
RecordType = "order", OccurredAt = today.AddHours(1), JsonData = "{}"
|
||
});
|
||
db.SyncedRecords.Add(new SyncedRecordEntity
|
||
{
|
||
ExternalSystemId = sysId, SyncJobId = Guid.NewGuid(), ExternalId = "o2",
|
||
RecordType = "order", OccurredAt = today.AddHours(2), JsonData = "{}"
|
||
});
|
||
db.SyncedRecords.Add(new SyncedRecordEntity
|
||
{
|
||
ExternalSystemId = sysId, SyncJobId = Guid.NewGuid(), ExternalId = "o3",
|
||
RecordType = "order", OccurredAt = today.AddDays(-2), JsonData = "{}"
|
||
});
|
||
await db.SaveChangesAsync();
|
||
|
||
var result = await new GetDailyTrendQueryHandler(db)
|
||
.Handle(new GetDailyTrendQuery(sysId, 14), CancellationToken.None);
|
||
result.Should().HaveCount(2, "今天 2 条 + 2 天前 1 条,跨 2 个日期");
|
||
result.Sum(r => r.RecordCount).Should().Be(3);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region GetSyncSummary
|
||
|
||
[Fact]
|
||
public async Task GetSyncSummary_Existing_ReturnsSummary()
|
||
{
|
||
await using var db = Db();
|
||
var sysId = await SeedSystem(db);
|
||
db.SyncJobs.Add(new SyncJobEntity
|
||
{
|
||
ExternalSystemId = sysId,
|
||
Status = SyncJobStatusEnum.Succeeded,
|
||
StartedAt = DateTime.UtcNow.AddMinutes(-5),
|
||
FinishedAt = DateTime.UtcNow,
|
||
RecordCount = 100,
|
||
DurationMs = 1234,
|
||
Data = new JobData { TriggerSource = "manual", SummaryMetrics = new() { ["order_count"] = "100" } }
|
||
});
|
||
await db.SaveChangesAsync();
|
||
|
||
var result = await new GetSyncSummaryQueryHandler(db)
|
||
.Handle(new GetSyncSummaryQuery(sysId, 10), CancellationToken.None);
|
||
result.Should().NotBeNull();
|
||
result.ExternalSystemId.Should().Be(sysId);
|
||
result.SystemName.Should().Be("u号租");
|
||
result.RecentJobs.Should().HaveCount(1);
|
||
result.RecentJobs[0].Status.Should().Be("Succeeded");
|
||
result.RecentJobs[0].RecordCount.Should().Be(100);
|
||
result.LatestMetrics.Should().ContainKey("order_count");
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetSyncSummary_NotFound_Throws()
|
||
{
|
||
await using var db = Db();
|
||
var act = async () => await new GetSyncSummaryQueryHandler(db)
|
||
.Handle(new GetSyncSummaryQuery(Guid.NewGuid(), 10), CancellationToken.None);
|
||
var ex = await act.Should().ThrowAsync<NotFoundException>();
|
||
ex.Which.Code.Should().Be(ErrorCode.NotFound);
|
||
}
|
||
|
||
#endregion
|
||
}
|