227 lines
6.8 KiB
C++
227 lines
6.8 KiB
C++
/**
|
||
* @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;
|
||
}
|