2013-10-28 00:59:46 +04:00
# Copyright (C) 2013 Red Hat, Inc.
2013-03-18 01:06:52 +04:00
#
# 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
2013-10-28 00:59:47 +04:00
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
2013-03-18 01:06:52 +04:00
#
# 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., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
import difflib
import os
import logging
import libvirt
import virtinst
import virtinst . cli
from virtinst import VirtualAudio
from virtinst import VirtualDisk
2013-04-12 17:02:12 +04:00
from virtinst import VirtualGraphics
2013-03-18 01:06:52 +04:00
from virtinst import VirtualVideoDevice
2013-04-12 00:32:00 +04:00
# pylint: disable=W0212
# Access to protected member, needed to unittest stuff
2013-08-18 16:19:58 +04:00
_capsprefix = " ,caps= %s /tests/capabilities-xml/ " % os . getcwd ( )
defaulturi = " __virtinst_test__test:///default,predictable "
testuri = " test:/// %s /tests/testdriver.xml " % os . getcwd ( )
fakeuri = " __virtinst_test__ " + testuri + " ,predictable "
uriremote = fakeuri + " ,remote "
uriqemu = " %s ,qemu " % fakeuri
urixen = " %s ,xen " % fakeuri
urixencaps = fakeuri + _capsprefix + " rhel5.4-xen-caps-virt-enabled.xml,xen "
urixenia64 = fakeuri + _capsprefix + " xen-ia64-hvm.xml,xen "
urikvm = uriqemu + _capsprefix + " libvirt-1.1.2-qemu-caps.xml "
urilxc = fakeuri + _capsprefix + " capabilities-lxc.xml,lxc "
2013-03-18 01:06:52 +04:00
2013-08-18 16:19:58 +04:00
os . environ [ " VIRTINST_TEST_SCRATCHDIR " ] = os . getcwd ( )
2013-07-17 15:53:47 +04:00
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def get_debug ( ) :
return ( " DEBUG_TESTS " in os . environ and
os . environ [ " DEBUG_TESTS " ] == " 1 " )
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def _make_uri ( base , connver = None , libver = None ) :
if connver :
base + = " ,connver= %s " % connver
if libver :
base + = " ,libver= %s " % libver
return base
2013-04-13 22:34:52 +04:00
2013-09-29 05:03:03 +04:00
_conn_cache = { }
def openconn ( uri ) :
"""
Extra super caching to speed up the test suite . We basically
cache the first guest / pool / vol poll attempt for each URI , and save it
across multiple reopenings of that connection . We aren ' t caching
libvirt objects , just parsed XML objects . This works fine since
generally every test uses a fresh virConnect , or undoes the
persistent changes it makes .
"""
conn = virtinst . cli . getConnection ( uri )
if uri not in _conn_cache :
_conn_cache [ uri ] = { }
cache = _conn_cache [ uri ]
def cb_fetch_all_guests ( ) :
if " vms " not in cache :
cache [ " vms " ] = conn . _fetch_all_guests_cached ( )
return cache [ " vms " ]
def cb_fetch_all_pools ( ) :
if " pools " not in cache :
cache [ " pools " ] = conn . _fetch_all_pools_cached ( )
return cache [ " pools " ]
def cb_fetch_all_vols ( ) :
if " vols " not in cache :
cache [ " vols " ] = conn . _fetch_all_vols_cached ( )
return cache [ " vols " ]
2014-01-18 23:57:39 +04:00
def cb_clear_cache ( pools = False ) :
if pools :
cache . pop ( " pools " , None )
2013-09-29 05:03:03 +04:00
conn . cb_fetch_all_guests = cb_fetch_all_guests
conn . cb_fetch_all_pools = cb_fetch_all_pools
conn . cb_fetch_all_vols = cb_fetch_all_vols
2014-01-18 23:57:39 +04:00
conn . cb_clear_cache = cb_clear_cache
2013-09-29 05:03:03 +04:00
return conn
2013-07-05 16:59:58 +04:00
def open_testdefault ( ) :
2013-09-29 05:03:03 +04:00
return openconn ( " test:///default " )
2013-07-05 16:59:58 +04:00
2013-03-18 01:06:52 +04:00
def open_testdriver ( ) :
2013-09-29 05:03:03 +04:00
return openconn ( testuri )
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def open_testkvmdriver ( ) :
2013-09-29 05:03:03 +04:00
return openconn ( urikvm )
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def open_plainkvm ( connver = None , libver = None ) :
2013-09-29 05:03:03 +04:00
return openconn ( _make_uri ( uriqemu , connver , libver ) )
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def open_plainxen ( connver = None , libver = None ) :
2013-09-29 05:03:03 +04:00
return openconn ( _make_uri ( urixen , connver , libver ) )
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def open_test_remote ( ) :
2013-09-29 05:03:03 +04:00
return openconn ( uriremote )
2013-03-18 01:06:52 +04:00
_default_conn = open_testdriver ( )
_conn = None
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def set_conn ( newconn ) :
global _conn
_conn = newconn
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def reset_conn ( ) :
set_conn ( _default_conn )
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def get_conn ( ) :
return _conn
reset_conn ( )
# Register libvirt handler
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def libvirt_callback ( ignore , err ) :
logging . warn ( " libvirt errmsg: %s " , err [ 2 ] )
libvirt . registerErrorHandler ( f = libvirt_callback , ctx = None )
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def sanitize_xml_for_define ( xml ) :
# Libvirt throws errors since we are defining domain
# type='xen', when test driver can only handle type='test'
# Sanitize the XML so we can define
if not xml :
return xml
xml = xml . replace ( " >linux< " , " >xen< " )
2013-07-12 22:19:54 +04:00
for t in [ " xen " , " qemu " , " kvm " ] :
xml = xml . replace ( " <domain type= \" %s \" > " % t ,
" <domain type= \" test \" > " )
xml = xml . replace ( " <domain type= ' %s ' > " % t ,
" <domain type= ' test ' > " )
2013-03-18 01:06:52 +04:00
return xml
2013-04-13 22:34:52 +04:00
2013-09-10 01:14:16 +04:00
def test_create ( testconn , xml , define_func = " defineXML " ) :
2013-03-18 01:06:52 +04:00
xml = sanitize_xml_for_define ( xml )
2013-06-14 22:58:52 +04:00
try :
2013-09-10 01:14:16 +04:00
func = getattr ( testconn , define_func )
obj = func ( xml )
2013-06-14 22:58:52 +04:00
except Exception , e :
raise RuntimeError ( str ( e ) + " \n " + xml )
2013-03-18 01:06:52 +04:00
try :
2013-09-10 01:14:16 +04:00
obj . create ( )
obj . destroy ( )
obj . undefine ( )
2013-03-18 01:06:52 +04:00
except :
try :
2013-09-10 01:14:16 +04:00
obj . destroy ( )
2013-03-18 01:06:52 +04:00
except :
pass
try :
2013-09-10 01:14:16 +04:00
obj . undefine ( )
2013-03-18 01:06:52 +04:00
except :
pass
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def read_file ( filename ) :
""" Helper function to read a files contents and return them """
f = open ( filename , " r " )
out = f . read ( )
f . close ( )
return out
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def diff_compare ( actual_out , filename = None , expect_out = None ) :
""" Compare passed string output to contents of filename """
if not expect_out :
2013-10-03 00:09:05 +04:00
#if filename:
# file(filename, "w").write(actual_out)
2013-03-18 01:06:52 +04:00
expect_out = read_file ( filename )
diff = " " . join ( difflib . unified_diff ( expect_out . splitlines ( 1 ) ,
actual_out . splitlines ( 1 ) ,
fromfile = filename ,
tofile = " Generated Output " ) )
if diff :
raise AssertionError ( " Conversion outputs did not match. \n %s " % diff )
def get_basic_paravirt_guest ( installer = None ) :
2013-07-17 00:47:08 +04:00
g = virtinst . Guest ( _conn )
g . type = " xen "
2013-03-18 01:06:52 +04:00
g . name = " TestGuest "
2013-07-14 07:07:01 +04:00
g . memory = int ( 200 * 1024 )
g . maxmemory = int ( 400 * 1024 )
2013-03-18 01:06:52 +04:00
g . uuid = " 12345678-1234-1234-1234-123456789012 "
2013-07-16 04:43:41 +04:00
gdev = VirtualGraphics ( _conn )
gdev . type = " vnc "
2013-07-16 05:52:18 +04:00
gdev . keymap = " ja "
2013-07-16 04:43:41 +04:00
g . add_device ( gdev )
2013-03-18 01:06:52 +04:00
g . vcpus = 5
if installer :
g . installer = installer
2013-04-12 17:15:38 +04:00
else :
2013-07-17 04:05:24 +04:00
g . installer . _install_kernel = " /boot/vmlinuz "
g . installer . _install_initrd = " /boot/initrd "
2013-03-18 01:06:52 +04:00
2013-07-16 23:59:27 +04:00
g . add_default_input_device ( )
g . add_default_console_device ( )
2013-03-18 01:06:52 +04:00
return g
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def get_basic_fullyvirt_guest ( typ = " xen " , installer = None ) :
2013-07-17 00:47:08 +04:00
g = virtinst . Guest ( _conn )
g . type = typ
2013-03-18 01:06:52 +04:00
g . name = " TestGuest "
2013-07-14 07:07:01 +04:00
g . memory = int ( 200 * 1024 )
g . maxmemory = int ( 400 * 1024 )
2013-03-18 01:06:52 +04:00
g . uuid = " 12345678-1234-1234-1234-123456789012 "
2013-09-26 03:35:05 +04:00
g . installer . location = " /dev/null "
2013-07-17 15:53:47 +04:00
g . installer . cdrom = True
2013-07-16 04:43:41 +04:00
gdev = VirtualGraphics ( _conn )
gdev . type = " sdl "
2013-09-28 22:42:37 +04:00
gdev . display = " :3.4 "
gdev . xauth = " /tmp/.Xauthority "
2013-07-16 04:43:41 +04:00
g . add_device ( gdev )
2013-09-27 23:08:44 +04:00
g . features . pae = False
2013-03-18 01:06:52 +04:00
g . vcpus = 5
if installer :
g . installer = installer
2013-04-12 16:50:48 +04:00
g . emulator = " /usr/lib/xen/bin/qemu-dm "
2013-07-17 15:53:47 +04:00
g . os . arch = " i686 "
g . os . os_type = " hvm "
2013-03-18 01:06:52 +04:00
2013-07-16 23:59:27 +04:00
g . add_default_input_device ( )
g . add_default_console_device ( )
2013-03-18 01:06:52 +04:00
return g
2013-04-13 22:34:52 +04:00
2013-07-17 15:53:47 +04:00
def make_import_installer ( ) :
return virtinst . ImportInstaller ( _conn )
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2013-07-26 06:06:28 +04:00
def make_distro_installer ( location = " /dev/default-pool/default-vol " ) :
2013-07-17 00:47:08 +04:00
inst = virtinst . DistroInstaller ( _conn )
inst . location = location
2013-03-18 01:06:52 +04:00
return inst
2013-04-13 22:34:52 +04:00
2013-09-26 03:35:05 +04:00
def make_live_installer ( location = " /dev/null " ) :
2013-07-17 00:47:08 +04:00
inst = virtinst . LiveCDInstaller ( _conn )
inst . location = location
2013-03-18 01:06:52 +04:00
return inst
2013-04-13 22:34:52 +04:00
2013-07-17 15:53:47 +04:00
def make_pxe_installer ( ) :
return virtinst . PXEInstaller ( _conn )
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2013-07-13 18:09:00 +04:00
def build_win_kvm ( path = None , fake = True ) :
2013-03-18 01:06:52 +04:00
g = get_basic_fullyvirt_guest ( " kvm " )
g . os_type = " windows "
g . os_variant = " winxp "
2013-07-13 18:09:00 +04:00
g . add_device ( get_filedisk ( path , fake = fake ) )
2013-04-12 17:39:34 +04:00
g . add_device ( get_blkdisk ( ) )
g . add_device ( get_virtual_network ( ) )
2013-07-06 04:14:57 +04:00
g . add_device ( VirtualAudio ( g . conn ) )
2013-03-18 01:06:52 +04:00
g . add_device ( VirtualVideoDevice ( g . conn ) )
return g
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def get_floppy ( path = None ) :
if not path :
2013-07-26 06:06:28 +04:00
path = " /dev/default-pool/testvol1.img "
2013-07-13 18:09:00 +04:00
d = VirtualDisk ( _conn )
d . path = path
d . device = d . DEVICE_FLOPPY
d . validate ( )
return d
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2013-07-13 18:09:00 +04:00
def get_filedisk ( path = None , fake = True ) :
2013-03-18 01:06:52 +04:00
if not path :
path = " /tmp/test.img "
2013-07-13 18:09:00 +04:00
d = VirtualDisk ( _conn )
d . path = path
size = None
if not fake :
size = .000001
d . set_create_storage ( fake = fake , size = size )
d . validate ( )
return d
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2013-10-03 00:05:43 +04:00
def get_blkdisk ( path = " /dev/disk-pool/diskvol1 " ) :
2013-07-13 18:09:00 +04:00
d = VirtualDisk ( _conn )
d . path = path
d . validate ( )
return d
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
def get_virtual_network ( ) :
2013-07-06 04:14:57 +04:00
dev = virtinst . VirtualNetworkInterface ( _conn )
2013-03-18 01:06:52 +04:00
dev . macaddr = " 22:22:33:44:55:66 "
dev . type = virtinst . VirtualNetworkInterface . TYPE_VIRTUAL
2013-09-24 18:00:01 +04:00
dev . source = " default "
2013-03-18 01:06:52 +04:00
return dev