summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCole Robinson <crobinso@redhat.com>2020-08-26 18:01:02 -0400
committerCole Robinson <crobinso@redhat.com>2020-08-27 18:10:11 -0400
commiteea394b9d3e94cd903fa37c1cb69388a8af7e1fd (patch)
treec8ddc490c5936bc581afeff483476f43a40a28fc
parent701164c66404a596be163c2abff3e67d2adb91b6 (diff)
downloadvirt-manager-eea394b9d3e94cd903fa37c1cb69388a8af7e1fd.tar.gz
uitests: Increase details + domain + vmwindow coverage
Signed-off-by: Cole Robinson <crobinso@redhat.com>
-rw-r--r--tests/data/capabilities/kvm-x86_64-insecure-domcaps.xml180
-rw-r--r--tests/data/testdriver/testdriver.xml2
-rw-r--r--tests/uitests/test_createvm.py87
-rw-r--r--tests/uitests/test_details.py180
-rw-r--r--tests/uitests/test_mediachange.py9
-rw-r--r--tests/utils.py1
-rw-r--r--ui/details.ui13
-rw-r--r--virtManager/details/details.py75
-rw-r--r--virtManager/lib/inspection.py11
-rw-r--r--virtManager/object/domain.py143
-rw-r--r--virtManager/vmwindow.py18
11 files changed, 559 insertions, 160 deletions
diff --git a/tests/data/capabilities/kvm-x86_64-insecure-domcaps.xml b/tests/data/capabilities/kvm-x86_64-insecure-domcaps.xml
new file mode 100644
index 00000000..8071e69b
--- /dev/null
+++ b/tests/data/capabilities/kvm-x86_64-insecure-domcaps.xml
@@ -0,0 +1,180 @@
+<domainCapabilities>
+ <path>/usr/bin/qemu-system-x86_64</path>
+ <domain>kvm</domain>
+ <machine>pc-i440fx-4.2</machine>
+ <arch>x86_64</arch>
+ <vcpu max='255'/>
+ <iothreads supported='yes'/>
+ <os supported='yes'>
+ <enum name='firmware'>
+ <value>efi</value>
+ </enum>
+ <loader supported='yes'>
+ <value>/usr/share/edk2/ovmf/OVMF_CODE.fd</value>
+ <enum name='type'>
+ <value>rom</value>
+ <value>pflash</value>
+ </enum>
+ <enum name='readonly'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
+ </loader>
+ </os>
+ <cpu>
+ <mode name='host-passthrough' supported='yes'/>
+ <mode name='host-model' supported='yes'>
+ <model fallback='forbid'>Skylake-Client-IBRS</model>
+ <vendor>Intel</vendor>
+ <feature policy='require' name='ss'/>
+ <feature policy='require' name='vmx'/>
+ <feature policy='require' name='hypervisor'/>
+ <feature policy='require' name='tsc_adjust'/>
+ <feature policy='require' name='clflushopt'/>
+ <feature policy='require' name='umip'/>
+ <feature policy='require' name='md-clear'/>
+ <feature policy='require' name='stibp'/>
+ <feature policy='require' name='arch-capabilities'/>
+ <feature policy='require' name='ssbd'/>
+ <feature policy='require' name='xsaves'/>
+ <feature policy='require' name='pdpe1gb'/>
+ <feature policy='require' name='invtsc'/>
+ <feature policy='require' name='ibpb'/>
+ <feature policy='require' name='amd-ssbd'/>
+ <feature policy='require' name='skip-l1dfl-vmentry'/>
+ </mode>
+ <mode name='custom' supported='yes'>
+ <model usable='yes'>qemu64</model>
+ <model usable='yes'>qemu32</model>
+ <model usable='no'>phenom</model>
+ <model usable='yes'>pentium3</model>
+ <model usable='yes'>pentium2</model>
+ <model usable='yes'>pentium</model>
+ <model usable='yes'>n270</model>
+ <model usable='yes'>kvm64</model>
+ <model usable='yes'>kvm32</model>
+ <model usable='yes'>coreduo</model>
+ <model usable='yes'>core2duo</model>
+ <model usable='no'>athlon</model>
+ <model usable='yes'>Westmere-IBRS</model>
+ <model usable='yes'>Westmere</model>
+ <model usable='no'>Skylake-Server-IBRS</model>
+ <model usable='no'>Skylake-Server</model>
+ <model usable='yes'>Skylake-Client-IBRS</model>
+ <model usable='yes'>Skylake-Client</model>
+ <model usable='yes'>SandyBridge-IBRS</model>
+ <model usable='yes'>SandyBridge</model>
+ <model usable='yes'>Penryn</model>
+ <model usable='no'>Opteron_G5</model>
+ <model usable='no'>Opteron_G4</model>
+ <model usable='no'>Opteron_G3</model>
+ <model usable='yes'>Opteron_G2</model>
+ <model usable='yes'>Opteron_G1</model>
+ <model usable='yes'>Nehalem-IBRS</model>
+ <model usable='yes'>Nehalem</model>
+ <model usable='yes'>IvyBridge-IBRS</model>
+ <model usable='yes'>IvyBridge</model>
+ <model usable='no'>Icelake-Server</model>
+ <model usable='no'>Icelake-Client</model>
+ <model usable='yes'>Haswell-noTSX-IBRS</model>
+ <model usable='yes'>Haswell-noTSX</model>
+ <model usable='yes'>Haswell-IBRS</model>
+ <model usable='yes'>Haswell</model>
+ <model usable='no'>EPYC-IBPB</model>
+ <model usable='no'>EPYC</model>
+ <model usable='no'>Dhyana</model>
+ <model usable='yes'>Conroe</model>
+ <model usable='no'>Cascadelake-Server</model>
+ <model usable='yes'>Broadwell-noTSX-IBRS</model>
+ <model usable='yes'>Broadwell-noTSX</model>
+ <model usable='yes'>Broadwell-IBRS</model>
+ <model usable='yes'>Broadwell</model>
+ <model usable='yes'>486</model>
+ </mode>
+ </cpu>
+ <devices>
+ <disk supported='yes'>
+ <enum name='diskDevice'>
+ <value>disk</value>
+ <value>cdrom</value>
+ <value>floppy</value>
+ <value>lun</value>
+ </enum>
+ <enum name='bus'>
+ <value>ide</value>
+ <value>fdc</value>
+ <value>scsi</value>
+ <value>virtio</value>
+ <value>usb</value>
+ <value>sata</value>
+ </enum>
+ <enum name='model'>
+ <value>virtio</value>
+ <value>virtio-transitional</value>
+ <value>virtio-non-transitional</value>
+ </enum>
+ </disk>
+ <graphics supported='yes'>
+ <enum name='type'>
+ <value>sdl</value>
+ <value>vnc</value>
+ <value>spice</value>
+ </enum>
+ </graphics>
+ <video supported='yes'>
+ <enum name='modelType'>
+ <value>vga</value>
+ <value>cirrus</value>
+ <value>vmvga</value>
+ <value>qxl</value>
+ <value>virtio</value>
+ <value>none</value>
+ <value>bochs</value>
+ <value>ramfb</value>
+ </enum>
+ </video>
+ <hostdev supported='yes'>
+ <enum name='mode'>
+ <value>subsystem</value>
+ </enum>
+ <enum name='startupPolicy'>
+ <value>default</value>
+ <value>mandatory</value>
+ <value>requisite</value>
+ <value>optional</value>
+ </enum>
+ <enum name='subsysType'>
+ <value>usb</value>
+ <value>pci</value>
+ <value>scsi</value>
+ </enum>
+ <enum name='capsType'/>
+ <enum name='pciBackend'/>
+ </hostdev>
+ <rng supported='yes'>
+ <enum name='model'>
+ <value>virtio</value>
+ <value>virtio-transitional</value>
+ <value>virtio-non-transitional</value>
+ </enum>
+ <enum name='backendModel'>
+ <value>random</value>
+ <value>egd</value>
+ <value>builtin</value>
+ </enum>
+ </rng>
+ </devices>
+ <features>
+ <gic supported='no'/>
+ <vmcoreinfo supported='yes'/>
+ <genid supported='yes'/>
+ <backingStoreInput supported='yes'/>
+ <backup supported='no'/>
+ <sev supported='no'/>
+ </features>
+</domainCapabilities>
+
+
diff --git a/tests/data/testdriver/testdriver.xml b/tests/data/testdriver/testdriver.xml
index e6618869..c7cc7e4c 100644
--- a/tests/data/testdriver/testdriver.xml
+++ b/tests/data/testdriver/testdriver.xml
@@ -703,7 +703,7 @@ test-many-devices, like an alternate RNG, EOL OS ID, title field
<currentMemory unit='GiB'>64</currentMemory>
<vcpu>2</vcpu>
<cpu mode='host-model'/>
- <os>
+ <os firmware='efi'>
<type arch='i686'>hvm</type>
<boot dev='hd'/>
</os>
diff --git a/tests/uitests/test_createvm.py b/tests/uitests/test_createvm.py
index 0f623d28..8085d5d6 100644
--- a/tests/uitests/test_createvm.py
+++ b/tests/uitests/test_createvm.py
@@ -231,6 +231,14 @@ class NewVM(uiutils.UITestCase):
appl.click()
uiutils.check(lambda: not appl.sensitive)
+ # Change NIC mac
+ vmwindow.find_fuzzy("NIC", "table cell").click()
+ tab = vmwindow.find("network-tab")
+ tab.print_nodes()
+ tab.find("mac-entry", "text").text = "00:11:00:11:00:11"
+ appl.click()
+ uiutils.check(lambda: not appl.sensitive)
+
# Start the install, close via the VM window
vmwindow.find_fuzzy("Begin Installation", "button").click()
uiutils.check(lambda: newvm.showing is False)
@@ -510,6 +518,20 @@ class NewVM(uiutils.UITestCase):
vmname = "container1"
details = self.app.root.find_fuzzy("%s on" % vmname, "frame")
+ # Tweak init values
+ details.find("Boot Options", "table cell").click()
+ tab = details.find("boot-tab")
+ tab.print_nodes()
+ tab.find("Init path:", "text").text = ""
+ tab.find("Init args:", "text").text = "some args"
+ appl = details.find("config-apply")
+ appl.click()
+ self._click_alert_button("init path must be specified", "OK")
+ uiutils.check(lambda: appl.sensitive)
+ tab.find("Init path:", "text").text = "/some/path"
+ appl.click()
+ uiutils.check(lambda: not appl.sensitive)
+
# Check that addhw container options are disabled
details.find("add-hardware", "push button").click()
addhw = self.app.root.find("Add New Virtual Hardware", "frame")
@@ -526,6 +548,71 @@ class NewVM(uiutils.UITestCase):
uiutils.check(lambda: not newvm.showing)
self.app.root.find_fuzzy("%s on" % vmname, "frame")
+ def testNewVMCustomizeCancel(self):
+ """
+ Test cancelling out of the customize wizard
+ """
+ newvm = self._open_create_wizard()
+ newvm.find_fuzzy("Manual", "radio").click()
+ self.forward(newvm)
+ newvm.find("oslist-entry").text = "generic"
+ newvm.find("oslist-popover").find_fuzzy("generic").click()
+ self.forward(newvm)
+ self.forward(newvm)
+ self.forward(newvm)
+
+ newvm.find_fuzzy("Customize", "check").click()
+ newvm.find_fuzzy("Finish", "button").click()
+ vmname = "vm1"
+ details = self.app.root.find_fuzzy("%s on" % vmname, "frame")
+
+ details.find("Cancel Installation", "push button").click()
+ self._click_alert_button("abort the installation", "No")
+ uiutils.check(lambda: details.active)
+ details.find("Cancel Installation", "push button").click()
+ self._click_alert_button("abort the installation", "Yes")
+ uiutils.check(lambda: not details.active)
+ uiutils.check(lambda: not newvm.active)
+
+ def testNewVMCustomizeMisc(self):
+ """
+ Some specific customize logic paths
+ """
+ newvm = self._open_create_wizard()
+ newvm.find_fuzzy("Manual", "radio").click()
+ self.forward(newvm)
+ newvm.find("oslist-entry").text = "generic"
+ newvm.find("oslist-popover").find_fuzzy("generic").click()
+ self.forward(newvm)
+ self.forward(newvm)
+ self.forward(newvm)
+
+ newvm.find_fuzzy("Customize", "check").click()
+ newvm.find_fuzzy("Finish", "button").click()
+ vmname = "vm1"
+ details = self.app.root.find_fuzzy("%s on" % vmname, "frame")
+
+ # Test name change
+ tab = details.find("overview-tab")
+ nametext = tab.find("Name:", "text")
+ nametext.text = "foonewname"
+ details.find("config-apply").click()
+ self.app.root.find_fuzzy("foonewname", "frame")
+
+ # Trigger XML failure to hit some codepaths
+ nametext.text = ""
+ details.find("Begin Installation").click()
+ self._click_alert_button("unapplied changes", "Yes")
+ self._click_alert_button("name must be specified", "Close")
+ uiutils.check(lambda: details.showing)
+
+ # Discard XML change and continue with install
+ details.find("Begin Installation").click()
+ self._click_alert_button("unapplied changes", "No")
+ uiutils.check(lambda: not details.showing)
+ uiutils.check(lambda: not newvm.showing)
+ self.app.root.find_fuzzy("foonewname on", "frame")
+
def testNewVMContainerTree(self):
"""
diff --git a/tests/uitests/test_details.py b/tests/uitests/test_details.py
index ab07183f..b5287228 100644
--- a/tests/uitests/test_details.py
+++ b/tests/uitests/test_details.py
@@ -96,11 +96,57 @@ class Details(uiutils.UITestCase):
self._testRename(origname, "test-new-name")
+ def testDetailsStateMisc(self):
+ """
+ Test state changes and unapplied changes warnings
+ """
+ self.app.uri = tests.utils.URIs.kvm
+ win = self._open_details_window(vmname="test", shutdown=True)
+ self.app.topwin.click_title()
+ # Double run to hit a show() codepath
+ win = self._open_details_window(vmname="test")
+ uiutils.check(lambda: win.active)
+ appl = win.find("config-apply", "push button")
+
+ # View Manager option
+ win.find("File", "menu").click()
+ win.find("View Manager", "menu item").click()
+ uiutils.check(lambda: self.app.topwin.active)
+ self.app.topwin.keyCombo("<alt>F4")
+ uiutils.check(lambda: win.active)
+
+ # Make a change and then trigger unapplied change warning
+ tab = self._select_hw(win, "Overview", "overview-tab")
+ tab.find("Name:", "text").text = ""
+ uiutils.check(lambda: appl.sensitive)
+ run = win.find("Run", "push button")
+ run.click()
+ # Trigger apply error to hit some code paths
+ self._click_alert_button("unapplied changes", "Yes")
+ self._click_alert_button("name must be specified", "Close")
+ uiutils.check(lambda: run.sensitive)
+ consolebtn = win.find("Console", "radio button")
+ consolebtn.click()
+ self._click_alert_button("unapplied changes", "Yes")
+ self._click_alert_button("name must be specified", "Close")
+ uiutils.check(lambda: not consolebtn.checked)
+
+ # Test the pause toggle
+ win.find("config-cancel").click()
+ run.click()
+ uiutils.check(lambda: not run.sensitive)
+ pause = win.find("Pause", "toggle button")
+ pause.click()
+ uiutils.check(lambda: pause.checked)
+ pause.click()
+ uiutils.check(lambda: not pause.checked)
+ uiutils.check(lambda: win.active)
+
def testDetailsEditDomain1(self):
"""
Test overview, memory, cpu pages
"""
- self.app.uri = tests.utils.URIs.kvm
+ self.app.uri = tests.utils.URIs.kvm_cpu_insecure
win = self._open_details_window(vmname="test")
appl = win.find("config-apply", "push button")
@@ -120,14 +166,9 @@ class Details(uiutils.UITestCase):
appl.click()
uiutils.check(lambda: not appl.sensitive)
- # vCPUs
- tab = self._select_hw(win, "CPUs", "cpu-tab")
- tab.find("vCPU allocation:", "spin button").text = "4"
- appl.click()
- uiutils.check(lambda: not appl.sensitive)
-
# Static CPU config
# more cpu config: host-passthrough, copy, clear CPU, manual
+ tab = self._select_hw(win, "CPUs", "cpu-tab")
tab.find("cpu-model").click_combo_entry()
tab.find_fuzzy("Clear CPU", "menu item").click()
appl.click()
@@ -136,27 +177,49 @@ class Details(uiutils.UITestCase):
tab.find("coreduo", "menu item").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
+ tab.find_fuzzy("CPU security", "check box").click()
+ appl.click()
+ uiutils.check(lambda: not appl.sensitive)
tab.find("cpu-model").click_combo_entry()
tab.find("Application Default", "menu item").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
- tab.find_fuzzy("Copy host").click()
+ copyhost = tab.find("Copy host", "check box")
+ uiutils.check(lambda: copyhost.selected)
+ copyhost.click()
tab.find("cpu-model").click_combo_entry()
tab.find("Hypervisor Default", "menu item").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
+ tab.find("cpu-model").text = "host-passthrough"
+ appl.click()
+ uiutils.check(lambda: not appl.sensitive)
+
+ # vCPUs
+ tab.find("vCPU allocation:", "spin button").text = "50"
+ appl.click()
+ uiutils.check(lambda: not appl.sensitive)
# CPU topology
tab.find_fuzzy("Topology", "toggle button").click_expander()
tab.find_fuzzy("Manually set", "check").click()
- tab.find("Sockets:", "spin button").typeText("8")
+ sockets = tab.find("Sockets:", "spin button")
+ sockets.typeText("8")
tab.find("Cores:", "spin button").typeText("2")
tab.find("Threads:", "spin button").typeText("2")
appl.click()
uiutils.check(lambda: not appl.sensitive)
+ # Confirm VCPUs were adjusted
vcpualloc = tab.find_fuzzy("vCPU allocation", "spin")
uiutils.check(lambda: vcpualloc.text == "32")
+ # Unset topology
+ tab.find_fuzzy("Manually set", "check").click()
+ uiutils.check(lambda: not sockets.sensitive)
+ appl.click()
+ # Currently generates an error
+ # uiutils.check(lambda: not appl.sensitive)
+
def testDetailsEditDomain2(self):
"""
@@ -207,17 +270,43 @@ class Details(uiutils.UITestCase):
# Kernel boot
tab.find_fuzzy("Direct kernel boot", "toggle button").click_expander()
tab.find_fuzzy("Enable direct kernel", "check box").click()
+
+ tab.find("Kernel args:", "text").text = "console=ttyS0"
+ appl.click()
+ self._click_alert_button("arguments without specifying", "OK")
+ uiutils.check(lambda: win.active)
+
+ initrd = tab.find("Initrd path:", "text")
+ tab.find("initrd-browse", "push button").click()
+ self._select_storagebrowser_volume("default-pool", "backingl1.img")
+ uiutils.check(lambda: win.active)
+ uiutils.check(lambda: "backing" in initrd.text)
+ appl.click()
+ self._click_alert_button("initrd without specifying", "OK")
+ uiutils.check(lambda: win.active)
+
tab.find("kernel-browse", "push button").click()
self._select_storagebrowser_volume("default-pool", "bochs-vol")
uiutils.check(lambda: win.active)
kernelpath = tab.find("Kernel path:", "text")
uiutils.check(lambda: "bochs" in kernelpath.text)
- tab.find("Initrd path:", "text").text = "/tmp/initrd"
- tab.find("DTB path:", "text").text = "/tmp/dtb"
- tab.find("Kernel args:", "text").text = "console=ttyS0"
+
+ dtb = tab.find("DTB path:", "text")
+ tab.find("dtb-browse", "push button").click()
+ self._select_storagebrowser_volume("default-pool", "iso-vol")
+ uiutils.check(lambda: win.active)
+ uiutils.check(lambda: "iso-vol" in dtb.text)
+
appl.click()
uiutils.check(lambda: not appl.sensitive)
+ # Now disable kernel, but verify that we keep the values in the UI
+ tab.find_fuzzy("Enable direct kernel", "check box").click()
+ appl.click()
+ uiutils.check(lambda: not appl.sensitive)
+ tab = self._select_hw(win, "OS information", "os-tab")
+ tab = self._select_hw(win, "Boot Options", "boot-tab")
+ uiutils.check(lambda: "backing" in initrd.text)
def testDetailsEditDiskNet(self):
"""
@@ -235,12 +324,14 @@ class Details(uiutils.UITestCase):
tab.find("Advanced options", "toggle button").click_expander()
tab.find("Cache mode:", "text").text = "unsafe"
tab.find("Discard mode:", "text").text = "unmap"
+ tab.find("Detect zeroes:", "text").text = "unmap"
appl.click()
uiutils.check(lambda: not appl.sensitive)
# Network values w/ macvtap manual
tab = self._select_hw(win, "NIC :54:32:10", "network-tab")
+ tab.find("IP address", "push button").click()
src = tab.find("net-source")
src.click()
self.pressKey("Home")
@@ -248,6 +339,7 @@ class Details(uiutils.UITestCase):
"menu item").bring_on_screen().click()
tab.find("Device name:", "text").text = "fakedev12"
tab.combo_select("Device model:", "rtl8139")
+ tab.find("Link state:", "check box").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
@@ -264,31 +356,54 @@ class Details(uiutils.UITestCase):
uiutils.check(lambda: not appl.sensitive)
- def testDetailsEditDevices(self):
+ def testDetailsEditDevices1(self):
"""
Test all other devices
"""
- win = self._open_details_window(vmname="test-many-devices")
+ win = self._open_details_window(vmname="test-many-devices",
+ shutdown=True)
appl = win.find("config-apply", "push button")
- self._stop_vm(win)
-
- # Graphics
+ # Graphics simple VNC -> SPICE
tab = self._select_hw(win, "Display VNC", "graphics-tab")
tab.combo_select("Type:", "Spice")
appl.click()
uiutils.check(lambda: not appl.sensitive)
- tab.combo_select("Type:", "VNC")
+ # Spice GL example
+ tab.combo_select("Listen type:", "None")
+ tab.find("OpenGL:", "check box").click()
+ tab.combo_check_default("graphics-rendernode", "0000")
appl.click()
uiutils.check(lambda: not appl.sensitive)
+ # Switch to VNC with options
+ tab.combo_select("Type:", "VNC")
+ tab.combo_select("Listen type:", "Address")
+ tab.find("graphics-port-auto", "check").click()
+ tab.find("graphics-port", "spin button").text = "6001"
+ tab.find("Password:", "check").click()
+ passwd = tab.find_fuzzy("graphics-password", "text")
+ newpass = "foobar"
+ passwd.typeText(newpass)
+ appl.click()
+ uiutils.check(lambda: not appl.sensitive)
# Sound device
tab = self._select_hw(win, "Sound sb16", "sound-tab")
tab.find("Model:", "text").text = "ac97"
appl.click()
uiutils.check(lambda: not appl.sensitive)
+ # Test non-disk removal
+ win.find("config-remove").click()
+ cell = win.find("Sound ac97", "table cell")
+ oldtext = cell.text
+ self._click_alert_button("Are you sure", "No")
+ uiutils.check(lambda: cell.state_selected)
+ cell.click(button=3)
+ self.app.root.find("Remove Hardware", "menu item").click()
+ self._click_alert_button("Are you sure", "Yes")
+ uiutils.check(lambda: cell.text != oldtext)
# Host device
@@ -315,6 +430,11 @@ class Details(uiutils.UITestCase):
uiutils.check(lambda: not appl.sensitive)
+ def testDetailsEditDevices2(self):
+ win = self._open_details_window(vmname="test-many-devices",
+ shutdown=True)
+ appl = win.find("config-apply", "push button")
+
# Controller SCSI
tab = self._select_hw(
win, "Controller VirtIO SCSI 9", "controller-tab")
@@ -351,15 +471,25 @@ class Details(uiutils.UITestCase):
appl.click()
uiutils.check(lambda: not appl.sensitive)
+ # TPM tweaks
+ tab = self._select_hw(win, "TPM", "tpm-tab")
+ tab.combo_select("tpm-model", "CRB")
+ appl.click()
+ uiutils.check(lambda: not appl.sensitive)
# vsock tweaks
tab = self._select_hw(win, "VirtIO VSOCK", "vsock-tab")
addr = tab.find("vsock-cid")
auto = tab.find("vsock-auto")
uiutils.check(lambda: addr.text == "5")
+ addr.text = "7"
+ appl.click()
+ uiutils.check(lambda: addr.text == "7")
+ uiutils.check(lambda: not appl.sensitive)
auto.click()
uiutils.check(lambda: not addr.visible)
appl.click()
+ uiutils.check(lambda: not appl.sensitive)
def testDetailsMiscEdits(self):
@@ -392,6 +522,15 @@ class Details(uiutils.UITestCase):
delete.find_fuzzy("Delete", "button").click()
uiutils.check(lambda: win.active)
+ # Attempt to apply changes when skipping away, but they fail
+ tab.find("Advanced options", "toggle button").click_expander()
+ cacheui = tab.find("Cache mode:", "text")
+ origcache = cacheui.text
+ cacheui.text = "badcachemode"
+ hwlist.find("CPUs", "table cell").click()
+ self._click_alert_button("There are unapplied changes", "Yes")
+ self._click_alert_button("badcachemode", "Close")
+
# Cancelling changes
tab = self._select_hw(win, "IDE Disk 1", "disk-tab")
share = tab.find("Shareable:", "check box")
@@ -449,6 +588,11 @@ class Details(uiutils.UITestCase):
self._click_alert_button("changes will be lost", "Yes")
uiutils.check(lambda: not tab.showing)
+ # Verify addhardware right click works
+ cell = win.find("Overview", "table cell").click(button=3)
+ self.app.root.find("Add Hardware", "menu item").click()
+ self.app.root.find("Add New Virtual Hardware", "frame")
+
def testDetailsXMLEdit(self):
"""
Test XML editing interaction
diff --git a/tests/uitests/test_mediachange.py b/tests/uitests/test_mediachange.py
index 6a3d118d..457d1526 100644
--- a/tests/uitests/test_mediachange.py
+++ b/tests/uitests/test_mediachange.py
@@ -53,6 +53,10 @@ class MediaChange(uiutils.UITestCase):
combo.click_combo_entry()
combo.find(path)
entry.click()
+ # Use the storage browser to select new floppy storage
+ tab.find("Browse", "push button").click()
+ self._select_storagebrowser_volume("default-pool", "iso-vol")
+ appl.click()
# Browse for image
hw.find("IDE CDROM 1", "table cell").click()
@@ -61,8 +65,11 @@ class MediaChange(uiutils.UITestCase):
entry.click()
tab.find("Browse", "push button").click()
self._select_storagebrowser_volume("default-pool", "backingl1.img")
- appl.click()
# Check 'already in use' dialog
+ appl.click()
+ self._click_alert_button("already in use by", "No")
+ uiutils.check(lambda: appl.sensitive)
+ appl.click()
self._click_alert_button("already in use by", "Yes")
uiutils.check(lambda: not appl.sensitive)
uiutils.check(lambda: "backing" in entry.text)
diff --git a/tests/utils.py b/tests/utils.py
index 5bc73f11..be343ffb 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -79,6 +79,7 @@ class _URIs(object):
_uri_qemu = _m("qemu:///system")
_kvm_x86_caps = _caps("kvm-x86_64.xml") + _domcaps("kvm-x86_64-domcaps.xml")
self.kvm = _uri_qemu + _kvm_x86_caps
+ self.kvm_cpu_insecure = _uri_qemu + _caps("kvm-x86_64.xml") + _domcaps("kvm-x86_64-insecure-domcaps.xml")
self.kvm_remote = _m("qemu+tls://fakeuri.example.com/system") + _kvm_x86_caps
self.kvm_session = _m("qemu:///session") + _kvm_x86_caps
diff --git a/ui/details.ui b/ui/details.ui
index db0fa5a1..56a40096 100644
--- a/ui/details.ui
+++ b/ui/details.ui
@@ -2942,8 +2942,9 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
- <property name="label" translatable="yes">MAC address:</property>
+ <property name="label" translatable="yes">_MAC address:</property>
<property name="use_underline">True</property>
+ <property name="mnemonic_widget">network-mac-entry</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -3022,6 +3023,11 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="changed" handler="on_network_mac_entry_changed" swapped="no"/>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="network-mac-entry-atkobject">
+ <property name="AtkObject::accessible-name">mac-entry</property>
+ </object>
+ </child>
</object>
<packing>
<property name="expand">False</property>
@@ -4613,6 +4619,11 @@
<property name="can_focus">True</property>
</object>
</child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="tpm-model-atkobject">
+ <property name="AtkObject::accessible-name">tpm-model</property>
+ </object>
+ </child>
</object>
<packing>
<property name="left_attach">1</property>
diff --git a/virtManager/details/details.py b/virtManager/details/details.py
index dfc733bf..926f93dd 100644
--- a/virtManager/details/details.py
+++ b/virtManager/details/details.py
@@ -190,10 +190,8 @@ def _label_for_device(dev):
}
if devtype == "interface":
- if dev.macaddr:
- return _("NIC %(mac)s") % {"mac": dev.macaddr[-9:]}
- else:
- return _("NIC")
+ mac = dev.macaddr[-9:] or ""
+ return _("NIC %(mac)s") % {"mac": mac}
if devtype == "input":
if dev.type == "tablet":
@@ -202,31 +200,26 @@ def _label_for_device(dev):
return _("Mouse")
elif dev.type == "keyboard":
return _("Keyboard")
- return _("Input")
+ return _("Input") # pragma: no cover
if devtype == "serial":
- if dev.target_port is not None:
- return _("Serial %(num)d") % {"num": int(dev.target_port) + 1}
- return _("Serial")
+ port = dev.target_port or 0
+ return _("Serial %(num)d") % {"num": port + 1}
if devtype == "parallel":
- if dev.target_port is not None:
- return _("Parallel %(num)d") % {"num": int(dev.target_port) + 1}
- return _("Parallel")
+ port = dev.target_port or 0
+ return _("Parallel %(num)d") % {"num": port + 1}
if devtype == "console":
- if dev.target_port is not None:
- return _("Console %(num)d") % {"num": int(dev.target_port) + 1}
- return _("Console")
+ port = dev.target_port or 0
+ return _("Console %(num)d") % {"num": port + 1}
if devtype == "channel":
name = vmmAddHardware.char_pretty_channel_name(dev.target_name)
if name:
return _("Channel %(name)s") % {"name": name}
pretty_type = vmmAddHardware.char_pretty_type(dev.type)
- if pretty_type:
- return _("Channel %(type)s") % {"type": pretty_type}
- return _("Channel")
+ return _("Channel %(type)s") % {"type": pretty_type}
if devtype == "graphics":
pretty = vmmGraphicsDetails.graphics_pretty_type_simple(dev.type)
@@ -290,9 +283,7 @@ def _icon_for_device(dev):
return "input-mouse"
if devtype == "redirdev":
- if dev.bus == "usb":
- return "device_usb"
- return "device_pci"
+ return "device_usb"
if devtype == "hostdev":
if dev.type == "usb":
@@ -331,7 +322,7 @@ def _get_performance_icon_name():
# fallback to system-run if it is missing
icon = "utilities-system-monitor"
if not Gtk.IconTheme.get_default().has_icon(icon):
- icon = "system-run"
+ icon = "system-run" # pragma: no cover
return icon
@@ -916,7 +907,7 @@ class vmmDetails(vmmGObjectUI):
# force select the list entry before showing popup_menu
path_tuple = widget.get_path_at_pos(int(event.x), int(event.y))
if path_tuple is None:
- return False
+ return False # pragma: no cover
path = path_tuple[0]
_iter = widget.get_model().get_iter(path)
widget.get_selection().select_iter(_iter)
@@ -939,6 +930,17 @@ class vmmDetails(vmmGObjectUI):
return uiutil.get_list_selected_row(self.widget("hw-list"))
def has_unapplied_changes(self, row):
+ """
+ This is a bit confusing.
+
+ * If there are now changes pending, we return False
+ * If there are changes pending, we prompt the user whether
+ they want to apply them. If they say no, return False
+ * If the applying the changes succeeds, return False
+ * Return True if applying the changes failed. In this
+ case the caller should attempt to abort the action they
+ are trying to perform, if possible
+ """
if not row:
return False
@@ -1086,23 +1088,29 @@ class vmmDetails(vmmGObjectUI):
except Exception as e: # pragma: no cover
self.err.show_err((_("Error launching hardware dialog: %s") %
str(e)))
- def remove_non_disk(self, devobj):
+
+ def _remove_non_disk(self, devobj):
if not self.err.chkbox_helper(self.config.get_confirm_removedev,
self.config.set_confirm_removedev,
text1=(_("Are you sure you want to remove this device?"))):
return
- self.remove_device(devobj)
- def remove_disk(self, disk):
+ success = vmmDeleteStorage.remove_devobj_internal(
+ self.vm, self.err, devobj)
+ if not success:
+ return
+ self.disable_apply()
+
+ def _remove_disk(self, disk):
dialog = vmmDeleteStorage(disk)
dialog.show(self.topwin, self.vm)
def remove_xml_dev(self, src_ignore):
devobj = self.get_hw_row()[HW_LIST_COL_DEVICE]
if devobj.DEVICE_TYPE == "disk":
- self.remove_disk(devobj)
+ self._remove_disk(devobj)
else:
- self.remove_non_disk(devobj)
+ self._remove_non_disk(devobj)
############################
@@ -1288,7 +1296,7 @@ class vmmDetails(vmmGObjectUI):
ignore = src
row = self.get_boot_selection()
if not row:
- return
+ return # pragma: no cover
row_key = row[BOOT_KEY]
boot_order = self.get_config_boot_order()
@@ -1780,11 +1788,6 @@ class vmmDetails(vmmGObjectUI):
kwargs, self.vm, self.err,
devobj=devobj)
- # Device removal
- def remove_device(self, devobj):
- success = vmmDeleteStorage.remove_devobj_internal(self.vm, self.err, devobj)
- if success:
- self.disable_apply()
#######################
# vmwindow Public API #
@@ -2195,14 +2198,12 @@ class vmmDetails(vmmGObjectUI):
self.vsockdetails.set_dev(dev)
def refresh_char_page(self, chardev):
- char_type = chardev.DEVICE_TYPE.capitalize()
+ char_type = chardev.DEVICE_TYPE
target_port = chardev.target_port
dev_type = chardev.type or "pty"
primary = self.vm.serial_is_console_dup(chardev)
- show_target_type = not (chardev.DEVICE_TYPE in
- ["serial", "parallel"])
+ show_target_type = not (char_type in ["serial", "parallel"])
- typelabel = ""
if char_type == "serial":
typelabel = _("Serial Device")
elif char_type == "parallel":
diff --git a/virtManager/lib/inspection.py b/virtManager/lib/inspection.py
index 11f3298a..a93aa6ae 100644
--- a/virtManager/lib/inspection.py
+++ b/virtManager/lib/inspection.py
@@ -41,14 +41,15 @@ def _make_fake_data():
for prefix in ["test_app1_", "test_app2_"]:
import time
app = vmmInspectionApplication()
- app.description = prefix + "description"
- app.name = prefix + "name"
- app.display_name = prefix + "display_name"
+ if "app1" in prefix:
+ app.display_name = prefix + "display_name"
+ app.summary = prefix + "summary-" + str(time.time())
+ else:
+ app.name = prefix + "name"
+ app.description = prefix + "description-" + str(time.time()) + "\n"
app.epoch = 1
app.version = "2"
app.release = "3"
- app.summary = prefix + "summary-" + str(time.time())
- app.description = prefix + "description-" + str(time.time())
data.applications.append(app)
return data
diff --git a/virtManager/object/domain.py b/virtManager/object/domain.py
index e8750220..f212408e 100644
--- a/virtManager/object/domain.py
+++ b/virtManager/object/domain.py
@@ -108,9 +108,9 @@ class vmmDomainSnapshot(vmmLibvirtObject):
return self._backend.getName()
def _conn_tick_poll_param(self):
- return None
+ return None # pragma: no cover
def class_name(self):
- return "snapshot"
+ return "snapshot" # pragma: no cover
def _XMLDesc(self, flags):
return self._backend.getXMLDesc(flags=flags)
@@ -138,17 +138,14 @@ class vmmDomainSnapshot(vmmLibvirtObject):
"crashed": libvirt.VIR_DOMAIN_CRASHED,
"pmsuspended": getattr(libvirt, "VIR_DOMAIN_PMSUSPENDED", 7)
}
-
- if state == "disk-snapshot" or state not in statemap:
- state = "shutoff"
- return statemap.get(state, libvirt.VIR_DOMAIN_NOSTATE)
+ return statemap.get(state, libvirt.VIR_DOMAIN_SHUTOFF)
def run_status(self):
status = self._state_str_to_int()
return LibvirtEnumMap.pretty_run_status(status, False)
def run_status_icon_name(self):
status = self._state_str_to_int()
- if status not in LibvirtEnumMap.VM_STATUS_ICONS:
+ if status not in LibvirtEnumMap.VM_STATUS_ICONS: # pragma: no cover
log.debug("Unknown status %d, using NOSTATE", status)
status = libvirt.VIR_DOMAIN_NOSTATE
return LibvirtEnumMap.VM_STATUS_ICONS[status]
@@ -314,7 +311,8 @@ class vmmDomain(vmmLibvirtObject):
# We don't want virt-manager to track Domain-0 since it
# doesn't work with our UI. Raising an error will ensures it
# is blacklisted.
- raise RuntimeError("Can't track Domain-0 as a vmmDomain")
+ raise RuntimeError( # pragma: no cover
+ "Can't track Domain-0 as a vmmDomain")
###########################
@@ -353,12 +351,6 @@ class vmmDomain(vmmLibvirtObject):
return True
return False
- def get_id_pretty(self):
- i = self.get_id()
- if i < 0:
- return "-"
- return str(i)
-
def has_nvram(self):
return bool(self.get_xmlobj().os.loader_ro is True and
self.get_xmlobj().os.loader_type == "pflash" and
@@ -427,12 +419,19 @@ class vmmDomain(vmmLibvirtObject):
# If we are removing multiple dev from an active VM, a double
# attempt may result in a lookup failure. If device is present
# in the active XML, assume all is good.
- if self.get_xmlobj().find_device(origdev):
+ if self.get_xmlobj().find_device(origdev): # pragma: no cover
log.debug("Device in active config but not inactive config.")
return
- raise RuntimeError(_("Could not find specified device in the "
- "inactive VM configuration: %s") % repr(origdev))
+ raise RuntimeError( # pragma: no cover
+ _("Could not find specified device in the "
+ "inactive VM configuration: %s") % repr(origdev))
+
+ def _process_device_define(self, editdev, xmlobj, do_hotplug):
+ if do_hotplug:
+ self.hotplug(device=editdev)
+ else:
+ self._redefine_xmlobj(xmlobj)
def _copy_nvram_file(self, new_name):
"""
@@ -464,6 +463,8 @@ class vmmDomain(vmmLibvirtObject):
##############################
def rename_domain(self, new_name):
+ Guest.validate_name(self.conn.get_backend(), str(new_name))
+
new_nvram = None
old_nvram = None
if self.has_nvram():
@@ -510,7 +511,7 @@ class vmmDomain(vmmLibvirtObject):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, False)
if not editdev:
- return
+ return # pragma: no cover
if con:
rmcon = xmlobj.find_device(con)
@@ -531,12 +532,17 @@ class vmmDomain(vmmLibvirtObject):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
xmlobj.devices.replace_child(editdev, newdev)
self._redefine_xmlobj(xmlobj)
return editdev, newdev
+
+ ##########################
+ # non-device XML editing #
+ ##########################
+
def define_cpu(self, vcpus=_SENTINEL,
model=_SENTINEL, secure=_SENTINEL, sockets=_SENTINEL,
cores=_SENTINEL, threads=_SENTINEL):
@@ -643,7 +649,7 @@ class vmmDomain(vmmLibvirtObject):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if path != _SENTINEL:
editdev.path = path
@@ -667,10 +673,7 @@ class vmmDomain(vmmLibvirtObject):
if bus != _SENTINEL:
editdev.change_bus(self.xmlobj, bus)
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_network(self, devobj, do_hotplug,
ntype=_SENTINEL, source=_SENTINEL,
@@ -679,7 +682,7 @@ class vmmDomain(vmmLibvirtObject):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if ntype != _SENTINEL:
editdev.source = None
@@ -699,10 +702,7 @@ class vmmDomain(vmmLibvirtObject):
if linkstate != _SENTINEL:
editdev.link_state = "up" if linkstate else "down"
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_graphics(self, devobj, do_hotplug,
listen=_SENTINEL, addr=_SENTINEL, port=_SENTINEL,
@@ -711,7 +711,7 @@ class vmmDomain(vmmLibvirtObject):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if addr != _SENTINEL or listen != _SENTINEL:
if listen == "none":
@@ -729,32 +729,26 @@ class vmmDomain(vmmLibvirtObject):
if rendernode != _SENTINEL:
editdev.rendernode = rendernode
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_sound(self, devobj, do_hotplug, model=_SENTINEL):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if model != _SENTINEL:
if editdev.model != model:
editdev.address.clear()
editdev.model = model
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_video(self, devobj, do_hotplug, model=_SENTINEL, accel3d=_SENTINEL):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if model != _SENTINEL and model != editdev.model:
editdev.model = model
@@ -772,17 +766,14 @@ class vmmDomain(vmmLibvirtObject):
if accel3d != _SENTINEL:
editdev.accel3d = accel3d
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_watchdog(self, devobj, do_hotplug,
model=_SENTINEL, action=_SENTINEL):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if model != _SENTINEL:
if editdev.model != model:
@@ -792,32 +783,26 @@ class vmmDomain(vmmLibvirtObject):
if action != _SENTINEL:
editdev.action = action
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_smartcard(self, devobj, do_hotplug, model=_SENTINEL):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if model != _SENTINEL:
editdev.mode = model
editdev.type = None
editdev.type = editdev.default_type()
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_controller(self, devobj, do_hotplug, model=_SENTINEL):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
def _change_model():
if editdev.type == "usb":
@@ -849,16 +834,13 @@ class vmmDomain(vmmLibvirtObject):
if model != _SENTINEL:
_change_model()
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_filesystem(self, devobj, do_hotplug, newdev=_SENTINEL):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if newdev != _SENTINEL:
# pylint: disable=maybe-no-member
@@ -872,56 +854,44 @@ class vmmDomain(vmmLibvirtObject):
editdev.source = newdev.source
editdev.target = newdev.target
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_hostdev(self, devobj, do_hotplug, rom_bar=_SENTINEL):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if rom_bar != _SENTINEL:
editdev.rom_bar = rom_bar
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_tpm(self, devobj, do_hotplug, model=_SENTINEL):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if model != _SENTINEL:
editdev.model = model
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
def define_vsock(self, devobj, do_hotplug,
auto_cid=_SENTINEL, cid=_SENTINEL):
xmlobj = self._make_xmlobj_to_define()
editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
if not editdev:
- return
+ return # pragma: no cover
if auto_cid != _SENTINEL:
editdev.auto_cid = auto_cid
if cid != _SENTINEL:
editdev.cid = cid
- if do_hotplug:
- self.hotplug(device=editdev)
- else:
- self._redefine_xmlobj(xmlobj)
+ self._process_device_define(editdev, xmlobj, do_hotplug)
####################
@@ -1375,12 +1345,12 @@ class vmmDomain(vmmLibvirtObject):
def has_managed_save(self):
if not self.managedsave_supported:
- return False
+ return False # pragma: no cover
if self._has_managed_save is None:
try:
self._has_managed_save = self._backend.hasManagedSaveImage(0)
- except Exception as e:
+ except Exception as e: # pragma: no cover
if self.conn.support.is_libvirt_error_no_domain(e):
return False
raise
@@ -1389,7 +1359,7 @@ class vmmDomain(vmmLibvirtObject):
def remove_saved_image(self):
if not self.has_managed_save():
- return
+ return # pragma: no cover
self._backend.managedSaveRemove(0)
self._has_managed_save = None
@@ -1494,9 +1464,9 @@ class vmmDomain(vmmLibvirtObject):
def _normalize_status(self, status):
if status == libvirt.VIR_DOMAIN_NOSTATE:
- return libvirt.VIR_DOMAIN_RUNNING
+ return libvirt.VIR_DOMAIN_RUNNING # pragma: no cover
elif status == libvirt.VIR_DOMAIN_BLOCKED:
- return libvirt.VIR_DOMAIN_RUNNING
+ return libvirt.VIR_DOMAIN_RUNNING # pragma: no cover
return status
def is_active(self):
@@ -1534,7 +1504,7 @@ class vmmDomain(vmmLibvirtObject):
def run_status_icon_name(self):
status = self.status()
- if status not in LibvirtEnumMap.VM_STATUS_ICONS:
+ if status not in LibvirtEnumMap.VM_STATUS_ICONS: # pragma: no cover
log.debug("Unknown status %s, using NOSTATE", status)
status = libvirt.VIR_DOMAIN_NOSTATE
return LibvirtEnumMap.VM_STATUS_ICONS[status]
@@ -1642,7 +1612,7 @@ class vmmDomainVirtinst(vmmDomain):
def get_uuid(self):
return self._backend.uuid
def get_id(self):
- return -1
+ return -1 # pragma: no cover
def has_managed_save(self):
return False
@@ -1750,4 +1720,5 @@ class vmmDomainVirtinst(vmmDomain):
self._redefine_xml_internal(self._orig_xml or "", xmlobj.get_xml())
def rename_domain(self, new_name):
+ Guest.validate_name(self._backend.conn, str(new_name))
self.define_name(new_name)
diff --git a/virtManager/vmwindow.py b/virtManager/vmwindow.py
index 6c6a612b..3a2c8b7e 100644
--- a/virtManager/vmwindow.py
+++ b/virtManager/vmwindow.py
@@ -220,7 +220,7 @@ class vmmVMWindow(vmmGObjectUI):
def _close(self):
fs = self.widget("details-menu-view-fullscreen")
if fs.get_active():
- fs.set_active(False)
+ fs.set_active(False) # pragma: no cover
if not self.is_visible():
return
@@ -268,7 +268,7 @@ class vmmVMWindow(vmmGObjectUI):
def window_resized(self, ignore, ignore2):
if not self.is_visible():
- return
+ return # pragma: no cover
self._window_size = self.topwin.get_size()
def control_fullscreen(self, src):
@@ -282,12 +282,8 @@ class vmmVMWindow(vmmGObjectUI):
active = src.get_active()
self.config.set_details_show_toolbar(active)
-
- if (active and not
- self.widget("details-menu-view-fullscreen").get_active()):
- self.widget("toolbar-box").show()
- else:
- self.widget("toolbar-box").hide()
+ fsactive = self.widget("details-menu-view-fullscreen").get_active()
+ self.widget("toolbar-box").set_visible(active and not fsactive)
def details_console_changed(self, src):
if self.ignoreDetails:
@@ -304,7 +300,7 @@ class vmmVMWindow(vmmGObjectUI):
pages = self.widget("details-pages")
if pages.get_current_page() == DETAILS_PAGE_DETAILS:
if self._details.vmwindow_has_unapplied_changes():
- self.sync_details_console_view(True)
+ self.sync_details_console_view(pages.get_current_page())
return
self._details.disable_apply()
@@ -534,13 +530,13 @@ class vmmVMWindow(vmmGObjectUI):
dialog_type=Gtk.FileChooserAction.SAVE,
browse_reason=self.config.CONFIG_DIR_SCREENSHOT,
default_name=default)
- if not path:
+ if not path: # pragma: no cover
log.debug("No screenshot path given, skipping save.")
return
filename = path
if not filename.endswith(".png"):
- filename += ".png"
+ filename += ".png" # pragma: no cover
open(filename, "wb").write(ret)