ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Apache HBase 代码覆盖率实战:基于 JaCoCo 与 SonarQube 的 run-coverage.sh 全流程解析

Apache HBase 代码覆盖率实战:基于 JaCoCo 与 SonarQube 的 run-coverage.sh 全流程解析 Apache HBase 代码覆盖率实战基于 JaCoCo 与 SonarQube 的 run-coverage.sh 全流程解析【免费下载链接】hbaseApache HBase项目地址: https://gitcode.com/GitHub_Trending/hb/hbaseHBase 源码树的dev-support/code-coverage/目录提供了一套完整的代码分析与覆盖率采集方案通过run-coverage.sh脚本以 Maven 的jacoco profile运行全量测试并生成 JaCoCo 覆盖率报告在提供必要参数时还可将结果推送到 SonarQube 服务器做代码质量分析。读完本文你能完整掌握 HBase 覆盖率报告的生成方式、报告位置、JaCoCo 代理注入机制的源码细节以及如何用正确的参数把覆盖率数据发布到 SonarQube。方案概览脚本、文档与报告位置官方说明见 code-coverage README其核心信息只有三点但每一点对应着脚本中的具体行为run-coverage.sh脚本会以jacoco profile运行 Maven为 Java 类生成测试覆盖率数据若提供了必要参数脚本还会执行 Sonar 代码分析并把结果上传到指定的 SonarQube 服务器运行结束后JaCoCo 生成的报告位于各相关模块的target/site/jacoco/目录下。脚本本体为 run-coverage.sh它的全部逻辑由usage()、execute()和一段getopts参数解析组成见下文逐段解析。生成覆盖率报告的基本命令README 原文dev-support/code-coverage/run-coverage.sh发布到 SonarQube 的示例命令README 原文./dev-support/code-coverage/run-coverage.sh -l ProjectCredentials \ -u https://exampleserver.com -k Project_Key -n Project_Name参数说明四个选项与必需/可选关系脚本通过getopts :u:l:k:n:h解析命令行选项run-coverage.sh 第 60–75 行帮助信息-h触发usage()明确列出选项对应变量含义是否必需发布到 SonarQube-uSONAR_URLSonarQube 主机 URL必需-lSONAR_LOGINSonarQube 登录凭证必需-kSONAR_PROJECT_KEYSonarQube 项目 Key必需-nSONAR_PROJECT_NAMESonarQube 项目名可选-h—显示帮助并退出—README 与脚本usage()输出的表述一致发布结果到 SonarQube 的必需参数是host URL、login credentials、project keyproject name 是可选参数。传入非法选项时脚本打印Error: Invalid option并直接退出。从源码结构看脚本对参数做了严格校验——execute()内部第 51 行if [ -n $SONAR_LOGIN ] [ -n $SONAR_PROJECT_KEY ] [ -n $SONAR_URL ]; then只有三个必需变量同时非空时才会执行mvn sonar:sonar。因此不传任何参数时脚本依然会完整执行覆盖率构建只是跳过 SonarQube 上传这正是“先出报告、可选再上传”的设计。执行流程测试、verify 与 Sonar 三阶段execute()函数run-coverage.sh 第 36–58 行定位仓库根目录的pom.xmlSCRIPT_DIR/../../pom.xml然后依次执行三条 Maven 命令阶段一以 runAllTests jacoco profile 运行全部测试mvn -B -e -f ${MAIN_POM} clean test -PrunAllTests -Pjacoco -Pbuild-with-jdk11 -fn各参数含义-B批处理模式不输出进度条-e出错时打印完整堆栈便于排查失败模块-f ${MAIN_POM}显式指定仓库根目录的 pom.xml 作为构建入口因此脚本可以从任意工作目录调用-PrunAllTests启用根 POM 中定义的runAllTestsprofilepom.xml 第 4376–4388 行它调整 surefire 的分组参数——第一部分跑SmallTests第二部分跑MediumTests,LargeTests即小、中、大三类测试全部执行-Pjacoco启用 jacoco profile注入覆盖率代理详见下一节-Pbuild-with-jdk11启用 JDK11 相关模块 profile。从源码结构看根 POM 本身没有build-with-jdk11profile该 profile 定义在部分子模块中如 hbase-http/pom.xml 第 340 行、hbase-compression/hbase-compression-brotli/pom.xml 第 155 行用于这些需要 JDK 11 特性的模块-fn--fail-never即使某个模块测试失败也继续跑完所有模块。对全仓库覆盖率采集来说这是合理取舍——覆盖率统计的是“跑了的测试”的集合单模块失败不应阻断其余模块的数据采集但注意失败模块的覆盖率数据会偏低解读报告时须结合测试日志。阶段二verify 阶段跳过测试mvn -B -e -f ${MAIN_POM} verify -DskipTests -DskipITs -Pjacoco -Pbuild-with-jdk11 -fn阶段一在test生命周期止步JaCoCo 的reportgoal 绑定在prepare-package阶段见下文配置因此阶段二带着同样的-Pjacoco再走一遍verify生命周期并跳过测试agent 已在阶段一写入的jacoco.exec数据文件得以保留prepare-package阶段的reportgoal 才会真正生成 HTML/CSV/XML 报告到各模块的target/site/jacoco/。这一步是整个流程里容易被忽略的关键——只跑阶段一会得到 .exec 原始数据但没有可读报告。阶段三SonarQube 分析条件触发mvn -B -e -f ${MAIN_POM} sonar:sonar -Dsonar.host.url$SONAR_URL \ -Dsonar.login$SONAR_LOGIN -Dsonar.projectKey$SONAR_PROJECT_KEY \ -Dsonar.projectName$SONAR_PROJECT_NAME -Pjacoco命令通过sonar-maven-plugin根 POM 中版本属性sonar-maven-plugin.version为3.9.1.2184见 pom.xml 第 996 行执行sonar:sonargoal将覆盖率数据与静态分析结果一并上报。注意-Dsonar.projectName即使为可选参数脚本也会无条件透传——未提供时其值为空字符串。jacoco profile 的源码级解析代理如何注入测试 JVM真正决定覆盖率机制的是根 POM 中jacocoprofile 的定义pom.xml 第 3428–3478 行。它的activeByDefault为false只有显式-Pjacoco才生效核心内容如下prepare-agent向 surefire 注入 JaCoCo 代理plugin groupIdorg.jacoco/groupId artifactIdjacoco-maven-plugin/artifactId version${jacoco.version}/version configuration excludes exclude**/generated/**/*/exclude /excludes /configuration executions execution idprepare-agent/id goalsgoalprepare-agent/goal/goals phaseinitialize/phase configuration propertyNamejacocoArgLine/propertyName appendtrue/append /configuration /execution execution idreport/id goalsgoalreport/goal/goals phaseprepare-package/phase /execution /executions /plugin要点插件版本由属性jacoco.version 0.8.8控制pom.xml 第 994 行prepare-agent绑定在initialize阶段把javaagent参数写入名为jacocoArgLine的 Maven 属性代理字符串如何到达测试 JVM根 POM 全局定义argLine为${hbase-surefire.argLine} {jacocoArgLine}pom.xml 第 1077 行。{...}是 surefire 的“延迟求值”语法——在测试 fork 时才解析jacocoArgLine的最新值从而避免属性提前固化。JDK 17 环境由build-with-jdk17profilepom.xml 第 3343–3354 行把--add-opens等 JDK17 参数与{jacocoArgLine}一起拼进argLineWindows/cygwin 环境下os.windowsprofile第 3511 行也做了同样的追加。hbase-surefire.argLine本身携带断言开关、-Xmx${surefire.Xmx}、build id 等参数第 1033–1037 行JaCoCo agent 是在这些既有测试 JVM 参数之后追加进去的个别模块如 hbase-it/pom.xml 第 300 行在自己的 surefireargLine末尾也显式追加了{jacocoArgLine}保证 fork 配置不同的模块同样被 agent 覆盖根 POM 的 m2e lifecycle-mapping 配置第 4819–4831 行对prepare-agentgoal 标记ignore这只是让 Eclipse m2e 插件不因该 goal 报警与覆盖率行为无关。report绑定在 prepare-package 阶段reportgoal 绑定prepare-package阶段pom.xml 第 3462–3468 行这解释了run-coverage.sh为什么需要阶段二的mvn verify -DskipTests只有走到prepare-package每个模块的target/site/jacoco/目录才会生成 index.html、包的类级明细以及 CSV/XML 原始数据。覆盖率排除规则Sonar 口径比 JaCoCo 口径更宽profile 还定义了两个 Sonar 专用属性pom.xml 第 3434–3437 行sonar.exclusions**/generated/**/*/sonar.exclusions sonar.coverage.exclusions**/generated/**/*,hbase-it/**,**/hbase-logging/**/*,**/hbase-testing-util/**/*, **/hbase-protocol-shaded/**/*,**/hbase-external-blockcache/**/*,**/hbase-examples/**/*, **/hbase-archetypes/**/*/sonar.coverage.exclusions即sonar.exclusions静态分析排除只排除**/generated/**/*——主要是 protobuf/thrift 生成代码sonar.coverage.exclusions覆盖率排除在此基础上额外排除hbase-it、hbase-logging、hbase-testing-util、hbase-protocol-shaded、hbase-external-blockcache、hbase-examples、hbase-archetypes等模块。从源码结构看这些是集成测试入口、日志封装、测试工具、协议桩与示例代码通常不具备单元测试覆盖的意义不计入 Sonar 的覆盖率分母。需要注意区分JaCoCo 本地报告的排除规则只有**/generated/**/*插件excludes配置而更宽泛的排除只作用于 SonarQube 端的统计口径。因此同一份.exec数据本地 HTML 报告与 Sonar 面板上的覆盖率数值可能不同原因即在此。适用前提与注意事项运行环境脚本依赖mvn、bash与 JDK。命令中显式启用了-Pbuild-with-jdk11服务于 hbase-http、hbase-compression 等需要 JDK 11 特性的子模块因此建议使用 JDK 11 或更高版本运行在 JDK 17/18 环境下根 POM 会自动激活build-with-jdk17/build-with-jdk18profile 追加相应的--add-opens、-Djava.security.managerallow等参数JaCoCo agent 注入方式不变。耗时代价runAllTests会运行 Small Medium Large 全部分类的测试-fn又保证失败不中断一次全量覆盖率构建是 HBase 所有 Maven 测试 profile 中耗时最长的路径之一建议在有足够 CPU/内存的构建机上执行。结果解读单模块测试失败时-fn不中断该模块覆盖率偏低属于数据不完整而非代码质量下降请结合 surefire 报告区分。报告路径与 README 一致报告在“相关模块”的target/site/jacoco/下例如hbase-server/target/site/jacoco/而非仓库根目录。凭证安全-l传入的登录凭证会出现在命令行与进程列表中请在受控环境中执行避免在共享 shell 历史中残留明文凭证。小结HBase 的覆盖率方案由三层构成run-coverage.sh负责编排三阶段构建test -PrunAllTests -Pjacoco→verify -DskipTests -Pjacoco→ 条件触发的sonar:sonar根 POM 的jacocoprofile 通过prepare-agent把 agent 参数写入jacocoArgLine再经 surefire 的{jacocoArgLine}延迟注入每个测试 forksonar.exclusions与sonar.coverage.exclusions分别约束 Sonar 端的分析范围与覆盖率分母。理解了这套机制你就可以在 HBase 贡献、本地质量分析或私有 SonarQube 平台接入时准确地生成、定位并解读覆盖率数据。相关文件索引文档dev-support/code-coverage/README.md脚本dev-support/code-coverage/run-coverage.shjacoco profile 与 argLine 注入pom.xmlrunAllTests profilepom.xml模块级 argLine 追加示例hbase-it/pom.xml【免费下载链接】hbaseApache HBase项目地址: https://gitcode.com/GitHub_Trending/hb/hbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表