ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Envoy 源码开发中的代码覆盖率检查指南:/coverage 命令、覆盖率报告与 per-directory 阈值解析

Envoy 源码开发中的代码覆盖率检查指南:/coverage 命令、覆盖率报告与 per-directory 阈值解析 Envoy 源码开发中的代码覆盖率检查指南/coverage 命令、覆盖率报告与 per-directory 阈值解析【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy本文是一份面向 Envoy 源码贡献者的代码覆盖率实战指南基于 source/docs/coverage.md 展开并结合仓库中 repokitteh 命令模块、Bazel 覆盖率脚本与阈值配置文件系统讲解如何在 Pull Request 中确认新代码是否被测试覆盖、如何解读覆盖率报告、以及 Envoy 是如何用分目录阈值来守护测试质量的。读完本文你将掌握从触发/coverage命令到定位未覆盖代码分支的完整工作流。一、在 PR 中快速确认新代码是否被测试覆盖Envoy 的贡献者文档给出了一个非常直接的答案在 Pull Request 的评论中发送/coverage命令即可。这是由仓库 CI 机器人在后台处理的其行为定义在 ci/repokitteh/modules/coverage.star 中COVERAGE_LINK_MESSAGE Coverage for this Pull Request will be rendered here: https://storage.googleapis.com/envoy-cncf-pr/%s/coverage/index.html For comparison, current coverage on main branch is here: https://storage.googleapis.com/envoy-cncf-postsubmit/main/coverage/index.html The coverage results are (re-)rendered each time the CI Envoy/Checks (coverage) job completes. def should_add_coverage_link(action, issue_title): return ( action opened and issue_title.startswith(coverage:) ) def add_coverage_link(issue_number): github.issue_create_comment(COVERAGE_LINK_MESSAGE % issue_number) def _pr(action, issue_number, issue_title): if should_add_coverage_link(action, issue_title): add_coverage_link(issue_number) def _add_coverage(issue_number): add_coverage_link(issue_number) handlers.pull_request(func _pr) handlers.command(name coverage, func _add_coverage)从这段机器人逻辑可以看出两条触发路径手动触发在 PR 评论区直接输入/coverage机器人收到命令后调用_add_coverage向 PR 中回贴覆盖率报告的访问地址。自动触发当 PR 的标题以coverage:开头时机器人会在 PR 打开opened事件中自动回贴覆盖率链接。回贴的链接包含两部分本 PR 专属的覆盖率报告按 PR 编号归档以及main分支当前覆盖率的对照地址方便开发者对比自己的改动是否拉低了整体覆盖水平。注释中还特别说明覆盖率结果会在 CI 的Envoy/Checks (coverage)任务每次完成后重新渲染。二、覆盖率报告的生成与解读触发/coverage命令后报告由 CI 的coverage任务生成对应 ci/do_ci.sh 中的coverage|fuzz_coverage分支。该分支会先setup_clang_toolchain配置 clang 工具链再调用覆盖率入口脚本coverage|fuzz_coverage) setup_clang_toolchain echo ${CI_TARGET} build with tests ${COVERAGE_TEST_TARGETS[*]} if [[ $CI_TARGET fuzz_coverage ]]; then export FUZZ_COVERAGEtrue fi export BAZEL_GRPC_LOG${ENVOY_BUILD_DIR}/grpc.log ${ENVOY_SRCDIR}/test/run_envoy_bazel_coverage.sh \ ${COVERAGE_TEST_TARGETS[]} collect_build_profile coverage ;;报告本身是基于 LCOV 的可浏览 HTML 页面按源码目录层级组织。拿到报告地址后你可以逐目录下钻定位到自己在改动的源码文件查看每一行的覆盖情况。需要注意的是报告中的红色高亮行并不一定意味着“缺测试”。文档中记录了一个真实案例贡献者在新代码中发现了未覆盖行追查后确认这其实是一个覆盖率统计工具的误报——测试过的switch语句中尾部的右花括号trailing braces被 LCOV 统计为未覆盖行。如文章开头截图source/docs/file.png所示报告中这类行会带有NOT REACHED GCOVR EXCL LINE之类的注释标记用于明确告知统计工具排除该行。绝大多数情况下报告中标记的行确实是“需要补单测的代码分支”但遇到switch尾括号这类边界情况时需要结合上下文判断是真缺口还是统计噪音。三、本地运行覆盖率test/run_envoy_bazel_coverage.sh 全流程如果你不想等 CIEnvoy 提供了完整的本地覆盖率运行脚本 test/run_envoy_bazel_coverage.sh。脚本默认行为与关键参数如下环境变量 / 参数默认值说明COVERAGE_TARGET/ 命令行参数//test/...要跑覆盖率的目标集合命令行参数优先级最高VALIDATE_COVERAGEtrue生成报告后是否校验阈值可设为false跳过FUZZ_COVERAGEfalse是否只对 fuzz 测试目标生成覆盖率SRCDIR${PWD}仓库根目录用于定位输出目录COVERAGE_DIR${SRCDIR}/generated/coverage普通覆盖率的输出目录COVERAGE_DIRfuzz 模式${SRCDIR}/generated/fuzz_coveragefuzz 覆盖率的输出目录整个脚本的流水线分为三个核心阶段运行覆盖率run_coverage执行bazel coverage附加--configtest-coveragefuzz 模式为--configfuzz-coverage以及--experimental_ui_max_stdouterr_bytes80000000以容纳超长日志。fuzz 模式下脚本会先用bazel query attr(tags, fuzz_target, ...)过滤出所有带fuzz_target标签的目标再执行覆盖。运行结束后检查bazel-out/_coverage/_coverage_report.dat是否存在且非空否则直接报错退出。解压报告unpack_coverage_reportBazel 产出的_coverage_report.dat实际上是 zstd 压缩的 tar 包脚本通过bazel run zstd//:zstd_cli -- -d -c ...解压再用tar -xf -展开到generated/coverage目录最终得到coverage.json供后续校验使用。校验阈值validate_coverage当VALIDATE_COVERAGEtrue时执行bazel run envoy//tools/coverage:validate传入coverage.json、FUZZ_COVERAGE与IS_MOBILE三个参数。也就是说本地跑覆盖率同样会执行阈值校验覆盖率不达标时脚本会失败——这正是 Envoy 用自动化手段强制维持测试水平的关键机制。注意老的 test/per_file_coverage.sh 目前仅输出提示说明“该文件已迁移覆盖率配置请见coverage.yaml”因此现代工作流统一以coverage.yaml与run_envoy_bazel_coverage.sh为准。四、分目录覆盖率阈值test/coverage.yaml覆盖率校验的依据是 test/coverage.yaml它定义了全局与逐目录两套阈值thresholds: total: 96.1 per_directory: 96.6 directories: source/common: 96.4 source/common/api: 94.9 # some syscalls require sandboxing source/common/crypto: 91.2 # Static singleton initialization and OpenSSL internal error paths not testable source/common/http: 96.5 source/common/http/http1: 93.6 # To be removed when http_inspector_use_balsa_parser is retired. source/common/http/http2: 96.6 source/common/memory: 98.1 source/common/network: 94.3 source/common/thread: 0.0 # Death tests dont report LCOV source/common/watchdog: 60.0 # Death tests dont report LCOV source/exe: 94.4 source/extensions/filters/http/ext_authz: 98.0 source/extensions/filters/network/ext_authz: 98.0 source/extensions/common/aws/credential_providers: 100.0 source/server: 93.3 # flaky: be careful adjusting ...这份配置透露了几个重要的项目事实全局红线total为 96.1%任何 PR 若把整体覆盖率拉低到 96.1% 以下校验即失败。分目录红线per_directory为 96.6%每个登记在案的目录都有各自的阈值部分目录甚至要求 100%如source/extensions/common/aws/credential_providers、source/extensions/formatter/cel、source/extensions/matching/input_matchers/cel_matcher。豁免是带理由的阈值较低的目录均附有注释说明原因例如source/common/thread: 0.0是因为 death tests 不会被 LCOV 统计source/extensions/wasm_runtime/wasmtime: 0.0是因为 coverage 构建中未启用该 runtimesource/common/signal: 87.4同样归因于 death tests。阈值调整是敏感操作source/server: 93.3的注释写着“flaky: be careful adjusting”source/extensions/common/wasm: 95.6也标注“flaky: be careful adjusting”提醒维护者不要轻易动这些易抖动目录的阈值。对于提交新代码的开发者这意味着一件事新增源码所在目录的覆盖率必须不低于该目录配置的阈值因此在撰写 PR 前先对照coverage.yaml检查目标目录的阈值再补齐对应单测是最稳妥的做法。五、fuzz 覆盖率独立的阈值体系除了常规单元测试覆盖率Envoy 还维护着一套独立的 fuzz 覆盖率体系配置在 test/fuzz_coverage.yamlthresholds: total: 23.75fuzz 覆盖率的整体阈值仅为 23.75%远低于常规覆盖率的 96.1%。这背后是有意为之fuzz 目标带fuzz_target标签的测试的代码路径本身高度集中且存在大量状态机分支不可能也不必要达到与单元测试相同的覆盖水平。在 CI 中fuzz 覆盖率通过CI_TARGETfuzz_coverage触发ci/do_ci.sh 中设置FUZZ_COVERAGEtrue产出物输出到generated/fuzz_coverage目录并同样经过validate_coverage的阈值校验。六、从报告到行动贡献者的自查闭环把以上机制串起来Envoy 贡献者的覆盖率自查闭环是这样的提交 PR 后在评论区输入/coverage或让 PR 标题以coverage:开头自动触发机器人回贴本 PR 与main分支的覆盖率报告链接。等 CI 的Envoy/Checks (coverage)任务完成后浏览报告下钻到改动所在的目录与文件。逐行甄别红色未覆盖行绝大多数是缺失的单测分支需要补充单元测试少数是switch尾括号等统计噪音可通过报告中的GCOVR EXCL LINE注释确认后忽略。对照 test/coverage.yaml 中目标目录的阈值确认新代码没有把目录覆盖率拉低到红线以下若确实拉低就需要补测直至达标因为本地脚本同样会执行阈值校验并失败退出。这套流程把“新代码有没有被测试覆盖”从一句模糊的自我检查变成了由机器人回贴报告、LCOV 逐行标记、Bazel 脚本自动校验的工程化闭环也是 Envoy 作为大型 C 项目长期维持高测试水平的基础设施之一。相关实现可进一步查阅 ci/repokitteh/modules/coverage.star、test/run_envoy_bazel_coverage.sh、test/coverage.yaml 与 ci/do_ci.sh。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表