ncroxon / gnu-efi

Develop EFI applications for ARM-64, ARM-32, x86_64, IA-64 (IPF), IA-32 (x86), and MIPS platforms using the GNU toolchain and the EFI development environment.
42 stars 10 forks source link

Add build time QEMU/UEFI tests #26

Closed pbatard closed 3 months ago

pbatard commented 4 months ago

Now that we have GitHub Actions build, we can use them to perform runtime validation, at build time, of the UEFI executables we produce through QEMU, as well as make the build artefacts available for download.

To accomplish that, we first need to fix the MinGW builds, that were producing broken executables (hence the reason why you want to have runtime tests at build) as well as fix the output of the apps we are going to use for testing, that were producing unwanted extra lines. This is accomplished with the first 2 patches.

The next patch then enables the generation of the GitHub Actions artifacts, which we will need for testing, and the last patch adds the actual tests, where you will see, on GitHub Actions output, that an extra task for the tests is now run after a successful build.

The testing is designed to be flexible and easy to modify (to add more tests as needed), as the whole test sequence, expected output, and buildup/teardown is defined in the test_list.txt file. This is based on what I already use in uefi-md5sum.

Basically, a test entry in that file starts with a # line that defines the display name for the test, and bash commands prefixed by > or <, that are used for buildup and teardown respectively, and, without any prefix, the expected text output of the test. Some shell variables ($UEFI_DIR and $UEFI_ARCH) can also be used in the bash commands.

Since we run UEFI applications and not UEFI bootloaders, most of the buildup is designed to create a startup.nsh Shell script that will be automatically executed by the Shell before we shutdown the QEMU UEFI firmware with reset -s (since we need to exit QEMU so that we don't error on a timeout, which is also detected).

This text file can then be converted to a series of bash scripts through gen_tests.sh, which are then run through the run_tests.sh script, which then produces an output similar to:

Test #001: ConOut text output...                                [PASS]
Test #002: Test args...                                         [PASS]
Test #003: Print args...                                        [PASS]

===============================================================================
# Test summary for gnu-efi
===============================================================================
# TOTAL: 3
# PASS:  3
# FAIL:  0
# ERROR: 0
===============================================================================

This is the output you will see, for each arch, in the Run tests step of the tests action.

At this stage, this testing obviously relies on elements that need to be sourced from third-parties, namely the AVMF/OVMF firmwares, a copy of which (along with their provenance) can be found at https://github.com/pbatard/EfiFs/tree/gh-pages/AAVMF and https://github.com/pbatard/EfiFs/tree/gh-pages/OVMF which is the content behind the https://efi.akeo.ie URL and that have been sourced from Debian packages, as well as the UEFI Shell, for which I also provide executables, built directly from stable EDK2 builds through GitHub Actions, at https://github.com/pbatard/UEFI-Shell.

For now, only x64, ia32, aa64 and arm are being tested, but I'll see if I can work on adding riscv64 at a later date.

Hopefully, this will help detect regressions as they arise.