eqpalg 测试说明文档
概述
eqpalg 测试采用轻量级自注册框架(test_harness.h),无 Boost.Test 依赖。测试入口为 test_main.cc,所有 TEST(name) 宏定义的用例通过静态构造函数自动注册。
构建与运行:
cd eqpalg/build
cmake .. -DCMAKE_BUILD_TYPE=Debug
make -j$(nproc)
cd test
./eqpalg_test
测试文件清单
| 文件 |
用例数 |
被测组件 |
test_expression_engine.cc |
14 |
ExpressionEngine — 表达式注册、求值、FunVars 重置 |
test_fb_state_machine.cc |
11 |
FbStateMachine — 7 状态反馈状态机 |
test_algorithms.cc |
52 |
BoundChecker + 算法核心逻辑 + Roller3/FaultCode 工具函数 |
总计:77 个测试用例
一、test_expression_engine.cc(14 用例)
测试 ExpressionEngine 的核心 API。
1.1 注册与求值(5 用例)
| 用例 |
验证内容 |
register_and_evaluate_simple_expression |
registerExpression 返回 0,evaluate 返回正确数值,evaluateBool 返回正确布尔值 |
register_duplicate_is_idempotent |
重复注册同名表达式是幂等操作,保留首次注册的表达式 |
evaluate_unregistered_returns_zero |
未注册表达式名求值返回 0.0 / false |
evaluate_zero_expression |
表达式 "0" 求值为 0.0,evaluateBool 为 false |
evaluate_boolean_true_constant |
表达式 "1" 的 evaluateBool 为 true |
1.2 变量变化(1 用例)
| 用例 |
验证内容 |
variable_change_reflected_in_evaluation |
修改 mm_vars 后 evaluate 立即反映新值 |
1.3 多表达式并存(1 用例)
| 用例 |
验证内容 |
multiple_expressions_independent |
3 个表达式独立求值,变量更新后各自正确反映 |
1.4 registerRawExpression(1 用例)
| 用例 |
验证内容 |
register_raw_no_funvars_processing |
registerRawExpression 跳过 FunVars 状态函数处理,直接编译原始表达式 |
1.5 FunVars 重置控制(3 用例)
| 用例 |
验证内容 |
autoReset_does_nothing_when_not_marked |
未标记时 autoResetFunVars 是 no-op |
mark_and_autoReset_sequence |
markFunVarsNeedReset + autoResetFunVars 联合工作,重置后标志清除 |
forceReset_works |
forceResetFunVars 立即执行,无延迟 |
1.6 复杂表达式(3 用例)
| 用例 |
验证内容 |
comparison_expression |
比较表达式 "tag1 > tag2",变量更新后布尔结果正确翻转 |
arithmetic_with_comparison |
算术表达式 "tag1 * 2 + tag2" |
二、test_fb_state_machine.cc(11 用例)
测试 FbStateMachine 的完整 7 状态生命周期。
2.1 初始状态(1 用例)
| 用例 |
验证内容 |
initial_state_is_idle |
新建 FSM 的 currentState() 为 FbState::Idle,isActive() 为 false |
2.2 Idle → Started(2 用例)
| 用例 |
验证内容 |
idle_to_started_when_triggered |
actTriggered=true → FbState::Started,funVarsNeedReset=false |
idle_stays_idle_when_not_triggered |
actTriggered=false → 保持 Idle,funVarsNeedReset=true(空闲时重置) |
2.3 Started → InProgress → Done(1 用例)
| 用例 |
验证内容 |
started_proceeds_to_done_via_feedback |
Started → InProgress(1-2 周期)→ checkFeedback(true) → Done → 自动回到 Idle |
2.4 NotHold(1 用例)
| 用例 |
验证内容 |
keep_mode_not_hold_when_trigger_lost |
keep_mode=true 时触发条件丢失 → FbState::NotHold,funVarsNeedReset=true |
2.5 Timeout(1 用例)
| 用例 |
验证内容 |
timeout_when_exceeds_limit |
超过 timeout 时间 → FbState::Timeout,funVarsNeedReset=true |
2.6 变量快照(1 用例)
| 用例 |
验证内容 |
snapshot_on_action_start |
Started 状态下,s1/s2 快照正确,stime 已设置,time=0,mv2_tagN 初始化为 0 |
2.7 变量累积(1 用例)
| 用例 |
验证内容 |
action_vars_accumulate_in_progress |
InProgress 状态下,mv2_tagN 正确累加,mx_tagN/mi_tagN 跟踪极值 |
2.8 forceReset(1 用例)
| 用例 |
验证内容 |
force_reset_returns_to_idle |
forceReset() → 状态回到 Idle,isActive() 变为 false |
2.9 非 keep 模式触发丢失(1 用例)
| 用例 |
验证内容 |
no_keep_mode_trigger_loss_stays_in_progress |
keep_mode=false 时触发丢失不退出 InProgress |
2.10 终端状态自动回归(1 用例)
| 用例 |
验证内容 |
terminal_state_returns_to_idle_next_cycle |
Timeout 后下一周期 update 返回 Idle |
三、test_algorithms.cc(52 用例)
由于算法子类(LogicAlg/BoundAlg 等)的构造函数依赖 CMemVar 共享内存等运行时基础设施,本测试文件采用组件组合模拟策略:不完整构造算法对象,而是测试已提取的独立组件和算法特有逻辑。
3.1 LogicAlg 核心逻辑(6 用例)
验证 LogicAlg::doMonProc() 使用的表达式求值流程。
| 用例 |
验证内容 |
logic_alg_trigger_true_produces_alarm |
表达式为 true → 应报警 |
logic_alg_trigger_false_no_alarm |
表达式为 false → 不报警 |
logic_alg_complex_expression |
tag1 > 2 && tag2 < 10 组合条件 |
logic_alg_and_short_circuit_false |
AND 条件中一个为 false 整体为 false |
logic_alg_or_expression |
OR 条件中一个为 true 整体为 true |
logic_alg_negation_operator |
!tag1 取反运算符(! 是项目新增的 matheval 运算符) |
3.2 BoundChecker 检测器(11 用例)
验证 BoundAlg::doMonProc() 使用的上下限检测逻辑。
| 用例 |
验证内容 |
bound_checker_detects_out_of_upper |
值超上限 → isOutOfBounds=true |
bound_checker_detects_out_of_lower |
值超下限 → isOutOfBounds=true |
bound_checker_only_right_mode_sentinel |
limit_down=-32768 → 自动推导 OnlyRight 模式,仅检测上限 |
bound_checker_only_left_mode_sentinel |
limit_up=32767 → 自动推导 OnlyLeft 模式,仅检测下限 |
bound_checker_only_left_mode_sentinel_32768 |
limit_up=32768 同样为哨兵值 |
bound_checker_default_bilateral |
正常上下限 → Default 双侧检测 |
bound_checker_error_mode |
双哨兵 (-32768, -32768) → ErrorMode,永不报警 |
bound_checker_exact_boundary_default |
等于限值的边界值不触发报警 |
bound_checker_boundary_only_left |
OnlyLeft 模式下的边界行为 |
bound_checker_boundary_only_right |
OnlyRight 模式下的边界行为 |
bound_checker_isValid + setDetectMode_override |
isValid() 查询 + setDetectMode 手动覆盖 |
3.3 BoundAlg 过滤表达式(2 用例)
| 用例 |
验证内容 |
bound_alg_filter_expression |
exp_feedback_ 过滤条件为 false 时不参与统计,为 true 时参与 |
bound_alg_filter_boundary |
过滤表达式边界值 >= 检查 |
3.4 BoundHoldAlg 保持时间(3 用例)
| 用例 |
验证内容 |
bound_hold_time_logic |
值需持续超限 hold_time 后才报警,hold_time <= delay_time 时立即报警 |
bound_hold_zero_hold_time |
hold_time=0 → 立即报警 |
bound_hold_long_delay |
长时间保持(60s),到期前不报警,到期后报警 |
3.5 FeedbackAlg 集成(3 用例)
验证 ExpressionEngine + FbStateMachine 组合行为。
| 用例 |
验证内容 |
feedback_full_flow_start_to_done |
触发 → Started → InProgress → 等待反馈条件 |
feedback_full_flow_not_hold |
keep_mode 下触发丢失 → NotHold,funVarsNeedReset=true |
feedback_timeout_scenario |
短超时(100ms)→ Timeout |
3.6 ExpTimes 累积逻辑(4 用例)
| 用例 |
验证内容 |
exp_times_occurrence_counting_logic |
6 次触发 → shear_times=6 > max_times=5 → 报警 |
exp_times_occurrence_below_threshold |
3 次触发 → 低于阈值 → 不报警 |
exp_times_time_accumulation_logic |
时间累积:5 秒 → 转换为小时(5000/3600000) |
exp_times_time_multiple_intervals |
多段时间累积:3s + 7s = 10s |
3.7 FaultCode bit 提取(6 用例)
| 用例 |
验证内容 |
fault_code_gitbit_extraction |
基本位提取:bit 3 of 8 = 1,bit 0 of 8 = 0 |
fault_code_bit_parsing_all_bits |
0x0F → 4 个置位 bit |
fault_code_bit_15_set |
bit 15(0x8000)单独置位 |
fault_code_all_bits_set_16bit |
0xFFFF → 16 位全置位 |
fault_code_single_bit_each_position |
每个 bit 位置独立验证 |
fault_code_gitbit_with_different_types |
unsigned int/short/long 类型兼容性 |
3.8 Roller3 工具函数(14 用例)
验证从 "tag1+tag2+tag3" 表达式中提取 tag 序号。
| 用例 |
验证内容 |
roller3_extract_tag_numbers |
"tag1+tag2+tag3" → [1, 2, 3] |
roller3_extract_tag_numbers_single |
"tag5" → [5] |
roller3_extract_tag_numbers_complex |
"tag10+tag2+tag35" → 包含 10, 2, 35 |
roller3_extract_empty_string |
空字符串 → 空结果 |
roller3_extract_no_tags |
无 tag 前缀 → 空结果 |
roller3_extract_tag_numbers_with_prefix |
"metatag1+tag2" → 提取 tag1 和 tag2(子串匹配特性) |
roller3_extract_large_tag_numbers |
"tag999+tag1000" → [999, 1000] |
calculateMedian(7 用例)
验证中位数计算。
| 用例 |
验证内容 |
roller3_calculate_median_odd |
奇数元素:[1,3,5] → 3.0,[10,2,8] → 8.0(内部排序) |
roller3_calculate_median_even |
偶数元素:[1,3,5,7] → 4.0,[1,2] → 1.5 |
roller3_calculate_median_single |
单元素:[42] → 42.0 |
roller3_calculate_median_empty |
空数组 → 0.0 |
roller3_calculate_median_negative_values |
负数:[-5,-1,-3] → -3.0 |
roller3_calculate_median_large_dataset |
大数据集:[1..99] → 50.0 |
roller3_calculate_median_unsorted_preserves_order |
乱序输入 → 内部排序后正确 |
3.9 JSON 配置校验(5 用例)
验证各算法类型的最小合法 JSON 结构完整性。
| 用例 |
验证内容 |
json_config_logic_alg_structure |
LogicAlg JSON 包含 tags/trigger/function/output |
json_config_bound_alg_structure |
BoundAlg JSON 包含 limit_down/limit_up |
json_config_feedback_logic_structure |
FeedbackAlg 逻辑型 JSON 包含 action_start/action_end/timeout |
json_config_feedback_bound_structure |
FeedbackAlg 上下限型 JSON 包含 bound params |
json_config_bound_hold_structure |
BoundHoldAlg JSON 包含 hold_time |
测试框架说明
宏
| 宏 |
用途 |
TEST(name) |
定义一个测试用例,自动注册到 TestRunner |
CHECK(expr) |
断言 expr 为 true |
CHECK_EQ(a, b) |
断言 a == b |
CHECK_FLOAT_EQ(a, b, eps) |
断言 abs(a-b) <= eps |
CHECK_THROWS(expr) |
断言 expr 抛出异常 |
运行指定测试
测试按文件编译为独立可执行文件 eqpalg_test,所有用例顺序执行,输出 PASSED/FAILED 及汇总。
已知限制
-
算法完整构造测试:LogicAlg/BoundAlg/FeedbackAlg 等算法子类的构造函数依赖 CMemVar::Const() 共享内存全局变量,无法在开发机上进行完整的端到端测试。当前测试策略是通过组件组合(ExpressionEngine + FbStateMachine + BoundChecker)模拟 doMonProc() 的控制流。
-
IHDB 依赖算法:TrendSlope2/3、Roller、GlitchDetection 等算法依赖 iHyperDB 查询,其 exec_mon() 无法在纯单元测试中运行。这些算法的核心逻辑(斜率计算、中位数离群检测、bit 提取)已在上面的测试中覆盖。
-
DB2 依赖:StatCollector、FaultCode 的数据库操作部分需要 DB2 连接,未在单元测试中覆盖。