/** * @file basic_test.cpp * @brief CMS 核心引擎基本单元测试 * * 使用标准库 assert 进行验证,不依赖外部测试框架。 */ #include "app.hpp" #include #include #include #include /** * @brief 测试事件接入与处理 */ static void testEventIngestion() { std::cout << "[TEST] testEventIngestion ... "; CmsEngine engine; // 空 ID 应被拒绝 EventRecord bad; bad.id = ""; assert(!engine.ingestEvent(bad)); // 有效事件应被接受 EventRecord evt; evt.id = "EVT-TEST-001"; evt.typeTag = "test_type"; evt.priority = 100; evt.threatLevel = 3; evt.status = EventStatus::Pending; evt.receiveTime = std::chrono::system_clock::now(); assert(engine.ingestEvent(evt)); // 查找事件 const auto* found = engine.findEventById("EVT-TEST-001"); assert(found != nullptr); assert(found->typeTag == "test_type"); // 处理待处理事件 → 应生成一个任务方案 size_t count = engine.processPendingEvents(); assert(count == 1); // 事件状态已变为 Generated found = engine.findEventById("EVT-TEST-001"); assert(found != nullptr); assert(found->status == EventStatus::Generated); // 方案列表应有 1 个方案 assert(engine.getAllPlans().size() == 1); std::cout << "PASSED\n"; } /** * @brief 测试任务方案管理 */ static void testPlanManagement() { std::cout << "[TEST] testPlanManagement ... "; CmsEngine engine; // 空名称应被拒绝 TaskPlan badPlan; badPlan.name = ""; assert(!engine.createTaskPlan(badPlan)); // 有效方案 TaskPlan plan; plan.name = "Operation-Storm"; plan.type = PlanType::Distributed; plan.status = PlanStatus::Drafting; plan.topologyNodes = {"Node-1", "Node-2", "Node-3"}; plan.resourceQuota = 0.8; plan.constraints = "max_delay=5s"; assert(engine.createTaskPlan(plan)); // 创建后应有 ID assert(!plan.id.empty()); // 按 ID 查找 const auto* found = engine.findPlanById(plan.id); assert(found != nullptr); assert(found->name == "Operation-Storm"); assert(found->type == PlanType::Distributed); // 更新状态 assert(engine.updatePlanStatus(plan.id, PlanStatus::Confirmed)); found = engine.findPlanById(plan.id); assert(found->status == PlanStatus::Confirmed); // 不存在的 ID 更新应失败 assert(!engine.updatePlanStatus("NONEXIST", PlanStatus::Completed)); std::cout << "PASSED\n"; } /** * @brief 测试模板注册与匹配 */ static void testTemplateMatching() { std::cout << "[TEST] testTemplateMatching ... "; CmsEngine engine; // 空库匹配应返回 nullptr assert(engine.matchTemplate("any") == nullptr); TemplateInstance tmpl; tmpl.id = "TMPL-TEST"; tmpl.scenario = "land_assault"; tmpl.complexity = 0.8; tmpl.version = "1.0.0"; tmpl.confidence = 0.95; engine.registerTemplate(tmpl); const auto* matched = engine.matchTemplate("land_assault"); assert(matched != nullptr); assert(matched->id == "TMPL-TEST"); assert(matched->confidence == 0.95); std::cout << "PASSED\n"; } /** * @brief 测试执行监控与健康检查 */ static void testExecutionMonitoring() { std::cout << "[TEST] testExecutionMonitoring ... "; CmsEngine engine; // 健康节点 ExecutionStatus healthy; healthy.nodeId = "NODE-H"; healthy.healthIndex = 0.95; healthy.errorCode = 0; healthy.lastReport = std::chrono::system_clock::now(); engine.reportExecutionStatus(healthy); // 异常节点(健康指数低) ExecutionStatus sick; sick.nodeId = "NODE-S"; sick.healthIndex = 0.3; sick.errorCode = 0; sick.lastReport = std::chrono::system_clock::now(); engine.reportExecutionStatus(sick); // 异常节点(异常码非零) ExecutionStatus error; error.nodeId = "NODE-E"; error.healthIndex = 0.9; error.errorCode = 0xA001; error.lastReport = std::chrono::system_clock::now(); engine.reportExecutionStatus(error); // 异常节点(心跳超时 - 45秒前) ExecutionStatus timeout; timeout.nodeId = "NODE-T"; timeout.healthIndex = 0.9; timeout.errorCode = 0; timeout.lastReport = std::chrono::system_clock::now() - std::chrono::seconds(45); engine.reportExecutionStatus(timeout); auto unhealthy = engine.checkHealth(); // 应有 3 个异常节点(NODE-S, NODE-E, NODE-T) assert(unhealthy.size() == 3); // 验证具体节点 bool foundS = false, foundE = false, foundT = false; for (const auto& u : unhealthy) { if (u.nodeId == "NODE-S") foundS = true; if (u.nodeId == "NODE-E") foundE = true; if (u.nodeId == "NODE-T") foundT = true; } assert(foundS && foundE && foundT); std::cout << "PASSED\n"; } /** * @brief 测试用户会话与权限 */ static void testUserSession() { std::cout << "[TEST] testUserSession ... "; CmsEngine engine; // 空用户 ID 应被拒绝 UserSession bad; bad.userId = ""; assert(!engine.createSession(bad)); // 创建有效用户 UserSession user; user.userId = "USER-001"; user.roleCode = "OPERATOR"; user.permissionBitmap = 0x0000000000000003ULL; // 位0+位1 assert(engine.createSession(user)); // 重复创建应失败 assert(!engine.createSession(user)); // 权限校验 assert(engine.checkPermission("USER-001", 0x0000000000000001ULL)); assert(engine.checkPermission("USER-001", 0x0000000000000002ULL)); assert(engine.checkPermission("USER-001", 0x0000000000000003ULL)); assert(!engine.checkPermission("USER-001", 0x0000000000000004ULL)); // 不存在的用户 assert(!engine.checkPermission("GHOST", 0x0000000000000001ULL)); std::cout << "PASSED\n"; } /** * @brief 测试通知管理 */ static void testNotification() { std::cout << "[TEST] testNotification ... "; CmsEngine engine; // 初始无未读通知 assert(engine.getUnreadNotifications().empty()); NotificationMessage msg; msg.id = "NTF-001"; msg.priority = 200; msg.type = NotificationType::Alert; msg.summary = "Test alert"; msg.triggerTime = std::chrono::system_clock::now(); msg.isRead = false; engine.pushNotification(msg); assert(engine.getUnreadNotifications().size() == 1); // 推送已读消息 NotificationMessage readMsg; readMsg.id = "NTF-002"; readMsg.priority = 50; readMsg.type = NotificationType::Hint; readMsg.summary = "Read message"; readMsg.triggerTime = std::chrono::system_clock::now(); readMsg.isRead = true; engine.pushNotification(readMsg); // 未读数量仍为 1 assert(engine.getUnreadNotifications().size() == 1); std::cout << "PASSED\n"; } /** * @brief 测试模式切换 */ static void testModeSwitch() { std::cout << "[TEST] testModeSwitch ... "; CmsEngine engine; // 初始模式为 Idle assert(engine.getSystemContext().currentMode == RunMode::Idle); // 正常切换 assert(engine.switchMode(RunMode::HumanLoop)); assert(engine.getSystemContext().currentMode == RunMode::HumanLoop); assert(engine.switchMode(RunMode::AutoExec)); assert(engine.getSystemContext().currentMode == RunMode::AutoExec); // 进入降级模式 assert(engine.switchMode(RunMode::Degraded)); assert(engine.getSystemContext().currentMode == RunMode::Degraded); // 降级模式下不允许切换回其他模式(安全策略) assert(!engine.switchMode(RunMode::Idle)); assert(!engine.switchMode(RunMode::HumanLoop)); std::cout << "PASSED\n"; } /** * @brief 主测试入口 * * 依次运行所有测试用例,汇总测试结果。 * * @return int 退出码(0 全部通过,1 有失败) */ int main() { std::cout << "╔══════════════════════════════════════════════╗\n"; std::cout << "║ CMS 单元测试 ║\n"; std::cout << "╚══════════════════════════════════════════════╝\n\n"; testEventIngestion(); testPlanManagement(); testTemplateMatching(); testExecutionMonitoring(); testUserSession(); testNotification(); testModeSwitch(); std::cout << "\n╔══════════════════════════════════════════════╗\n"; std::cout << "║ 全部测试通过 (ALL TESTS PASSED) ║\n"; std::cout << "╚══════════════════════════════════════════════╝\n"; return 0; }