[PATCH v2 0/9] tests: Add testing of qemu migration cookie

Add testing of migration cookie as we don't have any schema or examples of it to prevent breakage and help with development. v2: - no longer depends on the somewhat controversial GHashTable refactor - removed leftover commented out code in patch 2 Peter Krempa (9): qemuxml2xmltest: Remove 'WITH_QEMU' conditional qemuxml2xmltest: Split out status XML testing to qemustatusxml2xmltest.c qemu_migration_cookie: Make header standalone qemu_migration_cookie: Export qemuMigrationCookieXMLFormat for tests tests: Add mock library for virGetHostname and virGetHostUUID qemu_migration_cookie: Make cookie parsing robust against missing domain job tests: Add testing of qemu migration cookie qemumigrationcookiexmltest: Add synthetic test case virCPUDefFormatBufFull: Use virXMLFormatElement src/conf/cpu_conf.c | 16 +- src/qemu/qemu_migration_cookie.c | 4 +- src/qemu/qemu_migration_cookie.h | 9 + src/util/virutil.h | 2 +- src/util/viruuid.h | 2 +- tests/hostidmock.c | 36 ++ tests/meson.build | 3 + .../basic-xml2xml-in.xml | 6 + .../basic-xml2xml-out.xml | 9 + .../full-xml2xml-in.xml | 221 ++++++++++++ .../full-xml2xml-out.xml | 219 ++++++++++++ .../modern-dom-out-dest.xml | 12 + .../modern-dom-out-source.xml | 12 + tests/qemumigrationcookiexmltest.c | 337 ++++++++++++++++++ tests/qemustatusxml2xmltest.c | 155 ++++++++ tests/qemuxml2xmltest.c | 136 ++----- 16 files changed, 1044 insertions(+), 135 deletions(-) create mode 100644 tests/hostidmock.c create mode 100644 tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml create mode 100644 tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml create mode 100644 tests/qemumigrationcookiexmldata/full-xml2xml-in.xml create mode 100644 tests/qemumigrationcookiexmldata/full-xml2xml-out.xml create mode 100644 tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml create mode 100644 tests/qemumigrationcookiexmldata/modern-dom-out-source.xml create mode 100644 tests/qemumigrationcookiexmltest.c create mode 100644 tests/qemustatusxml2xmltest.c -- 2.26.2

The test is compiled only when the qemu driver is enabled so we don't need the conditional code. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemuxml2xmltest.c | 54 ++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 33 deletions(-) diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 44ac9fbce7..99e50f5f66 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -7,17 +7,15 @@ #include "testutils.h" -#ifdef WITH_QEMU +#include "internal.h" +#include "qemu/qemu_domain_address.h" +#include "qemu/qemu_domain.h" +#include "testutilsqemu.h" +#include "virstring.h" +#include "virfilewrapper.h" +#include "configmake.h" -# include "internal.h" -# include "qemu/qemu_domain_address.h" -# include "qemu/qemu_domain.h" -# include "testutilsqemu.h" -# include "virstring.h" -# include "virfilewrapper.h" -# include "configmake.h" - -# define VIR_FROM_THIS VIR_FROM_NONE +#define VIR_FROM_THIS VIR_FROM_NONE static virQEMUDriver driver; @@ -125,7 +123,7 @@ testInfoSetStatusPaths(struct testQemuInfo *info) } -# define FAKEROOTDIRTEMPLATE abs_builddir "/fakerootdir-XXXXXX" +#define FAKEROOTDIRTEMPLATE abs_builddir "/fakerootdir-XXXXXX" static int mymain(void) @@ -174,7 +172,7 @@ mymain(void) virSetConnectSecret(conn); virSetConnectStorage(conn); -# define DO_TEST_INTERNAL(_name, suffix, when, ...) \ +#define DO_TEST_INTERNAL(_name, suffix, when, ...) \ do { \ static struct testQemuInfo info = { \ .name = _name, \ @@ -209,38 +207,38 @@ mymain(void) testQemuInfoClear(&info); \ } while (0) -# define DO_TEST_CAPS_INTERNAL(name, arch, ver, ...) \ +#define DO_TEST_CAPS_INTERNAL(name, arch, ver, ...) \ DO_TEST_INTERNAL(name, "." arch "-" ver, WHEN_BOTH, \ ARG_CAPS_ARCH, arch, \ ARG_CAPS_VER, ver, \ __VA_ARGS__) -# define DO_TEST_CAPS_ARCH_LATEST_FULL(name, arch, ...) \ +#define DO_TEST_CAPS_ARCH_LATEST_FULL(name, arch, ...) \ DO_TEST_CAPS_INTERNAL(name, arch, "latest", __VA_ARGS__) -# define DO_TEST_CAPS_ARCH_VER_FULL(name, arch, ver, ...) \ +#define DO_TEST_CAPS_ARCH_VER_FULL(name, arch, ver, ...) \ DO_TEST_CAPS_INTERNAL(name, arch, ver, __VA_ARGS__) -# define DO_TEST_CAPS_ARCH_LATEST(name, arch) \ +#define DO_TEST_CAPS_ARCH_LATEST(name, arch) \ DO_TEST_CAPS_ARCH_LATEST_FULL(name, arch, ARG_END) -# define DO_TEST_CAPS_ARCH_VER(name, arch, ver) \ +#define DO_TEST_CAPS_ARCH_VER(name, arch, ver) \ DO_TEST_CAPS_ARCH_VER_FULL(name, arch, ver, ARG_END) -# define DO_TEST_CAPS_LATEST(name) \ +#define DO_TEST_CAPS_LATEST(name) \ DO_TEST_CAPS_ARCH_LATEST(name, "x86_64") -# define DO_TEST_CAPS_VER(name, ver) \ +#define DO_TEST_CAPS_VER(name, ver) \ DO_TEST_CAPS_ARCH_VER(name, "x86_64", ver) -# define DO_TEST_FULL(name, when, ...) \ +#define DO_TEST_FULL(name, when, ...) \ DO_TEST_INTERNAL(name, "", when, __VA_ARGS__) -# define DO_TEST(name, ...) \ +#define DO_TEST(name, ...) \ DO_TEST_FULL(name, WHEN_BOTH, \ ARG_QEMU_CAPS, __VA_ARGS__, QEMU_CAPS_LAST) -# define NONE QEMU_CAPS_LAST +#define NONE QEMU_CAPS_LAST /* Unset or set all envvars here that are copied in qemudBuildCommandLine * using ADD_ENV_COPY, otherwise these tests may fail due to unexpected @@ -1423,7 +1421,7 @@ mymain(void) QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_MCH_EXTENDED_TSEG_MBYTES); -# define DO_TEST_STATUS(_name) \ +#define DO_TEST_STATUS(_name) \ do { \ static struct testQemuInfo info = { \ .name = _name, \ @@ -1530,13 +1528,3 @@ VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("virrandom"), VIR_TEST_MOCK("domaincaps"), VIR_TEST_MOCK("virdeterministichash")) - -#else - -int -main(void) -{ - return EXIT_AM_SKIP; -} - -#endif /* WITH_QEMU */ -- 2.26.2

