plan_execute_t1/tests/test_app.cpp

301 lines
9.1 KiB
C++
Raw Normal View History

2026-06-04 08:10:45 +00:00
#include <gtest/gtest.h>
#include <string>
#include <vector>
#include "app.hpp"
// ============================================================
// 测试夹具CmsEngineTest
// ============================================================
class CmsEngineTest : public ::testing::Test {
protected:
CmsEngine engine;
void SetUp() override {
// 每个测试用例开始前重置引擎状态
// 注意CmsEngine 构造函数已初始化,但 plans_ 为空
}
void TearDown() override {
// 清理(如果需要)
}
};
// ============================================================
// 测试用例createTaskPlan
// ============================================================
/**
* @requirement(name="任务方案创建", id="REQ-PLAN-CREATE-001")
* ID
*
*/
// 正常输入测试:创建有效方案
TEST_F(CmsEngineTest, testCreateTaskPlanNormal) {
TaskPlan plan;
plan.name = "TestPlan";
plan.type = PlanType::Centralized;
plan.status = PlanStatus::Drafting;
plan.resourceQuota = 0.8;
plan.constraints = "无约束";
bool result = engine.createTaskPlan(plan);
EXPECT_TRUE(result);
EXPECT_FALSE(plan.id.empty());
EXPECT_EQ(plan.name, "TestPlan");
EXPECT_EQ(plan.type, PlanType::Centralized);
EXPECT_EQ(plan.status, PlanStatus::Drafting);
EXPECT_EQ(plan.resourceQuota, 0.8);
EXPECT_EQ(plan.constraints, "无约束");
// 验证方案已存入引擎
const auto& plans = engine.getAllPlans();
ASSERT_EQ(plans.size(), 1);
EXPECT_EQ(plans[0].id, plan.id);
EXPECT_EQ(plans[0].name, "TestPlan");
}
// 边界值测试:名称为空字符串
TEST_F(CmsEngineTest, testCreateTaskPlanEmptyName) {
TaskPlan plan;
plan.name = "";
plan.type = PlanType::Centralized;
plan.status = PlanStatus::Drafting;
bool result = engine.createTaskPlan(plan);
EXPECT_FALSE(result);
EXPECT_TRUE(plan.id.empty()); // 不应分配 ID
// 验证方案未存入引擎
const auto& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 0);
}
// 边界值测试:名称为空白字符串(仅空格)
TEST_F(CmsEngineTest, testCreateTaskPlanWhitespaceName) {
TaskPlan plan;
plan.name = " ";
plan.type = PlanType::Centralized;
plan.status = PlanStatus::Drafting;
bool result = engine.createTaskPlan(plan);
EXPECT_TRUE(result); // 空白字符串不为空,应视为合法
EXPECT_FALSE(plan.id.empty());
const auto& plans = engine.getAllPlans();
ASSERT_EQ(plans.size(), 1);
EXPECT_EQ(plans[0].name, " ");
}
// 边界值测试:名称长度极长
TEST_F(CmsEngineTest, testCreateTaskPlanLongName) {
TaskPlan plan;
plan.name = std::string(1000, 'A'); // 1000 个字符
plan.type = PlanType::Centralized;
plan.status = PlanStatus::Drafting;
bool result = engine.createTaskPlan(plan);
EXPECT_TRUE(result);
EXPECT_FALSE(plan.id.empty());
const auto& plans = engine.getAllPlans();
ASSERT_EQ(plans.size(), 1);
EXPECT_EQ(plans[0].name, std::string(1000, 'A'));
}
// 异常输入测试:创建多个方案,验证 ID 唯一性
TEST_F(CmsEngineTest, testCreateTaskPlanMultiplePlans) {
TaskPlan plan1;
plan1.name = "Plan1";
TaskPlan plan2;
plan2.name = "Plan2";
TaskPlan plan3;
plan3.name = "Plan3";
EXPECT_TRUE(engine.createTaskPlan(plan1));
EXPECT_TRUE(engine.createTaskPlan(plan2));
EXPECT_TRUE(engine.createTaskPlan(plan3));
// 验证 ID 唯一性
EXPECT_NE(plan1.id, plan2.id);
EXPECT_NE(plan1.id, plan3.id);
EXPECT_NE(plan2.id, plan3.id);
// 验证方案数量
const auto& plans = engine.getAllPlans();
ASSERT_EQ(plans.size(), 3);
}
// 特殊场景测试:创建方案后,验证 createTime 被设置
TEST_F(CmsEngineTest, testCreateTaskPlanCreateTimeSet) {
TaskPlan plan;
plan.name = "TimeTest";
plan.type = PlanType::Centralized;
plan.status = PlanStatus::Drafting;
auto before = std::chrono::system_clock::now();
bool result = engine.createTaskPlan(plan);
auto after = std::chrono::system_clock::now();
EXPECT_TRUE(result);
EXPECT_GE(plan.createTime, before);
EXPECT_LE(plan.createTime, after);
}
// ============================================================
// 测试用例getAllPlans
// ============================================================
/**
* @requirement(name="任务方案列表查询", id="REQ-PLAN-LIST-001")
*
*/
// 正常输入测试:空列表
TEST_F(CmsEngineTest, testGetAllPlansEmpty) {
const auto& plans = engine.getAllPlans();
EXPECT_TRUE(plans.empty());
EXPECT_EQ(plans.size(), 0);
}
// 正常输入测试:包含多个方案
TEST_F(CmsEngineTest, testGetAllPlansWithPlans) {
TaskPlan plan1;
plan1.name = "Plan1";
TaskPlan plan2;
plan2.name = "Plan2";
TaskPlan plan3;
plan3.name = "Plan3";
engine.createTaskPlan(plan1);
engine.createTaskPlan(plan2);
engine.createTaskPlan(plan3);
const auto& plans = engine.getAllPlans();
ASSERT_EQ(plans.size(), 3);
EXPECT_EQ(plans[0].name, "Plan1");
EXPECT_EQ(plans[1].name, "Plan2");
EXPECT_EQ(plans[2].name, "Plan3");
}
// 边界值测试:验证返回的是常量引用,不可修改
TEST_F(CmsEngineTest, testGetAllPlansConstReference) {
// 编译时验证const auto& 可以绑定auto& 会编译错误
const auto& plans = engine.getAllPlans();
EXPECT_TRUE(plans.empty());
// 以下代码如果取消注释,编译会失败(因为返回 const 引用)
// plans.push_back(TaskPlan()); // 编译错误
}
// 特殊场景测试:多次调用返回相同引用
TEST_F(CmsEngineTest, testGetAllPlansSameReference) {
const auto& plans1 = engine.getAllPlans();
const auto& plans2 = engine.getAllPlans();
EXPECT_EQ(&plans1, &plans2); // 应为同一对象
}
// ============================================================
// 测试用例findPlanById
// ============================================================
/**
* @requirement(name="任务方案查找", id="REQ-PLAN-FIND-001")
* ID
* nullptr
*/
// 正常输入测试:查找存在的方案
TEST_F(CmsEngineTest, testFindPlanByIdExisting) {
TaskPlan plan;
plan.name = "TestPlan";
plan.type = PlanType::Centralized;
plan.status = PlanStatus::Drafting;
engine.createTaskPlan(plan);
const TaskPlan* found = engine.findPlanById(plan.id);
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->id, plan.id);
EXPECT_EQ(found->name, "TestPlan");
EXPECT_EQ(found->type, PlanType::Centralized);
EXPECT_EQ(found->status, PlanStatus::Drafting);
}
// 边界值测试:查找不存在的 ID
TEST_F(CmsEngineTest, testFindPlanByIdNonExisting) {
const TaskPlan* found = engine.findPlanById("NON_EXISTENT_ID");
EXPECT_EQ(found, nullptr);
}
// 边界值测试:查找空字符串 ID
TEST_F(CmsEngineTest, testFindPlanByIdEmptyId) {
TaskPlan plan;
plan.name = "TestPlan";
engine.createTaskPlan(plan);
const TaskPlan* found = engine.findPlanById("");
EXPECT_EQ(found, nullptr);
}
// 边界值测试:在空列表中查找
TEST_F(CmsEngineTest, testFindPlanByIdEmptyList) {
const TaskPlan* found = engine.findPlanById("ANY_ID");
EXPECT_EQ(found, nullptr);
}
// 异常输入测试:查找 ID 格式异常
TEST_F(CmsEngineTest, testFindPlanByIdInvalidFormat) {
TaskPlan plan;
plan.name = "TestPlan";
engine.createTaskPlan(plan);
// 查找类似但不同的 ID
const TaskPlan* found = engine.findPlanById(plan.id + "_extra");
EXPECT_EQ(found, nullptr);
}
// 特殊场景测试:多个方案中查找特定方案
TEST_F(CmsEngineTest, testFindPlanByIdMultiplePlans) {
TaskPlan plan1;
plan1.name = "Plan1";
TaskPlan plan2;
plan2.name = "Plan2";
TaskPlan plan3;
plan3.name = "Plan3";
engine.createTaskPlan(plan1);
engine.createTaskPlan(plan2);
engine.createTaskPlan(plan3);
// 查找中间方案
const TaskPlan* found = engine.findPlanById(plan2.id);
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->name, "Plan2");
// 查找最后一个方案
found = engine.findPlanById(plan3.id);
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->name, "Plan3");
}
// 特殊场景测试:查找后修改方案(通过非 const 方法)
TEST_F(CmsEngineTest, testFindPlanByIdAndModify) {
TaskPlan plan;
plan.name = "TestPlan";
engine.createTaskPlan(plan);
// 通过 findPlanById 获取 const 指针,不能修改
const TaskPlan* found = engine.findPlanById(plan.id);
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->status, PlanStatus::Drafting);
// 通过 updatePlanStatus 修改状态
bool updated = engine.updatePlanStatus(plan.id, PlanStatus::Completed);
EXPECT_TRUE(updated);
// 再次查找,验证状态已更新
found = engine.findPlanById(plan.id);
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->status, PlanStatus::Completed);
}