mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-12-22 13:34:07 +03:00
uitests: details/domain/config coverage additions
Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
parent
301892f6b9
commit
687658832e
@ -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>
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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()))
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user