uitests: Big code reorganization

Break utils.py apart into a whole uitests/lib/ directory with

* lib/_dogtailinit.py: all the dogtail library init we need
* lib/_node.py: extending our dogtail node class with more functions
* lib/app.py: VMMDogtailApp
* lib/util.py: util functions plus all the special helpers previously
    in our custom TestCase
* lib/testcase.py: The TestCase that sets and tears down self.app

Adjust callers to match and make it easier to eventually convert to
native pytest usage

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2020-09-11 13:02:51 -04:00
parent aa9fcdfdb2
commit ebf76563b8
29 changed files with 1639 additions and 1618 deletions

View File

@ -1,43 +1,2 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import os
import signal
import sys
import warnings
# Dogtail is noisy with GTK and GI deprecation warnings
warnings.simplefilter("ignore")
# Ignores pylint error since dogtail doesn't specify this
import gi
gi.require_version('Atspi', '2.0')
import dogtail.config
from tests.uitests import utils
# Perform 5 search attempts if a widget lookup fails (default 20)
dogtail.config.config.searchCutoffCount = 5
# Use .1 second delay between each action (default 1)
dogtail.config.config.actionDelay = .1
# Turn off needlessly noisy debugging
DOGTAIL_DEBUG = False
dogtail.config.config.logDebugToStdOut = DOGTAIL_DEBUG
dogtail.config.config.logDebugToFile = False
# Dogtail screws with the default excepthook, disabling output if we turned
# off logging, so fix it
sys.excepthook = sys.__excepthook__
# dogtail.utils.Blinker creates a GLib.MainLoop on module import, which
# screws up SIGINT handling somehow. This reregisters the
# unittest.installHandler magic
signal.signal(signal.SIGINT, signal.getsignal(signal.SIGINT))
# Needed so labels are matched in english
os.environ['LANG'] = 'en_US.UTF-8'
os.environ.pop("VIRTINST_TEST_SUITE", None)

View File

@ -0,0 +1,8 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from . import _dogtailinit
from . import _node
from . import app
from . import utils
from . import testcase

View File

@ -0,0 +1,49 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import os
import signal
import sys
import warnings
# Dogtail is noisy with GTK and GI deprecation warnings
warnings.simplefilter("ignore")
# Ignores pylint error since dogtail doesn't specify this
import gi
gi.require_version('Atspi', '2.0')
import dogtail.config
import dogtail.utils
# Perform 5 search attempts if a widget lookup fails (default 20)
dogtail.config.config.searchCutoffCount = 5
# Use .1 second delay between each action (default 1)
dogtail.config.config.actionDelay = .1
# Turn off needlessly noisy debugging
DOGTAIL_DEBUG = False
dogtail.config.config.logDebugToStdOut = DOGTAIL_DEBUG
dogtail.config.config.logDebugToFile = False
# Dogtail screws with the default excepthook, disabling output if we turned
# off logging, so fix it
sys.excepthook = sys.__excepthook__
# dogtail.utils.Blinker creates a GLib.MainLoop on module import, which
# screws up SIGINT handling somehow. This reregisters the
# unittest.installHandler magic
signal.signal(signal.SIGINT, signal.getsignal(signal.SIGINT))
# Needed so labels are matched in english
os.environ['LANG'] = 'en_US.UTF-8'
os.environ.pop("VIRTINST_TEST_SUITE", None)
if not dogtail.utils.isA11yEnabled():
print("Enabling gsettings accessibility")
dogtail.utils.enableA11y()
# This will trigger an error if accessibility isn't enabled
import dogtail.tree # pylint: disable=wrong-import-order,ungrouped-imports

327
tests/uitests/lib/_node.py Normal file
View File

@ -0,0 +1,327 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import re
import time
from gi.repository import Gdk
import dogtail.tree
import pyatspi
from virtinst import log
from . import utils
class _FuzzyPredicate(dogtail.predicate.Predicate):
"""
Object dogtail/pyatspi want for node searching.
"""
def __init__(self, name=None, roleName=None, labeller_text=None):
"""
:param name: Match node.name or node.labeller.text if
labeller_text not specified
:param roleName: Match node.roleName
:param labeller_text: Match node.labeller.text
"""
self._name = name
self._roleName = roleName
self._labeller_text = labeller_text
self._name_pattern = None
self._role_pattern = None
self._labeller_pattern = None
if self._name:
self._name_pattern = re.compile(self._name, re.DOTALL)
if self._roleName:
self._role_pattern = re.compile(self._roleName, re.DOTALL)
if self._labeller_text:
self._labeller_pattern = re.compile(self._labeller_text, re.DOTALL)
def makeScriptMethodCall(self, isRecursive):
ignore = isRecursive
return
def makeScriptVariableName(self):
return
def describeSearchResult(self, node=None):
if not node:
return ""
return node.node_string()
def satisfiedByNode(self, node):
"""
The actual search routine
"""
try:
if self._roleName and not self._role_pattern.match(node.roleName):
return
labeller = ""
if node.labeller:
labeller = node.labeller.text
if (self._name and
not self._name_pattern.match(node.name) and
not self._name_pattern.match(labeller)):
return
if (self._labeller_text and
not self._labeller_pattern.match(labeller)):
return
return True
except Exception as e:
log.debug(
"got predicate exception name=%s role=%s labeller=%s: %s",
self._name, self._roleName, self._labeller_text, e)
class _VMMDogtailNode(dogtail.tree.Node):
"""
Our extensions to the dogtail node wrapper class.
"""
# The class hackery means pylint can't figure this class out
# pylint: disable=no-member
@property
def active(self):
"""
If the window is the raised and active window or not
"""
return self.getState().contains(pyatspi.STATE_ACTIVE)
@property
def state_selected(self):
return self.getState().contains(pyatspi.STATE_SELECTED)
@property
def onscreen(self):
# We need to check that full widget is on screen because we use this
# function to check whether we can click a widget. We may click
# anywhere within the widget and clicks outside the screen bounds are
# silently ignored.
if self.roleName in ["frame"]:
return True
screen = Gdk.Screen.get_default()
return (self.position[0] >= 0 and
self.position[0] + self.size[0] < screen.get_width() and
self.position[1] >= 0 and
self.position[1] + self.size[1] < screen.get_height())
def check_onscreen(self):
"""
Check in a loop that the widget is onscreen
"""
utils.check(lambda: self.onscreen)
def check_sensitive(self):
"""
Check whether interactive widgets are sensitive or not
"""
valid_types = [
"push button",
"toggle button",
"check button",
"combo box",
"menu item",
"text",
"menu",
]
if self.roleName not in valid_types:
return True
utils.check(lambda: self.sensitive)
def click_secondary_icon(self):
"""
Helper for clicking the secondary icon of a text entry
"""
self.check_onscreen()
self.check_sensitive()
button = 1
clickX = self.position[0] + self.size[0] - 10
clickY = self.position[1] + (self.size[1] / 2)
dogtail.rawinput.click(clickX, clickY, button)
def click_combo_entry(self):
"""
Helper for clicking the arrow of a combo entry, to expose the menu.
Clicks middle of Y axis, but 1/10th of the height from the right side.
Using a small, hardcoded offset may not work on some themes (e.g. when
running virt-manager on KDE)
"""
self.check_onscreen()
self.check_sensitive()
button = 1
clickX = self.position[0] + self.size[0] - self.size[1] / 4
clickY = self.position[1] + self.size[1] / 2
dogtail.rawinput.click(clickX, clickY, button)
def click_expander(self):
"""
Helper for clicking expander, hitting the text part to actually
open it. Basically clicks top left corner with some indent
"""
self.check_onscreen()
self.check_sensitive()
button = 1
clickX = self.position[0] + 10
clickY = self.position[1] + 5
dogtail.rawinput.click(clickX, clickY, button)
def title_coordinates(self):
"""
Return clickable coordinates of a window's titlebar
"""
x = self.position[0] + (self.size[0] / 2)
y = self.position[1] + 10
return x, y
def click_title(self):
"""
Helper to click a window title bar, hitting the horizontal
center of the bar
"""
if self.roleName not in ["frame", "alert"]:
raise RuntimeError("Can't use click_title() on type=%s" %
self.roleName)
button = 1
clickX, clickY = self.title_coordinates()
dogtail.rawinput.click(clickX, clickY, button)
def drag(self, x, y):
"""
Drag a window to the x/y coordinates
"""
time.sleep(.5)
self.click_title()
time.sleep(.5)
clickX, clickY = self.title_coordinates()
dogtail.rawinput.drag((clickX, clickY), (x, y))
def click(self, *args, **kwargs):
"""
click wrapper, give up to a second for widget to appear on
screen, helps reduce some test flakiness
"""
# pylint: disable=arguments-differ,signature-differs
self.check_onscreen()
self.check_sensitive()
dogtail.tree.Node.click(self, *args, **kwargs)
def set_text(self, text):
self.check_onscreen()
self.check_sensitive()
assert hasattr(self, "text")
self.text = text
def bring_on_screen(self, key_name="Down", max_tries=100):
"""
Attempts to bring the item to screen by repeatedly clicking the given
key. Raises exception if max_tries attempts are exceeded.
"""
cur_try = 0
while not self.onscreen:
dogtail.rawinput.pressKey(key_name)
cur_try += 1
if cur_try > max_tries:
raise RuntimeError("Could not bring widget on screen")
return self
#########################
# Widget search helpers #
#########################
def find(self, name, roleName=None, labeller_text=None, check_active=True):
"""
Search root for any widget that contains the passed name/role regex
strings.
"""
pred = _FuzzyPredicate(name, roleName, labeller_text)
try:
ret = self.findChild(pred)
except dogtail.tree.SearchError:
raise dogtail.tree.SearchError("Didn't find widget with name='%s' "
"roleName='%s' labeller_text='%s'" %
(name, roleName, labeller_text)) from None
# Wait for independent windows to become active in the window manager
# before we return them. This ensures the window is actually onscreen
# so it sidesteps a lot of race conditions
if ret.roleName in ["frame", "dialog", "alert"] and check_active:
utils.check(lambda: ret.active)
return ret
def find_fuzzy(self, name, roleName=None, labeller_text=None):
"""
Search root for any widget that contains the passed name/role strings.
"""
name_pattern = None
role_pattern = None
labeller_pattern = None
if name:
name_pattern = ".*%s.*" % name
if roleName:
role_pattern = ".*%s.*" % roleName
if labeller_text:
labeller_pattern = ".*%s.*" % labeller_text
return self.find(name_pattern, role_pattern, labeller_pattern)
##########################
# Higher level behaviors #
##########################
def combo_select(self, combolabel, itemlabel):
"""
Lookup the combo, click it, select the menu item
"""
combo = self.find(combolabel, "combo box")
combo.click_combo_entry()
combo.find(itemlabel, "menu item").click()
def combo_check_default(self, combolabel, itemlabel):
"""
Lookup the combo and verify the menu item is selected
"""
combo = self.find(combolabel, "combo box")
combo.click_combo_entry()
item = combo.find(itemlabel, "menu item")
utils.check(lambda: item.selected)
dogtail.rawinput.pressKey("Escape")
#####################
# Debugging helpers #
#####################
def node_string(self):
msg = "name='%s' roleName='%s'" % (self.name, self.roleName)
if self.labeller:
msg += " labeller.text='%s'" % self.labeller.text
return msg
def fmt_nodes(self):
strs = []
def _walk(node):
try:
strs.append(node.node_string())
except Exception as e:
strs.append("got exception: %s" % e)
self.findChildren(_walk, isLambda=True)
return "\n".join(strs)
def print_nodes(self):
"""
Helper to print the entire node tree for the passed root. Useful
if to figure out the roleName for the object you are looking for
"""
print(self.fmt_nodes())
# This is the same hack dogtail uses to extend the Accessible class.
_bases = list(pyatspi.Accessibility.Accessible.__bases__)
_bases.insert(_bases.index(dogtail.tree.Node), _VMMDogtailNode)
_bases.remove(dogtail.tree.Node)
pyatspi.Accessibility.Accessible.__bases__ = tuple(_bases)

212
tests/uitests/lib/app.py Normal file
View File

@ -0,0 +1,212 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import os
import signal
import subprocess
import sys
import time
import dogtail.rawinput
import dogtail.tree
from gi.repository import Gio
from virtinst import log
import tests.utils
from . import utils
class VMMDogtailApp(object):
"""
Wrapper class to simplify dogtail app handling
"""
def __init__(self, uri=tests.utils.URIs.test_full):
self._proc = None
self._root = None
self._topwin = None
self.uri = uri
####################################
# Helpers to save testcase imports #
####################################
def check(self, *args, **kwargs):
return utils.check(*args, **kwargs)
def sleep(self, *args, **kwargs):
return time.sleep(*args, **kwargs)
rawinput = dogtail.rawinput
tree = dogtail.tree
#################################
# virt-manager specific helpers #
#################################
def open_host_window(self, tab, conn_label="test testdriver.xml"):
"""
Helper to open host connection window and switch to a tab
"""
self.root.find_fuzzy(conn_label, "table cell").click()
self.root.find_fuzzy("Edit", "menu").click()
self.root.find_fuzzy("Connection Details", "menu item").click()
win = self.root.find_fuzzy(
"%s Connection Details" % conn_label, "frame")
win.find_fuzzy(tab, "page tab").click()
return win
def open_details_window(self, vmname, shutdown=False, double=False):
if double:
self.root.find_fuzzy(vmname, "table cell").doubleClick()
else:
self.root.find_fuzzy(vmname, "table cell").click(button=3)
self.root.find("Open", "menu item").click()
win = self.root.find("%s on" % vmname, "frame")
win.find("Details", "radio button").click()
if shutdown:
win.find("Shut Down", "push button").click()
run = win.find("Run", "push button")
utils.check(lambda: run.sensitive)
return win
def click_alert_button(self, label_text, button_text):
alert = self.root.find("vmm dialog", "alert")
alert.find_fuzzy(label_text, "label")
alert.find(button_text, "push button").click()
utils.check(lambda: not alert.active)
def select_storagebrowser_volume(self, pool, vol, doubleclick=False):
browsewin = self.root.find("vmm-storage-browser")
browsewin.find_fuzzy(pool, "table cell").click()
volcell = browsewin.find_fuzzy(vol, "table cell")
if doubleclick:
volcell.doubleClick()
else:
volcell.click()
browsewin.find_fuzzy("Choose Volume").click()
utils.check(lambda: not browsewin.active)
###########################
# Process management APIs #
###########################
@property
def root(self):
if self._root is None:
self.open()
return self._root
@property
def topwin(self):
if self._topwin is None:
self.open()
return self._topwin
def error_if_already_running(self):
# Ensure virt-manager isn't already running
dbus = Gio.DBusProxy.new_sync(
Gio.bus_get_sync(Gio.BusType.SESSION, None), 0, None,
"org.freedesktop.DBus", "/org/freedesktop/DBus",
"org.freedesktop.DBus", None)
if "org.virt-manager.virt-manager" in dbus.ListNames():
raise RuntimeError("virt-manager is already running. "
"Close it before running this test suite.")
def is_running(self):
return bool(self._proc and self._proc.poll() is None)
def wait_for_exit(self):
# Wait for shutdown for 2 sec
waittime = 2
for ignore in range(int(waittime / .05)):
time.sleep(.05)
if self._proc.poll() is not None:
self._proc = None
return True
return False
def stop(self):
"""
Try graceful process shutdown, then kill it
"""
if not self._proc:
return
try:
self._proc.send_signal(signal.SIGINT)
except Exception:
log.debug("Error terminating process", exc_info=True)
self._proc = None
return
if self.wait_for_exit():
return
log.warning("App didn't exit gracefully from SIGINT. Killing...")
self._proc.kill()
self.wait_for_exit()
#####################################
# virt-manager launching entrypoint #
#####################################
def open(self, extra_opts=None, check_already_running=True, use_uri=True,
window_name=None, xmleditor_enabled=False, keyfile=None,
break_setfacl=False, first_run=True, no_fork=True,
will_fail=False, enable_libguestfs=False,
firstrun_uri=None, fake_systemd_success=True):
extra_opts = extra_opts or []
if tests.utils.TESTCONFIG.debug and no_fork:
stdout = sys.stdout
stderr = sys.stderr
extra_opts.append("--debug")
else:
stdout = open(os.devnull)
stderr = open(os.devnull)
cmd = [sys.executable]
cmd += [os.path.join(tests.utils.TOPDIR, "virt-manager")]
if no_fork:
cmd += ["--no-fork"]
if use_uri:
cmd += ["--connect", self.uri]
if first_run:
cmd.append("--test-options=first-run")
if not firstrun_uri:
firstrun_uri = ""
if firstrun_uri is not None:
cmd.append("--test-options=firstrun-uri=%s" % firstrun_uri)
if xmleditor_enabled:
cmd.append("--test-options=xmleditor-enabled")
if break_setfacl:
cmd.append("--test-options=break-setfacl")
if enable_libguestfs is True:
cmd.append("--test-options=enable-libguestfs")
if enable_libguestfs is False:
cmd.append("--test-options=disable-libguestfs")
if fake_systemd_success:
cmd.append("--test-options=fake-systemd-success")
if keyfile:
import atexit
import tempfile
keyfile = tests.utils.UITESTDATADIR + "/keyfile/" + keyfile
tempname = tempfile.mktemp(prefix="virtmanager-uitests-keyfile")
open(tempname, "w").write(open(keyfile).read())
atexit.register(lambda: os.unlink(tempname))
cmd.append("--test-options=gsettings-keyfile=%s" % tempname)
cmd += extra_opts
if check_already_running:
self.error_if_already_running()
self._proc = subprocess.Popen(cmd, stdout=stdout, stderr=stderr)
if not will_fail:
self._root = dogtail.tree.root.application("virt-manager")
self._topwin = self._root.find(window_name, "(frame|dialog|alert)")

View File

@ -0,0 +1,16 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import unittest
from .app import VMMDogtailApp
class UITestCase(unittest.TestCase):
"""
Common testcase bits shared for ui tests
"""
def setUp(self):
self.app = VMMDogtailApp()
def tearDown(self):
self.app.stop()

View File

@ -0,0 +1,85 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import time
def check(func, timeout=2):
"""
Run the passed func in a loop every .1 seconds until timeout is hit or
the func returns True.
"""
start_time = time.time()
interval = 0.1
while True:
if func() is True:
return
if (time.time() - start_time) > timeout:
raise RuntimeError("Loop condition wasn't met")
time.sleep(interval)
def walkUIList(app, win, lst, error_cb, reverse=False):
"""
Toggle down through a UI list like addhardware, net/storage/iface
lists, and ensure an error isn't raised.
"""
# Walk the lst UI and find all labelled table cells, these are
# the actual list entries
all_cells = lst.findChildren(lambda w: w.roleName == "table cell")
if reverse:
all_cells.reverse()
all_cells[0].click()
cells_per_selection = len([c for c in all_cells if c.focused])
idx = 0
while idx < len(all_cells):
cell = all_cells[idx]
if not cell.state_selected:
# Could be a separator table cell. Try to figure it out
if not any([c.name for c in
all_cells[idx:(idx + cells_per_selection)]]):
idx += cells_per_selection
continue
check(lambda: cell.state_selected)
app.rawinput.pressKey(reverse and "Up" or "Down")
if not win.active:
# Should mean an error dialog popped up
app.root.find("Error", "alert")
raise AssertionError("Error dialog raised?")
if error_cb():
raise AssertionError("Error found on a page")
idx += cells_per_selection
if idx >= len(all_cells):
# Last cell, selection shouldn't have changed
check(lambda: cell.state_selected)
else:
check(lambda: not cell.state_selected)
def test_xmleditor_interactions(app, win, finish):
"""
Helper to test some common XML editor interactions
"""
# Click the tab, make a bogus XML edit
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
xmleditor.set_text(xmleditor.text.replace("<", "<FOO", 1))
# Trying to click away should warn that there's unapplied changes
win.find("Details", "page tab").click()
# Select 'No', meaning don't abandon changes
app.click_alert_button("changes will be lost", "No")
check(lambda: xmleditor.showing)
# Click the finish button, but our bogus change should trigger error
finish.click()
app.click_alert_button("(xmlParseDoc|tag.mismatch)", "Close")
# Try unapplied changes again, this time abandon our changes
win.find("Details", "page tab").click()
app.click_alert_button("changes will be lost", "Yes")
check(lambda: not xmleditor.showing)

View File

@ -3,10 +3,10 @@
import datetime
from tests.uitests import utils as uiutils
from . import lib
class VMMAbout(uiutils.UITestCase):
class VMMAbout(lib.testcase.UITestCase):
"""
UI tests for the 'About' dialog
"""
@ -26,4 +26,4 @@ class VMMAbout(uiutils.UITestCase):
print("Current year=%s not in about.ui dialog!" % curyear)
win.keyCombo("<ESC>")
uiutils.check(lambda: win.visible is False)
lib.utils.check(lambda: win.visible is False)

View File

