[HN Gopher] How is the Linux kernel tested?
       ___________________________________________________________________
        
       How is the Linux kernel tested?
        
       Author : sprado
       Score  : 88 points
       Date   : 2020-03-27 11:46 UTC (1 days ago)
        
 (HTM) web link (embeddedbits.org)
 (TXT) w3m dump (embeddedbits.org)
        
       | ndesaulniers wrote:
       | We run our own ci for building Linux kernels with clang.
       | (ClangBuiltLinux.github.io). We take Debian's nightly package of
       | ToT, make a docker image with the minimum tools we need, and use
       | buildroot ramdisks that have a custom init script that powers
       | down the machine once it reaches init. Our CI fetches various
       | kernel trees and branches, builds them, then boots them in Qemu.
       | The machine has 2 minutes to power up and down (usually takes
       | less than 10s), otherwise we consider the machine hung and fail
       | the run. We use travisci for the reporting, but are looking to
       | offload the building.
       | 
       | Also, Linaro's Tool chain Working Group runs a ton of CI on the
       | kernel as well. There's an effort from RedHat called KCI to
       | aggregate all of these reports.
        
         | Twirrim wrote:
         | There was a bug in a released kernel I ended up having to hunt
         | down back last summer. It required a very specific set of
         | circumstances to actually trigger the bug, but luckily for us
         | we found some obvious side effects from the bug such that it
         | was possible to get the relevant information via a very simple
         | statically compiled C program (there would be a certain value
         | under /sys).
         | 
         | I used that C program as the initramfs for qemu, with it
         | spinning up an instance based on the test kernel, and could
         | grep for what I wanted in the output to get a relevant exit
         | code.
         | 
         | Combine that git bisect's automatic bisecting process, and I
         | was able to automatically git bisect through a few thousand
         | commits in the kernel to find the cause. It only took it about
         | 50 minutes to find it in the end, which was helped a bunch by
         | ccache (and the sheer build parallelism granted by building on
         | a 52 core system).
         | 
         | That was a fun, somewhat out of the blue, task.
         | 
         | The process I took was based on https://ldpreload.com/blog/git-
         | bisect-run, with various adaptations to suit the needs and the
         | relevant build environment.
        
         | cat199 wrote:
         | so you have a very well tested boot sequence -
         | 
         | is this not a slightly better kernel equivalent of 'it builds,
         | ship it' ?
        
           | yjftsjthsd-h wrote:
           | > a slightly better kernel equivalent of 'it builds, ship it'
           | ?
           | 
           | Surely, "it _runs_ , ship it"? That seems quite a bit better.
        
       | umvi wrote:
       | So what happens when Linus Torvalds dies? Is there someone else
       | who will become BDFL?
        
         | LukeShu wrote:
         | Greg Kroah-Hartman has filled in before when Linus has had to
         | take time off.
        
       | thedance wrote:
       | Long way of saying "it's not".
        
         | GhettoMaestro wrote:
         | Fuck you.
         | 
         | I hate comments like this on HN.
         | 
         | The article clearly elaborates which methods/tools are used in
         | their test process.
        
         | DSingularity wrote:
         | No, it is.
         | 
         | https://github.com/linux-test-project/ltp
        
           | bonzini wrote:
           | LTP is only a small part of testing Linux.
        
           | 0xFFC wrote:
           | This has not been mainlined as far as I know.
        
             | recov wrote:
             | The commit history looks pretty healthy
        
               | yjftsjthsd-h wrote:
               | "Mainlined", not "maintained".
        
       | alkonaut wrote:
       | Why is there such little emphasis on "traditional" testing, that
       | is, regular unit tests? At least some portion of the code base is
       | surely suitable for normal unit tests. For example data
       | structures, scheduling algorithms, file systems, ...
        
         | ndesaulniers wrote:
         | How do I test a driver for which I do not possess the hardware?
        
           | vbezhenar wrote:
           | Write hardware emulation for VM with any behaviour you want
           | to test.
        
             | Bnshsysjab wrote:
             | Then I end up with a driver that conforms to emulated
             | hardware and not it's real counterpart
        
           | thedance wrote:
           | You write the software in such a way that instead of just
           | reading and writing registers or memory you exercise some set
           | of functions. In normal operation you pass the driver a set
           | of real functions that read and write real registers. In
           | testing you pass functions that do other things. This makes
           | it quite easy to exercise the features of the hardware that
           | are rarely seen in the wild. For example most IO adapters and
           | NICs have some kind of signal that they are overheating. Most
           | Linux drivers simply ignore or malfunction when these
           | conditions are raised, because the author of the driver never
           | got a chance to manually exercise that feature.
           | 
           | This is basic design for unit testing but it's impossible in
           | Linux because Linux lacks a zero-cost abstraction that would
           | let you mock out a device. C only has costly abstractions
           | such as tables of function pointers.
        
             | vbezhenar wrote:
             | You can compile object file in isolation and provide mocked
             | implementations for all imported functions.
        
         | 555dreams wrote:
         | I think many kernel developers view that as a problem as well.
         | KUnit hopefully will change this when it becomes more widely
         | used. I recommend more kernel developers check it out, it's
         | quite nice even in its current form!
        
         | varjag wrote:
         | Linux kernel project predates what you call traditional unit
         | testing practices+. Its success in the first decade and a half
         | coupled with pragmatics of hardware testing make the flow what
         | it is now.
         | 
         | + Regression testing was certainly known then, but it was not a
         | dogmatic movement yet.
        
           | alkonaut wrote:
           | I understand there are hurdles due to legacy, language, low
           | level etc. But if 1 or 2% of a huge code base is easily
           | testable, shouldn't it be? At least if/when regressions are
           | found in functionality that _can_ be easily testable (pure
           | functions etc) it would seem prudent to add regression tests
           | to prevent the thing from happening again. Even in a 30 year
           | old C code base.
        
         | EdSchouten wrote:
         | I think the main reason is that the Linux kernel (and similarly
         | the *BSD kernels) are written in a programming language (C)
         | that doesn't make it easy to do that. Code is often directly
         | built on top of other kernel subsystems without any dependency
         | injection whatsoever. This means that it's still possible to do
         | unit testing of parts of the kernel, but it takes a crazy
         | amount of effort, such as overriding symbols, overriding
         | include paths and provide stub headers, etc..
         | 
         | I am well aware that it's also possible to have dependency
         | injection in C by using structs with function pointers, but I
         | think we can all agree that it's a lot less pleasant to use
         | than C++ abstract base classes, Go interfaces or Rust traits.
         | This is why the Linux kernel only tends to use this sparingly
         | (e.g., inode operations).
        
           | eschaton wrote:
           | You don't need a dependency injection framework to write unit
           | tests, you just need cleanly separable units with well
           | defined interfaces.
        
           | [deleted]
        
           | joveian wrote:
           | This is a major advantage of NetBSD's Rump kernels that are
           | used for automated testing. Some people have tried doing the
           | same for Linux but I'm not sure if any such efforts are still
           | in progress.
        
           | rustybolt wrote:
           | This is probably the reason. I work at a place where most
           | software is written in C, and I see the same thing here:
           | literally all tests are either manual or integration tests.
           | Unfortunately, this also means that it takes about about half
           | a day to 'run the tests'.
        
         | cwzwarich wrote:
         | You could test data structures (which tend to be implemented
         | using macros), but any nontrivial subsystem of a monolithic
         | kernel lives in a web of dependencies with other subsystems.
         | This is especially true of Linux.
         | 
         | To solve this, you would need to either use a hierarchical
         | decomposition of subsystems or do some crazy mocking to run
         | subsystems outside of the full kernel.
         | 
         | There is a recent project (KUnit) to add a unit testing
         | framework to the Linux kernel, but it remains to be seen how
         | much adoption it will get.
        
           | yjftsjthsd-h wrote:
           | NetBSD has their rump kernel tech, which specifically exists
           | to run chunks of kernel code independently. It can do a lot
           | of neat things (I liked the "run netbsd drivers on other OSs"
           | trick, personally), but one of the big uses they've mentioned
           | is that it helps testing and development.
        
       ___________________________________________________________________
       (page generated 2020-03-28 23:00 UTC)