uitests: details/domain/config coverage additions

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2020-08-27 16:37:15 -04:00
parent 301892f6b9
commit 687658832e
17 changed files with 305 additions and 129 deletions

View File

@ -753,6 +753,16 @@ test-many-devices, like an alternate RNG, EOL OS ID, title field
<!-- To test enable USB in addhw -->
<controller type='usb' model='none'/>
<!-- serial console duplicate handling -->
<serial type='pty'>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
</devices>
</domain>

View File

@ -6,7 +6,7 @@ host-cpu-usage=true
memory-usage=true
[org/virt-manager/virt-manager/connections]
uris=['test:///default', 'foo:///']
uris=['test:///default']
autoconnect=['test:///default']
[org/virt-manager/virt-manager]

View File

@ -107,5 +107,18 @@ class VMMCLI(uiutils.UITestCase):
uiutils.check(lambda: not self.app.is_running())
def testCLITraceLibvirt(self):
self.app.open(extra_opts=["--trace-libvirt=mainloop"])
self.sleep(5)
# Just test this for code coverage
self.app.open(keyfile="allstats.ini",
extra_opts=["--trace-libvirt=mainloop"])
# Give it a little time to work
self.sleep(2)
uiutils.check(lambda: self.app.topwin.active)
def testCLILeakDebug(self):
# Just test this for code coverage
self.app.open(keyfile="allstats.ini",
extra_opts=["--test-options=leak-debug"])
self.sleep(2)
# Give it a little time to work
uiutils.check(lambda: self.app.topwin.active)
self.app.topwin.keyCombo("<alt>F4")

View File

@ -17,8 +17,7 @@ class VMMConnect(uiutils.UITestCase):
# Start with connection delete
c = self.app.root.find("test testdriver.xml", "table cell")
c.click(button=3)
self.app.root.find("conn-disconnect",
"menu item").click()
self.app.root.find("conn-disconnect", "menu item").click()
uiutils.check(lambda: "Not Connected" in c.text)
c.click(button=3)
self.app.root.find("conn-delete", "menu item").click()
@ -138,3 +137,8 @@ class VMMConnect(uiutils.UITestCase):
c.doubleClick()
c = self.app.root.find("test default", "table cell")
c.click()
# Delete it
c.click(button=3)
self.app.root.find("conn-delete", "menu item").click()
self._click_alert_button("will remove the connection", "Yes")
uiutils.check(lambda: c.dead)

View File