@ -5,7 +5,7 @@ import os
import tempfile
import tests
from tests.uitests import utils as uiutils
from . import lib
def _search_permissions_decorator(fn):
@ -40,7 +40,7 @@ def _search_permissions_decorator(fn):
return wrapper
class AddHardware(uiutils.UITestCase):
class AddHardware(lib.testcase.UITestCase):
"""
UI tests for virt-manager's VM addhardware window
"""
@ -49,8 +49,6 @@ class AddHardware(uiutils.UITestCase):
# Private helpers #
###################
_default_vmname = "test-clone-simple"
def _open_addhw_window(self, details):
details.find("add-hardware", "push button").click()
addhw = self.app.root.find("Add New Virtual Hardware", "frame")
@ -59,14 +57,14 @@ class AddHardware(uiutils.UITestCase):
def _select_hw(self, addhw, hwname, tabname):
addhw.find(hwname, "table cell").click()
tab = addhw.find(tabname, None)
uiutils.check(lambda: tab.showing)
lib.utils.check(lambda: tab.showing)
return tab
def _finish(self, addhw, check):
addhw.find("Finish", "push button").click()
uiutils.check(lambda: not addhw.active)
lib.utils.check(lambda: not addhw.active)
if check:
uiutils.check(lambda: check.active)
lib.utils.check(lambda: check.active)
##############
@ -77,7 +75,7 @@ class AddHardware(uiutils.UITestCase):
"""
Add various controller configs
"""
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
addhw = self._open_addhw_window(details)
# Default SCSI
@ -106,13 +104,13 @@ class AddHardware(uiutils.UITestCase):
tab.combo_select("Model:", "USB 3")
# Can't add more than 1 USB controller, so finish isn't sensitive
finish = addhw.find("Finish", "push button")
uiutils.check(lambda: not finish.sensitive)
lib.utils.check(lambda: not finish.sensitive)
def testAddCephDisk(self):
"""
Add a disk with a ceph volume, ensure it maps correctly
"""
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
addhw = self._open_addhw_window(details)
# Select ceph volume for disk
@ -128,15 +126,15 @@ class AddHardware(uiutils.UITestCase):
# Check disk details, make sure it correctly selected volume
details.find("IDE Disk 2", "table cell").click()
tab = details.find("disk-tab")
uiutils.check(lambda: tab.showing)
lib.utils.check(lambda: tab.showing)
disk_path = tab.find("disk-source-path")
uiutils.check(lambda: "rbd://" in disk_path.text)
lib.utils.check(lambda: "rbd://" in disk_path.text)
def testAddDisks(self):
"""
Add various disk configs and test storage browser
"""
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
addhw = self._open_addhw_window(details)
# Default disk
@ -157,7 +155,7 @@ class AddHardware(uiutils.UITestCase):
# Size too big
tab.find("GiB", "spin button").set_text("2000")
self._finish(addhw, check=None)
self._click_alert_button("not enough free space", "Close")
self.app.click_alert_button("not enough free space", "Close")
tab.find("GiB", "spin button").set_text("1.5")
self._finish(addhw, check=details)
@ -166,7 +164,7 @@ class AddHardware(uiutils.UITestCase):
tab = self._select_hw(addhw, "Storage", "storage-tab")
tab.find_fuzzy("Select or create", "radio").click()
self._finish(addhw, check=None)
self._click_alert_button("storage path must be specified", "OK")
self.app.click_alert_button("storage path must be specified", "OK")
tab.find("storage-browse", "push button").click()
browse = self.app.root.find("vmm-storage-browser")
@ -177,15 +175,15 @@ class AddHardware(uiutils.UITestCase):
newname = "a-newvol"
newvol.find("Name:", "text").set_text(newname)
newvol.find("Finish", "push button").click()
uiutils.check(lambda: not newvol.showing)
lib.utils.check(lambda: not newvol.showing)
volcell = browse.find(newname, "table cell")
uiutils.check(lambda: volcell.selected)
lib.utils.check(lambda: volcell.selected)
browse.find("vol-refresh", "push button").click()
volcell = browse.find(newname, "table cell")
uiutils.check(lambda: volcell.selected)
lib.utils.check(lambda: volcell.selected)
browse.find("vol-delete", "push button").click()
self._click_alert_button("permanently delete the volume", "Yes")
uiutils.check(lambda: volcell.dead)
self.app.click_alert_button("permanently delete the volume", "Yes")
lib.utils.check(lambda: volcell.dead)
# Test browse local
browse.find("Browse Local", "push button").click()
@ -198,10 +196,10 @@ class AddHardware(uiutils.UITestCase):
fname = "COPYING"
chooser.find(fname, "table cell").click()
chooser.find("Open", "push button").click()
uiutils.check(lambda: not chooser.showing)
uiutils.check(lambda: addhw.active)
lib.utils.check(lambda: not chooser.showing)
lib.utils.check(lambda: addhw.active)
storageent = tab.find("storage-entry")
uiutils.check(lambda: ("/" + fname) in storageent.text)
lib.utils.check(lambda: ("/" + fname) in storageent.text)
# Reopen dialog, select a volume, etic
tab.find("storage-browse", "push button").click()
@ -210,12 +208,12 @@ class AddHardware(uiutils.UITestCase):
browse.find_fuzzy("disk-pool", "table cell").click()
browse.find("diskvol1", "table cell").click()
browse.find("Choose Volume", "push button").click()
uiutils.check(lambda: "/diskvol1" in storageent.text)
lib.utils.check(lambda: "/diskvol1" in storageent.text)
self._finish(addhw, check=None)
self._click_alert_button("already in use by", "No")
self.app.click_alert_button("already in use by", "No")
self._finish(addhw, check=None)
self._click_alert_button("already in use by", "Yes")
uiutils.check(lambda: details.active)
self.app.click_alert_button("already in use by", "Yes")
lib.utils.check(lambda: details.active)
# choose file for floppy
@ -223,7 +221,7 @@ class AddHardware(uiutils.UITestCase):
tab = self._select_hw(addhw, "Storage", "storage-tab")
tab.combo_select("Device type:", "Floppy device")
diskradio = tab.find_fuzzy("Create a disk image", "radio")
uiutils.check(lambda: not diskradio.sensitive)
lib.utils.check(lambda: not diskradio.sensitive)
tab.find("storage-entry").set_text("/dev/default-pool/bochs-vol")
self._finish(addhw, check=details)
@ -240,7 +238,7 @@ class AddHardware(uiutils.UITestCase):
Test search permissions 'no' and checkbox case
"""
self.app.uri = uri
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
# Say 'No' but path should still work due to test driver
addhw = self._open_addhw_window(details)
@ -249,8 +247,8 @@ class AddHardware(uiutils.UITestCase):
path = tmpdir + "/foo1.img"
tab.find("storage-entry").set_text(path)
self._finish(addhw, check=None)
self._click_alert_button("emulator may not have", "No")
uiutils.check(lambda: details.active)
self.app.click_alert_button("emulator may not have", "No")
lib.utils.check(lambda: details.active)
# Say 'don't ask again'
addhw = self._open_addhw_window(details)
@ -261,8 +259,8 @@ class AddHardware(uiutils.UITestCase):
self._finish(addhw, check=None)
alert = self.app.root.find_fuzzy("vmm dialog", "alert")
alert.find_fuzzy("Don't ask", "check box").click()
self._click_alert_button("emulator may not have", "No")
uiutils.check(lambda: details.active)
self.app.click_alert_button("emulator may not have", "No")
lib.utils.check(lambda: details.active)
# Confirm it doesn't ask about path again
addhw = self._open_addhw_window(details)
@ -278,7 +276,7 @@ class AddHardware(uiutils.UITestCase):
Select 'Yes' for search perms fixing
"""
self.app.uri = uri
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
# Say 'Yes'
addhw = self._open_addhw_window(details)
@ -287,8 +285,8 @@ class AddHardware(uiutils.UITestCase):
path = tmpdir + "/foo1.img"
tab.find("storage-entry").set_text(path)
self._finish(addhw, check=None)
self._click_alert_button("emulator may not have", "Yes")
uiutils.check(lambda: details.active)
self.app.click_alert_button("emulator may not have", "Yes")
lib.utils.check(lambda: details.active)
# Confirm it doesn't ask about path again
addhw = self._open_addhw_window(details)
@ -305,7 +303,7 @@ class AddHardware(uiutils.UITestCase):
"""
self.app.uri = uri
self.app.open(break_setfacl=True)
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
# Say 'Yes' and it should fail, then blacklist the paths
addhw = self._open_addhw_window(details)
@ -314,12 +312,12 @@ class AddHardware(uiutils.UITestCase):
path = tmpdir + "/foo1.img"
tab.find("storage-entry").set_text(path)
self._finish(addhw, check=None)
self._click_alert_button("emulator may not have", "Yes")
self.app.click_alert_button("emulator may not have", "Yes")
alert = self.app.root.find("vmm dialog", "alert")
alert.find_fuzzy("Errors were encountered", "label")
alert.find_fuzzy("Don't ask", "check box").click()
alert.find_fuzzy("OK", "push button").click()
uiutils.check(lambda: details.active)
lib.utils.check(lambda: details.active)
# Confirm it doesn't ask about path again
addhw = self._open_addhw_window(details)
@ -333,7 +331,7 @@ class AddHardware(uiutils.UITestCase):
"""
Test various network configs
"""
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
addhw = self._open_addhw_window(details)
# Basic network + opts
@ -358,7 +356,7 @@ class AddHardware(uiutils.UITestCase):
tab.find("Device name:", "text").set_text("zbr0")
self._finish(addhw, check=None)
# Check MAC validation error
self._click_alert_button("00:11:22:33:44:55", "Close")
self.app.click_alert_button("00:11:22:33:44:55", "Close")
# Fix MAC
tab.find("mac-address-enable", "check box").click()
@ -370,7 +368,7 @@ class AddHardware(uiutils.UITestCase):
"""
Graphics device testing
"""
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
addhw = self._open_addhw_window(details)
# VNC example
@ -385,12 +383,12 @@ class AddHardware(uiutils.UITestCase):
newpass = "foobar"
passwd.typeText(newpass)
tab.find("Show password", "check").click()
uiutils.check(lambda: passwd.text == newpass)
lib.utils.check(lambda: passwd.text == newpass)
tab.find("Show password", "check").click()
uiutils.check(lambda: passwd.text != newpass)
lib.utils.check(lambda: passwd.text != newpass)
self._finish(addhw, check=None)
# Catch a port error
self._click_alert_button("Port must be above 5900", "Close")
self.app.click_alert_button("Port must be above 5900", "Close")
tab.find("graphics-port", "spin button").set_text("5920")
self._finish(addhw, check=details)
@ -413,25 +411,25 @@ class AddHardware(uiutils.UITestCase):
"""
Add a few different USB and PCI devices
"""
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
addhw = self._open_addhw_window(details)
# Add USB device dup1
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.app.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)
self.app.click_alert_button("device is already in use by", "Yes")
lib.utils.check(lambda: details.active)
# Add USB device dup2
self._open_addhw_window(details)
tab = self._select_hw(addhw, "USB Host Device", "host-tab")
tab.find_fuzzy("HP Dup USB 2", "table cell").click()
self._finish(addhw, check=None)
self._click_alert_button("device is already in use by", "Yes")
uiutils.check(lambda: details.active)
self.app.click_alert_button("device is already in use by", "Yes")
lib.utils.check(lambda: details.active)
# Add another USB device
self._open_addhw_window(details)
@ -444,15 +442,15 @@ class AddHardware(uiutils.UITestCase):
tab = self._select_hw(addhw, "PCI Host Device", "host-tab")
tab.find_fuzzy("(Interface eth0)", "table cell").click()
self._finish(addhw, check=None)
self._click_alert_button("device is already in use by", "Yes")
uiutils.check(lambda: details.active)
self.app.click_alert_button("device is already in use by", "Yes")
lib.utils.check(lambda: details.active)
def testAddChars(self):
"""
Add a bunch of char devices
"""
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
addhw = self._open_addhw_window(details)
# Add console device
@ -488,7 +486,7 @@ class AddHardware(uiutils.UITestCase):
"""
self.app.uri = tests.utils.URIs.lxc
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
addhw = self._open_addhw_window(details)
# Add File+nbd share
@ -505,12 +503,12 @@ class AddHardware(uiutils.UITestCase):
browsewin.find_fuzzy("default-pool", "table cell").click()
browsewin.find_fuzzy("bochs-vol", "table cell").click()
choose = browsewin.find("Choose Volume")
uiutils.check(lambda: not choose.sensitive)
lib.utils.check(lambda: not choose.sensitive)
browsewin.find_fuzzy("dir-vol", "table cell").click()
uiutils.check(lambda: choose.sensitive)
lib.utils.check(lambda: choose.sensitive)
choose.click()
uiutils.check(lambda: addhw.active)
uiutils.check(
lib.utils.check(lambda: addhw.active)
lib.utils.check(
lambda: source.text == "/dev/default-pool/dir-vol")
tab.find_fuzzy("Export filesystem", "check").click()
@ -518,7 +516,7 @@ class AddHardware(uiutils.UITestCase):
badtarget = "a" * 1024
tab.find("Target path:", "text").set_text(badtarget)
self._finish(addhw, check=None)
self._click_alert_button("aaa...", "Close")
self.app.click_alert_button("aaa...", "Close")
tab.find("Target path:", "text").set_text("/foo/target")
self._finish(addhw, check=details)
@ -535,7 +533,7 @@ class AddHardware(uiutils.UITestCase):
"""
Add some simple devices
"""
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
addhw = self._open_addhw_window(details)
# Add input
@ -577,7 +575,7 @@ class AddHardware(uiutils.UITestCase):
"""
Add some more simple devices"
"""
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
addhw = self._open_addhw_window(details)
# Add usb controller, to make usbredir work
@ -630,8 +628,8 @@ class AddHardware(uiutils.UITestCase):
"""
Test some special case handling when VM has controller usb model='none'
"""
details = self._open_details_window(
"test alternate devs title", shutdown=True)
details = self.app.open_details_window("test alternate devs title",
shutdown=True)
addhw = self._open_addhw_window(details)
# Add usb controller
@ -646,14 +644,14 @@ class AddHardware(uiutils.UITestCase):
combo = tab.find("Type:", "combo box")
combo.find(None, "text").set_text("foobar")
self._finish(addhw, check=None)
self._click_alert_button("Unable to add device", "Close")
uiutils.check(lambda: addhw.active)
self.app.click_alert_button("Unable to add device", "Close")
lib.utils.check(lambda: addhw.active)
def testAddHWCornerCases(self):
"""
Random addhardware related tests
"""
details = self._open_details_window("test-many-devices")
details = self.app.open_details_window("test-many-devices")
addhw = self._open_addhw_window(details)
# Test cancel
@ -668,7 +666,7 @@ class AddHardware(uiutils.UITestCase):
"label")
alert.find("Details", "toggle button").click_expander()
alert.find("No", "push button").click()
uiutils.check(lambda: details.active)
lib.utils.check(lambda: details.active)
# Test live adding, error dialog, click yes
self._open_addhw_window(details)
@ -679,14 +677,14 @@ class AddHardware(uiutils.UITestCase):
"label")
alert.find("Details", "toggle button").click_expander()
alert.find("Yes", "push button").click()
uiutils.check(lambda: alert.dead)
lib.utils.check(lambda: alert.dead)
def testAddHWXMLEdit(self):
"""
Test XML editor integration
"""
self.app.open(xmleditor_enabled=True)
details = self._open_details_window()
details = self.app.open_details_window("test-clone-simple")
win = self._open_addhw_window(details)
# Disk test, change path and make sure we error it is missing
@ -696,7 +694,7 @@ class AddHardware(uiutils.UITestCase):
newpath = "/FOO/XMLEDIT/test1.img"
xmleditor.set_text(xmleditor.text.replace(origpath, newpath))
self._finish(win, check=None)
self._click_alert_button("non-existent path", "Close")
self.app.click_alert_button("non-existent path", "Close")
# Undo the bad change, change bus/target
xmleditor.set_text(xmleditor.text.replace(newpath, origpath))
@ -706,7 +704,7 @@ class AddHardware(uiutils.UITestCase):
# Verify the changes applied
details.find("Xen Disk 1").click()
uiutils.check(lambda: details.active)
lib.utils.check(lambda: details.active)
win = self._open_addhw_window(details)
tab = self._select_hw(win, "Storage", "storage-tab")
tab.find_fuzzy("Select or create", "radio").click()
@ -718,12 +716,12 @@ class AddHardware(uiutils.UITestCase):
# Select XML, switch to new dev type, verify we change focus
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
uiutils.check(lambda: xmleditor.showing)
lib.utils.check(lambda: xmleditor.showing)
tab = self._select_hw(win, "Network", "network-tab")
uiutils.check(lambda: not xmleditor.showing)
lib.utils.check(lambda: not xmleditor.showing)
# Do standard xmleditor tests
finish = win.find("Finish", "push button")
self._test_xmleditor_interactions(win, finish)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
win.find("Cancel", "push button").click()
uiutils.check(lambda: not win.visible)
lib.utils.check(lambda: not win.visible)

View File

