服务端: - 新增 GET /api/test/batch-queue-status(查询队列项状态: id/status/errorMessage/collisionCount/detectionRecordId,供测试轮询) - BatchQueueManager 增加 internal GetDatabase() 访问器 客户端: - NavisworksTestAutomationClient 新增 BatchQueueStatusAsync / BatchQueueProcessAsync 测试: - BatchQueueF1ProcessAutomationTests(TestCategory=NavisworksIntegrationF1, 不在默认全量内):add(虚拟物体 F1 场景)→ process → 轮询 status 至 Completed → 断言碰撞报告。单独跑约 30 秒。 AGENTS.md:记录 F1 测试用法(bat 参数含 = 会截断,用 FullyQualifiedName~)
82 lines
3.5 KiB
C#
82 lines
3.5 KiB
C#
using System;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||
using Newtonsoft.Json.Linq;
|
||
|
||
namespace NavisworksTransport.UnitTests.Integration
|
||
{
|
||
/// <summary>
|
||
/// 批处理队列 F1 端到端测试(剖面盒自动检测,副实例多进程)。
|
||
///
|
||
/// 独立 TestCategory(NavisworksIntegrationF1),不进默认全量
|
||
/// (TestCategory=NavisworksIntegration),因为完整 F1 流程
|
||
/// (副实例启动 + 剖面盒导出 + 局部模型检测)耗时较长(分钟级)。
|
||
///
|
||
/// 单独运行:
|
||
/// run-integration-tests.bat "TestCategory=NavisworksIntegrationF1"
|
||
///
|
||
/// 覆盖链路:add(虚拟物体,DetectAllObjects=true)→ process(触发 F1)
|
||
/// → 轮询 batch-queue-status 至 Completed → 断言碰撞报告已生成。
|
||
/// </summary>
|
||
[TestClass]
|
||
[TestCategory("NavisworksIntegrationF1")]
|
||
public class BatchQueueF1ProcessAutomationTests
|
||
{
|
||
private const int TestFrameRate = 15;
|
||
private const double TestDurationSeconds = 5.0;
|
||
|
||
[TestMethod]
|
||
[Timeout(360000)]
|
||
public async Task BatchQueueF1_ProcessQueue_CompletesWithCollisionReport()
|
||
{
|
||
using (var client = new NavisworksTestAutomationClient())
|
||
{
|
||
await client.EnsureServiceReadyAsync(TimeSpan.FromSeconds(90)).ConfigureAwait(false);
|
||
|
||
// 1. 添加虚拟物体队列项(F1 剖面盒自动检测:DetectAllObjects=true 走副实例)
|
||
JObject add = await client.BatchQueueAddAsync(
|
||
"自动测试_Ground", TestFrameRate, TestDurationSeconds).ConfigureAwait(false);
|
||
Assert.IsTrue(add.Value<bool>("ok"), "添加队列项失败: " + (string)add["error"]);
|
||
|
||
int itemId = (int)((JObject)add["data"])["itemId"];
|
||
Assert.IsTrue(itemId > 0, "队列项 ID 无效");
|
||
|
||
// 2. 触发后台处理(F1)
|
||
JObject process = await client.BatchQueueProcessAsync().ConfigureAwait(false);
|
||
Assert.IsTrue(process.Value<bool>("ok"), "触发批处理失败: " + (string)process["error"]);
|
||
|
||
// 3. 轮询队列状态直到该 itemId 进入终态(Completed/Failed)
|
||
DateTime deadline = DateTime.UtcNow.AddMinutes(3);
|
||
string status = null;
|
||
string errorMessage = null;
|
||
while (DateTime.UtcNow < deadline)
|
||
{
|
||
await Task.Delay(5000).ConfigureAwait(false);
|
||
|
||
JObject statusResp = await client.BatchQueueStatusAsync(10).ConfigureAwait(false);
|
||
Assert.IsTrue(statusResp.Value<bool>("ok"), "查询队列状态失败");
|
||
|
||
var items = (JArray)statusResp["data"]["items"];
|
||
var mine = items?.FirstOrDefault(i => (int)i["itemId"] == itemId);
|
||
if (mine != null)
|
||
{
|
||
status = (string)mine["status"];
|
||
errorMessage = (string)mine["errorMessage"];
|
||
if (status == "Completed" || status == "Failed")
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
Assert.AreEqual(
|
||
"Completed",
|
||
status,
|
||
"F1 批处理未在时限内完成。itemId=" + itemId +
|
||
(string.IsNullOrEmpty(errorMessage) ? "" : ",错误: " + errorMessage));
|
||
}
|
||
}
|
||
}
|
||
}
|