恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

MongoDB WiredTiger 并行代码覆盖率测量:gcov/Gcovr 多构建目录并行测试与报告合并实践

  • 首页
  • 资讯中心
  • /
  • MongoDB WiredTiger 并行代码覆盖率测量:gcov/Gcovr 多构建目录并行测试与报告合并实践

相关资讯

工业协议协同接入实践:从Modbus到OPC UA的数采链路构建 2026/9/17 6:09:09
Linux运维shell脚本实战:从骨架搭建到自检清单 2026/9/17 6:04:09
RK3568 SPI LCD的FrameBuffer驱动实战:从设备树配置到性能优化 2026/9/17 6:04:09

最新资讯

VSCode + SAPUI5 + Fiori Tools:SAP Fiori本地开发环境搭建与Hello World实战
fvm 实战:Windows 下 Flutter 多版本管理与升级回退
黄金市场暴跌8%:流动性收缩与利率预期的量化分析
Flower 安全聚合协议解析:SecAgg 与 SecAgg+ 在联邦学习中的实现
成套工程制造SAP方案:WBS项目主线打通研供产销与成本归集
WinEdt 11.1深度评测:面向Windows 10/11的LaTeX编辑器进化

今日推荐

每日热评|13% 的 Agent 技能带严重漏洞,这个注册表想用“验证+签名”解决信任危机
即梦AI保姆级教程:从生图到数字人,一站式搞定AI视频创作
BERT+LLM混合架构:突破NER长尾实体抽取瓶颈的工程实践

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

MongoDB WiredTiger 并行代码覆盖率测量:gcov/Gcovr 多构建目录并行测试与报告合并实践