@ -3,10 +3,10 @@
import unittest.mock
from tests.uitests import utils as uiutils
from . import lib
class VMMCLI(uiutils.UITestCase):
class VMMCLI(lib.testcase.UITestCase):
"""
UI tests for virt-manager's command line --show options
"""
@ -17,48 +17,48 @@ class VMMCLI(uiutils.UITestCase):
def testShowNewVM(self):
self.app.open(extra_opts=["--show-domain-creator"])
uiutils.check(lambda: self.app.topwin.name == "New VM")
lib.utils.check(lambda: self.app.topwin.name == "New VM")
self.app.topwin.keyCombo("<alt>F4")
uiutils.check(lambda: self.app.is_running() is False)
lib.utils.check(lambda: self.app.is_running() is False)
def testShowHost(self):
self.app.open(extra_opts=["--show-host-summary"])
uiutils.check(lambda: self.app.topwin.name == "test testdriver.xml Connection Details")
lib.utils.check(lambda: self.app.topwin.name == "test testdriver.xml Connection Details")
nametext = self.app.topwin.find_fuzzy("Name:", "text")
uiutils.check(lambda: nametext.text == "test testdriver.xml")
lib.utils.check(lambda: nametext.text == "test testdriver.xml")
self.app.topwin.keyCombo("<alt>F4")
uiutils.check(lambda: self.app.is_running() is False)
lib.utils.check(lambda: self.app.is_running() is False)
def testShowDetails(self):
self.app.open(extra_opts=["--show-domain-editor", "test-clone-simple"])
uiutils.check(lambda: "test-clone-simple on" in self.app.topwin.name)
lib.utils.check(lambda: "test-clone-simple on" in self.app.topwin.name)
rlabel = self.app.topwin.find_fuzzy("Guest is not running", "label")
uiutils.check(lambda: not rlabel.showing)
lib.utils.check(lambda: not rlabel.showing)
addhw = self.app.topwin.find_fuzzy("add-hardware", "button")
uiutils.check(lambda: addhw.showing)
lib.utils.check(lambda: addhw.showing)
self.app.topwin.keyCombo("<alt>F4")
uiutils.check(lambda: self.app.is_running() is False)
lib.utils.check(lambda: self.app.is_running() is False)
def testShowPerformance(self):
domid = "1"
self.app.open(extra_opts=["--show-domain-performance", domid])
uiutils.check(lambda: "test on" in self.app.topwin.name)
lib.utils.check(lambda: "test on" in self.app.topwin.name)
cpulabel = self.app.topwin.find_fuzzy("CPU usage", "label")
uiutils.check(lambda: cpulabel.showing)
lib.utils.check(lambda: cpulabel.showing)
def testShowConsole(self):
# UUID of test-clone-simple
uuid = "12345678-1234-ffff-1234-12345678ffff"
self.app.open(extra_opts=["--show-domain-console", uuid])
uiutils.check(lambda: "test-clone-simple on" in self.app.topwin.name)
lib.utils.check(lambda: "test-clone-simple on" in self.app.topwin.name)
rlabel = self.app.topwin.find_fuzzy("Guest is not running", "label")
uiutils.check(lambda: rlabel.showing)
lib.utils.check(lambda: rlabel.showing)
addhw = self.app.topwin.find_fuzzy("add-hardware", "button")
uiutils.check(lambda: not addhw.showing)
lib.utils.check(lambda: not addhw.showing)
def testShowDelete(self):
self.app.open(
@ -70,10 +70,10 @@ class VMMCLI(uiutils.UITestCase):
delete = self.app.topwin
delete.find_fuzzy("Delete", "button").click()
self._click_alert_button("Are you sure", "Yes")
self.app.click_alert_button("Are you sure", "Yes")
# Ensure app exits
uiutils.check(lambda: not self.app.is_running())
lib.utils.check(lambda: not self.app.is_running())
def testShowRemoteDBusConnect(self):
@ -81,18 +81,17 @@ class VMMCLI(uiutils.UITestCase):
Test the remote app dbus connection
"""
self.app.open()
uiutils.check(lambda: "testdriver" in self.app.topwin.fmt_nodes())
uiutils.check(lambda: "test default" not in self.app.topwin.fmt_nodes())
lib.utils.check(lambda: "testdriver" in self.app.topwin.fmt_nodes())
lib.utils.check(lambda: "test default" not in self.app.topwin.fmt_nodes())
def _run_remote(opts):
newapp = uiutils.VMMDogtailApp("test:///default")
newapp = lib.app.VMMDogtailApp("test:///default")
newapp.open(check_already_running=False,
extra_opts=opts)
uiutils.check(lambda: not newapp.is_running())
import dogtail.tree
vapps = [a for a in dogtail.tree.root.applications() if
lib.utils.check(lambda: not newapp.is_running())
vapps = [a for a in newapp.tree.root.applications() if
a.name == "virt-manager"]
uiutils.check(lambda: len(vapps) == 1)
lib.utils.check(lambda: len(vapps) == 1)
# Ensure connection showed up
self.app.topwin.find("test default", "table cell")
@ -104,19 +103,19 @@ class VMMCLI(uiutils.UITestCase):
def testShowCLIError(self):
# Unknown option
self.app.open(extra_opts=["--idontexist"])
self._click_alert_button("Unhandled command line", "Close")
uiutils.check(lambda: not self.app.is_running())
self.app.click_alert_button("Unhandled command line", "Close")
lib.utils.check(lambda: not self.app.is_running())
# Missing VM
self.app.open(extra_opts=["--show-domain-delete", "IDONTEXIST"])
self._click_alert_button("does not have VM", "Close")
uiutils.check(lambda: not self.app.is_running())
self.app.click_alert_button("does not have VM", "Close")
lib.utils.check(lambda: not self.app.is_running())
# Bad URI
baduri = "fribfrobfroo"
self.app = uiutils.VMMDogtailApp(baduri)
self._click_alert_button(baduri, "Close")
uiutils.check(lambda: not self.app.is_running())
self.app = lib.app.VMMDogtailApp(baduri)
self.app.click_alert_button(baduri, "Close")
lib.utils.check(lambda: not self.app.is_running())
def testCLIFirstRunURIGood(self):
# Emulate first run with a URI that will succeed
@ -127,43 +126,43 @@ class VMMCLI(uiutils.UITestCase):
# Emulate first run with a URI that will succeed
self.app.open(use_uri=False, firstrun_uri="bad:///uri")
self.app.topwin.find("bad uri", "table cell")
self._click_alert_button("bad:///uri", "Close")
self.app.click_alert_button("bad:///uri", "Close")
def testCLITraceLibvirt(self):
# 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)
self.app.sleep(2)
lib.utils.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)
self.app.sleep(2)
# Give it a little time to work
uiutils.check(lambda: self.app.topwin.active)
lib.utils.check(lambda: self.app.topwin.active)
self.app.topwin.keyCombo("<alt>F4")
def testCLINoFirstRun(self):
# Test a simple case of loading without any config override
self.app.open(first_run=False, enable_libguestfs=None, use_uri=False)
self.sleep(2)
uiutils.check(lambda: self.app.topwin.showing)
self.app.sleep(2)
lib.utils.check(lambda: self.app.topwin.showing)
def testCLINoFork(self):
# Test app without forking
self.app.open(first_run=False, enable_libguestfs=None,
use_uri=False, no_fork=False)
assert self.app.wait_for_exit() is True
uiutils.check(lambda: self.app.topwin.showing)
lib.utils.check(lambda: self.app.topwin.showing)
self.app.topwin.keyCombo("<alt>F4")
def testCLIGTKArgs(self):
# Ensure gtk arg passthrough works
self.app.open(extra_opts=["--gtk-debug=misc"])
uiutils.check(lambda: self.app.topwin.showing)
lib.utils.check(lambda: self.app.topwin.showing)
self.app.topwin.keyCombo("<alt>F4")
@unittest.mock.patch.dict('os.environ', {"DISPLAY": ""})

View File

@ -3,8 +3,8 @@
import os
from tests import utils
from tests.uitests import utils as uiutils
import tests.utils
from . import lib
class _CloneRow:
@ -21,13 +21,13 @@ class _CloneRow:
self.is_clone_requested = not self.is_share_requested
def check_in_text(self, substr):
uiutils.check(lambda: substr in self.txtcell.text)
lib.utils.check(lambda: substr in self.txtcell.text)
def select(self):
self.txtcell.click()
class CloneVM(uiutils.UITestCase):
class CloneVM(lib.testcase.UITestCase):
"""
UI tests for virt-manager's CloneVM wizard
"""
@ -42,7 +42,7 @@ class CloneVM(uiutils.UITestCase):
c.click(button=3)
item = self.app.root.find("Clone...", "menu item")
item.point()
self.sleep(.5)
self.app.sleep(.5)
item.click()
return self.app.root.find("Clone Virtual Machine", "frame")
@ -69,14 +69,14 @@ class CloneVM(uiutils.UITestCase):
def testCloneSimple(self):
# Disable predictable so UUID generation doesn't collide
uri = utils.URIs.test_full.replace(",predictable", "")
uri = tests.utils.URIs.test_full.replace(",predictable", "")
self.app.uri = uri
# Clone 'test-clone-simple' which is the most basic case
# Cancel, and reopen
win = self._open_window("test-clone-simple")
win.find("Cancel", "push button").click()
uiutils.check(lambda: not win.showing)
lib.utils.check(lambda: not win.showing)
# Do default clone
win = self._open_window("test-clone-simple")
@ -86,7 +86,7 @@ class CloneVM(uiutils.UITestCase):
rows[0].check_in_text("test-clone-simple.img")
win.find("Clone", "push button").click()
uiutils.check(lambda: not win.showing)
lib.utils.check(lambda: not win.showing)
# Check path was generated correctly
win = self._open_window("test-clone-simple-clone")
@ -100,11 +100,11 @@ class CloneVM(uiutils.UITestCase):
rows[0].check_in_text("Share disk with")
# Do 'cancel' first
win.find("Clone", "push button").click()
self._click_alert_button("cause data to be overwritten", "Cancel")
uiutils.check(lambda: win.active)
self.app.click_alert_button("cause data to be overwritten", "Cancel")
lib.utils.check(lambda: win.active)
win.find("Clone", "push button").click()
self._click_alert_button("cause data to be overwritten", "OK")
uiutils.check(lambda: not win.active)
self.app.click_alert_button("cause data to be overwritten", "OK")
lib.utils.check(lambda: not win.active)
# Verify the new VM shared storage
win = self._open_window("test-clone-simple-clone1")
@ -116,7 +116,7 @@ class CloneVM(uiutils.UITestCase):
# Clone 'test-clone', check some results, make sure clone works
win = self._open_window("test-clone\n")
win.find("Clone", "push button").click()
uiutils.check(lambda: not win.showing)
lib.utils.check(lambda: not win.showing)
self.app.topwin.find("test-clone1", "table cell")
# Check test-many-devices which will not work, but confirm
@ -124,17 +124,17 @@ class CloneVM(uiutils.UITestCase):
self.app.topwin.find("test-many-devices").click()
sbutton = self.app.topwin.find("Shut Down", "push button")
sbutton.click()
uiutils.check(lambda: not sbutton.sensitive)
self.sleep(.5)
lib.utils.check(lambda: not sbutton.sensitive)
self.app.sleep(.5)
win = self._open_window("test-many-devices")
win.find("Clone", "push button").click()
self._click_alert_button("No such file or", "Close")
self.app.click_alert_button("No such file or", "Close")
win.keyCombo("<alt>F4")
uiutils.check(lambda: not win.showing)
lib.utils.check(lambda: not win.showing)
def testCloneStorageChange(self):
# Disable predictable so UUID generation doesn't collide
uri = utils.URIs.test_full.replace(",predictable", "")
uri = tests.utils.URIs.test_full.replace(",predictable", "")
self.app.uri = uri
# Trigger some error handling scenarios
@ -142,7 +142,7 @@ class CloneVM(uiutils.UITestCase):
newname = "test-aaabbb"
win.find("Name:", "text").set_text(newname)
win.find("Clone", "push button").click()
uiutils.check(lambda: not win.showing)
lib.utils.check(lambda: not win.showing)
win = self._open_window(newname)
row = self._get_all_rows(win)[0]
@ -155,43 +155,43 @@ class CloneVM(uiutils.UITestCase):
win.find("Details", "push button").click()
stgwin = self.app.root.find("Change storage path", "dialog")
pathtxt = stgwin.find(None, "text", "New Path:")
uiutils.check(lambda: newname in pathtxt.text)
lib.utils.check(lambda: newname in pathtxt.text)
stgwin.find("Browse", "push button").click()
self._select_storagebrowser_volume("default-pool", "iso-vol")
uiutils.check(lambda: "iso-vol" in pathtxt.text)
self.app.select_storagebrowser_volume("default-pool", "iso-vol")
lib.utils.check(lambda: "iso-vol" in pathtxt.text)
stgwin.find("OK").click()
self._click_alert_button("overwrite the existing", "No")
uiutils.check(lambda: stgwin.showing)
self.app.click_alert_button("overwrite the existing", "No")
lib.utils.check(lambda: stgwin.showing)
stgwin.find("OK").click()
self._click_alert_button("overwrite the existing", "Yes")
uiutils.check(lambda: not stgwin.showing)
self.app.click_alert_button("overwrite the existing", "Yes")
lib.utils.check(lambda: not stgwin.showing)
# Can't clone onto existing storage volume
win.find("Clone", "push button").click()
self._click_alert_button(".*Clone onto existing.*", "Close")
self.app.click_alert_button(".*Clone onto existing.*", "Close")
# Reopen dialog and request to share it
win.find("Details", "push button").click()
stgwin = self.app.root.find("Change storage path", "dialog")
chkbox = stgwin.find("Create a new", "check")
uiutils.check(lambda: chkbox.checked)
lib.utils.check(lambda: chkbox.checked)
chkbox.click()
# Cancel and reopen, confirm changes didn't stick
stgwin.find("Cancel").click()
uiutils.check(lambda: not stgwin.showing)
lib.utils.check(lambda: not stgwin.showing)
win.find("Details", "push button").click()
stgwin = self.app.root.find("Change storage path", "dialog")
chkbox = stgwin.find("Create a new", "check")
uiutils.check(lambda: chkbox.checked)
lib.utils.check(lambda: chkbox.checked)
# Requesting sharing again and exit
chkbox.click()
stgwin.find("OK").click()
uiutils.check(lambda: not stgwin.active)
lib.utils.check(lambda: not stgwin.active)
# Finish install, verify storage was shared
win.find("Clone", "push button").click()
self._click_alert_button("cause data to be overwritten", "OK")
uiutils.check(lambda: not win.active)
self.app.click_alert_button("cause data to be overwritten", "OK")
lib.utils.check(lambda: not win.active)
win = self._open_window(newname)
row = self._get_all_rows(win)[0].check_in_text(oldnewname)
@ -200,8 +200,8 @@ class CloneVM(uiutils.UITestCase):
# Trigger some error handling scenarios
win = self._open_window("test-clone-full\n")
win.find("Clone", "push button").click()
self._click_alert_button("not enough free space", "Close")
uiutils.check(lambda: win.showing)
self.app.click_alert_button("not enough free space", "Close")
lib.utils.check(lambda: win.showing)
win.keyCombo("<alt>F4")
win = self._open_window("test-clone-simple")
@ -212,9 +212,9 @@ class CloneVM(uiutils.UITestCase):
rows[0].check_in_text("Share disk with")
win.find("Clone", "push button").click()
win.find("Clone", "push button").click()
self._click_alert_button("cause data to be overwritten", "OK")
self._click_alert_button(badname, "Close")
uiutils.check(lambda: win.active)
self.app.click_alert_button("cause data to be overwritten", "OK")
self.app.click_alert_button(badname, "Close")
lib.utils.check(lambda: win.active)
def testCloneNonmanaged(self):
@ -228,7 +228,7 @@ class CloneVM(uiutils.UITestCase):
self.app.open(xmleditor_enabled=True)
manager = self.app.topwin
win = self._open_details_window("test-clone-simple")
win = self.app.open_details_window("test-clone-simple")
win.find("IDE Disk 1", "table cell").click()
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
@ -238,11 +238,11 @@ class CloneVM(uiutils.UITestCase):
win.find("config-apply").click()
win.find("Details", "page tab").click()
disksrc = win.find("disk-source-path")
uiutils.check(lambda: disksrc.text == newpath)
lib.utils.check(lambda: disksrc.text == newpath)
win.keyCombo("<alt>F4")
uiutils.check(lambda: not win.active)
lib.utils.check(lambda: not win.active)
uiutils.check(lambda: manager.active)
lib.utils.check(lambda: manager.active)
win = self._open_window("test-clone-simple")
row = self._get_all_rows(win)[0]
row.check_in_text(tmpsrc.name)
@ -255,7 +255,7 @@ class CloneVM(uiutils.UITestCase):
pathtxt.set_text(tmpdst.name)
stgwin.find("OK").click()
win.find("Clone", "push button").click()
uiutils.check(lambda: not win.active)
uiutils.check(lambda: os.path.exists(tmpdst.name))
lib.utils.check(lambda: not win.active)
lib.utils.check(lambda: os.path.exists(tmpdst.name))
assert open(tmpsrc.name).read() == open(tmpdst.name).read()

View File

@ -1,10 +1,10 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests.uitests import utils as uiutils
from . import lib
class UITestConnection(uiutils.UITestCase):
class UITestConnection(lib.testcase.UITestCase):
"""
UI tests for various connection.py related bits
"""
@ -27,16 +27,16 @@ class UITestConnection(uiutils.UITestCase):
delete = self.app.root.find_fuzzy("Delete", "frame")
delete.find("Delete associated", "check box").click()
delete.find("Delete", "push button").click()
uiutils.check(lambda: cell.dead)
uiutils.check(lambda: manager.active)
lib.utils.check(lambda: cell.dead)
lib.utils.check(lambda: manager.active)
uiutils.check(
lib.utils.check(
lambda: "test-many-devices" not in self.app.topwin.fmt_nodes())
_delete_vm("test-arm-kernel")
_delete_vm("test alternate")
_delete_vm("test-clone-simple")
self.sleep(.5)
uiutils.check(
self.app.sleep(.5)
lib.utils.check(
lambda: "test-many-devices" not in self.app.topwin.fmt_nodes())
def testConnectionConnCrash(self):
@ -44,17 +44,17 @@ class UITestConnection(uiutils.UITestCase):
extra_opts=["--test-options=conn-crash"])
manager = self.app.topwin
self.sleep(1)
self.app.sleep(1)
manager.find(r"^test testdriver.xml - Not Connected", "table cell")
uiutils.check(lambda: manager.active)
lib.utils.check(lambda: manager.active)
def testConnectionFakeEvents(self):
self.app.open(
extra_opts=["--test-options=fake-nodedev-event=computer",
"--test-options=fake-agent-event=test-many-devices"])
manager = self.app.topwin
self.sleep(2.5)
uiutils.check(lambda: manager.active)
self.app.sleep(2.5)
lib.utils.check(lambda: manager.active)
def testConnectionOpenauth(self):
self.app.open(
@ -67,14 +67,14 @@ class UITestConnection(uiutils.UITestCase):
password = dialog.find("Password:.*entry")
username.click()
username.text = "foo"
self.pressKey("Enter")
uiutils.check(lambda: password.focused)
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: password.focused)
password.typeText("bar")
_run()
dialog.find("OK", "push button").click()
uiutils.check(lambda: not dialog.showing)
lib.utils.check(lambda: not dialog.showing)
manager = self.app.root.find("Virtual Machine Manager", "frame")
manager.find("^test testdriver.xml$", "table cell")
@ -94,19 +94,19 @@ class UITestConnection(uiutils.UITestCase):
_retrigger_connection()
dialog = self.app.root.find("Authentication required")
_run()
self.pressKey("Enter")
uiutils.check(lambda: not dialog.showing)
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: not dialog.showing)
manager = self.app.root.find("Virtual Machine Manager", "frame")
manager.find("^test testdriver.xml$", "table cell")
_retrigger_connection()
dialog = self.app.root.find("Authentication required")
dialog.find("Cancel", "push button").click()
uiutils.check(lambda: not dialog.showing)
self._click_alert_button("Unable to connect", "Close")
lib.utils.check(lambda: not dialog.showing)
self.app.click_alert_button("Unable to connect", "Close")
manager.find("test testdriver.xml - Not Connected", "table cell")
def testConnectionSessionError(self):
self.app.open(
extra_opts=["--test-options=fake-session-error"])
self._click_alert_button("Could not detect a local session", "Close")
self.app.click_alert_button("Could not detect a local session", "Close")

View File

@ -1,10 +1,10 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests.uitests import utils as uiutils
from . import lib
class VMMConnect(uiutils.UITestCase):
class VMMConnect(lib.testcase.UITestCase):
"""
UI tests for the 'open connection' dialog
"""
@ -18,15 +18,15 @@ class VMMConnect(uiutils.UITestCase):
c = self.app.root.find("test testdriver.xml", "table cell")
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
uiutils.check(lambda: "Not Connected" in c.text)
lib.utils.check(lambda: "Not Connected" in c.text)
c.click(button=3)
self.app.root.find("conn-delete", "menu item").click()
self._click_alert_button("will remove the connection", "No")
uiutils.check(lambda: not c.dead)
self.app.click_alert_button("will remove the connection", "No")
lib.utils.check(lambda: not c.dead)
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)
self.app.click_alert_button("will remove the connection", "Yes")
lib.utils.check(lambda: c.dead)
# Launch the dialog, grab some UI pointers
self.app.root.find("File", "menu").click()
@ -39,7 +39,7 @@ class VMMConnect(uiutils.UITestCase):
host = win.find("Hostname", "text")
urilabel = win.find("uri-label", "label")
urientry = win.find("uri-entry", "text")
uiutils.check(lambda: user.showing is host.showing is True)
lib.utils.check(lambda: user.showing is host.showing is True)
# Select all HV options
win.combo_select("Hypervisor", "QEMU/KVM user session")
@ -51,26 +51,26 @@ class VMMConnect(uiutils.UITestCase):
# Test a simple selection
win.combo_select("Hypervisor", "QEMU/KVM user session")
uiutils.check(lambda: user.showing is host.showing is False)
uiutils.check(lambda: urilabel.text == "qemu:///session")
lib.utils.check(lambda: user.showing is host.showing is False)
lib.utils.check(lambda: urilabel.text == "qemu:///session")
# Cancel the dialog
win.find_fuzzy("Cancel", "push button").click()
uiutils.check(lambda: not win.showing)
lib.utils.check(lambda: not win.showing)
# Reopen it, confirm content changed
self.app.root.find("File", "menu").click()
self.app.root.find("Add Connection...", "menu item").click()
win = self.app.root.find_fuzzy("Add Connection", "dialog")
uiutils.check(lambda: ":///session" not in urilabel.text)
lib.utils.check(lambda: ":///session" not in urilabel.text)
# Relaunch the dialog, confirm it doesn't overwrite content
win.combo_select("Hypervisor", ".*LXC.*")
uiutils.check(lambda: "lxc" in urilabel.text)
lib.utils.check(lambda: "lxc" in urilabel.text)
self.app.root.find("File", "menu").click()
self.app.root.find("Add Connection...", "menu item").click()
uiutils.check(lambda: win.active)
uiutils.check(lambda: "lxc" in urilabel.text)
lib.utils.check(lambda: win.active)
lib.utils.check(lambda: "lxc" in urilabel.text)
# Enter a failing URI, make sure error is raised, and we can
# fall back to the dialog
@ -78,34 +78,34 @@ class VMMConnect(uiutils.UITestCase):
remote.click()
user.set_text("fribuser")
connect.click()
self._click_alert_button("hostname is required", "OK")
self.app.click_alert_button("hostname is required", "OK")
fakeipv6 = "fe80::1"
host.set_text(fakeipv6)
uiutils.check(lambda: urilabel.text == "xen+ssh://fribuser@[%s]/" % fakeipv6)
lib.utils.check(lambda: urilabel.text == "xen+ssh://fribuser@[%s]/" % fakeipv6)
fakehost = "ix8khfyidontexistkdjur.com"
host.set_text(fakehost + ":12345")
uiutils.check(lambda: urilabel.text == "xen+ssh://fribuser@%s:12345/" % fakehost)
lib.utils.check(lambda: urilabel.text == "xen+ssh://fribuser@%s:12345/" % fakehost)
connect.click()
uiutils.check(lambda: win.showing is True)
lib.utils.check(lambda: win.showing is True)
c = self.app.root.find_fuzzy(fakehost, "table cell")
uiutils.check(lambda: "Connecting..." not in c.text, timeout=10)
self._click_alert_button("Unable to connect", "No")
lib.utils.check(lambda: "Connecting..." not in c.text, timeout=10)
self.app.click_alert_button("Unable to connect", "No")
# Ensure dialog shows old contents for editing
uiutils.check(lambda: win.showing)
uiutils.check(lambda: fakehost in host.text)
lib.utils.check(lambda: win.showing)
lib.utils.check(lambda: fakehost in host.text)
# This time say 'yes'
connect.click()
uiutils.check(lambda: win.showing is True)
lib.utils.check(lambda: win.showing is True)
c = self.app.root.find_fuzzy(fakehost, "table cell")
uiutils.check(lambda: "Connecting..." not in c.text, timeout=10)
self._click_alert_button("Unable to connect", "Yes")
lib.utils.check(lambda: "Connecting..." not in c.text, timeout=10)
self.app.click_alert_button("Unable to connect", "Yes")
c = self.app.root.find_fuzzy(fakehost, "table cell")
# Test with custom test:///default connection
uiutils.check(lambda: win.showing is False)
lib.utils.check(lambda: win.showing is False)
self.app.root.find("File", "menu").click()
self.app.root.find("Add Connection...", "menu item").click()
win = self.app.root.find_fuzzy("Add Connection", "dialog")
@ -114,7 +114,7 @@ class VMMConnect(uiutils.UITestCase):
connect.click()
# Do it again to make sure things don't explode
uiutils.check(lambda: win.showing is False)
lib.utils.check(lambda: win.showing is False)
self.app.root.find("File", "menu").click()
self.app.root.find("Add Connection...", "menu item").click()
win = self.app.root.find_fuzzy("Add Connection", "dialog")
@ -123,25 +123,25 @@ class VMMConnect(uiutils.UITestCase):
connect.click()
# Try various connect/disconnect routines
uiutils.check(lambda: win.showing is False)
lib.utils.check(lambda: win.showing is False)
c = self.app.root.find("test default", "table cell")
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
uiutils.check(lambda: "Not Connected" in c.text)
lib.utils.check(lambda: "Not Connected" in c.text)
c.click(button=3)
self.app.root.find("conn-connect", "menu item").click()
c = self.app.root.find("test default", "table cell")
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
uiutils.check(lambda: "Not Connected" in c.text)
lib.utils.check(lambda: "Not Connected" in c.text)
c.doubleClick()
c = self.app.root.find("test default", "table cell")
c.click()
# Delete it
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
uiutils.check(lambda: "Not Connected" in c.text)
lib.utils.check(lambda: "Not Connected" in c.text)
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)
self.app.click_alert_button("will remove the connection", "Yes")
lib.utils.check(lambda: c.dead)

View File

@ -1,10 +1,10 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests.uitests import utils as uiutils
from . import lib
class CreateNet(uiutils.UITestCase):
class CreateNet(lib.testcase.UITestCase):
"""
UI tests for the createnet wizard
"""
@ -24,20 +24,20 @@ class CreateNet(uiutils.UITestCase):
"""
Basic test with object state management afterwards
"""
hostwin = self._open_host_window("Virtual Networks")
hostwin = self.app.open_host_window("Virtual Networks")
win = self._open_create_win(hostwin)
# Create a simple default network
name = win.find("Name:", "text")
finish = win.find("Finish", "push button")
uiutils.check(lambda: name.text == "network")
lib.utils.check(lambda: name.text == "network")
newname = "a-test-new-net"
name.set_text(newname)
finish.click()
# Select the new network in the host window, then do
# stop->start->stop->delete, for lifecycle testing
uiutils.check(lambda: hostwin.active)
lib.utils.check(lambda: hostwin.active)
cell = hostwin.find(newname, "table cell")
delete = hostwin.find("net-delete", "push button")
start = hostwin.find("net-start", "push button")
@ -45,20 +45,20 @@ class CreateNet(uiutils.UITestCase):
cell.click()
stop.click()
uiutils.check(lambda: start.sensitive)
lib.utils.check(lambda: start.sensitive)
start.click()
uiutils.check(lambda: stop.sensitive)
lib.utils.check(lambda: stop.sensitive)
stop.click()
uiutils.check(lambda: delete.sensitive)
lib.utils.check(lambda: delete.sensitive)
# Delete it, clicking No first
delete.click()
self._click_alert_button("permanently delete the network", "No")
uiutils.check(lambda: not cell.dead)
self.app.click_alert_button("permanently delete the network", "No")
lib.utils.check(lambda: not cell.dead)
delete.click()
self._click_alert_button("permanently delete the network", "Yes")
self.app.click_alert_button("permanently delete the network", "Yes")
# Ensure it's gone
uiutils.check(lambda: cell.dead)
lib.utils.check(lambda: cell.dead)
def testCreateNetXMLEditor(self):
@ -66,7 +66,7 @@ class CreateNet(uiutils.UITestCase):
Test the XML editor
"""
self.app.open(xmleditor_enabled=True)
hostwin = self._open_host_window("Virtual Networks")
hostwin = self.app.open_host_window("Virtual Networks")
win = self._open_create_win(hostwin)
name = win.find("Name:", "text")
finish = win.find("Finish", "push button")
@ -80,20 +80,20 @@ class CreateNet(uiutils.UITestCase):
newtext = xmleditor.text.replace(">%s<" % tmpname, ">%s<" % newname)
xmleditor.set_text(newtext)
finish.click()
uiutils.check(lambda: hostwin.active)
lib.utils.check(lambda: hostwin.active)
cell = hostwin.find(newname, "table cell")
cell.click()
# Do standard xmleditor tests
win = self._open_create_win(hostwin)
self._test_xmleditor_interactions(win, finish)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
win.find("Cancel", "push button").click()
uiutils.check(lambda: not win.visible)
lib.utils.check(lambda: not win.visible)
# Ensure host window closes fine
hostwin.click()
hostwin.keyCombo("<ctrl>w")
uiutils.check(lambda: not hostwin.showing and
lib.utils.check(lambda: not hostwin.showing and
not hostwin.active)
def testCreateNetMulti(self):
@ -101,7 +101,7 @@ class CreateNet(uiutils.UITestCase):
Test remaining create options
"""
self.app.uri = "test:///default"
hostwin = self._open_host_window(
hostwin = self.app.open_host_window(
"Virtual Networks", conn_label="test default")
win = self._open_create_win(hostwin)
finish = win.find("Finish", "push button")
@ -114,8 +114,8 @@ class CreateNet(uiutils.UITestCase):
win.find("ipv4-network").set_text("192.168.100.0/25")
ipv4start = win.find("ipv4-start")
ipv4end = win.find("ipv4-end")
uiutils.check(lambda: ipv4start.text == "192.168.100.64")
uiutils.check(lambda: ipv4end.text == "192.168.100.126")
lib.utils.check(lambda: ipv4start.text == "192.168.100.64")
lib.utils.check(lambda: ipv4end.text == "192.168.100.126")
win.find("Enable DHCPv4").click()
win.find("Enable IPv4").click()
win.find("IPv6 configuration").click_expander()
@ -129,23 +129,23 @@ class CreateNet(uiutils.UITestCase):
win.find("domain-custom").set_text("mydomain")
finish.click()
# Name collision validation
self._click_alert_button("in use by another network", "Close")
self.app.click_alert_button("in use by another network", "Close")
win.find("Name:", "text").set_text("newnet1")
finish.click()
# XML define error
self._click_alert_button("Error creating virtual network", "Close")
self.app.click_alert_button("Error creating virtual network", "Close")
win.find("ipv6-end").set_text("fd00:beef:10:6::1:f1")
finish.click()
uiutils.check(lambda: hostwin.active)
lib.utils.check(lambda: hostwin.active)
# More option work
win = self._open_create_win(hostwin)
win.find("Name:", "text").set_text("newnet2")
devicelist = win.find("net-devicelist")
uiutils.check(lambda: not devicelist.visible)
lib.utils.check(lambda: not devicelist.visible)
win.find("net-mode").click()
win.find("SR-IOV", "menu item").click()
uiutils.check(lambda: devicelist.visible)
lib.utils.check(lambda: devicelist.visible)
# Just confirm this is here
win.find("No available device", "menu item")
win.find("net-mode").click()
@ -154,14 +154,14 @@ class CreateNet(uiutils.UITestCase):
win.find("Physical device", "menu item").click()
win.find("net-device").set_text("fakedev0")
finish.click()
uiutils.check(lambda: hostwin.active)
lib.utils.check(lambda: hostwin.active)
def testCreateNetSRIOV(self):
"""
We need the full URI to test the SRIOV method
"""
self.app.open(xmleditor_enabled=True)
hostwin = self._open_host_window("Virtual Networks")
hostwin = self.app.open_host_window("Virtual Networks")
win = self._open_create_win(hostwin)
finish = win.find("Finish", "push button")

View File

@ -1,10 +1,10 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests.uitests import utils as uiutils
from . import lib
class CreatePool(uiutils.UITestCase):
class CreatePool(lib.testcase.UITestCase):
"""
UI tests for the createpool wizard
"""
@ -13,7 +13,7 @@ class CreatePool(uiutils.UITestCase):
hostwin.find("pool-add", "push button").click()
win = self.app.root.find(
"Add a New Storage Pool", "frame")
uiutils.check(lambda: win.active)
lib.utils.check(lambda: win.active)
return win
@ -22,7 +22,7 @@ class CreatePool(uiutils.UITestCase):
##############
def testCreatePools(self):
hostwin = self._open_host_window("Storage")
hostwin = self.app.open_host_window("Storage")
win = self._open_create_win(hostwin)
finish = win.find("Finish", "push button")
name = win.find("Name:", "text")
@ -32,20 +32,20 @@ class CreatePool(uiutils.UITestCase):
# Enter the filename and select it
chooser.find(usepath, "table cell").click()
obutton = chooser.find("Open", "push button")
uiutils.check(lambda: obutton.sensitive)
lib.utils.check(lambda: obutton.sensitive)
obutton.click()
uiutils.check(lambda: not chooser.showing)
uiutils.check(lambda: win.active)
lib.utils.check(lambda: not chooser.showing)
lib.utils.check(lambda: win.active)
# Create a simple default dir pool
uiutils.check(lambda: name.text == "pool")
lib.utils.check(lambda: name.text == "pool")
newname = "a-test-new-pool"
name.set_text(newname)
finish.click()
# Select the new object in the host window, then do
# stop->start->stop->delete, for lifecycle testing
uiutils.check(lambda: hostwin.active)
lib.utils.check(lambda: hostwin.active)
cell = hostwin.find(newname, "table cell")
delete = hostwin.find("pool-delete", "push button")
start = hostwin.find("pool-start", "push button")
@ -53,20 +53,20 @@ class CreatePool(uiutils.UITestCase):
cell.click()
stop.click()
uiutils.check(lambda: start.sensitive)
lib.utils.check(lambda: start.sensitive)
start.click()
uiutils.check(lambda: stop.sensitive)
lib.utils.check(lambda: stop.sensitive)
stop.click()
uiutils.check(lambda: delete.sensitive)
lib.utils.check(lambda: delete.sensitive)
# Delete it, clicking 'No' first
delete.click()
self._click_alert_button("permanently delete the pool", "No")
uiutils.check(lambda: not cell.dead)
self.app.click_alert_button("permanently delete the pool", "No")
lib.utils.check(lambda: not cell.dead)
delete.click()
self._click_alert_button("permanently delete the pool", "Yes")
self.app.click_alert_button("permanently delete the pool", "Yes")
# Ensure it's gone
uiutils.check(lambda: cell.dead)
lib.utils.check(lambda: cell.dead)
# Test a disk pool
win = self._open_create_win(hostwin)
@ -87,7 +87,7 @@ class CreatePool(uiutils.UITestCase):
_browse_local_path("Choose target directory", "by-path")
finish.click()
# Catch example error
self._click_alert_button("source host name", "Close")
self.app.click_alert_button("source host name", "Close")
win.find("Host Name:", "text").set_text("example.com")
win.find("pool-source-path-text").set_text("foo-iqn")
win.find_fuzzy("Initiator IQN:", "check").click()
@ -123,19 +123,19 @@ class CreatePool(uiutils.UITestCase):
win.find_fuzzy("Host Name:", "text").set_text("example.com:1234")
win.find_fuzzy("pool-source-name-text", "text").typeText("frob")
finish.click()
uiutils.check(lambda: not win.showing)
uiutils.check(lambda: hostwin.active)
lib.utils.check(lambda: not win.showing)
lib.utils.check(lambda: hostwin.active)
hostwin.find(newname, "table cell")
# Ensure host window closes fine
hostwin.click()
hostwin.keyCombo("<ctrl>w")
uiutils.check(lambda: not hostwin.showing)
lib.utils.check(lambda: not hostwin.showing)
def testCreatePoolXMLEditor(self):
self.app.open(xmleditor_enabled=True)
hostwin = self._open_host_window("Storage")
hostwin = self.app.open_host_window("Storage")
win = self._open_create_win(hostwin)
finish = win.find("Finish", "push button")
name = win.find("Name:", "text")
@ -149,12 +149,12 @@ class CreatePool(uiutils.UITestCase):
newtext = xmleditor.text.replace(">%s<" % tmpname, ">%s<" % newname)
xmleditor.set_text(newtext)
finish.click()
uiutils.check(lambda: hostwin.active)
lib.utils.check(lambda: hostwin.active)
cell = hostwin.find(newname, "table cell")
cell.click()
# Do standard xmleditor tests
win = self._open_create_win(hostwin)
self._test_xmleditor_interactions(win, finish)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
win.find("Cancel", "push button").click()
uiutils.check(lambda: not win.visible)
lib.utils.check(lambda: not win.visible)

View File

@ -4,11 +4,11 @@
import unittest.mock
import tests
from tests.uitests import utils as uiutils
from . import lib
class NewVM(uiutils.UITestCase):
class NewVM(lib.testcase.UITestCase):
"""
UI tests for virt-manager's NewVM wizard
"""
@ -27,14 +27,14 @@ class NewVM(uiutils.UITestCase):
oldtext = pagenumlabel.text
newvm.find_fuzzy("Forward", "button").click()
if check:
uiutils.check(lambda: pagenumlabel.text != oldtext)
lib.utils.check(lambda: pagenumlabel.text != oldtext)
def back(self, newvm, check=True):
pagenumlabel = newvm.find("pagenum-label")
oldtext = pagenumlabel.text
newvm.find_fuzzy("Back", "button").click()
if check:
uiutils.check(lambda: pagenumlabel.text != oldtext)
lib.utils.check(lambda: pagenumlabel.text != oldtext)
##############
@ -60,14 +60,14 @@ class NewVM(uiutils.UITestCase):
c.click()
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
uiutils.check(lambda: "Not Connected" in c.text)
lib.utils.check(lambda: "Not Connected" in c.text)
# Check the dialog shows 'no connection' error
_stop_conn("test testdriver.xml")
newvm = self._open_create_wizard()
newvm.find_fuzzy("No active connection to install on")
newvm.keyCombo("<alt>F4")
uiutils.check(lambda: manager.active)
lib.utils.check(lambda: manager.active)
# Check the xen PV only startup warning
def _capsopt(fname):
@ -106,7 +106,7 @@ class NewVM(uiutils.UITestCase):
entry.click()
# Launch this so we can verify storage browser is reset too
newvm.find_fuzzy("install-iso-browse", "button").click()
self._select_storagebrowser_volume("default-pool", "iso-vol")
self.app.select_storagebrowser_volume("default-pool", "iso-vol")
newvm.find_fuzzy("Automatically detect", "check").click()
newvm.find("oslist-entry").set_text("generic")
newvm.find("oslist-popover").find_fuzzy("generic").click()
@ -119,10 +119,10 @@ class NewVM(uiutils.UITestCase):
newvm.combo_select("create-conn", ".*test default.*")
self.forward(newvm)
cdrom.click_combo_entry()
uiutils.check(lambda: "/dev/sr1" not in cdrom.fmt_nodes())
lib.utils.check(lambda: "/dev/sr1" not in cdrom.fmt_nodes())
newvm.find_fuzzy("install-iso-browse", "button").click()
browsewin = self.app.root.find("vmm-storage-browser")
uiutils.check(lambda: "disk-pool" not in browsewin.fmt_nodes())
lib.utils.check(lambda: "disk-pool" not in browsewin.fmt_nodes())
def testNewVMManualDefault(self):
"""
@ -134,37 +134,37 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Manual", "radio").click()
self.forward(newvm)
osentry = newvm.find("oslist-entry")
uiutils.check(lambda: not osentry.text)
lib.utils.check(lambda: not osentry.text)
# Make sure we throw an error if no OS selected
self.forward(newvm, check=False)
self._click_alert_button("You must select", "OK")
self.app.click_alert_button("You must select", "OK")
# Test activating the osentry to grab the popover selection
osentry.click()
osentry.typeText("generic")
newvm.find("oslist-popover")
osentry.click()
self.pressKey("Enter")
uiutils.check(lambda: osentry.text == "Generic OS")
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: osentry.text == "Generic OS")
# Verify back+forward still keeps Generic selected
self.sleep(.5)
self.app.sleep(.5)
self.back(newvm)
self.sleep(.5)
self.app.sleep(.5)
self.forward(newvm)
self.sleep(.5)
uiutils.check(lambda: "Generic" in osentry.text)
uiutils.check(lambda: osentry.onscreen)
self.app.sleep(.5)
lib.utils.check(lambda: "Generic" in osentry.text)
lib.utils.check(lambda: osentry.onscreen)
# The sleeps shouldn't be required, but this test continues to be
# flakey, so this is an attempt to fix it.
self.forward(newvm)
self.sleep(.5)
self.app.sleep(.5)
self.forward(newvm)
self.sleep(.5)
self.app.sleep(.5)
self.forward(newvm)
self.sleep(.5)
self.app.sleep(.5)
# Empty triggers a specific codepath
@ -172,7 +172,7 @@ class NewVM(uiutils.UITestCase):
# Name collision failure
newvm.find_fuzzy("Name", "text").set_text("test-many-devices")
newvm.find_fuzzy("Finish", "button").click()
self._click_alert_button("in use", "OK")
self.app.click_alert_button("in use", "OK")
newvm.find_fuzzy("Name", "text").set_text("vm1")
newvm.find_fuzzy("Finish", "button").click()
@ -183,10 +183,10 @@ class NewVM(uiutils.UITestCase):
delete = self.app.root.find_fuzzy("Delete", "frame")
delete.find_fuzzy("Delete", "button").click()
self._click_alert_button("Are you sure", "Yes")
self.app.click_alert_button("Are you sure", "Yes")
# Verify delete dialog and VM dialog are now gone
uiutils.check(lambda: vmwindow.showing is False)
lib.utils.check(lambda: vmwindow.showing is False)
def testNewVMStorage(self):
"""
@ -205,7 +205,7 @@ class NewVM(uiutils.UITestCase):
sizetext = newvm.find(None, "spin button", "GiB")
sizetext.set_text("10000000")
self.forward(newvm, check=False)
self._click_alert_button("Storage parameter error", "OK")
self.app.click_alert_button("Storage parameter error", "OK")
sizetext.set_text("1")
# Use the storage browser to select a local file
@ -219,14 +219,14 @@ class NewVM(uiutils.UITestCase):
fname = "COPYING"
chooser.find(fname, "table cell").click()
chooser.find("Open", "push button").click()
uiutils.check(lambda: newvm.active)
uiutils.check(lambda: "COPYING" in storagetext.text)
lib.utils.check(lambda: newvm.active)
lib.utils.check(lambda: "COPYING" in storagetext.text)
# Start the install
self.forward(newvm)
newvm.find("Finish", "push button").click()
self.app.root.find_fuzzy("vm1 on", "frame")
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
def testNewVMCDROMRegular(self):
@ -250,49 +250,49 @@ class NewVM(uiutils.UITestCase):
entry.click()
entry.set_text("")
self.forward(newvm, check=False)
self._click_alert_button("media selection is required", "OK")
self.app.click_alert_button("media selection is required", "OK")
# test entry activation too
entry.click()
entry.set_text("/dev/sr0")
self.pressKey("Enter")
self.app.rawinput.pressKey("Enter")
# Select a fake iso
newvm.find_fuzzy("install-iso-browse", "button").click()
self._select_storagebrowser_volume("default-pool", "iso-vol")
self.app.select_storagebrowser_volume("default-pool", "iso-vol")
osentry = newvm.find("oslist-entry")
uiutils.check(lambda: osentry.text == "None detected")
lib.utils.check(lambda: osentry.text == "None detected")
# Change distro to win8
newvm.find_fuzzy("Automatically detect", "check").click()
osentry.click()
osentry.set_text("windows 8")
popover = newvm.find("oslist-popover")
uiutils.check(lambda: popover.onscreen)
lib.utils.check(lambda: popover.onscreen)
# Verify Escape resets the text entry
self.pressKey("Escape")
uiutils.check(lambda: not popover.onscreen)
uiutils.check(lambda: osentry.text == "")
self.app.rawinput.pressKey("Escape")
lib.utils.check(lambda: not popover.onscreen)
lib.utils.check(lambda: osentry.text == "")
# Re-enter text
osentry.set_text("windows 8")
uiutils.check(lambda: popover.onscreen)
lib.utils.check(lambda: popover.onscreen)
popover.find_fuzzy("include-eol").click()
popover.find_fuzzy(r"\(win8\)").click()
uiutils.check(lambda: not popover.onscreen)
lib.utils.check(lambda: not popover.onscreen)
foundtext = osentry.text
# Start typing again, and exit, make sure it resets to previous entry
osentry.click()
osentry.set_text("foo")
uiutils.check(lambda: popover.onscreen)
self.pressKey("Escape")
uiutils.check(lambda: not popover.onscreen)
uiutils.check(lambda: osentry.text == foundtext)
lib.utils.check(lambda: popover.onscreen)
self.app.rawinput.pressKey("Escape")
lib.utils.check(lambda: not popover.onscreen)
lib.utils.check(lambda: osentry.text == foundtext)
self.forward(newvm)
# Verify that CPU values are non-default
cpus = newvm.find("cpus", "spin button")
uiutils.check(lambda: int(cpus.text) > 1, timeout=5)
lib.utils.check(lambda: int(cpus.text) > 1, timeout=5)
self.forward(newvm)
self.forward(newvm)
@ -304,7 +304,7 @@ class NewVM(uiutils.UITestCase):
vmwindow = self.app.root.find_fuzzy("win8 on", "frame")
vmwindow.find_fuzzy("IDE CDROM", "table cell").click()
mediaent = vmwindow.find("media-entry")
uiutils.check(lambda: "iso-vol" in mediaent.text)
lib.utils.check(lambda: "iso-vol" in mediaent.text)
# Change boot autostart
vmwindow.find_fuzzy("Boot", "table cell").click()
@ -320,7 +320,7 @@ class NewVM(uiutils.UITestCase):
vmwindow.find("add-hardware", "push button").click()
addhw = self.app.root.find("Add New Virtual Hardware", "frame")
addhw.find("Finish", "push button").click()
uiutils.check(lambda: vmwindow.active)
lib.utils.check(lambda: vmwindow.active)
# Select the new disk, change the bus to USB
vmwindow.find_fuzzy("IDE Disk 2", "table cell").click()
@ -329,29 +329,29 @@ class NewVM(uiutils.UITestCase):
tab = vmwindow.find("disk-tab")
tab.find("Disk bus:", "text").set_text("usb")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Device is now 'USB Disk 1'
c = hwlist.find("USB Disk 1", "table cell")
uiutils.check(lambda: c.state_selected)
lib.utils.check(lambda: c.state_selected)
tab.find("Advanced options", "toggle button").click_expander()
tab.find("Removable:", "check box").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Change NIC mac
vmwindow.find_fuzzy("NIC", "table cell").click()
tab = vmwindow.find("network-tab")
tab.find("mac-entry", "text").set_text("00:11:00:11:00:11")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.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)
lib.utils.check(lambda: newvm.showing is False)
vmwindow = self.app.root.find_fuzzy("win8 on", "frame")
vmwindow.find_fuzzy("File", "menu").click()
vmwindow.find_fuzzy("Quit", "menu item").click()
uiutils.check(lambda: self.app.is_running())
lib.utils.check(lambda: self.app.is_running())
def testNewVMCDROMDetect(self):
"""
@ -369,7 +369,7 @@ class NewVM(uiutils.UITestCase):
self.forward(newvm)
newvm.find("Finish", "push button").click()
self.app.root.find_fuzzy("win7 on", "frame")
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
def testNewVMURL(self):
@ -383,46 +383,46 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Network Install", "radio").click()
self.forward(newvm)
osentry = newvm.find("oslist-entry")
uiutils.check(lambda: osentry.text.startswith("Waiting"))
lib.utils.check(lambda: osentry.text.startswith("Waiting"))
newvm.find("install-url-entry").set_text("")
self.forward(newvm, check=False)
self._click_alert_button("tree is required", "OK")
self.app.click_alert_button("tree is required", "OK")
url = "https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/10/Fedora/x86_64/os/"
oslabel = "Fedora 10"
newvm.find("install-url-entry").set_text(url)
newvm.find("install-url-entry").click()
self.pressKey("Enter")
self.app.rawinput.pressKey("Enter")
newvm.find("install-urlopts-expander").click_expander()
newvm.find("install-urlopts-entry").set_text("foo=bar")
uiutils.check(lambda: osentry.text == oslabel, timeout=10)
lib.utils.check(lambda: osentry.text == oslabel, timeout=10)
# Move forward, then back, ensure OS stays selected
self.forward(newvm)
self.back(newvm)
uiutils.check(lambda: osentry.text == oslabel)
lib.utils.check(lambda: osentry.text == oslabel)
# Disable autodetect, make sure OS still selected
newvm.find_fuzzy("Automatically detect", "check").click()
uiutils.check(lambda: osentry.text == oslabel)
lib.utils.check(lambda: osentry.text == oslabel)
self.forward(newvm)
self.back(newvm)
# Ensure the EOL field was selected
osentry.click()
self.pressKey("Down")
self.app.rawinput.pressKey("Down")
popover = newvm.find("oslist-popover")
uiutils.check(lambda: popover.showing)
lib.utils.check(lambda: popover.showing)
includeeol = newvm.find("include-eol", "check")
uiutils.check(lambda: includeeol.isChecked)
lib.utils.check(lambda: includeeol.isChecked)
# Re-enable autodetect, check for detecting text
newvm.find_fuzzy("Automatically detect", "check").click()
uiutils.check(lambda: not popover.showing)
uiutils.check(lambda: "Detecting" in osentry.text)
uiutils.check(lambda: osentry.text == oslabel, timeout=10)
lib.utils.check(lambda: not popover.showing)
lib.utils.check(lambda: "Detecting" in osentry.text)
lib.utils.check(lambda: osentry.text == oslabel, timeout=10)
# Progress the install
self.forward(newvm)
@ -432,10 +432,10 @@ class NewVM(uiutils.UITestCase):
progress = self.app.root.find_fuzzy(
"Creating Virtual Machine", "frame")
uiutils.check(lambda: not progress.showing, timeout=120)
lib.utils.check(lambda: not progress.showing, timeout=120)
details = self.app.root.find_fuzzy("fedora10 on", "frame")
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
# Re-run the newvm wizard, check that URL was remembered
details.keyCombo("<alt>F4")
@ -443,8 +443,8 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Network Install", "radio").click()
self.forward(newvm)
urlcombo = newvm.find("install-url-combo")
uiutils.check(lambda: urlcombo.showing)
uiutils.check(lambda: url in urlcombo.fmt_nodes())
lib.utils.check(lambda: urlcombo.showing)
lib.utils.check(lambda: url in urlcombo.fmt_nodes())
def testNewKVMQ35Tweaks(self):
"""
@ -478,36 +478,36 @@ class NewVM(uiutils.UITestCase):
# Switch i440FX and back
details.combo_select("Chipset:", "i440FX")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
details.combo_select("Chipset:", "Q35")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.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)
lib.utils.check(lambda: not appl.sensitive)
# Switch back to BIOS
details.combo_select("Firmware:", "BIOS")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Switch back to UEFI
details.combo_select("Firmware:", ".*x86_64.*")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.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)
lib.utils.check(lambda: tab.showing)
addhw.find("Finish", "push button").click()
uiutils.check(lambda: not addhw.active)
uiutils.check(lambda: details.active)
lib.utils.check(lambda: not addhw.active)
lib.utils.check(lambda: details.active)
# Finish
details.find_fuzzy("Begin Installation", "button").click()
uiutils.check(lambda: details.dead)
lib.utils.check(lambda: details.dead)
self.app.root.find_fuzzy("%s on" % vmname, "frame")
def testNewKVMQ35UEFI(self):
@ -542,7 +542,7 @@ class NewVM(uiutils.UITestCase):
# Finish
details.find_fuzzy("Begin Installation", "button").click()
uiutils.check(lambda: details.dead)
lib.utils.check(lambda: details.dead)
self.app.root.find_fuzzy("%s on" % vmname, "frame")
def testNewPPC64(self):
@ -577,32 +577,32 @@ class NewVM(uiutils.UITestCase):
tab.combo_select("machine-combo", "pseries-2.1")
appl = details.find("config-apply")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.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")
addhw.find("TPM", "table cell").click()
tab = addhw.find("tpm-tab", None)
uiutils.check(lambda: tab.showing)
lib.utils.check(lambda: tab.showing)
addhw.find("Finish", "push button").click()
uiutils.check(lambda: not addhw.active)
uiutils.check(lambda: details.active)
lib.utils.check(lambda: not addhw.active)
lib.utils.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)
lib.utils.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)
lib.utils.check(lambda: not addhw.active)
lib.utils.check(lambda: details.active)
# Finish
details.find_fuzzy("Begin Installation", "button").click()
uiutils.check(lambda: details.dead)
lib.utils.check(lambda: details.dead)
self.app.root.find_fuzzy("vm-ppc64 on", "frame")
def testNewVMAArch64UEFI(self):
@ -626,7 +626,7 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Finish", "button").click()
self.app.root.find_fuzzy("vm1 on", "frame")
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
def testNewVMArmKernel(self):
"""
@ -639,23 +639,23 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Virt Type", "combo").click()
KVM = newvm.find_fuzzy("KVM", "menu item")
TCG = newvm.find_fuzzy("TCG", "menu item")
uiutils.check(lambda: KVM.focused)
uiutils.check(lambda: TCG.showing)
self.pressKey("Esc")
lib.utils.check(lambda: KVM.focused)
lib.utils.check(lambda: TCG.showing)
self.app.rawinput.pressKey("Esc")
# Validate some initial defaults
local = newvm.find_fuzzy("Local", "radio")
uiutils.check(lambda: not local.sensitive)
lib.utils.check(lambda: not local.sensitive)
newvm.find_fuzzy("Machine Type", "combo").click()
self.sleep(.2)
self.app.sleep(.2)
newvm.find_fuzzy("canon", "menu item").click()
newvm.find_fuzzy("Machine Type", "combo").click()
self.sleep(.2)
self.app.sleep(.2)
newvm.find("virt", "menu item").click()
self.sleep(.5)
self.app.sleep(.5)
importradio = newvm.find("Import", "radio")
importradio.click()
uiutils.check(lambda: importradio.checked)
lib.utils.check(lambda: importradio.checked)
self.forward(newvm)
newvm.find("import-entry").set_text("/dev/default-pool/default-vol")
@ -666,12 +666,12 @@ class NewVM(uiutils.UITestCase):
self.forward(newvm, check=False)
# Disk collision box pops up, hit ok
self._click_alert_button("in use", "Yes")
self.app.click_alert_button("in use", "Yes")
self.forward(newvm)
newvm.find_fuzzy("Finish", "button").click()
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
self.app.root.find_fuzzy("vm1 on", "frame")
@ -689,10 +689,10 @@ class NewVM(uiutils.UITestCase):
apptext = newvm.find_fuzzy(None, "text", "application path")
apptext.set_text("")
self.forward(newvm, check=False)
self._click_alert_button("path is required", "OK")
self.app.click_alert_button("path is required", "OK")
newvm.find("install-app-browse").click()
self._select_storagebrowser_volume("default-pool", "aaa-unused.qcow2")
uiutils.check(lambda: "aaa-unused.qcow2" in apptext.text)
self.app.select_storagebrowser_volume("default-pool", "aaa-unused.qcow2")
lib.utils.check(lambda: "aaa-unused.qcow2" in apptext.text)
self.forward(newvm)
self.forward(newvm)
@ -716,11 +716,11 @@ class NewVM(uiutils.UITestCase):
tab.find("Init args:", "text").set_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)
self.app.click_alert_button("init path must be specified", "OK")
lib.utils.check(lambda: appl.sensitive)
tab.find("Init path:", "text").set_text("/some/path")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Check that addhw container options are disabled
details.find("add-hardware", "push button").click()
@ -728,14 +728,14 @@ class NewVM(uiutils.UITestCase):
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)
lib.utils.check(lambda: label.onscreen)
addhw.find("Cancel", "push button").click()
uiutils.check(lambda: not addhw.active)
uiutils.check(lambda: details.active)
lib.utils.check(lambda: not addhw.active)
lib.utils.check(lambda: details.active)
# Finish
details.find_fuzzy("Begin Installation", "button").click()
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
self.app.root.find_fuzzy("%s on" % vmname, "frame")
def testNewVMCustomizeCancel(self):
@ -757,12 +757,12 @@ class NewVM(uiutils.UITestCase):
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)
self.app.click_alert_button("abort the installation", "No")
lib.utils.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)
self.app.click_alert_button("abort the installation", "Yes")
lib.utils.check(lambda: not details.active)
lib.utils.check(lambda: not newvm.active)
def testNewVMCustomizeMisc(self):
"""
@ -792,15 +792,15 @@ class NewVM(uiutils.UITestCase):
# Trigger XML failure to hit some codepaths
nametext.set_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)
self.app.click_alert_button("unapplied changes", "Yes")
self.app.click_alert_button("name must be specified", "Close")
lib.utils.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.click_alert_button("unapplied changes", "No")
lib.utils.check(lambda: not details.showing)
lib.utils.check(lambda: not newvm.showing)
self.app.root.find_fuzzy("foonewname on", "frame")
@ -818,17 +818,17 @@ class NewVM(uiutils.UITestCase):
dirtext = newvm.find_fuzzy(None, "text", "root directory")
dirtext.set_text("")
self.forward(newvm, check=False)
self._click_alert_button("path is required", "OK")
self.app.click_alert_button("path is required", "OK")
newvm.find("install-oscontainer-browse").click()
self._select_storagebrowser_volume("default-pool", "dir-vol")
uiutils.check(lambda: "dir-vol" in dirtext.text)
self.app.select_storagebrowser_volume("default-pool", "dir-vol")
lib.utils.check(lambda: "dir-vol" in dirtext.text)
self.forward(newvm)
self.forward(newvm)
newvm.find_fuzzy("Finish", "button").click()
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
self.app.root.find_fuzzy("container1 on", "frame")
@ -848,14 +848,14 @@ class NewVM(uiutils.UITestCase):
templatetext = newvm.find_fuzzy(None, "text", "container template")
templatetext.set_text("")
self.forward(newvm, check=False)
self._click_alert_button("template name is required", "OK")
self.app.click_alert_button("template name is required", "OK")
templatetext.set_text("centos-6-x86_64")
self.forward(newvm)
self.forward(newvm)
newvm.find_fuzzy("Finish", "button").click()
self.app.root.find_fuzzy("container1 on", "frame")
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
def testNewVMContainerBootstrap(self):
@ -877,33 +877,33 @@ class NewVM(uiutils.UITestCase):
uritext = newvm.find("install-oscontainer-source-uri")
uritext.text = ""
self.forward(newvm, check=False)
self._click_alert_button("Source URL is required", "OK")
self.app.click_alert_button("Source URL is required", "OK")
uritext.text = "docker://alpine"
rootdir = newvm.find_fuzzy(None, "text", "root directory")
uiutils.check(lambda: ".local/share/libvirt" in rootdir.text)
lib.utils.check(lambda: ".local/share/libvirt" in rootdir.text)
rootdir.set_text("/dev/null")
self.forward(newvm, check=False)
self._click_alert_button("not directory", "OK")
self.app.click_alert_button("not directory", "OK")
rootdir.set_text("/root")
self.forward(newvm, check=False)
self._click_alert_button("No write permissions", "OK")
self.app.click_alert_button("No write permissions", "OK")
rootdir.set_text("/tmp")
self.forward(newvm, check=False)
self._click_alert_button("directory is not empty", "No")
self.app.click_alert_button("directory is not empty", "No")
rootdir.set_text(tmpdir.name)
newvm.find("install-oscontainer-root-passwd").set_text("foobar")
# Invalid credentials to trigger failure
newvm.find("Credentials", "toggle button").click_expander()
newvm.find("bootstrap-registry-user").set_text("foo")
self.forward(newvm, check=None)
self._click_alert_button("Please specify password", "OK")
self.app.click_alert_button("Please specify password", "OK")
newvm.find("bootstrap-registry-password").set_text("bar")
self.forward(newvm)
self.forward(newvm)
newvm.find_fuzzy("Finish", "button").click()
self._click_alert_button("virt-bootstrap did not complete", "Close")
self.app.click_alert_button("virt-bootstrap did not complete", "Close")
self.back(newvm)
self.back(newvm)
newvm.find("bootstrap-registry-user").set_text("")
@ -913,9 +913,9 @@ class NewVM(uiutils.UITestCase):
self.forward(newvm)
newvm.find_fuzzy("Finish", "button").click()
prog = self.app.root.find("Creating Virtual Machine", "frame")
uiutils.check(lambda: not prog.showing, timeout=30)
lib.utils.check(lambda: not prog.showing, timeout=30)
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
self.app.root.find_fuzzy("container1 on", "frame")
@ -939,7 +939,7 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Finish", "button").click()
self.app.root.find_fuzzy("vm1 on", "frame")
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
def testNewVMInstallFail(self):
@ -956,7 +956,7 @@ class NewVM(uiutils.UITestCase):
# '/' in name will trigger libvirt error
_newvm.find_fuzzy("Name", "text").set_text("test/bad")
_newvm.find_fuzzy("Finish", "button").click()
self._click_alert_button("Unable to complete install", "Close")
self.app.click_alert_button("Unable to complete install", "Close")
return _newvm
newvm = dofail()
@ -964,12 +964,12 @@ class NewVM(uiutils.UITestCase):
generatedpath = pathlabel.text
# Changing VM name should not generate a new path
newvm.find_fuzzy("Name", "text").set_text("test/badfoo")
uiutils.check(lambda: pathlabel.text == generatedpath)
lib.utils.check(lambda: pathlabel.text == generatedpath)
newvm.find_fuzzy("Finish", "button").click()
self._click_alert_button("Unable to complete install", "Close")
self.app.click_alert_button("Unable to complete install", "Close")
# Closing dialog should trigger storage cleanup path
newvm.find_fuzzy("Cancel", "button").click()
uiutils.check(lambda: not newvm.visible)
lib.utils.check(lambda: not newvm.visible)
# Run again
newvm = dofail()
@ -982,7 +982,7 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Finish", "button").click()
self.app.root.find_fuzzy("test-foo on", "frame")
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
def testNewVMCustomizeXMLEdit(self):
@ -999,13 +999,13 @@ class NewVM(uiutils.UITestCase):
nonexistpath = "/dev/foovmm-idontexist"
existpath = "/dev/default-pool/testvol1.img"
newvm.find("media-entry").set_text(nonexistpath)
uiutils.check(
lib.utils.check(
lambda: newvm.find("oslist-entry").text == "None detected")
newvm.find_fuzzy("Automatically detect", "check").click()
newvm.find("oslist-entry").set_text("generic")
newvm.find("oslist-popover").find_fuzzy("generic").click()
self.forward(newvm, check=False)
self._click_alert_button("Error setting installer", "OK")
self.app.click_alert_button("Error setting installer", "OK")
newvm.find("media-entry").set_text(existpath)
self.forward(newvm)
self.forward(newvm)
@ -1023,7 +1023,7 @@ class NewVM(uiutils.UITestCase):
win.find("XML", "page tab").click()
# Change the disk path via the XML editor
fname = vmname + ".qcow2"
uiutils.check(lambda: fname in xmleditor.text)
lib.utils.check(lambda: fname in xmleditor.text)
newx = xmleditor.text.replace(fname, "default-vol")
xmleditor.set_text(newx)
appl = win.find("config-apply")
@ -1031,21 +1031,21 @@ class NewVM(uiutils.UITestCase):
# 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)
lib.utils.check(lambda: not appl.sensitive)
lib.utils.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")
uiutils.check(lambda: not bootmenu.checked)
lib.utils.check(lambda: not bootmenu.checked)
win.find("XML", "page tab").click()
newtext = xmleditor.text.replace(
"<os>", "<os><bootmenu enable='yes'/>")
xmleditor.set_text(newtext)
finish.click()
win.find("Details", "page tab").click()
uiutils.check(lambda: bootmenu.checked)
lib.utils.check(lambda: bootmenu.checked)
# Change a device setting with the XML editor
win.find_fuzzy("NIC", "table cell").click()
@ -1059,7 +1059,7 @@ class NewVM(uiutils.UITestCase):
# Finish install.
win.find_fuzzy("Begin Installation", "button").click()
uiutils.check(lambda: win.dead)
lib.utils.check(lambda: win.dead)
win = self.app.root.find_fuzzy("%s on" % vmname, "frame")
win.find("Details", "radio button").click()
@ -1067,23 +1067,23 @@ class NewVM(uiutils.UITestCase):
win.find_fuzzy("Boot", "table cell").click()
tab = win.find("boot-tab")
bootmenu = tab.find("Enable boot menu", "check box")
uiutils.check(lambda: bootmenu.checked)
lib.utils.check(lambda: bootmenu.checked)
# Verify device change stuck
win.find_fuzzy("NIC", "table cell").click()
tab = win.find("network-tab")
devname = tab.find("Device name:", "text")
uiutils.check(lambda: devname.text == newbrname)
lib.utils.check(lambda: devname.text == newbrname)
# Verify install media is handled correctly after XML customize
win.find_fuzzy("IDE CDROM 1", "table cell").click()
tab = win.find("disk-tab")
mediaent = tab.find("media-entry")
uiutils.check(lambda: mediaent.text == existpath)
lib.utils.check(lambda: mediaent.text == existpath)
win.find("Shut Down", "push button").click()
run = win.find("Run", "push button")
uiutils.check(lambda: run.sensitive)
uiutils.check(lambda: mediaent.text == "")
lib.utils.check(lambda: run.sensitive)
lib.utils.check(lambda: mediaent.text == "")
# Verify default disk storage was actually created. This has some
# special handling in domain.py
@ -1104,17 +1104,17 @@ class NewVM(uiutils.UITestCase):
# Click forward, hitting missing Import path error
self.forward(newvm, check=False)
self._click_alert_button("import is required", "OK")
self.app.click_alert_button("import is required", "OK")
# Click forward, but Import path doesn't exist
importtext.set_text("/dev/default-pool/idontexist")
self.forward(newvm, check=False)
self._click_alert_button("import path must point", "OK")
self.app.click_alert_button("import path must point", "OK")
importtext.set_text("/dev/default-pool/default-vol")
# Click forward, hitting missing OS error
self.forward(newvm, check=False)
self._click_alert_button("select an OS", "OK")
self.app.click_alert_button("select an OS", "OK")
# Set OS
newvm.find("oslist-entry").set_text("generic")
@ -1122,21 +1122,21 @@ class NewVM(uiutils.UITestCase):
# Click forward, but Import path is in use, and exit
self.forward(newvm, check=False)
self._click_alert_button("in use", "No")
self.app.click_alert_button("in use", "No")
# storagebrowser bits
newvm.find("install-import-browse").click()
browsewin = self.app.root.find("vmm-storage-browser")
# Insensitive for remote connection
browselocal = browsewin.find("Browse Local")
uiutils.check(lambda: browselocal.sensitive is False)
lib.utils.check(lambda: browselocal.sensitive is False)
# Close the browser and reopen
browsewin.find("Cancel").click()
uiutils.check(lambda: not browsewin.active)
lib.utils.check(lambda: not browsewin.active)
# Reopen, select storage
newvm.find("install-import-browse").click()
self._select_storagebrowser_volume("default-pool", "bochs-vol")
uiutils.check(
self.app.select_storagebrowser_volume("default-pool", "bochs-vol")
lib.utils.check(
lambda: importtext.text == "/dev/default-pool/bochs-vol")
self.forward(newvm)
@ -1144,7 +1144,7 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Finish", "button").click()
self.app.root.find_fuzzy("vm1 on", "frame")
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
def testNewVMSession(self):
"""
@ -1164,7 +1164,7 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Finish", "button").click()
self.app.root.find_fuzzy("vm1 on", "frame")
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)
def testNewVMEmptyConn(self):
"""
@ -1182,7 +1182,7 @@ class NewVM(uiutils.UITestCase):
self.forward(newvm)
newvm.combo_check_default("net-source", "Bridge")
warnlabel = newvm.find_fuzzy("suitable default network", "label")
uiutils.check(lambda: warnlabel.onscreen)
lib.utils.check(lambda: warnlabel.onscreen)
newvm.find("Device name:", "text").set_text("foobr0")
# Select customize wizard, we will use this VM to hit specific
@ -1197,16 +1197,16 @@ class NewVM(uiutils.UITestCase):
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)
lib.utils.check(lambda: tab.showing)
cell = tab.find("No Devices", "table cell")
uiutils.check(lambda: cell.selected)
lib.utils.check(lambda: cell.selected)
addhw.find("Cancel", "push button").click()
uiutils.check(lambda: not addhw.active)
uiutils.check(lambda: details.active)
lib.utils.check(lambda: not addhw.active)
lib.utils.check(lambda: details.active)
# Finish
details.find_fuzzy("Begin Installation", "button").click()
uiutils.check(lambda: details.dead)
lib.utils.check(lambda: details.dead)
self.app.root.find_fuzzy("%s on" % vmname, "frame")
def testNewVMInactiveNetwork(self):
@ -1214,7 +1214,7 @@ class NewVM(uiutils.UITestCase):
Test with an inactive 'default' network
"""
self.app.uri = tests.utils.URIs.test_default
hostwin = self._open_host_window("Virtual Networks",
hostwin = self.app.open_host_window("Virtual Networks",
conn_label="test default")
cell = hostwin.find("default", "table cell")
cell.click()
@ -1232,8 +1232,8 @@ class NewVM(uiutils.UITestCase):
self.forward(newvm)
newvm.find_fuzzy("Finish", "button").click()
self._click_alert_button("start the network", "Yes")
uiutils.check(lambda: not newvm.showing)
self.app.click_alert_button("start the network", "Yes")
lib.utils.check(lambda: not newvm.showing)
@unittest.mock.patch.dict('os.environ', {"VIRTINST_TEST_SUITE": "1"})
def testNewVMDefaultBridge(self):
@ -1254,8 +1254,8 @@ class NewVM(uiutils.UITestCase):
newvm.find("Network selection", "toggle button").click_expander()
newvm.combo_check_default("net-source", "Bridge")
devname = newvm.find("Device name:", "text")
uiutils.check(lambda: devname.text == "testsuitebr0")
lib.utils.check(lambda: devname.text == "testsuitebr0")
newvm.find_fuzzy("Finish", "button").click()
self.app.root.find_fuzzy("vm1 on", "frame")
uiutils.check(lambda: not newvm.showing)
lib.utils.check(lambda: not newvm.showing)

View File

@ -1,10 +1,10 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests.uitests import utils as uiutils
from . import lib
class CreateVol(uiutils.UITestCase):
class CreateVol(lib.testcase.UITestCase):
"""
UI tests for the createvol wizard
"""
@ -13,7 +13,7 @@ class CreateVol(uiutils.UITestCase):
hostwin.find("vol-new", "push button").click()
win = self.app.root.find(
"Add a Storage Volume", "frame")
uiutils.check(lambda: win.active)
lib.utils.check(lambda: win.active)
return win
@ -25,7 +25,7 @@ class CreateVol(uiutils.UITestCase):
"""
Create default volume, clean it up
"""
hostwin = self._open_host_window("Storage")
hostwin = self.app.open_host_window("Storage")
poolcell = hostwin.find("default-pool", "table cell")
poolcell.click()
vollist = hostwin.find("vol-list", "table")
@ -34,7 +34,7 @@ class CreateVol(uiutils.UITestCase):
name = win.find("Name:", "text")
# Create a default qcow2 volume
uiutils.check(lambda: name.text == "vol")
lib.utils.check(lambda: name.text == "vol")
newname = "a-newvol"
name.set_text(newname)
win.find("Max Capacity:", "spin button").set_text("10.5")
@ -45,22 +45,22 @@ class CreateVol(uiutils.UITestCase):
volcell.click()
hostwin.find("vol-refresh", "push button").click()
hostwin.find("vol-delete", "push button").click()
self._click_alert_button("permanently delete the volume", "No")
self.app.click_alert_button("permanently delete the volume", "No")
volcell = vollist.find(newname + ".qcow2")
hostwin.find("vol-delete", "push button").click()
self._click_alert_button("permanently delete the volume", "Yes")
uiutils.check(lambda: volcell.dead)
self.app.click_alert_button("permanently delete the volume", "Yes")
lib.utils.check(lambda: volcell.dead)
# Ensure host window closes fine
hostwin.keyCombo("<ctrl>w")
uiutils.check(lambda: not hostwin.showing and
lib.utils.check(lambda: not hostwin.showing and
not hostwin.active)
def testCreateVolMisc(self):
"""
Cover all createvol options
"""
hostwin = self._open_host_window("Storage")
hostwin = self.app.open_host_window("Storage")
poolcell = hostwin.find("default-pool", "table cell")
poolcell.click()
win = self._open_create_win(hostwin)
@ -77,7 +77,7 @@ class CreateVol(uiutils.UITestCase):
browsewin = self.app.root.find("vmm-storage-browser")
# Test cancel button
browsewin.find("Cancel", "push button").click()
uiutils.check(lambda: not browsewin.active)
lib.utils.check(lambda: not browsewin.active)
win.find("Browse...").click()
browsewin = self.app.root.find("vmm-storage-browser")
# Test browse local opening
@ -85,10 +85,10 @@ class CreateVol(uiutils.UITestCase):
chooser = self.app.root.find(
"Locate existing storage", "file chooser")
chooser.keyCombo("<alt>F4")
self._select_storagebrowser_volume(
self.app.select_storagebrowser_volume(
"default-pool", "bochs-vol", doubleclick=True)
backingstore = win.find("backing-store")
uiutils.check(lambda: "bochs-vol" in backingstore.text)
lib.utils.check(lambda: "bochs-vol" in backingstore.text)
finish.click()
vollist.find(newname)
@ -101,19 +101,19 @@ class CreateVol(uiutils.UITestCase):
alloc = win.find("Allocation:", "spin button")
alloc.set_text("50.0")
alloc.click()
self.pressKey("Enter")
uiutils.check(lambda: cap.text == "50.0")
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: cap.text == "50.0")
cap.set_text("1.0")
cap.click()
self.pressKey("Enter")
uiutils.check(lambda: alloc.text == "1.0")
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: alloc.text == "1.0")
alloc.set_text("0.5")
alloc.click()
self.pressKey("Enter")
uiutils.check(lambda: cap.text == "1.0")
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: cap.text == "1.0")
finish.click()
self._click_alert_button("Error validating volume", "Close")
self.app.click_alert_button("Error validating volume", "Close")
newname = "a-newvol.raw"
name.set_text(newname)
finish.click()
@ -126,14 +126,14 @@ class CreateVol(uiutils.UITestCase):
name.set_text(newname)
win.find("Backing store").click_expander()
win.find("Browse...").click()
self._select_storagebrowser_volume("disk-pool", "diskvol7")
self.app.select_storagebrowser_volume("disk-pool", "diskvol7")
finish.click()
vollist.find(newname)
def testCreateVolXMLEditor(self):
self.app.open(xmleditor_enabled=True)
hostwin = self._open_host_window("Storage")
hostwin = self.app.open_host_window("Storage")
poolcell = hostwin.find("default-pool", "table cell")
poolcell.click()
win = self._open_create_win(hostwin)
@ -151,11 +151,11 @@ class CreateVol(uiutils.UITestCase):
">%s.qcow2<" % tmpname, ">%s<" % newname)
xmleditor.set_text(newtext)
finish.click()
uiutils.check(lambda: hostwin.active)
lib.utils.check(lambda: hostwin.active)
vollist.find(newname)
# Do standard xmleditor tests
win = self._open_create_win(hostwin)
self._test_xmleditor_interactions(win, finish)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
win.find("Cancel", "push button").click()
uiutils.check(lambda: not win.visible)
lib.utils.check(lambda: not win.visible)

