[Libvir] Adding test suite for sexpr<->xml conversions

Daniel P. Berrange berrange at redhat.com
Thu Aug 24 13:07:51 UTC 2006


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  -=| 
-------------- next part --------------
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);
+ }


More information about the libvir-list mailing list