direct-io.hg

changeset 7546:601ae1c4fe61

Added test_create.py, a test script for create.py. This contains a unit test
for the command line parsing code in xm create. To make it easier to test,
create.py has changed in structure around the main(argv) function, adding a new
parseCommandLine function.

Remove a large number of useless parameters, where the opts structure was being
passed all over the place, just to eventually log through it. Instead two
methods -- err and warn -- have been broken out from the Opts class, and there
is now no need to pass the opts value everywhere.

Change the parsing inside make_config to remove lots of cut-and-pasted cruft.

Change the documentation to the vif command to indicate that the bridge can be
auto-detected.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Sun Oct 30 13:42:30 2005 +0100 (2005-10-30)
parents ab8768317e20
children 03612b7f69d5
files tools/python/xen/xm/create.py tools/python/xen/xm/tests/__init__.py tools/python/xen/xm/tests/test_create.py
line diff
     1.1 --- a/tools/python/xen/xm/create.py	Sun Oct 30 13:34:12 2005 +0100
     1.2 +++ b/tools/python/xen/xm/create.py	Sun Oct 30 13:42:30 2005 +0100
     1.3 @@ -34,7 +34,6 @@ from xen.xend import sxp
     1.4  from xen.xend import PrettyPrint
     1.5  from xen.xend.XendClient import server, XendError
     1.6  from xen.xend.XendBootloader import bootloader
     1.7 -from xen.xend import XendRoot; xroot = XendRoot.instance()
     1.8  from xen.util import blkif
     1.9  
    1.10  from xen.xm.opts import *
    1.11 @@ -254,7 +253,7 @@ gopts.var('vif', val="mac=MAC,be_mac=MAC
    1.12            If mac is not specified a random MAC address is used.
    1.13            The MAC address of the backend interface can be selected with be_mac.
    1.14            If not specified then the network backend chooses it's own MAC address.
    1.15 -          If bridge is not specified the default bridge is used.
    1.16 +          If bridge is not specified the first bridge found is used.
    1.17            If script is not specified the default script is used.
    1.18            If backend is not specified the default backend driver domain is used.
    1.19            If vifname is not specified the backend virtual interface will have name vifD.N
    1.20 @@ -380,6 +379,20 @@ gopts.var('display', val='DISPLAY',
    1.21            fn=set_value, default='localhost:0',
    1.22            use="X11 display to use")
    1.23  
    1.24 +
    1.25 +def err(msg):
    1.26 +    """Print an error to stderr and exit.
    1.27 +    """
    1.28 +    print >>sys.stderr, "Error:", msg
    1.29 +    sys.exit(1)
    1.30 +
    1.31 +
    1.32 +def warn(msg):
    1.33 +    """Print a warning to stdout.
    1.34 +    """
    1.35 +    print >>sys.stderr, "Warning:", msg
    1.36 +
    1.37 +
    1.38  def strip(pre, s):
    1.39      """Strip prefix 'pre' if present.
    1.40      """
    1.41 @@ -388,7 +401,7 @@ def strip(pre, s):
    1.42      else:
    1.43          return s
    1.44  
    1.45 -def configure_image(opts, vals):
    1.46 +def configure_image(vals):
    1.47      """Create the image config.
    1.48      """
    1.49      config_image = [ vals.builder ]
    1.50 @@ -407,7 +420,7 @@ def configure_image(opts, vals):
    1.51          config_image.append(['vcpus', vals.vcpus])
    1.52      return config_image
    1.53      
    1.54 -def configure_disks(opts, config_devs, vals):
    1.55 +def configure_disks(config_devs, vals):
    1.56      """Create the config for disks (virtual block devices).
    1.57      """
    1.58      for (uname, dev, mode, backend) in vals.disk:
    1.59 @@ -419,19 +432,19 @@ def configure_disks(opts, config_devs, v
    1.60              config_vbd.append(['backend', backend])
    1.61          config_devs.append(['device', config_vbd])
    1.62  
    1.63 -def configure_pci(opts, config_devs, vals):
    1.64 +def configure_pci(config_devs, vals):
    1.65      """Create the config for pci devices.
    1.66      """
    1.67      for (bus, dev, func) in vals.pci:
    1.68          config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]]
    1.69          config_devs.append(['device', config_pci])
    1.70  
    1.71 -def configure_usb(opts, config_devs, vals):
    1.72 +def configure_usb(config_devs, vals):
    1.73      for path in vals.usb:
    1.74          config_usb = ['usb', ['path', path]]
    1.75          config_devs.append(['device', config_usb])
    1.76  
    1.77 -def configure_vtpm(opts, config_devs, vals):
    1.78 +def configure_vtpm(config_devs, vals):
    1.79      """Create the config for virtual TPM interfaces.
    1.80      """
    1.81      vtpm = vals.vtpm
    1.82 @@ -445,9 +458,9 @@ def configure_vtpm(opts, config_devs, va
    1.83              else:
    1.84                  try:
    1.85                      if int(instance) == 0:
    1.86 -                        opts.err('VM config error: vTPM instance must not be 0.')
    1.87 +                        err('VM config error: vTPM instance must not be 0.')
    1.88                  except ValueError:
    1.89 -                    opts.err('Vm config error: could not parse instance number.')
    1.90 +                    err('Vm config error: could not parse instance number.')
    1.91              backend = d.get('backend')
    1.92              config_vtpm = ['vtpm']
    1.93              if instance:
    1.94 @@ -456,7 +469,7 @@ def configure_vtpm(opts, config_devs, va
    1.95                  config_vtpm.append(['backend', backend])
    1.96              config_devs.append(['device', config_vtpm])
    1.97  
    1.98 -def configure_tpmif(opts, config_devs, vals):
    1.99 +def configure_tpmif(config_devs, vals):
   1.100      """Create the config for virtual TPM interfaces.
   1.101      """
   1.102      tpmif = vals.tpmif
   1.103 @@ -489,7 +502,7 @@ def randomMAC():
   1.104              random.randint(0x00, 0xff) ]
   1.105      return ':'.join(map(lambda x: "%02x" % x, mac))
   1.106  
   1.107 -def configure_vifs(opts, config_devs, vals):
   1.108 +def configure_vifs(config_devs, vals):
   1.109      """Create the config for virtual network interfaces.
   1.110      """
   1.111      vifs = vals.vif
   1.112 @@ -508,6 +521,7 @@ def configure_vifs(opts, config_devs, va
   1.113              ip = d.get('ip')
   1.114              vifname = d.get('vifname')
   1.115          else:
   1.116 +            
   1.117              mac = randomMAC()
   1.118              be_mac = None
   1.119              bridge = None
   1.120 @@ -531,7 +545,7 @@ def configure_vifs(opts, config_devs, va
   1.121              config_vif.append(['ip', ip])
   1.122          config_devs.append(['device', config_vif])
   1.123  
   1.124 -def configure_vfr(opts, config, vals):
   1.125 +def configure_vfr(config, vals):
   1.126       if not vals.ipaddr: return
   1.127       config_vfr = ['vfr']
   1.128       idx = 0 # No way of saying which IP is for which vif?
   1.129 @@ -539,7 +553,7 @@ def configure_vfr(opts, config, vals):
   1.130           config_vfr.append(['vif', ['id', idx], ['ip', ip]])
   1.131       config.append(config_vfr)
   1.132  
   1.133 -def configure_vmx(opts, config_image, vals):
   1.134 +def configure_vmx(config_image, vals):
   1.135      """Create the config for VMX devices.
   1.136      """
   1.137      args = [ 'memmap', 'device_model', 'vcpus', 'cdrom',
   1.138 @@ -549,27 +563,32 @@ def configure_vmx(opts, config_image, va
   1.139          if (vals.__dict__[a]):
   1.140              config_image.append([a, vals.__dict__[a]])
   1.141  
   1.142 -def run_bootloader(opts, vals):
   1.143 +def run_bootloader(vals):
   1.144      if not os.access(vals.bootloader, os.X_OK):
   1.145 -        opts.err("Bootloader isn't executable")
   1.146 +        err("Bootloader isn't executable")
   1.147      if len(vals.disk) < 1:
   1.148 -        opts.err("No disks configured and boot loader requested")
   1.149 +        err("No disks configured and boot loader requested")
   1.150      (uname, dev, mode, backend) = vals.disk[0]
   1.151      file = blkif.blkdev_uname_to_file(uname)
   1.152  
   1.153      return bootloader(vals.bootloader, file, not vals.console_autoconnect,
   1.154                        vals.vcpus, vals.blentry)
   1.155  
   1.156 -def make_config(opts, vals):
   1.157 +def make_config(vals):
   1.158      """Create the domain configuration.
   1.159      """
   1.160      
   1.161 -    config = ['vm',
   1.162 -              ['name', vals.name ],
   1.163 -              ['memory', vals.memory ],
   1.164 -              ['ssidref', vals.ssidref ]]
   1.165 -    if vals.maxmem:
   1.166 -        config.append(['maxmem', vals.maxmem])
   1.167 +    config = ['vm']
   1.168 +
   1.169 +    def add_conf(n):
   1.170 +        if hasattr(vals, n):
   1.171 +            v = getattr(vals, n)
   1.172 +            if v:
   1.173 +                config.append([n, v])
   1.174 +
   1.175 +    map(add_conf, ['name', 'memory', 'ssidref', 'maxmem', 'restart',
   1.176 +                   'on_poweroff', 'on_reboot', 'on_crash'])
   1.177 +    
   1.178      if vals.cpu is not None:
   1.179          config.append(['cpu', vals.cpu])
   1.180      if vals.cpu_weight is not None:
   1.181 @@ -580,34 +599,26 @@ def make_config(opts, vals):
   1.182          config.append(['backend', ['netif']])
   1.183      if vals.tpmif:
   1.184          config.append(['backend', ['tpmif']])
   1.185 -    if vals.restart:
   1.186 -        config.append(['restart', vals.restart])
   1.187 -    if vals.on_poweroff:
   1.188 -        config.append(['on_poweroff', vals.on_poweroff])
   1.189 -    if vals.on_reboot:
   1.190 -        config.append(['on_reboot', vals.on_reboot])
   1.191 -    if vals.on_crash:
   1.192 -        config.append(['on_crash', vals.on_crash])
   1.193  
   1.194      if vals.bootloader:
   1.195          config.append(['bootloader', vals.bootloader])
   1.196 -        config_image = run_bootloader(opts, vals)
   1.197 +        config_image = run_bootloader(vals)
   1.198      else:
   1.199 -        config_image = configure_image(opts, vals)
   1.200 -    configure_vmx(opts, config_image, vals)
   1.201 -    config.append(['image', config_image ])
   1.202 +        config_image = configure_image(vals)
   1.203 +    configure_vmx(config_image, vals)
   1.204 +    config.append(['image', config_image])
   1.205  
   1.206      config_devs = []
   1.207 -    configure_disks(opts, config_devs, vals)
   1.208 -    configure_pci(opts, config_devs, vals)
   1.209 -    configure_vifs(opts, config_devs, vals)
   1.210 -    configure_usb(opts, config_devs, vals)
   1.211 -    configure_vtpm(opts, config_devs, vals)
   1.212 +    configure_disks(config_devs, vals)
   1.213 +    configure_pci(config_devs, vals)
   1.214 +    configure_vifs(config_devs, vals)
   1.215 +    configure_usb(config_devs, vals)
   1.216 +    configure_vtpm(config_devs, vals)
   1.217      config += config_devs
   1.218  
   1.219      return config
   1.220  
   1.221 -def preprocess_disk(opts, vals):
   1.222 +def preprocess_disk(vals):
   1.223      if not vals.disk: return
   1.224      disk = []
   1.225      for v in vals.disk:
   1.226 @@ -618,23 +629,23 @@ def preprocess_disk(opts, vals):
   1.227          elif n == 4:
   1.228              pass
   1.229          else:
   1.230 -            opts.err('Invalid disk specifier: ' + v)
   1.231 +            err('Invalid disk specifier: ' + v)
   1.232          disk.append(d)
   1.233      vals.disk = disk
   1.234  
   1.235 -def preprocess_pci(opts, vals):
   1.236 +def preprocess_pci(vals):
   1.237      if not vals.pci: return
   1.238      pci = []
   1.239      for v in vals.pci:
   1.240          d = v.split(',')
   1.241          if len(d) != 3:
   1.242 -            opts.err('Invalid pci specifier: ' + v)
   1.243 +            err('Invalid pci specifier: ' + v)
   1.244          # Components are in hex: add hex specifier.
   1.245          hexd = map(lambda v: '0x'+v, d)
   1.246          pci.append(hexd)
   1.247      vals.pci = pci
   1.248  
   1.249 -def preprocess_vifs(opts, vals):
   1.250 +def preprocess_vifs(vals):
   1.251      if not vals.vif: return
   1.252      vifs = []
   1.253      for vif in vals.vif:
   1.254 @@ -645,12 +656,12 @@ def preprocess_vifs(opts, vals):
   1.255              k = k.strip()
   1.256              v = v.strip()
   1.257              if k not in ['mac', 'be_mac', 'bridge', 'script', 'backend', 'ip', 'vifname']:
   1.258 -                opts.err('Invalid vif specifier: ' + vif)
   1.259 +                err('Invalid vif specifier: ' + vif)
   1.260              d[k] = v
   1.261          vifs.append(d)
   1.262      vals.vif = vifs
   1.263  
   1.264 -def preprocess_vtpm(opts, vals):
   1.265 +def preprocess_vtpm(vals):
   1.266      if not vals.vtpm: return
   1.267      vtpms = []
   1.268      for vtpm in vals.vtpm:
   1.269 @@ -661,12 +672,12 @@ def preprocess_vtpm(opts, vals):
   1.270              k = k.strip()
   1.271              v = v.strip()
   1.272              if k not in ['backend', 'instance']:
   1.273 -                opts.err('Invalid vtpm specifier: ' + vtpm)
   1.274 +                err('Invalid vtpm specifier: ' + vtpm)
   1.275              d[k] = v
   1.276          vtpms.append(d)
   1.277      vals.vtpm = vtpms
   1.278  
   1.279 -def preprocess_tpmif(opts, vals):
   1.280 +def preprocess_tpmif(vals):
   1.281      if not vals.tpmif: return
   1.282      tpmifs = []
   1.283      for tpmif in vals.tpmif:
   1.284 @@ -677,12 +688,12 @@ def preprocess_tpmif(opts, vals):
   1.285              k = k.strip()
   1.286              v = v.strip()
   1.287              if k not in ['frontend']:
   1.288 -                opts.err('Invalid tpmif specifier: ' + vtpm)
   1.289 +                err('Invalid tpmif specifier: ' + vtpm)
   1.290              d[k] = v
   1.291          tpmifs.append(d)
   1.292      vals.tpmif = tpmifs
   1.293  
   1.294 -def preprocess_ip(opts, vals):
   1.295 +def preprocess_ip(vals):
   1.296      if vals.ip or vals.dhcp != 'off':
   1.297          dummy_nfs_server = '1.2.3.4'
   1.298          ip = (vals.ip
   1.299 @@ -696,10 +707,10 @@ def preprocess_ip(opts, vals):
   1.300          ip = ''
   1.301      vals.cmdline_ip = ip
   1.302  
   1.303 -def preprocess_nfs(opts, vals):
   1.304 +def preprocess_nfs(vals):
   1.305      if not vals.nfs_root: return
   1.306      if not vals.nfs_server:
   1.307 -        opts.err('Must set nfs root and nfs server')
   1.308 +        err('Must set nfs root and nfs server')
   1.309      nfs = 'nfsroot=' + vals.nfs_server + ':' + vals.nfs_root
   1.310      vals.extra = nfs + ' ' + vals.extra
   1.311  
   1.312 @@ -745,14 +756,14 @@ def spawn_vnc(display):
   1.313  
   1.314      return VNC_BASE_PORT + display
   1.315      
   1.316 -def preprocess_vnc(opts, vals):
   1.317 +def preprocess_vnc(vals):
   1.318      """If vnc was specified, spawn a vncviewer in listen mode
   1.319      and pass its address to the domain on the kernel command line.
   1.320      """
   1.321      if not (vals.vnc and vals.vncviewer) or vals.dryrun: return
   1.322      vnc_display = choose_vnc_display()
   1.323      if not vnc_display:
   1.324 -        opts.warn("No free vnc display")
   1.325 +        warn("No free vnc display")
   1.326          return
   1.327      print 'VNC=', vnc_display
   1.328      vnc_port = spawn_vnc(vnc_display)
   1.329 @@ -761,17 +772,17 @@ def preprocess_vnc(opts, vals):
   1.330          vnc = 'VNC_VIEWER=%s:%d' % (vnc_host, vnc_port)
   1.331          vals.extra = vnc + ' ' + vals.extra
   1.332      
   1.333 -def preprocess(opts, vals):
   1.334 +def preprocess(vals):
   1.335      if not vals.kernel:
   1.336 -        opts.err("No kernel specified")
   1.337 -    preprocess_disk(opts, vals)
   1.338 -    preprocess_pci(opts, vals)
   1.339 -    preprocess_vifs(opts, vals)
   1.340 -    preprocess_ip(opts, vals)
   1.341 -    preprocess_nfs(opts, vals)
   1.342 -    preprocess_vnc(opts, vals)
   1.343 -    preprocess_vtpm(opts, vals)
   1.344 -    preprocess_tpmif(opts, vals)
   1.345 +        err("No kernel specified")
   1.346 +    preprocess_disk(vals)
   1.347 +    preprocess_pci(vals)
   1.348 +    preprocess_vifs(vals)
   1.349 +    preprocess_ip(vals)
   1.350 +    preprocess_nfs(vals)
   1.351 +    preprocess_vnc(vals)
   1.352 +    preprocess_vtpm(vals)
   1.353 +    preprocess_tpmif(vals)
   1.354           
   1.355  def make_domain(opts, config):
   1.356      """Create, build and start a domain.
   1.357 @@ -792,14 +803,14 @@ def make_domain(opts, config):
   1.358          import signal
   1.359          if vncpid:
   1.360              os.kill(vncpid, signal.SIGKILL)
   1.361 -        opts.err(str(ex))
   1.362 +        err(str(ex))
   1.363  
   1.364      dom = sxp.child_value(dominfo, 'name')
   1.365  
   1.366      if not opts.vals.paused:
   1.367          if server.xend_domain_unpause(dom) < 0:
   1.368              server.xend_domain_destroy(dom)
   1.369 -            opts.err("Failed to unpause domain %s" % dom)
   1.370 +            err("Failed to unpause domain %s" % dom)
   1.371      opts.info("Started domain %s" % (dom))
   1.372      return int(sxp.child_value(dominfo, 'domid'))
   1.373  
   1.374 @@ -853,8 +864,8 @@ def balloon_out(dom0_min_mem, opts):
   1.375      del xc
   1.376      return ret
   1.377  
   1.378 -def main(argv):
   1.379 -    random.seed()
   1.380 +
   1.381 +def parseCommandLine(argv):
   1.382      opts = gopts
   1.383      args = opts.parse(argv)
   1.384      if opts.vals.help:
   1.385 @@ -862,25 +873,43 @@ def main(argv):
   1.386      if opts.vals.help or opts.vals.help_config:
   1.387          opts.load_defconfig(help=1)
   1.388      if opts.vals.help or opts.vals.help_config:
   1.389 -        return
   1.390 +        return (None, None)
   1.391 +
   1.392 +    if not opts.vals.display:
   1.393 +        opts.vals.display = os.getenv("DISPLAY")
   1.394 +
   1.395      # Process remaining args as config variables.
   1.396      for arg in args:
   1.397          if '=' in arg:
   1.398              (var, val) = arg.strip().split('=', 1)
   1.399              gopts.setvar(var.strip(), val.strip())
   1.400 -    opts.vals.display = os.getenv("DISPLAY")
   1.401      if opts.vals.config:
   1.402          config = opts.vals.config
   1.403      else:
   1.404          opts.load_defconfig()
   1.405 -        preprocess(opts, opts.vals)
   1.406 +        preprocess(opts.vals)
   1.407          if not opts.getopt('name') and opts.getopt('defconfig'):
   1.408              opts.setopt('name', os.path.basename(opts.getopt('defconfig')))
   1.409 -        config = make_config(opts, opts.vals)
   1.410 +        config = make_config(opts.vals)
   1.411 +
   1.412 +    return (opts, config)
   1.413 +
   1.414 +
   1.415 +def main(argv):
   1.416 +    random.seed()
   1.417 +
   1.418 +    (opts, config) = parseCommandLine(argv)
   1.419 +
   1.420 +    if not opts:
   1.421 +        return
   1.422  
   1.423      if opts.vals.dryrun:
   1.424          PrettyPrint.prettyprint(config)
   1.425      else:
   1.426 +        from xen.xend import XendRoot
   1.427 +
   1.428 +        xroot = XendRoot.instance()
   1.429 +
   1.430          dom0_min_mem = xroot.get_dom0_min_mem()
   1.431          if dom0_min_mem != 0:
   1.432              if balloon_out(dom0_min_mem, opts):
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/python/xen/xm/tests/test_create.py	Sun Oct 30 13:42:30 2005 +0100
     3.3 @@ -0,0 +1,96 @@
     3.4 +import os
     3.5 +import os.path
     3.6 +import tempfile
     3.7 +import unittest
     3.8 +
     3.9 +import xen.xend.XendRoot
    3.10 +
    3.11 +xen.xend.XendRoot.XendRoot.config_default = '/dev/null'
    3.12 +
    3.13 +import xen.xm.create
    3.14 +
    3.15 +
    3.16 +class test_create(unittest.TestCase):
    3.17 +
    3.18 +    def assertEqualModuloNulls_(self, a, b):
    3.19 +        for k, v in a.iteritems():
    3.20 +            if v:
    3.21 +                self.failUnless(k in b, '%s not in b' % k)
    3.22 +                self.assertEqual(v, b[k])
    3.23 +            else:
    3.24 +                self.assert_(k not in b or not b[k], '%s in b' % k)
    3.25 +
    3.26 +
    3.27 +    def assertEqualModuloNulls(self, a, b):
    3.28 +        self.assertEqualModuloNulls_(a, b)
    3.29 +        self.assertEqualModuloNulls_(b, a)
    3.30 +
    3.31 +
    3.32 +    def t(self, args, expected):
    3.33 +        self.assertEqualModuloNulls(
    3.34 +            xen.xm.create.parseCommandLine(args.split(' '))[0].vals.__dict__,
    3.35 +            expected)
    3.36 +
    3.37 +
    3.38 +    def testCommandLine(self):
    3.39 +        (fd, fname) = tempfile.mkstemp()
    3.40 +        try:
    3.41 +            self.t('-f %s kernel=/mykernel display=fakedisplay '
    3.42 +                   'macaddr=ab:cd:ef:ed nics=0' % fname,
    3.43 +                   { 'name'      : os.path.basename(fname),
    3.44 +                     'xm_file'   : fname,
    3.45 +                     'defconfig' : fname,
    3.46 +                     'kernel'    : '/mykernel',
    3.47 +                     'display'   : 'fakedisplay',
    3.48 +                     'macaddr'   : 'ab:cd:ef:ed',
    3.49 +                     'memory'    : 128,
    3.50 +                     'vcpus'     : 1,
    3.51 +                     'boot'      : 'c',
    3.52 +                     'dhcp'      : 'off',
    3.53 +                     'interface' : 'eth0',
    3.54 +                     'path'      : '.:/etc/xen',
    3.55 +                     'builder'   : 'linux',
    3.56 +                     })
    3.57 +        finally:
    3.58 +            os.close(fd)
    3.59 +
    3.60 +
    3.61 +    def testConfigFileAndCommandLine(self):
    3.62 +        (fd, fname) = tempfile.mkstemp()
    3.63 +        os.write(fd,
    3.64 +                 '''
    3.65 +name       = "testname"
    3.66 +memory     = 256
    3.67 +ssidref    = 1
    3.68 +kernel     = "/mykernel"
    3.69 +maxmem     = 1024
    3.70 +cpu        = 2
    3.71 +cpu_weight = 0.75
    3.72 +                 ''')
    3.73 +        try:
    3.74 +            self.t('-f %s display=fakedisplay macaddr=ab:cd:ef:ed nics=0' %
    3.75 +              fname,
    3.76 +                   { 'name'       : 'testname',
    3.77 +                     'xm_file'    : fname,
    3.78 +                     'defconfig'  : fname,
    3.79 +                     'kernel'     : '/mykernel',
    3.80 +                     'display'    : 'fakedisplay',
    3.81 +                     'macaddr'    : 'ab:cd:ef:ed',
    3.82 +                     'memory'     : 256,
    3.83 +                     'maxmem'     : 1024,
    3.84 +                     'cpu'        : 2,
    3.85 +                     'ssidref'    : 1,
    3.86 +                     'cpu_weight' : 0.75,
    3.87 +                     'vcpus'      : 1,
    3.88 +                     'boot'       : 'c',
    3.89 +                     'dhcp'       : 'off',
    3.90 +                     'interface'  : 'eth0',
    3.91 +                     'path'       : '.:/etc/xen',
    3.92 +                     'builder'    : 'linux',
    3.93 +                     })
    3.94 +        finally:
    3.95 +            os.close(fd)
    3.96 +            
    3.97 +
    3.98 +def test_suite():
    3.99 +    return unittest.makeSuite(test_create)