plan_execute_t1/tests/test_app.cpp

349 lines
10 KiB
C++
Raw 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 <string>
#include <vector>
#include "app.hpp"
// ============================================================================
// Test Fixture for CmsEngine
// ============================================================================
class CmsEngineTest : public ::testing::Test {
protected:
void SetUp() override {
// 在每个测试用例之前创建一个新的 CmsEngine 实例
engine = new CmsEngine();
}
void TearDown() override {
delete engine;
}
CmsEngine* engine;
};
// ============================================================================
// Tests for ingestEvent
// ============================================================================
/**
* @brief 测试 ingestEvent 正常输入场景
*
* 验证一个有效的事件(非空 ID优先级 <= 255可以被成功接入。
*/
TEST_F(CmsEngineTest, testIngestEventNormal) {
EventRecord event;
event.id = "EVT-001";
event.priority = 100;
event.status = EventStatus::Pending;
bool result = engine->ingestEvent(event);
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 空 ID 场景
*
* 验证空 ID 的事件会被拒绝接入。
*/
TEST_F(CmsEngineTest, testIngestEventEmptyId) {
EventRecord event;
event.id = "";
event.priority = 100;
bool result = engine->ingestEvent(event);
EXPECT_FALSE(result);
// 验证事件未被存储
const EventRecord* found = engine->findEventById("");
EXPECT_EQ(found, nullptr);
}
/**
* @brief 测试 ingestEvent 优先级边界值场景
*
* 验证优先级为 0最小值和 255最大值的事件可以被接入。
*/
TEST_F(CmsEngineTest, testIngestEventPriorityBoundary) {
// 测试优先级为 0
EventRecord event1;
event1.id = "EVT-002";
event1.priority = 0;
EXPECT_TRUE(engine->ingestEvent(event1));
// 测试优先级为 255
EventRecord event2;
event2.id = "EVT-003";
event2.priority = 255;
EXPECT_TRUE(engine->ingestEvent(event2));
// 验证两个事件都已存储
EXPECT_NE(engine->findEventById("EVT-002"), nullptr);
EXPECT_NE(engine->findEventById("EVT-003"), nullptr);
}
/**
* @brief 测试 ingestEvent 优先级越界场景
*
* 验证优先级超过 255 的事件会被拒绝接入。
*/
TEST_F(CmsEngineTest, testIngestEventPriorityOverflow) {
EventRecord event;
event.id = "EVT-004";
event.priority = 256; // 超过最大值
bool result = engine->ingestEvent(event);
EXPECT_FALSE(result);
// 验证事件未被存储
const EventRecord* found = engine->findEventById("EVT-004");
EXPECT_EQ(found, nullptr);
}
/**
* @brief 测试 ingestEvent 优先级为负数场景
*
* 验证优先级为负数的事件可以被接入(因为负数小于 255
*/
TEST_F(CmsEngineTest, testIngestEventNegativePriority) {
EventRecord event;
event.id = "EVT-005";
event.priority = -1; // 负数,但小于 255
bool result = engine->ingestEvent(event);
EXPECT_TRUE(result);
// 验证事件已存储
const EventRecord* found = engine->findEventById("EVT-005");
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->priority, -1);
}
/**
* @brief 测试 ingestEvent 多次接入相同 ID 事件场景
*
* 验证相同 ID 的事件可以被多次接入(事件库允许重复 ID
*/
TEST_F(CmsEngineTest, testIngestEventDuplicateId) {
EventRecord event1;
event1.id = "EVT-006";
event1.priority = 50;
EXPECT_TRUE(engine->ingestEvent(event1));
EventRecord event2;
event2.id = "EVT-006"; // 相同 ID
event2.priority = 100;
EXPECT_TRUE(engine->ingestEvent(event2));
// 验证 findEventById 返回第一个匹配的事件
const EventRecord* found = engine->findEventById("EVT-006");
ASSERT_NE(found, nullptr);
EXPECT_EQ(found->priority, 50); // 返回第一个
}
// ============================================================================
// Tests for processPendingEvents
// ============================================================================
/**
* @brief 测试 processPendingEvents 正常处理场景
*
* 验证 Pending 状态的事件会被正确处理并生成 TaskPlan。
*/
TEST_F(CmsEngineTest, testProcessPendingEventsNormal) {
// 添加一个 Pending 事件
EventRecord event;
event.id = "EVT-010";
event.priority = 100;
event.status = EventStatus::Pending;
engine->ingestEvent(event);
size_t processed = engine->processPendingEvents();
EXPECT_EQ(processed, 1);
// 验证事件状态已更新为 Generated
const EventRecord* foundEvent = engine->findEventById("EVT-010");
ASSERT_NE(foundEvent, nullptr);
EXPECT_EQ(foundEvent->status, EventStatus::Generated);
// 验证生成了一个 TaskPlan
const auto& plans = engine->getAllPlans();
ASSERT_EQ(plans.size(), 1);
EXPECT_EQ(plans[0].name, "AutoPlan-EVT-010");
EXPECT_EQ(plans[0].type, PlanType::Centralized);
EXPECT_EQ(plans[0].status, PlanStatus::Drafting);
EXPECT_EQ(plans[0].relatedEventId, "EVT-010");
EXPECT_EQ(plans[0].resourceQuota, 0.5);
EXPECT_EQ(plans[0].constraints, "自动生成约束");
}
/**
* @brief 测试 processPendingEvents 无 Pending 事件场景
*
* 验证当没有 Pending 事件时,返回 0 且不生成 TaskPlan。
*/
TEST_F(CmsEngineTest, testProcessPendingEventsNoPending) {
// 添加一个非 Pending 事件
EventRecord event;
event.id = "EVT-011";
event.priority = 100;
event.status = EventStatus::Generated; // 不是 Pending
engine->ingestEvent(event);
size_t processed = engine->processPendingEvents();
EXPECT_EQ(processed, 0);
// 验证事件状态未改变
const EventRecord* foundEvent = engine->findEventById("EVT-011");
ASSERT_NE(foundEvent, nullptr);
EXPECT_EQ(foundEvent->status, EventStatus::Generated);
// 验证没有生成 TaskPlan
const auto& plans = engine->getAllPlans();
EXPECT_EQ(plans.size(), 0);
}
/**
* @brief 测试 processPendingEvents 多个 Pending 事件场景
*
* 验证多个 Pending 事件都会被处理并生成对应的 TaskPlan。
*/
TEST_F(CmsEngineTest, testProcessPendingEventsMultiple) {
// 添加三个 Pending 事件
for (int i = 0; i < 3; ++i) {
EventRecord event;
event.id = "EVT-0" + std::to_string(i + 1);
event.priority = 50 + i * 10;
event.status = EventStatus::Pending;
engine->ingestEvent(event);
}
size_t processed = engine->processPendingEvents();
EXPECT_EQ(processed, 3);
// 验证所有事件状态已更新
for (int i = 0; i < 3; ++i) {
std::string eventId = "EVT-0" + std::to_string(i + 1);
const EventRecord* foundEvent = engine->findEventById(eventId);
ASSERT_NE(foundEvent, nullptr);
EXPECT_EQ(foundEvent->status, EventStatus::Generated);
}
// 验证生成了三个 TaskPlan
const auto& plans = engine->getAllPlans();
ASSERT_EQ(plans.size(), 3);
for (int i = 0; i < 3; ++i) {
std::string eventId = "EVT-0" + std::to_string(i + 1);
EXPECT_EQ(plans[i].name, "AutoPlan-" + eventId);
EXPECT_EQ(plans[i].relatedEventId, eventId);
}
}
/**
* @brief 测试 processPendingEvents 混合状态事件场景
*
* 验证只有 Pending 状态的事件被处理,其他状态的事件被忽略。
*/
TEST_F(CmsEngineTest, testProcessPendingEventsMixedStatus) {
// 添加一个 Pending 事件
EventRecord pendingEvent;
pendingEvent.id = "EVT-020";
pendingEvent.priority = 100;
pendingEvent.status = EventStatus::Pending;
engine->ingestEvent(pendingEvent);
// 添加一个 Generated 事件
EventRecord generatedEvent;
generatedEvent.id = "EVT-021";
generatedEvent.priority = 100;
generatedEvent.status = EventStatus::Generated;
engine->ingestEvent(generatedEvent);
size_t processed = engine->processPendingEvents();
EXPECT_EQ(processed, 1);
// 验证只有 Pending 事件被处理
const EventRecord* foundPending = engine->findEventById("EVT-020");
ASSERT_NE(foundPending, nullptr);
EXPECT_EQ(foundPending->status, EventStatus::Generated);
const EventRecord* foundGenerated = engine->findEventById("EVT-021");
ASSERT_NE(foundGenerated, nullptr);
EXPECT_EQ(foundGenerated->status, EventStatus::Generated); // 未改变
// 验证只生成了一个 TaskPlan
const auto& plans = engine->getAllPlans();
ASSERT_EQ(plans.size(), 1);
EXPECT_EQ(plans[0].relatedEventId, "EVT-020");
}
/**
* @brief 测试 processPendingEvents 空事件库场景
*
* 验证当事件库为空时,返回 0 且不生成 TaskPlan。
*/
TEST_F(CmsEngineTest, testProcessPendingEventsEmpty) {
size_t processed = engine->processPendingEvents();
EXPECT_EQ(processed, 0);
const auto& plans = engine->getAllPlans();
EXPECT_EQ(plans.size(), 0);
}
/**
* @brief 测试 processPendingEvents 生成 ID 唯一性场景
*
* 验证每次生成的 TaskPlan ID 是唯一的。
*/
TEST_F(CmsEngineTest, testProcessPendingEventsUniqueIds) {
// 添加两个 Pending 事件
EventRecord event1;
event1.id = "EVT-030";
event1.priority = 100;
event1.status = EventStatus::Pending;
engine->ingestEvent(event1);
EventRecord event2;
event2.id = "EVT-031";
event2.priority = 100;
event2.status = EventStatus::Pending;
engine->ingestEvent(event2);
engine->processPendingEvents();
const auto& plans = engine->getAllPlans();
ASSERT_EQ(plans.size(), 2);
EXPECT_NE(plans[0].id, plans[1].id); // ID 必须唯一
}
/**
* @brief 测试 processPendingEvents 多次调用场景
*
* 验证多次调用 processPendingEvents 不会重复处理已处理的事件。
*/
TEST_F(CmsEngineTest, testProcessPendingEventsMultipleCalls) {
// 添加一个 Pending 事件
EventRecord event;
event.id = "EVT-040";
event.priority = 100;
event.status = EventStatus::Pending;
engine->ingestEvent(event);
// 第一次调用
size_t first = engine->processPendingEvents();
EXPECT_EQ(first, 1);
// 第二次调用(应该没有 Pending 事件了)
size_t second = engine->processPendingEvents();
EXPECT_EQ(second, 0);
// 验证只生成了一个 TaskPlan
const auto& plans = engine->getAllPlans();
ASSERT_EQ(plans.size(), 1);
}