#include #include "app.hpp" #include #include namespace c2sys { class AppTest : public ::testing::Test { protected: App app; void SetUp() override { app.initialize(""); } }; // generateId tests TEST(AppTest, GenerateIdFormat) { std::string id = app.generateId(); EXPECT_TRUE(id.find("ID-") == 0); EXPECT_EQ(id.length(), 23u); } TEST(AppTest, GenerateIdUniqueness) { std::string id1 = app.generateId(); std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::string id2 = app.generateId(); EXPECT_NE(id1, id2); } // nowMs tests TEST(AppTest, NowMsReturnsPositive) { int64_t ms = app.nowMs(); EXPECT_GT(ms, 0); } // Impl constructor tests TEST(AppTest, InitialState) { EXPECT_EQ(app.getState(), SystemState::Ready); EXPECT_EQ(app.getRunMode(), RunMode::HumanInLoop); } // initialize tests TEST_F(AppTest, InitializeWithEmptyConfig) { EXPECT_TRUE(app.initialize("")); EXPECT_EQ(app.getState(), SystemState::Ready); } TEST_F(AppTest, InitializeClearsData) { app.addPlan({"plan1", PlanType::Centralized, 0.5, 10, 0.8, 0.7, 0.9}); app.initialize(""); EXPECT_TRUE(app.getAllPlans().empty()); } // start tests TEST_F(AppTest, StartFromReady) { EXPECT_TRUE(app.start()); EXPECT_EQ(app.getState(), SystemState::Running); } TEST_F(AppTest, StartFromStopped) { app.stop(); EXPECT_TRUE(app.start()); EXPECT_EQ(app.getState(), SystemState::Running); } TEST_F(AppTest, StartFromRunningFails) { app.start(); EXPECT_FALSE(app.start()); } // stop tests TEST_F(AppTest, StopChangesState) { app.start(); app.stop(); EXPECT_EQ(app.getState(), SystemState::Stopped); } // getState tests TEST_F(AppTest, GetStateAfterStart) { app.start(); EXPECT_EQ(app.getState(), SystemState::Running); } // setRunMode tests TEST_F(AppTest, SetRunModeUpdatesCache) { app.setRunMode(RunMode::Autonomous); EXPECT_EQ(app.getRunMode(), RunMode::Autonomous); } // getRunMode tests TEST_F(AppTest, GetRunModeDefault) { EXPECT_EQ(app.getRunMode(), RunMode::HumanInLoop); } // addPlan tests TEST_F(AppTest, AddValidPlan) { PlanData plan{"p1", PlanType::Distributed, 0.6, 15, 0.9, 0.8, 0.7}; EXPECT_TRUE(app.addPlan(plan)); EXPECT_EQ(app.getAllPlans().size(), 1u); } TEST_F(AppTest, AddEmptyIdPlanFails) { PlanData plan{"", PlanType::Centralized, 0.5, 10, 0.8, 0.7, 0.9}; EXPECT_FALSE(app.addPlan(plan)); } TEST_F(AppTest, AddDuplicatePlanFails) { PlanData plan{"p1", PlanType::Centralized, 0.5, 10, 0.8, 0.7, 0.9}; app.addPlan(plan); EXPECT_FALSE(app.addPlan(plan)); } // getAllPlans tests TEST_F(AppTest, GetAllPlansReturnsAll) { app.addPlan({"p1", PlanType::Centralized, 0.5, 10, 0.8, 0.7, 0.9}); app.addPlan({"p2", PlanType::Distributed, 0.6, 15, 0.9, 0.8, 0.7}); EXPECT_EQ(app.getAllPlans().size(), 2u); } // findPlanById tests TEST_F(AppTest, FindExistingPlan) { app.addPlan({"p1", PlanType::Centralized, 0.5, 10, 0.8, 0.7, 0.9}); EXPECT_NE(app.findPlanById("p1"), nullptr); } TEST_F(AppTest, FindNonExistingPlan) { EXPECT_EQ(app.findPlanById("invalid"), nullptr); } // comparePlans tests TEST_F(AppTest, CompareValidPlans) { app.addPlan({"p1", PlanType::Centralized, 0.5, 10, 0.8, 0.7, 0.9}); std::string report = app.comparePlans({"p1"}); EXPECT_TRUE(report.find("集中式") != std::string::npos); } TEST_F(AppTest, CompareMissingPlan) { std::string report = app.comparePlans({"missing"}); EXPECT_TRUE(report.find("未找到") != std::string::npos); } // ingestRawEvent tests TEST_F(AppTest, IngestValidEvent) { EventRaw raw{"src1", "payload", 3, "TCP"}; std::string id = app.ingestRawEvent(raw); EXPECT_FALSE(id.empty()); } TEST_F(AppTest, IngestEmptySourceFails) { EventRaw raw{"", "payload", 3, "TCP"}; EXPECT_TRUE(app.ingestRawEvent(raw).empty()); } // getPendingEvents tests TEST_F(AppTest, GetPendingAfterIngest) { EventRaw raw{"src1", "payload", 3, "TCP"}; app.ingestRawEvent(raw); EXPECT_EQ(app.getPendingEvents().size(), 1u); } // processEvent tests TEST_F(AppTest, ProcessAcceptEvent) { EventRaw raw{"src1", "payload", 3, "TCP"}; std::string id = app.ingestRawEvent(raw); EXPECT_TRUE(app.processEvent(id, true)); EXPECT_EQ(app.getPendingEvents().size(), 0u); } TEST_F(AppTest, ProcessInvalidEventFails) { EXPECT_FALSE(app.processEvent("invalid", true)); } // generateTaskFromEvent tests TEST_F(AppTest, GenerateTaskFromPendingEvent) { EventRaw raw{"src1", "payload", 3, "TCP"}; std::string evtId = app.ingestRawEvent(raw); std::string taskId = app.generateTaskFromEvent(evtId); EXPECT_FALSE(taskId.empty()); EXPECT_NE(app.getExecutionStatus(taskId), nullptr); } TEST_F(AppTest, GenerateTaskFromIgnoredEventFails) { EventRaw raw{"src1", "payload", 3, "TCP"}; std::string evtId = app.ingestRawEvent(raw); app.processEvent(evtId, false); EXPECT_TRUE(app.generateTaskFromEvent(evtId).empty()); } // addTemplate tests TEST_F(AppTest, AddValidTemplate) { TaskTemplate tmpl{"t1", "scenario", 0.8}; EXPECT_TRUE(app.addTemplate(tmpl)); } TEST_F(AppTest, AddEmptyIdTemplateFails) { TaskTemplate tmpl{"", "scenario", 0.8}; EXPECT_FALSE(app.addTemplate(tmpl)); } // matchBestTemplate tests TEST_F(AppTest, MatchExistingTemplate) { app.addTemplate({"t1", "threat_3", 0.9}); EXPECT_NE(app.matchBestTemplate("threat_3"), nullptr); } TEST_F(AppTest, MatchNoTemplate) { EXPECT_EQ(app.matchBestTemplate("unknown"), nullptr); } // saveSnapshot tests TEST_F(AppTest, SaveSnapshotReturnsVersion) { std::string ver = app.saveSnapshot(); EXPECT_TRUE(ver.find("SNAP-") == 0); } // rollbackToSnapshot tests TEST_F(AppTest, RollbackValidSnapshot) { std::string ver = app.saveSnapshot(); EXPECT_TRUE(app.rollbackToSnapshot(ver)); } TEST_F(AppTest, RollbackInvalidSnapshotFails) { EXPECT_FALSE(app.rollbackToSnapshot("invalid")); } // dispatchPlan tests TEST_F(AppTest, DispatchValidPlan) { app.addPlan({"p1", PlanType::Centralized, 0.5, 10, 0.8, 0.7, 0.9}); int count = app.dispatchPlan("p1", {"node1", "node2"}); EXPECT_GE(count, 0); EXPECT_LE(count, 2); } TEST_F(AppTest, DispatchInvalidPlanFails) { EXPECT_EQ(app.dispatchPlan("invalid", {"node1"}), 0); } // getDistributionAcks tests TEST_F(AppTest, GetAcksAfterDispatch) { app.addPlan({"p1", PlanType::Centralized, 0.5, 10, 0.8, 0.7, 0.9}); app.dispatchPlan("p1", {"node1"}); EXPECT_FALSE(app.getDistributionAcks().empty()); } // reportExecutionStatus tests TEST_F(AppTest, ReportStatusUpdatesMap) { ExecutionStatus status{"task1", "PHASE1", 50.0, 1000, 0}; app.reportExecutionStatus(status); EXPECT_NE(app.getExecutionStatus("task1"), nullptr); } // getExecutionStatus tests TEST_F(AppTest, GetExistingStatus) { ExecutionStatus status{"task1", "PHASE1", 50.0, 1000, 0}; app.reportExecutionStatus(status); EXPECT_NE(app.getExecutionStatus("task1"), nullptr); } TEST_F(AppTest, GetNonExistingStatus) { EXPECT_EQ(app.getExecutionStatus("invalid"), nullptr); } // logOperation tests TEST_F(AppTest, LogOperationAddsEntry) { OperationLog log{"op1", "action", 1000}; app.logOperation(log); EXPECT_EQ(app.getOperationLogs().size(), 1u); } // getOperationLogs tests TEST_F(AppTest, GetLogsAfterLogging) { app.logOperation({"op1", "action", 1000}); EXPECT_FALSE(app.getOperationLogs().empty()); } // getConfig tests TEST_F(AppTest, GetConfigReturnsReference) { const auto& config = app.getConfig(); EXPECT_EQ(config.maxRetryCount, 3); } } // namespace c2sys