@ -234,7 +234,6 @@ class NewVM(uiutils.UITestCase):
# Change NIC mac
vmwindow.find_fuzzy("NIC", "table cell").click()
tab = vmwindow.find("network-tab")
tab.print_nodes()
tab.find("mac-entry", "text").set_text("00:11:00:11:00:11")
appl.click()
uiutils.check(lambda: not appl.sensitive)
@ -307,9 +306,73 @@ class NewVM(uiutils.UITestCase):
self.app.root.find_fuzzy("fedora10 on", "frame")
uiutils.check(lambda: not newvm.showing)
def testNewKVMQ35(self):
def testNewKVMQ35Tweaks(self):
"""
New VM that should default to Q35
New VM that should default to Q35, but tweak things a bunch
"""
self.app.uri = tests.utils.URIs.kvm
newvm = self._open_create_wizard()
newvm.find_fuzzy("Import", "radio").click()
self.forward(newvm)
newvm.find("import-entry").set_text("/dev/default-pool/testvol1.img")
newvm.find("oslist-entry").set_text("fedora30")
popover = newvm.find("oslist-popover")
popover.find("include-eol").click()
popover.find_fuzzy("Fedora 30").click()
self.forward(newvm)
self.forward(newvm)
# Select customize wizard, we will use this VM to
# hit some code paths elsewhere
newvm.find_fuzzy("Customize", "check").click()
newvm.find_fuzzy("Finish", "button").click()
vmname = "fedora30"
details = self.app.root.find_fuzzy("%s on" % vmname, "frame")
appl = details.find("config-apply")
# Tweak some Overview settings
details.combo_check_default("Chipset:", "Q35")
details.combo_check_default("Firmware:", "BIOS")
# Switch i440FX and back
details.combo_select("Chipset:", "i440FX")
appl.click()
uiutils.check(lambda: not appl.sensitive)
details.combo_select("Chipset:", "Q35")
appl.click()
uiutils.check(lambda: not appl.sensitive)
# Switch to UEFI, back to BIOS, back to UEFI
details.combo_select("Firmware:", ".*x86_64.*")
appl.click()
uiutils.check(lambda: not appl.sensitive)
# Switch back to BIOS
details.combo_select("Firmware:", "BIOS")
appl.click()
uiutils.check(lambda: not appl.sensitive)
# Switch back to UEFI
details.combo_select("Firmware:", ".*x86_64.*")
appl.click()
uiutils.check(lambda: not appl.sensitive)
# Add another network device
details.find("add-hardware", "push button").click()
addhw = self.app.root.find("Add New Virtual Hardware", "frame")
addhw.find("Network", "table cell").click()
tab = addhw.find("network-tab", None)
uiutils.check(lambda: tab.showing)
addhw.find("Finish", "push button").click()
uiutils.check(lambda: not addhw.active)
uiutils.check(lambda: details.active)
# Finish
details.find_fuzzy("Begin Installation", "button").click()
uiutils.check(lambda: details.dead)
self.app.root.find_fuzzy("%s on" % vmname, "frame")
def testNewKVMQ35UEFI(self):
"""
New VM that should default to Q35, and set UEFI
"""
self.app.uri = tests.utils.URIs.kvm
newvm = self._open_create_wizard()
@ -331,28 +394,17 @@ class NewVM(uiutils.UITestCase):
vmname = "fedora30"
details = self.app.root.find_fuzzy("%s on" % vmname, "frame")
# Tweak some Overview settings
# Change to UEFI
details.combo_check_default("Chipset:", "Q35")
details.combo_check_default("Firmware:", "BIOS")
details.combo_select("Firmware:", ".*x86_64.*")
details.find("config-apply").click()
# Add another network device
details.find("add-hardware", "push button").click()
addhw = self.app.root.find("Add New Virtual Hardware", "frame")
addhw.find("Network", "table cell").click()
tab = addhw.find("network-tab", None)
uiutils.check(lambda: tab.showing)
addhw.find("Finish", "push button").click()
uiutils.check(lambda: not addhw.active)
uiutils.check(lambda: details.active)
# Finish
details.find_fuzzy("Begin Installation", "button").click()
uiutils.check(lambda: details.dead)
self.app.root.find_fuzzy("%s on" % vmname, "frame")
def testNewPPC64(self):
"""
New PPC64 VM to test architecture selection
@ -380,6 +432,13 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Finish", "button").click()
details = self.app.root.find_fuzzy("vm-ppc64 on", "frame")
tab = details.find("overview-tab")
tab.combo_check_default("machine-combo", "pseries")
tab.combo_select("machine-combo", "pseries-2.1")
appl = details.find("config-apply")
appl.click()
uiutils.check(lambda: not appl.sensitive)
# Add a TPM SPAPR device
details.find("add-hardware", "push button").click()
addhw = self.app.root.find("Add New Virtual Hardware", "frame")
@ -513,7 +572,6 @@ class NewVM(uiutils.UITestCase):
# Tweak init values
details.find("Boot Options", "table cell").click()
tab = details.find("boot-tab")
tab.print_nodes()
tab.find("Init path:", "text").set_text("")
tab.find("Init args:", "text").set_text("some args")
appl = details.find("config-apply")
@ -772,11 +830,28 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Customize", "check").click()
newvm.find_fuzzy("Name", "text").set_text(vmname)
newvm.find_fuzzy("Finish", "button").click()
# Change a VM setting and verify it
win = self.app.root.find_fuzzy("%s on" % vmname, "frame")
xmleditor = win.find("XML editor")
finish = win.find("config-apply")
# Change a device setting with the XML editor
win.find_fuzzy("IDE Disk 1", "table cell").click()
tab = win.find("disk-tab")
win.find("XML", "page tab").click()
# Change the disk path via the XML editor
fname = vmname + ".qcow2"
uiutils.check(lambda: fname in xmleditor.text)
newx = xmleditor.text.replace(fname, "default-vol")
xmleditor.set_text(newx)
appl = win.find("config-apply")
# This is kindof a bug, changing path in XML editor in Customize
# doesn't take effect for storage with creation parameters, but
# it's a pain to fix.
appl.click()
uiutils.check(lambda: not appl.sensitive)
uiutils.check(lambda: vmname in xmleditor.text)
# Change a VM setting and verify it
win.find_fuzzy("Boot", "table cell").click()
tab = win.find("boot-tab")
bootmenu = tab.find("Enable boot menu", "check box")
@ -833,7 +908,6 @@ class NewVM(uiutils.UITestCase):
browser = self.app.root.find("vmm-storage-browser")
browser.find("%s.qcow2" % vmname, "table cell")
def testNewVMRemote(self):
"""
Hit some is_remote code paths

