ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Wazuh OS Regex 引擎 execute 路径测试框架深度解析:基于 JSON 数据驱动的单元测试体系

Wazuh OS Regex 引擎 execute 路径测试框架深度解析:基于 JSON 数据驱动的单元测试体系 Wazuh OS Regex 引擎 execute 路径测试框架深度解析基于 JSON 数据驱动的单元测试体系【免费下载链接】wazuhWazuh - The Open Source Security Platform. Unified XDR and SIEM protection for endpoints and cloud workloads.项目地址: https://gitcode.com/GitHub_Trending/wa/wazuhWazuh 的os_regex模块实现了自研的轻量级正则表达式引擎被广泛应用于日志匹配、规则解析等安全分析链路。本文以 test_os_regex_execute.md 为核心结合 test_os_regex_execute.c、test_os_regex_execute.json 及底层实现 os_regex_execute.c完整讲解该测试框架的分层结构、字段语义、执行器源码逻辑与扩展编写方法。读完本文你将掌握如何阅读、运行并新增针对OSRegex_Execute_ex()的单元测试理解其捕获组、end_match返回值语义及已知边界缺陷的处理策略。一、测试对象OSRegex_Execute 与 regex_matching在深入测试框架之前先明确被测对象。os_regex是 Wazuh 自研的正则库非 POSIX/PCRE其核心执行函数定义在 os_regex.hOSRegex_Execute()对已编译正则与字符串做匹配返回指向最后一个匹配字符的指针失败返回NULLOSRegex_Execute_ex()OSRegex_Execute的扩展版允许通过外部传入的regex_matching结构体接收捕获组结果从而支持并行化匹配。const char *OSRegex_Execute(const char *str, OSRegex *reg) __attribute__((nonnull(2))); const char *OSRegex_Execute_ex(const char *str, OSRegex *reg, regex_matching *regex_match) __attribute__((nonnull(2)));regex_matching结构体见 os_regex.h保存匹配结果typedef struct regex_matching { char **sub_strings; /* 捕获到的子串数组 */ const char ***prts_str; /* 括号闭合位置的指针 */ regex_dynamic_size d_size; /* 动态分配大小信息 */ } regex_matching;OSRegex_Execute_ex的实现位于 os_regex_execute.c当regex_match非空即external_context为真时捕获结果写入外部结构体为空时则写入OSRegex内部的动态字段并加互斥锁保护。测试框架正是围绕OSRegex_Execute_ex的外部上下文模式设计的——共享同一个regex_matching结构体恰好可以验证该结构体在多次执行间被复用时的内存行为。二、测试框架总体结构三层 JSON 嵌套整个测试集test suites定义在 test_os_regex_execute.json 中最外层是一个 JSON 数组[ test_suite_1, test_suite_2, ... test_suite_n ]每个test suite对应一个功能主题例如无转义 token 的字符映射、带量词的反斜杠 token是包含description与batch_test的 JSON 对象{ description: 这里应说明被测的功能或用例场景。, batch_test: [ UT_1, UT_2, ... UT_m ] }batch_test是按功能分组的单元测试数组。关键设计点是同一个 test suite 下的所有单元测试共享一个初始为空的regex_matching结构体用于顺带验证该结构体在多次匹配间的内存复用与分配增长逻辑在OSRegex_Execute_ex中体现为sub_strings_size、prts_str_alloc_size的动态扩容判断。这一设计在exectute_batch_test()test_os_regex_execute.c中实现void exectute_batch_test(batch_test batch) { regex_matching regex_match {0}; // Execute a batch of test cases for (int case_id 0; batch[case_id] ! NULL; case_id) { exec_test_case(batch[case_id], regex_match); } OSRegex_free_regex_matching(regex_match); }三、单元测试字段语义一张表看懂 JSON 格式每个单元测试同样是一个 JSON 对象完整字段示例如下{ description: 可选单元测试描述, skip_test: false, ignore_result: false, debug: false, pattern: ^Some pattern in a (\\w) , log: Some pattern in a Wazuh log., end_match: log., captured_groups: [ Wazuh ] }各字段的语义与约束结合 test_os_regex_execute.md 与load_test_case()的解析逻辑如下字段类型/必填说明descriptionstring / 可选单元测试描述便于定位失败用例skip_testbool / 可选为true时跳过该测试。适用于本应通过但当前存在已知 bug的用例尤其是会产生段错误或导致测试中止而无法处理的情形ignore_resultbool / 可选为true时测试照常执行但失败会被忽略、不中断。适用于已知失败但可绕过的用例用于记录缺陷而非掩盖缺陷debugbool / 可选为true时在出错时打印详尽的诊断信息参数、期望值、实际值patternstring /必填OS Regex 正则表达式logstring /必填待分析匹配的日志字符串end_matchstring /必填可为null匹配成功后OSRegex_Execute_ex返回指向最后一个匹配字符的指针该字段是从该字符到 log 末尾构成的字符串若期望不匹配则填nullcaptured_groupsstring 数组 /必填可为空数组期望捕获到的分组内容注意pattern、log、end_match、captured_groups在load_test_case()test_os_regex_execute.c中都是必检字段——pattern/log必须为非空字符串end_match必须为字符串或nullcaptured_groups必须为数组否则直接断言失败。description、skip_test、ignore_result、debug四个字段缺省时按calloc清零后的默认值处理描述为 NULL、三个布尔为 false。四、执行器源码级剖析exec_test_case 的四步校验exec_test_case() 是框架的核心执行函数其校验流程与OSRegex_Execute_ex的返回值语义一一对应分四个阶段1. 跳过与计数若skip_test为真直接累加skipped_unit_test_count并返回否则累加executed_unit_test_count。2. 编译阶段OSRegex * regex calloc(1, sizeof(OSRegex)); const char * match_retval NULL; bool compile_regex OSRegex_Compile(test_case-pattern, regex, OS_RETURN_SUBSTRING);编译使用OS_RETURN_SUBSTRING标志os_regex.h该标志使引擎在匹配时提取捕获子串。编译失败时累加失败计数打印Syntax error on regex: %s: %dregex-error为错误码并仅在ignore_result为假时assert_false(true)中止。3. 匹配与 end_match 校验match_retval OSRegex_Execute_ex(test_case-log, regex, matching_result);随后用逻辑互斥方式校验匹配结果与期望的一致性end_match NULL但实际匹配成功match_retval ! NULL→ 失败regex should not match but it doesend_match ! NULL但实际未匹配match_retval NULL→ 失败regex should match but it doesnt。若match_retval非空且end_match也非空则用strcmp校验从最后一个匹配字符到 log 末尾的剩余字符串是否等于期望值。例如pattern: hi Wazuh、log: hi Wazuh时返回指针指向首个字符h因此end_match为h若 log 为prefixhi Wazuhsub则end_match为hsub。4. 捕获组校验遍历matching_result-sub_strings与期望的captured_groups先用逻辑异或检查存在性是否一致parity为真表示两者要么都存在、要么都不存在再对都存在的情况逐组strcmp比对内容。若ignore_result为真某组校验失败时直接break跳出循环避免无谓的后续断言。从OSRegex_Execute_ex的实现看捕获子串由_OS_Regex通过prts_str记录括号闭合位置、再由sub_strings[k]逐段截取而来os_regex_execute.c因此captured_groups的顺序与正则中括号出现的顺序一致。五、真实用例解读从 JSON 看引擎行为test_os_regex_execute.json 共 5068 行按 20 余个功能套件组织覆盖了引擎的主要语法面。以下摘录典型套件1字符映射charmap与字面量匹配{ description: [Functionality] Charmap without backslashed tokens., batch_test: [ { description: Literal match. Match all., pattern: hi Wazuh, log: hi Wazuh, end_match: h, captured_groups: [] }, { description: Match with sufix and group., pattern: (hi) (Wazuh), log: fixhi Wazuhsub, end_match: hsub, captured_groups: [hi, Wazuh] }, { description: Literal match, with the end flag. It does not match., pattern: hi Wazuh$, log: hi Wazuh 123, end_match: null, captured_groups: [] } ] }这里验证了三类行为整串匹配时end_match为首字符带前后缀的局部匹配时捕获组与剩余串语义$结尾锚点在末尾存在多余字符时拒绝匹配。2反斜杠 token 与量词{ description: [Functionality] Only backslashed tokens without quantifiers (*, )., batch_test: [ { description: Match all., pattern: \\w\\w\\s\\S\\S\\S\\S\\S, log: hi Wazuh, end_match: h, captured_groups: [] }, { description: Match all with capture groups., pattern: \\w(\\w\\s\\S)\\S(\\S\\S\\S), log: hi Wazuh, end_match: h, captured_groups: [i W, zuh] } ] }\w、\s、\S等为引擎内置字符映射 token支持与捕获组混用先部分匹配失败、随后在更靠后位置重新匹配成功的场景如log: hi Waz hi Wazuh.专门用于验证_OS_Regex中的st_error/pt_error[]回退机制os_regex_execute.c。\p表示标点字符、\d表示数字这些映射在Supported expression tests套件中逐一验证。3锚点、转义与 OR 组合专门的套件覆盖^、$单独及组合使用、\$、\(、\)、\\、\|、\等特殊字符的转义以及^/$/|组合下的分支匹配。六、已知缺陷的显式登记ignore_result 与 expected_failed_tests该框架最有价值的设计之一是把已知缺陷固化为可回归的测试记录。JSON 中多处出现__known_issue与ignore_result: true的搭配例如相邻捕获组不被支持pattern: (hi)(Wazuh)、log: hiWazuh本应匹配但实际失败空日志无法匹配pattern: ^$、log: 本应匹配但实际失败以量词/*结尾时返回值指针不准如pattern: Pattern \\w \\d、log: Pattern Wazuh 123期望end_match指向3实际却指向1。这些用例集中收录在 Corner cases 套件中。为了不让已知缺陷导致构建失败同时又保留回归信号框架采用双重手段用例级ignore_result: true失败被记录但不中断套件级在 test_os_regex_execute.c 中硬编码result.expected_failed_tests 211并在测试收尾处用assert_int_equal(result.expected_failed_tests, result.failed_tests_count)做双重校验。这意味着修复 bug 时必须同步调低该数字新增已知失败用例时必须同步调高任何静默漂移都会在测试输出中暴露。最终统计输出包括执行套件数、单元测试总数、实际执行数、跳过数、失败数与错误总数。七、构建与运行CMake 集成方式测试通过 CMakeLists.txt 集成到src/unit_tests的构建体系中测试二进制test_os_regex_execute由test_os_regex_execute.c编译生成链接OS_REGEX_O静态聚合的 os_regex 目标文件、${WAZUHLIB}与${WAZUHEXT}关键宏JSON_PATH_TEST被定义为${CMAKE_CURRENT_SOURCE_DIR}/test_os_regex_execute.json第 64-65 行编译期把 JSON 数据文件路径固化进二进制readFile()test_os_regex_execute.c据此打开文件并交给 cJSON 解析通过add_test(NAME test_os_regex_execute COMMAND test_os_regex_execute)注册为 CTest 用例可使用ctest直接执行Windows 目标winagent下额外注入针对 syscheck/rootcheck 等模块的--wrap链接选项用于隔离外部依赖。因此新增或修改测试用例只需编辑 JSON 文件无需改动 C 源码重新构建即可生效——这是该框架数据驱动设计的核心收益。八、如何新增一个单元测试实战指南遵循框架约定添加测试只需三步定位套件在 test_os_regex_execute.json 中找到与被测功能最贴近的batch_test数组若功能全新则新增一个带description与batch_test的 suite 对象保持description以[Functionality]开头的一致风格编写用例对象确保pattern、log、end_match、captured_groups四个必填字段完整。确定end_match的方法在匹配成功时它就是从最后一个被匹配字符起到 log 末尾的子串不期望匹配则置null。捕获组按正则中括号顺序排列无捕获时给空数组[]处理已知缺陷若用例涉及已知 bug标注__known_issue说明缺陷背景按情况设skip_test段错误类或ignore_result可绕过类并同步更新 test_os_regex_execute.c 中的expected_failed_tests计数。调试时可对单个用例临时开启debug: true失败时执行器会打印完整参数、实际/期望的end_match与每个捕获组的比对差异配合OSRegex_Execute_ex的返回值语义即可快速定位问题。九、总结Wazuh 的os_regex_execute测试框架以JSON 数据 通用 C 执行器的方式将OSRegex_Execute_ex的匹配语义、捕获组提取、返回指针定位及内存复用行为全部固化为可回归的断言并通过skip_test/ignore_result/expected_failed_tests三层机制把已知缺陷纳入版本控制而不阻塞构建。理解这一框架不仅便于为 os_regex 引擎贡献测试用例也为其他嵌入式正则引擎或自研 DSL 的测试体系设计提供了可借鉴的范本。【免费下载链接】wazuhWazuh - The Open Source Security Platform. Unified XDR and SIEM protection for endpoints and cloud workloads.项目地址: https://gitcode.com/GitHub_Trending/wa/wazuh创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表