From dfbbd6626261c9d8a5881d0d76aba51855e45a79 Mon Sep 17 00:00:00 2001 From: lids <1713278948@qq.com> Date: Fri, 15 May 2026 09:42:17 +0800 Subject: [PATCH] =?UTF-8?q?AI=20=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/CMakeLists.txt | 25 ++++ tests/test_app.cpp | 314 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 339 insertions(+) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/test_app.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..4cb68f5 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.10.0) +project(test_plan_execute_t1) +include(FetchContent) +if (MSVC) + add_compile_options(/utf-8) +endif() +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include) + +include(CTest) +enable_testing() + +add_executable(test_plan_execute_t1 test_app.cpp ../src/app.cpp) + +target_link_libraries(test_plan_execute_t1 gtest gmock gtest_main) +include(GoogleTest) +gtest_discover_tests(test_plan_execute_t1) \ No newline at end of file diff --git a/tests/test_app.cpp b/tests/test_app.cpp new file mode 100644 index 0000000..c479dcf --- /dev/null +++ b/tests/test_app.cpp @@ -0,0 +1,314 @@ +#include +#include +#include +#include +#include "app.hpp" + +// ============================================================================ +// 测试夹具:CmsEngineTest +// ============================================================================ +class CmsEngineTest : public ::testing::Test { +protected: + CmsEngine engine; + + // 辅助函数:创建一个有效的事件(注意:EventRecord 没有 timestamp 成员) + EventRecord createValidEvent(const std::string& id = "EVT-001", int priority = 100) { + EventRecord evt; + evt.id = id; + evt.priority = priority; + evt.status = EventStatus::Pending; + return evt; + } + + // 辅助函数:向引擎添加多个事件 + void addEventsToEngine(const std::vector& events) { + for (const auto& evt : events) { + engine.ingestEvent(evt); + } + } +}; + +// ============================================================================ +// ingestEvent 测试用例 +// ============================================================================ + +/** + * @brief 测试 ingestEvent 正常输入:有效事件应成功接入 + */ +TEST_F(CmsEngineTest, testIngestEventValidEvent) { + EventRecord evt = createValidEvent("EVT-001", 100); + bool result = engine.ingestEvent(evt); + EXPECT_TRUE(result); + + // 验证事件已存储 + const EventRecord* found = engine.findEventById("EVT-001"); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->id, "EVT-001"); + EXPECT_EQ(found->priority, 100); + EXPECT_EQ(found->status, EventStatus::Pending); +} + +/** + * @brief 测试 ingestEvent 边界值:优先级为 0 的最小值 + */ +TEST_F(CmsEngineTest, testIngestEventPriorityMin) { + EventRecord evt = createValidEvent("EVT-002", 0); + bool result = engine.ingestEvent(evt); + EXPECT_TRUE(result); + + const EventRecord* found = engine.findEventById("EVT-002"); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->priority, 0); +} + +/** + * @brief 测试 ingestEvent 边界值:优先级为 255 的最大值 + */ +TEST_F(CmsEngineTest, testIngestEventPriorityMax) { + EventRecord evt = createValidEvent("EVT-003", 255); + bool result = engine.ingestEvent(evt); + EXPECT_TRUE(result); + + const EventRecord* found = engine.findEventById("EVT-003"); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->priority, 255); +} + +/** + * @brief 测试 ingestEvent 异常输入:空 ID 应返回 false + */ +TEST_F(CmsEngineTest, testIngestEventEmptyId) { + EventRecord evt = createValidEvent("", 100); + bool result = engine.ingestEvent(evt); + EXPECT_FALSE(result); + + // 验证事件未存储 + const EventRecord* found = engine.findEventById(""); + EXPECT_EQ(found, nullptr); +} + +/** + * @brief 测试 ingestEvent 异常输入:优先级超过 255 应返回 false + */ +TEST_F(CmsEngineTest, testIngestEventPriorityOverflow) { + EventRecord evt = createValidEvent("EVT-004", 256); + bool result = engine.ingestEvent(evt); + EXPECT_FALSE(result); + + const EventRecord* found = engine.findEventById("EVT-004"); + EXPECT_EQ(found, nullptr); +} + +/** + * @brief 测试 ingestEvent 特殊场景:重复 ID 的事件应允许接入 + */ +TEST_F(CmsEngineTest, testIngestEventDuplicateId) { + EventRecord evt1 = createValidEvent("EVT-005", 100); + EventRecord evt2 = createValidEvent("EVT-005", 200); + + bool result1 = engine.ingestEvent(evt1); + EXPECT_TRUE(result1); + + bool result2 = engine.ingestEvent(evt2); + EXPECT_TRUE(result2); + + // 验证两个事件都存储(findEventById 返回第一个匹配的) + const EventRecord* found = engine.findEventById("EVT-005"); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->priority, 100); +} + +// ============================================================================ +// processPendingEvents 测试用例 +// ============================================================================ + +/** + * @brief 测试 processPendingEvents 正常输入:处理所有 Pending 事件 + */ +TEST_F(CmsEngineTest, testProcessPendingEventsAllPending) { + std::vector events = { + createValidEvent("EVT-010", 100), + createValidEvent("EVT-011", 200), + createValidEvent("EVT-012", 150) + }; + addEventsToEngine(events); + + size_t processed = engine.processPendingEvents(); + EXPECT_EQ(processed, 3); + + // 验证事件状态已更新 + const EventRecord* evt1 = engine.findEventById("EVT-010"); + ASSERT_NE(evt1, nullptr); + EXPECT_EQ(evt1->status, EventStatus::Generated); + + const EventRecord* evt2 = engine.findEventById("EVT-011"); + ASSERT_NE(evt2, nullptr); + EXPECT_EQ(evt2->status, EventStatus::Generated); + + // 验证生成了对应的 TaskPlan + const std::vector& plans = engine.getAllPlans(); + EXPECT_EQ(plans.size(), 3); + EXPECT_EQ(plans[0].relatedEventId, "EVT-010"); + EXPECT_EQ(plans[0].type, PlanType::Centralized); + EXPECT_EQ(plans[0].status, PlanStatus::Drafting); +} + +/** + * @brief 测试 processPendingEvents 边界值:没有 Pending 事件 + */ +TEST_F(CmsEngineTest, testProcessPendingEventsNoPending) { + // 添加一个非 Pending 状态的事件 + EventRecord evt = createValidEvent("EVT-020", 100); + evt.status = EventStatus::Generated; + engine.ingestEvent(evt); + + size_t processed = engine.processPendingEvents(); + EXPECT_EQ(processed, 0); + + // 验证没有生成新的 TaskPlan + const std::vector& plans = engine.getAllPlans(); + EXPECT_EQ(plans.size(), 0); +} + +/** + * @brief 测试 processPendingEvents 边界值:空事件库 + */ +TEST_F(CmsEngineTest, testProcessPendingEventsEmpty) { + size_t processed = engine.processPendingEvents(); + EXPECT_EQ(processed, 0); + + const std::vector& plans = engine.getAllPlans(); + EXPECT_EQ(plans.size(), 0); +} + +/** + * @brief 测试 processPendingEvents 特殊场景:混合状态的事件 + */ +TEST_F(CmsEngineTest, testProcessPendingEventsMixedStatus) { + EventRecord evt1 = createValidEvent("EVT-030", 100); + evt1.status = EventStatus::Pending; + engine.ingestEvent(evt1); + + EventRecord evt2 = createValidEvent("EVT-031", 200); + evt2.status = EventStatus::Generated; + engine.ingestEvent(evt2); + + EventRecord evt3 = createValidEvent("EVT-032", 150); + evt3.status = EventStatus::Pending; + engine.ingestEvent(evt3); + + size_t processed = engine.processPendingEvents(); + EXPECT_EQ(processed, 2); + + // 验证只有 Pending 的事件被处理 + const EventRecord* evt1_after = engine.findEventById("EVT-030"); + ASSERT_NE(evt1_after, nullptr); + EXPECT_EQ(evt1_after->status, EventStatus::Generated); + + const EventRecord* evt2_after = engine.findEventById("EVT-031"); + ASSERT_NE(evt2_after, nullptr); + EXPECT_EQ(evt2_after->status, EventStatus::Generated); + + const EventRecord* evt3_after = engine.findEventById("EVT-032"); + ASSERT_NE(evt3_after, nullptr); + EXPECT_EQ(evt3_after->status, EventStatus::Generated); + + // 验证生成了 2 个 TaskPlan + const std::vector& plans = engine.getAllPlans(); + EXPECT_EQ(plans.size(), 2); +} + +// ============================================================================ +// findEventById 测试用例 +// ============================================================================ + +/** + * @brief 测试 findEventById 正常输入:查找已存在的事件 + */ +TEST_F(CmsEngineTest, testFindEventByIdExisting) { + EventRecord evt = createValidEvent("EVT-100", 100); + engine.ingestEvent(evt); + + const EventRecord* found = engine.findEventById("EVT-100"); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->id, "EVT-100"); + EXPECT_EQ(found->priority, 100); + EXPECT_EQ(found->status, EventStatus::Pending); +} + +/** + * @brief 测试 findEventById 边界值:查找空字符串 ID + */ +TEST_F(CmsEngineTest, testFindEventByIdEmptyString) { + // 添加一个空 ID 的事件(虽然 ingestEvent 会拒绝,但直接测试 findEventById) + const EventRecord* found = engine.findEventById(""); + EXPECT_EQ(found, nullptr); +} + +/** + * @brief 测试 findEventById 异常输入:查找不存在的事件 + */ +TEST_F(CmsEngineTest, testFindEventByIdNonExistent) { + EventRecord evt = createValidEvent("EVT-200", 100); + engine.ingestEvent(evt); + + const EventRecord* found = engine.findEventById("EVT-999"); + EXPECT_EQ(found, nullptr); +} + +/** + * @brief 测试 findEventById 特殊场景:查找长 ID 字符串 + */ +TEST_F(CmsEngineTest, testFindEventByIdLongId) { + std::string longId = "EVT-" + std::string(100, 'A'); + EventRecord evt = createValidEvent(longId, 100); + engine.ingestEvent(evt); + + const EventRecord* found = engine.findEventById(longId); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->id, longId); +} + +/** + * @brief 测试 findEventById 特殊场景:多个事件中查找特定 ID + */ +TEST_F(CmsEngineTest, testFindEventByIdAmongMultiple) { + std::vector events = { + createValidEvent("EVT-300", 100), + createValidEvent("EVT-301", 200), + createValidEvent("EVT-302", 150) + }; + addEventsToEngine(events); + + // 查找中间的事件 + const EventRecord* found = engine.findEventById("EVT-301"); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->id, "EVT-301"); + EXPECT_EQ(found->priority, 200); + + // 查找第一个事件 + found = engine.findEventById("EVT-300"); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->id, "EVT-300"); + + // 查找最后一个事件 + found = engine.findEventById("EVT-302"); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->id, "EVT-302"); +} + +/** + * @brief 测试 findEventById 特殊场景:查找已处理事件的状态 + */ +TEST_F(CmsEngineTest, testFindEventByIdAfterProcessing) { + EventRecord evt = createValidEvent("EVT-400", 100); + engine.ingestEvent(evt); + + // 处理事件 + engine.processPendingEvents(); + + // 查找事件并验证状态已更新 + const EventRecord* found = engine.findEventById("EVT-400"); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->status, EventStatus::Generated); +}