openGauss
开源数据库
openGauss社区官网
开源社区
如何跑增量代码覆盖率
全量代码覆盖率统计:
- 下载安装 lcov 工具(版本 >= 1.14), http://ltp.sourceforge.net/coverage/lcov.php
[pengjiong@localhost ~]$ lcov -v
lcov: LCOV version 1.14
- 增加插桩函数用于收集结果:在代码根目录下执行, 假设此代码根目录为 /home/test/openGauss-server
sed -i '/NotifyProcessActive();/i __gcov_flush();' src/gausskernel/process/postmaster/postmaster.cpp
sed -i 'N;256 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 ea2c611f2..61d044431 100755
--- a/src/gausskernel/process/postmaster/postmaster.cpp
--- b/src/gausskernel/process/postmaster/postmaster.cpp
@@ -252,6 +252,7 @@ static bool isNeedGetLCName = true;
#define IS_FD_TO_RECV_GSSOCK(fd) \
((fd) == t_thrd.postmaster_cxt.sock_for_libcomm || (fd) == t_thrd.libpq_cxt.listen_fd_for_recv_flow_ctrl)
+extern "C" void __gcov_flush();
/* These two are only here before of the SSL multithread initialization of OpenSSL component */
#include "ssl/gs_openssl_client.h"
@@ -4546,6 +4547,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 CC=g++ CFLAGS='-O0 -fprofile-arcs -ftest-coverage' --prefix=/XXX --enable-debug --enable-cassert --enable-thread-safety --without-readline --without-zlib --gcc-version=7.3.0 --3rd=/XXX 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 文件,找到/xxx/src/test/whitebox/knl_whitebox_test.cpp 这一行,将其修改为文件的正确路径
- 接下来,使用生成的 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 需要的格式 2. 由全量覆盖率结果(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