Compare commits
1 Commits
main
...
test_20260
| Author | SHA1 | Date |
|---|---|---|
|
|
3851b2eebf |
|
|
@ -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)
|
||||||
|
|
@ -0,0 +1,324 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include "app.hpp"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// 测试夹具:CmsEngineTest
|
||||||
|
// ============================================================
|
||||||
|
class CmsEngineTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
CmsEngine engine;
|
||||||
|
|
||||||
|
void SetUp() override {
|
||||||
|
// 初始化一些事件用于测试
|
||||||
|
EventRecord evt1;
|
||||||
|
evt1.id = "EVT-001";
|
||||||
|
evt1.priority = 100;
|
||||||
|
evt1.status = EventStatus::Pending;
|
||||||
|
engine.ingestEvent(evt1);
|
||||||
|
|
||||||
|
EventRecord evt2;
|
||||||
|
evt2.id = "EVT-002";
|
||||||
|
evt2.priority = 200;
|
||||||
|
evt2.status = EventStatus::Pending;
|
||||||
|
engine.ingestEvent(evt2);
|
||||||
|
|
||||||
|
EventRecord evt3;
|
||||||
|
evt3.id = "EVT-003";
|
||||||
|
evt3.priority = 50;
|
||||||
|
evt3.status = EventStatus::Generated; // 非 Pending 状态
|
||||||
|
engine.ingestEvent(evt3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown() override {
|
||||||
|
// 清理工作(如果需要)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// 测试用例:processPendingEvents
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requirement(name="待处理事件处理", id="REQ-EVENT-PROC-001")
|
||||||
|
* 系统需遍历事件库中所有 Pending 状态的事件,自动将其状态标记为 Generated,
|
||||||
|
* 并据此生成一个对应的 TaskPlan 草案,实现事件到方案的自动转化。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 正常输入测试:处理所有 Pending 事件
|
||||||
|
TEST_F(CmsEngineTest, testProcessPendingEventsNormal) {
|
||||||
|
// 执行:处理待处理事件
|
||||||
|
size_t processedCount = engine.processPendingEvents();
|
||||||
|
|
||||||
|
// 验证:应该处理了 2 个 Pending 事件(EVT-001 和 EVT-002)
|
||||||
|
EXPECT_EQ(processedCount, 2);
|
||||||
|
|
||||||
|
// 验证:事件状态已更新
|
||||||
|
const EventRecord* evt1 = engine.findEventById("EVT-001");
|
||||||
|
ASSERT_NE(evt1, nullptr);
|
||||||
|
EXPECT_EQ(evt1->status, EventStatus::Generated);
|
||||||
|
|
||||||
|
const EventRecord* evt2 = engine.findEventById("EVT-002");
|
||||||
|
ASSERT_NE(evt2, nullptr);
|
||||||
|
EXPECT_EQ(evt2->status, EventStatus::Generated);
|
||||||
|
|
||||||
|
// 验证:非 Pending 事件状态不变
|
||||||
|
const EventRecord* evt3 = engine.findEventById("EVT-003");
|
||||||
|
ASSERT_NE(evt3, nullptr);
|
||||||
|
EXPECT_EQ(evt3->status, EventStatus::Generated); // 原本就是 Generated
|
||||||
|
|
||||||
|
// 验证:生成了对应的 TaskPlan
|
||||||
|
const std::vector<TaskPlan>& plans = engine.getAllPlans();
|
||||||
|
EXPECT_EQ(plans.size(), 2);
|
||||||
|
|
||||||
|
// 验证第一个方案的属性
|
||||||
|
EXPECT_EQ(plans[0].name, "AutoPlan-EVT-001");
|
||||||
|
EXPECT_EQ(plans[0].type, PlanType::Centralized);
|
||||||
|
EXPECT_EQ(plans[0].status, PlanStatus::Drafting);
|
||||||
|
EXPECT_EQ(plans[0].relatedEventId, "EVT-001");
|
||||||
|
EXPECT_FLOAT_EQ(plans[0].resourceQuota, 0.5);
|
||||||
|
EXPECT_EQ(plans[0].constraints, "自动生成约束");
|
||||||
|
|
||||||
|
// 验证第二个方案的属性
|
||||||
|
EXPECT_EQ(plans[1].name, "AutoPlan-EVT-002");
|
||||||
|
EXPECT_EQ(plans[1].relatedEventId, "EVT-002");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 边界值测试:没有 Pending 事件
|
||||||
|
TEST_F(CmsEngineTest, testProcessPendingEventsNoPending) {
|
||||||
|
// 先处理所有 Pending 事件
|
||||||
|
engine.processPendingEvents();
|
||||||
|
|
||||||
|
// 再次调用,应该没有 Pending 事件了
|
||||||
|
size_t processedCount = engine.processPendingEvents();
|
||||||
|
|
||||||
|
// 验证:处理数量为 0
|
||||||
|
EXPECT_EQ(processedCount, 0);
|
||||||
|
|
||||||
|
// 验证:方案数量没有增加
|
||||||
|
const std::vector<TaskPlan>& plans = engine.getAllPlans();
|
||||||
|
EXPECT_EQ(plans.size(), 2); // 仍然是第一次处理生成的 2 个方案
|
||||||
|
}
|
||||||
|
|
||||||
|
// 边界值测试:事件列表为空
|
||||||
|
TEST_F(CmsEngineTest, testProcessPendingEventsEmptyEvents) {
|
||||||
|
// 创建一个新的空引擎
|
||||||
|
CmsEngine emptyEngine;
|
||||||
|
|
||||||
|
// 执行:处理待处理事件
|
||||||
|
size_t processedCount = emptyEngine.processPendingEvents();
|
||||||
|
|
||||||
|
// 验证:处理数量为 0
|
||||||
|
EXPECT_EQ(processedCount, 0);
|
||||||
|
|
||||||
|
// 验证:方案列表为空
|
||||||
|
const std::vector<TaskPlan>& plans = emptyEngine.getAllPlans();
|
||||||
|
EXPECT_TRUE(plans.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 特殊场景测试:多次调用 processPendingEvents
|
||||||
|
TEST_F(CmsEngineTest, testProcessPendingEventsMultipleCalls) {
|
||||||
|
// 第一次调用
|
||||||
|
size_t firstCount = engine.processPendingEvents();
|
||||||
|
EXPECT_EQ(firstCount, 2);
|
||||||
|
|
||||||
|
// 第二次调用(已经没有 Pending 事件了)
|
||||||
|
size_t secondCount = engine.processPendingEvents();
|
||||||
|
EXPECT_EQ(secondCount, 0);
|
||||||
|
|
||||||
|
// 验证:方案数量为 2(只有第一次生成的)
|
||||||
|
const std::vector<TaskPlan>& plans = engine.getAllPlans();
|
||||||
|
EXPECT_EQ(plans.size(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// 测试用例:findEventById
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requirement(name="事件查询", id="REQ-EVENT-QUERY-001")
|
||||||
|
* 系统需支持根据事件 ID 在事件库中查找对应的事件记录,
|
||||||
|
* 找到则返回事件指针,未找到返回 nullptr。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 正常输入测试:查找存在的事件
|
||||||
|
TEST_F(CmsEngineTest, testFindEventByIdNormal) {
|
||||||
|
const EventRecord* evt = engine.findEventById("EVT-001");
|
||||||
|
|
||||||
|
// 验证:找到事件
|
||||||
|
ASSERT_NE(evt, nullptr);
|
||||||
|
EXPECT_EQ(evt->id, "EVT-001");
|
||||||
|
EXPECT_EQ(evt->priority, 100);
|
||||||
|
EXPECT_EQ(evt->status, EventStatus::Pending);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 边界值测试:查找不存在的事件
|
||||||
|
TEST_F(CmsEngineTest, testFindEventByIdNotFound) {
|
||||||
|
const EventRecord* evt = engine.findEventById("NONEXISTENT");
|
||||||
|
|
||||||
|
// 验证:返回 nullptr
|
||||||
|
EXPECT_EQ(evt, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 边界值测试:查找空字符串 ID
|
||||||
|
TEST_F(CmsEngineTest, testFindEventByIdEmptyId) {
|
||||||
|
const EventRecord* evt = engine.findEventById("");
|
||||||
|
|
||||||
|
// 验证:返回 nullptr(因为事件 ID 不能为空,所以不会有空 ID 的事件)
|
||||||
|
EXPECT_EQ(evt, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 边界值测试:查找特殊字符 ID
|
||||||
|
TEST_F(CmsEngineTest, testFindEventByIdSpecialChars) {
|
||||||
|
const EventRecord* evt = engine.findEventById("EVT-@#$");
|
||||||
|
|
||||||
|
// 验证:返回 nullptr(不存在该事件)
|
||||||
|
EXPECT_EQ(evt, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 特殊场景测试:查找已处理的事件(状态已改变)
|
||||||
|
TEST_F(CmsEngineTest, testFindEventByIdAfterProcessing) {
|
||||||
|
// 先处理事件
|
||||||
|
engine.processPendingEvents();
|
||||||
|
|
||||||
|
// 查找已处理的事件
|
||||||
|
const EventRecord* evt = engine.findEventById("EVT-001");
|
||||||
|
|
||||||
|
// 验证:找到事件,且状态已更新
|
||||||
|
ASSERT_NE(evt, nullptr);
|
||||||
|
EXPECT_EQ(evt->id, "EVT-001");
|
||||||
|
EXPECT_EQ(evt->status, EventStatus::Generated);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// 测试用例:createTaskPlan
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requirement(name="任务方案创建", id="REQ-PLAN-CREATE-001")
|
||||||
|
* 系统需校验方案名称非空后,为其分配系统 ID 并存入方案库,
|
||||||
|
* 确保方案数据的完整性和可追溯性。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 正常输入测试:创建有效的任务方案
|
||||||
|
TEST_F(CmsEngineTest, testCreateTaskPlanNormal) {
|
||||||
|
TaskPlan plan;
|
||||||
|
plan.name = "Test Plan";
|
||||||
|
plan.type = PlanType::Centralized;
|
||||||
|
plan.status = PlanStatus::Drafting;
|
||||||
|
plan.resourceQuota = 0.8;
|
||||||
|
plan.constraints = "测试约束";
|
||||||
|
|
||||||
|
// 执行:创建任务方案
|
||||||
|
bool result = engine.createTaskPlan(plan);
|
||||||
|
|
||||||
|
// 验证:创建成功
|
||||||
|
EXPECT_TRUE(result);
|
||||||
|
|
||||||
|
// 验证:方案 ID 已被填充(格式为 ID-xxxxx)
|
||||||
|
EXPECT_FALSE(plan.id.empty());
|
||||||
|
EXPECT_EQ(plan.id.substr(0, 3), "ID-");
|
||||||
|
EXPECT_EQ(plan.id.length(), 8); // "ID-" + 5 位数字
|
||||||
|
|
||||||
|
// 验证:创建时间已被填充
|
||||||
|
// 由于 createTime 是 system_clock::time_point,我们无法直接比较,
|
||||||
|
// 但可以确认它已经被设置(不为默认值)
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
auto diff = std::chrono::duration_cast<std::chrono::seconds>(now - plan.createTime).count();
|
||||||
|
EXPECT_LE(diff, 1); // 创建时间应该在 1 秒内
|
||||||
|
|
||||||
|
// 验证:方案已被添加到方案库
|
||||||
|
const std::vector<TaskPlan>& plans = engine.getAllPlans();
|
||||||
|
EXPECT_EQ(plans.size(), 1);
|
||||||
|
EXPECT_EQ(plans[0].id, plan.id);
|
||||||
|
EXPECT_EQ(plans[0].name, "Test Plan");
|
||||||
|
EXPECT_EQ(plans[0].type, PlanType::Centralized);
|
||||||
|
EXPECT_EQ(plans[0].status, PlanStatus::Drafting);
|
||||||
|
EXPECT_FLOAT_EQ(plans[0].resourceQuota, 0.8);
|
||||||
|
EXPECT_EQ(plans[0].constraints, "测试约束");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 边界值测试:创建名称为空的方案
|
||||||
|
TEST_F(CmsEngineTest, testCreateTaskPlanEmptyName) {
|
||||||
|
TaskPlan plan;
|
||||||
|
plan.name = ""; // 空名称
|
||||||
|
plan.type = PlanType::Centralized;
|
||||||
|
plan.status = PlanStatus::Drafting;
|
||||||
|
|
||||||
|
// 执行:创建任务方案
|
||||||
|
bool result = engine.createTaskPlan(plan);
|
||||||
|
|
||||||
|
// 验证:创建失败
|
||||||
|
EXPECT_FALSE(result);
|
||||||
|
|
||||||
|
// 验证:方案 ID 未被填充
|
||||||
|
EXPECT_TRUE(plan.id.empty());
|
||||||
|
|
||||||
|
// 验证:方案未被添加到方案库
|
||||||
|
const std::vector<TaskPlan>& plans = engine.getAllPlans();
|
||||||
|
EXPECT_TRUE(plans.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 边界值测试:创建名称为空格的方案
|
||||||
|
TEST_F(CmsEngineTest, testCreateTaskPlanSpaceName) {
|
||||||
|
TaskPlan plan;
|
||||||
|
plan.name = " "; // 空格名称
|
||||||
|
plan.type = PlanType::Centralized;
|
||||||
|
plan.status = PlanStatus::Drafting;
|
||||||
|
|
||||||
|
// 执行:创建任务方案
|
||||||
|
bool result = engine.createTaskPlan(plan);
|
||||||
|
|
||||||
|
// 验证:创建成功(因为空格不是空字符串)
|
||||||
|
EXPECT_TRUE(result);
|
||||||
|
|
||||||
|
// 验证:方案已被添加到方案库
|
||||||
|
const std::vector<TaskPlan>& plans = engine.getAllPlans();
|
||||||
|
EXPECT_EQ(plans.size(), 1);
|
||||||
|
EXPECT_EQ(plans[0].name, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 特殊场景测试:创建多个方案,验证 ID 自增
|
||||||
|
TEST_F(CmsEngineTest, testCreateTaskPlanMultiplePlans) {
|
||||||
|
TaskPlan plan1;
|
||||||
|
plan1.name = "Plan 1";
|
||||||
|
engine.createTaskPlan(plan1);
|
||||||
|
|
||||||
|
TaskPlan plan2;
|
||||||
|
plan2.name = "Plan 2";
|
||||||
|
engine.createTaskPlan(plan2);
|
||||||
|
|
||||||
|
TaskPlan plan3;
|
||||||
|
plan3.name = "Plan 3";
|
||||||
|
engine.createTaskPlan(plan3);
|
||||||
|
|
||||||
|
// 验证:生成了 3 个方案
|
||||||
|
const std::vector<TaskPlan>& plans = engine.getAllPlans();
|
||||||
|
EXPECT_EQ(plans.size(), 3);
|
||||||
|
|
||||||
|
// 验证:ID 自增(ID-00001, ID-00002, ID-00003)
|
||||||
|
EXPECT_EQ(plans[0].id, "ID-00001");
|
||||||
|
EXPECT_EQ(plans[1].id, "ID-00002");
|
||||||
|
EXPECT_EQ(plans[2].id, "ID-00003");
|
||||||
|
|
||||||
|
// 验证:名称正确
|
||||||
|
EXPECT_EQ(plans[0].name, "Plan 1");
|
||||||
|
EXPECT_EQ(plans[1].name, "Plan 2");
|
||||||
|
EXPECT_EQ(plans[2].name, "Plan 3");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 特殊场景测试:创建方案后,通过 findPlanById 验证
|
||||||
|
TEST_F(CmsEngineTest, testCreateTaskPlanAndFindById) {
|
||||||
|
TaskPlan plan;
|
||||||
|
plan.name = "Findable Plan";
|
||||||
|
engine.createTaskPlan(plan);
|
||||||
|
|
||||||
|
// 通过 ID 查找方案
|
||||||
|
const TaskPlan* foundPlan = engine.findPlanById(plan.id);
|
||||||
|
|
||||||
|
// 验证:找到方案
|
||||||
|
ASSERT_NE(foundPlan, nullptr);
|
||||||
|
EXPECT_EQ(foundPlan->id, plan.id);
|
||||||
|
EXPECT_EQ(foundPlan->name, "Findable Plan");
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue