Kernel networking unit tests

Since Android 5.0, proper operation of the Android networking stack on Linux kernels requires a number of commits that were upstreamed relatively recently or have not yet made it upstream. It is not easy to manually verify the required kernel functionality or track the missing commits, so the Android team is sharing the tests it uses to ensure the kernel behaves as expected.

Reasons to run the tests

These tests exist for three main reasons:

  1. The exact version of the Linux kernel used on a device is typically device-specific, and it's difficult to know whether any kernel works properly without running the tests.
  2. Forward-porting and back-porting the kernel patches to different kernel versions or different device trees may introduce subtle issues that can be impossible to spot without running the tests.
  3. New networking features may require new kernel functionality or kernel bug fixes.

If the tests don't pass, the device's network stack behaves incorrectly, causing user-visible connectivity bugs (such as falling off Wi-Fi networks). The device will likely also fail Android Compatibility Test Suite (CTS) tests.

Use the tests

The tests use User-Mode Linux to boot the kernel as a process on a Linux host machine. See Establishing a Build Environment for suitable operating system versions. The unit test framework boots the kernel with an appropriate disk image and runs the tests from the host file system. The tests are written in Python and use TAP interfaces to exercise kernel behaviour and the socket API.

Compile the kernel for ARCH=um

For the tests to run, the kernel must compile for ARCH=um SUBARCH=x86_64. This is a supported architecture both upstream and in the common Android kernel trees (such as android-4.4). But sometimes device kernels do not compile in this mode because device trees contain device-specific or hardware-specific code in common files (for example sys/exit.c).

In many cases, it's sufficient to ensure that hardware-specific code is behind an #ifdef. Typically this should be an #ifdef on a configuration option that controls the specific feature relevant to the code. If there is no such configuration option, put hardware-specific code inside #ifndef CONFIG_UML blocks.

In general, fixing this should be the responsibility of the kernel tree provider (such as the chipset or SoC vendor). We're working with OEMs and vendors to ensure that current and future kernels compile for ARCH=um SUBARCH=x86_64 without requiring any changes.

Run the tests

The tests are at kernel/tests/net/test. It is recommended that the tests be run from AOSP main because they are the most up-to-date; in some cases, kernel features that are necessary for proper operation in a given Android release do not yet have full test coverage in the given release. For information on how to run the tests, see the kernel network test README file. Basically, from the top of your kernel tree, run:

ANDROID_TREE/kernel/tests/net/test/run_net_test.sh all_tests.sh

Pass the tests

The kernel network test Python source files contain comments that specify kernel commits that are known to be required to pass the tests. The tests should pass in the common kernel trees - all common kernel branches android-4.4 and higher - in the kernel/common project in AOSP. Therefore, passing the tests on a kernel is simply a matter of continuously merging from the corresponding common kernel branch.

Contributions

Report issues

Report any issues with the kernel network tests in the Android issue tracker with the Component-Networking label.

Document commits and adding tests

Report issues as described above, and if possible upload a change to fix the issue, if:

  • The tests do not pass on the common kernel trees
  • You find a necessary commit that is not mentioned in the source comments,
  • Getting the tests to pass on upstream kernels requires major changes
  • You believe that the tests are overspecified, or the test fail on future kernels
  • You'd like to add more tests or more coverage to existing tests.