task_plan/tests/basic_test.cpp

250 lines
8.8 KiB
C++
Raw Permalink Normal View History

2026-05-20 08:00:11 +00:00
/// @file basic_test.cpp
/// @brief ETMS 核心模块单元测试(使用标准库 assert无外部依赖
#include "app.hpp"
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
/// @brief 测试事件状态枚举与字符串转换。
static void test_EventStatusToString() {
std::cout << " [test] EventStatusToString ... ";
assert(std::string(etms::EventStatusToString(etms::EventStatus::Received)) == "Received");
assert(std::string(etms::EventStatusToString(etms::EventStatus::Processed)) == "Processed");
assert(std::string(etms::EventStatusToString(etms::EventStatus::PendingTask)) == "Pending Task");
assert(std::string(etms::EventStatusToString(etms::EventStatus::Rejected)) == "Rejected");
assert(std::string(etms::EventStatusToString(etms::EventStatus::TaskGenerated)) == "Task Generated");
std::cout << "PASSED\n";
}
/// @brief 测试接收原始事件(正常情况)。
static void test_ReceiveRawEvent_Valid() {
std::cout << " [test] ReceiveRawEvent (valid JSON) ... ";
const std::string json = R"({"event_id":"EVT-TEST-001","event_type":""})";
auto ack = etms::ReceiveRawEvent(json);
assert(ack.accepted == true);
assert(ack.event_id == "EVT-TEST-001");
assert(!ack.message.empty());
std::cout << "PASSED\n";
}
/// @brief 测试接收原始事件(空载荷应拒绝)。
static void test_ReceiveRawEvent_Empty() {
std::cout << " [test] ReceiveRawEvent (empty) ... ";
auto ack = etms::ReceiveRawEvent("");
assert(ack.accepted == false);
assert(ack.event_id.empty());
std::cout << "PASSED\n";
}
/// @brief 测试接收原始事件(缺少 event_id 应拒绝)。
static void test_ReceiveRawEvent_MissingId() {
std::cout << " [test] ReceiveRawEvent (missing event_id) ... ";
const std::string json = R"({"event_type":""})";
auto ack = etms::ReceiveRawEvent(json);
assert(ack.accepted == false);
std::cout << "PASSED\n";
}
/// @brief 测试处理事件:状态从 Received → Processed。
static void test_ProcessEvent() {
std::cout << " [test] ProcessEvent ... ";
etms::Event evt;
evt.event_id = "EVT-PROC-001";
evt.status = etms::EventStatus::Received;
bool ok = etms::ProcessEvent(evt);
assert(ok == true);
assert(evt.status == etms::EventStatus::Processed);
std::cout << "PASSED\n";
}
/// @brief 测试处理事件:非 Received 状态不应被处理。
static void test_ProcessEvent_WrongStatus() {
std::cout << " [test] ProcessEvent (wrong status) ... ";
etms::Event evt;
evt.status = etms::EventStatus::TaskGenerated;
bool ok = etms::ProcessEvent(evt);
assert(ok == false);
assert(evt.status == etms::EventStatus::TaskGenerated);
std::cout << "PASSED\n";
}
/// @brief 测试事件查询返回非空列表。
static void test_QueryAllEvents() {
std::cout << " [test] QueryAllEvents ... ";
auto events = etms::QueryAllEvents();
assert(!events.empty());
// 默认应倒序create_time 递减)
for (size_t i = 1; i < events.size(); ++i) {
assert(events[i - 1].create_time >= events[i].create_time);
}
std::cout << "PASSED (" << events.size() << " events)\n";
}
/// @brief 测试紧迫事件筛选。
static void test_FilterUrgentEvents() {
std::cout << " [test] FilterUrgentEvents ... ";
auto events = etms::QueryAllEvents();
auto urgent = etms::FilterUrgentEvents(events);
for (const auto& e : urgent) {
assert(e.level >= 8);
}
assert(!urgent.empty());
std::cout << "PASSED (" << urgent.size() << " urgent)\n";
}
/// @brief 测试模板推荐(匹配类型应返回对应模板 ID
static void test_RecommendTemplate() {
std::cout << " [test] RecommendTemplate ... ";
auto templates = etms::GetAvailableTemplates();
etms::Event recon_evt;
recon_evt.event_type = "侦察";
auto id1 = etms::RecommendTemplate(recon_evt, templates);
assert(id1 == "TMPL-RECON-001");
etms::Event strike_evt;
strike_evt.event_type = "打击";
auto id2 = etms::RecommendTemplate(strike_evt, templates);
assert(id2 == "TMPL-STRIKE-001");
// 不匹配类型时应返回兜底(第一个模板)
etms::Event unknown_evt;
unknown_evt.event_type = "未知";
auto id3 = etms::RecommendTemplate(unknown_evt, templates);
assert(id3 == templates.front().template_id);
std::cout << "PASSED\n";
}
/// @brief 测试空模板列表时的推荐行为。
static void test_RecommendTemplate_EmptyTemplates() {
std::cout << " [test] RecommendTemplate (empty list) ... ";
std::vector<etms::TaskTemplate> empty;
etms::Event evt;
evt.event_type = "侦察";
auto id = etms::RecommendTemplate(evt, empty);
assert(id.empty());
std::cout << "PASSED\n";
}
/// @brief 测试任务请求组装。
static void test_BuildTaskRequest() {
std::cout << " [test] BuildTaskRequest ... ";
std::map<std::string, std::string> params = {{"key1", "val1"}, {"key2", "val2"}};
auto req = etms::BuildTaskRequest("EVT-REQ-001", "TMPL-001", "KB-V1.0", params);
assert(req.request_id.find("REQ-") == 0);
assert(req.event_id == "EVT-REQ-001");
assert(req.template_id == "TMPL-001");
assert(req.kb_version_id == "KB-V1.0");
assert(req.params.size() == 2);
assert(req.request_time > 0);
std::cout << "PASSED\n";
}
/// @brief 测试知识库版本查询。
static void test_GetAvailableKbVersions() {
std::cout << " [test] GetAvailableKbVersions ... ";
auto versions = etms::GetAvailableKbVersions();
assert(!versions.empty());
bool has_active = false;
for (const auto& v : versions) {
if (v.status == "Active") has_active = true;
}
assert(has_active);
std::cout << "PASSED (" << versions.size() << " versions)\n";
}
/// @brief 测试模板查询。
static void test_GetAvailableTemplates() {
std::cout << " [test] GetAvailableTemplates ... ";
auto templates = etms::GetAvailableTemplates();
assert(!templates.empty());
for (const auto& t : templates) {
assert(!t.template_id.empty());
assert(!t.name.empty());
}
std::cout << "PASSED (" << templates.size() << " templates)\n";
}
/// @brief 测试事件状态推进机。
static void test_AdvanceEventStatus() {
std::cout << " [test] AdvanceEventStatus ... ";
etms::Event evt;
evt.status = etms::EventStatus::Received;
// Received → Processed
assert(etms::AdvanceEventStatus(evt) == true);
assert(evt.status == etms::EventStatus::Processed);
// Processed → PendingTask
assert(etms::AdvanceEventStatus(evt) == true);
assert(evt.status == etms::EventStatus::PendingTask);
// PendingTask → TaskGenerated
assert(etms::AdvanceEventStatus(evt) == true);
assert(evt.status == etms::EventStatus::TaskGenerated);
// TaskGenerated → 不可再推进
assert(etms::AdvanceEventStatus(evt) == false);
assert(evt.status == etms::EventStatus::TaskGenerated);
std::cout << "PASSED\n";
}
/// @brief 测试 Rejected 状态不可推进。
static void test_AdvanceEventStatus_Rejected() {
std::cout << " [test] AdvanceEventStatus (Rejected) ... ";
etms::Event evt;
evt.status = etms::EventStatus::Rejected;
assert(etms::AdvanceEventStatus(evt) == false);
assert(evt.status == etms::EventStatus::Rejected);
std::cout << "PASSED\n";
}
/// @brief 测试排序函数(按等级降序)。
static void test_SortEventsByLevelDesc() {
std::cout << " [test] SortEventsByLevelDesc ... ";
auto events = etms::QueryAllEvents();
etms::SortEventsByLevelDesc(events);
for (size_t i = 1; i < events.size(); ++i) {
assert(events[i - 1].level >= events[i].level);
}
std::cout << "PASSED\n";
}
/// @brief 测试排序函数(按时间升序)。
static void test_SortEventsByTimeAsc() {
std::cout << " [test] SortEventsByTimeAsc ... ";
auto events = etms::QueryAllEvents();
etms::SortEventsByTimeAsc(events);
for (size_t i = 1; i < events.size(); ++i) {
assert(events[i - 1].timestamp <= events[i].timestamp);
}
std::cout << "PASSED\n";
}
/// @brief 主测试入口。
int main() {
std::cout << "=== ETMS Basic Unit Tests ===\n\n";
test_EventStatusToString();
test_ReceiveRawEvent_Valid();
test_ReceiveRawEvent_Empty();
test_ReceiveRawEvent_MissingId();
test_ProcessEvent();
test_ProcessEvent_WrongStatus();
test_QueryAllEvents();
test_FilterUrgentEvents();
test_RecommendTemplate();
test_RecommendTemplate_EmptyTemplates();
test_BuildTaskRequest();
test_GetAvailableKbVersions();
test_GetAvailableTemplates();
test_AdvanceEventStatus();
test_AdvanceEventStatus_Rejected();
test_SortEventsByLevelDesc();
test_SortEventsByTimeAsc();
std::cout << "\n=== All " << 17 << " tests PASSED ===\n";
return 0;
}