diff --git a/tests/data/testdriver/testdriver.xml b/tests/data/testdriver/testdriver.xml index fd7444ce3..e6618869c 100644 --- a/tests/data/testdriver/testdriver.xml +++ b/tests/data/testdriver/testdriver.xml @@ -330,6 +330,9 @@ Foo bar baz & yeah boii < > yeahfoo + + + @@ -421,6 +424,9 @@ Foo bar baz & yeah boii < > yeahfoo + @@ -727,6 +733,9 @@ test-many-devices, like an alternate RNG, EOL OS ID, title field + + + diff --git a/tests/uitests/test_addhardware.py b/tests/uitests/test_addhardware.py index f105aedf5..822de50e6 100644 --- a/tests/uitests/test_addhardware.py +++ b/tests/uitests/test_addhardware.py @@ -149,6 +149,8 @@ class AddHardware(uiutils.UITestCase): tab.combo_select("Bus type:", "VirtIO") tab.find("Advanced options", "toggle button").click_expander() tab.combo_select("Cache mode:", "none") + tab.combo_select("Discard mode:", "ignore") + tab.combo_select("Detect zeroes:", "unmap") # Size too big tab.find("GiB", "spin button").text = "2000" self._finish(addhw, check=None) @@ -415,7 +417,10 @@ class AddHardware(uiutils.UITestCase): tab = self._select_hw(addhw, "USB Host Device", "host-tab") tab.find_fuzzy("HP Dup USB 1", "table cell").click() self._finish(addhw, check=None) + self._click_alert_button("device is already in use by", "No") + self._finish(addhw, check=None) self._click_alert_button("device is already in use by", "Yes") + uiutils.check(lambda: details.active) # Add USB device dup2 self._open_addhw_window(details) @@ -468,7 +473,9 @@ class AddHardware(uiutils.UITestCase): # Add spicevmc channel self._open_addhw_window(details) tab = self._select_hw(addhw, "Channel", "char-tab") - combo = tab.combo_select("Device Type:", ".*spicevmc.*") + tab.combo_check_default("char-target-name", ".*redhat.spice.0.*") + tab.combo_select("char-target-name", ".*webdav.*") + tab.combo_select("char-target-name", ".*org.qemu.guest_agent*") self._finish(addhw, check=details) @@ -558,6 +565,11 @@ class AddHardware(uiutils.UITestCase): tab.combo_select("Mode:", "Passthrough") self._finish(addhw, check=details) + # Add TPM emulated + self._open_addhw_window(details) + tab = self._select_hw(addhw, "TPM", "tpm-tab") + self._finish(addhw, check=details) + def testAddHWMisc2(self): """ Add some more simple devices" @@ -565,6 +577,18 @@ class AddHardware(uiutils.UITestCase): details = self._open_details_window() addhw = self._open_addhw_window(details) + # Add usb controller, to make usbredir work + addhw = self._open_addhw_window(details) + tab = self._select_hw(addhw, "Controller", "controller-tab") + tab.combo_select("Type:", "USB") + self._finish(addhw, check=details) + + # Add usb redir + self._open_addhw_window(details) + tab = self._select_hw(addhw, "USB Redirection", "usbredir-tab") + tab.combo_select("Type:", "Spice") + self._finish(addhw, check=details) + # Add basic filesystem self._open_addhw_window(details) tab = self._select_hw(addhw, "Filesystem", "filesystem-tab") @@ -572,7 +596,7 @@ class AddHardware(uiutils.UITestCase): tab.find("Target path:", "text").text = "/foo/target" self._finish(addhw, check=details) - # Add TPM + # Add TPM passthrough self._open_addhw_window(details) tab = self._select_hw(addhw, "TPM", "tpm-tab") tab.combo_select("Model:", "TIS") @@ -599,6 +623,28 @@ class AddHardware(uiutils.UITestCase): tab.find("vsock-cid").text = "7" self._finish(addhw, check=details) + def testAddHWUSBNone(self): + """ + Test some special case handling when VM has controller usb model='none' + """ + details = self._open_details_window( + "test alternate devs title", shutdown=True) + addhw = self._open_addhw_window(details) + + # Add usb controller + addhw = self._open_addhw_window(details) + tab = self._select_hw(addhw, "Controller", "controller-tab") + tab.combo_select("Type:", "USB") + self._finish(addhw, check=details) + + # Trigger a libvirt error to test error handling + addhw = self._open_addhw_window(details) + tab = self._select_hw(addhw, "Controller", "controller-tab") + combo = tab.find("Type:", "combo box") + combo.find(None, "text").text = "foobar" + self._finish(addhw, check=None) + self._click_alert_button("Unable to add device", "Close") + uiutils.check(lambda: addhw.active) def testAddHWCornerCases(self): """ diff --git a/tests/uitests/test_createvm.py b/tests/uitests/test_createvm.py index c3a13fa0c..0f623d284 100644 --- a/tests/uitests/test_createvm.py +++ b/tests/uitests/test_createvm.py @@ -299,6 +299,52 @@ class NewVM(uiutils.UITestCase): self.app.root.find_fuzzy("fedora10 on", "frame") uiutils.check(lambda: not newvm.showing) + def testNewKVMQ35(self): + """ + New VM that should default to Q35 + """ + self.app.uri = tests.utils.URIs.kvm + newvm = self._open_create_wizard() + + newvm.find_fuzzy("Import", "radio").click() + self.forward(newvm) + newvm.find_fuzzy(None, + "text", "existing storage").text = "/dev/default-pool/testvol1.img" + newvm.find("oslist-entry").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 PPC64 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") + + # Tweak some Overview settings + 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): """ @@ -311,18 +357,47 @@ class NewVM(uiutils.UITestCase): newvm.combo_select("Architecture", ".*ppc64.*") newvm.combo_check_default("Machine Type", ".*pseries.*") - newvm.find_fuzzy("Import", "radio").click() - newvm.find_fuzzy(None, - "text", "existing storage").text = "/dev/default-pool/testvol1.img" + 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, check=False) self.forward(newvm) - newvm.find_fuzzy("Finish", "button").click() + self.forward(newvm) + # Disable storage, we add some via customize + newvm.find_fuzzy("Enable storage", "check box").click() + self.forward(newvm) + # Select customize wizard, we will use this VM to + # hit some PPC64 code paths elsewhere + newvm.find_fuzzy("Customize", "check").click() + newvm.find_fuzzy("Finish", "button").click() + details = self.app.root.find_fuzzy("vm-ppc64 on", "frame") + + # Add a TPM SPAPR device + details.find("add-hardware", "push button").click() + addhw = self.app.root.find("Add New Virtual Hardware", "frame") + addhw.find("TPM", "table cell").click() + tab = addhw.find("tpm-tab", None) + uiutils.check(lambda: tab.showing) + addhw.find("Finish", "push button").click() + uiutils.check(lambda: not addhw.active) + uiutils.check(lambda: details.active) + + # Add a SCSI disk which also adds virtio-scsi controller + details.find("add-hardware", "push button").click() + addhw = self.app.root.find("Add New Virtual Hardware", "frame") + addhw.find("Storage", "table cell").click() + tab = addhw.find("storage-tab", None) + uiutils.check(lambda: tab.showing) + tab.combo_select("Bus type:", "SCSI") + 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("vm-ppc64 on", "frame") - uiutils.check(lambda: not newvm.showing) def testNewVMAArch64UEFI(self): """ @@ -427,10 +502,29 @@ class NewVM(uiutils.UITestCase): self.back(newvm) self.forward(newvm) self.forward(newvm) - newvm.find_fuzzy("Finish", "button").click() + # Select customize wizard, we will use this VM to hit specific + # code paths + newvm.find_fuzzy("Customize", "check").click() + newvm.find_fuzzy("Finish", "button").click() + vmname = "container1" + details = self.app.root.find_fuzzy("%s on" % vmname, "frame") + + # Check that addhw container options are disabled + details.find("add-hardware", "push button").click() + addhw = self.app.root.find("Add New Virtual Hardware", "frame") + addhw.find("PCI Host Device", "table cell").click() + # Ensure the error label is showing + label = addhw.find("Not supported for containers") + uiutils.check(lambda: label.onscreen) + addhw.find("Cancel", "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: not newvm.showing) - self.app.root.find_fuzzy("container1 on", "frame") + self.app.root.find_fuzzy("%s on" % vmname, "frame") def testNewVMContainerTree(self): @@ -523,9 +617,9 @@ class NewVM(uiutils.UITestCase): newvm.combo_select("Xen Type", ".*paravirt.*") newvm.find_fuzzy("Import", "radio").click() + self.forward(newvm) newvm.find_fuzzy(None, "text", "existing storage").text = "/dev/default-pool/testvol1.img" - self.forward(newvm) newvm.find("oslist-entry").text = "generic" newvm.find("oslist-popover").find_fuzzy("generic").click() self.forward(newvm) @@ -757,9 +851,29 @@ class NewVM(uiutils.UITestCase): uiutils.check(lambda: warnlabel.onscreen) newvm.find("Device name:", "text").text = "foobr0" + # Select customize wizard, we will use this VM to hit specific + # code paths + newvm.find_fuzzy("Customize", "check").click() newvm.find_fuzzy("Finish", "button").click() - self.app.root.find_fuzzy("vm1 on", "frame") - uiutils.check(lambda: not newvm.showing) + vmname = "vm1" + details = self.app.root.find_fuzzy("%s on" % vmname, "frame") + + # Check that addhw hostdev drop down is empty + details.find("add-hardware", "push button").click() + addhw = self.app.root.find("Add New Virtual Hardware", "frame") + addhw.find("USB Host Device", "table cell").click() + tab = addhw.find("host-tab", None) + uiutils.check(lambda: tab.showing) + cell = tab.find("No Devices", "table cell") + uiutils.check(lambda: cell.selected) + addhw.find("Cancel", "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 testNewVMInactiveNetwork(self): """ diff --git a/tests/uitests/test_manager.py b/tests/uitests/test_manager.py index d47ff0964..ea1865174 100644 --- a/tests/uitests/test_manager.py +++ b/tests/uitests/test_manager.py @@ -141,7 +141,10 @@ class Manager(uiutils.UITestCase): _drag(details) # Close the connection + self.sleep(1) + manager.click() c = manager.find_fuzzy("testdriver.xml", "table cell") + c.click() c.click(button=3) self.app.root.find("conn-disconnect", "menu item").click() diff --git a/ui/addhardware.ui b/ui/addhardware.ui index 2b32e8da0..6a2bcb7ea 100644 --- a/ui/addhardware.ui +++ b/ui/addhardware.ui @@ -1,5 +1,5 @@ - + @@ -29,9 +29,6 @@ Add New Virtual Hardware dialog - - - True @@ -907,6 +904,11 @@ 20 + + + char-target-name + + 1 @@ -1628,5 +1630,8 @@ + + + diff --git a/virtManager/addhardware.py b/virtManager/addhardware.py index 30c6669b9..aa82aa15a 100644 --- a/virtManager/addhardware.py +++ b/virtManager/addhardware.py @@ -217,7 +217,7 @@ class vmmAddHardware(vmmGObjectUI): is_local = not self.conn.is_remote() have_storage = (is_local or self.conn.support.conn_storage()) storage_tooltip = None - if not have_storage: + if not have_storage: # pragma: no cover storage_tooltip = _("Connection does not support storage" " management.") @@ -383,13 +383,8 @@ class vmmAddHardware(vmmGObjectUI): if did_hotplug and not hotplug_err: return True - if len(define_args) > 1: - msg = _("Some changes may require a guest shutdown " - "to take effect.") - else: - msg = _("These changes will take effect after " - "the next guest shutdown.") - + msg = _("These changes will take effect after " + "the next guest shutdown.") dtype = (hotplug_err and Gtk.MessageType.WARNING or Gtk.MessageType.INFO) hotplug_msg = "" @@ -494,8 +489,6 @@ class vmmAddHardware(vmmGObjectUI): if guest.type in ["qemu", "kvm", "test"]: ret.append("sd") ret.append("virtio") - if "scsi" not in ret: - ret.append("scsi") if guest.conn.is_xen() or guest.conn.is_test(): ret.append("xen") @@ -567,22 +560,6 @@ class vmmAddHardware(vmmGObjectUI): } return labels.get(val, val) - @staticmethod - def rng_pretty_backend_type(val): - labels = { - "udp": "UDP", - "tcp": "TCP", - } - return labels.get(val, val) - - @staticmethod - def rng_pretty_mode(val): - labels = { - "bind": _("Bind"), - "connect": _("Connect"), - } - return labels.get(val, val) - @staticmethod def sound_recommended_models(_guest): return ["ich6", "ich9", "ac97"] @@ -683,7 +660,7 @@ class vmmAddHardware(vmmGObjectUI): def safeint(val, fmt="%.3d"): try: int(val) - except Exception: + except Exception: # pragma: no cover return str(val) return fmt % int(val) @@ -1104,7 +1081,7 @@ class vmmAddHardware(vmmGObjectUI): return _("PCI Device") return _("USB Device") - raise RuntimeError("Unknown page %s" % page) + raise RuntimeError("Unknown page %s" % page) # pragma: no cover def _set_page_title(self, page): title = self._dev_to_title(page) @@ -1156,7 +1133,7 @@ class vmmAddHardware(vmmGObjectUI): def _change_tpm_device_type(self, src): devtype = uiutil.get_list_selection(src) if devtype is None: - return + return # pragma: no cover dev = DeviceTpm(self.conn.get_backend()) dev.type = devtype @@ -1284,7 +1261,7 @@ class vmmAddHardware(vmmGObjectUI): try: pool = self.conn.get_pool(poolname) self.idle_add(pool.refresh) - except Exception: + except Exception: # pragma: no cover log.debug("Error looking up pool=%s for refresh after " "storage creation.", poolname, exc_info=True) @@ -1336,13 +1313,9 @@ class vmmAddHardware(vmmGObjectUI): return False # Alter persistent config - try: - if controller is not None: - self.vm.add_device(controller) - self.vm.add_device(dev) - except Exception as e: - self.err.show_err(_("Error adding device: %s") % str(e)) - return True + if controller is not None: + self.vm.add_device(controller) + self.vm.add_device(dev) return False @@ -1395,7 +1368,7 @@ class vmmAddHardware(vmmGObjectUI): names = [] nodedev = getattr(dev, "vmm_nodedev", None) if not nodedev: - return + return # pragma: no cover for vm in self.conn.list_vms(): for hostdev in vm.xmlobj.devices.hostdev: @@ -1418,7 +1391,8 @@ class vmmAddHardware(vmmGObjectUI): self._netlist.validate_device(dev) if dev.DEVICE_TYPE == "hostdev": - self._validate_hostdev_collision(dev) + if self._validate_hostdev_collision(dev) is False: + return False dev.validate() @@ -1566,11 +1540,9 @@ class vmmAddHardware(vmmGObjectUI): if not listen or listen == "none": dev.listen = "none" - elif listen == "address": + else: dev.listen = addr dev.port = port - else: - raise ValueError(_("invalid listen type")) return dev diff --git a/virtManager/details/details.py b/virtManager/details/details.py index f928a0d4f..c1cf51ee7 100644 --- a/virtManager/details/details.py +++ b/virtManager/details/details.py @@ -170,29 +170,21 @@ def _label_for_device(dev): if dev.device == "floppy": return _("Floppy %(index)d") % {"index": dev.disk_bus_index} + busstr = "" if dev.bus: busstr = vmmAddHardware.disk_pretty_bus(dev.bus) - if dev.device == "cdrom": - return _("%(bus)s CDROM %(index)d") % { - "bus": busstr, - "index": dev.disk_bus_index, - } - elif dev.device == "disk": - return _("%(bus)s Disk %(index)d") % { - "bus": busstr, - "index": dev.disk_bus_index, - } - return _("%(bus)s %(device)s %(index)d") % { + if dev.device == "cdrom": + return _("%(bus)s CDROM %(index)d") % { "bus": busstr, - "device": dev.device.capitalize(), "index": dev.disk_bus_index, } - - if dev.device == "cdrom": - return _("CDROM %(index)d") % {"index": dev.disk_bus_index} elif dev.device == "disk": - return _("Disk %(index)d") % {"index": dev.disk_bus_index} - return _("%(device)s %(index)d") % { + return _("%(bus)s Disk %(index)d") % { + "bus": busstr, + "index": dev.disk_bus_index, + } + return _("%(bus)s %(device)s %(index)d") % { + "bus": busstr, "device": dev.device.capitalize(), "index": dev.disk_bus_index, } @@ -1063,9 +1055,9 @@ class vmmDetails(vmmGObjectUI): self.refresh_panic_page(dev) elif pagetype == HW_LIST_TYPE_VSOCK: self.refresh_vsock_page(dev) - else: + else: # pragma: no cover pagetype = -1 - except Exception as e: + except Exception as e: # pragma: no cover self.err.show_err(_("Error refreshing hardware page: %s") % str(e)) # Don't return, we want the rest of the bits to run regardless @@ -1106,7 +1098,7 @@ class vmmDetails(vmmGObjectUI): self.addhw = vmmAddHardware(self.vm) self.addhw.show(self.topwin) - except Exception as e: + except Exception as e: # pragma: no cover self.err.show_err((_("Error launching hardware dialog: %s") % str(e))) def remove_non_disk(self, devobj): @@ -1175,11 +1167,9 @@ class vmmDetails(vmmGObjectUI): # Details/Hardware listeners # ############################## - def _browse_file(self, callback, is_media=False, reason=None): + def _browse_file(self, callback, reason=None): if not reason: reason = self.config.CONFIG_DIR_IMAGE - if is_media: - reason = self.config.CONFIG_DIR_ISO_MEDIA if self.storage_browser is None: self.storage_browser = vmmStorageBrowser(self.conn) @@ -1573,7 +1563,7 @@ class vmmDetails(vmmGObjectUI): auto = self.widget("boot-autostart") try: self.vm.set_autostart(auto.get_active()) - except Exception as e: + except Exception as e: # pragma: no cover self.err.show_err( (_("Error changing autostart value: %s") % str(e))) return False @@ -2334,7 +2324,7 @@ class vmmDetails(vmmGObjectUI): heads = vid.heads try: ramlabel = ram and "%d MiB" % (int(ram) // 1024) or "-" - except Exception: + except Exception: # pragma: no cover ramlabel = "-" self.widget("video-ram").set_text(ramlabel) @@ -2418,7 +2408,7 @@ class vmmDetails(vmmGObjectUI): try: # Older libvirt versions return None if not supported autoval = self.vm.get_autostart() - except libvirt.libvirtError: + except libvirt.libvirtError: # pragma: no cover autoval = None # Autostart