[libvirt] [PATCH v1 08/15] test: Introduce qemufirmwaretest

Laszlo Ersek lersek at redhat.com
Thu Feb 28 09:42:49 UTC 2019


On 02/27/19 11:04, Michal Privoznik wrote:
> Test firmware description parsing so far.
> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  tests/Makefile.am                      |  9 ++++
>  tests/qemufirmwaredata/40-bios.json    | 35 +++++++++++++
>  tests/qemufirmwaredata/50-ovmf-sb.json | 36 +++++++++++++
>  tests/qemufirmwaredata/60-ovmf.json    | 35 +++++++++++++
>  tests/qemufirmwaredata/70-aavmf.json   | 35 +++++++++++++
>  tests/qemufirmwaretest.c               | 70 ++++++++++++++++++++++++++
>  6 files changed, 220 insertions(+)
>  create mode 100644 tests/qemufirmwaredata/40-bios.json
>  create mode 100644 tests/qemufirmwaredata/50-ovmf-sb.json
>  create mode 100644 tests/qemufirmwaredata/60-ovmf.json
>  create mode 100644 tests/qemufirmwaredata/70-aavmf.json
>  create mode 100644 tests/qemufirmwaretest.c

If the test data files added in this patch are from the examples in
QEMU's "docs/interop/firmware.json", I suggest stating so in the commit
message, also identifying the QEMU commit that added those examples.

In addition, I wonder if the filenames should carry the double-digit
priority prefixes at once in this patch.

Even if they do, I'm thinking that aavmf shouldn't be ordered (by
priority prefix) behind ovmf, given that the qemu targets / machine
types they are suitable for are mutually exclusive.

Other than that, I have two superficial comments (questions) below,
because my knowledge of the libvirt test infrastructure is nonexistent
to minimal:

> 
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index c3f633cee0..d23a8c2812 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -132,6 +132,7 @@ EXTRA_DIST = \
>  	qemuxml2xmloutdata \
>  	qemustatusxml2xmldata \
>  	qemumemlockdata \
> +	qemufirmwaredata \
>  	secretxml2xmlin \
>  	securityselinuxhelperdata \
>  	securityselinuxlabeldata \
> @@ -291,6 +292,7 @@ test_programs += qemuxml2argvtest qemuxml2xmltest \
>  	qemublocktest \
>  	qemumigparamstest \
>  	qemusecuritytest \
> +	qemufirmwaretest \
>  	$(NULL)
>  test_helpers += qemucapsprobe
>  test_libraries += libqemumonitortestutils.la \
> @@ -698,6 +700,12 @@ qemusecuritytest_SOURCES = \
>  	testutilsqemu.h testutilsqemu.c
>  qemusecuritytest_LDADD = $(qemu_LDADDS) $(LDADDS)
>  
> +qemufirmwaretest_SOURCES = \
> +	qemufirmwaretest.c \
> +	testutils.h testutils.c \
> +	$(NULL)
> +qemufirmwaretest_LDADD = $(qemu_LDADDS) $(LDADDS)
> +
>  else ! WITH_QEMU
>  EXTRA_DIST += qemuxml2argvtest.c qemuxml2xmltest.c qemuargv2xmltest.c \
>  	domainsnapshotxml2xmltest.c \
> @@ -711,6 +719,7 @@ EXTRA_DIST += qemuxml2argvtest.c qemuxml2xmltest.c qemuargv2xmltest.c \
>  	qemumigparamstest.c \
>  	qemusecuritytest.c qemusecuritytest.h \
>  	qemusecuritymock.c \
> +	qemufirmwaretest.c \
>  	$(QEMUMONITORTESTUTILS_SOURCES)
>  endif ! WITH_QEMU
>  
> diff --git a/tests/qemufirmwaredata/40-bios.json b/tests/qemufirmwaredata/40-bios.json
> new file mode 100644
> index 0000000000..137ff70779
> --- /dev/null
> +++ b/tests/qemufirmwaredata/40-bios.json
> @@ -0,0 +1,35 @@
> +{
> +    "description": "SeaBIOS",
> +    "interface-types": [
> +        "bios"
> +    ],
> +    "mapping": {
> +        "device": "memory",
> +        "filename": "/usr/share/seabios/bios-256k.bin"
> +    },
> +    "targets": [
> +        {
> +            "architecture": "i386",
> +            "machines": [
> +                "pc-i440fx-*",
> +                "pc-q35-*"
> +            ]
> +        },
> +        {
> +            "architecture": "x86_64",
> +            "machines": [
> +                "pc-i440fx-*",
> +                "pc-q35-*"
> +            ]
> +        }
> +    ],
> +    "features": [
> +        "acpi-s3",
> +        "acpi-s4"
> +    ],
> +    "tags": [
> +        "CONFIG_BOOTSPLASH=n",
> +        "CONFIG_ROM_SIZE=256",
> +        "CONFIG_USE_SMM=n"
> +    ]
> +}
> diff --git a/tests/qemufirmwaredata/50-ovmf-sb.json b/tests/qemufirmwaredata/50-ovmf-sb.json
> new file mode 100644
> index 0000000000..c804ac1038
> --- /dev/null
> +++ b/tests/qemufirmwaredata/50-ovmf-sb.json
> @@ -0,0 +1,36 @@
> +{
> +    "description": "OVMF with SB+SMM, SB enabled, MS certs enrolled",
> +    "interface-types": [
> +        "uefi"
> +    ],
> +    "mapping": {
> +        "device": "flash",
> +        "executable": {
> +            "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
> +            "format": "raw"
> +        },
> +        "nvram-template": {
> +            "filename": "/usr/share/OVMF/OVMF_VARS.secboot.fd",
> +            "format": "raw"
> +        }
> +    },
> +    "targets": [
> +        {
> +            "architecture": "x86_64",
> +            "machines": [
> +                "pc-q35-*"
> +            ]
> +        }
> +    ],
> +    "features": [
> +        "acpi-s3",
> +        "amd-sev",
> +        "enrolled-keys",
> +        "requires-smm",
> +        "secure-boot",
> +        "verbose-dynamic"
> +    ],
> +    "tags": [
> +
> +    ]
> +}
> diff --git a/tests/qemufirmwaredata/60-ovmf.json b/tests/qemufirmwaredata/60-ovmf.json
> new file mode 100644
> index 0000000000..5e8a94ae78
> --- /dev/null
> +++ b/tests/qemufirmwaredata/60-ovmf.json
> @@ -0,0 +1,35 @@
> +{
> +    "description": "OVMF with SB+SMM, empty varstore",
> +    "interface-types": [
> +        "uefi"
> +    ],
> +    "mapping": {
> +        "device": "flash",
> +        "executable": {
> +            "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
> +            "format": "raw"
> +        },
> +        "nvram-template": {
> +            "filename": "/usr/share/OVMF/OVMF_VARS.fd",
> +            "format": "raw"
> +        }
> +    },
> +    "targets": [
> +        {
> +            "architecture": "x86_64",
> +            "machines": [
> +                "pc-q35-*"
> +            ]
> +        }
> +    ],
> +    "features": [
> +        "acpi-s3",
> +        "amd-sev",
> +        "requires-smm",
> +        "secure-boot",
> +        "verbose-dynamic"
> +    ],
> +    "tags": [
> +
> +    ]
> +}
> diff --git a/tests/qemufirmwaredata/70-aavmf.json b/tests/qemufirmwaredata/70-aavmf.json
> new file mode 100644
> index 0000000000..114d1475a2
> --- /dev/null
> +++ b/tests/qemufirmwaredata/70-aavmf.json
> @@ -0,0 +1,35 @@
> +{
> +    "description": "UEFI firmware for ARM64 virtual machines",
> +    "interface-types": [
> +        "uefi"
> +    ],
> +    "mapping": {
> +        "device": "flash",
> +        "executable": {
> +            "filename": "/usr/share/AAVMF/AAVMF_CODE.fd",
> +            "format": "raw"
> +        },
> +        "nvram-template": {
> +            "filename": "/usr/share/AAVMF/AAVMF_VARS.fd",
> +            "format": "raw"
> +        }
> +    },
> +    "targets": [
> +        {
> +            "architecture": "aarch64",
> +            "machines": [
> +                "virt-*"
> +            ]
> +        }
> +    ],
> +    "features": [
> +
> +    ],
> +    "tags": [
> +        "-a AARCH64",
> +        "-p ArmVirtPkg/ArmVirtQemu.dsc",
> +        "-t GCC48",
> +        "-b DEBUG",
> +        "-D DEBUG_PRINT_ERROR_LEVEL=0x80000000"
> +    ]
> +}
> diff --git a/tests/qemufirmwaretest.c b/tests/qemufirmwaretest.c
> new file mode 100644
> index 0000000000..0c5fb1e55a
> --- /dev/null
> +++ b/tests/qemufirmwaretest.c
> @@ -0,0 +1,70 @@
> +#include <config.h>
> +
> +#include "testutils.h"
> +#include "qemu/qemu_firmware.h"
> +
> +#define VIR_FROM_THIS VIR_FROM_QEMU
> +
> +static int
> +testParseFormatFW(const void *opaque)
> +{
> +    const char *filename = opaque;
> +    VIR_AUTOFREE(char *) path = NULL;
> +    VIR_AUTOPTR(qemuFirmware) fw = NULL;
> +    VIR_AUTOFREE(char *) buf = NULL;
> +    VIR_AUTOPTR(virJSONValue) json = NULL;
> +    VIR_AUTOFREE(char *) expected = NULL;
> +    VIR_AUTOFREE(char *) actual = NULL;
> +
> +    if (virAsprintf(&path, "%s/qemufirmwaredata/%s",
> +                    abs_srcdir, filename) < 0)
> +        return -1;
> +
> +    if (!(fw = qemuFirmwareParse(path)))
> +        return -1;
> +
> +    if (virFileReadAll(path,
> +                       1024 * 1024, /* 1MiB */
> +                       &buf) < 0)
> +        return -1;
> +
> +    if (!(json = virJSONValueFromString(buf)))
> +        return -1;
> +
> +    /* Description and tags are not parsed. */
> +    if (virJSONValueObjectRemoveKey(json, "description", NULL) < 0 ||
> +        virJSONValueObjectRemoveKey(json, "tags", NULL) < 0)
> +        return -1;
> +
> +    if (!(expected = virJSONValueToString(json, true)))
> +        return -1;
> +
> +    if (!(actual = qemuFirmwareFormat(fw)))
> +        return -1;
> +
> +    return virTestCompareToString(expected, actual);
> +}

Can you add a comment to the function about the general idea? Or is this
approach common for libvirt tests? I mean, to make heads or tails of
this function, I have to decipher what each step does, and what the
final comparison compares. It would be easier to read if you explained
the steps in a comment, and then we'd only have to verify the steps
against that documentation.

My other question: when does virJSONValueObjectRemoveKey() fail? I
assume it doesn't fail when the key isn't present.

Thanks,
Laszlo

> +
> +
> +static int
> +mymain(void)
> +{
> +    int ret = 0;
> +
> +#define DO_PARSE_TEST(filename) \
> +    do { \
> +        if (virTestRun("QEMU FW " filename, \
> +                       testParseFormatFW, filename) < 0) \
> +            ret = -1; \
> +    } while (0)
> +
> +    DO_PARSE_TEST("40-bios.json");
> +    DO_PARSE_TEST("50-ovmf-sb.json");
> +    DO_PARSE_TEST("60-ovmf.json");
> +    DO_PARSE_TEST("70-aavmf.json");
> +
> +    return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
> +}
> +
> +
> +VIR_TEST_MAIN(mymain);
> 




More information about the libvir-list mailing list