task_plan_execute_2/tests/basic_test.cpp

227 lines
6.8 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.

/**
* @file basic_test.cpp
* @brief TPS 核心模块单元测试(使用标准库 assert无外部依赖
*/
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
#include "event_handler.hpp"
#include "template_manager.hpp"
#include "plan_manager.hpp"
#include "distribution_monitor.hpp"
/**
* @brief 测试事件接收与处理模块。
*
* @requirement(name="接收临机事件和规划事件", id="SRS-F-01-001")
* @requirement(name="事件数据过滤转化封装", id="SRS-F-01-002")
* @requirement(name="接收待处理事件列表", id="SRS-F-02-001")
*/
void test_event_handler() {
std::cout << "[测试] EventHandler ... ";
EventHandler handler;
// SRS-F-01-001: 接收 JSON 事件
bool r1 = handler.receiveEvent(R"({"type":""})", "json");
assert(r1 == true);
// SRS-F-01-001: 接收 XML 事件
bool r2 = handler.receiveEvent(R"(<event/>)", "xml");
assert(r2 == true);
// 无效格式应返回 false
bool r3 = handler.receiveEvent("data", "yaml");
assert(r3 == false);
// 空数据应返回 false
bool r4 = handler.receiveEvent("", "json");
assert(r4 == false);
// SRS-F-01-002: 验证标准化处理后的数据有元数据
auto allEvents = handler.getAllEvents();
assert(!allEvents.empty());
// SRS-F-02-001: 待处理事件列表不应为空
auto pending = handler.getPendingEvents();
assert(!pending.empty());
// 标准化事件应包含处理节点ID
for (const auto& evt : pending) {
assert(!evt.node_id.empty());
assert(!evt.receive_time.empty());
}
std::cout << "通过\n";
}
/**
* @brief 测试模板管理模块。
*
* @requirement(name="接收推送的任务模板集合数据", id="SRS-F-04-001")
* @requirement(name="任务模板先验知识库版本选择", id="SRS-F-03-001")
* @requirement(name="先验知识库配置调整", id="SRS-F-03-002")
* @requirement(name="自主执行模式下任务模板自动选择提示", id="SRS-F-04-006")
* @requirement(name="人环模式下用户选择任务模板", id="SRS-F-04-005")
*/
void test_template_manager() {
std::cout << "[测试] TemplateManager ... ";
TemplateManager mgr;
// SRS-F-04-001: 接收模板数据
bool ok = mgr.receiveTemplates(R"({"name":""})", "json");
assert(ok == true);
// 模板列表应有数据
auto list = mgr.getTemplateList();
assert(!list.empty());
// SRS-F-03-001: 获取版本列表
auto versions = mgr.getConfig(list[0].template_id);
assert(!versions.empty());
assert(versions[0].status == "有效");
// SRS-F-03-002: 更新配置
bool cfgOk = mgr.updateConfig("timeout", "30");
assert(cfgOk == true);
// 空 key 应失败
bool cfgFail = mgr.updateConfig("", "30");
assert(cfgFail == false);
// SRS-F-04-006: 自主推荐
std::string rec = mgr.autoSelectTemplate("打击");
assert(!rec.empty());
// SRS-F-04-005: 人环选择
bool selOk = mgr.selectTemplate(list[0].template_id, "v1.0.0");
assert(selOk == true);
// 不存在的模板应失败
bool selFail = mgr.selectTemplate("NONEXIST", "v1.0.0");
assert(selFail == false);
std::cout << "通过\n";
}
/**
* @brief 测试计划管理模块。
*
* @requirement(name="生成作战任务并送交处理", id="SRS-F-02-004")
* @requirement(name="集中式计划管理与偏好排序", id="SRS-F-05-001")
* @requirement(name="计划详情可视化与HITL通知", id="SRS-F-05-002")
* @requirement(name="计划重配置操作与可视化", id="SRS-F-05-003")
* @requirement(name="分布式计划管理与算法处理", id="SRS-F-05-004")
*/
void test_plan_manager() {
std::cout << "[测试] PlanManager ... ";
PlanManager mgr;
// SRS-F-02-004: 创建计划(至少需要一个事件)
std::vector<std::string> evtIds = {"EVT-001", "EVT-002"};
std::string planId = mgr.createPlan("测试计划", evtIds, "TPL-001");
assert(!planId.empty());
// 空事件列表应失败
std::string failPlan = mgr.createPlan("空计划", {}, "TPL-001");
assert(failPlan.empty());
// SRS-F-05-001: 加权排序
auto sorted = mgr.sortPlans(0.8, 0.2);
assert(!sorted.empty());
// SRS-F-05-002: HITL通知
bool hitlOk = mgr.notifyHITL(planId, "NODE-HITL-01", "admin");
assert(hitlOk == true);
// SRS-F-05-003: 计划重配置
std::vector<PlanNode> newNodes;
PlanNode node;
node.node_id = "NODE-01";
node.type = "任务";
node.content = "侦察";
node.order_index = 1;
node.status = "待执行";
newNodes.push_back(node);
std::string reconfId = mgr.reconfigurePlan(planId, newNodes);
assert(!reconfId.empty());
assert(reconfId != planId); // 应是新ID
// SRS-F-05-004: 一致性检查
std::vector<TaskPlan> external;
TaskPlan ext;
ext.plan_id = "EXT-001";
ext.name = "外部计划";
ext.status = "草案";
external.push_back(ext);
bool consistent = mgr.mergeAndCheckConsistency(external);
assert(consistent == true);
// 重复ID应导致冲突
external.push_back(ext); // 相同的 ext.plan_id
bool conflict = mgr.mergeAndCheckConsistency(external);
assert(conflict == false);
std::cout << "通过\n";
}
/**
* @brief 测试方案分发与状态监控模块。
*
* @requirement(name="方案驱动分发与状态响应", id="SRS-F-06-001")
* @requirement(name="驱动状态监控与异常信息展示", id="SRS-F-06-002")
*/
void test_distribution_monitor() {
std::cout << "[测试] DistributionMonitor ... ";
DistributionMonitor mon;
// SRS-F-06-001: 分发方案
DistributionLog dlog = mon.distributePlan("PLAN-001", "无人机");
assert(dlog.log_id > 0);
assert(dlog.plan_id == "PLAN-001");
assert(dlog.asset_type == "无人机");
// 接收 ACK
mon.receiveAck(dlog.log_id, "ACK");
auto logs = mon.getDistributionLogs();
assert(!logs.empty());
assert(logs.back().ack_code == "ACK");
// SRS-F-06-002: 接收正常遥测
StatusLog slog = mon.receiveTelemetry("正常数据包", "数据链-01");
assert(slog.status_code == "OK");
// SRS-F-06-002: 接收异常遥测(应触发报警)
StatusLog errLog = mon.receiveTelemetry("ERROR: 传感器故障", "数据链-02");
assert(errLog.status_code != "OK");
// 报警触发
bool alarm = mon.triggerAlarm("ERROR_01");
assert(alarm == true);
// "OK" 不应触发报警
bool noAlarm = mon.triggerAlarm("OK");
assert(noAlarm == false);
std::cout << "通过\n";
}
/**
* @brief 主测试入口。
*/
int main() {
std::cout << "=== TPS 核心模块单元测试 ===\n\n";
test_event_handler();
test_template_manager();
test_plan_manager();
test_distribution_monitor();
std::cout << "\n所有测试通过!\n";
return 0;
}