The Art of Testing in the Linux Kernel

In the realm of software development, unit testing is an integral part of the development process, often used to ensure the correct functionality of individual components or units of code. However, when it comes to the Linux kernel—the heart of the Linux operating system—this traditional approach to testing takes a backseat. This might raise eyebrows for some, leading to the question: Why doesn’t the Linux kernel have unit tests? To answer this, we must dive deep into the unique structure, complexity, and design of the Linux kernel.

Understanding the Linux Kernel

The Linux kernel is a complex piece of software, responsible for managing the system’s resources and facilitating communication between hardware and software components. Given its role as the intermediary between software applications and the physical hardware of a computer, it must handle a broad spectrum of functionalities and hardware configurations. This intricacy and scale make it challenging to isolate individual components for unit testing, as one might do with a simpler application.

Hardware Dependencies and the Kernel

A significant proportion of the kernel code is hardware-specific, designed to interface with the myriad of hardware configurations that exist in the world. This means that for a test to be truly comprehensive, it would need to emulate a multitude of hardware setups, which is, in most instances, impractical. Additionally, the kernel’s tight coupling with the hardware means it’s often more meaningful to see how changes function in the broader context of a full system, as opposed to isolated units.

The Preference for Integration Testing

Instead of unit tests, the Linux kernel tends to favor a different kind of testing known as integration testing. This form of testing involves assessing the system as a whole rather than its individual components. In a system as complex and interdependent as the Linux kernel, this kind of testing often provides more meaningful insights. It allows for a better understanding of how changes might affect the system’s overall behavior, which is critical in a system as intertwined and complex as a computer’s operating system.

The Power of Runtime Testing

The Linux kernel utilizes a system for runtime testing where certain parts of the kernel can check themselves for consistency while the system is running. This dynamic form of testing is another way the kernel ensures its integrity without conventional unit tests. It enables the system to validate its behavior during operation, providing a powerful tool for maintaining system stability.

Leveraging the Contributor Community

One of the strengths of the Linux kernel—and indeed, open-source software as a whole—is its vibrant community of contributors. When a new patch is submitted, it’s expected that the contributor has thoroughly tested it in various scenarios. Moreover, the patch is reviewed and potentially tested by others before it’s accepted, adding another layer of verification to the process.

Regression Testing: The Kernel Self-Test Framework

The Linux kernel also employs a suite of regression tests, known as the kernel self-test framework. This allows developers to add tests that ensure the functionality they’ve added or changed continues to work as expected in the future. It provides a form of automated verification that helps prevent the introduction of errors when modifying the system.

Conclusion

While the Linux kernel might not use traditional unit tests, it is by no means an untested system. On the contrary, the Linux kernel is rigorously tested through a combination of methods that suit its complexity, scale, and the variety of environments in which it operates. It stands as a testament to the multifaceted nature of software testing, demonstrating that there’s no one-size-fits-all approach when it comes to ensuring the reliability and stability of software systems.

Written by AI, edited by human

A possible solution for no sound in Firefox on Ubuntu

computer speakers

For the last couple of days I was having a weird issue with Firefox on Ubuntu, namely there was no sound.

After searching all over the Internet and trying different solutions I finally found one that worked and I wanted to share it with you in case you find yourself in the same situation.

Note: before running the following command, please make sure you have a backup of your data!

Run this command in a terminal:

rm ~/.config/pulse/*

And restart your computer.

You should now have a working sound in Firefox.

How to get environment variables from a running process in Linux

In Linux, everything is a file. Even running processes are represented as files. You will find all the running processes in /proc/, with a separate directory for each process id.

ps aux | grep [process name]  # to get the process ID
cat /proc/[process ID]/environ | tr '\0' '\n'

What the above commands do, is:

  • Get the id of a process by name
  • print the contents of the “environ” file for that process
  • print each environment variable on a new line; tr stands for “translate”

SQL Database Course

I’ve recently finished a great database course “Mastery with SQL” which I recommend to anyone interested in learning modern SQL as well as some specific PostgreSQL features.

It starts with the SQL fundamentals and builds up all the way to window functions, views and query performance optimizations.

Although it isn’t free, I’ve learned a lot from finishing this course and I consider it is well worth the money.

Book Review: Level Up! The Guide to Great Video Game Design, 2nd Edition

If you ever wanted to make a video game, it is pretty easy nowadays having game engines and game development environments such as Unity 3D and Unreal Engine being free. There are also a lot of tutorials and documentation on how to use them.

When it comes to game design, there aren’t as many resources. In my opinion, one of the best book to learn about game design is “Level Up! The Guide to Great Video Game Design, 2nd Edition” by Scott Rogers.

Continue reading →

How to investigate Ubuntu slow boot

Investigating why Ubuntu boots slowly can be difficult. There are a lot of things that can go wrong: a lingering service, a bad config file, a wrong disk uuid in fstab and others.

In my opinion the easiest way to start is by using “systemd-analyze” which is part of systemd.
Since version 15.04, Ubuntu has switched from upstart to systemd as the default system and service manager. Systemd is not something specific to Ubuntu, but rather an industry standard that other major distributions have adopted as well: Debian, Fedora and CentOS to name a few.
“systemd-analyze” gives us information about what programs are run on startup and how much time they need to start.

Continue reading →

Change swap size in Ubuntu 18.04 or newer

[Updated July 26, 2020]: Change swapfile permission; Set swapfile in /etc/fstab.

Swap is a special area on your computer, which the operating system can use as additional RAM.
Starting with Ubuntu 17.04, the swap partition was replaced by a swap file. The main advantage of the swap file is easy resizing.

Note: before running the following commands, please make sure you have a backup of your data!

In the following example, we’ll extend the swap space available in the /swapfile from 4 GB to 8 GB.

  1. Turn off all swap processes
sudo swapoff -a

2. Resize the swap

sudo dd if=/dev/zero of=/swapfile bs=1G count=8

if = input file
of = output file
bs = block size
count = multiplier of blocks

3. Change permission

sudo chmod 600 /swapfile

4. Make the file usable as swap

sudo mkswap /swapfile

5. Activate the swap file

sudo swapon /swapfile

6. Edit /etc/fstab and add the new swapfile if it isn’t already there

/swapfile none swap sw 0 0

7. Check the amount of swap available

grep SwapTotal /proc/meminfo