View File

@ -4,8 +4,8 @@
import os
import shutil
from tests.uitests import utils as uiutils
import tests.utils
from . import lib
class _DeleteRow:
@ -40,7 +40,7 @@ def _create_testdriver_path(fn):
return wrapper
class Delete(uiutils.UITestCase):
class Delete(lib.testcase.UITestCase):
"""
UI tests for virt-manager's VM delete window
"""
@ -74,7 +74,7 @@ class Delete(uiutils.UITestCase):
return
alert.find("Yes", "push button").click()
if not expect_fail:
uiutils.check(lambda: not delete.showing)
lib.utils.check(lambda: not delete.showing)
def _get_all_rows(self, delete):
slist = delete.find("storage-list")
@ -124,7 +124,7 @@ class Delete(uiutils.UITestCase):
chkcell.click()
chkcell.click()
chkcell.click()
uiutils.check(lambda: chkcell.checked)
lib.utils.check(lambda: chkcell.checked)
paths = []
if defpath:
@ -139,7 +139,7 @@ class Delete(uiutils.UITestCase):
browser = self._open_storage_browser()
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
uiutils.check(lambda: "overlay.img" not in browser.fmt_nodes())
lib.utils.check(lambda: "overlay.img" not in browser.fmt_nodes())
browser.find("sharevol.img", "table cell")
@_create_testdriver_path
@ -174,10 +174,10 @@ class Delete(uiutils.UITestCase):
os.chmod(os.path.dirname(tmppath), 0o555)
delete = self.app.root.find_fuzzy("Delete", "frame")
self._finish(delete, paths, expect_fail=True, click_no=True)
uiutils.check(lambda: delete.active)
lib.utils.check(lambda: delete.active)
self._finish(delete, paths, expect_fail=True)
assert os.path.exists(tmppath)
self._click_alert_button("Errors encountered", "Close")
self.app.click_alert_button("Errors encountered", "Close")
def testDeleteRemoteManyDevices(self):
"""
@ -194,10 +194,10 @@ class Delete(uiutils.UITestCase):
chk = delete.find("Delete associated", "check box")
slist = delete.find("storage-list")
uiutils.check(lambda: chk.checked)
lib.utils.check(lambda: chk.checked)
chk.click()
uiutils.check(lambda: not chk.checked)
uiutils.check(lambda: not slist.showing)
lib.utils.check(lambda: not chk.checked)
lib.utils.check(lambda: not slist.showing)
self._finish(delete, None)
@ -205,7 +205,7 @@ class Delete(uiutils.UITestCase):
browser = self._open_storage_browser()
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
self.sleep(.5)
self.app.sleep(.5)
browser.find("overlay.img", "table cell")
browser.find("sharevol.img", "table cell")
@ -214,7 +214,7 @@ class Delete(uiutils.UITestCase):
Verify successful device remove with storage doesn't
touch host storage
"""
details = self._open_details_window("test-many-devices",
details = self.app.open_details_window("test-many-devices",
shutdown=True)
hwlist = details.find("hw-list")
@ -223,12 +223,12 @@ class Delete(uiutils.UITestCase):
c.bring_on_screen()
c.click()
tab = details.find("disk-tab")
uiutils.check(lambda: tab.showing)
lib.utils.check(lambda: tab.showing)
details.find("config-remove").click()
delete = self.app.root.find_fuzzy("Remove Disk", "frame")
chk = delete.find("Delete associated", "check box")
uiutils.check(lambda: not chk.checked)
lib.utils.check(lambda: not chk.checked)
self._finish(delete, [])
details.click()
details.keyCombo("<alt>F4")
@ -236,14 +236,14 @@ class Delete(uiutils.UITestCase):
browser = self._open_storage_browser()
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
self.sleep(.5)
self.app.sleep(.5)
browser.find("overlay.img", "table cell")
def testDeleteDeviceWithStorage(self):
"""
Verify successful device remove deletes storage
"""
details = self._open_details_window("test-many-devices",
details = self.app.open_details_window("test-many-devices",
shutdown=True)
hwlist = details.find("hw-list")
@ -252,14 +252,14 @@ class Delete(uiutils.UITestCase):
c.bring_on_screen()
c.click()
tab = details.find("disk-tab")
uiutils.check(lambda: tab.showing)
lib.utils.check(lambda: tab.showing)
details.find("config-remove").click()
delete = self.app.root.find_fuzzy("Remove Disk", "frame")
chk = delete.find("Delete associated", "check box")
uiutils.check(lambda: not chk.checked)
lib.utils.check(lambda: not chk.checked)
chk.click()
uiutils.check(lambda: chk.checked)
lib.utils.check(lambda: chk.checked)
path = "/dev/default-pool/overlay.img"
delete.find_fuzzy(path)
self._finish(delete, [path])
@ -269,13 +269,13 @@ class Delete(uiutils.UITestCase):
browser = self._open_storage_browser()
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
uiutils.check(lambda: "overlay.img" not in browser.fmt_nodes())
lib.utils.check(lambda: "overlay.img" not in browser.fmt_nodes())
def testDeleteDeviceFail(self):
"""
Verify failed device remove does not touch storage
"""
details = self._open_details_window("test-many-devices")
details = self.app.open_details_window("test-many-devices")
hwlist = details.find("hw-list")
hwlist.click()
@ -283,18 +283,18 @@ class Delete(uiutils.UITestCase):
c.bring_on_screen()
c.click()
tab = details.find("disk-tab")
uiutils.check(lambda: tab.showing)
lib.utils.check(lambda: tab.showing)
details.find("config-remove").click()
delete = self.app.root.find_fuzzy("Remove Disk", "frame")
chk = delete.find("Delete associated", "check box")
uiutils.check(lambda: not chk.checked)
lib.utils.check(lambda: not chk.checked)
chk.click()
uiutils.check(lambda: chk.checked)
lib.utils.check(lambda: chk.checked)
path = "/dev/default-pool/overlay.img"
delete.find_fuzzy(path)
self._finish(delete, [path], expect_fail=True)
self._click_alert_button("Storage will not be.*deleted", "OK")
self.app.click_alert_button("Storage will not be.*deleted", "OK")
details.click()
details.keyCombo("<alt>F4")
@ -302,5 +302,5 @@ class Delete(uiutils.UITestCase):
browser = self._open_storage_browser()
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
self.sleep(.5)
self.app.sleep(.5)
browser.find("overlay.img", "table cell")

View File

@ -1,11 +1,11 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests.uitests import utils as uiutils
import tests.utils
from . import lib
class Details(uiutils.UITestCase):
class Details(lib.testcase.UITestCase):
"""
UI tests for virt-manager's VM details window
"""
@ -16,27 +16,26 @@ class Details(uiutils.UITestCase):
hwlist = win.find("hw-list")
hwlist.point()
hwlist.click()
import dogtail.rawinput
dogtail.rawinput.keyCombo("<ctrl>f")
self.app.rawinput.keyCombo("<ctrl>f")
searchentry = self.app.root.find(None, "window").find(None, "text")
searchentry.set_text(hwname)
uiutils.check(lambda: c.onscreen)
uiutils.check(lambda: c.state_selected)
self.pressKey("Enter")
lib.utils.check(lambda: c.onscreen)
lib.utils.check(lambda: c.state_selected)
self.app.rawinput.pressKey("Enter")
c.click()
tab = win.find(tabname, None)
uiutils.check(lambda: tab.showing)
lib.utils.check(lambda: tab.showing)
return tab
def _stop_vm(self, win):
run = win.find("Run", "push button")
win.find("Shut Down", "push button").click()
uiutils.check(lambda: run.sensitive)
lib.utils.check(lambda: run.sensitive)
def _start_vm(self, win):
run = win.find("Run", "push button")
run.click()
uiutils.check(lambda: not run.sensitive)
lib.utils.check(lambda: not run.sensitive)
##############
@ -48,13 +47,13 @@ class Details(uiutils.UITestCase):
Open the VM with all the crazy hardware and just verify that each
HW panel shows itself without raising any error.
"""
win = self._open_details_window(vmname=vmname, double=True)
win = self.app.open_details_window(vmname, double=True)
lst = win.find("hw-list", "table")
self._walkUIList(win, lst, lambda: False)
lib.utils.walkUIList(self.app, win, lst, lambda: False)
# Select XML editor, and reverse walk the list
win.find("XML", "page tab").click()
self._walkUIList(win, lst, lambda: False, reverse=True)
lib.utils.walkUIList(self.app, win, lst, lambda: False, reverse=True)
return win
def testDetailsHardwareSmokeTest(self):
@ -66,11 +65,11 @@ class Details(uiutils.UITestCase):
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)
self.app.sleep(2)
def _testRename(self, origname, newname):
# Enable all stats prefs to hit some extra code
win = self._open_details_window(origname)
win = self.app.open_details_window(origname)
# Ensure the Overview page is the first selected
win.find("Hypervisor Details", "label")
@ -81,19 +80,19 @@ class Details(uiutils.UITestCase):
win.find("Name:", "text").set_text(badname)
appl = win.find("config-apply")
appl.click()
self._click_alert_button(badname, "Close")
self.app.click_alert_button(badname, "Close")
# Actual name change
win.find("Name:", "text").set_text(newname)
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Confirm lists were updated
self.app.root.find("%s on" % newname, "frame")
self.app.root.find_fuzzy(newname, "table cell")
# Make sure the old entry is gone
uiutils.check(lambda: origname not in oldcell.name)
lib.utils.check(lambda: origname not in oldcell.name)
def testDetailsRenameSimple(self):
"""
@ -110,7 +109,7 @@ class Details(uiutils.UITestCase):
self.app.root.find_fuzzy(origname, "table cell").click()
b = self.app.root.find("Shut Down", "push button")
b.click()
uiutils.check(lambda: b.sensitive is False)
lib.utils.check(lambda: b.sensitive is False)
self._testRename(origname, "test-new-name")
@ -119,55 +118,55 @@ class Details(uiutils.UITestCase):
Test state changes and unapplied changes warnings
"""
self.app.uri = tests.utils.URIs.kvm
win = self._open_details_window(vmname="test", shutdown=True)
win = self.app.open_details_window("test", shutdown=True)
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)
win = self.app.open_details_window("test")
lib.utils.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)
lib.utils.check(lambda: self.app.topwin.active)
self.app.topwin.keyCombo("<alt>F4")
uiutils.check(lambda: win.active)
lib.utils.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").set_text("")
uiutils.check(lambda: appl.sensitive)
lib.utils.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)
self.app.click_alert_button("unapplied changes", "Yes")
self.app.click_alert_button("name must be specified", "Close")
lib.utils.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)
self.app.click_alert_button("unapplied changes", "Yes")
self.app.click_alert_button("name must be specified", "Close")
lib.utils.check(lambda: not consolebtn.checked)
# Test the pause toggle
win.find("config-cancel").click()
run.click()
uiutils.check(lambda: not run.sensitive)
lib.utils.check(lambda: not run.sensitive)
pause = win.find("Pause", "toggle button")
pause.click()
uiutils.check(lambda: pause.checked)
lib.utils.check(lambda: pause.checked)
pause.click()
uiutils.check(lambda: not pause.checked)
uiutils.check(lambda: win.active)
lib.utils.check(lambda: not pause.checked)
lib.utils.check(lambda: win.active)
def testDetailsEditDomain1(self):
"""
Test overview, memory, cpu pages
"""
self.app.uri = tests.utils.URIs.kvm_cpu_insecure
win = self._open_details_window(vmname="test")
win = self.app.open_details_window("test")
appl = win.find("config-apply", "push button")
# Overview description
@ -175,7 +174,7 @@ class Details(uiutils.UITestCase):
tab.find("Description:", "text").set_text("hey new description")
tab.find("Title:", "text").set_text("hey new title")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# There's no hotplug operations after this point
self._stop_vm(win)
@ -184,7 +183,7 @@ class Details(uiutils.UITestCase):
tab = self._select_hw(win, "Memory", "memory-tab")
tab.find("Memory allocation:", "spin button").set_text("300")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Static CPU config
# more cpu config: host-passthrough, copy, clear CPU, manual
@ -192,33 +191,33 @@ class Details(uiutils.UITestCase):
tab.find("cpu-model").click_combo_entry()
tab.find_fuzzy("Clear CPU", "menu item").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
tab.find("cpu-model").click_combo_entry()
tab.find("coreduo", "menu item").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
tab.find_fuzzy("CPU security", "check box").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.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)
lib.utils.check(lambda: not appl.sensitive)
copyhost = tab.find("Copy host", "check box")
uiutils.check(lambda: copyhost.checked)
lib.utils.check(lambda: copyhost.checked)
copyhost.click()
tab.find("cpu-model").click_combo_entry()
tab.find("Hypervisor Default", "menu item").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
tab.find("cpu-model").find(None, "text").text = "host-passthrough"
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# vCPUs
tab.find("vCPU allocation:", "spin button").set_text("50")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# CPU topology
tab.find_fuzzy("Topology", "toggle button").click_expander()
@ -228,23 +227,23 @@ class Details(uiutils.UITestCase):
tab.find("Cores:", "spin button").typeText("2")
tab.find("Threads:", "spin button").typeText("2")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Confirm VCPUs were adjusted
vcpualloc = tab.find_fuzzy("vCPU allocation", "spin")
uiutils.check(lambda: vcpualloc.text == "32")
lib.utils.check(lambda: vcpualloc.text == "32")
# Unset topology
tab.find_fuzzy("Manually set", "check").click()
uiutils.check(lambda: not sockets.sensitive)
lib.utils.check(lambda: not sockets.sensitive)
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
def testDetailsEditDomain2(self):
"""
Test boot and OS pages
"""
win = self._open_details_window(vmname="test-many-devices")
win = self.app.open_details_window("test-many-devices")
appl = win.find("config-apply", "push button")
self._stop_vm(win)
@ -252,28 +251,27 @@ class Details(uiutils.UITestCase):
# OS edits
tab = self._select_hw(win, "OS information", "os-tab")
entry = tab.find("oslist-entry")
uiutils.check(lambda: entry.text == "Fedora")
lib.utils.check(lambda: entry.text == "Fedora")
entry.click()
self.pressKey("Down")
self.app.rawinput.pressKey("Down")
popover = win.find("oslist-popover")
popover.find("include-eol").click()
entry.set_text("fedora12")
popover.find_fuzzy("fedora12").bring_on_screen().click()
uiutils.check(lambda: not popover.visible)
uiutils.check(lambda: entry.text == "Fedora 12")
lib.utils.check(lambda: not popover.visible)
lib.utils.check(lambda: entry.text == "Fedora 12")
appl.click()
uiutils.check(lambda: not appl.sensitive)
uiutils.check(lambda: entry.text == "Fedora 12")
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: entry.text == "Fedora 12")
# Boot tweaks
def check_bootorder(c):
# Click the bootlist checkbox, which is hard to find in the tree
import dogtail.rawinput
x = c.position[0] - 30
y = c.position[1] + c.size[1] / 2
button = 1
dogtail.rawinput.click(x, y, button)
self.app.rawinput.click(x, y, button)
tab = self._select_hw(win, "Boot Options", "boot-tab")
tab.find_fuzzy("Start virtual machine on host", "check box").click()
@ -285,7 +283,7 @@ class Details(uiutils.UITestCase):
check_bootorder(tab.find("NIC :33:44", "table cell"))
check_bootorder(tab.find("PCI 0003:", "table cell"))
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Kernel boot
tab.find_fuzzy("Direct kernel boot", "toggle button").click_expander()
@ -293,59 +291,59 @@ class Details(uiutils.UITestCase):
tab.find("Kernel args:", "text").set_text("console=ttyS0")
appl.click()
self._click_alert_button("arguments without specifying", "OK")
uiutils.check(lambda: win.active)
self.app.click_alert_button("arguments without specifying", "OK")
lib.utils.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)
self.app.select_storagebrowser_volume("default-pool", "backingl1.img")
lib.utils.check(lambda: win.active)
lib.utils.check(lambda: "backing" in initrd.text)
appl.click()
self._click_alert_button("initrd without specifying", "OK")
uiutils.check(lambda: win.active)
self.app.click_alert_button("initrd without specifying", "OK")
lib.utils.check(lambda: win.active)
tab.find("kernel-browse", "push button").click()
self._select_storagebrowser_volume("default-pool", "bochs-vol")
uiutils.check(lambda: win.active)
self.app.select_storagebrowser_volume("default-pool", "bochs-vol")
lib.utils.check(lambda: win.active)
kernelpath = tab.find("Kernel path:", "text")
uiutils.check(lambda: "bochs" in kernelpath.text)
lib.utils.check(lambda: "bochs" in kernelpath.text)
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)
self.app.select_storagebrowser_volume("default-pool", "iso-vol")
lib.utils.check(lambda: win.active)
lib.utils.check(lambda: "iso-vol" in dtb.text)
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.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)
lib.utils.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)
lib.utils.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")
win = self.app.open_details_window("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.app.click_alert_button("Are you sure", "Yes")
self.app.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")
win = self.app.open_details_window("test-state-crashed")
self._select_hw(win, "Boot Options", "boot-tab")
win.find("No bootable devices")
@ -356,7 +354,7 @@ class Details(uiutils.UITestCase):
"""
Test disk and network devices
"""
win = self._open_details_window(vmname="test-many-devices")
win = self.app.open_details_window("test-many-devices")
appl = win.find("config-apply", "push button")
# Quick test to hit some serialcon.py paths
@ -365,7 +363,7 @@ class Details(uiutils.UITestCase):
textmenu = viewmenu.find("Consoles", "menu")
textmenu.point()
conitem = textmenu.find("Serial 1")
uiutils.check(lambda: not conitem.sensitive)
lib.utils.check(lambda: not conitem.sensitive)
viewmenu.click()
self._stop_vm(win)
@ -380,21 +378,21 @@ class Details(uiutils.UITestCase):
tab.combo_select("Discard mode:", "unmap")
tab.combo_select("Detect zeroes:", "unmap")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.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")
self.app.rawinput.pressKey("Home")
tab.find_fuzzy("Macvtap device...",
"menu item").bring_on_screen().click()
tab.find("Device name:", "text").set_text("fakedev12")
tab.combo_select("Device model:", "rtl8139")
tab.find("Link state:", "check box").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Manual bridge
src.click()
@ -403,16 +401,16 @@ class Details(uiutils.UITestCase):
tab.find("Device name:", "text").set_text("")
appl.click()
# Check validation error
self._click_alert_button("Error changing VM configuration", "Close")
self.app.click_alert_button("Error changing VM configuration", "Close")
tab.find("Device name:", "text").set_text("zbr0")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
def testDetailsNetIPAddress(self):
"""
Test all the IP code paths with a few mock cases
"""
win = self._open_details_window(vmname="test-many-devices")
win = self.app.open_details_window("test-many-devices")
def check_ip(*args):
for ip in args:
tab.find_fuzzy(ip, "label")
@ -430,11 +428,11 @@ class Details(uiutils.UITestCase):
check_ip("10.0.0.3")
win.keyCombo("<alt>F4")
uiutils.check(lambda: not win.showing)
lib.utils.check(lambda: not win.showing)
self.app.topwin.click_title()
# Tests the fake qemu guest agent path
win = self._open_details_window(vmname="test alternate devs title")
win = self.app.open_details_window("test alternate devs title")
tab = self._select_hw(win, "NIC :11:72:72", "network-tab")
check_ip("10.0.0.1", "fd00:beef::1/128")
@ -443,7 +441,7 @@ class Details(uiutils.UITestCase):
"""
Test all other devices
"""
win = self._open_details_window(vmname="test-many-devices")
win = self.app.open_details_window("test-many-devices")
appl = win.find("config-apply", "push button")
# Fail to hotremove
@ -451,14 +449,14 @@ class Details(uiutils.UITestCase):
tab.find("Advanced options", "toggle button").click_expander()
share = tab.find("Shareable", "check box")
share.click()
uiutils.check(lambda: appl.sensitive)
lib.utils.check(lambda: appl.sensitive)
win.find("config-remove").click()
delete = self.app.root.find_fuzzy("Remove Disk", "frame")
delete.find_fuzzy("Delete", "button").click()
self._click_alert_button("change will take effect", "OK")
uiutils.check(lambda: not delete.showing)
uiutils.check(lambda: appl.sensitive)
uiutils.check(lambda: share.checked)
self.app.click_alert_button("change will take effect", "OK")
lib.utils.check(lambda: not delete.showing)
lib.utils.check(lambda: appl.sensitive)
lib.utils.check(lambda: share.checked)
win.find("config-cancel").click()
self._stop_vm(win)
@ -467,14 +465,14 @@ class Details(uiutils.UITestCase):
tab = self._select_hw(win, "Display VNC", "graphics-tab")
tab.combo_select("Type:", "Spice")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# 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)
lib.utils.check(lambda: not appl.sensitive)
# Switch to VNC with options
tab.combo_select("Type:", "VNC")
@ -487,30 +485,30 @@ class Details(uiutils.UITestCase):
newpass = "foobar"
passwd.typeText(newpass)
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Sound device
tab = self._select_hw(win, "Sound sb16", "sound-tab")
tab.find("Model:", "text").set_text("ac97")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.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)
self.app.click_alert_button("Are you sure", "No")
lib.utils.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)
self.app.click_alert_button("Are you sure", "Yes")
lib.utils.check(lambda: cell.text != oldtext)
# Host device
tab = self._select_hw(win, "PCI 0000:00:19.0", "host-tab")
tab.find("ROM BAR:", "check box").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Video device
@ -518,20 +516,20 @@ class Details(uiutils.UITestCase):
tab.find("Model:", "text").set_text("virtio")
tab.find("3D acceleration:", "check box").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Watchdog
tab = self._select_hw(win, "Watchdog", "watchdog-tab")
tab.find("Model:", "text").set_text("diag288")
tab.find("Action:", "text").click()
self.pressKey("Down")
self.app.rawinput.pressKey("Down")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
def testDetailsEditDevices2(self):
win = self._open_details_window(vmname="test-many-devices",
win = self.app.open_details_window("test-many-devices",
shutdown=True)
appl = win.find("config-apply", "push button")
@ -541,21 +539,21 @@ class Details(uiutils.UITestCase):
tab.combo_select("controller-model", "Hypervisor")
tab.find("SCSI Disk 1 on 9:0:0:0", "table cell")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Controller USB
tab = self._select_hw(win, "Controller USB 0", "controller-tab")
tab.combo_select("controller-model", "USB 2")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
tab = self._select_hw(win, "Controller USB 0", "controller-tab")
tab.combo_select("controller-model", "USB 3")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.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)
lib.utils.check(lambda: not appl.sensitive)
# Filesystem tweaks
@ -566,34 +564,34 @@ class Details(uiutils.UITestCase):
tab.find("Target path:", "text").set_text("newtarget")
tab.find_fuzzy("Export filesystem", "check box").click()
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
# Smartcard tweaks
tab = self._select_hw(win, "Smartcard", "smartcard-tab")
tab.combo_select("smartcard-mode", "Passthrough")
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.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)
lib.utils.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")
lib.utils.check(lambda: addr.text == "5")
addr.set_text("7")
appl.click()
uiutils.check(lambda: addr.text == "7")
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: addr.text == "7")
lib.utils.check(lambda: not appl.sensitive)
auto.click()
uiutils.check(lambda: not addr.visible)
lib.utils.check(lambda: not addr.visible)
appl.click()
uiutils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not appl.sensitive)
def testDetailsMiscEdits(self):
@ -601,7 +599,7 @@ class Details(uiutils.UITestCase):
Test misc editing behavior, like checking for unapplied
changes
"""
win = self._open_details_window(vmname="test-many-devices",
win = self.app.open_details_window("test-many-devices",
double=True)
hwlist = win.find("hw-list")
@ -613,41 +611,41 @@ class Details(uiutils.UITestCase):
delete.find_fuzzy("Delete", "button").click()
# Will be fixed eventually
self._click_alert_button("Device could not be removed", "OK")
self.app.click_alert_button("Device could not be removed", "OK")
c = hwlist.find(disklabel, "table cell")
self._stop_vm(win)
uiutils.check(lambda: c.text != disklabel)
lib.utils.check(lambda: c.text != disklabel)
# Remove a device for offline VM
tab = self._select_hw(win, "SCSI CDROM 1", "disk-tab")
win.find("config-remove", "push button").click()
delete = self.app.root.find_fuzzy("Remove Disk", "frame")
delete.find_fuzzy("Delete", "button").click()
uiutils.check(lambda: win.active)
lib.utils.check(lambda: win.active)
# Attempt to apply changes when skipping away, but they fail
tab.find("Advanced options", "toggle button").click_expander()
tab.find("Cache mode:", "combo").find(None, "text").set_text("badcachemode")
hwlist.find("CPUs", "table cell").click()
self._click_alert_button("There are unapplied changes", "Yes")
self._click_alert_button("badcachemode", "Close")
self.app.click_alert_button("There are unapplied changes", "Yes")
self.app.click_alert_button("badcachemode", "Close")
# Cancelling changes
tab = self._select_hw(win, "IDE Disk 1", "disk-tab")
share = tab.find("Shareable:", "check box")
uiutils.check(lambda: not share.checked)
lib.utils.check(lambda: not share.checked)
share.click()
win.find("config-cancel").click()
uiutils.check(lambda: not share.checked)
lib.utils.check(lambda: not share.checked)
# Unapplied, clicking no
share = tab.find("Shareable:", "check box")
share.click()
hwlist.find("CPUs", "table cell").click()
self._click_alert_button("There are unapplied changes", "No")
self.app.click_alert_button("There are unapplied changes", "No")
tab = self._select_hw(win, "IDE Disk 1", "disk-tab")
uiutils.check(lambda: not share.checked)
lib.utils.check(lambda: not share.checked)
# Unapplied changes but clicking yes
share.click()
@ -657,38 +655,38 @@ class Details(uiutils.UITestCase):
alert.find_fuzzy("Don't warn", "check box").click()
alert.find("Yes", "push button").click()
tab = self._select_hw(win, "IDE Disk 1", "disk-tab")
uiutils.check(lambda: share.checked)
lib.utils.check(lambda: share.checked)
# Make sure no unapplied changes option sticks
share.click()
self._select_hw(win, "CPUs", "cpu-tab")
tab = self._select_hw(win, "IDE Disk 1", "disk-tab")
uiutils.check(lambda: share.checked)
lib.utils.check(lambda: share.checked)
# VM State change doesn't refresh UI
share.click()
self._start_vm(win)
uiutils.check(lambda: not share.checked)
lib.utils.check(lambda: not share.checked)
# Now apply changes to running VM, ensure they show up on shutdown
win.find("config-apply").click()
self._click_alert_button("changes will take effect", "OK")
uiutils.check(lambda: share.checked)
self.app.click_alert_button("changes will take effect", "OK")
lib.utils.check(lambda: share.checked)
self._stop_vm(win)
uiutils.check(lambda: not share.checked)
lib.utils.check(lambda: not share.checked)
# Unapplied changes should warn when switching to XML tab
tab = self._select_hw(win, "Overview", "overview-tab")
tab.find("Description:", "text").set_text("hey new description")
win.find("XML", "page tab").click()
# Select 'No', meaning don't abandon changes
self._click_alert_button("changes will be lost", "No")
uiutils.check(lambda: tab.showing)
self.app.click_alert_button("changes will be lost", "No")
lib.utils.check(lambda: tab.showing)
# Try unapplied changes again, this time abandon our changes
win.find("XML", "page tab").click()
self._click_alert_button("changes will be lost", "Yes")
uiutils.check(lambda: not tab.showing)
self.app.click_alert_button("changes will be lost", "Yes")
lib.utils.check(lambda: not tab.showing)
# Verify addhardware right click works
win.find("Overview", "table cell").click(button=3)
@ -700,7 +698,7 @@ class Details(uiutils.UITestCase):
Test XML editing interaction
"""
self.app.open(xmleditor_enabled=True)
win = self._open_details_window(vmname="test-clone-simple")
win = self.app.open_details_window("test-clone-simple")
finish = win.find("config-apply")
xmleditor = win.find("XML editor")
@ -711,7 +709,7 @@ class Details(uiutils.UITestCase):
finish.click()
win.find("Details", "page tab").click()
vcpualloc = tab.find("vCPU allocation:", "spin button")
uiutils.check(lambda: vcpualloc.text == "8")
lib.utils.check(lambda: vcpualloc.text == "8")
# Make some disk edits
tab = self._select_hw(win, "IDE Disk 1", "disk-tab")
@ -722,10 +720,10 @@ class Details(uiutils.UITestCase):
finish.click()
win.find("Details", "page tab").click()
disksrc = win.find("disk-source-path")
uiutils.check(lambda: disksrc.text == newpath)
lib.utils.check(lambda: disksrc.text == newpath)
# Do standard xmleditor tests
self._test_xmleditor_interactions(win, finish)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
def testDetailsConsoleChecksSSH(self):
"""
@ -748,13 +746,13 @@ class Details(uiutils.UITestCase):
def _run():
win.click_title()
run.click()
uiutils.check(lambda: not run.sensitive)
lib.utils.check(lambda: not run.sensitive)
def _stop():
shutdown.click()
uiutils.check(lambda: not shutdown.sensitive)
lib.utils.check(lambda: not shutdown.sensitive)
def _checkcon(msg):
conbtn.click()
uiutils.check(lambda: conpages.showing)
lib.utils.check(lambda: conpages.showing)
conpages.find(msg)
def _check_textconsole_menu(msg):
vmenu = win.find("^View$", "menu")
@ -778,8 +776,8 @@ class Details(uiutils.UITestCase):
dev = '<graphics type="sdl" display=":3.4" xauth="/tmp/.Xauthority"/>'
addhw.find("XML editor").text = dev
addhw.find("Finish", "push button").click()
uiutils.check(lambda: not addhw.active)
uiutils.check(lambda: win.active)
lib.utils.check(lambda: not addhw.active)
lib.utils.check(lambda: win.active)
_run()
_checkcon("Cannot display graphical console type")
@ -853,13 +851,13 @@ class Details(uiutils.UITestCase):
def _run():
win.click_title()
run.click()
uiutils.check(lambda: not run.sensitive)
lib.utils.check(lambda: not run.sensitive)
def _stop():
shutdown.click()
uiutils.check(lambda: not shutdown.sensitive)
lib.utils.check(lambda: not shutdown.sensitive)
def _checkcon(msg):
conbtn.click()
uiutils.check(lambda: conpages.showing)
lib.utils.check(lambda: conpages.showing)
conpages.find(msg)
# Check initial state
@ -875,7 +873,7 @@ class Details(uiutils.UITestCase):
dev = '<graphics type="vnc" port="6000" address="127.0.0.1"/>'
addhw.find("XML editor").text = dev
addhw.find("Finish", "push button").click()
uiutils.check(lambda: not addhw.active)
uiutils.check(lambda: win.active)
lib.utils.check(lambda: not addhw.active)
lib.utils.check(lambda: win.active)
_run()
_checkcon(".*configured to listen locally.*")

View File

@ -1,10 +1,10 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests.uitests import utils as uiutils
from . import lib
class Host(uiutils.UITestCase):
class Host(lib.testcase.UITestCase):
"""
UI tests for virt-manager's VM details window
"""
@ -17,21 +17,21 @@ class Host(uiutils.UITestCase):
"""
Verify that each virtual network displays, without error.
"""
win = self._open_host_window("Virtual Networks")
win = self.app.open_host_window("Virtual Networks")
lst = win.find("net-list", "table")
errlabel = win.find("net-error-label", "label")
self._walkUIList(win, lst, lambda: errlabel.showing)
lib.utils.walkUIList(self.app, win, lst, lambda: errlabel.showing)
# Select XML editor, and reverse walk the list
win.find("network-grid").find("XML", "page tab").click()
self._walkUIList(win, lst, lambda: errlabel.showing, reverse=True)
lib.utils.walkUIList(self.app, win, lst, lambda: errlabel.showing, reverse=True)
def testHostNetworkEdit(self):
"""
Test edits to net config
"""
self.app.open(xmleditor_enabled=True)
win = self._open_host_window("Virtual Networks").find("network-grid")
win = self.app.open_host_window("Virtual Networks").find("network-grid")
finish = win.find("Apply", "push button")
# Shut it off, do an XML edit, verify it
@ -39,7 +39,7 @@ class Host(uiutils.UITestCase):
delete = win.find("net-delete", "push button")
stop = win.find("net-stop", "push button")
stop.click()
uiutils.check(lambda: delete.sensitive)
lib.utils.check(lambda: delete.sensitive)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
origdev = "virbr0"
@ -48,7 +48,7 @@ class Host(uiutils.UITestCase):
finish.click()
win.find("Details", "page tab").click()
netdev = win.find("net-device")
uiutils.check(lambda: netdev.text == newdev)
lib.utils.check(lambda: netdev.text == newdev)
# Rename it
win.find("default", "table cell").click()
@ -59,31 +59,31 @@ class Host(uiutils.UITestCase):
win.find("newsort-default", "table cell").click()
win.find("net-autostart").click()
win.find("netboot", "table cell").click()
self._click_alert_button("There are unapplied changes", "Yes")
self.app.click_alert_button("There are unapplied changes", "Yes")
# Do standard xmleditor tests
self._test_xmleditor_interactions(win, finish)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
def testHostStorageSmokeTest(self):
"""
Verify that each storage pool displays, without error.
"""
win = self._open_host_window("Storage")
win = self.app.open_host_window("Storage")
lst = win.find("pool-list", "table")
errlabel = win.find("pool-error-label", "label")
self._walkUIList(win, lst, lambda: errlabel.showing)
lib.utils.walkUIList(self.app, win, lst, lambda: errlabel.showing)
# Select XML editor, and reverse walk the list
win.find("storage-grid").find("XML", "page tab").click()
self._walkUIList(win, lst, lambda: errlabel.showing, reverse=True)
lib.utils.walkUIList(self.app, win, lst, lambda: errlabel.showing, reverse=True)
def testHostStorageEdit(self):
"""
Test edits to pool config
"""
self.app.open(xmleditor_enabled=True)
win = self._open_host_window("Storage").find("storage-grid")
win = self.app.open_host_window("Storage").find("storage-grid")
finish = win.find("Apply", "push button")
# Shut off a pool, do an XML edit, verify it
@ -91,7 +91,7 @@ class Host(uiutils.UITestCase):
delete = win.find("pool-delete", "push button")
stop = win.find("pool-stop", "push button")
stop.click()
uiutils.check(lambda: delete.sensitive)
lib.utils.check(lambda: delete.sensitive)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
origpath = "/dev/default-pool"
@ -100,7 +100,7 @@ class Host(uiutils.UITestCase):
finish.click()
win.find("Details", "page tab").click()
poolloc = win.find("pool-location")
uiutils.check(lambda: poolloc.text == newpath)
lib.utils.check(lambda: poolloc.text == newpath)
# Rename it
win.find("default", "table cell").click()
@ -111,33 +111,33 @@ class Host(uiutils.UITestCase):
win.find("newsort-default", "table cell").click()
win.find("pool-autostart").click()
win.find("disk-pool", "table cell").click()
self._click_alert_button("There are unapplied changes", "Yes")
self.app.click_alert_button("There are unapplied changes", "Yes")
# Do standard xmleditor tests
self._test_xmleditor_interactions(win, finish)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
def testHostStorageVolMisc(self):
"""
Misc actions involving volumes
"""
win = self._open_host_window("Storage").find("storage-grid")
win = self.app.open_host_window("Storage").find("storage-grid")
win.find_fuzzy("default-pool", "table cell").click()
vollist = win.find("vol-list", "table")
vol1 = vollist.find("backingl1.img", "table cell")
vol2 = vollist.find("UPPER", "table cell")
uiutils.check(lambda: vol1.onscreen)
uiutils.check(lambda: not vol2.onscreen)
lib.utils.check(lambda: vol1.onscreen)
lib.utils.check(lambda: not vol2.onscreen)
win.find("Size", "table column header").click()
win.find("Size", "table column header").click()
uiutils.check(lambda: not vol1.onscreen)
uiutils.check(lambda: vol2.onscreen)
lib.utils.check(lambda: not vol1.onscreen)
lib.utils.check(lambda: vol2.onscreen)
vol2.click(button=3)
self.app.root.find("Copy Volume Path", "menu item").click()
from gi.repository import Gdk, Gtk
clipboard = Gtk.Clipboard.get_default(Gdk.Display.get_default())
uiutils.check(lambda: clipboard.wait_for_text() == "/dev/default-pool/UPPER")
lib.utils.check(lambda: clipboard.wait_for_text() == "/dev/default-pool/UPPER")
def testHostConn(self):
"""
@ -148,7 +148,7 @@ class Host(uiutils.UITestCase):
c = manager.find_fuzzy("testdriver.xml", "table cell")
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
uiutils.check(lambda: "Not Connected" in c.text)
lib.utils.check(lambda: "Not Connected" in c.text)
# Open Host Details from right click menu
c.click(button=3)
@ -171,15 +171,15 @@ class Host(uiutils.UITestCase):
# Open the manager window
win.find("File", "menu").click()
win.find("View Manager", "menu item").click()
uiutils.check(lambda: manager.active)
lib.utils.check(lambda: manager.active)
# Confirm connection row is named differently in manager
manager.find("FOOBAR", "table cell")
# Close the manager
manager.keyCombo("<alt>F4")
uiutils.check(lambda: win.active)
lib.utils.check(lambda: win.active)
# Quit app from the file menu
win.find("File", "menu").click()
win.find("Quit", "menu item").click()
uiutils.check(lambda: not self.app.is_running())
lib.utils.check(lambda: not self.app.is_running())

View File

@ -3,7 +3,7 @@
import pytest
from tests.uitests import utils as uiutils
from . import lib
try:
import guestfs
@ -13,7 +13,7 @@ except Exception:
HAS_LIBGUESTFS = False
class VMMInspection(uiutils.UITestCase):
class VMMInspection(lib.testcase.UITestCase):
"""
UI tests for the libguestfs inspection infrastructure
"""
@ -31,22 +31,22 @@ class VMMInspection(uiutils.UITestCase):
self.app.open(enable_libguestfs=True)
manager = self.app.topwin
details = self._open_details_window("test-clone")
details = self.app.open_details_window("test-clone")
details.find("OS information", "table cell").click()
tab = details.find("os-tab")
tab.find("Application", "toggle").click_expander()
apps = tab.find("inspection-apps")
uiutils.check(lambda: apps.onscreen)
lib.utils.check(lambda: apps.onscreen)
apps.click_expander()
nodestr1 = apps.fmt_nodes()
assert "test_app1_summary" in nodestr1
tab.find("Refresh", "push button").click()
uiutils.check(lambda: apps.fmt_nodes() != nodestr1)
lib.utils.check(lambda: apps.fmt_nodes() != nodestr1)
details.keyCombo("<alt>F4")
uiutils.check(lambda: not details.showing)
lib.utils.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()
@ -69,4 +69,4 @@ class VMMInspection(uiutils.UITestCase):
c.click()
c.click(button=3)
self.app.root.find("conn-connect", "menu item").click()
self.sleep(2)
self.app.sleep(2)

View File

@ -8,7 +8,7 @@ import libvirt
from virtinst import log
import tests
from tests.uitests import utils as uiutils
from . import lib
def _vm_wrapper(vmname, uri="qemu:///system", opts=None):
@ -45,7 +45,7 @@ def _vm_wrapper(vmname, uri="qemu:///system", opts=None):
return wrap1
class Console(uiutils.UITestCase):
class Console(lib.testcase.UITestCase):
"""
Test live console connections with stub VMs
"""
@ -57,9 +57,9 @@ class Console(uiutils.UITestCase):
smenu = win.find("Menu", "toggle button")
smenu.click()
smenu.find("Force Off", "menu item").click()
self._click_alert_button("you sure", "Yes")
self.app.click_alert_button("you sure", "Yes")
run = win.find("Run", "push button")
uiutils.check(lambda: run.sensitive)
lib.utils.check(lambda: run.sensitive)
##############
@ -72,16 +72,16 @@ class Console(uiutils.UITestCase):
"""
win = self.app.topwin
con = win.find("console-gfx-viewport")
uiutils.check(lambda: con.showing)
lib.utils.check(lambda: con.showing)
win.find("Virtual Machine", "menu").click()
win.find("Take Screenshot", "menu item").click()
chooser = self.app.root.find(None, "file chooser")
fname = chooser.find("Name", "text").text
self.pressKey("Enter")
uiutils.check(lambda: os.path.exists(fname))
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: os.path.exists(fname))
os.unlink(fname)
uiutils.check(lambda: win.active)
lib.utils.check(lambda: win.active)
win.find("Send Key", "menu").click()
win.find(r"Ctrl\+Alt\+F1", "menu item").click()
@ -95,37 +95,37 @@ class Console(uiutils.UITestCase):
win.find("^View$", "menu").click()
win.find("Resize to VM", "menu item").click()
newsize = win.size
uiutils.check(lambda: oldsize != newsize)
lib.utils.check(lambda: oldsize != newsize)
# Fullscreen testing
win.find("^View$", "menu").click()
win.find("Fullscreen", "check menu item").click()
fstb = win.find("Fullscreen Toolbar")
uiutils.check(lambda: fstb.showing)
uiutils.check(lambda: win.size != newsize)
lib.utils.check(lambda: fstb.showing)
lib.utils.check(lambda: win.size != newsize)
# Wait for toolbar to hide, then reveal it again
uiutils.check(lambda: not fstb.showing, timeout=5)
self.point(win.position[0] + win.size[0] / 2, 0)
uiutils.check(lambda: fstb.showing)
lib.utils.check(lambda: not fstb.showing, timeout=5)
self.app.rawinput.point(win.position[0] + win.size[0] / 2, 0)
lib.utils.check(lambda: fstb.showing)
# Move it off and have it hide again
win.point()
uiutils.check(lambda: not fstb.showing, timeout=5)
self.point(win.position[0] + win.size[0] / 2, 0)
uiutils.check(lambda: fstb.showing)
lib.utils.check(lambda: not fstb.showing, timeout=5)
self.app.rawinput.point(win.position[0] + win.size[0] / 2, 0)
lib.utils.check(lambda: fstb.showing)
# Click stuff and exit fullscreen
win.find("Fullscreen Send Key").click()
self.pressKey("Escape")
self.app.rawinput.pressKey("Escape")
win.find("Fullscreen Exit").click()
uiutils.check(lambda: win.size == newsize)
lib.utils.check(lambda: win.size == newsize)
# Trigger pointer grab, verify title was updated
win.click()
uiutils.check(lambda: "Control_L" in win.name)
lib.utils.check(lambda: "Control_L" in win.name)
# Ungrab
win.keyCombo("<ctrl><alt>")
uiutils.check(lambda: "Control_L" not in win.name)
lib.utils.check(lambda: "Control_L" not in win.name)
# Tweak scaling
win.click_title()
@ -145,15 +145,15 @@ class Console(uiutils.UITestCase):
# Check that modifiers don't work
win.click()
self.sleep(1)
self.app.sleep(1)
win.keyCombo("<ctrl>w")
uiutils.check(lambda: win.showing)
lib.utils.check(lambda: win.showing)
dom.destroy()
win.find("Guest is not running.")
win.click_title()
self.sleep(1)
self.app.sleep(1)
win.keyCombo("<ctrl>w")
uiutils.check(lambda: not win.showing)
lib.utils.check(lambda: not win.showing)
@_vm_wrapper("uitests-vnc-standard")
def testConsoleVNCStandard(self, dom):
@ -168,44 +168,44 @@ class Console(uiutils.UITestCase):
"""
win = self.app.topwin
con = win.find("console-gfx-viewport")
uiutils.check(lambda: not con.showing)
lib.utils.check(lambda: not con.showing)
passwd = win.find("Password:", "password text")
uiutils.check(lambda: passwd.showing)
lib.utils.check(lambda: passwd.showing)
# Check wrong password handling
passwd.typeText("xx")
win.find("Login", "push button").click()
self._click_alert_button("Viewer authentication error", "OK")
self.app.click_alert_button("Viewer authentication error", "OK")
savecheck = win.find("Save this password", "check box")
if not savecheck.checked:
savecheck.click()
passwd.typeText("yy")
self.pressKey("Enter")
self._click_alert_button("Viewer authentication error", "OK")
self.app.rawinput.pressKey("Enter")
self.app.click_alert_button("Viewer authentication error", "OK")
# Check proper password
passwd.text = ""
passwd.typeText("goodp")
win.find("Login", "push button").click()
uiutils.check(lambda: con.showing)
lib.utils.check(lambda: con.showing)
# Restart VM to retrigger console connect
self._destroy(win)
win.find("Run", "push button").click()
uiutils.check(lambda: passwd.showing)
lib.utils.check(lambda: passwd.showing)
# Password should be filled in
uiutils.check(lambda: bool(passwd.text))
lib.utils.check(lambda: bool(passwd.text))
# Uncheck 'Save password' and login, which will delete it from keyring
savecheck.click()
win.find("Login", "push button").click()
uiutils.check(lambda: con.showing)
lib.utils.check(lambda: con.showing)
# Restart VM to retrigger console connect
self._destroy(win)
win.find("Run", "push button").click()
uiutils.check(lambda: passwd.showing)
lib.utils.check(lambda: passwd.showing)
# Password should be empty now
uiutils.check(lambda: not bool(passwd.text))
lib.utils.check(lambda: not bool(passwd.text))
@_vm_wrapper("uitests-vnc-password")
def testConsoleVNCPassword(self, dom):
@ -222,25 +222,25 @@ class Console(uiutils.UITestCase):
ignore = dom
win = self.app.topwin
con = win.find("console-gfx-viewport")
uiutils.check(lambda: not con.showing)
lib.utils.check(lambda: not con.showing)
passwd = win.find("Password:", "password text")
uiutils.check(lambda: passwd.showing)
lib.utils.check(lambda: passwd.showing)
username = win.find("Username:", "text")
uiutils.check(lambda: username.showing)
lib.utils.check(lambda: username.showing)
# Since we are mocking the username, sending the credentials
# is ignored, so with the correct password this succeeds
username.text = "fakeuser"
passwd.typeText("goodp")
win.find("Login", "push button").click()
uiutils.check(lambda: con.showing)
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-vnc-socket")
def testConsoleVNCSocket(self, dom):
ignore = dom
win = self.app.topwin
con = win.find("console-gfx-viewport")
uiutils.check(lambda: con.showing)
lib.utils.check(lambda: con.showing)
def _click_textconsole_menu(msg):
vmenu = win.find("^View$", "menu")
@ -251,27 +251,27 @@ class Console(uiutils.UITestCase):
# A bit of an extra test, make sure selecting Graphical Console works
_click_textconsole_menu("Serial 1")
uiutils.check(lambda: not con.showing)
lib.utils.check(lambda: not con.showing)
_click_textconsole_menu("Graphical Console")
uiutils.check(lambda: con.showing)
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-spice-standard")
def testConsoleAutoconnect(self, dom):
ignore = dom
win = self.app.topwin
con = win.find("console-gfx-viewport")
uiutils.check(lambda: con.showing)
lib.utils.check(lambda: con.showing)
# Disable autoconnect
vmenu = win.find("^View$", "menu")
vmenu.click()
vmenu.find("Autoconnect").click()
dom.destroy()
self.sleep(1)
self.app.sleep(1)
dom.create()
uiutils.check(lambda: not con.showing)
lib.utils.check(lambda: not con.showing)
win.find("Connect to console", "push button").click()
uiutils.check(lambda: con.showing)
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-lxc-serial", uri="lxc:///")
def testConsoleLXCSerial(self, dom):
@ -281,9 +281,9 @@ class Console(uiutils.UITestCase):
ignore = dom
win = self.app.topwin
term = win.find("Serial Terminal")
uiutils.check(lambda: term.showing)
lib.utils.check(lambda: term.showing)
term.typeText("help\n")
uiutils.check(lambda: "COMMANDS" in term.text)
lib.utils.check(lambda: "COMMANDS" in term.text)
term.doubleClick()
term.click(button=3)
@ -303,26 +303,26 @@ class Console(uiutils.UITestCase):
# Triggers some tooltip cases
textmenu = view.find("Consoles", "menu")
textmenu.point()
uiutils.check(lambda: textmenu.showing)
lib.utils.check(lambda: textmenu.showing)
item = textmenu.find("Text Console 1")
uiutils.check(lambda: not item.sensitive)
lib.utils.check(lambda: not item.sensitive)
# Restart the guest to trigger reconnect code
view.click()
win.find("Run", "push button").click()
term = win.find("Serial Terminal")
uiutils.check(lambda: term.showing)
lib.utils.check(lambda: term.showing)
# Ensure ctrl+w doesn't close the window, modifiers are disabled
term.click()
win.keyCombo("<ctrl>w")
uiutils.check(lambda: win.showing)
lib.utils.check(lambda: win.showing)
# Shut it down, ensure <ctrl>w works again
self._destroy(win)
win.click_title()
self.sleep(1)
self.app.sleep(1)
win.keyCombo("<ctrl>w")
uiutils.check(lambda: not win.showing)
lib.utils.check(lambda: not win.showing)
@_vm_wrapper("uitests-spice-specific",
@ -336,7 +336,7 @@ class Console(uiutils.UITestCase):
ignore = dom
win = self.app.topwin
con = win.find("console-gfx-viewport")
uiutils.check(lambda: con.showing)
lib.utils.check(lambda: con.showing)
# Just ensure the dialog pops up, can't really test much more
# than that
@ -351,8 +351,8 @@ class Console(uiutils.UITestCase):
chooser.find("virt-manager", "label").click()
chooser.find("virt-manager", "label").click()
chooser.find("COPYING").click()
self.pressKey("Enter")
uiutils.check(lambda: not chooser.showing)
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: not chooser.showing)
usbwin.find("Close", "push button").click()
# Test fake guest resize behavior
@ -378,44 +378,44 @@ class Console(uiutils.UITestCase):
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)
lib.utils.check(lambda: tab.showing)
tab.find("Select or create", "radio button").click()
tab.find("storage-entry").set_text(fname)
tab.combo_select("Bus type:", "SCSI")
addhw.find("Finish", "push button").click()
# Verify permission dialog pops up, ask to change
self._click_alert_button(
self.app.click_alert_button(
"The emulator may not have search permissions", "Yes")
# Verify no errors
uiutils.check(lambda: not addhw.showing)
uiutils.check(lambda: win.active)
lib.utils.check(lambda: not addhw.showing)
lib.utils.check(lambda: win.active)
# Hot unplug the disk
win.find("SCSI Disk 1", "table cell").click()
tab = win.find("disk-tab", None)
uiutils.check(lambda: tab.showing)
lib.utils.check(lambda: tab.showing)
win.find("config-remove").click()
delete = self.app.root.find_fuzzy("Remove Disk", "frame")
delete.find_fuzzy("Delete", "button").click()
uiutils.check(lambda: not delete.active)
uiutils.check(lambda: os.path.exists(fname))
lib.utils.check(lambda: not delete.active)
lib.utils.check(lambda: os.path.exists(fname))
# Change CDROM
win.find("IDE CDROM 1", "table cell").click()
tab = win.find("disk-tab", None)
entry = win.find("media-entry")
appl = win.find("config-apply")
uiutils.check(lambda: tab.showing)
lib.utils.check(lambda: tab.showing)
entry.set_text(fname)
appl.click()
uiutils.check(lambda: not appl.sensitive)
uiutils.check(lambda: entry.text == fname)
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: entry.text == fname)
entry.click_secondary_icon()
appl.click()
uiutils.check(lambda: not appl.sensitive)
uiutils.check(lambda: not entry.text)
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not entry.text)
@_vm_wrapper("uitests-hotplug")

View File

@ -1,11 +1,11 @@
# 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
import tests.utils
from . import lib
class Manager(uiutils.UITestCase):
class Manager(lib.testcase.UITestCase):
"""
UI tests for manager window, and basic VM lifecycle stuff
"""
@ -31,25 +31,25 @@ class Manager(uiutils.UITestCase):
c.click()
smenu.click()
force.click()
self._click_alert_button("Are you sure you want", "Yes")
uiutils.check(lambda: run.sensitive, timeout=5)
self.app.click_alert_button("Are you sure you want", "Yes")
lib.utils.check(lambda: run.sensitive, timeout=5)
run.click()
uiutils.check(lambda: not run.sensitive, timeout=5)
lib.utils.check(lambda: not run.sensitive, timeout=5)
pause.click()
uiutils.check(lambda: pause.checked, timeout=5)
lib.utils.check(lambda: pause.checked, timeout=5)
pause.click()
uiutils.check(lambda: not pause.checked, timeout=5)
lib.utils.check(lambda: not pause.checked, timeout=5)
smenu.click()
save.click()
uiutils.check(lambda: run.sensitive, timeout=5)
uiutils.check(lambda: "Saved" in c.text)
lib.utils.check(lambda: run.sensitive, timeout=5)
lib.utils.check(lambda: "Saved" in c.text)
run.click()
uiutils.check(lambda: shutdown.sensitive, timeout=5)
lib.utils.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.app.uri = tests.utils.URIs.kvm
self._testVMLifecycle()
def testVMNoEventsLifecycle(self):
@ -76,40 +76,40 @@ class Manager(uiutils.UITestCase):
pause = manager.find("Pause", "toggle button")
def confirm_is_running():
uiutils.check(lambda: not run.sensitive)
lib.utils.check(lambda: not run.sensitive)
def confirm_is_shutdown():
uiutils.check(lambda: not shutdown.sensitive)
lib.utils.check(lambda: not shutdown.sensitive)
def confirm_is_paused():
uiutils.check(lambda: pause.checked)
lib.utils.check(lambda: pause.checked)
def confirm_not_paused():
uiutils.check(lambda: not pause.checked)
lib.utils.check(lambda: not pause.checked)
def test_action(action, shutdown=True, confirm=True):
def _select():
cell = manager.find("test\n", "table cell")
cell.click(button=3)
menu = self.app.root.find("vm-action-menu")
uiutils.check(lambda: menu.onscreen)
lib.utils.check(lambda: menu.onscreen)
if shutdown:
smenu = menu.find("Shut Down", "menu")
smenu.point()
uiutils.check(lambda: smenu.onscreen)
lib.utils.check(lambda: smenu.onscreen)
item = smenu.find(action, "menu item")
else:
item = menu.find(action, "menu item")
uiutils.check(lambda: item.onscreen)
lib.utils.check(lambda: item.onscreen)
item.point()
self.sleep(.3)
self.app.sleep(.3)
item.click()
_select()
if confirm:
self._click_alert_button("Are you sure", "No")
self.app.click_alert_button("Are you sure", "No")
_select()
self._click_alert_button("Are you sure", "Yes")
self.app.click_alert_button("Are you sure", "Yes")
test_action("Force Reset")
@ -154,22 +154,22 @@ class Manager(uiutils.UITestCase):
# Attempt cancel which will fail, then find the error message
progwin.find("Cancel", "push button").click()
progwin.find("Error cancelling save job")
uiutils.check(lambda: not progwin.showing, timeout=5)
uiutils.check(lambda: run.sensitive)
lib.utils.check(lambda: not progwin.showing, timeout=5)
lib.utils.check(lambda: run.sensitive)
# Restore will fail and offer to remove managed save
run.click()
self._click_alert_button("remove the saved state", "No")
uiutils.check(lambda: run.sensitive)
self.app.click_alert_button("remove the saved state", "No")
lib.utils.check(lambda: run.sensitive)
run.click()
self._click_alert_button("remove the saved state", "Yes")
uiutils.check(lambda: not run.sensitive)
self.app.click_alert_button("remove the saved state", "Yes")
lib.utils.check(lambda: not run.sensitive)
def testManagerQEMUSetTime(self):
"""
Fake qemu setTime behavior for code coverage
"""
self.app.uri = utils.URIs.kvm
self.app.uri = tests.utils.URIs.kvm
manager = self.app.topwin
run = manager.find("Run", "push button")
smenu = manager.find("Menu", "toggle button")
@ -181,15 +181,15 @@ class Manager(uiutils.UITestCase):
# Save -> resume -> save
smenu.click()
save.click()
uiutils.check(lambda: run.sensitive)
self.sleep(1)
lib.utils.check(lambda: run.sensitive)
self.app.sleep(1)
run.click()
uiutils.check(lambda: not run.sensitive)
self.sleep(1)
lib.utils.check(lambda: not run.sensitive)
self.app.sleep(1)
smenu.click()
save.click()
uiutils.check(lambda: run.sensitive)
self.sleep(1)
lib.utils.check(lambda: run.sensitive)
self.app.sleep(1)
def testManagerVMRunFail(self):
# Force VM startup to fail so we can test the error path
@ -200,7 +200,7 @@ class Manager(uiutils.UITestCase):
c = manager.find("test-clone-simple", "table cell")
c.click()
manager.find("Run", "push button").click()
self._click_alert_button("fake error", "Close")
self.app.click_alert_button("fake error", "Close")
def testManagerColumns(self):
@ -219,7 +219,7 @@ class Manager(uiutils.UITestCase):
manager = self.app.topwin
def _test_sort(name):
col = manager.find(name, "table column header")
uiutils.check(lambda: col.onscreen)
lib.utils.check(lambda: col.onscreen)
# Trigger sorting
col.click()
col.click()
@ -248,11 +248,11 @@ class Manager(uiutils.UITestCase):
Restore previous position when window is reopened
"""
manager = self.app.topwin
host = self._open_host_window("Storage")
host = self.app.open_host_window("Storage")
fmenu = host.find("File", "menu")
fmenu.click()
fmenu.find("View Manager", "menu item").click()
uiutils.check(lambda: manager.active)
lib.utils.check(lambda: manager.active)
# Double click title to maximize
manager.click_title()
@ -263,7 +263,7 @@ class Manager(uiutils.UITestCase):
host.click_title()
host.find("File", "menu").click()
host.find("View Manager", "menu item").click()
uiutils.check(lambda: manager.showing)
lib.utils.check(lambda: manager.showing)
assert manager.position == (newx, newy)
@ -276,7 +276,7 @@ class Manager(uiutils.UITestCase):
"""
Drag a window so it's not obscuring the manager window
"""
uiutils.drag(win, 1000, 1000)
win.drag(1000, 1000)
manager = self.app.topwin
@ -290,7 +290,7 @@ class Manager(uiutils.UITestCase):
# Open clone dialog
c = manager.find("test-clone", "table cell")
c.click()
self.pressKey("Menu")
self.app.rawinput.pressKey("Menu")
self.app.root.find("Clone...", "menu item").click()
clone = self.app.root.find("Clone Virtual Machine", "frame")
_drag(clone)
@ -314,11 +314,11 @@ class Manager(uiutils.UITestCase):
_drag(host)
# Open details
details = self._open_details_window("test-many-devices")
details = self.app.open_details_window("test-many-devices")
_drag(details)
# Close the connection
self.sleep(1)
self.app.sleep(1)
manager.click()
c = manager.find_fuzzy("testdriver.xml", "table cell")
c.click()
@ -326,28 +326,28 @@ class Manager(uiutils.UITestCase):
self.app.root.find("conn-disconnect", "menu item").click()
# Ensure all those windows aren't showing
uiutils.check(lambda: not migrate.showing)
uiutils.check(lambda: not clone.showing)
uiutils.check(lambda: not create.showing)
uiutils.check(lambda: not details.showing)
uiutils.check(lambda: not delete.showing)
lib.utils.check(lambda: not migrate.showing)
lib.utils.check(lambda: not clone.showing)
lib.utils.check(lambda: not create.showing)
lib.utils.check(lambda: not details.showing)
lib.utils.check(lambda: not delete.showing)
# Delete the connection, ensure the host dialog disappears
c = manager.find_fuzzy("testdriver.xml", "table cell")
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: not host.showing)
self.app.click_alert_button("will remove the connection", "Yes")
lib.utils.check(lambda: not host.showing)
def testManagerDefaultStartup(self):
self.app.open(use_uri=False)
manager = self.app.topwin
errlabel = manager.find("error-label")
uiutils.check(
lib.utils.check(
lambda: "Checking for virtualization" in errlabel.text)
uiutils.check(
lib.utils.check(
lambda: "File->Add Connection" in errlabel.text)
uiutils.check(
lib.utils.check(
lambda: "appropriate QEMU/KVM" in errlabel.text)
manager.find("File", "menu").click()
@ -357,6 +357,6 @@ class Manager(uiutils.UITestCase):
self.app.open(keyfile="baduri.ini")
manager = self.app.topwin
manager.find_fuzzy("bad uri", "table cell").doubleClick()
uiutils.check(lambda: not manager.active)
self._click_alert_button("Unable to connect", "Close")
uiutils.check(lambda: manager.active)
lib.utils.check(lambda: not manager.active)
self.app.click_alert_button("Unable to connect", "Close")
lib.utils.check(lambda: manager.active)

View File

@ -1,10 +1,10 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests.uitests import utils as uiutils
from . import lib
class MediaChange(uiutils.UITestCase):
class MediaChange(lib.testcase.UITestCase):
"""
UI tests for details storage media change
"""
@ -14,7 +14,7 @@ class MediaChange(uiutils.UITestCase):
##############
def testMediaChange(self):
win = self._open_details_window(shutdown=True)
win = self.app.open_details_window("test-many-devices", shutdown=True)
hw = win.find("hw-list")
tab = win.find("disk-tab")
combo = win.find("media-combo")
@ -25,27 +25,27 @@ class MediaChange(uiutils.UITestCase):
hw.find("Floppy 1", "table cell").click()
combo.click_combo_entry()
combo.find(r"Floppy_install_label \(/dev/fdb\)")
uiutils.check(lambda: entry.text == "No media detected (/dev/fda)")
lib.utils.check(lambda: entry.text == "No media detected (/dev/fda)")
entry.click()
entry.click_secondary_icon()
uiutils.check(lambda: not entry.text)
lib.utils.check(lambda: not entry.text)
appl.click()
uiutils.check(lambda: not appl.sensitive)
uiutils.check(lambda: not entry.text)
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not entry.text)
# Enter /dev/fdb, after apply it should change to pretty label
entry.set_text("/dev/fdb")
appl.click()
uiutils.check(lambda: not appl.sensitive)
uiutils.check(lambda:
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda:
entry.text == "Floppy_install_label (/dev/fdb)")
# Specify manual path
path = "/tmp/aaaaaaaaaaaaaaaaaaaaaaa.img"
entry.set_text(path)
appl.click()
uiutils.check(lambda: not appl.sensitive)
uiutils.check(lambda: entry.text == path)
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: entry.text == path)
# Go to Floppy 2, make sure previous path is in recent list
hw.find("Floppy 2", "table cell").click()
@ -54,7 +54,7 @@ class MediaChange(uiutils.UITestCase):
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")
self.app.select_storagebrowser_volume("default-pool", "iso-vol")
appl.click()
# Browse for image
@ -63,41 +63,41 @@ class MediaChange(uiutils.UITestCase):
combo.find(r"Fedora12_media \(/dev/sr0\)")
entry.click()
tab.find("Browse", "push button").click()
self._select_storagebrowser_volume("default-pool", "backingl1.img")
self.app.select_storagebrowser_volume("default-pool", "backingl1.img")
# Check 'already in use' dialog
appl.click()
self._click_alert_button("already in use by", "No")
uiutils.check(lambda: appl.sensitive)
self.app.click_alert_button("already in use by", "No")
lib.utils.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)
self.app.click_alert_button("already in use by", "Yes")
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: "backing" in entry.text)
entry.set_text("")
appl.click()
uiutils.check(lambda: not appl.sensitive)
uiutils.check(lambda: not entry.text)
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not entry.text)
def testMediaHotplug(self):
"""
Test in the case of a running VM
"""
win = self._open_details_window()
win = self.app.open_details_window("test-many-devices")
hw = win.find("hw-list")
entry = win.find("media-entry")
appl = win.find("config-apply")
# CDROM + physical
hw.find("IDE CDROM 1", "table cell").click()
uiutils.check(lambda: not entry.text)
lib.utils.check(lambda: not entry.text)
entry.set_text("/dev/sr0")
appl.click()
self._click_alert_button("changes will take effect", "OK")
uiutils.check(lambda: not appl.sensitive)
uiutils.check(lambda: not entry.text)
self.app.click_alert_button("changes will take effect", "OK")
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not entry.text)
# Shutdown the VM, verify change shows up
win.find("Shut Down", "push button").click()
run = win.find("Run", "push button")
uiutils.check(lambda: run.sensitive)
uiutils.check(lambda: entry.text == "Fedora12_media (/dev/sr0)")
lib.utils.check(lambda: run.sensitive)
lib.utils.check(lambda: entry.text == "Fedora12_media (/dev/sr0)")

