MariaDB 中的 Gcov
Gcov 是一个覆盖率测试工具,用于创建更好的程序。它可以显示代码库中哪些部分未经测试。Gcov 与 *gcc* 位于同一软件包中。MariaDB 注重代码质量,并使用 Gcov 检查测试覆盖率。我们期待 Gcov 很快能作为 buildbot (MDBF-158) 的一部分使用。
如何使用 Gcov
我们来写一个演示示例,展示它是如何工作的。
— 源代码
$ cat -n test.c
int f1()
{
return 0;
}
int f2(int a, int b)
{
return a+b;
}
int main()
{
f1();
}
— 使用 *coverage* 标志编译源代码
$ gcc --coverage test.c -o test
# Result files:
test test.c test.gcno
— 运行可执行文件
$ ./test
# Result files
test test.c test.gcno test.gcda
请注意,会创建用于 Gcov 的额外文件。
— 运行 Gcov
$ gcov test.c
File 'test.c'
Lines executed:66.67% of 6
Creating 'test.c.gcov
# Result files
test test.c test.gcno test.gcda test.c.gcov
— 检查结果(请注意,*main()* 和 *f1()* 函数只被调用了一次)
$ cat test.c.gcov
-: 0:Source:test.c
-: 0:Graph:test.gcno
-: 0:Data:test.gcda
-: 0:Runs:1
1: 1: int f1()
-: 2: {
1: 3: return 0;
-: 4: }
-: 5:
#####: 6: int f2(int a, int b)
-: 7: {
#####: 8: return a+b;
-: 9: }
1: 10: int main()
-: 11: {
1: 12: f1();
-: 13:
-: 14: }
-: 15:
如果您更改源代码,再次调用 *f1()* 函数(总共 2 次),然后重复编译和运行二进制文件的过程,结果将是
2: 1: int f1()
-: 2: {
2: 3: return 0;
-: 4: }
1: 10: int main()
-: 11: {
1: 12: f1();
1: 13: f1();
MariaDB 与 Gcov
MariaDB 支持 Gcov,可以使用 *mysql-test-run.pl* (*mtr*) 脚本运行它,主要由 MariaDB 开发者或 MariaDB 代码库贡献者使用。目前,Gcov 只适用于 in-source 构建。
以下是使用 Gcov 的步骤
- 编写补丁
Gcov 将应用于您的补丁并显示您补丁的性能,因此这一步很有益。为了本教程的目的,我将在 10.3 分支上向您展示一个简单案例,其中我们将更改来自 *get_check_constraints_record* 函数的检查约束记录名称。假设这是我们创建的补丁
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -6601,7 +6601,7 @@ static int get_check_constraints_record(THD *thd, TABLE_LIST *tables,
}
#endif
Virtual_column_info *check= tables->table->check_constraints[i];
- table->field[0]->store(STRING_WITH_LEN("def"), system_charset_info);
+ table->field[0]->store(STRING_WITH_LEN("definition"), system_charset_info);
此更改应在测试中可见:*funcs_1.is_check_constraints.test*,其中 *funcs_1* 是套件名称,*is_check_constraints* 是测试名称。您可以在此处阅读有关 mysql-test-run
框架如何工作的更多信息。
- 使用特定参数编译和构建源代码
在文档中,您可以找到如何从源代码编译。在编译期间,添加 cmake 标志 **ENABLE_GCOV**。命令如下所示
$ cmake . -DCMAKE_BUILD_TYPE=Debug -DENABLE_GCOV=ON
编译源代码后,使用以下命令验证设置:
$ cmake . -LAH | grep ENABLE_GCOV
您应该在末尾看到 *ENABLE_GCOV:BOOL=ON*。现在通过调用 make
来构建二进制文件。
- 在
mysql-test
文件夹中,使用gcov
标志在mtr
中运行测试,并将结果保存到文件中,以查看补丁使用record
标志的效果
$ ./mtr funcs_1.is_check_constraints --gcov --record
Logging: ./mtr funcs_1.is_check_constraints --gcov --record
vardir: /home/anel/mariadb/10.2-gcov/mysql-test/var
Checking leftover processes...
Removing old var directory...
Creating var directory '/home/anel/mariadb/10.2-gcov/mysql-test/var'...
Checking supported features...
MariaDB Version 10.2.41-MariaDB-debug
- SSL connections supported
- binaries are debug compiled
- binaries built with wsrep patch
Collecting tests...
Installing system database...
==============================================================================
TEST RESULT TIME (ms) or COMMENT
--------------------------------------------------------------------------
worker[1] Using MTR_BUILD_THREAD 300, with reserved ports 16000..16019
funcs_1.is_check_constraints 'innodb' [ pass ] 327
--------------------------------------------------------------------------
The servers were restarted 0 times
Spent 0.327 of 5 seconds executing testcases
Completed: All 1 tests were successful.
Running dgcov
- 检查 Gcov 的结果。您应该看到您的更改被测试使用的权重。
$ cat var/last_changes.dgcov
*********************
dgcov sql/sql_show.cc
*********************
@@ +6601,7 @@ static int get_check_constraints_record(THD *thd, TABLE_LIST *tables,
: 6601: }
: 6602:#endif
: 6603: Virtual_column_info *check= tables->table->check_constraints[i];
88: 6605: table->field[0]->store(STRING_WITH_LEN("definition"), system_charset_info);
: 6606: table->field[3]->store(check->name.str, check->name.length,
: 6607: system_charset_info);
正如您所见,我们修改的行被执行了 88 次,这是好的。如果它根本没有被执行,我们就无法知道它是否工作正常。您可以在此处阅读更多关于使用 dgcov 进行代码覆盖率的信息。
欢迎反馈
如果您在此功能预览、设计或未按预期工作的边缘案例中遇到任何问题,请在 MDEV 项目的 JIRA 中提交 bug/功能请求告知我们。欢迎您在 Zulip 上讨论此事。