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

Laszlo Ersek lersek at redhat.com
Tue Mar 12 10:18:53 UTC 2019


On 03/07/19 10:29, Michal Privoznik wrote:
> Test firmware description parsing so far.
> 
> The test files come from three locations:
> 1) ovmf-sb-keys.json and ovmf-sb.json come from OVMF
> package from RHEL-7 (with slight name change to reflect their
> features in filename too),
> 
> 2) bios.json and aavmf.json come form comments from

(a) s/form/from/

(b) s/comments/example JSON documents/ -- I'm emphasizing this because
QEMU itself is pretty strict about calling those comment sections
"Examples".

> firmware.json from qemu's git (3a0adfc9bf),
> 
> 3) ovmf.json is then copied from ovmf-sb.json and stripped
> of SECURE_BOOT and REQUIRES_SMM flags (plus OVMF path change).

The way you derived "ovmf.json" from "ovmf-sb.json" is not bad, but it
should be improved. I'll make comments on the file itself, below.

(c) Please don't forget to update this section of the commit message in
sync.

> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  tests/Makefile.am                        |  9 +++
>  tests/qemufirmwaredata/aavmf.json        | 35 +++++++++++
>  tests/qemufirmwaredata/bios.json         | 35 +++++++++++
>  tests/qemufirmwaredata/ovmf-sb-keys.json | 36 ++++++++++++
>  tests/qemufirmwaredata/ovmf-sb.json      | 35 +++++++++++
>  tests/qemufirmwaredata/ovmf.json         | 33 +++++++++++
>  tests/qemufirmwaretest.c                 | 75 ++++++++++++++++++++++++
>  7 files changed, 258 insertions(+)
>  create mode 100644 tests/qemufirmwaredata/aavmf.json
>  create mode 100644 tests/qemufirmwaredata/bios.json
>  create mode 100644 tests/qemufirmwaredata/ovmf-sb-keys.json
>  create mode 100644 tests/qemufirmwaredata/ovmf-sb.json
>  create mode 100644 tests/qemufirmwaredata/ovmf.json
>  create mode 100644 tests/qemufirmwaretest.c
> 
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 72f0420bab..b3449fa96b 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -132,6 +132,7 @@ EXTRA_DIST = \
>  	qemuxml2xmloutdata \
>  	qemustatusxml2xmldata \
>  	qemumemlockdata \
> +	qemufirmwaredata \
>  	secretxml2xmlin \
>  	securityselinuxhelperdata \
>  	securityselinuxlabeldata \
> @@ -292,6 +293,7 @@ test_programs += qemuxml2argvtest qemuxml2xmltest \
>  	qemublocktest \
>  	qemumigparamstest \
>  	qemusecuritytest \
> +	qemufirmwaretest \
>  	$(NULL)
>  test_helpers += qemucapsprobe
>  test_libraries += libqemumonitortestutils.la \
> @@ -700,6 +702,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 \
> @@ -713,6 +721,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/aavmf.json b/tests/qemufirmwaredata/aavmf.json
> new file mode 100644
> index 0000000000..114d1475a2
> --- /dev/null
> +++ b/tests/qemufirmwaredata/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/qemufirmwaredata/bios.json b/tests/qemufirmwaredata/bios.json
> new file mode 100644
> index 0000000000..137ff70779
> --- /dev/null
> +++ b/tests/qemufirmwaredata/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/ovmf-sb-keys.json b/tests/qemufirmwaredata/ovmf-sb-keys.json
> new file mode 100644
> index 0000000000..c804ac1038
> --- /dev/null
> +++ b/tests/qemufirmwaredata/ovmf-sb-keys.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/ovmf-sb.json b/tests/qemufirmwaredata/ovmf-sb.json
> new file mode 100644
> index 0000000000..5e8a94ae78
> --- /dev/null
> +++ b/tests/qemufirmwaredata/ovmf-sb.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/ovmf.json b/tests/qemufirmwaredata/ovmf.json
> new file mode 100644
> index 0000000000..9d53094778
> --- /dev/null
> +++ b/tests/qemufirmwaredata/ovmf.json
> @@ -0,0 +1,33 @@
> +{
> +    "description": "OVMF with SB+SMM, empty varstore",

"SB", "SMM", and "empty varstore" are each either wrong or useless to
mention here.

(d) So I suggest retrofitting the AAVMF description instead -- just say
"UEFI firmware for x86_64 virtual machines".

> +    "interface-types": [
> +        "uefi"
> +    ],
> +    "mapping": {
> +        "device": "flash",
> +        "executable": {
> +            "filename": "/usr/share/OVMF/OVMF_CODE.fd",
> +            "format": "raw"
> +        },
> +        "nvram-template": {
> +            "filename": "/usr/share/OVMF/OVMF_VARS.fd",
> +            "format": "raw"
> +        }
> +    },
> +    "targets": [
> +        {
> +            "architecture": "x86_64",
> +            "machines": [
> +                "pc-q35-*"

(e) Because this build does not include the SMM driver stack, we should
permit "pc-i440fx-*", in addition to "pc-q35-*".


(Points (d) and (e) are not really relevant for the self-test in
libvirt, it's just that the examples should be as "meaningful" as possible.)

Other than that, thanks for addressing my comments. With the above updates:

Acked-by: Laszlo Ersek <lersek at redhat.com>

Thanks
Laszlo

> +            ]
> +        }
> +    ],
> +    "features": [
> +        "acpi-s3",
> +        "amd-sev",
> +        "verbose-dynamic"
> +    ],
> +    "tags": [
> +
> +    ]
> +}
> diff --git a/tests/qemufirmwaretest.c b/tests/qemufirmwaretest.c
> new file mode 100644
> index 0000000000..176cf0920d
> --- /dev/null
> +++ b/tests/qemufirmwaretest.c
> @@ -0,0 +1,75 @@
> +#include <config.h>
> +
> +#include "testutils.h"
> +#include "qemu/qemu_firmware.h"
> +
> +#define VIR_FROM_THIS VIR_FROM_QEMU
> +
> +/* A very basic test. Parse given JSON firmware description into
> + * an internal structure, format it back and compare with the
> + * contents of the file (minus some keys that are not parsed).
> + */
> +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);
> +}
> +
> +
> +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("bios.json");
> +    DO_PARSE_TEST("ovmf-sb-keys.json");
> +    DO_PARSE_TEST("ovmf-sb.json");
> +    DO_PARSE_TEST("ovmf.json");
> +    DO_PARSE_TEST("aavmf.json");
> +
> +    return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
> +}
> +
> +
> +VIR_TEST_MAIN(mymain);
> 




More information about the libvir-list mailing list