View File

@ -1,11 +1,11 @@
# 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
import tests.utils
from . import lib
class VMMMigrate(uiutils.UITestCase):
class VMMMigrate(lib.testcase.UITestCase):
"""
UI tests for the migrate dialog
"""
@ -22,7 +22,7 @@ class VMMMigrate(uiutils.UITestCase):
win.combo_select("Hypervisor", "Custom URI")
win.find("uri-entry", "text").set_text(uri)
win.find("Connect", "push button").click()
uiutils.check(lambda: win.showing is False)
lib.utils.check(lambda: win.showing is False)
def _open_migrate(self, vmname):
c = self.app.root.find(vmname, "table cell")
@ -32,28 +32,28 @@ class VMMMigrate(uiutils.UITestCase):
def testMigrateQemu(self):
# Use fake qemu connections
self.app.uri = utils.URIs.kvm
self._add_conn(utils.URIs.test_default +
self.app.uri = tests.utils.URIs.kvm
self._add_conn(tests.utils.URIs.test_default +
",fakeuri=qemu+tcp://fakehost/system")
# Run default migrate
mig = self._open_migrate("test-many-devices")
mig.find("Migrate", "push button").click()
self._click_alert_button(
self.app.click_alert_button(
"the.connection.driver:.virDomainMigrate", "Close")
mig.find("Cancel", "push button").click()
uiutils.check(lambda: not mig.showing)
lib.utils.check(lambda: not mig.showing)
# Run with deselected URI
mig = self._open_migrate("test-many-devices")
mig.find("address-check").click()
label = mig.find("Let libvirt decide")
uiutils.check(lambda: label.onscreen)
lib.utils.check(lambda: label.onscreen)
mig.find("Migrate", "push button").click()
self._click_alert_button(
self.app.click_alert_button(
"the.connection.driver:.virDomainMigrate", "Close")
mig.find("Cancel", "push button").click()
uiutils.check(lambda: not mig.showing)
lib.utils.check(lambda: not mig.showing)
# Run with tunnelled and other options
mig = self._open_migrate("test-many-devices")
@ -63,25 +63,25 @@ class VMMMigrate(uiutils.UITestCase):
mig.find("Temporary", "check box").click()
mig.find("Migrate", "push button").click()
self._click_alert_button("p2p migration", "Close")
self.app.click_alert_button("p2p migration", "Close")
mig.find("Cancel", "push button").click()
uiutils.check(lambda: not mig.showing)
lib.utils.check(lambda: not mig.showing)
def testMigrateXen(self):
# Use fake xen connections
self.app.uri = utils.URIs.test_full + ",fakeuri=xen:///"
self.app.uri = tests.utils.URIs.test_full + ",fakeuri=xen:///"
fakeremotexen = (utils.URIs.test_default +
fakeremotexen = (tests.utils.URIs.test_default +
",fakeuri=xen+tcp://fakehost/")
self._add_conn(fakeremotexen)
# Run default migrate
mig = self._open_migrate("test-many-devices")
mig.find("Migrate", "push button").click()
self._click_alert_button(
self.app.click_alert_button(
"the.connection.driver:.virDomainMigrate", "Close")
mig.find("Cancel", "push button").click()
uiutils.check(lambda: not mig.showing)
lib.utils.check(lambda: not mig.showing)
def testMigrateMock(self):
"""
@ -99,26 +99,26 @@ class VMMMigrate(uiutils.UITestCase):
# Attempt cancel which will fail, then find the error message
progwin.find("Cancel", "push button").click()
progwin.find("Error cancelling migrate job")
uiutils.check(lambda: not progwin.showing, timeout=5)
uiutils.check(lambda: not mig.showing)
lib.utils.check(lambda: not progwin.showing, timeout=5)
lib.utils.check(lambda: not mig.showing)
def testMigrateConnMismatch(self):
# Add a possible target but disconnect it
self.app.uri = utils.URIs.test_default
self.app.uri = tests.utils.URIs.test_default
c = self.app.root.find("test default", "table cell")
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
# Add a mismatched hv connection
fakexen = utils.URIs.test_empty + ",fakeuri=xen:///"
fakexen = tests.utils.URIs.test_empty + ",fakeuri=xen:///"
self._add_conn(fakexen)
# Open dialog and confirm no conns are available
self._add_conn(utils.URIs.test_full)
self._add_conn(tests.utils.URIs.test_full)
mig = self._open_migrate("test-many-devices")
mig.find("conn-combo").find("No usable", "menu item")
mig.keyCombo("<alt>F4")
uiutils.check(lambda: not mig.showing)
lib.utils.check(lambda: not mig.showing)
def testMigrateXMLEditor(self):
self.app.open(xmleditor_enabled=True)
@ -140,7 +140,7 @@ class VMMMigrate(uiutils.UITestCase):
">%s<" % vmname, ">%s<" % newname)
xmleditor.set_text(newtext)
win.find("Migrate", "push button").click()
uiutils.check(lambda: not win.showing, timeout=10)
lib.utils.check(lambda: not win.showing, timeout=10)
manager.find(newname, "table cell")
@ -148,6 +148,6 @@ class VMMMigrate(uiutils.UITestCase):
win = self._open_migrate(vmname)
win.find("address-text").set_text("TESTSUITE-FAKE")
finish = win.find("Migrate", "push button")
self._test_xmleditor_interactions(win, finish)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
win.find("Cancel", "push button").click()
uiutils.check(lambda: not win.visible)
lib.utils.check(lambda: not win.visible)

View File

@ -1,10 +1,10 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests.uitests import utils as uiutils
from . import lib
class VMMPrefs(uiutils.UITestCase):
class VMMPrefs(lib.testcase.UITestCase):
"""
UI tests for the preferences dialog
"""
@ -24,16 +24,16 @@ class VMMPrefs(uiutils.UITestCase):
consoletab = win.find("console-tab")
feedbacktab = win.find("feedback-tab")
uiutils.check(lambda: not feedbacktab.onscreen)
lib.utils.check(lambda: not feedbacktab.onscreen)
tab = generaltab
uiutils.check(lambda: tab.onscreen)
lib.utils.check(lambda: tab.onscreen)
tab.find_fuzzy("Enable system tray", "check").click()
tab.find_fuzzy("Enable XML").click()
tab.find_fuzzy("libguestfs VM").click()
win.find("Polling", "page tab").click()
tab = pollingtab
uiutils.check(lambda: tab.onscreen)
lib.utils.check(lambda: tab.onscreen)
tab.find("Poll CPU", "check box").click()
tab.find("Poll Disk", "check box").click()
tab.find("Poll Memory", "check box").click()
@ -44,7 +44,7 @@ class VMMPrefs(uiutils.UITestCase):
win.find("New VM", "page tab").click()
tab = newvmtab
uiutils.check(lambda: tab.onscreen)
lib.utils.check(lambda: tab.onscreen)
tab.find("Add sound device", "check box").click()
tab.combo_select("CPU default:", "Copy host")
tab.combo_select("Storage format:", "Raw")
@ -53,7 +53,7 @@ class VMMPrefs(uiutils.UITestCase):
win.find("Console", "page tab").click()
tab = consoletab
uiutils.check(lambda: tab.onscreen)
lib.utils.check(lambda: tab.onscreen)
tab.combo_select("SPICE USB", "Manual redirect")
tab.combo_select("Resize guest", "On")
tab.combo_select("Graphical console scaling", "Always")
@ -65,23 +65,23 @@ class VMMPrefs(uiutils.UITestCase):
# On certain environments pressing "Alt_L" and
# clicking a window starts window drag operation.
# Work around by pushing both Control and Alt.
self.holdKey("Control_L")
self.holdKey("Alt_L")
self.holdKey("Z")
self.app.rawinput.holdKey("Control_L")
self.app.rawinput.holdKey("Alt_L")
self.app.rawinput.holdKey("Z")
# Test releasekey handler
self.releaseKey("Z")
self.holdKey("Z")
self.app.rawinput.releaseKey("Z")
self.app.rawinput.holdKey("Z")
try:
keyframe.find_fuzzy("OK", "push button").click()
finally:
self.releaseKey("Z")
self.releaseKey("Alt_L")
self.releaseKey("Control_L")
self.app.rawinput.releaseKey("Z")
self.app.rawinput.releaseKey("Alt_L")
self.app.rawinput.releaseKey("Control_L")
win.find("Feedback", "page tab").click()
tab = feedbacktab
uiutils.check(lambda: tab.onscreen)
lib.utils.check(lambda: tab.onscreen)
tab.find("Force Poweroff", "check box").click()
tab.find("Poweroff/Reboot", "check box").click()
tab.find("Pause", "check box").click()
@ -93,22 +93,22 @@ class VMMPrefs(uiutils.UITestCase):
win.find_fuzzy("Enable system tray", "check").click()
win.find_fuzzy("Close", "push button").click()
uiutils.check(lambda: win.visible is False)
lib.utils.check(lambda: win.visible is False)
def testPrefsXMLEditor(self):
managerwin = self.app.topwin
uiutils.drag(managerwin, 0, 200)
detailswin = self._open_details_window(vmname="test-clone-simple")
managerwin.drag(0, 200)
detailswin = self.app.open_details_window("test-clone-simple")
finish = detailswin.find("config-apply")
xmleditor = detailswin.find("XML editor")
detailswin.find("XML", "page tab").click()
warnlabel = detailswin.find_fuzzy("XML editing is disabled")
uiutils.check(lambda: warnlabel.visible)
lib.utils.check(lambda: warnlabel.visible)
origtext = xmleditor.text
xmleditor.typeText("1234abcd")
uiutils.check(lambda: xmleditor.text == origtext)
lib.utils.check(lambda: xmleditor.text == origtext)
managerwin.click_title()
managerwin.grabFocus()
@ -117,7 +117,7 @@ class VMMPrefs(uiutils.UITestCase):
prefswin = self.app.root.find_fuzzy("Preferences", "frame")
prefswin.find_fuzzy("Enable XML").click()
prefswin.find_fuzzy("Close", "push button").click()
uiutils.check(lambda: prefswin.visible is False)
lib.utils.check(lambda: prefswin.visible is False)
managerwin.keyCombo("<alt>F4")
detailswin.click()
@ -125,7 +125,7 @@ class VMMPrefs(uiutils.UITestCase):
xmleditor.set_text(newtext)
finish.click()
detailswin.find("Details", "page tab").click()
uiutils.check(lambda:
lib.utils.check(lambda:
detailswin.find("Title:", "text").text == "FOOTITLE")
def testPrefsKeyfile(self):

View File

@ -1,10 +1,10 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from tests.uitests import utils as uiutils
from . import lib
class Snapshots(uiutils.UITestCase):
class Snapshots(lib.testcase.UITestCase):
"""
UI tests for virt-manager's VM snapshots
"""
@ -33,7 +33,7 @@ class Snapshots(uiutils.UITestCase):
win = self._open_snapshots_window()
errlabel = win.find("snapshot-error-label", "label")
lst = win.find("snapshot-list", "table")
self._walkUIList(win, lst, lambda: errlabel.showing)
lib.utils.walkUIList(self.app, win, lst, lambda: errlabel.showing)
def testSnapshotLifecycle(self):
"""
@ -48,25 +48,25 @@ class Snapshots(uiutils.UITestCase):
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)
self.app.click_alert_button("run the snapshot '%s'" % snapname, "Yes")
lib.utils.check(lambda: not vmrun.sensitive)
# Start offline snapshot
snapname = "offline-root"
win.find(snapname, "table cell").click()
snaprun.click()
self._click_alert_button("run the snapshot '%s'" % snapname, "No")
uiutils.check(lambda: not vmrun.sensitive)
self.app.click_alert_button("run the snapshot '%s'" % snapname, "No")
lib.utils.check(lambda: not vmrun.sensitive)
snaprun.click()
self._click_alert_button("run the snapshot '%s'" % snapname, "Yes")
uiutils.check(lambda: vmrun.sensitive)
self.app.click_alert_button("run the snapshot '%s'" % snapname, "Yes")
lib.utils.check(lambda: vmrun.sensitive)
# Start paused snapshot
snapname = "snap-paused"
win.find(snapname, "table cell").click()
snaprun.click()
self._click_alert_button("run the snapshot '%s'" % snapname, "Yes")
uiutils.check(lambda: vmpause.checked)
self.app.click_alert_button("run the snapshot '%s'" % snapname, "Yes")
lib.utils.check(lambda: vmpause.checked)
# Edit snapshot
descui = win.find("snapshot-description")
@ -74,12 +74,12 @@ class Snapshots(uiutils.UITestCase):
descui.set_text(desc)
win.find("snapshot-apply", "push button").click()
win.find("snapshot-refresh", "push button").click()
uiutils.check(lambda: descui.text == desc)
lib.utils.check(lambda: descui.text == desc)
# Apply by clicking away
desc += " ROUND2"
descui.set_text(desc)
win.find("internal-root", "table cell").click()
self._click_alert_button("There are unapplied changes", "Yes")
self.app.click_alert_button("There are unapplied changes", "Yes")
# Create new snapshot
win.find("snapshot-add", "push button").click()
@ -88,17 +88,17 @@ class Snapshots(uiutils.UITestCase):
newwin.find("Name:", "text").set_text(snapname)
newwin.find("Description:", "text").set_text("testdesc")
newwin.find("Finish", "push button").click()
uiutils.check(lambda: not newwin.showing)
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname, "table cell")
uiutils.check(lambda: newc.state_selected)
lib.utils.check(lambda: newc.state_selected)
# Delete it
win.find("snapshot-delete", "push button").click()
self._click_alert_button("permanently delete", "No")
uiutils.check(lambda: not newc.dead)
self.app.click_alert_button("permanently delete", "No")
lib.utils.check(lambda: not newc.dead)
win.find("snapshot-delete", "push button").click()
self._click_alert_button("permanently delete", "Yes")
uiutils.check(lambda: newc.dead)
self.app.click_alert_button("permanently delete", "Yes")
lib.utils.check(lambda: newc.dead)
# Recreate another snapshot with the same name
win.find("snapshot-add", "push button").click()
@ -106,13 +106,13 @@ class Snapshots(uiutils.UITestCase):
snapname = "testnewsnap"
newwin.find("Name:", "text").set_text(snapname)
newwin.find("Finish", "push button").click()
uiutils.check(lambda: not newwin.showing)
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname, "table cell")
uiutils.check(lambda: newc.state_selected)
lib.utils.check(lambda: newc.state_selected)
# Switch out of window
win.find("Details", "radio button").click()
uiutils.check(lambda: not snaprun.showing)
lib.utils.check(lambda: not snaprun.showing)
def testSnapshotMisc1(self):
"""
@ -121,7 +121,7 @@ class Snapshots(uiutils.UITestCase):
manager = self.app.topwin
manager.find("vm-list").click()
for ignore in range(8):
self.pressKey("Down")
self.app.rawinput.pressKey("Down")
vmname = "test-state-managedsave"
cell = manager.find_fuzzy(vmname, "table cell")
cell.bring_on_screen()
@ -131,62 +131,62 @@ class Snapshots(uiutils.UITestCase):
# Create new snapshot
win.find("snapshot-add", "push button").click()
self._click_alert_button("not become part of the snapshot", "Cancel")
uiutils.check(lambda: win.active)
self.app.click_alert_button("not become part of the snapshot", "Cancel")
lib.utils.check(lambda: win.active)
win.find("snapshot-add", "push button").click()
self._click_alert_button("not become part of the snapshot", "OK")
self.app.click_alert_button("not become part of the snapshot", "OK")
newwin = self.app.root.find("Create snapshot", "frame")
snapname1 = "testnewsnap1"
newwin.find("Name:", "text").set_text(snapname1)
newwin.find("Finish", "push button").click()
uiutils.check(lambda: not newwin.showing)
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname1, "table cell")
uiutils.check(lambda: newc.state_selected)
lib.utils.check(lambda: newc.state_selected)
# Start the VM, create another snapshot
vmrun.click()
uiutils.check(lambda: not vmrun.sensitive)
lib.utils.check(lambda: not vmrun.sensitive)
win.find("snapshot-add", "push button").click()
newwin = self.app.root.find("Create snapshot", "frame")
# Force validation error
newwin.find("Name:", "text").set_text("bad name")
newwin.find("Finish", "push button").click()
self._click_alert_button("validating snapshot", "OK")
self.app.click_alert_button("validating snapshot", "OK")
# Force name collision
newwin.find("Name:", "text").set_text(snapname1)
newwin.find("Finish", "push button").click()
self._click_alert_button(snapname1, "Close")
self.app.click_alert_button(snapname1, "Close")
# Make it succeed
snapname2 = "testnewsnap2"
newwin.find("Name:", "text").set_text(snapname2)
newwin.find("Finish", "push button").click()
uiutils.check(lambda: not newwin.showing)
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname2, "table cell")
uiutils.check(lambda: newc.state_selected)
lib.utils.check(lambda: newc.state_selected)
# Trigger another managed save warning
smenu = win.find("Menu", "toggle button")
smenu.click()
save = smenu.find("Save", "menu item")
save.click()
uiutils.check(lambda: vmrun.sensitive)
lib.utils.check(lambda: vmrun.sensitive)
win.find(snapname1, "table cell").click(button=3)
self.app.root.find("Start snapshot", "menu item").click()
self._click_alert_button("run the snapshot '%s'" % snapname1, "Yes")
self._click_alert_button("no memory state", "Cancel")
self.app.click_alert_button("run the snapshot '%s'" % snapname1, "Yes")
self.app.click_alert_button("no memory state", "Cancel")
win.find("snapshot-start").click()
self._click_alert_button("run the snapshot '%s'" % snapname1, "Yes")
self._click_alert_button("no memory state", "OK")
self.app.click_alert_button("run the snapshot '%s'" % snapname1, "Yes")
self.app.click_alert_button("no memory state", "OK")
# Multi select
cell1 = win.find(snapname1, "table cell")
cell2 = win.find(snapname2, "table cell")
cell1.click()
self.holdKey("Shift_L")
self.pressKey("Down")
self.releaseKey("Shift_L")
self.app.rawinput.holdKey("Shift_L")
self.app.rawinput.pressKey("Down")
self.app.rawinput.releaseKey("Shift_L")
win.find("snapshot-delete").click()
self._click_alert_button("permanently delete", "Yes")
uiutils.check(lambda: cell1.dead)
uiutils.check(lambda: cell2.dead)
uiutils.check(lambda: win.active)
self.app.click_alert_button("permanently delete", "Yes")
lib.utils.check(lambda: cell1.dead)
lib.utils.check(lambda: cell2.dead)
lib.utils.check(lambda: win.active)

View File

@ -2,10 +2,10 @@
# See the COPYING file in the top-level directory.
import tests.utils
from tests.uitests import utils as uiutils
from . import lib
class Systray(uiutils.UITestCase):
class Systray(lib.testcase.UITestCase):
"""
UI tests for virt-manager's systray using a fake testing backend
"""
@ -22,7 +22,7 @@ class Systray(uiutils.UITestCase):
manager = self.app.topwin
systray = self.app.root.find("vmm-fake-systray", check_active=False)
uiutils.drag(manager, 1000, 1000)
manager.drag(1000, 1000)
# Add a connection to trigger systray update
uri = tests.utils.URIs.kvm
@ -36,8 +36,8 @@ class Systray(uiutils.UITestCase):
# Hide the manager
systray.click_title()
systray.click()
uiutils.check(lambda: not manager.showing)
uiutils.check(lambda: self.app.is_running())
lib.utils.check(lambda: not manager.showing)
lib.utils.check(lambda: self.app.is_running())
systray.click(button=3)
menu = self.app.root.find("vmm-systray-menu")
@ -45,21 +45,21 @@ class Systray(uiutils.UITestCase):
def _get_conn_action(connstr, actionstr):
if not menu.showing:
systray.click(button=3)
uiutils.check(lambda: menu.showing)
lib.utils.check(lambda: menu.showing)
connmenu = menu.find(connstr, "menu")
connmenu.point()
return connmenu.find(actionstr, "menu")
def _check_conn_action(connstr, actionstr):
item = _get_conn_action(connstr, actionstr)
uiutils.check(lambda: item.showing)
lib.utils.check(lambda: item.showing)
systray.click(button=3)
uiutils.check(lambda: not menu.showing)
lib.utils.check(lambda: not menu.showing)
def _do_conn_action(connstr, actionstr):
item = _get_conn_action(connstr, actionstr)
item.click()
uiutils.check(lambda: not menu.showing)
lib.utils.check(lambda: not menu.showing)
def _get_vm_action(connstr, vmname, action):
vmenu = _get_conn_action(connstr, vmname)
@ -68,14 +68,14 @@ class Systray(uiutils.UITestCase):
def _check_vm_action(connstr, vmname, action):
item = _get_vm_action(connstr, vmname, action)
uiutils.check(lambda: item.showing)
lib.utils.check(lambda: item.showing)
systray.click(button=3)
uiutils.check(lambda: not menu.showing)
lib.utils.check(lambda: not menu.showing)
def _do_vm_action(connstr, vmname, action):
item = _get_vm_action(connstr, vmname, action)
item.click()
uiutils.check(lambda: not menu.showing)
lib.utils.check(lambda: not menu.showing)
# Right click start a connection
_check_conn_action("QEMU/KVM", "Disconnect")
@ -90,8 +90,8 @@ class Systray(uiutils.UITestCase):
# Reshow the manager
systray.click()
uiutils.check(lambda: manager.showing)
uiutils.check(lambda: self.app.is_running())
lib.utils.check(lambda: manager.showing)
lib.utils.check(lambda: self.app.is_running())
# Close from the menu
systray.click_title()
@ -99,7 +99,7 @@ class Systray(uiutils.UITestCase):
menu = self.app.root.find("vmm-systray-menu")
menu.find("Quit", "menu item").click()
uiutils.check(lambda: not self.app.is_running())
lib.utils.check(lambda: not self.app.is_running())
def testSystrayToggle(self):
self.app.open(
@ -116,9 +116,9 @@ class Systray(uiutils.UITestCase):
# Close the system tray
prefs.click_title()
prefs.find_fuzzy("Enable system tray", "check").click()
uiutils.check(lambda: not systray.showing)
lib.utils.check(lambda: not systray.showing)
# Close the manager
manager.click_title()
manager.keyCombo("<alt>F4")
uiutils.check(lambda: not self.app.is_running())
lib.utils.check(lambda: not self.app.is_running())

View File

@ -1,630 +0,0 @@
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import os
import re
import time
import signal
import subprocess
import sys
import unittest
from gi.repository import Gio
from gi.repository import Gdk
import pyatspi
import dogtail.utils
from virtinst import log
import tests
if not dogtail.utils.isA11yEnabled():
print("Enabling gsettings accessibility")
dogtail.utils.enableA11y()
# This will trigger an error if accessibility isn't enabled
import dogtail.tree # pylint: disable=wrong-import-order,ungrouped-imports
class UITestCase(unittest.TestCase):
"""
Common testcase bits shared for ui tests
"""
def setUp(self):
self.app = VMMDogtailApp(tests.utils.URIs.test_full)
def tearDown(self):
self.app.stop()
_default_vmname = "test-many-devices"
# Helpers to save testfile imports
@staticmethod
def sleep(*args, **kwargs):
return time.sleep(*args, **kwargs)
@staticmethod
def pressKey(*args, **kwargs):
return dogtail.rawinput.pressKey(*args, **kwargs)
def holdKey(self, keyName):
# From dogtail 9.9.0 which isn't widely distributed yet
code = dogtail.rawinput.keyNameToKeyCode(keyName)
pyatspi.Registry().generateKeyboardEvent(
code, None, pyatspi.KEY_PRESS)
def releaseKey(self, keyName):
# From dogtail 9.9.0 which isn't widely distributed yet
code = dogtail.rawinput.keyNameToKeyCode(keyName)
pyatspi.Registry().generateKeyboardEvent(
code, None, pyatspi.KEY_RELEASE)
def point(self, x, y):
# From dogtail 9.9.0 which isn't widely distributed yet
pyatspi.Registry().generateMouseEvent(x, y, 'abs')
#################################
# virt-manager specific helpers #
#################################
def _open_host_window(self, tab, conn_label="test testdriver.xml"):
"""
Helper to open host connection window and switch to a tab
"""
self.app.root.find_fuzzy(conn_label, "table cell").click()
self.app.root.find_fuzzy("Edit", "menu").click()
self.app.root.find_fuzzy("Connection Details", "menu item").click()
win = self.app.root.find_fuzzy(
"%s Connection Details" % conn_label, "frame")
win.find_fuzzy(tab, "page tab").click()
return win
def _open_details_window(self, vmname=None, shutdown=False,
double=False):
if vmname is None:
vmname = self._default_vmname
if double:
self.app.root.find_fuzzy(vmname, "table cell").doubleClick()
else:
self.app.root.find_fuzzy(vmname, "table cell").click(button=3)
self.app.root.find("Open", "menu item").click()
win = self.app.root.find("%s on" % vmname, "frame")
win.find("Details", "radio button").click()
if shutdown:
win.find("Shut Down", "push button").click()
run = win.find("Run", "push button")
check(lambda: run.sensitive)
return win
def _click_alert_button(self, label_text, button_text):
alert = self.app.root.find("vmm dialog", "alert")
alert.find_fuzzy(label_text, "label")
alert.find(button_text, "push button").click()
check(lambda: not alert.active)
def _select_storagebrowser_volume(self, pool, vol, doubleclick=False):
browsewin = self.app.root.find("vmm-storage-browser")
browsewin.find_fuzzy(pool, "table cell").click()
volcell = browsewin.find_fuzzy(vol, "table cell")
if doubleclick:
volcell.doubleClick()
else:
volcell.click()
browsewin.find_fuzzy("Choose Volume").click()
check(lambda: not browsewin.active)
def _walkUIList(self, win, lst, error_cb, reverse=False):
"""
Toggle down through a UI list like addhardware, net/storage/iface
lists, and ensure an error isn't raised.
"""
# Walk the lst UI and find all labelled table cells, these are
# the actual list entries
all_cells = lst.findChildren(lambda w: w.roleName == "table cell")
if reverse:
all_cells.reverse()
all_cells[0].click()
cells_per_selection = len([c for c in all_cells if c.focused])
idx = 0
while idx < len(all_cells):
cell = all_cells[idx]
if not cell.state_selected:
# Could be a separator table cell. Try to figure it out
if not any([c.name for c in
all_cells[idx:(idx + cells_per_selection)]]):
idx += cells_per_selection
continue
check(lambda: cell.state_selected)
dogtail.rawinput.pressKey(reverse and "Up" or "Down")
if not win.active:
# Should mean an error dialog popped up
self.app.root.find("Error", "alert")
raise AssertionError("Error dialog raised?")
if error_cb():
raise AssertionError("Error found on a page")
idx += cells_per_selection
if idx >= len(all_cells):
# Last cell, selection shouldn't have changed
check(lambda: cell.state_selected)
else:
check(lambda: not cell.state_selected)
def _test_xmleditor_interactions(self, win, finish):
"""
Helper to test some common XML editor interactions
"""
# Click the tab, make a bogus XML edit
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
xmleditor.set_text(xmleditor.text.replace("<", "<FOO", 1))
# Trying to click away should warn that there's unapplied changes
win.find("Details", "page tab").click()
# Select 'No', meaning don't abandon changes
self._click_alert_button("changes will be lost", "No")
check(lambda: xmleditor.showing)
# Click the finish button, but our bogus change should trigger error
finish.click()
self._click_alert_button("(xmlParseDoc|tag.mismatch)", "Close")
# Try unapplied changes again, this time abandon our changes
win.find("Details", "page tab").click()
self._click_alert_button("changes will be lost", "Yes")
check(lambda: not xmleditor.showing)
class _FuzzyPredicate(dogtail.predicate.Predicate):
"""
Object dogtail/pyatspi want for node searching.
"""
def __init__(self, name=None, roleName=None, labeller_text=None):
"""
:param name: Match node.name or node.labeller.text if
labeller_text not specified
:param roleName: Match node.roleName
:param labeller_text: Match node.labeller.text
"""
self._name = name
self._roleName = roleName
self._labeller_text = labeller_text
self._name_pattern = None
self._role_pattern = None
self._labeller_pattern = None
if self._name:
self._name_pattern = re.compile(self._name, re.DOTALL)
if self._roleName:
self._role_pattern = re.compile(self._roleName, re.DOTALL)
if self._labeller_text:
self._labeller_pattern = re.compile(self._labeller_text, re.DOTALL)
def makeScriptMethodCall(self, isRecursive):
ignore = isRecursive
return
def makeScriptVariableName(self):
return
def describeSearchResult(self, node=None):
if not node:
return ""
return node.node_string()
def satisfiedByNode(self, node):
"""
The actual search routine
"""
try:
if self._roleName and not self._role_pattern.match(node.roleName):
return
labeller = ""
if node.labeller:
labeller = node.labeller.text
if (self._name and
not self._name_pattern.match(node.name) and
not self._name_pattern.match(labeller)):
return
if (self._labeller_text and
not self._labeller_pattern.match(labeller)):
return
return True
except Exception as e:
log.debug(
"got predicate exception name=%s role=%s labeller=%s: %s",
self._name, self._roleName, self._labeller_text, e)
def check(func, timeout=2):
"""
Run the passed func in a loop every .1 seconds until timeout is hit or
the func returns True.
"""
start_time = time.time()
interval = 0.1
while True:
if func() is True:
return
if (time.time() - start_time) > timeout:
raise RuntimeError("Loop condition wasn't met")
time.sleep(interval)
def _title_coordinates(win):
x = win.position[0] + (win.size[0] / 2)
y = win.position[1] + 10
return x, y
def drag(win, x, y):
"""
Drag a window to the x/y coordinates
"""
time.sleep(.5)
win.click_title()
time.sleep(.5)
clickX, clickY = _title_coordinates(win)
dogtail.rawinput.drag((clickX, clickY), (x, y))
class VMMDogtailNode(dogtail.tree.Node):
"""
Our extensions to the dogtail node wrapper class.
"""
# The class hackery means pylint can't figure this class out
# pylint: disable=no-member
@property
def active(self):
"""
If the window is the raised and active window or not
"""
return self.getState().contains(pyatspi.STATE_ACTIVE)
@property
def state_selected(self):
return self.getState().contains(pyatspi.STATE_SELECTED)
@property
def onscreen(self):
# We need to check that full widget is on screen because we use this
# function to check whether we can click a widget. We may click
# anywhere within the widget and clicks outside the screen bounds are
# silently ignored.
if self.roleName in ["frame"]:
return True
screen = Gdk.Screen.get_default()
return (self.position[0] >= 0 and
self.position[0] + self.size[0] < screen.get_width() and
self.position[1] >= 0 and
self.position[1] + self.size[1] < screen.get_height())
def check_onscreen(self):
"""
Check in a loop that the widget is onscreen
"""
check(lambda: self.onscreen)
def check_sensitive(self):
"""
Check whether interactive widgets are sensitive or not
"""
valid_types = [
"push button",
"toggle button",
"check button",
"combo box",
"menu item",
"text",
"menu",
]
if self.roleName not in valid_types:
return True
check(lambda: self.sensitive)
def click_secondary_icon(self):
"""
Helper for clicking the secondary icon of a text entry
"""
self.check_onscreen()
self.check_sensitive()
button = 1
clickX = self.position[0] + self.size[0] - 10
clickY = self.position[1] + (self.size[1] / 2)
dogtail.rawinput.click(clickX, clickY, button)
def click_combo_entry(self):
"""
Helper for clicking the arrow of a combo entry, to expose the menu.
Clicks middle of Y axis, but 1/10th of the height from the right side.
Using a small, hardcoded offset may not work on some themes (e.g. when
running virt-manager on KDE)
"""
self.check_onscreen()
self.check_sensitive()
button = 1
clickX = self.position[0] + self.size[0] - self.size[1] / 4
clickY = self.position[1] + self.size[1] / 2
dogtail.rawinput.click(clickX, clickY, button)
def click_expander(self):
"""
Helper for clicking expander, hitting the text part to actually
open it. Basically clicks top left corner with some indent
"""
self.check_onscreen()
self.check_sensitive()
button = 1
clickX = self.position[0] + 10
clickY = self.position[1] + 5
dogtail.rawinput.click(clickX, clickY, button)
def click_title(self):
"""
Helper to click a window title bar, hitting the horizontal
center of the bar
"""
if self.roleName not in ["frame", "alert"]:
raise RuntimeError("Can't use click_title() on type=%s" %
self.roleName)
button = 1
clickX, clickY = _title_coordinates(self)
dogtail.rawinput.click(clickX, clickY, button)
def click(self, *args, **kwargs):
"""
click wrapper, give up to a second for widget to appear on
screen, helps reduce some test flakiness
"""
# pylint: disable=arguments-differ,signature-differs
self.check_onscreen()
self.check_sensitive()
dogtail.tree.Node.click(self, *args, **kwargs)
def set_text(self, text):
self.check_onscreen()
self.check_sensitive()
assert hasattr(self, "text")
self.text = text
def bring_on_screen(self, key_name="Down", max_tries=100):
"""
Attempts to bring the item to screen by repeatedly clicking the given
key. Raises exception if max_tries attempts are exceeded.
"""
cur_try = 0
while not self.onscreen:
dogtail.rawinput.pressKey(key_name)
cur_try += 1
if cur_try > max_tries:
raise RuntimeError("Could not bring widget on screen")
return self
#########################
# Widget search helpers #
#########################
def find(self, name, roleName=None, labeller_text=None, check_active=True):
"""
Search root for any widget that contains the passed name/role regex
strings.
"""
pred = _FuzzyPredicate(name, roleName, labeller_text)
try:
ret = self.findChild(pred)
except dogtail.tree.SearchError:
raise dogtail.tree.SearchError("Didn't find widget with name='%s' "
"roleName='%s' labeller_text='%s'" %
(name, roleName, labeller_text)) from None
# Wait for independent windows to become active in the window manager
# before we return them. This ensures the window is actually onscreen
# so it sidesteps a lot of race conditions
if ret.roleName in ["frame", "dialog", "alert"] and check_active:
check(lambda: ret.active)
return ret
def find_fuzzy(self, name, roleName=None, labeller_text=None):
"""
Search root for any widget that contains the passed name/role strings.
"""
name_pattern = None
role_pattern = None
labeller_pattern = None
if name:
name_pattern = ".*%s.*" % name
if roleName:
role_pattern = ".*%s.*" % roleName
if labeller_text:
labeller_pattern = ".*%s.*" % labeller_text
return self.find(name_pattern, role_pattern, labeller_pattern)
##########################
# Higher level behaviors #
##########################
def combo_select(self, combolabel, itemlabel):
"""
Lookup the combo, click it, select the menu item
"""
combo = self.find(combolabel, "combo box")
combo.click_combo_entry()
combo.find(itemlabel, "menu item").click()
def combo_check_default(self, combolabel, itemlabel):
"""
Lookup the combo and verify the menu item is selected
"""
combo = self.find(combolabel, "combo box")
combo.click_combo_entry()
item = combo.find(itemlabel, "menu item")
check(lambda: item.selected)
dogtail.rawinput.pressKey("Escape")
#####################
# Debugging helpers #
#####################
def node_string(self):
msg = "name='%s' roleName='%s'" % (self.name, self.roleName)
if self.labeller:
msg += " labeller.text='%s'" % self.labeller.text
return msg
def fmt_nodes(self):
strs = []
def _walk(node):
try:
strs.append(node.node_string())
except Exception as e:
strs.append("got exception: %s" % e)
self.findChildren(_walk, isLambda=True)
return "\n".join(strs)
def print_nodes(self):
"""
Helper to print the entire node tree for the passed root. Useful
if to figure out the roleName for the object you are looking for
"""
print(self.fmt_nodes())
# This is the same hack dogtail uses to extend the Accessible class.
_bases = list(pyatspi.Accessibility.Accessible.__bases__)
_bases.insert(_bases.index(dogtail.tree.Node), VMMDogtailNode)
_bases.remove(dogtail.tree.Node)
pyatspi.Accessibility.Accessible.__bases__ = tuple(_bases)
class VMMDogtailApp(object):
"""
Wrapper class to simplify dogtail app handling
"""
def __init__(self, uri):
self._proc = None
self._root = None
self._topwin = None
self.uri = uri
@property
def root(self):
if self._root is None:
self.open()
return self._root
@property
def topwin(self):
if self._topwin is None:
self.open()
return self._topwin
def error_if_already_running(self):
# Ensure virt-manager isn't already running
dbus = Gio.DBusProxy.new_sync(
Gio.bus_get_sync(Gio.BusType.SESSION, None), 0, None,
"org.freedesktop.DBus", "/org/freedesktop/DBus",
"org.freedesktop.DBus", None)
if "org.virt-manager.virt-manager" in dbus.ListNames():
raise RuntimeError("virt-manager is already running. "
"Close it before running this test suite.")
def is_running(self):
return bool(self._proc and self._proc.poll() is None)
def open(self, extra_opts=None, check_already_running=True, use_uri=True,
window_name=None, xmleditor_enabled=False, keyfile=None,
break_setfacl=False, first_run=True, no_fork=True,
will_fail=False, enable_libguestfs=False,
firstrun_uri=None, fake_systemd_success=True):
extra_opts = extra_opts or []
if tests.utils.TESTCONFIG.debug and no_fork:
stdout = sys.stdout
stderr = sys.stderr
extra_opts.append("--debug")
else:
stdout = open(os.devnull)
stderr = open(os.devnull)
cmd = [sys.executable]
cmd += [os.path.join(tests.utils.TOPDIR, "virt-manager")]
if no_fork:
cmd += ["--no-fork"]
if use_uri:
cmd += ["--connect", self.uri]
if first_run:
cmd.append("--test-options=first-run")
if not firstrun_uri:
firstrun_uri = ""
if firstrun_uri is not None:
cmd.append("--test-options=firstrun-uri=%s" % firstrun_uri)
if xmleditor_enabled:
cmd.append("--test-options=xmleditor-enabled")
if break_setfacl:
cmd.append("--test-options=break-setfacl")
if enable_libguestfs is True:
cmd.append("--test-options=enable-libguestfs")
if enable_libguestfs is False:
cmd.append("--test-options=disable-libguestfs")
if fake_systemd_success:
cmd.append("--test-options=fake-systemd-success")
if keyfile:
import atexit
import tempfile
keyfile = tests.utils.UITESTDATADIR + "/keyfile/" + keyfile
tempname = tempfile.mktemp(prefix="virtmanager-uitests-keyfile")
open(tempname, "w").write(open(keyfile).read())
atexit.register(lambda: os.unlink(tempname))
cmd.append("--test-options=gsettings-keyfile=%s" % tempname)
cmd += extra_opts
if check_already_running:
self.error_if_already_running()
self._proc = subprocess.Popen(cmd, stdout=stdout, stderr=stderr)
if not will_fail:
self._root = dogtail.tree.root.application("virt-manager")
self._topwin = self._root.find(window_name, "(frame|dialog|alert)")
def wait_for_exit(self):
# Wait for shutdown for 2 sec
waittime = 2
for ignore in range(int(waittime / .05)):
time.sleep(.05)
if self._proc.poll() is not None:
self._proc = None
return True
return False
def stop(self):
"""
Try graceful process shutdown, then kill it
"""
if not self._proc:
return
try:
self._proc.send_signal(signal.SIGINT)
except Exception:
log.debug("Error terminating process", exc_info=True)
self._proc = None
return
if self.wait_for_exit():
return
log.warning("App didn't exit gracefully from SIGINT. Killing...")
self._proc.kill()
self.wait_for_exit()