ia64/xen-unstable

changeset 12760:b37e66b08bf5

This patch provides XmTestManagedDomain and XenManagedDomain classes
similar to the XmTestDomain and XenDomain classes. I have wrapped the
xen-api for VM configuration creation, starting and stopping of VMs and
destruction of the VM configuration in the XenManagedDomain class's
methods. No device-related functions are provided through the class.

The managed domains' UUIDs are tracked and all created VMs are destroyed
upon failure or skipping of the test or by calling
xapi.vm_destroy_all().

I am adding a new grouptest 'xapi' for running xen-api tests.

Only caveat: I am using an empty username and password
(XmTestList/xapi.py) with Xend's authentication deactivated to run these
tests.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author Ewan Mellor <ewan@xensource.com>
date Fri Dec 01 17:37:09 2006 +0000 (2006-12-01)
parents 4b577c1909a9
children 990bee220f20 7dc0dd5cdb4d
files tools/python/scripts/xapi.py tools/xm-test/grouptest/xapi tools/xm-test/lib/XmTestLib/Test.py tools/xm-test/lib/XmTestLib/XenManagedDomain.py tools/xm-test/lib/XmTestLib/xapi.py tools/xm-test/tests/vtpm/09_vtpm-xapi.py tools/xm-test/tests/vtpm/Makefile.am
line diff
     1.1 --- a/tools/python/scripts/xapi.py	Fri Dec 01 17:31:50 2006 +0000
     1.2 +++ b/tools/python/scripts/xapi.py	Fri Dec 01 17:37:09 2006 +0000
     1.3 @@ -438,17 +438,6 @@ def xapi_vtpm_create(*args):
     1.4      print "Creating vTPM with cfg = %s" % cfg
     1.5      vtpm_uuid = execute(server.VTPM.create, session, cfg)
     1.6      print "Done. (%s)" % vtpm_uuid
     1.7 -    vtpm_id = execute(server.VTPM.get_instance, session, vtpm_uuid)
     1.8 -    print "Has instance number '%s'" % vtpm_id
     1.9 -    vtpm_be = execute(server.VTPM.get_backend, session, vtpm_uuid)
    1.10 -    print "Has backend in '%s'" % vtpm_be
    1.11 -    driver = execute(server.VTPM.get_driver, session, vtpm_uuid)
    1.12 -    print "Has driver type '%s'" % driver
    1.13 -    vtpm_rec = execute(server.VTPM.get_record, session, vtpm_uuid)
    1.14 -    print "Has vtpm record '%s'" % vtpm_rec
    1.15 -    vm = execute(server.VTPM.get_VM, session, vtpm_uuid)
    1.16 -    print "Has VM '%s'" % vm
    1.17 -
    1.18  
    1.19  #
    1.20  # Command Line Utils
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/xm-test/grouptest/xapi	Fri Dec 01 17:37:09 2006 +0000
     2.3 @@ -0,0 +1,1 @@
     2.4 +vtpm 09_vtpm-xapi.test
     3.1 --- a/tools/xm-test/lib/XmTestLib/Test.py	Fri Dec 01 17:31:50 2006 +0000
     3.2 +++ b/tools/xm-test/lib/XmTestLib/Test.py	Fri Dec 01 17:37:09 2006 +0000
     3.3 @@ -33,6 +33,7 @@ import select
     3.4  import signal
     3.5  import re
     3.6  import glob
     3.7 +import xapi
     3.8  
     3.9  TEST_PASS = 0
    3.10  TEST_FAIL = 255
    3.11 @@ -133,10 +134,12 @@ def becomeNonRoot():
    3.12  
    3.13  def FAIL(format, *args):
    3.14      print "\nREASON:", (format % args)
    3.15 +    xapi.vm_destroy_all()
    3.16      sys.exit(TEST_FAIL)
    3.17  
    3.18  def SKIP(format, *args):
    3.19      print "\nREASON:", (format % args)
    3.20 +    xapi.vm_destroy_all()
    3.21      sys.exit(TEST_SKIP)
    3.22  
    3.23  def saveLog(logText, filename=None):
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/xm-test/lib/XmTestLib/XenManagedDomain.py	Fri Dec 01 17:37:09 2006 +0000
     4.3 @@ -0,0 +1,176 @@
     4.4 +#!/usr/bin/python
     4.5 +"""
     4.6 + Copyright (C) International Business Machines Corp., 2005
     4.7 + Author: Stefan Berger <stefanb@us.ibm.com>
     4.8 +
     4.9 + Based on XenDomain.py by Dan Smith <danms@us.ibm.com>
    4.10 +
    4.11 + This program is free software; you can redistribute it and/or modify
    4.12 + it under the terms of the GNU General Public License as published by
    4.13 + the Free Software Foundation; under version 2 of the License.
    4.14 +
    4.15 + This program is distributed in the hope that it will be useful,
    4.16 + but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.18 + GNU General Public License for more details.
    4.19 +
    4.20 + You should have received a copy of the GNU General Public License
    4.21 + along with this program; if not, write to the Free Software
    4.22 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.23 +
    4.24 +"""
    4.25 +import os
    4.26 +import sys
    4.27 +from XmTestLib import *
    4.28 +from xen.util.xmlrpclib2 import ServerProxy
    4.29 +from types import DictType
    4.30 +
    4.31 +
    4.32 +class XenManagedConfig:
    4.33 +    """An object to help create a VM configuration usable via Xen-API"""
    4.34 +    def __init__(self):
    4.35 +        self.opts = {}
    4.36 +        #Array to translate old option to new ones
    4.37 +        self.opttrlate = { 'name' : 'name_label' ,
    4.38 +                           'memory' : [ 'memory_static_max' ,
    4.39 +                                        'memory_static_min' ,
    4.40 +                                        'memory_dynamic_min',
    4.41 +                                        'memory_dynamic_max' ],
    4.42 +                           'kernel' : 'kernel_kernel',
    4.43 +                           'ramdisk': 'kernel_initrd',
    4.44 +                           'root'   : 'kernel_args'}
    4.45 +
    4.46 +    def setOpt(self, name, value):
    4.47 +        """Set an option in the config"""
    4.48 +        if name in self.opttrlate.keys():
    4.49 +            _name = self.opttrlate[name]
    4.50 +        else:
    4.51 +            _name = name
    4.52 +
    4.53 +        if isinstance(_name, list):
    4.54 +            for _n in _name:
    4.55 +                self.opts[_n] = value
    4.56 +        else:
    4.57 +            self.opts[_name] = value
    4.58 +
    4.59 +    def getOpt(self, name):
    4.60 +        """Return the value of a config option"""
    4.61 +        if name in self.opts.keys():
    4.62 +            return self.opts[name]
    4.63 +        else:
    4.64 +            return None
    4.65 +
    4.66 +    def setOpts(self, opts):
    4.67 +        """Batch-set options from a dictionary"""
    4.68 +        for k, v in opts.items():
    4.69 +            self.setOpt(k, v)
    4.70 +
    4.71 +    def getOpts(self):
    4.72 +        return self.opts
    4.73 +
    4.74 +
    4.75 +class XenManagedDomain(XenDomain):
    4.76 +
    4.77 +    def __init__(self, name=None, config=None):
    4.78 +        if name:
    4.79 +            self.name = name
    4.80 +        else:
    4.81 +            self.name = getUniqueName()
    4.82 +
    4.83 +        self.config = config
    4.84 +        self.console = None
    4.85 +        self.netEnv = "bridge"
    4.86 +
    4.87 +        self.server, self.session = xapi._connect()
    4.88 +        server = self.server
    4.89 +        try:
    4.90 +            self.vm_uuid = xapi.execute(server.VM.create, self.session,
    4.91 +                                        self.config.getOpts())
    4.92 +            xapi._VMuuids.append(self.vm_uuid)
    4.93 +        except:
    4.94 +            raise DomainError("Could not create VM config file for "
    4.95 +                              "managed domain.")
    4.96 +
    4.97 +        #Only support PV for now.
    4.98 +        self.type = "PV"
    4.99 +
   4.100 +    def start(self, noConsole=False):
   4.101 +        #start the VM
   4.102 +        server = self.server
   4.103 +        if self.vm_uuid:
   4.104 +            try:
   4.105 +                xapi.execute(server.VM.start, self.session, self.vm_uuid)
   4.106 +            except:
   4.107 +                raise DomainError("Could not start domain")
   4.108 +        else:
   4.109 +            raise DomainError("VM has not UUID - VM config does not exist?")
   4.110 +
   4.111 +        if self.getDomainType() == "HVM":
   4.112 +           waitForBoot()
   4.113 +
   4.114 +        if self.console and noConsole == True:
   4.115 +            self.closeConsole()
   4.116 +
   4.117 +        elif self.console and noConsole == False:
   4.118 +            return self.console
   4.119 +
   4.120 +        elif not self.console and noConsole == False:
   4.121 +            return self.getConsole()
   4.122 +
   4.123 +    def stop(self):
   4.124 +        if self.vm_uuid:
   4.125 +            server = self.server
   4.126 +            xapi.execute(server.VM.hard_shutdown, self.session, self.vm_uuid)
   4.127 +        else:
   4.128 +            raise DomainError("VM has not UUID - VM config does not exist?")
   4.129 +
   4.130 +    def destroy(self):
   4.131 +        #Stop VM first.
   4.132 +        self.stop()
   4.133 +        if self.vm_uuid:
   4.134 +            server = self.server
   4.135 +            xapi.execute(server.VM.destroy, self.session, self.vm_uuid)
   4.136 +            xapi._VMuuids.remove(self.vm_uuid)
   4.137 +        else:
   4.138 +            raise DomainError("VM has not UUID - VM config does not exist?")
   4.139 +
   4.140 +    def get_uuid(self):
   4.141 +        return self.vm_uuid
   4.142 +
   4.143 +    def newDevice(self, Device, *args):
   4.144 +        raise DomainError("No support for newDevice().")
   4.145 +
   4.146 +    def removeDevice(self, id):
   4.147 +        raise DomainError("No support for removeDevice().")
   4.148 +
   4.149 +    def removeAllDevices(self, id):
   4.150 +        raise DomainError("No support for removeAllDevices().")
   4.151 +
   4.152 +    def isRunning(self):
   4.153 +        return isDomainRunning(self.name)
   4.154 +
   4.155 +    def getDevice(self, id):
   4.156 +        raise DomainError("No support for getDevice().")
   4.157 +
   4.158 +
   4.159 +class XmTestManagedDomain(XenManagedDomain):
   4.160 +
   4.161 +    """Create a new managed xm-test domain
   4.162 +    @param name: The requested domain name
   4.163 +    @param extraConfig: Additional configuration options
   4.164 +    @param baseConfig: The initial configuration defaults to use
   4.165 +    """
   4.166 +    def __init__(self, name=None, extraConfig=None,
   4.167 +                 baseConfig=arch.configDefaults):
   4.168 +        config = XenManagedConfig()
   4.169 +        config.setOpts(baseConfig)
   4.170 +        if extraConfig:
   4.171 +            config.setOpts(extraConfig)
   4.172 +
   4.173 +        if name:
   4.174 +            config.setOpt("name_label", name)
   4.175 +        elif not config.getOpt("name_label"):
   4.176 +            config.setOpt("name_label", getUniqueName())
   4.177 +
   4.178 +        XenManagedDomain.__init__(self, config.getOpt("name_label"),
   4.179 +                                  config=config)
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/xm-test/lib/XmTestLib/xapi.py	Fri Dec 01 17:37:09 2006 +0000
     5.3 @@ -0,0 +1,66 @@
     5.4 +#!/usr/bin/python
     5.5 +#============================================================================
     5.6 +# This library is free software; you can redistribute it and/or
     5.7 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
     5.8 +# License as published by the Free Software Foundation.
     5.9 +#
    5.10 +# This library is distributed in the hope that it will be useful,
    5.11 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.12 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.13 +# Lesser General Public License for more details.
    5.14 +#
    5.15 +# You should have received a copy of the GNU Lesser General Public
    5.16 +# License along with this library; if not, write to the Free Software
    5.17 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.18 +#============================================================================
    5.19 +# Copyright (C) 2006 XenSource Ltd.
    5.20 +# Copyright (C) 2006 IBM Corporation
    5.21 +#============================================================================
    5.22 +
    5.23 +import os
    5.24 +import sys
    5.25 +from XmTestLib import *
    5.26 +from xen.util.xmlrpclib2 import ServerProxy
    5.27 +from types import DictType
    5.28 +
    5.29 +
    5.30 +XAPI_DEFAULT_LOGIN = " "
    5.31 +XAPI_DEFAULT_PASSWORD = " "
    5.32 +
    5.33 +class XenAPIError(Exception):
    5.34 +    pass
    5.35 +
    5.36 +
    5.37 +#A list of VMs' UUIDs that were created using vm_create
    5.38 +_VMuuids = []
    5.39 +
    5.40 +#Terminate previously created managed(!) VMs and destroy their configs
    5.41 +def vm_destroy_all():
    5.42 +    server, session = _connect()
    5.43 +    for uuid in _VMuuids:
    5.44 +        execute(server.VM.hard_shutdown, session, uuid)
    5.45 +        execute(server.VM.destroy      , session, uuid)
    5.46 +
    5.47 +
    5.48 +def execute(fn, *args):
    5.49 +    result = fn(*args)
    5.50 +    if type(result) != DictType:
    5.51 +        raise TypeError("Function returned object of type: %s" %
    5.52 +                        str(type(result)))
    5.53 +    if 'Value' not in result:
    5.54 +        raise XenAPIError(*result['ErrorDescription'])
    5.55 +    return result['Value']
    5.56 +
    5.57 +_initialised = False
    5.58 +_server = None
    5.59 +_session = None
    5.60 +def _connect(*args):
    5.61 +    global _server, _session, _initialised
    5.62 +    if not _initialised:
    5.63 +        _server = ServerProxy('httpu:///var/run/xend/xmlrpc.sock')
    5.64 +        login = XAPI_DEFAULT_LOGIN
    5.65 +        password = XAPI_DEFAULT_PASSWORD
    5.66 +        creds = (login, password)
    5.67 +        _session = execute(_server.session.login_with_password, *creds)
    5.68 +        _initialised = True
    5.69 +    return (_server, _session)
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py	Fri Dec 01 17:37:09 2006 +0000
     6.3 @@ -0,0 +1,76 @@
     6.4 +#!/usr/bin/python
     6.5 +
     6.6 +# Copyright (C) International Business Machines Corp., 2006
     6.7 +# Author: Stefan Berger <stefanb@us.ibm.com>
     6.8 +
     6.9 +# Test to test the vtpm class through the Xen-API
    6.10 +
    6.11 +from XmTestLib import xapi
    6.12 +from XmTestLib.XenManagedDomain import XmTestManagedDomain
    6.13 +from XmTestLib import *
    6.14 +from vtpm_utils import *
    6.15 +import commands
    6.16 +import os
    6.17 +
    6.18 +def do_test():
    6.19 +    domain = XmTestManagedDomain()
    6.20 +    vm_uuid = domain.get_uuid()
    6.21 +
    6.22 +    vtpmcfg = {}
    6.23 +    vtpmcfg['type'] = "paravirtualised"
    6.24 +    vtpmcfg['backend'] = "Domain-0"
    6.25 +    vtpmcfg['instance'] = 1
    6.26 +    vtpmcfg['VM'] = vm_uuid
    6.27 +
    6.28 +    server, session = xapi._connect()
    6.29 +
    6.30 +    vtpm_uuid = xapi.execute(server.VTPM.create, session, vtpmcfg)
    6.31 +
    6.32 +    vtpm_id = xapi.execute(server.VTPM.get_instance, session, vtpm_uuid)
    6.33 +    vtpm_be = xapi.execute(server.VTPM.get_backend , session, vtpm_uuid)
    6.34 +    if vtpm_be != vtpmcfg['backend']:
    6.35 +        FAIL("vTPM's backend is in '%s', expected: '%s'" %
    6.36 +             (vtpm_be, vtpmcfg['backend']))
    6.37 +
    6.38 +    driver = xapi.execute(server.VTPM.get_driver, session, vtpm_uuid)
    6.39 +    if driver != vtpmcfg['type']:
    6.40 +        FAIL("vTPM has driver type '%s', expected: '%s'" %
    6.41 +             (driver, vtpmcfg['type']))
    6.42 +
    6.43 +    vtpm_rec = xapi.execute(server.VTPM.get_record, session, vtpm_uuid)
    6.44 +
    6.45 +    if vtpm_rec['driver']  != vtpmcfg['type']:
    6.46 +        FAIL("vTPM record shows driver type '%s', expected: '%s'" %
    6.47 +             (vtpm_rec['driver'], vtpmcfg['type']))
    6.48 +    if vtpm_rec['uuid']  != vtpm_uuid:
    6.49 +        FAIL("vTPM record shows vtpm uuid '%s', expected: '%s'" %
    6.50 +             (vtpm_rec['uuid'], vtpm_uuid))
    6.51 +    if vtpm_rec['VM']  != vm_uuid:
    6.52 +        FAIL("vTPM record shows VM uuid '%s', expected: '%s'" %
    6.53 +             (vtpm_rec['VM'], vm_uuid))
    6.54 +
    6.55 +    success = domain.start()
    6.56 +
    6.57 +    console = domain.getConsole()
    6.58 +
    6.59 +    try:
    6.60 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
    6.61 +    except ConsoleError, e:
    6.62 +        saveLog(console.getHistory())
    6.63 +        vtpm_cleanup(domName)
    6.64 +        FAIL("No result from dumping the PCRs")
    6.65 +
    6.66 +    if re.search("No such file",run["output"]):
    6.67 +        vtpm_cleanup(domName)
    6.68 +        FAIL("TPM frontend support not compiled into (domU?) kernel")
    6.69 +
    6.70 +    domain.stop()
    6.71 +    domain.destroy()
    6.72 +
    6.73 +
    6.74 +
    6.75 +try:
    6.76 +    do_test()
    6.77 +finally:
    6.78 +    #Make sure all domains are gone that were created in this test case
    6.79 +    xapi.vm_destroy_all()
     7.1 --- a/tools/xm-test/tests/vtpm/Makefile.am	Fri Dec 01 17:31:50 2006 +0000
     7.2 +++ b/tools/xm-test/tests/vtpm/Makefile.am	Fri Dec 01 17:37:09 2006 +0000
     7.3 @@ -7,7 +7,8 @@ TESTS = 01_vtpm-list_pos.test \
     7.4          05_vtpm-loc_migr.test \
     7.5          06_vtpm-susp_res_pcrs.test \
     7.6          07_vtpm-mig_pcrs.test \
     7.7 -        08_vtpm-mig_pcrs.test
     7.8 +        08_vtpm-mig_pcrs.test \
     7.9 +        09_vtpm-xapi.test
    7.10  
    7.11  XFAIL_TESTS =
    7.12