Quite a critical bit of the libvirt code is that which converts between SEXPR and XML, and vica-verca. I've broken this code several times when making changes, so it is way overdue to get some unit test coverage in this area. The attached patch adds such coverage - defining two tests xml2sexprtest and sexpr2xmltest. The tests are pretty simple, in the tests/ directory I just have a bunch of xml & sexpr files - one is the fixed input, the other is the expected output. The test just runs the conversion and compares the actual output with the expected output. Currently I've added two example data files - one for paravirt & one for fully-virt. With this patch you can run tests: $ make check make check-TESTS make[1]: Entering directory `/home/berrange/src/xen/libvirt/tests' XML-2-SEXPR PV config ... OK XML-2-SEXPR FV config ... OK PASS: xml2sexprtest SEXPR-2-XML PV config ... OK SEXPR-2-XML FV config ... OK PASS: sexpr2xmltest ================== All 2 tests passed ================== make[1]: Leaving directory `/home/berrange/src/xen/libvirt/tests' I'm shortly about to start on updating the code to deal with new CDROM configuration format for HVM guests in Xen 3.0.3, and so intend to add further test files during this process (and of course make sure I don't break the existing ones :-) Regards, Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
Index: src/xend_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xend_internal.c,v retrieving revision 1.56 diff -c -r1.56 xend_internal.c *** src/xend_internal.c 16 Aug 2006 17:58:23 -0000 1.56 --- src/xend_internal.c 24 Aug 2006 13:57:36 -0000 *************** *** 1655,1660 **** --- 1655,1674 ---- return (NULL); } + char * + xend_parse_domain_sexp(virConnectPtr conn, char *sexpr) { + struct sexpr *root = string2sexpr(sexpr); + char *data; + + if (!root) + return NULL; + + data = xend_parse_sexp_desc(conn, root); + + sexpr_free(root); + + return data; + } /** * sexpr_to_xend_domain_info: Index: src/xend_internal.h =================================================================== RCS file: /data/cvs/libvirt/src/xend_internal.h,v retrieving revision 1.24 diff -c -r1.24 xend_internal.h *** src/xend_internal.h 9 Aug 2006 15:21:16 -0000 1.24 --- src/xend_internal.h 24 Aug 2006 13:57:36 -0000 *************** *** 613,618 **** --- 613,620 ---- */ int xend_log(virConnectPtr xend, char *buffer, size_t n_buffer); + char *xend_parse_domain_sexp(virConnectPtr conn, char *root); + /* refactored ones */ void xenDaemonRegister(void); int xenDaemonOpen(virConnectPtr conn, const char *name, int flags); Index: src/xs_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xs_internal.c,v retrieving revision 1.15 diff -c -r1.15 xs_internal.c *** src/xs_internal.c 9 Aug 2006 15:21:16 -0000 1.15 --- src/xs_internal.c 24 Aug 2006 13:57:37 -0000 *************** *** 148,154 **** char s[256]; unsigned int len = 0; ! if (conn->xshandle == NULL) return (NULL); snprintf(s, 255, "/local/domain/%d/%s", domid, path); --- 148,154 ---- char s[256]; unsigned int len = 0; ! if (!conn || conn->xshandle == NULL) return (NULL); snprintf(s, 255, "/local/domain/%d/%s", domid, path); Index: tests/.cvsignore =================================================================== RCS file: /data/cvs/libvirt/tests/.cvsignore,v retrieving revision 1.1 diff -c -r1.1 .cvsignore *** tests/.cvsignore 5 Jul 2006 21:52:52 -0000 1.1 --- tests/.cvsignore 24 Aug 2006 13:57:37 -0000 *************** *** 3,5 **** --- 3,7 ---- .deps .libs xmlrpctest + sexpr2xmltest + xml2sexprtest Index: tests/Makefile.am =================================================================== RCS file: /data/cvs/libvirt/tests/Makefile.am,v retrieving revision 1.2 diff -c -r1.2 Makefile.am *** tests/Makefile.am 29 May 2006 16:05:05 -0000 1.2 --- tests/Makefile.am 24 Aug 2006 13:57:37 -0000 *************** *** 16,22 **** EXTRA_DIST = xmlrpcserver.py ! noinst_PROGRAMS = xmlrpctest # Note: xmlrpc.[c|h] is not in libvirt yet xmlrpctest_SOURCES = \ --- 16,24 ---- EXTRA_DIST = xmlrpcserver.py ! noinst_PROGRAMS = xmlrpctest xml2sexprtest sexpr2xmltest ! ! TESTS = xml2sexprtest sexpr2xmltest # Note: xmlrpc.[c|h] is not in libvirt yet xmlrpctest_SOURCES = \ *************** *** 28,32 **** --- 30,46 ---- xmlrpctest_LDFLAGS = xmlrpctest_LDADD = $(LDADDS) + xml2sexprtest_SOURCES = \ + xml2sexprtest.c \ + testutils.c testutils.h + xml2sexprtest_LDFLAGS = + xml2sexprtest_LDADD = $(LDADDS) + + sexpr2xmltest_SOURCES = \ + sexpr2xmltest.c \ + testutils.c testutils.h + sexpr2xmltest_LDFLAGS = + sexpr2xmltest_LDADD = $(LDADDS) + $(LIBVIRT): -@(cd $(top_builddir)/src && $(MAKE) MAKEFLAGS+=--silent) Index: tests/sexpr2xml-fv.sexpr =================================================================== RCS file: tests/sexpr2xml-fv.sexpr diff -N tests/sexpr2xml-fv.sexpr *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/sexpr2xml-fv.sexpr 24 Aug 2006 13:57:37 -0000 *************** *** 0 **** --- 1 ---- + (domain (domid 3)(name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)(uuid 'b5d70dd275cdaca517769660b059d8bc')(on_poweroff 'destroy')(on_reboot 'restart')(on_crash 'restart')(image (hvm (kernel '/usr/lib/xen/boot/hvmloader')(device_model '/usr/lib64/xen/bin/qemu-dm')(boot c)(cdrom '/root/boot.iso')(acpi 1)(vnc 1)))(device (vbd (dev 'ioemu:hda')(uname 'file:/root/foo.img')(mode 'w')))(device (vif (mac '00:16:3e:1b:b1:47')(bridge 'xenbr0')(script 'vif-bridge')(type ioemu)))) Index: tests/sexpr2xml-fv.xml =================================================================== RCS file: tests/sexpr2xml-fv.xml diff -N tests/sexpr2xml-fv.xml *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/sexpr2xml-fv.xml 24 Aug 2006 13:57:37 -0000 *************** *** 0 **** --- 1,35 ---- + <domain type='xen' id='3'> + <name>fvtest</name> + <uuid>b5d70dd275cdaca517769660b059d8bc</uuid> + <os> + <type>hvm</type> + <loader>/usr/lib/xen/boot/hvmloader</loader> + <boot dev='hd'/> + </os> + <memory>409600</memory> + <vcpu>1</vcpu> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/lib64/xen/bin/qemu-dm</emulator> + <disk type='file' device='disk'> + <source file='/root/foo.img'/> + <target dev='hda'/> + </disk> + <interface type='bridge'> + <source bridge='xenbr0'/> + <mac address='00:16:3e:1b:b1:47'/> + <script path='vif-bridge'/> + </interface> + <disk type='file' device='cdrom'> + <source file='/root/boot.iso'/> + <target dev='hdc'/> + <readonly/> + </disk> + <graphics type='vnc' port='5903'/> + </devices> + </domain> Index: tests/sexpr2xml-pv.sexpr =================================================================== RCS file: tests/sexpr2xml-pv.sexpr diff -N tests/sexpr2xml-pv.sexpr *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/sexpr2xml-pv.sexpr 24 Aug 2006 13:57:37 -0000 *************** *** 0 **** --- 1,2 ---- + (domain (domid 6)(name 'pvtest')(memory 420)(maxmem 420)(vcpus 2)(uuid '596a5d2171f48fb2e068e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os ')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w')))) + Index: tests/sexpr2xml-pv.xml =================================================================== RCS file: tests/sexpr2xml-pv.xml diff -N tests/sexpr2xml-pv.xml *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/sexpr2xml-pv.xml 24 Aug 2006 13:57:37 -0000 *************** *** 0 **** --- 1,21 ---- + <domain type='xen' id='6'> + <name>pvtest</name> + <uuid>596a5d2171f48fb2e068e2386a5c413e</uuid> + <os> + <type>linux</type> + <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel> + <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd> + <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os </cmdline> + </os> + <memory>430080</memory> + <vcpu>2</vcpu> + <on_poweroff>destroy</on_poweroff> + <on_reboot>destroy</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <disk type='file' device='disk'> + <source file='/root/some.img'/> + <target dev='xvda'/> + </disk> + </devices> + </domain> Index: tests/sexpr2xmltest.c =================================================================== RCS file: tests/sexpr2xmltest.c diff -N tests/sexpr2xmltest.c *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/sexpr2xmltest.c 24 Aug 2006 13:57:37 -0000 *************** *** 0 **** --- 1,71 ---- + + #include <stdio.h> + #include <string.h> + + #include "xml.h" + #include "xend_internal.h" + #include "testutils.h" + #include "internal.h" + + static char *progname; + + #define MAX_FILE 4096 + + static int testCompareFiles(const char *xml, const char *sexpr) { + char xmlData[MAX_FILE]; + char sexprData[MAX_FILE]; + char *gotxml = NULL; + char *xmlPtr = &(xmlData[0]); + char *sexprPtr = &(sexprData[0]); + + if (virtTestLoadFile(xml, &xmlPtr, MAX_FILE) < 0) + return -1; + + if (virtTestLoadFile(sexpr, &sexprPtr, MAX_FILE) < 0) + return -1; + + if (!(gotxml = xend_parse_domain_sexp(NULL, sexprData))) + return -1; + + if (getenv("DEBUG_TESTS")) { + printf("In %d '%s'\n", strlen(xmlData), xmlData); + printf("Out %d '%s'\n", strlen(gotxml), gotxml); + } + if (strcmp(xmlData, gotxml)) + return -1; + + return 0; + } + + static int testComparePV(void *data ATTRIBUTE_UNUSED) { + return testCompareFiles("sexpr2xml-pv.xml", + "sexpr2xml-pv.sexpr"); + } + + static int testCompareFV(void *data ATTRIBUTE_UNUSED) { + return testCompareFiles("sexpr2xml-fv.xml", + "sexpr2xml-fv.sexpr"); + } + + int + main(int argc, char **argv) + { + int ret = 0; + + progname = argv[0]; + + if (argc > 1) { + fprintf(stderr, "Usage: %s\n", progname); + exit(EXIT_FAILURE); + } + + if (virtTestRun("SEXPR-2-XML PV config", + 1, testComparePV, NULL) != 0) + ret = -1; + + if (virtTestRun("SEXPR-2-XML FV config", + 1, testCompareFV, NULL) != 0) + ret = -1; + + exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE); + } Index: tests/testutils.c =================================================================== RCS file: /data/cvs/libvirt/tests/testutils.c,v retrieving revision 1.2 diff -c -r1.2 testutils.c *** tests/testutils.c 22 May 2006 14:38:33 -0000 1.2 --- tests/testutils.c 24 Aug 2006 13:57:37 -0000 *************** *** 13,18 **** --- 13,21 ---- #include <stdio.h> #include <stdlib.h> #include <sys/time.h> + #include <sys/types.h> + #include <sys/stat.h> + #include <unistd.h> #include "testutils.h" *************** *** 72,74 **** --- 75,107 ---- free(ts); return ret; } + + int virtTestLoadFile(const char *name, + char **buf, + int buflen) { + FILE *fp = fopen(name, "r"); + struct stat st; + + if (!fp) + return -1; + + if (fstat(fileno(fp), &st) < 0) { + fclose(fp); + return -1; + } + + if (st.st_size > (buflen-1)) { + fclose(fp); + return -1; + } + + if (fread(*buf, st.st_size, 1, fp) != 1) { + fclose(fp); + return -1; + } + (*buf)[st.st_size] = '\0'; + + fclose(fp); + return st.st_size; + } + Index: tests/testutils.h =================================================================== RCS file: /data/cvs/libvirt/tests/testutils.h,v retrieving revision 1.1 diff -c -r1.1 testutils.h *** tests/testutils.h 9 May 2006 15:35:46 -0000 1.1 --- tests/testutils.h 24 Aug 2006 13:57:37 -0000 *************** *** 25,30 **** --- 25,33 ---- int nloops, int (*body)(void *data), void *data); + int virtTestLoadFile(const char *name, + char **buf, + int buflen); #ifdef __cplusplus } Index: tests/xml2sexpr-fv.sexpr =================================================================== RCS file: tests/xml2sexpr-fv.sexpr diff -N tests/xml2sexpr-fv.sexpr *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/xml2sexpr-fv.sexpr 24 Aug 2006 13:57:37 -0000 *************** *** 0 **** --- 1 ---- + (vm (name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)(uuid 'b5d70dd275cdaca517769660b059d8bc')(on_poweroff 'destroy')(on_reboot 'restart')(on_crash 'restart')(image (hvm (kernel '/usr/lib/xen/boot/hvmloader')(device_model '/usr/lib64/xen/bin/qemu-dm')(boot c)(cdrom '/root/boot.iso')(acpi 1)(vnc 1)))(device (vbd (dev 'ioemu:hda')(uname 'file:/root/foo.img')(mode 'w')))(device (vif (mac '00:16:3e:1b:b1:47')(bridge 'xenbr0')(script 'vif-bridge')(type ioemu)))) \ No newline at end of file Index: tests/xml2sexpr-fv.xml =================================================================== RCS file: tests/xml2sexpr-fv.xml diff -N tests/xml2sexpr-fv.xml *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/xml2sexpr-fv.xml 24 Aug 2006 13:57:37 -0000 *************** *** 0 **** --- 1,36 ---- + <domain type='xen'> + <name>fvtest</name> + <uuid>b5d70dd275cdaca517769660b059d8bc</uuid> + <os> + <type>hvm</type> + <loader>/usr/lib/xen/boot/hvmloader</loader> + <boot dev='hd'/> + </os> + <memory>409600</memory> + <vcpu>1</vcpu> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <features> + <acpi/> + </features> + <devices> + <emulator>/usr/lib64/xen/bin/qemu-dm</emulator> + <interface type='bridge'> + <source bridge='xenbr0'/> + <mac address='00:16:3e:1b:b1:47'/> + <script path='vif-bridge'/> + </interface> + <disk type='file' device='cdrom'> + <source file='/root/boot.iso'/> + <target dev='hdc'/> + <readonly/> + </disk> + <disk type='file'> + <source file='/root/foo.img'/> + <target dev='ioemu:hda'/> + </disk> + <graphics type='vnc' port='5917'/> + </devices> + </domain> + Index: tests/xml2sexpr-pv.sexpr =================================================================== RCS file: tests/xml2sexpr-pv.sexpr diff -N tests/xml2sexpr-pv.sexpr *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/xml2sexpr-pv.sexpr 24 Aug 2006 13:57:37 -0000 *************** *** 0 **** --- 1 ---- + (vm (name 'pvtest')(memory 420)(maxmem 420)(vcpus 2)(uuid '596a5d2171f48fb2e068e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os ')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w')))) \ No newline at end of file Index: tests/xml2sexpr-pv.xml =================================================================== RCS file: tests/xml2sexpr-pv.xml diff -N tests/xml2sexpr-pv.xml *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/xml2sexpr-pv.xml 24 Aug 2006 13:57:37 -0000 *************** *** 0 **** --- 1,23 ---- + <domain type='xen' id='15'> + <name>pvtest</name> + <uuid>596a5d2171f48fb2e068e2386a5c413e</uuid> + <os> + <type>linux</type> + <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel> + <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd> + <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os </cmdline> + </os> + <memory>430080</memory> + <vcpu>2</vcpu> + <on_poweroff>destroy</on_poweroff> + <on_reboot>destroy</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <disk type='file' device='disk'> + <source file='/root/some.img'/> + <target dev='xvda'/> + </disk> + <console tty='/dev/pts/4'/> + </devices> + </domain> + Index: tests/xml2sexprtest.c =================================================================== RCS file: tests/xml2sexprtest.c diff -N tests/xml2sexprtest.c *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/xml2sexprtest.c 24 Aug 2006 13:57:37 -0000 *************** *** 0 **** --- 1,76 ---- + + #include <stdio.h> + #include <string.h> + + #include "xml.h" + #include "testutils.h" + #include "internal.h" + + static char *progname; + + #define MAX_FILE 4096 + + static int testCompareFiles(const char *xml, const char *sexpr, const char *name) { + char xmlData[MAX_FILE]; + char sexprData[MAX_FILE]; + char *gotname = NULL; + char *gotsexpr = NULL; + char *xmlPtr = &(xmlData[0]); + char *sexprPtr = &(sexprData[0]); + + if (virtTestLoadFile(xml, &xmlPtr, MAX_FILE) < 0) + return -1; + + if (virtTestLoadFile(sexpr, &sexprPtr, MAX_FILE) < 0) + return -1; + + if (!(gotsexpr = virDomainParseXMLDesc(xmlData, &gotname))) + return -1; + + if (getenv("DEBUG_TESTS")) { + printf("In %d '%s'\n", strlen(sexprData), sexprData); + printf("Out %d '%s'\n", strlen(gotsexpr), gotsexpr); + } + if (strcmp(sexprData, gotsexpr)) + return -1; + + if (strcmp(name, gotname)) + return -1; + + return 0; + } + + static int testComparePV(void *data ATTRIBUTE_UNUSED) { + return testCompareFiles("xml2sexpr-pv.xml", + "xml2sexpr-pv.sexpr", + "pvtest"); + } + + static int testCompareFV(void *data ATTRIBUTE_UNUSED) { + return testCompareFiles("xml2sexpr-fv.xml", + "xml2sexpr-fv.sexpr", + "fvtest"); + } + + int + main(int argc, char **argv) + { + int ret = 0; + + progname = argv[0]; + + if (argc > 1) { + fprintf(stderr, "Usage: %s\n", progname); + exit(EXIT_FAILURE); + } + + if (virtTestRun("XML-2-SEXPR PV config", + 1, testComparePV, NULL) != 0) + ret = -1; + + if (virtTestRun("XML-2-SEXPR FV config", + 1, testCompareFV, NULL) != 0) + ret = -1; + + exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE); + }