From 107a7bd06bc8049619e964ced796ed18aa00a514 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 21 May 2009 14:22:51 +0000 Subject: [PATCH] Test case for QEMU driver ARGV -> XML conversion --- .hgignore | 1 + ChangeLog | 17 ++ tests/.cvsignore | 1 + tests/.gitignore | 1 + tests/Makefile.am | 11 +- tests/qemuargv2xmltest.c | 235 ++++++++++++++++++ .../qemuxml2argv-bootloader.args | 2 +- .../qemuxml2argv-bootloader.xml | 2 +- .../qemuxml2argv-disk-cdrom-empty.xml | 1 - .../qemuxml2argv-hostdev-pci-address.xml | 2 +- tests/testutils.c | 46 ++++ tests/testutils.h | 2 + 12 files changed, 314 insertions(+), 7 deletions(-) create mode 100644 tests/qemuargv2xmltest.c diff --git a/.hgignore b/.hgignore index 34b995f030..935b5b57d4 100644 --- a/.hgignore +++ b/.hgignore @@ -270,6 +270,7 @@ tests/object-locking tests/object-locking-files.txt tests/object-locking.cmi tests/object-locking.cmx +tests/qemuargv2xmltest tests/qemuxml2argvtest tests/qemuxml2xmltest tests/qparamtest diff --git a/ChangeLog b/ChangeLog index 2ebe580dca..d69f3d9545 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +Thu May 21 15:22:22 BST 2009 Daniel P. Berrange + + Test case for QEMU driver ARGV -> XML conversion + * tests/qemuargv2xmltest.c: Add test case for ARGV -> XML + conversion in QEMU driver + * tests/qemuxml2argvdata/qemuxml2argv-bootloader.args, + tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml: Fix QEMU + binary to be xenner, not qemu-kvm + * tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml: Remove + trailing blank line + * tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml: + Switch to unmanaged PCI device for tests + * tests/testutils.c, tests/testutils.h: Add API for stripping + lines matching a pattern. + * .hgignore, tests/.cvsignore, tests/.gitignore: Ignore new + test case binary + Thu May 21 15:20:22 BST 2009 Daniel P. Berrange * docs/drvqemu.html[.in], docs/drvxen.html[.in]: Add docs on diff --git a/tests/.cvsignore b/tests/.cvsignore index 60f77229fc..f71d708eb8 100644 --- a/tests/.cvsignore +++ b/tests/.cvsignore @@ -11,6 +11,7 @@ xmconfigtest xencapstest qemuxml2xmltest qemuxml2argvtest +qemuargv2xmltest nodedevxml2xmltest nodeinfotest statstest diff --git a/tests/.gitignore b/tests/.gitignore index 60f77229fc..f71d708eb8 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -11,6 +11,7 @@ xmconfigtest xencapstest qemuxml2xmltest qemuxml2argvtest +qemuargv2xmltest nodedevxml2xmltest nodeinfotest statstest diff --git a/tests/Makefile.am b/tests/Makefile.am index d375bcf00e..a6a7eb5658 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -61,7 +61,7 @@ noinst_PROGRAMS += xml2sexprtest sexpr2xmltest \ reconnect xmconfigtest xencapstest endif if WITH_QEMU -noinst_PROGRAMS += qemuxml2argvtest qemuxml2xmltest +noinst_PROGRAMS += qemuxml2argvtest qemuxml2xmltest qemuargv2xmltest endif if WITH_SECDRIVER_SELINUX @@ -119,7 +119,7 @@ endif endif if WITH_QEMU -TESTS += qemuxml2argvtest qemuxml2xmltest +TESTS += qemuxml2argvtest qemuxml2xmltest qemuargv2xmltest endif if WITH_SECDRIVER_SELINUX @@ -194,8 +194,13 @@ qemuxml2xmltest_SOURCES = \ qemuxml2xmltest.c testutilsqemu.c testutilsqemu.h \ testutils.c testutils.h qemuxml2xmltest_LDADD = ../src/libvirt_driver_qemu.la $(LDADDS) + +qemuargv2xmltest_SOURCES = \ + qemuargv2xmltest.c testutilsqemu.c testutilsqemu.h \ + testutils.c testutils.h +qemuargv2xmltest_LDADD = ../src/libvirt_driver_qemu.la $(LDADDS) else -EXTRA_DIST += qemuxml2argvtest.c qemuxml2xmltest.c testutilsqemu.c testutilsqemu.h +EXTRA_DIST += qemuxml2argvtest.c qemuxml2xmltest.c qemuargv2xmltest.c testutilsqemu.c testutilsqemu.h endif nodedevxml2xmltest_SOURCES = \ diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c new file mode 100644 index 0000000000..fbf92ae6e6 --- /dev/null +++ b/tests/qemuargv2xmltest.c @@ -0,0 +1,235 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#ifdef WITH_QEMU + +#include "internal.h" +#include "testutils.h" +#include "qemu_conf.h" + +#include "testutilsqemu.h" + +static char *progname; +static char *abs_srcdir; +static struct qemud_driver driver; + +#define MAX_FILE 4096 + +static int blankProblemElements(char *data) +{ + if (virtTestClearLineRegex("[[:alnum:]]+", data) < 0 || + virtTestClearLineRegex("([[:alnum:]]|-)+", data) < 0 || + virtTestClearLineRegex("[[:digit:]]+", data) < 0 || + virtTestClearLineRegex("[[:digit:]]+", data) < 0 || + virtTestClearLineRegex("", data) < 0 || + virtTestClearLineRegex("", data) < 0) + return -1; + return 0; +} + +static int testCompareXMLToArgvFiles(const char *xml, + const char *cmdfile) { + char xmlData[MAX_FILE]; + char cmdData[MAX_FILE]; + char *expectxml = &(xmlData[0]); + char *actualxml = NULL; + char *cmd = &(cmdData[0]); + int ret = -1; + virDomainDefPtr vmdef = NULL; + + if (virtTestLoadFile(cmdfile, &cmd, MAX_FILE) < 0) + goto fail; + if (virtTestLoadFile(xml, &expectxml, MAX_FILE) < 0) + goto fail; + + if (!(vmdef = qemuParseCommandLineString(NULL, cmd))) + goto fail; + + if (!(actualxml = virDomainDefFormat(NULL, vmdef, 0))) + goto fail; + + if (blankProblemElements(expectxml) < 0 || + blankProblemElements(actualxml) < 0) + goto fail; + + if (STRNEQ(expectxml, actualxml)) { + virtTestDifference(stderr, expectxml, actualxml); + goto fail; + } + + ret = 0; + + fail: + free(actualxml); + virDomainDefFree(vmdef); + return ret; +} + + +struct testInfo { + const char *name; + int extraFlags; + const char *migrateFrom; +}; + +static int testCompareXMLToArgvHelper(const void *data) { + const struct testInfo *info = data; + char xml[PATH_MAX]; + char args[PATH_MAX]; + snprintf(xml, PATH_MAX, "%s/qemuxml2argvdata/qemuxml2argv-%s.xml", + abs_srcdir, info->name); + snprintf(args, PATH_MAX, "%s/qemuxml2argvdata/qemuxml2argv-%s.args", + abs_srcdir, info->name); + return testCompareXMLToArgvFiles(xml, args); +} + + + +static int +mymain(int argc, char **argv) +{ + int ret = 0; + char cwd[PATH_MAX]; + + progname = argv[0]; + + if (argc > 1) { + fprintf(stderr, "Usage: %s\n", progname); + return (EXIT_FAILURE); + } + + abs_srcdir = getenv("abs_srcdir"); + if (!abs_srcdir) + abs_srcdir = getcwd(cwd, sizeof(cwd)); + + if ((driver.caps = testQemuCapsInit()) == NULL) + return EXIT_FAILURE; + if((driver.stateDir = strdup("/nowhere")) == NULL) + return EXIT_FAILURE; + +#define DO_TEST_FULL(name, extraFlags, migrateFrom) \ + do { \ + const struct testInfo info = { name, extraFlags, migrateFrom }; \ + if (virtTestRun("QEMU ARGV-2-XML " name, \ + 1, testCompareXMLToArgvHelper, &info) < 0) \ + ret = -1; \ + } while (0) + +#define DO_TEST(name, extraFlags) \ + DO_TEST_FULL(name, extraFlags, NULL) + + setenv("PATH", "/bin", 1); + setenv("USER", "test", 1); + setenv("LOGNAME", "test", 1); + setenv("HOME", "/home/test", 1); + unsetenv("TMPDIR"); + unsetenv("LD_PRELOAD"); + unsetenv("LD_LIBRARY_PATH"); + + /* Can't roundtrip vcpu cpuset attribute */ + /*DO_TEST("minimal", QEMUD_CMD_FLAG_NAME);*/ + DO_TEST("boot-cdrom", 0); + DO_TEST("boot-network", 0); + DO_TEST("boot-floppy", 0); + /* Can't roundtrip xenner arch */ + /*DO_TEST("bootloader", 0);*/ + DO_TEST("clock-utc", 0); + DO_TEST("clock-localtime", 0); + DO_TEST("disk-cdrom", 0); + DO_TEST("disk-cdrom-empty", QEMUD_CMD_FLAG_DRIVE); + DO_TEST("disk-floppy", 0); + DO_TEST("disk-many", 0); + DO_TEST("disk-virtio", QEMUD_CMD_FLAG_DRIVE | + QEMUD_CMD_FLAG_DRIVE_BOOT); + DO_TEST("disk-xenvbd", QEMUD_CMD_FLAG_DRIVE | + QEMUD_CMD_FLAG_DRIVE_BOOT); + DO_TEST("disk-drive-boot-disk", QEMUD_CMD_FLAG_DRIVE | + QEMUD_CMD_FLAG_DRIVE_BOOT); + DO_TEST("disk-drive-boot-cdrom", QEMUD_CMD_FLAG_DRIVE | + QEMUD_CMD_FLAG_DRIVE_BOOT); + DO_TEST("disk-drive-fmt-qcow", QEMUD_CMD_FLAG_DRIVE | + QEMUD_CMD_FLAG_DRIVE_BOOT); + /* Can't roundtrip shareable+cache mode option */ + /*DO_TEST("disk-drive-shared", QEMUD_CMD_FLAG_DRIVE);*/ + /* Can't roundtrip v1 writethrough option */ + /*DO_TEST("disk-drive-cache-v1-wt", QEMUD_CMD_FLAG_DRIVE);*/ + DO_TEST("disk-drive-cache-v1-wb", QEMUD_CMD_FLAG_DRIVE); + DO_TEST("disk-drive-cache-v1-none", QEMUD_CMD_FLAG_DRIVE); + DO_TEST("disk-drive-cache-v2-wt", QEMUD_CMD_FLAG_DRIVE | + QEMUD_CMD_FLAG_DRIVE_CACHE_V2); + DO_TEST("disk-drive-cache-v2-wb", QEMUD_CMD_FLAG_DRIVE | + QEMUD_CMD_FLAG_DRIVE_CACHE_V2); + DO_TEST("disk-drive-cache-v2-none", QEMUD_CMD_FLAG_DRIVE | + QEMUD_CMD_FLAG_DRIVE_CACHE_V2); + DO_TEST("disk-usb", 0); + DO_TEST("graphics-vnc", 0); + + driver.vncSASL = 1; + driver.vncSASLdir = strdup("/root/.sasl2"); + DO_TEST("graphics-vnc-sasl", 0); + driver.vncTLS = 1; + driver.vncTLSx509verify = 1; + driver.vncTLSx509certdir = strdup("/etc/pki/tls/qemu"); + DO_TEST("graphics-vnc-tls", 0); + driver.vncSASL = driver.vncTLSx509verify = driver.vncTLS = 0; + free(driver.vncSASLdir); + free(driver.vncTLSx509certdir); + driver.vncSASLdir = driver.vncTLSx509certdir = NULL; + + DO_TEST("graphics-sdl", 0); + DO_TEST("graphics-sdl-fullscreen", 0); + DO_TEST("input-usbmouse", 0); + DO_TEST("input-usbtablet", 0); + /* Can't rountrip xenner arch */ + /*DO_TEST("input-xen", 0);*/ + DO_TEST("misc-acpi", 0); + DO_TEST("misc-no-reboot", 0); + DO_TEST("misc-uuid", QEMUD_CMD_FLAG_NAME | + QEMUD_CMD_FLAG_UUID | QEMUD_CMD_FLAG_DOMID); + DO_TEST("net-user", 0); + DO_TEST("net-virtio", 0); + DO_TEST("net-eth", 0); + DO_TEST("net-eth-ifname", 0); + + DO_TEST("serial-vc", 0); + DO_TEST("serial-pty", 0); + DO_TEST("serial-dev", 0); + DO_TEST("serial-file", 0); + DO_TEST("serial-unix", 0); + DO_TEST("serial-tcp", 0); + DO_TEST("serial-udp", 0); + DO_TEST("serial-tcp-telnet", 0); + DO_TEST("serial-many", 0); + DO_TEST("parallel-tcp", 0); + DO_TEST("console-compat", 0); + DO_TEST("sound", 0); + + DO_TEST("hostdev-usb-product", 0); + DO_TEST("hostdev-usb-address", 0); + + DO_TEST("hostdev-pci-address", 0); + + DO_TEST_FULL("restore-v1", QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO, "stdio"); + DO_TEST_FULL("restore-v2", QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC, "stdio"); + DO_TEST_FULL("restore-v2", QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC, "exec:cat"); + DO_TEST_FULL("migrate", QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP, "tcp:10.0.0.1:5000"); + + virCapabilitiesFree(driver.caps); + + return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE); +} + +VIRT_TEST_MAIN(mymain) + +#else + +int main (void) { return (77); /* means 'test skipped' for automake */ } + +#endif /* WITH_QEMU */ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.args b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.args index b40032c4f1..0a01b8f2a7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-kvm -S -M xenner -m 214 -smp 1 -nographic -monitor pty -no-acpi -bootloader /usr/bin/pygrub -cdrom /dev/cdrom -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/xenner -S -M xenner -m 214 -smp 1 -nographic -monitor pty -no-acpi -bootloader /usr/bin/pygrub -cdrom /dev/cdrom -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml index 52b798f46a..e28709e1b1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml @@ -13,7 +13,7 @@ restart destroy - /usr/bin/qemu-kvm + /usr/bin/xenner diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml index 257d4ef9ec..d5341b395f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml @@ -24,4 +24,3 @@ - diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml index 9a6207e5ef..ac5ad47eca 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml @@ -18,7 +18,7 @@ - +
diff --git a/tests/testutils.c b/tests/testutils.c index c90d4a9e1f..78df731d1d 100644 --- a/tests/testutils.c +++ b/tests/testutils.c @@ -18,6 +18,7 @@ #ifndef WIN32 #include #endif +#include #include #include #include @@ -457,3 +458,48 @@ cleanup: virResetLastError(); return ret; } + + +int virtTestClearLineRegex(const char *pattern, + char *str) +{ + regex_t reg; + char *lineStart = str; + char *lineEnd = strchr(str, '\n'); + + if (regcomp(®, pattern, REG_EXTENDED | REG_NOSUB) != 0) + return -1; + + while (lineStart) { + int ret; + if (lineEnd) + *lineEnd = '\0'; + + + ret = regexec(®, lineStart, 0, NULL, 0); + //fprintf(stderr, "Match %d '%s' '%s'\n", ret, lineStart, pattern); + if (ret == 0) { + if (lineEnd) { + memmove(lineStart, lineEnd + 1, strlen(lineEnd+1) + 1); + /* Don't update lineStart - just iterate again on this + location */ + lineEnd = strchr(lineStart, '\n'); + } else { + *lineStart = '\0'; + lineStart = NULL; + } + } else { + if (lineEnd) { + *lineEnd = '\n'; + lineStart = lineEnd + 1; + lineEnd = strchr(lineStart, '\n'); + } else { + lineStart = NULL; + } + } + } + + regfree(®); + + return 0; +} diff --git a/tests/testutils.h b/tests/testutils.h index 1f79c81da4..96b246f2a2 100644 --- a/tests/testutils.h +++ b/tests/testutils.h @@ -27,6 +27,8 @@ int virtTestCaptureProgramOutput(const char *const argv[], char **buf, int buflen); +int virtTestClearLineRegex(const char *pattern, + char *string); int virtTestDifference(FILE *stream, const char *expect,