发布时间:2026/9/17 6:09:09
MongoDB WiredTiger 并行代码覆盖率测量:gcov/Gcovr 多构建目录并行测试与报告合并实践 MongoDB WiredTiger 并行代码覆盖率测量gcov/Gcovr 多构建目录并行测试与报告合并实践【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo本篇技术指南围绕 MongoDB 仓库中 WiredTiger 存储引擎的文档 README.md 展开讲解如何利用 gcov 与 gcovr 在 16 核 ARM 实例上并行运行数百个测试、在约 13 分钟内完成整库覆盖率测量的完整方案。读完本文你将理解并行覆盖率测量中.gcda数据竞争、CMake 构建树不可复制等核心难题的成因并掌握多构建目录调度、GCOV_PREFIX路径重映射与 gcovr 多进程报告合并这一套可直接复用的工程实践。一、为什么要把覆盖率测量做进 PR 流水线代码覆盖率是评估测试有效性的工具它能帮助开发者识别测试中未被执行的代码区域发现测试盲区。WiredTiger 选择用 gcov 采集运行时覆盖数据再用 gcovr 生成分析报告文档中的 Wikipedia/gcovr 外链在此仅作背景参考仓库内以实际工具链为准。这套方案能否进入每次 PR 必跑的测试矩阵取决于一个硬性的时间预算整个测量过程必须控制在约 15 到 20 分钟以内。只有满足这个条件开发者和 PR 评审人才能在代码评审时看到本次修改的代码被测试覆盖到了什么程度这一关键信息。覆盖率测量对构建过程有两项特殊要求编译期产物.gcno必须以覆盖率模式构建 WiredTiger 及其测试代码编译器会为每个编译单元生成.gcno文件记录程序计数器的布局信息关闭优化优化会打乱源码行与二进制指令的对应关系因此覆盖率构建必须禁用优化保证源码每一行 ↔ 二进制的映射关系成立。代码构建完成后执行一组测试会产生运行期覆盖统计写入.gcda文件供 gcovr 后续分析。整个流程即覆盖率模式构建 → 生成 .gcno编译期数据 ↓ 并行执行测试 → 生成 .gcda运行期数据 ↓ gcovr 分析 .gcno .gcda → 生成覆盖率报告二、测试集的选择在 30 分钟内拿到约 50% 覆盖率并行化之前首先要解决跑哪些测试的问题。文档说明当前测试集基于Code Coverage Competition覆盖率竞赛的筛选结果目标是串行执行约 30 分钟内达到约 50% 的覆盖率在此之后还剔除了少量执行时间长但覆盖率收益不明显的测试。其中一条关键的筛选原则是RTSRollback To Stable测试很慢必须跳过慢速用例具体跳过了 RTS 测试 10、12、14、20、26、35、37、38、39 这几个编号。文档同时坦诚指出当前测试集的覆盖率尚未达到很高的水平但已经是一个很好的起点。实际选中的测试清单维护在 code_coverage_config.json 的test_tasks字段中规模约 200 余条混合了四类执行体Python 测试套件python3 ../test/suite/run.py test_xxx如test_overwrite、test_salvage01、cursor_random、test_timestamp10等C 语言测试程序test/csuite/wt8659_reconstruct_database_from_logs/test_wt8659_reconstruct_database_from_logs、test/csuite/incr_backup/test_incr_backup -S 123456789等cppsuite 单元测试test/cppsuite/run -t hs_cleanup -f test/cppsuite/configs/hs_cleanup_default.txtwt 工具命令行覆盖大量./wt -h WT_HOME_COVERAGE subcommand调用load、drop、verify、salvage、backup、dump -x -p test_table、stat、printlog等把 wt 工具的每个子命令都当作被测路径以及一条兜底的ctest -R (...)正则过滤执行。配置文件的_comments字段JSON 不支持注释的变通手法还说明了两点重要设计测试顺序按执行时长降序排列——脚本使用共享队列并行执行所有任务让最短的测试最后运行可以减少等待最后一个线程完成的时间ex_hello与wt create用于在每个构建目录中预创建两个数据库供后续测试复用避免每个测试重复建库的开销。setup_actions字段则固化了构建步骤-j 16并行编译setup_actions: [ cmake --preset linux-gcc -DHAVE_UNITTEST1 -DHAVE_DIAGNOSTIC0 -DCODE_COVERAGE_MEASUREMENT1 -DINLINE_FUNCTIONS_INSTEAD_OF_MACROS1 -DCMAKE_BUILD_TYPECoverage -G Ninja ../., ninja -j 16, mkdir WT_HOME_COVERAGE, examples/c/ex_hello/ex_hello, ./wt -h WT_HOME_COVERAGE load -j -f ../test/evergreen/code_coverage/test_table.json ]注意其中的-DCODE_COVERAGE_MEASUREMENT1与-DCMAKE_BUILD_TYPECoverage它们分别打开 WiredTiger 的覆盖率编译选项和覆盖率构建类型对应第一节所说的生成.gcno并关闭优化。最后一条wt load命令加载的是 test_table.json——一份 WiredTiger dump 格式的表定义table:test_table含完整建表配置与key1/key2两条示例数据为list、dump、verify等 wt 命令提供真实操作对象。三、并行覆盖率测量的两大挑战测试并行化本身能显著缩短执行时间但引入了两个必须解决的工程问题3.1.gcda文件没有写同步机制gcov 把运行期数据保存在.gcda文件里。多个测试并行运行时各测试向同一批.gcda文件写数据没有任何同步保护因此存在覆盖数据相互踩踏、丢失的风险。3.2 测试数据库必须隔离在独立子目录WiredTiger 测试通常把数据库生成在子目录中。多个测试在同一目录并行运行时每个测试必须把自己的数据库放进独立子目录否则数据文件互相冲突。文档指出这个子目录问题相对容易解决真正的硬骨头是.gcda数据文件问题。3.3 两条候选路线GCOV_PREFIX 重定向 vs 多构建目录路线一gcc 的交叉剖析cross profiling宏。gcov 提供GCOV_PREFIX和GCOV_PREFIX_STRIP两个环境变量来配置.gcda的落盘位置GCOV_PREFIX_STRIP指示从绝对路径中剥离多少层目录GCOV_PREFIX再把前缀拼回去。这样可以把多个测试的.gcda结果推到各自不同的目标目录——但代价是必须把.gcno文件拷贝进每一个目标目录才能完成分析。路线二多个构建目录。为每个并行测试准备一棵独立的构建树各测试在自己的目录树中运行。这里踩到一个 CMake 的著名限制CMake 明确不支持复制构建树——复制后构建系统内嵌的绝对路径全部失效会导致部分测试因路径错误而失败。因此最简做法是在每个构建目录中分别配置 CMake 并完整构建 WiredTiger。仓库的实现最终走的是路线二的变体code_coverage_utils.py 的setup_build_dirs()先编译一个基础构建目录执行setup_actions其中含ninja -j 16再用shutil.copytree把它复制成 N 份build_0、build_1……。复制构建树本应违反 CMake 的原则但复制发生在所有编译完成之后之后不再执行任何构建动作因此路径失效问题不会触发——而.gcno中记录的仍是原始构建目录路径于是 parallel_code_coverage.py 在执行每个测试任务前用路线一的环境变量把.gcda的写回位置纠正到当前副本目录# GCOV doesnt like it that we have copied the base build directory to construct the other # build directories. ... path_depth build_dir.count(/) env[GCOV_PREFIX_STRIP] str(path_depth) # 剥离原始绝对路径的层级数 env[GCOV_PREFIX] build_dir # 前缀替换为当前副本目录代码注释直接说明了动机GCOV 不欢迎构建目录被复制这件事GCOV_PREFIX_STRIPGCOV_PREFIX的组合相当于做了一次路径重映射让每个副本中的测试把覆盖数据写回自己所在的那棵目录树从而既只编译一次又天然隔离了每个并行测试的.gcda数据一举化解 3.1 的同步问题。四、当前方案16 核 ARM 上的构建目录数量权衡文档描述的生产配置是16 CPU 核的 ARM 实例并行运行尽可能多的测试。其中构建目录数量是一个典型的权衡点构建目录越多上限为 CPU 核数能并行跑的测试越多总执行时间越短但构建目录越多意味着更多重复编译工作削弱了用-j利用空闲核加速构建的能力。文档给出的实测折中是8 个构建目录 每个目录以-j 2并行编译得到约 6.5 分钟构建时间、约 2.5 分钟测试时间加上报告生成等杂项后总耗时约 13 分钟——正好满足 PR 测试的时间预算。从源码结构看配置注释ninja -j 16编译一个目录后复制与上述8 目录 × -j 2 分别编译的描述对应了方案演化的两个阶段早期做法是在每个构建目录中并行执行相同 setup 操作当前 code_coverage_utils.py 中的实现则简化为单目录编译 复制进一步压缩了构建阶段。4.1 任务调度共享队列 每进程绑定一个构建目录测试任务的并行调度由 parallel_code_coverage.py 驱动核心参数如下main()中的 argparse 定义参数说明-c, --config_pathJSON 配置文件路径setup_actionstest_tasks-b, --build_dir_base构建目录基础名实际目录为build_0、build_1……-j, --parallel并行测试数须 ≥ 1-s, --setup在每个构建目录执行配置中的 setup 动作-u, --bucket仅运行python或other非 Python分桶的子集供两台机器分摊任务-o, --optimize_test_order分析模式实测各测试耗时并回写配置按时长降序重排test_tasks-e, --check_errors检查各任务返回码失败即退出调度细节在 code_coverage_utils.py 的run_task_lists_in_parallel()用multiprocessing.Queue装好所有构建目录ProcessPoolExecutor(max_workers构建目录数)的初始化函数setup_run_tasks_parallel让每个工作进程从队列取走一个构建目录并chdir进去之后所有任务提交到池中被进程按需领取——即每个并行进程拥有自己的构建目录 共享任务队列。check_build_dirs()则在不执行 setup 的复用场景下校验各构建目录中确实存在.gcno编译期覆盖文件否则直接退出提示请为覆盖率构建。文档Current Solution一节把任务分桶描述为放进桶中每个构建树一个再各桶并行执行并在改进方向中承认当前分桶没有考虑测试时长不均可能导致部分桶提前跑完单队列可以消除这种不均衡。结合配置注释与代码实现来看仓库最终采用的正是这个单队列形态——配合按时长降序的测试顺序让短任务自然落在长任务之后的空闲时段减少尾部的等待浪费。五、并行生成报告parallel_gcovr.py测试跑完后的报告生成同样做了并行化实现于 parallel_gcovr.py。其设计动机在文件头部注释中写得很清楚gcovr 自带的-j选项只能开线程而解析 gcov 输出时线程受 GIL 限制无法真正利用多核因此需要进程级并行。工作流分四步收集数据文件find_coverage_data从wiredtiger目录起递归遍历包括全部build_*副本目录收集所有.gcda文件同时收集没有对应.gcda的.gcno——这些对象说明对应代码从未被执行必须出现在报告中显示为未覆盖否则报告会缺失整块文件贪心分组split_into_groups按文件大小降序排序后依次把最大的文件分给当前负载最小的组使各 gcovr 进程大致同时结束并行执行每组拉起一个独立的gcovr --json tracefile_XXX.json ...进程合并各 JSON tracefile 最后用gcovr --add-tracefile合并成一份组合报告。主命令参数参数默认值说明-j, --jobsCPU 核数并行的 gcovr 进程数-f, --filtersrcgcovr 报告过滤只统计src下的源码-o, --output_dir必填JSON tracefile 输出目录-s, --search_dir.覆盖数据搜索根目录-v, --verbose关DEBUG 日志两个源码细节值得特别注意共享的 gcovr 解析参数GCOV_PARSE_FLAGS--include-internal-functionsWiredTiger 内部函数以__前缀命名gcovr 默认会把它们当作编译器生成的符号而静默剔除必须显式包含--gcov-ignore-parse-errorsnegative_hits.warn_once_per_file与suspicious_hits.warn_once_per_file剖析多线程程序时负数和可疑计数器值是 gcov 的已知行为源码注释引用了 GCC bugzilla #68080这些行按零命中记录而不视为错误gcov 版本门禁只有 gcov 12 及以上版本会为每个数据文件生成唯一命名的中间文件旧版本按源码路径哈希命名中间文件多个并发 gcovr 进程处理同一源码时会互相覆盖而 gcovr 自身的目录锁只防自己的线程。因此脚本会先探测gcov --version若主版本 12 则自动回退到单进程并打印告警。脚本还在开始前清空output_dir中残留的.json——因为合并步骤会 glob 该目录下所有 JSON旧文件会被重复计数。六、衍生形态逐测试覆盖率与 PR 代码变更报告同一目录下的 per_test_code_coverage.py 将整体覆盖率进一步细化为逐测试覆盖率run_coverage_task()在每个测试运行前调用delete_runtime_coverage_files()清掉本构建副本中所有.gcda测试结束后用shutil.copytree把整棵构建副本保存为build_N_index_copy并写入task_info.json记录任务身份。随后run_gcovr()对每个副本单独执行gcovr build_copy --include-internal-functions \ --gcov-ignore-parse-errorsnegative_hits.warn_once_per_file \ --gcov-ignore-parse-errorssuspicious_hits.warn_once_per_file \ -f src -j 16 --html-self-contained --html-details .../2_coverage_report.html \ --json-summary-pretty --json-summary .../1_coverage_report_summary.json \ --json .../full_coverage_report.json得到每个测试各自贡献的 HTML/JSON 覆盖数据。该形态由 coverage-report-per-test.sh 驱动固定pip3 install gcovr8.6其输出coverage_data再被 coverage-report.sh 消费补丁构建下先用git_diff_tool.py相对base_branch生成 diff再用 Metrix 采集当前与上一提交git worktree检出HEAD~或 merge-base两版代码的行数与圈复杂度指标最终由code_change_report.py产出本次 PR 改动的代码被覆盖到多少的 HTML 变更报告——正是第一节所述 PR 评审场景的落点。七、文档指出的改进方向README 最后列出了两个明确的待改进点读起来是这套方案诚实的自白理想情况不应多次构建 WiredTiger期望出现支持复制构建树或能把.gcda/.gcno分别导向不同目录的机制从而免去多目录编译/复制的代价分桶未考虑测试时长不均部分测试桶可能提前完成、核心闲置单队列调度能改善均衡性。文档说明分桶方案之所以成为临时方案是因为它用concurrent.futures.ProcessPoolExecutor和subprocess.run就能非常容易地实现。八、小结这套并行覆盖率方案可以抽象为四个可迁移的工程决策时间预算驱动以 15~20 分钟能否跑完作为进入 PR 常跑的门槛并据此反向选择约 50% 覆盖率、30 分钟串行基线的测试集剔除慢而低收益的用例用目录隔离替代同步.gcda无并发保护就让每个并行进程独占一棵构建目录树配合单目录编译 复制 GCOV_PREFIX/GCOV_PREFIX_STRIP路径重映射绕开 CMake 不可复制构建树的限制进程级并行生成报告认清 gcovr 线程模式受 GIL 约束的现实用文件大小贪心分组 多进程 gcovr --add-tracefile合并实现真正多核的报告转换并以 gcov ≥ 12 作为并发安全的前提顺序与桶策略服务于尾部时间测试按实测时长降序、配合共享队列领取让短测试填补长测试留下的空隙。以上流程的全部实现集中于 code_coverage 目录调度脚本、并行 gcovr、逐测试覆盖率、测试清单外围的报告与变更分析脚本位于 test/evergreencoverage-report.sh、code_coverage_analysis.sh、code_change_report/可作为阅读源码的入口。【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号