2014-02-06 15:12:12 +04:00
# Copyright (C) 2013, 2014 Red Hat, Inc.
2013-03-18 01:06:52 +04:00
#
2018-04-04 16:35:41 +03:00
# This work is licensed under the GNU GPLv2 or later.
2018-03-20 22:00:02 +03:00
# See the COPYING file in the top-level directory.
2013-03-18 01:06:52 +04:00
import difflib
import os
2018-02-22 22:57:10 +03:00
import sys
import unittest
import libvirt
2013-03-18 01:06:52 +04:00
import virtinst
import virtinst . cli
2015-09-22 18:34:15 +03:00
import virtinst . uri
2013-03-18 01:06:52 +04:00
2014-01-31 22:44:50 +04:00
2014-04-03 02:39:43 +04:00
# pylint: disable=protected-access
2013-04-12 00:32:00 +04:00
# Access to protected member, needed to unittest stuff
2018-01-09 01:05:55 +03:00
class _CLIState ( object ) :
"""
Class containing any bits passed in from setup . py
"""
def __init__ ( self ) :
self . regenerate_output = False
2018-01-09 02:00:14 +03:00
self . use_coverage = False
2018-02-22 21:46:24 +03:00
self . debug = False
2018-01-09 01:05:55 +03:00
clistate = _CLIState ( )
2018-10-05 02:18:27 +03:00
def has_old_osinfo ( ) :
# Some tests rely on newer osinfo data. Check for a new condition
# here, and older tests will be skipped
osname = " rhel7.0 "
if not virtinst . OSDB . lookup_os ( osname ) :
return True
return not virtinst . OSDB . lookup_os ( osname ) . supports_usb3 ( )
2018-02-22 22:57:10 +03:00
class _URIs ( object ) :
def __init__ ( self ) :
self . _conn_cache = { }
self . _testdriver_cache = None
self . _testdriver_error = None
self . _testdriver_default = None
2018-06-12 18:48:11 +03:00
_capspath = " %s /tests/capabilities-xml/ " % os . getcwd ( )
def _domcaps ( path ) :
return " ,domcaps= " + _capspath + path
def _caps ( path ) :
return " ,caps= " + _capspath + path
_testtmpl = " __virtinst_test__test:// %s ,predictable "
self . test_default = _testtmpl % " /default "
self . test_full = _testtmpl % ( os . getcwd ( ) + " /tests/testdriver.xml " )
self . test_suite = _testtmpl % ( os . getcwd ( ) + " /tests/testsuite.xml " )
self . test_remote = self . test_full + " ,remote "
self . xen = self . test_full + _caps ( " xen-rhel5.4.xml " ) + " ,xen "
self . lxc = self . test_full + _caps ( " lxc.xml " ) + " ,lxc "
self . vz = self . test_full + _caps ( " vz.xml " ) + " ,vz "
_uri_qemu = " %s ,qemu " % self . test_full
_uri_kvm = _uri_qemu + _domcaps ( " kvm-x86_64-domcaps.xml " )
_uri_kvm_q35 = _uri_qemu + _domcaps ( " kvm-x86_64-domcaps-q35.xml " )
_uri_kvm_aarch64 = _uri_qemu + _domcaps ( " kvm-aarch64-domcaps.xml " )
self . kvm = _uri_kvm + _caps ( " kvm-x86_64.xml " )
2018-06-12 19:26:13 +03:00
self . kvm_remote = _uri_kvm + _caps ( " kvm-x86_64.xml " ) + " ,remote "
2018-06-12 18:48:11 +03:00
self . kvm_nodomcaps = _uri_qemu + _caps ( " kvm-x86_64.xml " )
self . kvm_rhel = _uri_kvm + _caps ( " kvm-x86_64-rhel7.xml " )
self . kvm_q35 = _uri_kvm_q35 + _caps ( " kvm-x86_64.xml " )
self . kvm_session = self . kvm + " ,session "
self . kvm_armv7l = _uri_kvm + _caps ( " kvm-armv7l.xml " )
2018-08-31 23:47:10 +03:00
self . kvm_armv7l_nodomcaps = _uri_qemu + _caps ( " kvm-armv7l.xml " )
2018-06-12 18:48:11 +03:00
self . kvm_aarch64 = _uri_kvm_aarch64 + _caps ( " kvm-aarch64.xml " )
self . kvm_ppc64le = _uri_kvm + _caps ( " kvm-ppc64le.xml " )
self . kvm_s390x = _uri_kvm + _caps ( " kvm-s390x.xml " )
self . kvm_s390x_KVMIBM = _uri_kvm + _caps ( " kvm-s390x-KVMIBM.xml " )
2018-02-22 22:57:10 +03:00
def openconn ( self , 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 .
"""
virtinst . util . register_libvirt_error_handler ( )
is_testdriver_xml = " /testdriver.xml " in uri
if not ( is_testdriver_xml and self . _testdriver_error ) :
try :
conn = virtinst . cli . getConnection ( uri )
except libvirt . libvirtError as e :
if not is_testdriver_xml :
raise
self . _testdriver_error = (
" error opening testdriver.xml: %s \n "
" libvirt is probably too old " % str ( e ) )
print ( self . _testdriver_error , file = sys . stderr )
if is_testdriver_xml and self . _testdriver_error :
raise unittest . SkipTest ( self . _testdriver_error )
uri = conn . _open_uri
# For the basic test:///default URI, skip this caching, so we have
# an option to test the stock code
2018-06-12 18:48:11 +03:00
if uri == self . test_default :
2018-02-22 22:57:10 +03:00
return conn
if uri not in self . _conn_cache :
2018-08-31 22:20:50 +03:00
conn . fetch_all_domains ( )
2018-02-22 22:57:10 +03:00
conn . fetch_all_pools ( )
conn . fetch_all_vols ( )
conn . fetch_all_nodedevs ( )
self . _conn_cache [ uri ] = { }
for key , value in conn . _fetch_cache . items ( ) :
self . _conn_cache [ uri ] [ key ] = value [ : ]
# Prime the internal connection cache
for key , value in self . _conn_cache [ uri ] . items ( ) :
conn . _fetch_cache [ key ] = value [ : ]
def cb_cache_new_pool ( poolobj ) :
# Used by clonetest.py nvram-newpool test
if poolobj . name ( ) == " nvram-newpool " :
from virtinst import StorageVolume
vol = StorageVolume ( conn )
vol . pool = poolobj
vol . name = " clone-orig-vars.fd "
vol . capacity = 1024 * 1024
vol . install ( )
conn . _cache_new_pool_raw ( poolobj )
conn . cb_cache_new_pool = cb_cache_new_pool
2013-09-29 05:03:03 +04:00
2017-08-30 17:36:37 +03:00
return conn
2018-02-22 22:57:10 +03:00
def open_testdriver_cached ( self ) :
"""
Open plain testdriver . xml and cache the instance . Tests that
use this are expected to clean up after themselves so driver
state doesn ' t become polluted.
"""
if not self . _testdriver_cache :
2018-06-12 18:48:11 +03:00
self . _testdriver_cache = self . openconn ( self . test_full )
2018-02-22 22:57:10 +03:00
return self . _testdriver_cache
def open_testdefault_cached ( self ) :
if not self . _testdriver_default :
2018-06-12 18:48:11 +03:00
self . _testdriver_default = self . openconn ( self . test_default )
2018-02-22 22:57:10 +03:00
return self . _testdriver_default
2018-06-12 18:48:11 +03:00
def _make_uri ( self , base , connver = None , libver = None ) :
if connver :
base + = " ,connver= %s " % connver
if libver :
base + = " ,libver= %s " % libver
return base
2018-02-22 22:57:10 +03:00
def open_kvm ( self , connver = None , libver = None ) :
2018-06-12 18:48:11 +03:00
return self . openconn ( self . _make_uri ( self . kvm , connver , libver ) )
2018-02-22 22:57:10 +03:00
def open_kvm_rhel ( self , connver = None ) :
2018-06-12 18:48:11 +03:00
return self . openconn ( self . _make_uri ( self . kvm_rhel , connver ) )
2018-02-22 22:57:10 +03:00
def open_test_remote ( self ) :
2018-06-12 18:48:11 +03:00
return self . openconn ( self . test_remote )
2018-02-22 22:57:10 +03:00
URIs = _URIs ( )
2013-04-13 22:34:52 +04:00
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2013-09-10 01:14:16 +04:00
def test_create ( testconn , xml , define_func = " defineXML " ) :
2015-09-22 18:34:15 +03:00
xml = virtinst . uri . sanitize_xml_for_test_define ( xml )
2013-03-18 01:06:52 +04:00
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 )
2017-05-05 19:47:21 +03:00
except Exception as e :
2013-06-14 22:58:52 +04:00
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 ( )
2017-07-24 11:26:48 +03:00
except Exception :
2013-03-18 01:06:52 +04:00
try :
2013-09-10 01:14:16 +04:00
obj . destroy ( )
2017-07-24 11:26:48 +03:00
except Exception :
2013-03-18 01:06:52 +04:00
pass
try :
2013-09-10 01:14:16 +04:00
obj . undefine ( )
2017-07-24 11:26:48 +03:00
except Exception :
2013-03-18 01:06:52 +04:00
pass
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 :
2018-01-09 01:05:55 +03:00
if not os . path . exists ( filename ) or clistate . regenerate_output :
2017-05-05 21:19:54 +03:00
open ( filename , " w " ) . write ( actual_out )
2018-06-12 18:37:02 +03:00
expect_out = open ( filename ) . read ( )
2013-03-18 01:06:52 +04:00
diff = " " . join ( difflib . unified_diff ( expect_out . splitlines ( 1 ) ,
actual_out . splitlines ( 1 ) ,
2017-10-11 14:35:54 +03:00
fromfile = filename or ' ' ,
2013-03-18 01:06:52 +04:00
tofile = " Generated Output " ) )
if diff :
raise AssertionError ( " Conversion outputs did not match. \n %s " % diff )