View File

@ -49,13 +49,18 @@ class Details(uiutils.UITestCase):
# Select XML editor, and reverse walk the list
win.find("XML", "page tab").click()
self._walkUIList(win, lst, lambda: False, reverse=True)
return win
def testDetailsHardwareSmokeTest(self):
self._testSmokeTest(None)
def testDetailsHardwareSmokeTestAlternate(self):
self.app.open(keyfile="allstats.ini")
self._testSmokeTest("test alternate devs title")
win = self._testSmokeTest("test alternate devs title")
win.find("Details", "page tab").click()
self._select_hw(win, "Performance", "performance-tab")
# Wait for perf signals to trigger, to cover more code
self.sleep(2)
def _testRename(self, origname, newname):
# Enable all stats prefs to hit some extra code
@ -66,8 +71,16 @@ class Details(uiutils.UITestCase):
win.find("Overview", "table cell").click()
oldcell = self.app.root.find_fuzzy(origname, "table cell")
badname = "foo/bar"
win.find("Name:", "text").set_text(badname)
appl = win.find("config-apply")
appl.click()
self._click_alert_button(badname, "Close")
# Actual name change
win.find("Name:", "text").set_text(newname)
win.find("config-apply", "push button").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
# Confirm lists were updated
self.app.root.find("%s on" % newname, "frame")
@ -91,7 +104,6 @@ class Details(uiutils.UITestCase):
self.app.root.find_fuzzy(origname, "table cell").click()
b = self.app.root.find("Shut Down", "push button")
b.click()
# This insures the VM finished shutting down
uiutils.check(lambda: b.sensitive is False)
self._testRename(origname, "test-new-name")
@ -102,7 +114,9 @@ class Details(uiutils.UITestCase):
"""
self.app.uri = tests.utils.URIs.kvm
win = self._open_details_window(vmname="test", shutdown=True)
self.app.topwin.click_title()
fmenu = win.find("File", "menu")
fmenu.click()
fmenu.find("View Manager").click()
# Double run to hit a show() codepath
win = self._open_details_window(vmname="test")
uiutils.check(lambda: win.active)
@ -308,6 +322,30 @@ class Details(uiutils.UITestCase):
tab = self._select_hw(win, "Boot Options", "boot-tab")
uiutils.check(lambda: "backing" in initrd.text)
def testDetailsAlternateEdits(self):
"""
Some specific handling via test-alternate-devs
"""
win = self._open_details_window(vmname="test alternate devs title")
# tests the console dup removal
self._select_hw(win, "Serial 1", "char-tab")
win.find("config-remove").click()
self._click_alert_button("Are you sure", "Yes")
self._click_alert_button("take effect after", "OK")
self._stop_vm(win)
def testDetailsEmptyBoot(self):
"""
Check boot handling when VM has no devices
"""
win = self._open_details_window(vmname="test-state-crashed")
self._select_hw(win, "Boot Options", "boot-tab")
win.find("No bootable devices")
# Add in switching back to the console view to hit a vmwindow path
win.find("Console", "radio button").click()
def testDetailsEditDiskNet(self):
"""
Test disk and network devices
@ -398,8 +436,7 @@ class Details(uiutils.UITestCase):
"""
Test all other devices
"""
win = self._open_details_window(vmname="test-many-devices",
shutdown=True)
win = self._open_details_window(vmname="test-many-devices")
appl = win.find("config-apply", "push button")
# Fail to hotremove
@ -506,6 +543,10 @@ class Details(uiutils.UITestCase):
tab.combo_select("controller-model", "USB 3")
appl.click()
uiutils.check(lambda: not appl.sensitive)
tab = self._select_hw(win, "Controller USB 0", "controller-tab")
tab.find("controller-model").find(None, "text").text = "piix3-uhci"
appl.click()
uiutils.check(lambda: not appl.sensitive)
# Filesystem tweaks

