2014-01-20 20:09:13 +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 os
2018-03-18 18:32:25 +03:00
import tempfile
import unittest
2013-03-18 01:06:52 +04:00
import virtinst
2020-01-27 01:12:09 +03:00
from virtinst import cli
2018-03-20 19:18:35 +03:00
from virtinst import DeviceDisk
2013-04-12 00:32:00 +04:00
2013-04-11 03:48:07 +04:00
from tests import utils
2013-03-18 01:06:52 +04:00
2013-04-12 00:32:00 +04:00
2018-09-03 22:21:11 +03:00
def _make_guest ( conn = None , os_variant = None ) :
2018-02-20 21:00:24 +03:00
if not conn :
2018-09-03 22:21:11 +03:00
conn = utils . URIs . open_testdriver_cached ( )
2014-12-09 19:33:43 +03:00
2018-09-07 03:28:05 +03:00
g = virtinst . Guest ( conn )
2014-12-09 19:33:43 +03:00
g . name = " TestGuest "
2019-05-11 20:34:21 +03:00
g . currentMemory = int ( 200 * 1024 )
g . memory = int ( 400 * 1024 )
2014-12-09 19:33:43 +03:00
2017-06-28 23:12:04 +03:00
if os_variant :
2018-09-13 00:23:01 +03:00
g . set_os_name ( os_variant )
2014-12-09 19:33:43 +03:00
# File disk
2018-03-20 19:18:35 +03:00
d = virtinst . DeviceDisk ( conn )
2018-10-13 17:06:25 +03:00
d . path = " /dev/default-pool/new-test-suite.img "
2014-12-09 19:33:43 +03:00
if d . wants_storage_creation ( ) :
parent_pool = d . get_parent_pool ( )
2018-03-20 19:18:35 +03:00
vol_install = virtinst . DeviceDisk . build_vol_install ( conn ,
2018-10-13 17:06:25 +03:00
os . path . basename ( d . path ) , parent_pool , .0000001 , True )
2014-12-09 19:33:43 +03:00
d . set_vol_install ( vol_install )
d . validate ( )
g . add_device ( d )
# Block disk
2018-03-20 19:18:35 +03:00
d = virtinst . DeviceDisk ( conn )
2018-10-13 17:06:25 +03:00
d . path = " /dev/disk-pool/diskvol1 "
2014-12-09 19:33:43 +03:00
d . validate ( )
g . add_device ( d )
# Network device
2018-03-20 19:18:35 +03:00
dev = virtinst . DeviceInterface ( conn )
2014-12-09 19:33:43 +03:00
g . add_device ( dev )
return g
def _make_installer ( location = None , conn = None ) :
2018-02-22 22:57:10 +03:00
conn = conn or utils . URIs . open_testdriver_cached ( )
2018-10-13 01:35:09 +03:00
cdrom = not location and " /dev/null " or None
inst = virtinst . Installer ( conn , location = location , cdrom = cdrom )
2014-12-09 19:33:43 +03:00
return inst
class TestXMLMisc ( unittest . TestCase ) :
"""
Misc tests for various XML special behavior . These should only aim for
testing any particularly tricky bits , general XML generation should
2020-01-27 02:29:39 +03:00
be through virt - install examples in test_cli
2014-12-09 19:33:43 +03:00
"""
2018-02-22 22:57:10 +03:00
@property
def conn ( self ) :
return utils . URIs . open_testdefault_cached ( )
2014-12-09 19:33:43 +03:00
def _compare ( self , guest , filebase , do_install ) :
2020-01-27 02:11:43 +03:00
filename = os . path . join ( " tests/data/xmlconfig " , filebase + " .xml " )
2013-03-18 01:06:52 +04:00
2018-09-03 22:21:11 +03:00
installer = _make_installer ( conn = guest . conn )
inst_xml , boot_xml = installer . start_install (
guest , return_xml = True , dry = True )
2014-12-09 19:33:43 +03:00
if do_install :
2013-08-15 03:43:02 +04:00
actualXML = inst_xml
else :
actualXML = boot_xml
2014-12-09 19:33:43 +03:00
utils . diff_compare ( actualXML , filename )
utils . test_create ( guest . conn , actualXML )
2013-03-18 01:06:52 +04:00
2013-10-03 15:20:54 +04:00
def testDiskNumbers ( self ) :
2014-12-09 19:33:43 +03:00
# Various testing our target generation
2020-06-03 16:14:34 +03:00
#
# Note: using single quotes in strings to avoid
# codespell flagging the 'ba' assert
self . assertEqual ( ' a ' , DeviceDisk . num_to_target ( 1 ) )
self . assertEqual ( ' b ' , DeviceDisk . num_to_target ( 2 ) )
self . assertEqual ( ' z ' , DeviceDisk . num_to_target ( 26 ) )
self . assertEqual ( ' aa ' , DeviceDisk . num_to_target ( 27 ) )
self . assertEqual ( ' ab ' , DeviceDisk . num_to_target ( 28 ) )
self . assertEqual ( ' az ' , DeviceDisk . num_to_target ( 52 ) )
self . assertEqual ( ' ba ' , DeviceDisk . num_to_target ( 53 ) )
self . assertEqual ( ' zz ' , DeviceDisk . num_to_target ( 27 * 26 ) )
self . assertEqual ( ' aaa ' , DeviceDisk . num_to_target ( 27 * 26 + 1 ) )
self . assertEqual ( DeviceDisk . target_to_num ( ' hda ' ) , 0 )
self . assertEqual ( DeviceDisk . target_to_num ( ' hdb ' ) , 1 )
self . assertEqual ( DeviceDisk . target_to_num ( ' sdz ' ) , 25 )
self . assertEqual ( DeviceDisk . target_to_num ( ' sdaa ' ) , 26 )
self . assertEqual ( DeviceDisk . target_to_num ( ' vdab ' ) , 27 )
self . assertEqual ( DeviceDisk . target_to_num ( ' vdaz ' ) , 51 )
self . assertEqual ( DeviceDisk . target_to_num ( ' xvdba ' ) , 52 )
self . assertEqual ( DeviceDisk . target_to_num ( ' xvdzz ' ) ,
2014-12-09 19:33:43 +03:00
26 * ( 25 + 1 ) + 25 )
2020-06-03 16:14:34 +03:00
self . assertEqual ( DeviceDisk . target_to_num ( ' xvdaaa ' ) ,
2014-12-09 19:33:43 +03:00
26 * 26 * 1 + 26 * 1 + 0 )
2014-02-12 18:44:40 +04:00
2018-03-20 19:18:35 +03:00
disk = virtinst . DeviceDisk ( self . conn )
2020-06-03 16:14:34 +03:00
disk . bus = ' ide '
2013-10-03 16:40:24 +04:00
2020-06-03 16:14:34 +03:00
self . assertEqual ( ' hda ' , disk . generate_target ( [ ] ) )
self . assertEqual ( ' hdb ' , disk . generate_target ( [ ' hda ' ] ) )
self . assertEqual ( ' hdc ' , disk . generate_target ( [ ' hdb ' , ' sda ' ] ) )
self . assertEqual ( ' hdb ' , disk . generate_target ( [ ' hda ' , ' hdd ' ] ) )
2013-10-03 16:40:24 +04:00
2014-12-09 19:33:43 +03:00
def testQuickTreeinfo ( self ) :
# Simple sanity test to make sure detect_distro works. test-urls
# does much more exhaustive testing but it's only run occasionally
i = _make_installer (
2020-01-27 02:29:39 +03:00
location = " tests/data/cli/fakefedoratree " )
2018-09-03 22:21:11 +03:00
g = _make_guest ( )
2013-08-11 02:48:43 +04:00
v = i . detect_distro ( g )
2017-05-05 18:39:59 +03:00
self . assertEqual ( v , " fedora17 " )
2013-03-18 01:06:52 +04:00
2014-12-09 19:33:43 +03:00
i = _make_installer (
2020-01-27 02:29:39 +03:00
location = " tests/data/cli/fakerhel6tree " )
2018-09-03 22:21:11 +03:00
g = _make_guest ( )
2014-12-09 19:33:43 +03:00
v = i . detect_distro ( g )
2017-05-05 18:39:59 +03:00
self . assertEqual ( v , " rhel6.0 " )
2014-12-09 19:33:43 +03:00
2018-10-13 17:11:26 +03:00
def testCDROMInsert ( self ) :
# After set_install_defaults, cdrom media should be inserted
i = _make_installer ( )
g = _make_guest ( )
i . set_install_defaults ( g )
for disk in g . devices . disk :
if disk . device == " cdrom " and disk . path == " /dev/null " :
return
raise AssertionError ( " Didn ' t find inserted cdrom media " )
2014-12-09 19:33:43 +03:00
def testCPUTopology ( self ) :
# Test CPU topology determining
2018-03-20 22:10:04 +03:00
cpu = virtinst . DomainCpu ( self . conn )
2020-01-27 16:59:02 +03:00
cpu . set_topology_defaults ( 6 )
assert cpu . sockets is None
2014-12-09 19:33:43 +03:00
cpu . sockets = " 2 "
cpu . set_topology_defaults ( 6 )
2017-05-05 18:39:59 +03:00
self . assertEqual ( [ cpu . sockets , cpu . cores , cpu . threads ] , [ 2 , 3 , 1 ] )
2014-12-09 19:33:43 +03:00
2018-03-20 22:10:04 +03:00
cpu = virtinst . DomainCpu ( self . conn )
2014-12-09 19:33:43 +03:00
cpu . cores = " 4 "
cpu . set_topology_defaults ( 9 )
2017-05-05 18:39:59 +03:00
self . assertEqual ( [ cpu . sockets , cpu . cores , cpu . threads ] , [ 2 , 4 , 1 ] )
2014-12-09 19:33:43 +03:00
2018-03-20 22:10:04 +03:00
cpu = virtinst . DomainCpu ( self . conn )
2014-12-09 19:33:43 +03:00
cpu . threads = " 3 "
cpu . set_topology_defaults ( 14 )
2017-05-05 18:39:59 +03:00
self . assertEqual ( [ cpu . sockets , cpu . cores , cpu . threads ] , [ 4 , 1 , 3 ] )
2014-12-09 19:33:43 +03:00
2018-03-20 22:10:04 +03:00
cpu = virtinst . DomainCpu ( self . conn )
2014-12-09 19:33:43 +03:00
cpu . sockets = 5
cpu . cores = 2
2017-05-05 18:39:59 +03:00
self . assertEqual ( cpu . vcpus_from_topology ( ) , 10 )
2014-12-09 19:33:43 +03:00
2018-03-20 22:10:04 +03:00
cpu = virtinst . DomainCpu ( self . conn )
2017-05-05 18:39:59 +03:00
self . assertEqual ( cpu . vcpus_from_topology ( ) , 1 )
2014-12-09 19:33:43 +03:00
2018-09-12 19:36:58 +03:00
def test_set_defaults_double ( self ) :
"""
Check that a common config has idempotent set_defaults
"""
2018-09-13 00:23:01 +03:00
g = _make_guest ( conn = utils . URIs . open_kvm ( ) , os_variant = " fedora-unknown " )
2018-09-12 19:36:58 +03:00
g . set_defaults ( None )
xml1 = g . get_xml ( )
g . set_defaults ( None )
xml2 = g . get_xml ( )
self . assertEqual ( xml1 , xml2 )
2018-09-13 22:03:36 +03:00
def test_guest_osinfo_metadata ( self ) :
g = _make_guest ( )
self . assertEqual ( g . osinfo . name , " generic " )
g . set_os_name ( " fedora17 " )
self . assertEqual ( g . osinfo . name , " fedora17 " )
g = _make_guest ( )
g . _metadata . libosinfo . os_id = " http://fedoraproject.org/fedora/20 " # pylint: disable=protected-access
self . assertEqual ( g . osinfo . name , " fedora20 " )
g = _make_guest ( )
g . _metadata . libosinfo . os_id = " http://example.com/idontexit " # pylint: disable=protected-access
self . assertEqual ( g . osinfo . name , " generic " )
2018-03-18 18:32:25 +03:00
def test_dir_searchable ( self ) :
# Normally the dir searchable test is skipped in the unittest,
# but let's contrive an example that should trigger all the code
2018-10-12 01:52:45 +03:00
# to ensure it isn't horribly broken
2020-01-29 03:03:44 +03:00
conn = utils . URIs . open_kvm ( )
2020-01-31 00:17:42 +03:00
def _set_caps_baselabel_uid ( uid ) :
secmodel = [ s for s in conn . caps . host . secmodels
if s . model == " dac " ] [ 0 ]
for baselabel in [ b for b in secmodel . baselabels
if b . type in [ " qemu " , " kvm " ] ] :
baselabel . content = " + %s :+ %s " % ( uid , uid )
tmpobj = tempfile . TemporaryDirectory ( prefix = " virtinst-test-search " )
tmpdir = tmpobj . name
try :
# Invalid uid
_set_caps_baselabel_uid ( - 1 )
2020-01-29 03:03:44 +03:00
searchdata = virtinst . DeviceDisk . check_path_search ( conn , tmpdir )
2020-01-31 00:17:42 +03:00
self . assertEqual ( searchdata . uid , None )
# Use our uid, verify it shows we have expected access
_set_caps_baselabel_uid ( os . getuid ( ) )
2020-02-05 22:37:15 +03:00
searchdata = virtinst . DeviceDisk . check_path_search ( conn ,
tmpdir + " /footest " )
2020-01-31 00:17:42 +03:00
self . assertEqual ( searchdata . uid , os . getuid ( ) )
self . assertEqual ( searchdata . fixlist , [ ] )
# Remove perms on the tmpdir, now it should report failures
os . chmod ( tmpdir , 0o000 )
searchdata = virtinst . DeviceDisk . check_path_search ( conn , tmpdir )
self . assertEqual ( searchdata . fixlist , [ tmpdir ] )
2020-01-29 03:03:44 +03:00
errdict = virtinst . DeviceDisk . fix_path_search ( searchdata )
2019-06-08 16:11:00 +03:00
self . assertTrue ( not bool ( errdict ) )
2020-01-31 00:17:42 +03:00
# Mock setfacl to definitely fail
2020-01-29 15:30:51 +03:00
with unittest . mock . patch ( " virtinst.diskbackend.SETFACL " ,
" getfacl " ) :
errdict = virtinst . DeviceDisk . fix_path_search ( searchdata )
2020-01-31 00:17:42 +03:00
finally :
# Reset changes we made
conn . invalidate_caps ( )
os . chmod ( tmpdir , 0o777 )
2020-01-29 15:30:51 +03:00
2020-01-29 03:03:44 +03:00
def test_path_in_use ( self ) :
# Extra tests for DeviceDisk.path_in_use
conn = utils . URIs . open_kvm ( )
# Comparing against kernel
vms = virtinst . DeviceDisk . path_in_use_by (
conn , " /dev/default-pool/test-arm-kernel " )
assert vms == [ " test-arm-kernel " ]
2019-06-07 01:35:36 +03:00
def test_nonpredicatble_generate ( self ) :
2019-06-10 23:08:45 +03:00
kvm_uri = utils . URIs . kvm . replace ( " ,predictable " , " " )
2020-01-27 01:12:09 +03:00
kvmconn = cli . getConnection ( kvm_uri )
testconn = cli . getConnection ( " test:///default " )
2019-06-07 01:35:36 +03:00
testuuid = virtinst . Guest . generate_uuid ( self . conn )
2019-06-10 23:08:45 +03:00
randomuuid = virtinst . Guest . generate_uuid ( testconn )
2019-06-07 01:35:36 +03:00
self . assertTrue ( randomuuid != testuuid )
self . assertTrue ( len ( randomuuid ) == len ( testuuid ) )
testmac = virtinst . DeviceInterface . generate_mac ( self . conn )
2019-06-10 23:08:45 +03:00
randommac = virtinst . DeviceInterface . generate_mac ( testconn )
qemumac = virtinst . DeviceInterface . generate_mac ( kvmconn )
2019-06-07 01:35:36 +03:00
self . assertTrue ( randommac != testmac )
2019-06-10 23:08:45 +03:00
self . assertTrue ( qemumac != testmac )
2019-06-07 01:35:36 +03:00
self . assertTrue ( len ( randommac ) == len ( testmac ) )
2019-06-07 23:39:33 +03:00
2020-07-06 01:56:36 +03:00
# Ensure check_mac_in_use doesn't error on None
virtinst . DeviceInterface . check_mac_in_use ( self . conn , None )
2020-07-06 01:39:15 +03:00
2019-06-07 23:39:33 +03:00
def test_support_misc ( self ) :
try :
self . conn . lookupByName ( " foobar-idontexist " )
except Exception as e :
if not self . conn . support . is_libvirt_error_no_domain ( e ) :
raise
2020-01-29 15:30:51 +03:00
def test_disk_backend ( self ) :
# Test get_size() with vol_install
disk = virtinst . DeviceDisk ( self . conn )
pool = self . conn . storagePoolLookupByName ( " default-pool " )
vol_install = disk . build_vol_install ( self . conn , " newvol1.img " ,
pool , 1 , False )
disk . set_vol_install ( vol_install )
assert disk . get_size ( ) == 1.0
# Test some blockdev inspecting
2020-01-29 16:57:10 +03:00
conn = utils . URIs . openconn ( " test:///default " )
2020-01-29 15:30:51 +03:00
if os . path . exists ( " /dev/loop0 " ) :
disk = virtinst . DeviceDisk ( conn )
disk . path = " /dev/loop0 "
assert disk . type == " block "
disk . get_size ( )
2020-01-29 16:57:10 +03:00
# Test sparse cloning
tmpinput = tempfile . NamedTemporaryFile ( )
open ( tmpinput . name , " wb " ) . write ( b ' \0 ' * 10000 )
srcdisk = virtinst . DeviceDisk ( conn )
srcdisk . path = tmpinput . name
newdisk = virtinst . DeviceDisk ( conn )
tmpoutput = tempfile . NamedTemporaryFile ( )
os . unlink ( tmpoutput . name )
newdisk . path = tmpoutput . name
newdisk . set_local_disk_to_clone ( srcdisk , True )
newdisk . build_storage ( None )
# Test cloning onto existing disk
2020-07-18 01:58:00 +03:00
newdisk = virtinst . DeviceDisk ( conn , parsexml = newdisk . get_xml ( ) )
2020-01-29 16:57:10 +03:00
newdisk . path = newdisk . path
newdisk . set_local_disk_to_clone ( srcdisk , True )
newdisk . build_storage ( None )