openGauss
开源数据库
openGauss社区官网
开源社区
如何跑增量代码覆盖率
全量代码覆盖率统计:
- 下载安装 lcov 工具(版本 >= 1.15)
wget https://sourceforge.net/projects/ltp/files/Coverage%20Analysis/LCOV-1.15/lcov-1.15.tar.gz
tar -zxvf lcov-1.15.tar.gz
cd lcov-1.15/bin
./lcov -v
结果显示:
lcov: LCOV version 1.15
并将lcov路径增加在环境变量中
export PATH=/xxx/lcov-1.15/bin:$PATH
- 增加插桩函数用于收集结果:在代码根目录下执行, 假设此代码根目录为 /home/test/openGauss-server
sed -i '/NotifyProcessActive();/i __gcov_flush();' src/gausskernel/process/postmaster/postmaster.cpp
sed -i '/extern void InitGlobalSeq();/i extern "C" void __gcov_flush();' src/gausskernel/process/postmaster/postmaster.cpp
执行完可以 git diff src/gausskernel/process/postmaster/postmaster.cpp 查看插桩是否成功。
[pengjiong@localhost openGauss-server]$ git diff src/gausskernel/process/postmaster/postmaster.cpp
diff --git a/src/gausskernel/process/postmaster/postmaster.cpp b/src/gausskernel/process/postmaster/postmaster.cpp
index d7b939fed..e8f5cdc0f 100644
--- a/src/gausskernel/process/postmaster/postmaster.cpp
+++ b/src/gausskernel/process/postmaster/postmaster.cpp
@@ -293,6 +293,7 @@
#include "utils/postinit.h"
+extern "C" void __gcov_flush();
extern void InitGlobalSeq();
extern void auto_explain_init(void);
extern int S3_init();
@@ -6687,6 +6688,7 @@ static void pmdie(SIGNAL_ARGS)
break;
}
+__gcov_flush();
NotifyProcessActive();
gs_signal_setmask(&t_thrd.libpq_cxt.UnBlockSig, NULL);
- configure 时增加编译选项:"-fprofile-arcs -ftest-coverage" 和 "LDFLAGS='-lgcov'"是必须要新增的选项(其他选项请根据实际情况调整)
./configure --gcc-version=10.3.1 CC=g++ CFLAGS='-O0 -fprofile-arcs -ftest-coverage' --prefix=$GAUSSHOME --3rd=$BINARYLIBS --enable-debug --enable-cassert --enable-thread-safety --with-readline --without-zlib LDFLAGS='-lgcov'
- 正常执行 make && make install
- 然后正常执行 fastcheck 或者其他 LLT 用例即可
- 用例运行完后,执行 gs_ctl stop -D xxx 停止 gaussdb,开始准备收集覆盖率信息
- 在代码根目录下执行:
lcov --capture --directory . --output-file coverage.info
然后会在根目录生成 coverage.info 文件
[pengjiong@localhost openGauss-server]$ ll coverage.info
-rw-------. 1 pengjiong pengjiong 20M Apr 26 16:31 coverage.info
- 执行下面命令,修改 coverage.info 文件,将shark相关的四个文件路径修改正确
sed -i 's|contrib/shark/gram\.y|contrib/shark/src/backend_parser/gram-tsql-rule.y|g' coverage.info
sed -i 's|contrib/shark/scan-tsql-rule\.l|contrib/shark/src/backend_parser/scan-tsql-rule.l|g' coverage.info
sed -i 's|contrib/shark/scan\.l|contrib/shark/src/backend_parser/scan-tsql-rule.l|g' coverage.info
sed -i 's|contrib/shark/scan-tsql-epilogue\.l\.cpp|contrib/shark/src/backend_parser/scan-tsql-epilogue.l.cpp|g' coverage.info
- 接下来,使用生成的 info 文件转换为可视化的 html 文件,在代码根目录执行:
genhtml --no-prefix --no-sort coverage.info -o results
- 执行成功显示覆盖率如下:
Writing directory view page.
Overall coverage rate:
lines......: 15.1% (144084 of 957019 lines)
functions..: 18.9% (12059 of 63944 functions)
- 同时在根目录下生成 results 文件夹,将 results 文件夹下载到 windows 上,用浏览器打开 results 目录下的 index.html 文件,即可看到此次覆盖率的全部情况。也可以点击文件夹或者文件查看到具体文件,具体函数的覆盖率。
增量代码覆盖率统计: 在全量代码覆盖率结果的基础上,通过增量代码的 diff 文件,生成增量代码覆盖率。
- 得到基线代码和修改后的新代码的 diff 文件,注意拉取两份完全干净的代码进行比较获取 diff 结果,以免其他文件影响最终结果。同时注意两份代码的路径深度要一致,如下面的例子所示,基线代码和修改后的新代码,都在 /home/workspace/xx/ 路径下,深度一致。
diff -r -N -x ".git" -x "*.gcov" -u /home/workspace/base/openGauss-server /home/workspace/increment/openGauss-server>> diff.txt
-r 表示递归,子目录也产生输出
-N 文件不存在当做空文件,比如新版本增加了一个文件,此选项会将每一行都输出
-x 表示排除,比如.git 不需要
-u 是 lcov 需要的格式
- 由全量覆盖率结果(coverage.info)和 diff 文件,生成增量覆盖率结果。addlcov 工具下载地址:https://github.com/Dragonliu2018/addlcov
addlcov --rc lcov_branch_coverage=1 --diff coverage.info diff.txt -o increment.info --strip $dep --path $new_Addr
coverage.info:前面得到的全量覆盖率文件路径
increment.info:输出的增量覆盖率文件路径
$new_Addr: 原始代码路径
$dep:diff 文件中的代码路径深度,即分隔符”/”的个数(包括结尾的)
以前面的代码路径为例,原始代码路径为 /home/test/openGauss-server。
用来生成 diff.txt 文件的干净基线代码路径为 /home/workspace/base/openGauss-server。
用来生成 diff.txt 文件的干净增量代码路径为 /home/workspace/increment/openGauss-server。
那么 $new_Addr 应该为原始代码路径即 /home/test/openGauss-server。
$dep 应该为 5,即 /home/workspace/base/openGauss-server 的路径深度,这也是为何生成 diff.txt 时,要求基线代码和修改后的新代码保持深度一致。
同时命令中所有文件路径全部使用绝对路径,如果 coverage.info 文件中部分文件在增量修改后被删除了,在 coverage.info 里面把那一行删除
可以得出命令为:
addlcov --rc lcov_branch_coverage=1 --diff /home/test/openGauss-server/coverage.info /home/test/openGauss-server/diff.txt -o /home/test/openGauss-server/increment.info --strip 5 --path /home/test/openGauss-server
- 收集增量覆盖率结果,同全量的操作一样:
genhtml --rc lcov_branch_coverage=1 --no-prefix --no-sort increment.info -o incremen_results