View File

@ -160,7 +160,8 @@ class Host(uiutils.UITestCase):
win.find_fuzzy("Network", "tab").click()
win.find_fuzzy("Overview", "tab").click()
# Unset autoconnect
# Toggle autoconnect
win.find("Autoconnect:", "check box").click()
win.find("Autoconnect:", "check box").click()
# Change the name, verify that title bar changed

View File

@ -42,3 +42,14 @@ class VMMInspection(uiutils.UITestCase):
assert "test_app1_summary" in nodestr1
tab.find("Refresh", "push button").click()
uiutils.check(lambda: apps.fmt_nodes() != nodestr1)
details.keyCombo("<alt>F4")
uiutils.check(lambda: not details.showing)
# Open a VM with no disks which will report an inspection error
self.app.root.find_fuzzy("test\n", "table cell").doubleClick()
details = self.app.root.find("test on", "frame")
details.find("Details", "radio button").click()
details.find("OS information", "table cell").click()
tab = details.find("os-tab")
tab.find_fuzzy("Fake test error no disks")

View File

@ -1,6 +1,7 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests import utils
from tests.uitests import utils as uiutils
@ -47,6 +48,8 @@ class Manager(uiutils.UITestCase):
uiutils.check(lambda: shutdown.sensitive, timeout=5)
def testVMLifecycle(self):
# qemu hits some different domain code paths for setTime
self.app.uri = utils.URIs.kvm
self._testVMLifecycle()
def testVMNoEventsLifecycle(self):
@ -130,7 +133,7 @@ class Manager(uiutils.UITestCase):
test_action("Restore", shutdown=False, confirm=False)
confirm_is_running()
def testManagedManagedSaveCornerCases(self):
def testManagerSaveCancelError(self):
"""
Test managed save special behavior
"""
@ -162,6 +165,32 @@ class Manager(uiutils.UITestCase):
self._click_alert_button("remove the saved state", "Yes")
uiutils.check(lambda: not run.sensitive)
def testManagerQEMUSetTime(self):
"""
Fake qemu setTime behavior for code coverage
"""
self.app.uri = utils.URIs.kvm
manager = self.app.topwin
run = manager.find("Run", "push button")
smenu = manager.find("Menu", "toggle button")
save = manager.find("Save", "menu item")
c = manager.find("test alternate devs title", "table cell")
c.click()
# Save -> resume -> save
smenu.click()
save.click()
uiutils.check(lambda: run.sensitive)
self.sleep(1)
run.click()
uiutils.check(lambda: not run.sensitive)
self.sleep(1)
smenu.click()
save.click()
uiutils.check(lambda: run.sensitive)
self.sleep(1)
def testManagerVMRunFail(self):
# Force VM startup to fail so we can test the error path
self.app.open(extra_opts=["--test-options=test-vm-run-fail"])
@ -220,6 +249,10 @@ class Manager(uiutils.UITestCase):
"""
manager = self.app.topwin
host = self._open_host_window("Storage")
fmenu = host.find("File", "menu")
fmenu.click()
fmenu.find("View Manager", "menu item").click()
uiutils.check(lambda: manager.active)
# Double click title to maximize
manager.click_title()

View File

@ -44,6 +44,13 @@ class Snapshots(uiutils.UITestCase):
vmpause = win.find("Pause", "toggle button")
snaprun = win.find("snapshot-start", "push button")
# Start already running snapshot
snapname = "internal-root"
win.find(snapname, "table cell").click()
snaprun.click()
self._click_alert_button("run the snapshot '%s'" % snapname, "Yes")
uiutils.check(lambda: not vmrun.sensitive)
# Start offline snapshot
snapname = "offline-root"
win.find(snapname, "table cell").click()

View File

@ -569,6 +569,11 @@
<property name="can_focus">False</property>
<property name="halign">start</property>
<signal name="changed" handler="on_machine_type_changed" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="machine-type-atkobject">
<property name="AtkObject::accessible-name">machine-combo</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>

View File

@ -4,8 +4,6 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import os
from gi.repository import Gio
from gi.repository import GLib
from gi.repository import Gtk
@ -151,18 +149,25 @@ class vmmConfig(object):
"local_title": _("Locate existing storage"),
"dialog_type": Gtk.FileChooserAction.SAVE,
"choose_button": Gtk.STOCK_OPEN,
"gsettings_key": "image",
},
CONFIG_DIR_SCREENSHOT: {
"gsettings_key": "screenshot",
},
CONFIG_DIR_ISO_MEDIA: {
"enable_create": False,
"storage_title": _("Locate ISO media volume"),
"local_title": _("Locate ISO media"),
"gsettings_key": "media",
},
CONFIG_DIR_FLOPPY_MEDIA: {
"enable_create": False,
"storage_title": _("Locate floppy media volume"),
"local_title": _("Locate floppy media"),
"gsettings_key": "media",
},
CONFIG_DIR_FS: {
@ -367,11 +372,9 @@ class vmmConfig(object):
def on_keys_combination_changed(self, cb):
return self.conf.notify_add("/console/grab-keys", cb)
# This key is not intended to be exposed in the UI yet
# This key is not intended to be exposed in the UI yet (maybe ever)
def get_keyboard_grab_default(self):
return self.conf.get("/console/grab-keyboard")
def set_keyboard_grab_default(self, val):
self.conf.set("/console/grab-keyboard", val)
def on_keyboard_grab_default_changed(self, cb):
return self.conf.notify_add("/console/grab-keyboard", cb)
@ -422,8 +425,6 @@ class vmmConfig(object):
# Libguestfs VM inspection
def on_libguestfs_inspect_vms_changed(self, cb):
return self.conf.notify_add("/enable-libguestfs-vm-inspection", cb)
def get_libguestfs_inspect_vms(self):
if self.CLITestOptions.config_libguestfs:
return True
@ -439,9 +440,7 @@ class vmmConfig(object):
return 120
def get_stats_update_interval(self):
interval = self.conf.get("/stats/update-interval")
if interval < 1:
return 1
return interval
return max(interval, 1)
def set_stats_update_interval(self, interval):
self.conf.set("/stats/update-interval", interval)
def on_stats_update_interval_changed(self, cb):
@ -482,20 +481,16 @@ class vmmConfig(object):
def get_console_accels(self):
console_pref = self.conf.get("/console/enable-accels")
if console_pref is None:
console_pref = False
console_pref = False # pragma: no cover
return console_pref
def set_console_accels(self, pref):
self.conf.set("/console/enable-accels", pref)
def on_console_scaling_changed(self, cb):
return self.conf.notify_add("/console/scaling", cb)
def get_console_scaling(self):
return self.conf.get("/console/scaling")
def set_console_scaling(self, pref):
self.conf.set("/console/scaling", pref)
def on_console_resizeguest_changed(self, cb):
return self.conf.notify_add("/console/resize-guest", cb)
def get_console_resizeguest(self):
val = self.conf.get("/console/resize-guest")
if val == -1:
@ -513,21 +508,11 @@ class vmmConfig(object):
def get_details_show_toolbar(self):
res = self.conf.get("/details/show-toolbar")
if res is None:
res = True
res = True # pragma: no cover
return res
def set_details_show_toolbar(self, state):
self.conf.set("/details/show-toolbar", state)
# VM details default size
def get_details_window_size(self):
w = self.conf.get("/details/window_width")
h = self.conf.get("/details/window_height")
return (w, h)
def set_details_window_size(self, w, h):
self.conf.set("/details/window_width", w)
self.conf.set("/details/window_height", h)
# New VM preferences
def get_new_vm_sound(self):
return self.conf.get("/new-vm/add-sound")
@ -537,7 +522,7 @@ class vmmConfig(object):
def get_graphics_type(self, raw=False):
ret = self.conf.get("/new-vm/graphics-type")
if ret not in ["system", "vnc", "spice"]:
ret = "system"
ret = "system" # pragma: no cover
if ret == "system" and not raw:
return self.default_graphics_from_config
return ret
@ -547,9 +532,7 @@ class vmmConfig(object):
def get_add_spice_usbredir(self, raw=False):
ret = self.conf.get("/new-vm/add-spice-usbredir")
if ret not in ["system", "yes", "no"]:
ret = "system"
if not raw and self.get_graphics_type() != "spice":
return "no"
ret = "system" # pragma: no cover
if ret == "system" and not raw:
return self.default_add_spice_usbredir
return ret
@ -559,7 +542,7 @@ class vmmConfig(object):
def get_default_storage_format(self, raw=False):
ret = self.conf.get("/new-vm/storage-format")
if ret not in ["default", "raw", "qcow2"]:
ret = "default"
ret = "default" # pragma: no cover
if ret == "default" and not raw:
return self.default_storage_format_from_config
return ret
@ -570,7 +553,7 @@ class vmmConfig(object):
ret = self.conf.get("/new-vm/cpu-default")
if ret not in DomainCpu.SPECIAL_MODES:
ret = DomainCpu.SPECIAL_MODE_APP_DEFAULT
ret = DomainCpu.SPECIAL_MODE_APP_DEFAULT # pragma: no cover
return ret
def set_default_cpu_setting(self, val):
self.conf.set("/new-vm/cpu-default", val.lower())
@ -579,15 +562,13 @@ class vmmConfig(object):
# URL/Media path history
def _url_add_helper(self, gsettings_path, url):
maxlength = 10
urls = self.conf.get(gsettings_path)
if urls is None:
urls = []
urls = self.conf.get(gsettings_path) or []
if urls.count(url) == 0 and len(url) > 0 and not url.isspace():
# The url isn't already in the list, so add it
urls.insert(0, url)
if len(urls) > maxlength:
del urls[len(urls) - 1]
del urls[len(urls) - 1] # pragma: no cover
self.conf.set(gsettings_path, urls)
def add_container_url(self, url):
@ -613,7 +594,7 @@ class vmmConfig(object):
current_list = self.get_perms_fix_ignore() or []
for path in pathlist:
if path in current_list:
continue
continue # pragma: no cover
current_list.append(path)
self.conf.set("/paths/perms-fix-ignore", current_list)
def get_perms_fix_ignore(self):
@ -654,9 +635,7 @@ class vmmConfig(object):
return ((uris is not None) and (uri in uris))
def set_conn_autoconnect(self, uri, val):
uris = self.conf.get("/connections/autoconnect")
if uris is None:
uris = []
uris = self.conf.get("/connections/autoconnect") or []
if not val and uri in uris:
uris.remove(uri)
elif val and uri not in uris:
@ -666,36 +645,23 @@ class vmmConfig(object):
# Default directory location dealings
def _get_default_dir_key(self, _type):
if (_type in [self.CONFIG_DIR_ISO_MEDIA,
self.CONFIG_DIR_FLOPPY_MEDIA]):
return "media"
if (_type in [self.CONFIG_DIR_IMAGE,
self.CONFIG_DIR_SCREENSHOT]):
return _type
return None
def get_default_directory(self, conn, _type):
ignore = conn
key = self._get_default_dir_key(_type)
browsedata = self.browse_reason_data.get(_type, {})
key = browsedata.get("gsettings_key", None)
path = None
if key:
path = self.conf.get("/paths/%s-default" % key)
if not path:
if (_type == self.CONFIG_DIR_IMAGE or
_type == self.CONFIG_DIR_ISO_MEDIA or
_type == self.CONFIG_DIR_FLOPPY_MEDIA):
path = os.getcwd()
log.debug("directory for type=%s returning=%s", _type, path)
return path
def set_default_directory(self, folder, _type):
key = self._get_default_dir_key(_type)
browsedata = self.browse_reason_data.get(_type, {})
key = browsedata.get("gsettings_key", None)
if not key:
return
return # pragma: no cover
log.debug("saving directory for type=%s to %s", key, folder)
self.conf.set("/paths/%s-default" % key, folder)

View File

@ -342,8 +342,7 @@ class vmmDeleteStorage(_vmmDeleteBase):
# Try to hot remove
detach_err = ()
try:
if vm.is_active():
vm.detach_device(devobj)
vm.detach_device(devobj)
except Exception as e:
log.debug("Device could not be hotUNplugged: %s", str(e))
detach_err = (str(e), "".join(traceback.format_exc()))

View File

@ -683,7 +683,7 @@ class vmmDetails(vmmGObjectUI):
warn_icon.set_tooltip_text(
_("Libvirt or hypervisor does not support UEFI."))
elif not uefipaths:
warn_icon.set_tooltip_text(
warn_icon.set_tooltip_text( # pragma: no cover
_("Libvirt did not detect any UEFI/OVMF firmware image "
"installed on the host."))
@ -982,7 +982,7 @@ class vmmDetails(vmmGObjectUI):
pagetype = self._get_hw_row()[HW_LIST_COL_TYPE]
if pagetype is None:
return
return # pragma: no cover
if self.widget("config-apply").get_sensitive():
# Apply button sensitive means user is making changes, don't
@ -1046,6 +1046,10 @@ class vmmDetails(vmmGObjectUI):
self.vm, self.err, devobj)
if not success:
return
# This call here means when the vm config changes and triggers
# refresh event, the UI page will be updated, rather than leaving
# it untouched because it thinks changes are in progress
self._disable_apply()
def _remove_disk(self, disk):
@ -1233,7 +1237,7 @@ class vmmDetails(vmmGObjectUI):
if new_idx < 0 or new_idx >= len(boot_order):
# Somehow we went out of bounds
return
return # pragma: no cover
boot_list = self.widget("boot-list")
model = boot_list.get_model()
@ -1814,19 +1818,17 @@ class vmmDetails(vmmGObjectUI):
# Machine settings
machtype = self.vm.get_machtype() or _("Unknown")
self.widget("machine-type-label").set_text(machtype)
if self.widget("machine-type").is_visible():
uiutil.set_list_selection(
self.widget("machine-type"), machtype)
elif self.widget("machine-type-label").is_visible():
self.widget("machine-type-label").set_text(machtype)
# Chipset
chipset = _chipset_label_from_machine(machtype)
self.widget("overview-chipset-label").set_text(chipset)
if self.widget("overview-chipset").is_visible():
uiutil.set_list_selection(
self.widget("overview-chipset"), chipset)
elif self.widget("overview-chipset-label").is_visible():
self.widget("overview-chipset-label").set_text(chipset)
def _refresh_os_page(self):
self._os_list.select_os(self.vm.xmlobj.osinfo)
@ -2165,7 +2167,7 @@ class vmmDetails(vmmGObjectUI):
typelabel = _("Console Device")
elif char_type == "channel":
typelabel = _("Channel Device")
else:
else: # pragma: no cover
typelabel = _("%s Device") % char_type.capitalize()
if (target_port is not None and

View File

@ -19,10 +19,13 @@ def _inspection_error(_errstr):
return data
def _make_fake_data():
def _make_fake_data(vm):
"""
Return fake vmmInspectionData for use with the test driver
"""
if not vm.xmlobj.devices.disk:
return _inspection_error("Fake test error no disks")
data = vmmInspectionData()
data.os_type = "test_os_type"
data.distro = "test_distro"
@ -324,7 +327,7 @@ class vmmInspection(vmmGObject):
return _inspection_error(
_("Cannot inspect VM on remote connection"))
if conn.is_test():
return _make_fake_data()
return _make_fake_data(vm)
return _perform_inspection(conn, vm)

View File

@ -276,8 +276,9 @@ class _vmmDomainSetTimeThread(vmmGObject):
# Only run the API for qemu and test drivers, they are the only ones
# that support it. This will save spamming logs with error output.
if not self._domain.conn.is_qemu() and not self._domain.conn.is_test():
return
if (not self._domain.conn.is_qemu() and
not self._domain.conn.is_test()):
return # pragma: no cover
# For qemu, only run the API if the VM has the qemu guest agent in
# the XML.
@ -304,30 +305,32 @@ class _vmmDomainSetTimeThread(vmmGObject):
self._thread = None
self._do_cancel.clear()
def _wait_for_agent(self):
# Setting time of a qemu domain can only work if an agent is
# defined and online. We only get here if one is defined. So wait
# for it to come online now.
waited = 0
while waited < self._maxwait and not self._domain.agent_ready():
if waited == 0:
log.debug("Waiting for qemu guest agent to come online...")
# sleep some time and potentially abort
if self._do_cancel.wait(self._sleep):
return
waited += self._sleep
if not self._domain.agent_ready(): # pragma: no cover
log.debug("Giving up on qemu guest agent for time sync")
return
def _do_loop(self):
"""
Run the domain's set time operation. Potentially wait for a guest agent
to come online beforehand.
"""
if self._domain.conn.is_qemu():
# Setting time of a qemu domain can only work if an agent is
# defined and online. We only get here if one is defined. So wait
# for it to come online now.
waited = 0
while waited < self._maxwait and not self._domain.agent_ready():
if waited == 0:
log.debug("Waiting for qemu guest agent to come online...")
# sleep some time and potentially abort
if self._do_cancel.wait(self._sleep):
return
waited += self._sleep
if not self._domain.agent_ready():
log.debug("Giving up on qemu guest agent for time sync")
return
self._wait_for_agent()
self._domain.set_time()
def _cleanup(self):
@ -369,6 +372,8 @@ class vmmDomain(vmmLibvirtObject):
for snap in self._snapshot_list or []:
snap.cleanup()
self._snapshot_list = None
self._set_time_thread.cleanup()
self._set_time_thread = None
vmmLibvirtObject._cleanup(self)
def _init_libvirt_state(self):
@ -556,7 +561,7 @@ class vmmDomain(vmmLibvirtObject):
if new_nvram:
try:
new_nvram.get_vol_object().delete(0)
except Exception as warn:
except Exception as warn: # pragma: no cover
log.debug("rename failed and new nvram was not "
"removed: '%s'", warn)
raise error
@ -564,7 +569,7 @@ class vmmDomain(vmmLibvirtObject):
if new_nvram:
try:
old_nvram.get_vol_object().delete(0)
except Exception as warn:
except Exception as warn: # pragma: no cover
log.debug("old nvram file was not removed: '%s'", warn)
self.define_overview(nvram=new_nvram.path)
@ -1059,7 +1064,9 @@ class vmmDomain(vmmLibvirtObject):
def job_info(self):
if self.conn.is_test():
return testmock.fake_job_info()
return self._backend.jobInfo()
# It's tough to hit this via uitests because it depends
# on the job lasting more than a second
return self._backend.jobInfo() # pragma: no cover
def abort_job(self):
self._backend.abortJob()
@ -1168,7 +1175,7 @@ class vmmDomain(vmmLibvirtObject):
self._backend.setTime(time={"seconds": seconds,
"nseconds": nseconds})
log.debug("Successfully set guest time")
except Exception as e:
except Exception as e: # pragma: no cover
log.debug("Failed to set time: %s", e)
def _async_set_time(self):
@ -1256,7 +1263,7 @@ class vmmDomain(vmmLibvirtObject):
consoles = self.xmlobj.devices.console
if not consoles:
return False
return False # pragma: no cover
console = consoles[0]
if (console.type == serial.type and

View File

@ -462,8 +462,8 @@ class vmmVMWindow(vmmGObjectUI):
vmmenu.VMActionUI.resume(self, self.vm)
def control_vm_menu(self, src_ignore):
can_usb = bool(self.console.details_viewer_has_usb_redirection() and
self.vm.has_spicevmc_type_redirdev())
can_usb = bool(self.vm.has_spicevmc_type_redirdev() and
self.console.details_viewer_has_usb_redirection())
self.widget("details-menu-usb-redirection").set_sensitive(can_usb)
def control_vm_run(self, src_ignore):