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:
parent
aa9fcdfdb2
commit
ebf76563b8
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
|
@ -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)")
|
|
@ -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()
|
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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": ""})
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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.*")
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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()
|
Loading…
Reference in New Issue