using System; using System.Linq; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json.Linq; namespace NavisworksTransport.UnitTests.Integration { /// /// 批处理队列 F1 端到端测试(剖面盒自动检测,副实例多进程)。 /// /// 独立 TestCategory(NavisworksIntegrationF1),不进默认全量 /// (TestCategory=NavisworksIntegration),因为完整 F1 流程 /// (副实例启动 + 剖面盒导出 + 局部模型检测)耗时较长(分钟级)。 /// /// 单独运行: /// run-integration-tests.bat "TestCategory=NavisworksIntegrationF1" /// /// 覆盖链路:add(虚拟物体,DetectAllObjects=true)→ process(触发 F1) /// → 轮询 batch-queue-status 至 Completed → 断言碰撞报告已生成。 /// [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("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("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("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)); // 等待后台批处理完全退出(避免后台任务残留影响后续测试的 isExecuting 断言) DateTime exitDeadline = DateTime.UtcNow.AddSeconds(90); while (DateTime.UtcNow < exitDeadline) { JObject statusResp = await client.BatchQueueStatusAsync(1).ConfigureAwait(false); bool isExecuting = (bool?)statusResp["data"]?["isExecuting"] ?? false; if (!isExecuting) { break; } await Task.Delay(2000).ConfigureAwait(false); } } } } }