openGauss

开源数据库

openGauss社区官网

开源社区

如何跑增量代码覆盖率

彭炯2022-05-05覆盖率

全量代码覆盖率统计:

  1. 下载安装 lcov 工具(版本 >= 1.14), http://ltp.sourceforge.net/coverage/lcov.php
shell
[pengjiong@localhost ~]$ lcov -v
lcov: LCOV version 1.14
  1. 增加插桩函数用于收集结果:在代码根目录下执行, 假设此代码根目录为 /home/test/openGauss-server
shell
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 查看插桩是否成功。

shell
[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);
  1. configure 时增加编译选项:"-fprofile-arcs -ftest-coverage" 和 "LDFLAGS='-lgcov'"是必须要新增的选项(其他选项请根据实际情况调整)
shell
./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'
  1. 正常执行 make && make install
  2. 然后正常执行 fastcheck 或者其他 LLT 用例即可
  3. 用例运行完后,执行 gs_ctl stop -D xxx 停止 gaussdb,开始准备收集覆盖率信息
  4. 在代码根目录下执行:
shell
lcov --capture --directory . --output-file coverage.info

然后会在根目录生成 coverage.info 文件

shell
[pengjiong@localhost openGauss-server]$ ll coverage.info
-rw-------. 1 pengjiong pengjiong 20M Apr 26 16:31 coverage.info
  1. 编辑 coverage.info 文件,找到/xxx/src/test/whitebox/knl_whitebox_test.cpp 这一行,将其修改为文件的正确路径
  2. 接下来,使用生成的 info 文件转换为可视化的 html 文件,在代码根目录执行:
shell
genhtml --no-prefix --no-sort coverage.info -o results
  1. 执行成功显示覆盖率如下:
Writing directory view page.
Overall coverage rate:
  lines......: 15.1% (144084 of 957019 lines)
  functions..: 18.9% (12059 of 63944 functions)
  1. 同时在根目录下生成 results 文件夹,将 results 文件夹下载到 windows 上,用浏览器打开 results 目录下的 index.html 文件,即可看到此次覆盖率的全部情况。也可以点击文件夹或者文件查看到具体文件,具体函数的覆盖率。

增量代码覆盖率统计: 在全量代码覆盖率结果的基础上,通过增量代码的 diff 文件,生成增量代码覆盖率。

  1. 得到基线代码和修改后的新代码的 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
  1. 收集增量覆盖率结果,同全量的操作一样:
shell
genhtml --rc lcov_branch_coverage=1 --no-prefix --no-sort increment.info -o incremen_results