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);
}
}
}
}
}