Wazuh DBSync 冒烟测试实战指南:用 dbsync_test_tool 端到端验证数据库同步引擎
【免费下载链接】wazuhWazuh - The Open Source Security Platform. Unified XDR and SIEM protection for endpoints and cloud workloads.项目地址: https://gitcode.com/GitHub_Trending/wa/wazuh
本文档以 Wazuh 仓库中的 DBSync Smoke Tests 为主体(见 src/shared_modules/dbsync/smokeTests/Readme.md),深入讲解如何通过dbsync_test_tool黑盒工具触发 DBSync 库的全部公开 API,覆盖增删改查、快照同步、触发器动作与事务操作四大典型场景。读完本文,你将掌握 DBSync 冒烟测试的目录组织方式、配置文件与动作 JSON 的字段含义、每个用例的执行命令与预期行为,并能对照 dbsync.h 与 action.h 理解工具与底层 C API 的调用关系。
什么是 DBSync Smoke Tests
DBSync 是 Wazuh 开源安全平台中负责本地数据库同步的共享模块,位于 src/shared_modules/dbsync,它基于 SQLite3 为 syscollector、sca、inventory-sync 等模块提供统一的数据库抽象、行级增量同步与快照更新能力。
DBSync Smoke Tests 的定位正如其文档所言:"stimulate the entire DBSync library APIs through the DBSync Tool"——即通过dbsync_test_tool依次调用 DBSync 库的整套 API,以端到端的方式验证核心功能链路是否按预期工作。它属于黑盒验证:工具接收配置与动作文件,执行后产出增量数据文件,测试人员据此分析结果。
冒烟测试与仓库内的其他测试互补:
- 单元测试(src/shared_modules/dbsync/tests)针对 dbengine、sqlite 封装、接口层与 pipelineFactory 做细粒度验证;
- 集成测试(src/shared_modules/dbsync/integrationTests)验证模块在具体业务场景(如 FIM)中的联动;
- 冒烟测试(src/shared_modules/dbsync/smokeTests)则站在用户视角,用一组可读的 JSON 动作文件把最常用的 API 组合跑通一遍。
测试工具 dbsync_test_tool 概览
dbsync_test_tool是为测试和验证 dbsync 模块而专门创建的命令行工具,其完整说明见 testtool/Readme.md。它作为一个黑盒运行:用户传入配置文件和一组动作 JSON,工具按顺序执行,并把每一步产生的 diff 快照输出到指定目录。
工具的架构关系如下图所示:
从源码结构看(testtool/main.cpp、testtool/action.h、testtool/factoryAction.h),工具内部采用"动作工厂 + 参数解析"模式:命令行参数-c指定配置、-a指定动作文件列表(逗号分隔)、-o指定输出目录;每个动作 JSON 的action字段决定调用哪个 DBSync API。
编译构建
要运行冒烟测试,首先需要构建出dbsync_test_tool二进制。按 testtool/Readme.md 的说明,在仓库根目录执行:
make TARGET=server|agent <DEBUG=1>TARGET指定构建目标:server或agent;DEBUG=1可选,用于生成带调试信息的构建,便于后续单步排查。
构建成功后,dbsync_test_tool会随目标产物生成(其 CMake 目标定义见 testtool/CMakeLists.txt)。
配置文件与动作文件的格式约定
冒烟测试的全部用例都遵循"一个 config.json + 若干动作 JSON"的组织方式。
config.json:数据库初始化配置
冒烟测试共享的配置文件位于 src/shared_modules/dbsync/smokeTests/config.json,其字段与 testtool/input/config_template.json 模板一一对应:
| 字段 | 含义 | 取值说明 |
|---|---|---|
db_name | 数据库名称/文件路径 | 如temp.db,决定数据库落盘位置 |
db_type | 数据库类型 | 当前仅支持 SQLITE3,取值为1 |
host_type | 运行方类型 | 0(Agent)或1(Manager),影响路径与运行环境相关行为 |
persistance | 持久化类型 | 冒烟测试中为空字符串 |
sql_statement | 建表 SQL 语句 | 多条 SQL 可用分号连接,动作文件中的表结构必须与之一致 |
冒烟测试的sql_statement创建了两张表:
CREATE TABLE processes( `pid` BIGINT, `name` TEXT, `path` TEXT, `cmdline` TEXT, `state` TEXT, `cwd` TEXT, `root` TEXT, `uid` BIGINT, `gid` BIGINT, `euid` BIGINT, `egid` BIGINT, `suid` BIGINT, `sgid` BIGINT, `on_disk` INTEGER, `wired_size` BIGINT, `resident_size` BIGINT, `total_size` BIGINT, `user_time` BIGINT, `system_time` BIGINT, `disk_bytes_read` BIGINT, `disk_bytes_written` BIGINT, `start_time` BIGINT, `parent` BIGINT, `pgroup` BIGINT, `threads` INTEGER, `nice` INTEGER, `is_elevated_token` INTEGER, `elapsed_time` BIGINT, `handle_count` BIGINT, `percent_processor_time` BIGINT, `upid` BIGINT HIDDEN, `uppid` BIGINT HIDDEN, `cpu_type` INTEGER HIDDEN, `cpu_subtype` INTEGER HIDDEN, `phys_footprint` BIGINT HIDDEN, PRIMARY KEY (`pid`)) WITHOUT ROWID; CREATE TABLE processes_sockets( `socket_id` BIGINT, `pid` BIGINT, PRIMARY KEY (`socket_id`)) WITHOUT ROWID;这是模拟 syscollector 进程与 socket 信息的典型表结构:processes以pid为主键,processes_sockets以socket_id为主键并通过pid关联到进程。
动作 JSON:一次 API 调用
动作文件的顶层结构为{"action": "<API 名称>", "body": {...}},body随动作类型不同而不同。冒烟测试覆盖的动作与底层 C API 的映射关系(对应 dbsync.h 中的导出函数)如下:
| 动作名(action) | 底层 API | body 关键字段 |
|---|---|---|
dbsync_sync_row | dbsync_sync_row/dbsync_sync_txn_row | table、data(行数组) |
dbsync_insert_data | dbsync_insert_data | table、data |
dbsync_delete_rows | dbsync_delete_rows | table、query.data、query.row_filter_opt/where_filter_opt |
dbsync_select_rows | dbsync_select_rows | table、query.column_list、row_filter、distinct_opt、order_by_opt、count_opt |
dbsync_create_txn | dbsync_create_txn | tables(事务涉及的表列表) |
dbsync_close_txn | dbsync_close_txn | 无 |
dbsync_get_deleted_rows | dbsync_get_deleted_rows | 无(行为由工具参数或测试上下文决定) |
dbsync_add_table_relationship | dbsync_add_table_relationship | base_table、relationed_tables(含table与field_match) |
dbsync_update_with_snapshot | dbsync_update_with_snapshot | table、data(快照数据) |
工具在 action.h 中为每个动作实现了一个执行分支,执行结果(如{"dbsync_insert_data": retVal})会回写到输出目录。
目录结构与用例总览
冒烟测试目录按"一个文件夹一个用例"组织(见 src/shared_modules/dbsync/smokeTests),每个用例目录内包含本用例所需的动作 JSON,以及一份Readme.md说明该场景的步骤与预期结果:
smokeTests/ ├── config.json # 共享数据库配置 ├── InsertionUpdateDeleteSelect/ # 增删改查完整链路 ├── snapshotsUpdate/ # 快照更新 ├── triggerActions/ # 表关系与级联删除(触发器) └── txnOperation/ # 事务操作通用执行模板为(来自 testtool/Readme.md):
./dbsync_test_tool -c config.json -a input1.json,input2.json,input3.json -o ./output执行后,所有 diff 快照会按动作顺序输出到./output目录,文件命名为action_1.json、action_2.json……action_n.json,其中n等于-a参数传入的动作文件数量。
用例一:InsertionUpdateDeleteSelect(增删改查全链路)
该用例位于 InsertionUpdateDeleteSelect,模拟最典型的数据库操作顺序,其 Readme 定义的步骤为:
- 依据
config.json中的sql_statement创建数据库; - 将
inputSyncRowInsert.json的数据插入数据库; - 用
inputSyncRowModified.json的数据更新数据库; - 依据
deleteRows.json删除部分数据; - 依据
inputSelectRows.json查询数据。
执行命令:
$> ./dbsync_test_tool -c config.json -a inputSyncRowInsert.json,inputSyncRowModified.json,deleteRows.json,inputSelectRows.json -o ./output各动作文件要点如下:
inputSyncRowInsert.json:动作dbsync_sync_row,一次插入 4 行processes数据(pid 4/5/6/7),字段模拟真实进程信息,未提供的列用-1或空串占位,is_elevated_token使用布尔false;inputSyncRowModified.json:动作dbsync_sync_row,对pid=4的行做修改(name 改为User、cmdline 改为Guake、parent 改为 1),验证"同一主键再次 sync 即更新"的语义;deleteRows.json:动作dbsync_delete_rows,query中给出待删除行的完整数据(pid 4 与 pid 6 两行),并附带"row_filter_opt":"pid>=4"作为行过滤条件,说明删除既可按主键精确匹配,也可叠加过滤表达式;inputSelectRows.json:动作dbsync_select_rows,query中指定column_list(仅取 pid、name、path、cmdline 四列)、row_filter(WHERE pid>5)、distinct_opt=false、order_by_opt为空、count_opt=100,验证带投影、过滤与条数限制的查询。
该用例完整覆盖了dbsync_sync_row(对应 API dbsync_sync_row)、dbsync_delete_rows(dbsync.h)与dbsync_select_rows(dbsync.h)三条核心 API 的调用链。
用例二:snapshotsUpdate(快照更新)
该用例位于 snapshotsUpdate,用于验证"以完整快照驱动增量更新"的场景,其步骤为:
- 依据
config.json创建数据库; - 将
insertData.json的数据插入数据库; - 用
updateWithSnapshot.json的快照数据更新数据库(dbsync_update_with_snapshot); - 关闭事务。
执行命令:
$> ./dbsync_test_tool -c config.json -a insertData.json,updateWithSnapshot.json -o ./outputinsertData.json:动作dbsync_insert_data,先把若干行进程数据写入库中;updateWithSnapshot.json:动作dbsync_update_with_snapshot,body 携带table与一份完整快照data。底层 API dbsync_update_with_snapshot 会以快照为准对目标表做比对,生成并返回 diff(新增/删除/变更行),这正是 syscollector 周期性向中心同步清单数据所用的机制。该 API 还提供带回调的变体dbsync_update_with_snapshot_cb(dbsync.h),可在每次 diff 产生时实时回调处理。
用例三:triggerActions(表关系与级联删除)
该用例位于 triggerActions,验证 DBSync 的"表关系 + 隐式级联删除"能力,其步骤为:
- 依据
config.json创建数据库; - 将
insertDataProcesses.json的数据插入processes表; - 将
insertDataSocket.json的数据插入processes_sockets表; - 依据
addTableRelationship.json为两表建立关系; - 依据
deleteRows.json删除processes表中的数据,应隐式删除processes_sockets表中关联的数据。
执行命令:
$> ./dbsync_test_tool -c config.json -a insertDataProcesses.json,insertDataSocket.json,addTableRelationship.json,deleteRows.json -o ./output各动作要点:
insertDataProcesses.json:动作dbsync_insert_data,插入一条pid=4的进程;insertDataSocket.json:动作dbsync_insert_data,插入一条pid=4, socket_id=1的 socket 记录,与进程建立外键语义上的关联;addTableRelationship.json:动作dbsync_add_table_relationship,body 为base_table: "processes",relationed_tables中声明processes_sockets通过field_match: {"pid": "pid"}关联到基表。底层 API dbsync_add_table_relationship 会在引擎内部登记这一关系;deleteRows.json:动作dbsync_delete_rows,仅凭{"pid":4}(where_filter_opt为空)删除基表进程行。
预期结果是:删除processes中 pid=4 的行时,processes_sockets中 pid=4 的 socket 记录被隐式删除,验证触发器(TRIGGER)级别的级联行为。这一机制在 DBSync 中被 syscollector 等模块用于保证父子表数据一致性。
用例四:txnOperation(事务操作)
该用例位于 txnOperation,验证 DBSync 的事务化同步能力,其步骤为:
- 依据
config.json创建数据库; - 创建事务(
createTxn.json); - 将
inputSyncRowInsertTxn.json的数据插入数据库; - 获取删除行信息,
pksGetDeletedRows.json与fullyGetDeletedRows.json决定信息详细程度; - 用
inputSyncRowModifiedTxn.json更新数据库; - 关闭事务。
执行命令(注意-a中带子目录前缀):
$> ./dbsync_test_tool -c config.json -a txnOperation/createTxn.json,txnOperation/inputSyncRowInsertTxn.json,txnOperation/pksGetDeletedRows.json,txnOperation/inputSyncRowModifiedTxn.json,txnOperation/closeTxn.json -o ./output各动作要点:
createTxn.json:动作dbsync_create_txn,body 为{"tables": ["processes"]},声明事务涉及的表。底层 API dbsync_create_txn 返回一个事务句柄(TXN_HANDLE),后续操作都通过该句柄执行(如dbsync_sync_txn_row);inputSyncRowInsertTxn.json:在事务内插入数据(对应事务内 APIdbsync_sync_txn_row,见 action.h);pksGetDeletedRows.json/fullyGetDeletedRows.json:均为动作dbsync_get_deleted_rows。从命名可以推断,前者用于只取删除行的主键(PKs),后者用于取完整删除行信息;二者对应的 API 是 dbsync_get_deleted_rows,工具在执行时会按测试上下文向事务查询待删除数据;inputSyncRowModifiedTxn.json:在事务内更新数据;closeTxn.json:动作dbsync_close_txn,关闭事务并落库(对应 dbsync_close_txn)。
该用例完整展示了"创建事务 → 事务内增改 → 查询待删除行 → 关闭事务"的典型流程,这也是 Wazuh 中需要原子性批量同步数据的业务场景所依赖的能力。
输出与验证方式
所有用例执行完成后,./output目录中的action_N.json即为每个动作的 diff 快照(或返回值封装)。验证步骤建议如下:
- 检查是否生成了与
-a参数等量的action_*.json文件; - 逐个核对每个动作的返回值:成功路径下
dbsync_insert_data、dbsync_delete_rows等应返回 0; - 对
dbsync_update_with_snapshot与dbsync_get_deleted_rows,重点核对 diff 内容是否符合用例 Readme 描述的预期(如 triggerActions 中删除进程后 socket 记录同步消失); - 如需进一步确认库内数据,可直接用 SQLite3 客户端打开
db_name指定的数据库文件(如temp.db)做终态校验。
扩展阅读与源码索引
- 工具使用细节与架构说明:src/shared_modules/dbsync/testtool/Readme.md
- 动作执行实现(各 action 分支与返回值封装):src/shared_modules/dbsync/testtool/action.h
- 命令行参数解析与上下文管理:src/shared_modules/dbsync/testtool/cmdArgsHelper.h、src/shared_modules/dbsync/testtool/testContext.h
- 全部导出 API 声明:src/shared_modules/dbsync/include/dbsync.h
- 底层 SQLite3 引擎实现:src/shared_modules/dbsync/src/sqlite/sqlite_dbengine.cpp
- 单元测试(dbengine / interface / pipelineFactory / sqlite):src/shared_modules/dbsync/tests
- 集成测试(FIM 场景):src/shared_modules/dbsync/integrationTests
通过上述四个用例,你可以从零开始跑通 DBSync 的增删改查、快照更新、级联删除与事务四类核心能力,并把冒烟测试作为 DBSync 改动后的快速回归手段。
【免费下载链接】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),仅供参考