On a Wednesday in 2020, Peter Krempa wrote:
The test is compiled only when the qemu driver is enabled so we don't need the conditional code.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemuxml2xmltest.c | 54 ++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 33 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Separate the test files. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/meson.build | 1 + tests/qemustatusxml2xmltest.c | 155 ++++++++++++++++++++++++++++++++++ tests/qemuxml2xmltest.c | 84 ------------------ 3 files changed, 156 insertions(+), 84 deletions(-) create mode 100644 tests/qemustatusxml2xmltest.c diff --git a/tests/meson.build b/tests/meson.build index a59002c083..56a916c090 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -454,6 +454,7 @@ if conf.has('WITH_QEMU') { 'name': 'qemuvhostusertest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_file_wrapper_lib ] }, { 'name': 'qemuxml2argvtest', 'link_with': [ test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, { 'name': 'qemuxml2xmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, + { 'name': 'qemustatusxml2xmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, ] endif diff --git a/tests/qemustatusxml2xmltest.c b/tests/qemustatusxml2xmltest.c new file mode 100644 index 0000000000..0fcee34051 --- /dev/null +++ b/tests/qemustatusxml2xmltest.c @@ -0,0 +1,155 @@ +#include <config.h> + +#include <unistd.h> + +#include <sys/types.h> +#include <fcntl.h> + +#include "testutils.h" + +#include "internal.h" +#include "testutilsqemu.h" +#include "configmake.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +static virQEMUDriver driver; + +static int +testCompareStatusXMLToXMLFiles(const void *opaque) +{ + const struct testQemuInfo *data = opaque; + virDomainObjPtr obj = NULL; + g_autofree char *actual = NULL; + int ret = -1; + + if (!(obj = virDomainObjParseFile(data->infile, driver.xmlopt, + VIR_DOMAIN_DEF_PARSE_STATUS | + VIR_DOMAIN_DEF_PARSE_ACTUAL_NET | + VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES | + VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE | + VIR_DOMAIN_DEF_PARSE_ALLOW_POST_PARSE_FAIL))) { + VIR_TEST_DEBUG("\nfailed to parse '%s'", data->infile); + goto cleanup; + } + + if (!(actual = virDomainObjFormat(obj, driver.xmlopt, + VIR_DOMAIN_DEF_FORMAT_SECURE | + VIR_DOMAIN_DEF_FORMAT_STATUS | + VIR_DOMAIN_DEF_FORMAT_ACTUAL_NET | + VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES | + VIR_DOMAIN_DEF_FORMAT_CLOCK_ADJUST))) { + VIR_TEST_DEBUG("\nfailed to format back '%s'", data->infile); + goto cleanup; + } + + if (virTestCompareToFile(actual, data->outfile) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virDomainObjEndAPI(&obj); + return ret; +} + + +static const char *statusPath = abs_srcdir "/qemustatusxml2xmldata/"; + +static void +testInfoSetStatusPaths(struct testQemuInfo *info) +{ + info->infile = g_strdup_printf("%s%s-in.xml", statusPath, info->name); + info->outfile = g_strdup_printf("%s%s-out.xml", statusPath, info->name); +} + + +#define FAKEROOTDIRTEMPLATE abs_builddir "/fakerootdir-XXXXXX" + +static int +mymain(void) +{ + int ret = 0; + g_autofree char *fakerootdir = NULL; + g_autoptr(virQEMUDriverConfig) cfg = NULL; + g_autoptr(virHashTable) capslatest = NULL; + g_autoptr(virConnect) conn = NULL; + + capslatest = testQemuGetLatestCaps(); + if (!capslatest) + return EXIT_FAILURE; + + fakerootdir = g_strdup(FAKEROOTDIRTEMPLATE); + + if (!g_mkdtemp(fakerootdir)) { + fprintf(stderr, "Cannot create fakerootdir"); + abort(); + } + + g_setenv("LIBVIRT_FAKE_ROOT_DIR", fakerootdir, TRUE); + + if (qemuTestDriverInit(&driver) < 0) + return EXIT_FAILURE; + + cfg = virQEMUDriverGetConfig(&driver); + driver.privileged = true; + + if (!(conn = virGetConnect())) + goto cleanup; + + virSetConnectInterface(conn); + virSetConnectNetwork(conn); + virSetConnectNWFilter(conn); + virSetConnectNodeDev(conn); + virSetConnectSecret(conn); + virSetConnectStorage(conn); + +#define DO_TEST_STATUS(_name) \ + do { \ + static struct testQemuInfo info = { \ + .name = _name, \ + }; \ + if (testQemuInfoSetArgs(&info, capslatest, \ + ARG_QEMU_CAPS, QEMU_CAPS_LAST, \ + ARG_END) < 0 || \ + qemuTestCapsCacheInsert(driver.qemuCapsCache, info.qemuCaps) < 0) { \ + VIR_TEST_DEBUG("Failed to generate status test data for '%s'", _name); \ + return -1; \ + } \ + testInfoSetStatusPaths(&info); \ +\ + if (virTestRun("QEMU status XML-2-XML " _name, \ + testCompareStatusXMLToXMLFiles, &info) < 0) \ + ret = -1; \ +\ + testQemuInfoClear(&info); \ + } while (0) + + + DO_TEST_STATUS("blockjob-mirror"); + DO_TEST_STATUS("vcpus-multi"); + DO_TEST_STATUS("modern"); + DO_TEST_STATUS("migration-out-nbd"); + DO_TEST_STATUS("migration-in-params"); + DO_TEST_STATUS("migration-out-params"); + DO_TEST_STATUS("migration-out-nbd-tls"); + DO_TEST_STATUS("upgrade"); + + DO_TEST_STATUS("blockjob-blockdev"); + + DO_TEST_STATUS("backup-pull"); + + cleanup: + if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) + virFileDeleteTree(fakerootdir); + + qemuTestDriverFree(&driver); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIR_TEST_MAIN_PRELOAD(mymain, + VIR_TEST_MOCK("virpci"), + VIR_TEST_MOCK("virrandom"), + VIR_TEST_MOCK("domaincaps"), + VIR_TEST_MOCK("virdeterministichash")) diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 99e50f5f66..1240ef389e 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -48,45 +48,6 @@ testXML2XMLInactive(const void *opaque) } -static int -testCompareStatusXMLToXMLFiles(const void *opaque) -{ - const struct testQemuInfo *data = opaque; - virDomainObjPtr obj = NULL; - g_autofree char *actual = NULL; - int ret = -1; - - if (!(obj = virDomainObjParseFile(data->infile, driver.xmlopt, - VIR_DOMAIN_DEF_PARSE_STATUS | - VIR_DOMAIN_DEF_PARSE_ACTUAL_NET | - VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES | - VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE | - VIR_DOMAIN_DEF_PARSE_ALLOW_POST_PARSE_FAIL))) { - VIR_TEST_DEBUG("\nfailed to parse '%s'", data->infile); - goto cleanup; - } - - if (!(actual = virDomainObjFormat(obj, driver.xmlopt, - VIR_DOMAIN_DEF_FORMAT_SECURE | - VIR_DOMAIN_DEF_FORMAT_STATUS | - VIR_DOMAIN_DEF_FORMAT_ACTUAL_NET | - VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES | - VIR_DOMAIN_DEF_FORMAT_CLOCK_ADJUST))) { - VIR_TEST_DEBUG("\nfailed to format back '%s'", data->infile); - goto cleanup; - } - - if (virTestCompareToFile(actual, data->outfile) < 0) - goto cleanup; - - ret = 0; - - cleanup: - virDomainObjEndAPI(&obj); - return ret; -} - - static int testInfoSetPaths(struct testQemuInfo *info, const char *suffix, @@ -113,16 +74,6 @@ testInfoSetPaths(struct testQemuInfo *info, } -static const char *statusPath = abs_srcdir "/qemustatusxml2xmldata/"; - -static void -testInfoSetStatusPaths(struct testQemuInfo *info) -{ - info->infile = g_strdup_printf("%s%s-in.xml", statusPath, info->name); - info->outfile = g_strdup_printf("%s%s-out.xml", statusPath, info->name); -} - - #define FAKEROOTDIRTEMPLATE abs_builddir "/fakerootdir-XXXXXX" static int @@ -1421,41 +1372,6 @@ mymain(void) QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_MCH_EXTENDED_TSEG_MBYTES); -#define DO_TEST_STATUS(_name) \ - do { \ - static struct testQemuInfo info = { \ - .name = _name, \ - }; \ - if (testQemuInfoSetArgs(&info, capslatest, \ - ARG_QEMU_CAPS, QEMU_CAPS_LAST, \ - ARG_END) < 0 || \ - qemuTestCapsCacheInsert(driver.qemuCapsCache, info.qemuCaps) < 0) { \ - VIR_TEST_DEBUG("Failed to generate status test data for '%s'", _name); \ - return -1; \ - } \ - testInfoSetStatusPaths(&info); \ -\ - if (virTestRun("QEMU status XML-2-XML " _name, \ - testCompareStatusXMLToXMLFiles, &info) < 0) \ - ret = -1; \ -\ - testQemuInfoClear(&info); \ - } while (0) - - - DO_TEST_STATUS("blockjob-mirror"); - DO_TEST_STATUS("vcpus-multi"); - DO_TEST_STATUS("modern"); - DO_TEST_STATUS("migration-out-nbd"); - DO_TEST_STATUS("migration-in-params"); - DO_TEST_STATUS("migration-out-params"); - DO_TEST_STATUS("migration-out-nbd-tls"); - DO_TEST_STATUS("upgrade"); - - DO_TEST_STATUS("blockjob-blockdev"); - - DO_TEST_STATUS("backup-pull"); - DO_TEST("vhost-vsock", QEMU_CAPS_DEVICE_VHOST_VSOCK); DO_TEST("vhost-vsock-auto", QEMU_CAPS_DEVICE_VHOST_VSOCK); DO_TEST("vhost-vsock-ccw", QEMU_CAPS_DEVICE_VHOST_VSOCK, -- 2.26.2

On a Wednesday in 2020, Peter Krempa wrote:
Separate the test files.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/meson.build | 1 + tests/qemustatusxml2xmltest.c | 155 ++++++++++++++++++++++++++++++++++ tests/qemuxml2xmltest.c | 84 ------------------ 3 files changed, 156 insertions(+), 84 deletions(-) create mode 100644 tests/qemustatusxml2xmltest.c
diff --git a/tests/meson.build b/tests/meson.build index a59002c083..56a916c090 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -454,6 +454,7 @@ if conf.has('WITH_QEMU') { 'name': 'qemuvhostusertest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_file_wrapper_lib ] }, { 'name': 'qemuxml2argvtest', 'link_with': [ test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, { 'name': 'qemuxml2xmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, + { 'name': 'qemustatusxml2xmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] },
This breaks the alphabetical sorting of this section.
] endif
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Include qemu_domain.h and qemu_domainjob.h as the types from those headers are used by this header. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration_cookie.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qemu/qemu_migration_cookie.h b/src/qemu/qemu_migration_cookie.h index f2801b2704..040ed913d5 100644 --- a/src/qemu/qemu_migration_cookie.h +++ b/src/qemu/qemu_migration_cookie.h @@ -18,6 +18,8 @@ #pragma once +#include "qemu_domain.h" +#include "qemu_domainjob.h" #include "qemu_migration_params.h" #include "virenum.h" -- 2.26.2

On a Wednesday in 2020, Peter Krempa wrote:
Include qemu_domain.h and qemu_domainjob.h as the types from those headers are used by this header.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration_cookie.h | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration_cookie.c | 2 +- src/qemu/qemu_migration_cookie.h | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c index 39445ef8de..9ede125cfd 100644 --- a/src/qemu/qemu_migration_cookie.c +++ b/src/qemu/qemu_migration_cookie.c @@ -758,7 +758,7 @@ qemuMigrationCookieNBDXMLFormat(qemuMigrationCookieNBDPtr nbd, } -static int +int qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver, virQEMUCapsPtr qemuCaps, virBufferPtr buf, diff --git a/src/qemu/qemu_migration_cookie.h b/src/qemu/qemu_migration_cookie.h index 040ed913d5..ecd1a01375 100644 --- a/src/qemu/qemu_migration_cookie.h +++ b/src/qemu/qemu_migration_cookie.h @@ -185,3 +185,10 @@ qemuMigrationCookieAddPersistent(qemuMigrationCookiePtr mig, virDomainDefPtr qemuMigrationCookieGetPersistent(qemuMigrationCookiePtr mig); + +/* qemuMigrationCookieXMLFormat is exported for test use only! */ +int +qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver, + virQEMUCapsPtr qemuCaps, + virBufferPtr buf, + qemuMigrationCookiePtr mig); -- 2.26.2

On a Wednesday in 2020, Peter Krempa wrote:
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration_cookie.c | 2 +- src/qemu/qemu_migration_cookie.h | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The 'qemu_migration_cookie' module uses these. Provide a stable override for tests. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/util/virutil.h | 2 +- src/util/viruuid.h | 2 +- tests/hostidmock.c | 36 ++++++++++++++++++++++++++++++++++++ tests/meson.build | 1 + 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 tests/hostidmock.c diff --git a/src/util/virutil.h b/src/util/virutil.h index 8b0e38e335..46328727c1 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -92,7 +92,7 @@ static inline int pthread_sigmask(int how, } #endif -char *virGetHostname(void); +char *virGetHostname(void) G_GNUC_NO_INLINE; char *virGetHostnameQuiet(void); char *virGetUserDirectory(void); diff --git a/src/util/viruuid.h b/src/util/viruuid.h index 6ea01bb7c1..5d64e58405 100644 --- a/src/util/viruuid.h +++ b/src/util/viruuid.h @@ -41,7 +41,7 @@ int virSetHostUUIDStr(const char *host_uuid); -int virGetHostUUID(unsigned char *host_uuid) ATTRIBUTE_NONNULL(1); +int virGetHostUUID(unsigned char *host_uuid) ATTRIBUTE_NONNULL(1) G_GNUC_NO_INLINE; int virUUIDIsValid(unsigned char *uuid); diff --git a/tests/hostidmock.c b/tests/hostidmock.c new file mode 100644 index 0000000000..bdf61c18ad --- /dev/null +++ b/tests/hostidmock.c @@ -0,0 +1,36 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include "util/virutil.h" +#include "util/viruuid.h" + +char * +virGetHostname(void) +{ + return g_strdup("hostname"); +} + + +int +virGetHostUUID(unsigned char *uuid) +{ + /* uuidgen --sha1 --namespace @dns --name "hostname" */ + const char *fakeuuid = "4a802f00-4cba-5df6-9679-a08c4c5b577f"; + + return virUUIDParse(fakeuuid, uuid); +} diff --git a/tests/meson.build b/tests/meson.build index 56a916c090..818fce65f3 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -106,6 +106,7 @@ if conf.has('WITH_QEMU') { 'name': 'qemucpumock' }, { 'name': 'qemuhotplugmock' }, { 'name': 'qemuxml2argvmock' }, + { 'name': 'hostidmock' }, ] endif -- 2.26.2

On a Wednesday in 2020, Peter Krempa wrote:
The 'qemu_migration_cookie' module uses these. Provide a stable override for tests.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/util/virutil.h | 2 +- src/util/viruuid.h | 2 +- tests/hostidmock.c | 36 ++++++++++++++++++++++++++++++++++++ tests/meson.build | 1 + 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 tests/hostidmock.c
diff --git a/src/util/virutil.h b/src/util/virutil.h index 8b0e38e335..46328727c1 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -92,7 +92,7 @@ static inline int pthread_sigmask(int how, } #endif
-char *virGetHostname(void); +char *virGetHostname(void) G_GNUC_NO_INLINE; char *virGetHostnameQuiet(void);
char *virGetUserDirectory(void); diff --git a/src/util/viruuid.h b/src/util/viruuid.h index 6ea01bb7c1..5d64e58405 100644 --- a/src/util/viruuid.h +++ b/src/util/viruuid.h @@ -41,7 +41,7 @@
int virSetHostUUIDStr(const char *host_uuid); -int virGetHostUUID(unsigned char *host_uuid) ATTRIBUTE_NONNULL(1); +int virGetHostUUID(unsigned char *host_uuid) ATTRIBUTE_NONNULL(1) G_GNUC_NO_INLINE;
int virUUIDIsValid(unsigned char *uuid);
diff --git a/tests/hostidmock.c b/tests/hostidmock.c new file mode 100644 index 0000000000..bdf61c18ad --- /dev/null +++ b/tests/hostidmock.c @@ -0,0 +1,36 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include "util/virutil.h" +#include "util/viruuid.h" + +char * +virGetHostname(void) +{ + return g_strdup("hostname"); +} + + +int +virGetHostUUID(unsigned char *uuid) +{ + /* uuidgen --sha1 --namespace @dns --name "hostname" */ + const char *fakeuuid = "4a802f00-4cba-5df6-9679-a08c4c5b577f"; + + return virUUIDParse(fakeuuid, uuid); +} diff --git a/tests/meson.build b/tests/meson.build index 56a916c090..818fce65f3 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -106,6 +106,7 @@ if conf.has('WITH_QEMU') { 'name': 'qemucpumock' }, { 'name': 'qemuhotplugmock' }, { 'name': 'qemuxml2argvmock' }, + { 'name': 'hostidmock' },
'virhostidmock', please Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

In testing code we don't properly populate the job sometimes. If it isn't populated we should not touch it though in the migration cookie code. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration_cookie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c index 9ede125cfd..cebd66a5d7 100644 --- a/src/qemu/qemu_migration_cookie.c +++ b/src/qemu/qemu_migration_cookie.c @@ -1429,7 +1429,7 @@ qemuMigrationCookieParse(virQEMUDriverPtr driver, } } - if (flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobInfo) + if (flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobInfo && priv->job.current) mig->jobInfo->operation = priv->job.current->operation; return g_steal_pointer(&mig); -- 2.26.2

On a Wednesday in 2020, Peter Krempa wrote:
In testing code we don't properly populate the job sometimes. If it isn't populated we should not touch it though in the migration cookie code.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration_cookie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Migration cookie transports a lot of information but there are no tests for it. The test supports both xml2xml testing and also testing of the population of the migration cookie data from a domain object, although that option is not very useful as many things are collected from running qemu and thus can't be tested efficiently here. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/meson.build | 1 + .../basic-xml2xml-in.xml | 6 + .../basic-xml2xml-out.xml | 9 + .../modern-dom-out-dest.xml | 12 + .../modern-dom-out-source.xml | 12 + tests/qemumigrationcookiexmltest.c | 336 ++++++++++++++++++ 6 files changed, 376 insertions(+) create mode 100644 tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml create mode 100644 tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml create mode 100644 tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml create mode 100644 tests/qemumigrationcookiexmldata/modern-dom-out-source.xml create mode 100644 tests/qemumigrationcookiexmltest.c diff --git a/tests/meson.build b/tests/meson.build index 818fce65f3..68a309ebfb 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -456,6 +456,7 @@ if conf.has('WITH_QEMU') { 'name': 'qemuxml2argvtest', 'link_with': [ test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, { 'name': 'qemuxml2xmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, { 'name': 'qemustatusxml2xmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, + { 'name': 'qemumigrationcookiexmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, ] endif diff --git a/tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml b/tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml new file mode 100644 index 0000000000..5722bafe89 --- /dev/null +++ b/tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml @@ -0,0 +1,6 @@ +<qemu-migration> + <name>upstream</name> + <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid> + <hostname>hostname2</hostname> + <hostuuid>8b3f4dc4-6a8e-5f9b-94a5-4c35babd8d95</hostuuid> +</qemu-migration> diff --git a/tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml b/tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml new file mode 100644 index 0000000000..42b351047e --- /dev/null +++ b/tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml @@ -0,0 +1,9 @@ +<qemu-migration> + <name>upstream</name> + <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid> + <hostname>hostname</hostname> + <hostuuid>4a802f00-4cba-5df6-9679-a08c4c5b577f</hostuuid> + <allowReboot value='default'/> + <capabilities> + </capabilities> +</qemu-migration> diff --git a/tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml b/tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml new file mode 100644 index 0000000000..ba84c65a3d --- /dev/null +++ b/tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml @@ -0,0 +1,12 @@ +<qemu-migration> + <name>upstream</name> + <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid> + <hostname>hostname2</hostname> + <hostuuid>8b3f4dc4-6a8e-5f9b-94a5-4c35babd8d95</hostuuid> + <feature name='memory-hotplug'/> + <feature name='cpu-hotplug'/> + <graphics type='spice' port='5900' listen='127.0.0.1' tlsPort='-1'/> + <allowReboot value='yes'/> + <capabilities> + </capabilities> +</qemu-migration> diff --git a/tests/qemumigrationcookiexmldata/modern-dom-out-source.xml b/tests/qemumigrationcookiexmldata/modern-dom-out-source.xml new file mode 100644 index 0000000000..ba84c65a3d --- /dev/null +++ b/tests/qemumigrationcookiexmldata/modern-dom-out-source.xml @@ -0,0 +1,12 @@ +<qemu-migration> + <name>upstream</name> + <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid> + <hostname>hostname2</hostname> + <hostuuid>8b3f4dc4-6a8e-5f9b-94a5-4c35babd8d95</hostuuid> + <feature name='memory-hotplug'/> + <feature name='cpu-hotplug'/> + <graphics type='spice' port='5900' listen='127.0.0.1' tlsPort='-1'/> + <allowReboot value='yes'/> + <capabilities> + </capabilities> +</qemu-migration> diff --git a/tests/qemumigrationcookiexmltest.c b/tests/qemumigrationcookiexmltest.c new file mode 100644 index 0000000000..d8ed8b253c --- /dev/null +++ b/tests/qemumigrationcookiexmltest.c @@ -0,0 +1,336 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include <unistd.h> + +#include <sys/types.h> +#include <fcntl.h> + +#include "testutils.h" + +#include "internal.h" +#include "testutilsqemu.h" +#include "configmake.h" + +#include "qemu/qemu_migration_cookie.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +static virQEMUDriver driver; + +static virBuffer testnamebuf = VIR_BUFFER_INITIALIZER; + +static const char * +tn(const char *str, ...) +{ + va_list ap; + + virBufferFreeAndReset(&testnamebuf); + virBufferAdd(&testnamebuf, str, -1); + + va_start(ap, str); + virBufferStrcatVArgs(&testnamebuf, ap); + va_end(ap); + + return virBufferCurrentContent(&testnamebuf); +} + + +struct testQemuMigrationCookieData { + const char *name; + char *inStatus; + virDomainObjPtr vm; + + unsigned int cookiePopulateFlags; + unsigned int cookieParseFlags; + + qemuMigrationParty cookiePopulateParty; + + char *xmlstr; + int xmlstrlen; + char *infile; + char *outfile; +}; + + +static int +testQemuMigrationCookiePopulate(const void *opaque) +{ + struct testQemuMigrationCookieData *data = (struct testQemuMigrationCookieData *) opaque; + g_autoptr(qemuMigrationCookie) cookie = NULL; + + if (!(cookie = qemuMigrationCookieNew(data->vm->def, NULL))) + return -1; + + /* doctor the hostname and uuid, so that the output can be simply used for + * the xml2xmltest where the parser validates UUID match (yuck) */ + g_free(cookie->localHostname); + cookie->localHostname = g_strdup("hostname2"); + + /* uuidgen --sha1 --namespace @dns --name "hostname2" */ + if (virUUIDParse("8b3f4dc4-6a8e-5f9b-94a5-4c35babd8d95", cookie->localHostuuid) < 0) { + VIR_TEST_DEBUG("\nfailed to parse fake UUID"); + return -1; + } + + /* allow re-run for checking both miration parties */ + g_clear_pointer(&data->xmlstr, g_free); + + if (qemuMigrationCookieFormat(cookie, + &driver, + data->vm, + data->cookiePopulateParty, + &data->xmlstr, + &data->xmlstrlen, + data->cookiePopulateFlags) < 0) { + VIR_TEST_DEBUG("\n failed to populate and format qemu migration cookie"); + return -1; + } + + if (virTestCompareToFile(data->xmlstr, data->outfile) < 0) + return -1; + + return 0; +} + + +static int +testQemuMigrationCookieParse(const void *opaque) +{ + struct testQemuMigrationCookieData *data = (struct testQemuMigrationCookieData *) opaque; + qemuDomainObjPrivatePtr priv = data->vm->privateData; + g_auto(virBuffer) actual = VIR_BUFFER_INITIALIZER; + g_autoptr(qemuMigrationCookie) cookie = NULL; + + if (!(cookie = qemuMigrationCookieParse(&driver, + data->vm->def, + NULL, + priv, + data->xmlstr, + data->xmlstrlen, + data->cookieParseFlags))) { + VIR_TEST_DEBUG("\nfailed to parse qemu migration cookie:\n%s\n", data->xmlstr); + return -1; + } + + /* set all flags so that formatter attempts to format everything */ + cookie->flags = ~0; + + if (qemuMigrationCookieXMLFormat(&driver, + priv->qemuCaps, + &actual, + cookie) < 0) { + VIR_TEST_DEBUG("\nfailed to format back qemu migration cookie"); + return -1; + } + + if (virTestCompareToFile(virBufferCurrentContent(&actual), data->outfile) < 0) + return -1; + + return 0; +} + + +static int +testQemuMigrationCookieDomInit(const void *opaque) +{ + struct testQemuMigrationCookieData *data = (struct testQemuMigrationCookieData *) opaque; + + if (!(data->vm = virDomainObjParseFile(data->inStatus, driver.xmlopt, + VIR_DOMAIN_DEF_PARSE_STATUS | + VIR_DOMAIN_DEF_PARSE_ACTUAL_NET | + VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES | + VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE | + VIR_DOMAIN_DEF_PARSE_ALLOW_POST_PARSE_FAIL))) { + VIR_TEST_DEBUG("\nfailed to parse status xml'%s'", data->inStatus); + return -1; + } + + return 0; +} + + +static int +testQemuMigrationCookieXMLLoad(const void *opaque) +{ + struct testQemuMigrationCookieData *data = (struct testQemuMigrationCookieData *) opaque; + + if (virTestLoadFile(data->infile, &data->xmlstr) < 0) + return -1; + + data->xmlstrlen = strlen(data->xmlstr) + 1; + + return 0; +} + + +static void +testQemuMigrationCookieDataFree(struct testQemuMigrationCookieData *data) +{ + if (!data) + return; + + g_free(data->xmlstr); + g_free(data->outfile); + g_free(data->infile); + g_free(data->inStatus); + virDomainObjEndAPI(&data->vm); + g_free(data); +} + + +static int +testQemuMigrationCookieDom2XML(const char *namesuffix, + const char *domxml, + unsigned int cookiePopulateFlags, + unsigned int cookieParseFlags) +{ + struct testQemuMigrationCookieData *data = g_new0(struct testQemuMigrationCookieData, 1); + int ret = 0; + + if (cookiePopulateFlags == 0) { + /* flags unsupported by default: + * - lockstate: internals are NULL in tests, causes crash + * - nbd: monitor not present + */ + unsigned int cookiePopulateFlagMask = QEMU_MIGRATION_COOKIE_LOCKSTATE | + QEMU_MIGRATION_COOKIE_NBD; + data->cookiePopulateFlags = ~cookiePopulateFlagMask; + } + + if (cookieParseFlags == 0) + data->cookieParseFlags = ~0; + + data->inStatus = g_strconcat(abs_srcdir, "/", domxml, NULL); + + /* load status XML as domain object */ + + if (virTestRun(tn("qemumigrationcookiedom2xml-load-", namesuffix, NULL), + testQemuMigrationCookieDomInit, data) < 0) + ret = -1; + + /* test dom -> migration cookie conversion for source */ + + data->cookiePopulateParty = QEMU_MIGRATION_SOURCE; + data->outfile = g_strconcat(abs_srcdir, "/qemumigrationcookiexmldata/", + namesuffix, "-dom-out-source.xml", NULL); + + if (virTestRun(tn("qemumigrationcookiedom2xml-source-populate-", namesuffix, NULL), + testQemuMigrationCookiePopulate, data) < 0) + ret = -1; + + /* test dom -> migration cookie conversion for destination */ + + g_free(data->outfile); + data->cookiePopulateParty = QEMU_MIGRATION_DESTINATION; + data->outfile = g_strconcat(abs_srcdir, "/qemumigrationcookiexmldata/", + namesuffix, "-dom-out-dest.xml", NULL); + + if (virTestRun(tn("qemumigrationcookiedom2xml-dest-populate-", namesuffix, NULL), + testQemuMigrationCookiePopulate, data) < 0) + ret = -1; + + testQemuMigrationCookieDataFree(data); + + return ret; +} + + +static int +testQemuMigrationCookieXML2XML(const char *name, + const char *statusxml, + unsigned int cookieParseFlags) +{ + struct testQemuMigrationCookieData *data = g_new0(struct testQemuMigrationCookieData, 1); + int ret = 0; + + if (cookieParseFlags == 0) + data->cookieParseFlags = ~0; + + data->inStatus = g_strconcat(abs_srcdir, "/", statusxml, NULL); + data->infile = g_strconcat(abs_srcdir, "/qemumigrationcookiexmldata/", + name, "-xml2xml-in.xml", NULL); + data->outfile = g_strconcat(abs_srcdir, "/qemumigrationcookiexmldata/", + name, "-xml2xml-out.xml", NULL); + + if (virTestRun(tn("qemumigrationcookieXML2XML-dom-", name, NULL), + testQemuMigrationCookieDomInit, data) < 0) + ret = -1; + + if (virTestRun(tn("qemumigrationcookieXML2XML-load-", name, NULL), + testQemuMigrationCookieXMLLoad, data) < 0) + ret = -1; + + if (virTestRun(tn("qemumigrationcookieXML2XML-parse-", name, NULL), + testQemuMigrationCookieParse, data) < 0) + ret = -1; + + testQemuMigrationCookieDataFree(data); + + return ret; +} + + +static int +mymain(void) +{ + int ret = 0; + g_autoptr(virQEMUDriverConfig) cfg = NULL; + g_autoptr(virHashTable) capslatest = NULL; + g_autoptr(virConnect) conn = NULL; + + capslatest = testQemuGetLatestCaps(); + if (!capslatest) + return EXIT_FAILURE; + + if (qemuTestDriverInit(&driver) < 0) + return EXIT_FAILURE; + + cfg = virQEMUDriverGetConfig(&driver); + driver.privileged = true; + + if (!(conn = virGetConnect())) + goto cleanup; + + virSetConnectInterface(conn); + virSetConnectNetwork(conn); + virSetConnectNWFilter(conn); + virSetConnectNodeDev(conn); + virSetConnectSecret(conn); + virSetConnectStorage(conn); + + if (testQemuMigrationCookieDom2XML("modern", "qemustatusxml2xmldata/modern-in.xml", 0, 0) < 0) + ret = -1; + + if (testQemuMigrationCookieXML2XML("basic", "qemustatusxml2xmldata/modern-in.xml", 0) < 0) + ret = -1; + + virBufferFreeAndReset(&testnamebuf); + + cleanup: + + qemuTestDriverFree(&driver); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIR_TEST_MAIN_PRELOAD(mymain, + VIR_TEST_MOCK("virpci"), + VIR_TEST_MOCK("virrandom"), + VIR_TEST_MOCK("domaincaps"), + VIR_TEST_MOCK("hostid")) -- 2.26.2

On a Wednesday in 2020, Peter Krempa wrote:
Migration cookie transports a lot of information but there are no tests for it.
The test supports both xml2xml testing and also testing of the population of the migration cookie data from a domain object, although that option is not very useful as many things are collected from running qemu and thus can't be tested efficiently here.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/meson.build | 1 + .../basic-xml2xml-in.xml | 6 + .../basic-xml2xml-out.xml | 9 + .../modern-dom-out-dest.xml | 12 + .../modern-dom-out-source.xml | 12 + tests/qemumigrationcookiexmltest.c | 336 ++++++++++++++++++ 6 files changed, 376 insertions(+) create mode 100644 tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml create mode 100644 tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml create mode 100644 tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml create mode 100644 tests/qemumigrationcookiexmldata/modern-dom-out-source.xml create mode 100644 tests/qemumigrationcookiexmltest.c
diff --git a/tests/meson.build b/tests/meson.build index 818fce65f3..68a309ebfb 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -456,6 +456,7 @@ if conf.has('WITH_QEMU') { 'name': 'qemuxml2argvtest', 'link_with': [ test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, { 'name': 'qemuxml2xmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, { 'name': 'qemustatusxml2xmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] }, + { 'name': 'qemumigrationcookiexmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] },
Same comment about ordering.
] endif
+ +#define VIR_FROM_THIS VIR_FROM_NONE + +static virQEMUDriver driver; + +static virBuffer testnamebuf = VIR_BUFFER_INITIALIZER; + +static const char * +tn(const char *str, ...)
This name is not very descriptive. How about testName?
+{ + va_list ap; + + virBufferFreeAndReset(&testnamebuf); + virBufferAdd(&testnamebuf, str, -1); + + va_start(ap, str); + virBufferStrcatVArgs(&testnamebuf, ap); + va_end(ap); + + return virBufferCurrentContent(&testnamebuf); +} + + +struct testQemuMigrationCookieData { + const char *name; + char *inStatus; + virDomainObjPtr vm; + + unsigned int cookiePopulateFlags; + unsigned int cookieParseFlags; + + qemuMigrationParty cookiePopulateParty; + + char *xmlstr; + int xmlstrlen; + char *infile; + char *outfile; +}; + + +static int +testQemuMigrationCookiePopulate(const void *opaque) +{ + struct testQemuMigrationCookieData *data = (struct testQemuMigrationCookieData *) opaque; + g_autoptr(qemuMigrationCookie) cookie = NULL; + + if (!(cookie = qemuMigrationCookieNew(data->vm->def, NULL))) + return -1; + + /* doctor the hostname and uuid, so that the output can be simply used for + * the xml2xmltest where the parser validates UUID match (yuck) */
Please drop the yuck.
+ g_free(cookie->localHostname); + cookie->localHostname = g_strdup("hostname2"); + + /* uuidgen --sha1 --namespace @dns --name "hostname2" */ + if (virUUIDParse("8b3f4dc4-6a8e-5f9b-94a5-4c35babd8d95", cookie->localHostuuid) < 0) { + VIR_TEST_DEBUG("\nfailed to parse fake UUID"); + return -1; + } + + /* allow re-run for checking both miration parties */
s/miration/migration/
+ g_clear_pointer(&data->xmlstr, g_free); + + if (qemuMigrationCookieFormat(cookie, + &driver, + data->vm, + data->cookiePopulateParty, + &data->xmlstr, + &data->xmlstrlen, + data->cookiePopulateFlags) < 0) { + VIR_TEST_DEBUG("\n failed to populate and format qemu migration cookie"); + return -1; + } + + if (virTestCompareToFile(data->xmlstr, data->outfile) < 0) + return -1; + + return 0; +} + +
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Add a test case attempting to excercise the most of the cookie XML parsing/formatting infra. Note that the data is not based on any real case. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- .../full-xml2xml-in.xml | 221 ++++++++++++++++++ .../full-xml2xml-out.xml | 219 +++++++++++++++++ tests/qemumigrationcookiexmltest.c | 3 +- 3 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 tests/qemumigrationcookiexmldata/full-xml2xml-in.xml create mode 100644 tests/qemumigrationcookiexmldata/full-xml2xml-out.xml diff --git a/tests/qemumigrationcookiexmldata/full-xml2xml-in.xml b/tests/qemumigrationcookiexmldata/full-xml2xml-in.xml new file mode 100644 index 0000000000..f312018850 --- /dev/null +++ b/tests/qemumigrationcookiexmldata/full-xml2xml-in.xml @@ -0,0 +1,221 @@ +<qemu-migration> + <name>upstream</name> + <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid> + <hostname>hostname2</hostname> + <hostuuid>8b3f4dc4-6a8e-5f9b-94a5-4c35babd8d95</hostuuid> + <feature name='graphics'/> + <feature name='memory-hotplug'/> + <graphics type='spice' port='123' listen='test' tlsPort='321'> + <cert info='subject' value='testsubject'/> + </graphics> + <lockstate driver='blurb'> + <leases>leastest</leases> + </lockstate> + <domain type='kvm'> + <name>upstream</name> + <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid> + <memory unit='KiB'>1024000</memory> + <currentMemory unit='KiB'>1024000</currentMemory> + <memoryBacking> + <access mode='shared'/> + </memoryBacking> + <vcpu placement='auto' current='2'>8</vcpu> + <numatune> + <memory mode='strict' placement='auto'/> + </numatune> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='x86_64' machine='pc-i440fx-2.9'>hvm</type> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + <apic/> + <vmport state='off'/> + </features> + <cpu> + <numa> + <cell id='0' cpus='0,2,4,6' memory='512000' unit='KiB'/> + <cell id='1' cpus='1,3,5,7' memory='512000' unit='KiB'/> + </numa> + </cpu> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='no'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' discard='unmap' detect_zeroes='on'/> + <auth username='testuser'> + <secret type='iscsi' usage='libvirtiscsi'/> + </auth> + <source file='/var/lib/libvirt/images/a.qcow2'/> + <backingStore type='file'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/base.qcow2'> + <slices> + <slice type='storage' offset='1234' size='3456'/> + </slices> + <seclabel model='dac' relabel='yes'> + <label>qemu:qemu</label> + </seclabel> + <reservations managed='yes'/> + </source> + <backingStore/> + </backingStore> + <target dev='vdb' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/images/systemrescuecd-x86-4.9.5.iso'/> + <backingStore/> + <target dev='hda' bus='ide'/> + <readonly/> + <boot order='1'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/> + </controller> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='scsi' index='0' model='lsilogic'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + </controller> + <controller type='fdc' index='0'/> + <interface type='network'> + <mac address='52:54:00:36:bd:3b'/> + <source network='default'/> + <model type='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + <serial type='pty'> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <channel type='unix'> + <target type='virtio' name='org.qemu.guest_agent.0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <channel type='spicevmc'> + <target type='virtio' name='com.redhat.spice.0'/> + <address type='virtio-serial' controller='0' bus='0' port='2'/> + </channel> + <input type='tablet' bus='usb'> + <address type='usb' bus='0' port='1'/> + </input> + <input type='mouse' bus='ps2'/> + <graphics type='spice' autoport='yes'> + <listen type='address'/> + <image compression='off'/> + </graphics> + <sound model='ich6'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </sound> + <video> + <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source protocol='iscsi' name='iqn.1992-01.com.example:storage/1'> + <host name='example.org' port='3260'/> + <auth username='myname'> + <secret type='iscsi' usage='mycluster_myname'/> + </auth> + </source> + <address type='drive' controller='0' bus='0' target='2' unit='4'/> + </hostdev> + <redirdev bus='usb' type='spicevmc'> + <address type='usb' bus='0' port='2'/> + </redirdev> + <redirdev bus='usb' type='spicevmc'> + <address type='usb' bus='0' port='3'/> + </redirdev> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> + </memballoon> + <rng model='virtio'> + <backend model='random'>/dev/random</backend> + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + </rng> + </devices> + <seclabel type='dynamic' model='dac' relabel='yes'/> + </domain> + <network> + <interface index='0' vporttype='midonet'> + <portdata>testportdata</portdata> + </interface> + </network> + <nbd port='456'> + <disk target='vda' capacity='123'/> + <disk target='vdb' capacity='1235'/> + </nbd> + <statistics> + <started>12345</started> + <stopped>54321</stopped> + <sent>986</sent> + <delta>7654</delta> + <time_elapsed>1</time_elapsed> + <downtime>11</downtime> + <setup_time>12</setup_time> + <memory_total>2</memory_total> + <memory_processed>3</memory_processed> + <memory_remaining>4</memory_remaining> + <memory_bps>5</memory_bps> + <memory_constant>51</memory_constant> + <memory_normal>52</memory_normal> + <memory_normal_bytes>53</memory_normal_bytes> + <memory_dirty_rate>6</memory_dirty_rate> + <memory_iteration>7</memory_iteration> + <memory_postcopy_requests>8</memory_postcopy_requests> + <memory_page_size>9</memory_page_size> + <disk_total>10</disk_total> + <disk_processed>11</disk_processed> + <disk_remaining>12</disk_remaining> + <disk_bps>13</disk_bps> + <compression_cache>131</compression_cache> + <compression_bytes>132</compression_bytes> + <compression_pages>133</compression_pages> + <compression_cache_misses>134</compression_cache_misses> + <compression_overflow>135</compression_overflow> + <auto_converge_throttle>14</auto_converge_throttle> + </statistics> + <cpu mode='host-passthrough' check='partial' migratable='on'/> + <allowReboot value='yes'/> + <capabilities> + <cap name='xbzrle' auto='yes'/> + <cap name='postcopy-ram' auto='no'/> + </capabilities> +</qemu-migration> diff --git a/tests/qemumigrationcookiexmldata/full-xml2xml-out.xml b/tests/qemumigrationcookiexmldata/full-xml2xml-out.xml new file mode 100644 index 0000000000..a07dd1f147 --- /dev/null +++ b/tests/qemumigrationcookiexmldata/full-xml2xml-out.xml @@ -0,0 +1,219 @@ +<qemu-migration> + <name>upstream</name> + <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid> + <hostname>hostname</hostname> + <hostuuid>4a802f00-4cba-5df6-9679-a08c4c5b577f</hostuuid> + <graphics type='spice' port='123' listen='test' tlsPort='321'> + <cert info='subject' value='testsubject'/> + </graphics> + <lockstate driver='blurb'> + <leases>leastest</leases> + </lockstate> + <domain type='kvm'> + <name>upstream</name> + <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid> + <memory unit='KiB'>1024000</memory> + <currentMemory unit='KiB'>1024000</currentMemory> + <memoryBacking> + <access mode='shared'/> + </memoryBacking> + <vcpu placement='auto' current='2'>8</vcpu> + <numatune> + <memory mode='strict' placement='auto'/> + </numatune> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='x86_64' machine='pc-i440fx-2.9'>hvm</type> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + <apic/> + <vmport state='off'/> + </features> + <cpu> + <numa> + <cell id='0' cpus='0,2,4,6' memory='512000' unit='KiB'/> + <cell id='1' cpus='1,3,5,7' memory='512000' unit='KiB'/> + </numa> + </cpu> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='no'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' discard='unmap' detect_zeroes='on'/> + <auth username='testuser'> + <secret type='iscsi' usage='libvirtiscsi'/> + </auth> + <source file='/var/lib/libvirt/images/a.qcow2'/> + <backingStore type='file'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/base.qcow2'> + <slices> + <slice type='storage' offset='1234' size='3456'/> + </slices> + <seclabel model='dac' relabel='yes'> + <label>qemu:qemu</label> + </seclabel> + <reservations managed='yes'/> + </source> + <backingStore/> + </backingStore> + <target dev='vdb' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/images/systemrescuecd-x86-4.9.5.iso'/> + <backingStore/> + <target dev='hda' bus='ide'/> + <readonly/> + <boot order='1'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/> + </controller> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='scsi' index='0' model='lsilogic'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + </controller> + <controller type='fdc' index='0'/> + <interface type='network'> + <mac address='52:54:00:36:bd:3b'/> + <source network='default'/> + <model type='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + <serial type='pty'> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + </serial> + <console type='pty'> + <target type='serial' port='0'/> + </console> + <channel type='unix'> + <target type='virtio' name='org.qemu.guest_agent.0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <channel type='spicevmc'> + <target type='virtio' name='com.redhat.spice.0'/> + <address type='virtio-serial' controller='0' bus='0' port='2'/> + </channel> + <input type='tablet' bus='usb'> + <address type='usb' bus='0' port='1'/> + </input> + <input type='mouse' bus='ps2'/> + <graphics type='spice' autoport='yes'> + <listen type='address'/> + <image compression='off'/> + </graphics> + <sound model='ich6'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </sound> + <video> + <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source protocol='iscsi' name='iqn.1992-01.com.example:storage/1'> + <host name='example.org' port='3260'/> + <auth username='myname'> + <secret type='iscsi' usage='mycluster_myname'/> + </auth> + </source> + <address type='drive' controller='0' bus='0' target='2' unit='4'/> + </hostdev> + <redirdev bus='usb' type='spicevmc'> + <address type='usb' bus='0' port='2'/> + </redirdev> + <redirdev bus='usb' type='spicevmc'> + <address type='usb' bus='0' port='3'/> + </redirdev> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> + </memballoon> + <rng model='virtio'> + <backend model='random'>/dev/random</backend> + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + </rng> + </devices> + <seclabel type='dynamic' model='dac' relabel='yes'/> + </domain> + <network> + <interface index='0' vporttype='midonet'> + <portdata>testportdata</portdata> + </interface> + </network> + <nbd port='456'> + <disk target='vda' capacity='123'/> + <disk target='vdb' capacity='1235'/> + </nbd> + <statistics> + <started>12345</started> + <stopped>54321</stopped> + <sent>986</sent> + <delta>7654</delta> + <time_elapsed>1</time_elapsed> + <downtime>11</downtime> + <setup_time>12</setup_time> + <memory_total>2</memory_total> + <memory_processed>3</memory_processed> + <memory_remaining>4</memory_remaining> + <memory_bps>5</memory_bps> + <memory_constant>51</memory_constant> + <memory_normal>52</memory_normal> + <memory_normal_bytes>53</memory_normal_bytes> + <memory_dirty_rate>6</memory_dirty_rate> + <memory_iteration>7</memory_iteration> + <memory_postcopy_requests>8</memory_postcopy_requests> + <memory_page_size>9</memory_page_size> + <disk_total>10</disk_total> + <disk_processed>11</disk_processed> + <disk_remaining>12</disk_remaining> + <disk_bps>13</disk_bps> + <compression_cache>131</compression_cache> + <compression_bytes>132</compression_bytes> + <compression_pages>133</compression_pages> + <compression_cache_misses>134</compression_cache_misses> + <compression_overflow>135</compression_overflow> + <auto_converge_throttle>14</auto_converge_throttle> + </statistics> + <cpu mode='host-passthrough' check='partial' migratable='on'/> + <allowReboot value='yes'/> + <capabilities> + <cap name='xbzrle' auto='yes'/> + <cap name='postcopy-ram' auto='no'/> + </capabilities> +</qemu-migration> diff --git a/tests/qemumigrationcookiexmltest.c b/tests/qemumigrationcookiexmltest.c index d8ed8b253c..3168da7e1c 100644 --- a/tests/qemumigrationcookiexmltest.c +++ b/tests/qemumigrationcookiexmltest.c @@ -317,7 +317,8 @@ mymain(void) if (testQemuMigrationCookieDom2XML("modern", "qemustatusxml2xmldata/modern-in.xml", 0, 0) < 0) ret = -1; - if (testQemuMigrationCookieXML2XML("basic", "qemustatusxml2xmldata/modern-in.xml", 0) < 0) + if (testQemuMigrationCookieXML2XML("basic", "qemustatusxml2xmldata/modern-in.xml", 0) < 0 || + testQemuMigrationCookieXML2XML("full", "qemustatusxml2xmldata/modern-in.xml", 0) < 0) ret = -1; virBufferFreeAndReset(&testnamebuf); -- 2.26.2

On a Wednesday in 2020, Peter Krempa wrote:
Add a test case attempting to excercise the most of the cookie XML
* exercise
parsing/formatting infra. Note that the data is not based on any real case.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- .../full-xml2xml-in.xml | 221 ++++++++++++++++++ .../full-xml2xml-out.xml | 219 +++++++++++++++++ tests/qemumigrationcookiexmltest.c | 3 +- 3 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 tests/qemumigrationcookiexmldata/full-xml2xml-in.xml create mode 100644 tests/qemumigrationcookiexmldata/full-xml2xml-out.xml
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The function was basically open-coding it. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/cpu_conf.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c index 7778e01131..5cf7716b12 100644 --- a/src/conf/cpu_conf.c +++ b/src/conf/cpu_conf.c @@ -743,21 +743,7 @@ virCPUDefFormatBufFull(virBufferPtr buf, if (virDomainNumaDefFormatXML(&childrenBuf, numa) < 0) return -1; - /* Put it all together */ - if (virBufferUse(&attributeBuf) || virBufferUse(&childrenBuf)) { - virBufferAddLit(buf, "<cpu"); - - if (virBufferUse(&attributeBuf)) - virBufferAddBuffer(buf, &attributeBuf); - - if (virBufferUse(&childrenBuf)) { - virBufferAddLit(buf, ">\n"); - virBufferAddBuffer(buf, &childrenBuf); - virBufferAddLit(buf, "</cpu>\n"); - } else { - virBufferAddLit(buf, "/>\n"); - } - } + virXMLFormatElement(buf, "cpu", &attributeBuf, &childrenBuf); return 0; } -- 2.26.2

On a Wednesday in 2020, Peter Krempa wrote:
The function was basically open-coding it.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/cpu_conf.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko
-
Peter Krempa