mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
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>
This commit is contained in:
1 parent
c88422678e
commit
cebaab7c6b
7 files changed
+324
-12
No files matched your search
@@ -438,17 +438,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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
vtpm 09_vtpm-xapi.test
|
||||
@@ -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):
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
Copyright (C) International Business Machines Corp., 2005
|
||||
Author: Stefan Berger <stefanb@us.ibm.com>
|
||||
|
||||
Based on XenDomain.py by Dan Smith <danms@us.ibm.com>
|
||||
|
||||
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)
|
||||
@@ -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)
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Copyright (C) International Business Machines Corp., 2006
|
||||
# Author: Stefan Berger <stefanb@us.ibm.com>
|
||||
|
||||
# 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()
|
||||
@@ -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 =
|
||||
|
||||
|
||||