plan_execute_t1/tests/test_cms_engine.cpp

366 lines
13 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "app.hpp"
#include <string>
#include <vector>
#include <chrono>
using namespace testing;
// ============================================================================
// CmsEngine 测试套件
// ============================================================================
class CmsEngineTest : public Test {
protected:
CmsEngine engine;
void SetUp() override {
// 每个测试用例开始前重置引擎状态
}
void TearDown() override {
// 每个测试用例结束后清理
}
// 辅助函数:创建一个有效的事件记录(根据实际 EventRecord 结构定义)
EventRecord createValidEvent(const std::string& id = "EVT-001",
uint32_t priority = 100,
EventStatus status = EventStatus::Pending) {
EventRecord event;
event.id = id;
event.priority = priority;
event.status = status;
// 注意根据编译错误EventRecord 没有 timestamp, source, type 成员
// 因此这里只设置实际存在的成员
return event;
}
// 辅助函数:创建多个事件并接入
void ingestMultipleEvents(size_t count) {
for (size_t i = 0; i < count; ++i) {
EventRecord event = createValidEvent("EVT-" + std::to_string(i + 1), 100);
engine.ingestEvent(event);
}
}
};
// ============================================================================
// CmsEngine 构造函数测试
// ============================================================================
TEST_F(CmsEngineTest, testCmsEngineDefaultConstructor) {
// 正常输入测试:验证默认构造函数正确初始化
const auto& context = engine.getSystemContext();
EXPECT_EQ(context.currentMode, RunMode::Idle);
EXPECT_EQ(context.consistencyMark, 0);
EXPECT_EQ(context.contextSnapshot, R"({"mode":"Idle","version":"1.0.0"})");
// 验证初始状态为空
EXPECT_EQ(engine.getAllPlans().size(), 0);
EXPECT_EQ(engine.getSummary().find("Events : 0") != std::string::npos, true);
}
TEST_F(CmsEngineTest, testCmsEngineMultipleInstances) {
// 正常输入测试:多个实例独立运行
CmsEngine engine1;
CmsEngine engine2;
// 向 engine1 添加事件
EventRecord event1 = createValidEvent("EVT-001", 100);
engine1.ingestEvent(event1);
// 验证 engine2 不受影响
EXPECT_EQ(engine2.getSummary().find("Events : 0") != std::string::npos, true);
EXPECT_EQ(engine1.getSummary().find("Events : 1") != std::string::npos, true);
}
TEST_F(CmsEngineTest, testCmsEngineConstructorIdGeneration) {
// 特殊场景测试:验证构造函数后 ID 生成器从 0 开始
// 通过 processPendingEvents 间接验证 ID 生成
EventRecord event = createValidEvent("EVT-001", 100, EventStatus::Pending);
engine.ingestEvent(event);
size_t processed = engine.processPendingEvents();
EXPECT_EQ(processed, 1);
const auto& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 1);
EXPECT_EQ(plans[0].id, "ID-00001");
}
// ============================================================================
// ingestEvent 函数测试
// ============================================================================
TEST_F(CmsEngineTest, testIngestEventValidEvent) {
// 正常输入测试:接入有效事件
EventRecord event = createValidEvent("EVT-001", 100);
bool result = engine.ingestEvent(event);
EXPECT_TRUE(result);
// 验证事件已存储
const EventRecord* found = engine.findEventById("EVT-001");
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->priority, 100);
EXPECT_EQ(found->status, EventStatus::Pending);
}
TEST_F(CmsEngineTest, testIngestEventEmptyId) {
// 边界值测试:空 ID 事件
EventRecord event = createValidEvent("", 100);
bool result = engine.ingestEvent(event);
EXPECT_FALSE(result);
// 验证事件未被存储
EXPECT_EQ(engine.findEventById(""), nullptr);
}
TEST_F(CmsEngineTest, testIngestEventMaxPriority) {
// 边界值测试最大优先级255
EventRecord event = createValidEvent("EVT-001", 255);
bool result = engine.ingestEvent(event);
EXPECT_TRUE(result);
const EventRecord* found = engine.findEventById("EVT-001");
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->priority, 255);
}
TEST_F(CmsEngineTest, testIngestEventExceedMaxPriority) {
// 异常输入测试:超过最大优先级
EventRecord event = createValidEvent("EVT-001", 256);
bool result = engine.ingestEvent(event);
EXPECT_FALSE(result);
// 验证事件未被存储
EXPECT_EQ(engine.findEventById("EVT-001"), nullptr);
}
TEST_F(CmsEngineTest, testIngestEventZeroPriority) {
// 边界值测试:零优先级
EventRecord event = createValidEvent("EVT-001", 0);
bool result = engine.ingestEvent(event);
EXPECT_TRUE(result);
const EventRecord* found = engine.findEventById("EVT-001");
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->priority, 0);
}
TEST_F(CmsEngineTest, testIngestEventMultipleEvents) {
// 正常输入测试:接入多个事件
ingestMultipleEvents(5);
for (size_t i = 0; i < 5; ++i) {
std::string id = "EVT-" + std::to_string(i + 1);
const EventRecord* found = engine.findEventById(id);
ASSERT_NE(found, nullptr) << "Event " << id << " not found";
EXPECT_EQ(found->priority, 100);
}
}
TEST_F(CmsEngineTest, testIngestEventDuplicateId) {
// 特殊场景测试:重复 ID 的事件
EventRecord event1 = createValidEvent("EVT-001", 100);
EventRecord event2 = createValidEvent("EVT-001", 200);
EXPECT_TRUE(engine.ingestEvent(event1));
EXPECT_TRUE(engine.ingestEvent(event2)); // 允许重复 ID
// 验证两个事件都被存储
const EventRecord* found = engine.findEventById("EVT-001");
ASSERT_NE(found, nullptr);
// findEventById 返回第一个匹配的事件
EXPECT_EQ(found->priority, 100);
}
TEST_F(CmsEngineTest, testIngestEventSpecialCharacters) {
// 边界值测试:特殊字符 ID
EventRecord event = createValidEvent("EVT-@#$%^&*()", 100);
bool result = engine.ingestEvent(event);
EXPECT_TRUE(result);
const EventRecord* found = engine.findEventById("EVT-@#$%^&*()");
ASSERT_NE(found, nullptr);
}
TEST_F(CmsEngineTest, testIngestEventVeryLongId) {
// 边界值测试:超长 ID
std::string longId(1000, 'A');
EventRecord event = createValidEvent(longId, 100);
bool result = engine.ingestEvent(event);
EXPECT_TRUE(result);
const EventRecord* found = engine.findEventById(longId);
ASSERT_NE(found, nullptr);
}
// ============================================================================
// processPendingEvents 函数测试
// ============================================================================
TEST_F(CmsEngineTest, testProcessPendingEventsNoEvents) {
// 边界值测试:无事件
size_t processed = engine.processPendingEvents();
EXPECT_EQ(processed, 0);
// 验证没有生成方案
EXPECT_EQ(engine.getAllPlans().size(), 0);
}
TEST_F(CmsEngineTest, testProcessPendingEventsSingleEvent) {
// 正常输入测试:处理单个待处理事件
EventRecord event = createValidEvent("EVT-001", 100, EventStatus::Pending);
engine.ingestEvent(event);
size_t processed = engine.processPendingEvents();
EXPECT_EQ(processed, 1);
// 验证事件状态已更新
const EventRecord* found = engine.findEventById("EVT-001");
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->status, EventStatus::Generated);
// 验证生成了对应的方案
const auto& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 1);
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_EQ(plans[0].resourceQuota, 0.5);
EXPECT_EQ(plans[0].constraints, "自动生成约束");
}
TEST_F(CmsEngineTest, testProcessPendingEventsMultipleEvents) {
// 正常输入测试:处理多个待处理事件
ingestMultipleEvents(5);
size_t processed = engine.processPendingEvents();
EXPECT_EQ(processed, 5);
// 验证所有事件状态已更新
for (size_t i = 0; i < 5; ++i) {
std::string id = "EVT-" + std::to_string(i + 1);
const EventRecord* found = engine.findEventById(id);
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->status, EventStatus::Generated);
}
// 验证生成了对应的方案
const auto& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 5);
for (size_t i = 0; i < 5; ++i) {
EXPECT_EQ(plans[i].name, "AutoPlan-EVT-" + std::to_string(i + 1));
EXPECT_EQ(plans[i].relatedEventId, "EVT-" + std::to_string(i + 1));
}
}
TEST_F(CmsEngineTest, testProcessPendingEventsMixedStatus) {
// 特殊场景测试:混合状态的事件
EventRecord pendingEvent1 = createValidEvent("EVT-001", 100, EventStatus::Pending);
EventRecord generatedEvent = createValidEvent("EVT-002", 100, EventStatus::Generated);
EventRecord pendingEvent2 = createValidEvent("EVT-003", 100, EventStatus::Pending);
engine.ingestEvent(pendingEvent1);
engine.ingestEvent(generatedEvent);
engine.ingestEvent(pendingEvent2);
size_t processed = engine.processPendingEvents();
EXPECT_EQ(processed, 2); // 只处理 Pending 状态的事件
// 验证 Pending 事件已处理
const EventRecord* found1 = engine.findEventById("EVT-001");
ASSERT_NE(found1, nullptr);
EXPECT_EQ(found1->status, EventStatus::Generated);
const EventRecord* found3 = engine.findEventById("EVT-003");
ASSERT_NE(found3, nullptr);
EXPECT_EQ(found3->status, EventStatus::Generated);
// 验证 Generated 事件未改变
const EventRecord* found2 = engine.findEventById("EVT-002");
ASSERT_NE(found2, nullptr);
EXPECT_EQ(found2->status, EventStatus::Generated);
// 验证生成了 2 个方案
EXPECT_EQ(engine.getAllPlans().size(), 2);
}
TEST_F(CmsEngineTest, testProcessPendingEventsIdGeneration) {
// 特殊场景测试:验证 ID 生成顺序
EventRecord event1 = createValidEvent("EVT-001", 100, EventStatus::Pending);
EventRecord event2 = createValidEvent("EVT-002", 100, EventStatus::Pending);
engine.ingestEvent(event1);
engine.ingestEvent(event2);
engine.processPendingEvents();
const auto& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 2);
EXPECT_EQ(plans[0].id, "ID-00001");
EXPECT_EQ(plans[1].id, "ID-00002");
}
TEST_F(CmsEngineTest, testProcessPendingEventsMultipleCalls) {
// 特殊场景测试:多次调用 processPendingEvents
EventRecord event1 = createValidEvent("EVT-001", 100, EventStatus::Pending);
engine.ingestEvent(event1);
// 第一次调用
size_t processed1 = engine.processPendingEvents();
EXPECT_EQ(processed1, 1);
// 第二次调用,没有新的 Pending 事件
size_t processed2 = engine.processPendingEvents();
EXPECT_EQ(processed2, 0);
// 验证方案数量不变
EXPECT_EQ(engine.getAllPlans().size(), 1);
}
TEST_F(CmsEngineTest, testProcessPendingEventsLargeNumberOfEvents) {
// 边界值测试:大量事件
const size_t NUM_EVENTS = 1000;
for (size_t i = 0; i < NUM_EVENTS; ++i) {
EventRecord event = createValidEvent("EVT-" + std::to_string(i + 1), 100, EventStatus::Pending);
engine.ingestEvent(event);
}
size_t processed = engine.processPendingEvents();
EXPECT_EQ(processed, NUM_EVENTS);
// 验证所有事件已处理
for (size_t i = 0; i < NUM_EVENTS; ++i) {
std::string id = "EVT-" + std::to_string(i + 1);
const EventRecord* found = engine.findEventById(id);
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->status, EventStatus::Generated);
}
// 验证生成了对应数量的方案
EXPECT_EQ(engine.getAllPlans().size(), NUM_EVENTS);
}
TEST_F(CmsEngineTest, testProcessPendingEventsPlanProperties) {
// 正常输入测试:验证生成的方案属性
EventRecord event = createValidEvent("EVT-001", 100, EventStatus::Pending);
engine.ingestEvent(event);
engine.processPendingEvents();
const auto& plans = engine.getAllPlans();
ASSERT_EQ(plans.size(), 1);
// 验证方案时间戳不为空
auto now = std::chrono::system_clock::now();
auto timeDiff = std::chrono::duration_cast<std::chrono::seconds>(
now - plans[0].createTime).count();
EXPECT_LT(timeDiff, 5); // 时间差小于 5 秒
// 验证方案 ID 格式
EXPECT_THAT(plans[0].id, testing::MatchesRegex("ID-\\d{5}"));
}