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@xxxxxxxxxx>
Index: root/xen-unstable.hg/tools/xm-test/grouptest/xapi
===================================================================
--- /dev/null
+++ root/xen-unstable.hg/tools/xm-test/grouptest/xapi
@@ -0,0 +1 @@
+vtpm 09_vtpm-xapi.test
Index: root/xen-unstable.hg/tools/xm-test/tests/vtpm/09_vtpm-xapi.py
===================================================================
--- /dev/null
+++ root/xen-unstable.hg/tools/xm-test/tests/vtpm/09_vtpm-xapi.py
@@ -0,0 +1,76 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2006
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+
+# Test to test the vtpm class through the Xen-API
+
+from XmTestLib import xapi
+from XmTestLib.XenManagedDomain import XmTestManagedDomain
+from XmTestLib import *
+from vtpm_utils import *
+import commands
+import os
+
+def do_test():
+ domain = XmTestManagedDomain()
+ vm_uuid = domain.get_uuid()
+
+ vtpmcfg = {}
+ vtpmcfg['type'] = "paravirtualised"
+ vtpmcfg['backend'] = "Domain-0"
+ vtpmcfg['instance'] = 1
+ vtpmcfg['VM'] = vm_uuid
+
+ server, session = xapi._connect()
+
+ vtpm_uuid = xapi.execute(server.VTPM.create, session, vtpmcfg)
+
+ vtpm_id = xapi.execute(server.VTPM.get_instance, session, vtpm_uuid)
+ vtpm_be = xapi.execute(server.VTPM.get_backend , session, vtpm_uuid)
+ if vtpm_be != vtpmcfg['backend']:
+ FAIL("vTPM's backend is in '%s', expected: '%s'" %
+ (vtpm_be, vtpmcfg['backend']))
+
+ driver = xapi.execute(server.VTPM.get_driver, session, vtpm_uuid)
+ if driver != vtpmcfg['type']:
+ FAIL("vTPM has driver type '%s', expected: '%s'" %
+ (driver, vtpmcfg['type']))
+
+ vtpm_rec = xapi.execute(server.VTPM.get_record, session, vtpm_uuid)
+
+ if vtpm_rec['driver'] != vtpmcfg['type']:
+ FAIL("vTPM record shows driver type '%s', expected: '%s'" %
+ (vtpm_rec['driver'], vtpmcfg['type']))
+ if vtpm_rec['uuid'] != vtpm_uuid:
+ FAIL("vTPM record shows vtpm uuid '%s', expected: '%s'" %
+ (vtpm_rec['uuid'], vtpm_uuid))
+ if vtpm_rec['VM'] != vm_uuid:
+ FAIL("vTPM record shows VM uuid '%s', expected: '%s'" %
+ (vtpm_rec['VM'], vm_uuid))
+
+ success = domain.start()
+
+ console = domain.getConsole()
+
+ try:
+ run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+ except ConsoleError, e:
+ saveLog(console.getHistory())
+ vtpm_cleanup(domName)
+ FAIL("No result from dumping the PCRs")
+
+ if re.search("No such file",run["output"]):
+ vtpm_cleanup(domName)
+ FAIL("TPM frontend support not compiled into (domU?) kernel")
+
+ domain.stop()
+ domain.destroy()
+
+
+
+try:
+ do_test()
+finally:
+ #Make sure all domains are gone that were created in this test case
+ xapi.vm_destroy_all()
Index: root/xen-unstable.hg/tools/xm-test/lib/XmTestLib/xapi.py
===================================================================
--- /dev/null
+++ root/xen-unstable.hg/tools/xm-test/lib/XmTestLib/xapi.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#============================================================================
+# Copyright (C) 2006 XenSource Ltd.
+# Copyright (C) 2006 IBM Corporation
+#============================================================================
+
+import os
+import sys
+from XmTestLib import *
+from xen.util.xmlrpclib2 import ServerProxy
+from types import DictType
+
+
+XAPI_DEFAULT_LOGIN = " "
+XAPI_DEFAULT_PASSWORD = " "
+
+class XenAPIError(Exception):
+ pass
+
+
+#A list of VMs' UUIDs that were created using vm_create
+_VMuuids = []
+
+#Terminate previously created managed(!) VMs and destroy their configs
+def vm_destroy_all():
+ server, session = _connect()
+ for uuid in _VMuuids:
+ execute(server.VM.hard_shutdown, session, uuid)
+ execute(server.VM.destroy , session, uuid)
+
+
+def execute(fn, *args):
+ result = fn(*args)
+ if type(result) != DictType:
+ raise TypeError("Function returned object of type: %s" %
+ str(type(result)))
+ if 'Value' not in result:
+ raise XenAPIError(*result['ErrorDescription'])
+ return result['Value']
+
+_initialised = False
+_server = None
+_session = None
+def _connect(*args):
+ global _server, _session, _initialised
+ if not _initialised:
+ _server = ServerProxy('httpu:///var/run/xend/xmlrpc.sock')
+ login = XAPI_DEFAULT_LOGIN
+ password = XAPI_DEFAULT_PASSWORD
+ creds = (login, password)
+ _session = execute(_server.session.login_with_password, *creds)
+ _initialised = True
+ return (_server, _session)
Index: root/xen-unstable.hg/tools/xm-test/tests/vtpm/Makefile.am
===================================================================
--- root.orig/xen-unstable.hg/tools/xm-test/tests/vtpm/Makefile.am
+++ root/xen-unstable.hg/tools/xm-test/tests/vtpm/Makefile.am
@@ -7,7 +7,8 @@ TESTS = 01_vtpm-list_pos.test \
05_vtpm-loc_migr.test \
06_vtpm-susp_res_pcrs.test \
07_vtpm-mig_pcrs.test \
- 08_vtpm-mig_pcrs.test
+ 08_vtpm-mig_pcrs.test \
+ 09_vtpm-xapi.test
XFAIL_TESTS =
Index: root/xen-unstable.hg/tools/python/scripts/xapi.py
===================================================================
--- root.orig/xen-unstable.hg/tools/python/scripts/xapi.py
+++ root/xen-unstable.hg/tools/python/scripts/xapi.py
@@ -412,17 +412,6 @@ def xapi_vtpm_create(*args):
print "Creating vTPM with cfg = %s" % cfg
vtpm_uuid = execute(server.VTPM.create, session, cfg)
print "Done. (%s)" % vtpm_uuid
- vtpm_id = execute(server.VTPM.get_instance, session, vtpm_uuid)
- print "Has instance number '%s'" % vtpm_id
- vtpm_be = execute(server.VTPM.get_backend, session, vtpm_uuid)
- print "Has backend in '%s'" % vtpm_be
- driver = execute(server.VTPM.get_driver, session, vtpm_uuid)
- print "Has driver type '%s'" % driver
- vtpm_rec = execute(server.VTPM.get_record, session, vtpm_uuid)
- print "Has vtpm record '%s'" % vtpm_rec
- vm = execute(server.VTPM.get_VM, session, vtpm_uuid)
- print "Has VM '%s'" % vm
-
#
# Command Line Utils
Index: root/xen-unstable.hg/tools/xm-test/lib/XmTestLib/Test.py
===================================================================
--- root.orig/xen-unstable.hg/tools/xm-test/lib/XmTestLib/Test.py
+++ root/xen-unstable.hg/tools/xm-test/lib/XmTestLib/Test.py
@@ -33,6 +33,7 @@ import select
import signal
import re
import glob
+import xapi
TEST_PASS = 0
TEST_FAIL = 255
@@ -133,10 +134,12 @@ def becomeNonRoot():
def FAIL(format, *args):
print "\nREASON:", (format % args)
+ xapi.vm_destroy_all()
sys.exit(TEST_FAIL)
def SKIP(format, *args):
print "\nREASON:", (format % args)
+ xapi.vm_destroy_all()
sys.exit(TEST_SKIP)
def saveLog(logText, filename=None):
Index: root/xen-unstable.hg/tools/xm-test/lib/XmTestLib/XenManagedDomain.py
===================================================================
--- /dev/null
+++ root/xen-unstable.hg/tools/xm-test/lib/XmTestLib/XenManagedDomain.py
@@ -0,0 +1,176 @@
+#!/usr/bin/python
+"""
+ Copyright (C) International Business Machines Corp., 2005
+ Author: Stefan Berger <stefanb@xxxxxxxxxx>
+
+ Based on XenDomain.py by Dan Smith <danms@xxxxxxxxxx>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; under version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""
+import os
+import sys
+from XmTestLib import *
+from xen.util.xmlrpclib2 import ServerProxy
+from types import DictType
+
+
+class XenManagedConfig:
+ """An object to help create a VM configuration usable via Xen-API"""
+ def __init__(self):
+ self.opts = {}
+ #Array to translate old option to new ones
+ self.opttrlate = { 'name' : 'name_label' ,
+ 'memory' : [ 'memory_static_max' ,
+ 'memory_static_min' ,
+ 'memory_dynamic_min',
+ 'memory_dynamic_max' ],
+ 'kernel' : 'kernel_kernel',
+ 'ramdisk': 'kernel_initrd',
+ 'root' : 'kernel_args'}
+
+ def setOpt(self, name, value):
+ """Set an option in the config"""
+ if name in self.opttrlate.keys():
+ _name = self.opttrlate[name]
+ else:
+ _name = name
+
+ if isinstance(_name, list):
+ for _n in _name:
+ self.opts[_n] = value
+ else:
+ self.opts[_name] = value
+
+ def getOpt(self, name):
+ """Return the value of a config option"""
+ if name in self.opts.keys():
+ return self.opts[name]
+ else:
+ return None
+
+ def setOpts(self, opts):
+ """Batch-set options from a dictionary"""
+ for k, v in opts.items():
+ self.setOpt(k, v)
+
+ def getOpts(self):
+ return self.opts
+
+
+class XenManagedDomain(XenDomain):
+
+ def __init__(self, name=None, config=None):
+ if name:
+ self.name = name
+ else:
+ self.name = getUniqueName()
+
+ self.config = config
+ self.console = None
+ self.netEnv = "bridge"
+
+ self.server, self.session = xapi._connect()
+ server = self.server
+ try:
+ self.vm_uuid = xapi.execute(server.VM.create, self.session,
+ self.config.getOpts())
+ xapi._VMuuids.append(self.vm_uuid)
+ except:
+ raise DomainError("Could not create VM config file for "
+ "managed domain.")
+
+ #Only support PV for now.
+ self.type = "PV"
+
+ def start(self, noConsole=False):
+ #start the VM
+ server = self.server
+ if self.vm_uuid:
+ try:
+ xapi.execute(server.VM.start, self.session, self.vm_uuid)
+ except:
+ raise DomainError("Could not start domain")
+ else:
+ raise DomainError("VM has not UUID - VM config does not exist?")
+
+ if self.getDomainType() == "HVM":
+ waitForBoot()
+
+ if self.console and noConsole == True:
+ self.closeConsole()
+
+ elif self.console and noConsole == False:
+ return self.console
+
+ elif not self.console and noConsole == False:
+ return self.getConsole()
+
+ def stop(self):
+ if self.vm_uuid:
+ server = self.server
+ xapi.execute(server.VM.hard_shutdown, self.session, self.vm_uuid)
+ else:
+ raise DomainError("VM has not UUID - VM config does not exist?")
+
+ def destroy(self):
+ #Stop VM first.
+ self.stop()
+ if self.vm_uuid:
+ server = self.server
+ xapi.execute(server.VM.destroy, self.session, self.vm_uuid)
+ xapi._VMuuids.remove(self.vm_uuid)
+ else:
+ raise DomainError("VM has not UUID - VM config does not exist?")
+
+ def get_uuid(self):
+ return self.vm_uuid
+
+ def newDevice(self, Device, *args):
+ raise DomainError("No support for newDevice().")
+
+ def removeDevice(self, id):
+ raise DomainError("No support for removeDevice().")
+
+ def removeAllDevices(self, id):
+ raise DomainError("No support for removeAllDevices().")
+
+ def isRunning(self):
+ return isDomainRunning(self.name)
+
+ def getDevice(self, id):
+ raise DomainError("No support for getDevice().")
+
+
+class XmTestManagedDomain(XenManagedDomain):
+
+ """Create a new managed xm-test domain
+ @param name: The requested domain name
+ @param extraConfig: Additional configuration options
+ @param baseConfig: The initial configuration defaults to use
+ """
+ def __init__(self, name=None, extraConfig=None,
+ baseConfig=arch.configDefaults):
+ config = XenManagedConfig()
+ config.setOpts(baseConfig)
+ if extraConfig:
+ config.setOpts(extraConfig)
+
+ if name:
+ config.setOpt("name_label", name)
+ elif not config.getOpt("name_label"):
+ config.setOpt("name_label", getUniqueName())
+
+ XenManagedDomain.__init__(self, config.getOpt("name_label"),
+ config=config)
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|