Linux 内核开发人员如何在本地和提交代码后测试他们的代码?他们是否使用某种单元测试和构建自动化?测试计划?
Linux 内核非常重视社区测试。
通常,任何开发人员都会在提交之前测试他们自己的代码,而且他们通常会使用来自 Linus 的开发版本的内核,或者与他们的工作相关的项目的其他不稳定/开发树之一。这意味着他们经常同时测试他们的更改和其他人的更改。
正式测试计划的方式往往不多,但在将功能合并到上游树之前可能会要求进行额外的测试。
正如 Dean 指出的,还有一些自动化测试,linux test project 和 kernel autotest (good overview)。
开发人员通常还会编写自动化测试来测试他们的更改,但我不确定是否有(经常使用的)机制来集中收集这些临时测试。
当然,这在很大程度上取决于内核的哪个区域正在更改 - 您为新网络驱动程序所做的测试与更换核心调度算法时所做的测试完全不同。
当然,内核本身及其部件在发布之前都会进行测试,但这些测试仅涵盖基本功能。有一些测试系统执行 Linux 内核的测试:
The Linux Test Project (LTP) 向开源社区提供测试套件,以验证 Linux 的可靠性和稳定性。 LTP 测试套件包含一组用于测试 Linux 内核和相关功能的工具。
Autotest——全自动测试框架。它主要设计用于测试 Linux 内核,尽管它可用于许多其他目的,例如验证新硬件、虚拟化测试和 Linux 平台下的其他一般用户空间程序测试。它是 GPL 下的一个开源项目,被许多组织使用和开发,包括 Google、IBM、Red Hat 和许多其他组织。
还有一些主要的 GNU/Linux 发行公司开发的认证系统。这些系统通常会检查完整的 GNU/Linux 发行版是否与硬件兼容。有 Novell、Red Hat、Oracle、Canonical 和 Google 开发的认证系统。
Linux内核也有动态分析系统:
Kmemleak 是一个包含在 Linux 内核中的内存泄漏检测器。它提供了一种以类似于跟踪垃圾收集器的方式检测可能的内核内存泄漏的方法,不同之处在于不释放孤立对象,而仅通过 /sys/kernel/debug/kmemleak 报告。
Kmemcheck 捕获对动态分配的内存的每次读取和写入(即,使用 kmalloc())。如果读取了以前未写入的内存地址,则会在内核日志中打印一条消息。它也是 Linux 内核的一部分。
故障注入框架(包含在 Linux 内核中)允许将错误和异常注入应用程序的逻辑,以实现更高的系统覆盖率和容错能力。
Linux 内核开发人员如何在本地和提交代码后测试他们的代码?他们是否使用某种单元测试和构建自动化?
用经典的话来说,不。
例如,Ingo Molnar 正在运行以下工作负载:
用一组随机的配置选项构建一个新内核 启动到它去 1
每次构建失败、启动失败、错误或运行时警告都会得到处理。 24/7。乘以几格,可以发现不少问题。
测试计划?
不。
可能有一个误解,认为有一个中央测试设施,但没有。每个人都做他/她想做的事。
树内工具
在内核中找到测试工具的一个好方法是:
提供帮助并阅读所有目标
查看工具/测试
在 v4.0 中,这导致我:
工具/测试/自我测试下的 kselftest。使用 make kselftest 运行。必须已经在运行构建的内核。另见:文档/kselftest.txt,https://kselftest.wiki.kernel.org/
ktest 在工具/测试/ktest 下。另见:http://elinux.org/Ktest,http://www.slideshare.net/satorutakeuchi18/kernel-auto-testbyktest
make help 的静态分析器部分,其中包含以下目标: checkstack: Perl: what does checkstack.pl in linux source do? Coccinelle 的 coccicheck(由 askb 提及)
checkstack: Perl: linux 源代码中的 checkstack.pl 是做什么的?
Coccinelle 的 coccicheck(由 askb 提及)
内核 CI
https://kernelci.org/ 是一个旨在使内核测试更加自动化和可见的项目。
它似乎只做构建和启动测试(TODO 如何自动测试启动工作的源应该在 https://github.com/kernelci/)。
Linaro 似乎是该项目的主要维护者,来自许多大公司的贡献:https://kernelci.org/sponsors/
利纳罗熔岩
http://www.linaro.org/initiatives/lava/ 看起来像是一个专注于开发板启动和 Linux 内核的 CI 系统。
手臂丽莎
https://github.com/ARM-software/lisa
不确定它的详细功能,但它是由 ARM 和 Apache 授权的,因此可能值得一看。
演示:https://www.youtube.com/watch?v=yXZzzUEngiU
步进调试器
不是真正的单元测试,但一旦你的测试开始失败可能会有所帮助:
QEMU + GDB:https://stackoverflow.com/a/42316607/895245
KGDB:https://stackoverflow.com/a/44226360/895245
我自己的 QEMU + Buildroot + Python 设置
我还开始了一个专注于易于开发的设置,但最终我也添加了一些简单的测试功能:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/8217e5508782827320209644dcbaf9a6b3141724#test-this-repo
我还没有详细分析所有其他设置,它们可能比我做的更多,但是我相信我的设置很容易快速上手,因为它有很多文档和自动化。
自动化内核测试并不容易。大多数 Linux 开发人员自己进行测试,就像 adobriyan mentioned。
但是,有一些东西有助于调试 Linux 内核:
kexec:一个系统调用,允许您将另一个内核放入内存并重新启动,而无需返回 BIOS,如果失败,则重新启动。
dmesg:绝对是查找有关内核启动期间发生的事情以及它是否有效/无效的信息的地方。
Kernel Instrumentation:除了 printk(和一个名为 'CONFIG_PRINTK_TIME' 的选项,它允许您查看(精确到微秒)内核何时输出什么),内核配置允许您打开许多跟踪器,使它们能够调试什么正在发生。
然后,开发人员通常会让其他人审查他们的补丁。一旦补丁在本地被审查并且不会干扰其他任何东西,并且补丁经过测试可以与来自 Linus 的最新内核一起工作而不会破坏任何东西,这些补丁就会被推送到上游。
Here's a nice video 详细说明补丁在集成到内核之前所经历的过程。
除了其他答案外,本文更强调Linux内核的功能测试、硬件认证测试和性能测试。
很多测试实际上是通过脚本、静态代码分析工具、代码审查等进行的,这在捕捉错误方面非常有效,否则会破坏应用程序中的某些东西。
Sparse – 一种开源工具,旨在查找 Linux 内核中的故障。
Coccinelle 是另一个执行匹配和转换引擎的程序,它提供语言 SmPL(语义补丁语言)用于在 C 代码中指定所需的匹配和转换。
checkpatch.pl and other scripts - 编码风格问题可以在内核源代码树的 Documentation/CodingStyle 文件中找到。阅读时要记住的重要一点不是这种风格比任何其他风格都好,只是它是一致的。这有助于开发人员轻松查找和修复编码风格问题。内核源代码树中的脚本 scripts/checkpatch.pl 已为其开发。这个脚本可以很容易地指出问题,并且应该始终由开发人员在他们的更改上运行,而不是让审阅者在以后指出问题时浪费他们的时间。
我可以想象他们使用虚拟化来进行快速测试。它可能是 QEMU、VirtualBox 或 Xen,以及一些用于执行配置和自动化测试的脚本。
自动化测试可能是通过尝试许多随机配置或一些特定配置(如果他们正在处理特定问题)来完成的。 Linux 有很多低级工具(例如 dmesg)来监视和记录来自内核的调试数据,所以我想也可以使用它。
据我所知,英特尔运行/资助了一个自动性能回归检查工具(名为 lkp/0 day)。它将测试发送到邮件列表的每个有效补丁,并检查从不同的微基准测试(如 hackbench、fio、unixbench、netperf 等)更改的分数。
一旦出现性能回归/改进,相应的报告将直接发送给补丁作者和抄送相关维护者。
LTP 和 Memtests 通常是首选工具。
adobriyan mentioned Ingo 的随机配置构建测试循环。现在,0-day 测试机器人(又名 kbuild 测试机器人)几乎涵盖了这一点。此处介绍了一篇关于基础架构的好文章:Kernel Build/boot testing
这种设置背后的想法是尽快通知开发人员,以便他们能够尽快纠正错误(在某些情况下,在补丁进入 Linus 的树之前,因为 kbuild 基础设施也会针对维护者的子系统树进行测试)。
我已经完成了 Linux 内核编译并为 Android(Android 6.0 (Marshmallow) 和 Android 7.0 (Nougat))做了一些修改,其中我使用 Linux 版本 3。我在 Linux 上交叉编译了它系统,手动调试错误,然后在 Android 中运行其启动映像文件并检查它是否进入漏洞。如果它运行完美,则意味着它是根据系统要求完美编译的。
注意:Linux内核会根据系统硬件的要求而变化
在贡献者提交补丁文件并提出合并请求后,Linux 看门人会通过集成和审查来检查补丁。一旦成功,他们会将补丁合并到相关分支并发布新版本。
Linux Test Project 是提供在应用补丁后针对内核运行的测试场景(测试用例)的主要来源。这可能需要大约 2 到 4 个小时,这取决于具体情况。
请注意选定内核的文件系统将被测试。示例:ext4 针对 ext3 生成不同的结果,依此类推。
内核测试程序。
从存储库(Linux Kernel Archives 或 GitHub)获取最新的内核源代码应用补丁文件(使用 diff 工具)构建新内核。针对 LTP(Linux 测试项目)中的测试过程进行测试