task_auto_plan_execute_project/tests/basic_test.cpp

285 lines
8.3 KiB
C++

/**
* @file basic_test.cpp
* @brief C2SYS 系统基础单元测试。
*
* 使用标准库 assert 对核心数据结构和业务功能进行验证。
* 不依赖 GoogleTest 等外部测试框架。
*/
#include "app.hpp"
#include "config.hpp"
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
using namespace c2sys;
/**
* @brief 测试数据实体构造与字段访问。
*/
static void testDataEntities() {
std::cout << " [测试] 数据实体构造 ... ";
// PlanData
PlanData plan;
plan.id = "PLAN-TEST-001";
plan.type = PlanType::Centralized;
plan.resourceUsage = 50.0;
plan.executionPeriod = 100.0;
plan.successRate = 0.9;
plan.survivability = 0.8;
plan.collaborationEfficiency = 0.85;
plan.subTaskIds = {"ST-A", "ST-B"};
plan.createTimestamp = 1715000000000LL;
assert(plan.id == "PLAN-TEST-001");
assert(plan.type == PlanType::Centralized);
assert(plan.resourceUsage == 50.0);
assert(plan.executionPeriod == 100.0);
assert(plan.successRate == 0.9);
assert(plan.survivability == 0.8);
assert(plan.collaborationEfficiency == 0.85);
assert(plan.subTaskIds.size() == 2);
assert(plan.subTaskIds[0] == "ST-A");
std::cout << "PlanData OK\n";
// EventRaw
EventRaw raw;
raw.sourceId = "RADAR-001";
raw.timestamp = 1715000300000LL;
raw.threatLevel = 4;
raw.payloadHash = "abc123";
raw.protocolType = "LINK16";
raw.payload = "test_payload";
assert(raw.sourceId == "RADAR-001");
assert(raw.threatLevel == 4);
assert(raw.protocolType == "LINK16");
std::cout << " [测试] 数据实体构造 ... EventRaw OK\n";
// StandardEvent
StandardEvent evt;
evt.id = "EVT-001";
evt.type = EventType::Contingency;
evt.status = EventStatus::Pending;
evt.metadata["key1"] = "val1";
assert(evt.id == "EVT-001");
assert(evt.type == EventType::Contingency);
assert(evt.status == EventStatus::Pending);
assert(evt.metadata.at("key1") == "val1");
std::cout << " [测试] 数据实体构造 ... StandardEvent OK\n";
// TaskTemplate
TaskTemplate tmpl;
tmpl.id = "TMPL-001";
tmpl.version = "1.0";
tmpl.applicableScenario = "threat_4";
tmpl.matchScore = 0.91;
assert(tmpl.id == "TMPL-001");
assert(tmpl.matchScore == 0.91);
std::cout << " [测试] 数据实体构造 ... TaskTemplate OK\n";
// ExecutionStatus
ExecutionStatus st;
st.taskId = "TASK-001";
st.currentPhase = "EXECUTING";
st.completionPercent = 50.0;
st.errorCode = 0;
assert(st.taskId == "TASK-001");
assert(st.completionPercent == 50.0);
assert(st.errorCode == 0);
std::cout << " [测试] 数据实体构造 ... ExecutionStatus OK\n";
// DistributionAck
DistributionAck ack;
ack.nodeId = "NODE-A";
ack.status = AckStatus::Confirmed;
ack.retryCount = 0;
assert(ack.nodeId == "NODE-A");
assert(ack.status == AckStatus::Confirmed);
std::cout << " [测试] 数据实体构造 ... DistributionAck OK\n";
std::cout << " [测试] 数据实体构造 ... 全部通过 ✓\n";
}
/**
* @brief 测试 App 核心业务功能。
*/
static void testAppCoreFunctions() {
std::cout << " [测试] App 核心功能 ... ";
App app;
// 初始化
bool initOk = app.initialize("");
assert(initOk);
assert(app.getState() == SystemState::Ready);
std::cout << "\n 初始化 OK\n";
// 模式切换
bool modeOk = app.setRunMode(RunMode::Autonomous);
assert(modeOk);
assert(app.getRunMode() == RunMode::Autonomous);
std::cout << " 模式切换 OK\n";
// 添加方案
PlanData plan;
plan.id = "PLAN-TEST";
plan.type = PlanType::Centralized;
plan.resourceUsage = 50.0;
plan.executionPeriod = 100.0;
plan.successRate = 0.9;
bool addOk = app.addPlan(plan);
assert(addOk);
assert(app.getAllPlans().size() == 1);
// 重复添加应失败
bool dupOk = app.addPlan(plan);
assert(!dupOk);
std::cout << " 方案管理 OK\n";
// 查找方案
const auto* found = app.findPlanById("PLAN-TEST");
assert(found != nullptr);
assert(found->resourceUsage == 50.0);
const auto* notFound = app.findPlanById("NONEXIST");
assert(notFound == nullptr);
std::cout << " 方案查询 OK\n";
// 事件处理
EventRaw raw;
raw.sourceId = "RADAR-TEST";
raw.timestamp = 1715000000000LL;
raw.threatLevel = 4;
raw.payloadHash = "hash123";
raw.protocolType = "TEST";
raw.payload = "test_data";
std::string evtId = app.ingestRawEvent(raw);
assert(!evtId.empty());
auto pending = app.getPendingEvents();
assert(pending.size() >= 1);
bool procOk = app.processEvent(evtId, true);
assert(procOk);
auto pendingAfter = app.getPendingEvents();
// 处理后待办应减少(或为空)
std::cout << " 事件处理 OK\n";
// 任务生成
std::string taskId = app.generateTaskFromEvent(evtId);
assert(!taskId.empty());
const auto* taskStatus = app.getExecutionStatus(taskId);
assert(taskStatus != nullptr);
assert(taskStatus->currentPhase == "INIT");
std::cout << " 任务生成 OK\n";
// 模板管理
TaskTemplate tmpl;
tmpl.id = "TMPL-TEST";
tmpl.version = "1.0";
tmpl.applicableScenario = "threat_4";
tmpl.matchScore = 0.95;
bool tmplOk = app.addTemplate(tmpl);
assert(tmplOk);
const auto* matched = app.matchBestTemplate("threat_4");
assert(matched != nullptr);
assert(matched->id == "TMPL-TEST");
std::cout << " 模板管理 OK\n";
// 快照管理
std::string snapVer = app.saveSnapshot();
assert(!snapVer.empty());
bool rollbackOk = app.rollbackToSnapshot(snapVer);
assert(rollbackOk);
std::cout << " 快照管理 OK\n";
// 方案分发
std::vector<std::string> nodes = {"NODE-X", "NODE-Y"};
int success = app.dispatchPlan("PLAN-TEST", nodes);
assert(success >= 0 && success <= 2);
auto acks = app.getDistributionAcks();
assert(acks.size() >= 1);
std::cout << " 分发监控 OK\n";
// 执行状态上报
ExecutionStatus status;
status.taskId = taskId;
status.currentPhase = "COMPLETED";
status.completionPercent = 100.0;
status.errorCode = 0;
app.reportExecutionStatus(status);
const auto* updatedStatus = app.getExecutionStatus(taskId);
assert(updatedStatus != nullptr);
assert(updatedStatus->completionPercent == 100.0);
std::cout << " 状态监控 OK\n";
// 操作日志
OperationLog log{"TEST-OP", 1715000000000LL, "TEST", "OBJ-001", "OK"};
app.logOperation(log);
assert(app.getOperationLogs().size() >= 1);
std::cout << " 操作日志 OK\n";
// 启动/停止
bool startOk = app.start();
assert(startOk);
assert(app.getState() == SystemState::Running);
app.stop();
assert(app.getState() == SystemState::Stopped);
std::cout << " 生命周期管理 OK\n";
std::cout << " [测试] App 核心功能 ... 全部通过 ✓\n";
}
/**
* @brief 测试 SystemConfig 配置加载。
*/
static void testConfigLoading() {
std::cout << " [测试] 配置加载 ... ";
SystemConfig config;
// 默认值检查
assert(config.refreshIntervalMs == 50);
assert(config.websocketPort == 8080);
assert(config.maxRetryCount == 3);
assert(config.logLevel == 2);
// 尝试加载不存在的配置文件应失败但不影响默认值
bool loaded = config.loadFromFile("nonexistent_config.txt");
assert(!loaded);
assert(config.refreshIntervalMs == 50);
std::cout << "默认配置 OK, 文件不存在时回退 OK\n";
std::cout << " [测试] 配置加载 ... 通过 ✓\n";
}
/**
* @brief 主测试函数入口。
*/
int main() {
std::cout << "\n╔══════════════════════════════════════════════════════╗\n";
std::cout << "║ C2SYS 系统单元测试 (基于 assert) ║\n";
std::cout << "╚══════════════════════════════════════════════════════╝\n\n";
testDataEntities();
std::cout << "\n";
testConfigLoading();
std::cout << "\n";
testAppCoreFunctions();
std::cout << "\n✅ 所有单元测试通过!\n";
return 0;
}