#include #include #include "app.hpp" #include #include using namespace testing; // ============================================================================ // Test Fixture for CmsEngine // ============================================================================ class CmsEngineTest : public ::testing::Test { protected: void SetUp() override { engine = std::make_unique(); } void TearDown() override { engine.reset(); } std::unique_ptr engine; }; // ============================================================================ // Tests for CmsEngine Constructor // ============================================================================ /** * @brief 测试构造函数初始化系统状态上下文 * * 验证构造函数正确初始化系统状态上下文,包括模式、一致性标记、切换时间和快照。 */ TEST_F(CmsEngineTest, testConstructorInitializesSystemContext) { const auto& context = engine->getSystemContext(); EXPECT_EQ(context.currentMode, RunMode::Idle); EXPECT_EQ(context.consistencyMark, 0); auto now = std::chrono::system_clock::now(); auto diff = std::chrono::duration_cast(now - context.switchTime).count(); EXPECT_GE(diff, 0); EXPECT_LT(diff, 5); EXPECT_THAT(context.contextSnapshot, HasSubstr("\"mode\":\"Idle\"")); EXPECT_THAT(context.contextSnapshot, HasSubstr("\"version\":\"1.0.0\"")); } /** * @brief 测试构造函数初始化空容器 * * 验证构造函数正确初始化所有容器为空。 */ TEST_F(CmsEngineTest, testConstructorInitializesEmptyContainers) { EXPECT_EQ(engine->getAllPlans().size(), 0); std::string summary = engine->getSummary(); EXPECT_THAT(summary, HasSubstr("Events : 0")); EXPECT_THAT(summary, HasSubstr("Plans : 0")); EXPECT_THAT(summary, HasSubstr("Templates : 0")); EXPECT_THAT(summary, HasSubstr("Monitor Nodes : 0")); EXPECT_THAT(summary, HasSubstr("Active Sessions : 0")); EXPECT_THAT(summary, HasSubstr("Notifications : 0")); EXPECT_THAT(summary, HasSubstr("Mode : Idle")); } // ============================================================================ // Tests for ingestEvent // ============================================================================ /** * @brief 测试正常事件接入 * * 验证具有有效 ID 和合法优先级的事件能够成功接入。 */ TEST_F(CmsEngineTest, testIngestEventValidEvent) { EventRecord event; event.id = "EVT-001"; event.priority = 100; event.status = EventStatus::Pending; bool result = engine->ingestEvent(event); EXPECT_TRUE(result); const EventRecord* storedEvent = engine->findEventById("EVT-001"); ASSERT_NE(storedEvent, nullptr); EXPECT_EQ(storedEvent->id, "EVT-001"); EXPECT_EQ(storedEvent->priority, 100); EXPECT_EQ(storedEvent->status, EventStatus::Pending); } /** * @brief 测试接入优先级为 0 的事件 * * 验证优先级为 0(最小值)的事件能够成功接入。 */ TEST_F(CmsEngineTest, testIngestEventMinPriority) { EventRecord event; event.id = "EVT-002"; event.priority = 0; event.status = EventStatus::Pending; bool result = engine->ingestEvent(event); EXPECT_TRUE(result); const EventRecord* storedEvent = engine->findEventById("EVT-002"); ASSERT_NE(storedEvent, nullptr); EXPECT_EQ(storedEvent->priority, 0); } /** * @brief 测试接入优先级为 255 的事件 * * 验证优先级为 255(最大值)的事件能够成功接入。 */ TEST_F(CmsEngineTest, testIngestEventMaxPriority) { EventRecord event; event.id = "EVT-003"; event.priority = 255; event.status = EventStatus::Pending; bool result = engine->ingestEvent(event); EXPECT_TRUE(result); const EventRecord* storedEvent = engine->findEventById("EVT-003"); ASSERT_NE(storedEvent, nullptr); EXPECT_EQ(storedEvent->priority, 255); } /** * @brief 测试接入空 ID 事件 * * 验证 ID 为空的事件接入失败,返回 false。 */ TEST_F(CmsEngineTest, testIngestEventEmptyId) { EventRecord event; event.id = ""; event.priority = 100; event.status = EventStatus::Pending; bool result = engine->ingestEvent(event); EXPECT_FALSE(result); const EventRecord* storedEvent = engine->findEventById(""); EXPECT_EQ(storedEvent, nullptr); } /** * @brief 测试接入优先级超限事件 * * 验证优先级大于 255 的事件接入失败,返回 false。 */ TEST_F(CmsEngineTest, testIngestEventPriorityExceedsMax) { EventRecord event; event.id = "EVT-004"; event.priority = 256; event.status = EventStatus::Pending; bool result = engine->ingestEvent(event); EXPECT_FALSE(result); const EventRecord* storedEvent = engine->findEventById("EVT-004"); EXPECT_EQ(storedEvent, nullptr); } /** * @brief 测试接入多个事件 * * 验证多个事件能够依次成功接入,且事件列表正确增长。 */ TEST_F(CmsEngineTest, testIngestEventMultipleEvents) { EventRecord event1; event1.id = "EVT-005"; event1.priority = 50; event1.status = EventStatus::Pending; EventRecord event2; event2.id = "EVT-006"; event2.priority = 150; event2.status = EventStatus::Pending; EXPECT_TRUE(engine->ingestEvent(event1)); EXPECT_TRUE(engine->ingestEvent(event2)); const EventRecord* storedEvent1 = engine->findEventById("EVT-005"); ASSERT_NE(storedEvent1, nullptr); EXPECT_EQ(storedEvent1->priority, 50); const EventRecord* storedEvent2 = engine->findEventById("EVT-006"); ASSERT_NE(storedEvent2, nullptr); EXPECT_EQ(storedEvent2->priority, 150); } /** * @brief 测试接入事件后处理待处理事件 * * 验证接入 Pending 状态的事件后,processPendingEvents 能正确处理。 */ TEST_F(CmsEngineTest, testIngestEventAndProcessPending) { EventRecord event; event.id = "EVT-007"; event.priority = 100; event.status = EventStatus::Pending; EXPECT_TRUE(engine->ingestEvent(event)); size_t processedCount = engine->processPendingEvents(); EXPECT_EQ(processedCount, 1); const EventRecord* storedEvent = engine->findEventById("EVT-007"); ASSERT_NE(storedEvent, nullptr); EXPECT_EQ(storedEvent->status, EventStatus::Generated); // 通过 getAllPlans 获取方案列表,验证自动生成的方案 const auto& plans = engine->getAllPlans(); ASSERT_EQ(plans.size(), 1); EXPECT_EQ(plans[0].relatedEventId, "EVT-007"); EXPECT_EQ(plans[0].name, "AutoPlan-EVT-007"); } // ============================================================================ // Tests for findPlanById // ============================================================================ /** * @brief 测试查找存在的方案 * * 验证能够通过 ID 查找到已创建的任务方案。 */ TEST_F(CmsEngineTest, testFindPlanByIdExistingPlan) { TaskPlan plan; plan.name = "TestPlan"; plan.type = PlanType::Centralized; plan.status = PlanStatus::Drafting; plan.resourceQuota = 0.8; plan.constraints = "测试约束"; EXPECT_TRUE(engine->createTaskPlan(plan)); std::string planId = plan.id; EXPECT_FALSE(planId.empty()); const TaskPlan* foundPlan = engine->findPlanById(planId); ASSERT_NE(foundPlan, nullptr); EXPECT_EQ(foundPlan->id, planId); EXPECT_EQ(foundPlan->name, "TestPlan"); EXPECT_EQ(foundPlan->type, PlanType::Centralized); EXPECT_EQ(foundPlan->status, PlanStatus::Drafting); EXPECT_DOUBLE_EQ(foundPlan->resourceQuota, 0.8); EXPECT_EQ(foundPlan->constraints, "测试约束"); } /** * @brief 测试查找不存在的方案 * * 验证查找不存在的 ID 时返回 nullptr。 */ TEST_F(CmsEngineTest, testFindPlanByIdNonExistentPlan) { const TaskPlan* foundPlan = engine->findPlanById("NONEXISTENT"); EXPECT_EQ(foundPlan, nullptr); } /** * @brief 测试查找空 ID 方案 * * 验证查找空字符串 ID 时返回 nullptr。 */ TEST_F(CmsEngineTest, testFindPlanByIdEmptyId) { const TaskPlan* foundPlan = engine->findPlanById(""); EXPECT_EQ(foundPlan, nullptr); } /** * @brief 测试查找多个方案中的特定方案 * * 验证在多个方案中能够正确查找到指定 ID 的方案。 */ TEST_F(CmsEngineTest, testFindPlanByIdAmongMultiplePlans) { TaskPlan plan1; plan1.name = "PlanAlpha"; EXPECT_TRUE(engine->createTaskPlan(plan1)); std::string id1 = plan1.id; TaskPlan plan2; plan2.name = "PlanBeta"; EXPECT_TRUE(engine->createTaskPlan(plan2)); std::string id2 = plan2.id; TaskPlan plan3; plan3.name = "PlanGamma"; EXPECT_TRUE(engine->createTaskPlan(plan3)); std::string id3 = plan3.id; EXPECT_NE(id1, id2); EXPECT_NE(id2, id3); EXPECT_NE(id1, id3); const TaskPlan* foundPlan = engine->findPlanById(id2); ASSERT_NE(foundPlan, nullptr); EXPECT_EQ(foundPlan->id, id2); EXPECT_EQ(foundPlan->name, "PlanBeta"); foundPlan = engine->findPlanById(id1); ASSERT_NE(foundPlan, nullptr); EXPECT_EQ(foundPlan->id, id1); EXPECT_EQ(foundPlan->name, "PlanAlpha"); foundPlan = engine->findPlanById(id3); ASSERT_NE(foundPlan, nullptr); EXPECT_EQ(foundPlan->id, id3); EXPECT_EQ(foundPlan->name, "PlanGamma"); } /** * @brief 测试查找已更新状态的方案 * * 验证方案状态更新后仍能查找到,且状态正确。 */ TEST_F(CmsEngineTest, testFindPlanByIdAfterStatusUpdate) { TaskPlan plan; plan.name = "StatusTestPlan"; EXPECT_TRUE(engine->createTaskPlan(plan)); std::string planId = plan.id; EXPECT_TRUE(engine->updatePlanStatus(planId, PlanStatus::Approved)); const TaskPlan* foundPlan = engine->findPlanById(planId); ASSERT_NE(foundPlan, nullptr); EXPECT_EQ(foundPlan->status, PlanStatus::Approved); } /** * @brief 测试查找通过事件处理生成的方案 * * 验证通过 processPendingEvents 自动生成的方案能够被正确查找。 */ TEST_F(CmsEngineTest, testFindPlanByIdGeneratedFromEvent) { EventRecord event; event.id = "EVT-GEN-001"; event.priority = 100; event.status = EventStatus::Pending; EXPECT_TRUE(engine->ingestEvent(event)); size_t processedCount = engine->processPendingEvents(); EXPECT_EQ(processedCount, 1); // 通过 getAllPlans 获取方案列表,验证自动生成的方案 const auto& plans = engine->getAllPlans(); ASSERT_EQ(plans.size(), 1); std::string planId = plans[0].id; EXPECT_FALSE(planId.empty()); const TaskPlan* foundPlan = engine->findPlanById(planId); ASSERT_NE(foundPlan, nullptr); EXPECT_EQ(foundPlan->relatedEventId, "EVT-GEN-001"); EXPECT_EQ(foundPlan->name, "AutoPlan-EVT-GEN-001"); EXPECT_EQ(foundPlan->type, PlanType::Centralized); EXPECT_EQ(foundPlan->status, PlanStatus::Drafting); EXPECT_DOUBLE_EQ(foundPlan->resourceQuota, 0.5); EXPECT_EQ(foundPlan->constraints, "自动生成约束"); } /** * @brief 测试查找方案时的常量正确性 * * 验证 const 版本的 findPlanById 返回的指针指向常量对象。 */ TEST_F(CmsEngineTest, testFindPlanByIdConstCorrectness) { TaskPlan plan; plan.name = "ConstTestPlan"; EXPECT_TRUE(engine->createTaskPlan(plan)); std::string planId = plan.id; const CmsEngine& constEngine = *engine; const TaskPlan* foundPlan = constEngine.findPlanById(planId); ASSERT_NE(foundPlan, nullptr); EXPECT_EQ(foundPlan->id, planId); EXPECT_EQ(foundPlan->name, "ConstTestPlan"); }