[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] [Xm-Test] XenManagedDomain and initial test case for vTPM management using xen-api
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |