uitests: big mess of work

* Convert to pytest style functions
* Move lots of shared code to our App class
* Reduce dogtail sleep amounts to speed up the whole testsuite
* Improve robustness in a lot of areas

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2020-09-18 17:27:50 -04:00
parent 799c82584c
commit 8ce83dbc53
27 changed files with 5712 additions and 5650 deletions

View File

@ -5,4 +5,3 @@ from . import _dogtailinit
from . import _node
from . import app
from . import utils
from . import testcase

View File

@ -16,11 +16,13 @@ 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
# find() backoff handling
dogtail.config.config.searchBackoffDuration = .1
dogtail.config.config.searchCutoffCount = 20
# Use .1 second delay between each action (default 1)
dogtail.config.config.actionDelay = .1
dogtail.config.config.defaultDelay = .1
# Turn off needlessly noisy debugging
DOGTAIL_DEBUG = False

View File

@ -210,7 +210,17 @@ class _VMMDogtailNode(dogtail.tree.Node):
# pylint: disable=arguments-differ,signature-differs
self.check_onscreen()
self.check_sensitive()
dogtail.tree.Node.click(self, *args, **kwargs)
super().click(*args, **kwargs)
def point(self, *args, **kwargs):
# pylint: disable=signature-differs
super().point(*args, **kwargs)
if (self.roleName == "menu" and
self.accessible_parent.roleName == "menu"):
# Widget is a submenu, make sure the item is in selected
# state before we return
utils.check(lambda: self.state_selected)
def set_text(self, text):
self.check_onscreen()
@ -231,12 +241,29 @@ class _VMMDogtailNode(dogtail.tree.Node):
raise RuntimeError("Could not bring widget on screen")
return self
def window_maximize(self):
assert self.roleName in ["frame", "dialog"]
utils.check(lambda: self.active)
self.click_title()
s1 = self.size
self.keyCombo("<alt>F10")
utils.check(lambda: self.size != s1)
self.grabFocus()
def window_close(self):
assert self.roleName in ["frame", "alert", "dialog"]
self.click_title()
utils.check(lambda: self.active)
self.keyCombo("<alt>F4")
utils.check(lambda: not self.showing)
#########################
# Widget search helpers #
#########################
def find(self, name, roleName=None, labeller_text=None, check_active=True):
def find(self, name, roleName=None, labeller_text=None,
check_active=True, recursive=True):
"""
Search root for any widget that contains the passed name/role regex
strings.
@ -244,7 +271,7 @@ class _VMMDogtailNode(dogtail.tree.Node):
pred = _FuzzyPredicate(name, roleName, labeller_text)
try:
ret = self.findChild(pred)
ret = self.findChild(pred, recursive=recursive)
except dogtail.tree.SearchError:
raise dogtail.tree.SearchError("Didn't find widget with name='%s' "
"roleName='%s' labeller_text='%s'" %
@ -325,6 +352,9 @@ class _VMMDogtailNode(dogtail.tree.Node):
"""
print(self.fmt_nodes())
def print_states(self):
print([s.value_nick for s in self.getState().get_states()])
# This is the same hack dogtail uses to extend the Accessible class.
_bases = list(pyatspi.Accessibility.Accessible.__bases__)

View File

@ -24,6 +24,7 @@ class VMMDogtailApp(object):
self._proc = None
self._root = None
self._topwin = None
self._manager = None
self.uri = uri
@ -37,6 +38,11 @@ class VMMDogtailApp(object):
def sleep(self, *args, **kwargs):
return time.sleep(*args, **kwargs)
def find_window(self, name, roleName=None):
if roleName is None:
roleName = "(frame|dialog|alert|window)"
return self.root.find(name=name, roleName=roleName, recursive=False)
rawinput = dogtail.rawinput
tree = dogtail.tree
@ -45,27 +51,16 @@ class VMMDogtailApp(object):
# 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 get_manager(self):
if not self._manager:
self._manager = self.find_window("Virtual Machine Manager")
return self._manager
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()
def find_details_window(self, vmname,
click_details=False, shutdown=False):
win = self.find_window("%s on" % vmname, "frame")
if click_details:
win.find("Details", "radio button").click()
if shutdown:
win.find("Shut Down", "push button").click()
run = win.find("Run", "push button")
@ -73,13 +68,13 @@ class VMMDogtailApp(object):
return win
def click_alert_button(self, label_text, button_text):
alert = self.root.find("vmm dialog", "alert")
alert = self.find_window("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 = self.find_window("vmm-storage-browser")
browsewin.find_fuzzy(pool, "table cell").click()
volcell = browsewin.find_fuzzy(vol, "table cell")
if doubleclick:
@ -90,6 +85,134 @@ class VMMDogtailApp(object):
utils.check(lambda: not browsewin.active)
##########################
# manager window helpers #
##########################
def manager_open_createconn(self):
manager = self.get_manager()
manager.find("File", "menu").click()
manager.find("Add Connection...", "menu item").click()
win = self.root.find("Add Connection", "dialog")
return win
def manager_createconn(self, uri):
win = self.manager_open_createconn()
win.combo_select("Hypervisor", "Custom URI")
win.find("uri-entry", "text").set_text(uri)
win.find("Connect", "push button").click()
utils.check(lambda: win.showing is False)
def manager_get_conn_cell(self, conn_label):
return self.get_manager().find(conn_label, "table cell")
def manager_conn_connect(self, conn_label):
c = self.manager_get_conn_cell(conn_label)
c.click(button=3)
self.root.find("conn-connect", "menu item").click()
utils.check(lambda: "Not Connected" not in c.text)
return c
def manager_conn_disconnect(self, conn_label):
c = self.manager_get_conn_cell(conn_label)
c.click(button=3)
self.root.find("conn-disconnect", "menu item").click()
utils.check(lambda: "Not Connected" in c.text)
return c
def manager_conn_delete(self, conn_label):
c = self.manager_get_conn_cell(conn_label)
c.click(button=3)
self.root.find("conn-delete", "menu item").click()
self.click_alert_button("will remove the connection", "Yes")
utils.check(lambda: c.dead)
def manager_vm_action(self, vmname, confirm_click_no=False,
run=False, shutdown=False, destroy=False, reset=False,
reboot=False, pause=False, resume=False, save=False,
restore=False, clone=False, migrate=False, delete=False,
details=False):
manager = self.get_manager()
vmcell = manager.find(vmname + "\n", "table cell")
if run:
action = "Run"
if shutdown:
action = "Shut Down"
if reboot:
action = "Reboot"
if reset:
action = "Force Reset"
if destroy:
action = "Force Off"
if pause:
action = "Pause"
if resume:
action = "Resume"
if save:
action = "Save"
if restore:
action = "Restore"
if clone:
action = "Clone"
if migrate:
action = "Migrate"
if delete:
action = "Delete"
if details:
action = "Open"
needs_shutdown = shutdown or destroy or reset or reboot or save
needs_confirm = needs_shutdown or pause
def _do_click():
vmcell.click()
vmcell.click(button=3)
menu = self.root.find("vm-action-menu")
utils.check(lambda: menu.onscreen)
if needs_shutdown:
smenu = menu.find("Shut Down", "menu")
smenu.point()
utils.check(lambda: smenu.onscreen)
item = smenu.find(action, "menu item")
else:
item = menu.find(action, "menu item")
utils.check(lambda: item.onscreen)
item.point()
utils.check(lambda: item.state_selected)
item.click()
return menu
m = _do_click()
if needs_confirm:
if confirm_click_no:
self.click_alert_button("Are you sure", "No")
m = _do_click()
self.click_alert_button("Are you sure", "Yes")
utils.check(lambda: not m.onscreen)
def manager_open_clone(self, vmname):
self.manager_vm_action(vmname, clone=True)
return self.find_window("Clone Virtual Machine")
def manager_open_details(self, vmname, shutdown=False):
self.manager_vm_action(vmname, details=True)
win = self.find_details_window(vmname,
shutdown=shutdown, click_details=True)
return win
def manager_open_host(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.find_window("%s - Connection Details" % conn_label)
win.find_fuzzy(tab, "page tab").click()
return win
###########################
# Process management APIs #
###########################
@ -156,7 +279,7 @@ class VMMDogtailApp(object):
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):
firstrun_uri=None, show_console=None):
extra_opts = extra_opts or []
uri = uri or self.uri
@ -174,6 +297,8 @@ class VMMDogtailApp(object):
cmd += ["--no-fork"]
if use_uri:
cmd += ["--connect", uri]
if show_console:
cmd += ["--show-domain-console=%s" % show_console]
if first_run:
cmd.append("--test-options=first-run")
@ -205,4 +330,4 @@ class VMMDogtailApp(object):
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)")
self._topwin = self.find_window(window_name)

View File

@ -1,16 +0,0 @@
# 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()

File diff suppressed because it is too large Load Diff

View File

@ -6,192 +6,201 @@ import unittest.mock
from . import lib
class VMMCLI(lib.testcase.UITestCase):
# UI tests for virt-manager's command line --show options
def testShowNewVM(app):
app.open(
uri="test:///default",
extra_opts=["--show-domain-creator"])
lib.utils.check(lambda: app.topwin.name == "New VM")
app.topwin.keyCombo("<alt>F4")
app.wait_for_exit()
def testShowHost(app):
app.open(
uri="test:///default",
extra_opts=["--show-host-summary"])
lib.utils.check(lambda: app.topwin.name == "test default - Connection Details")
nametext = app.topwin.find_fuzzy("Name:", "text")
lib.utils.check(lambda: nametext.text == "test default")
app.topwin.keyCombo("<alt>F4")
app.wait_for_exit()
def testShowDetails(app):
app.open(
extra_opts=["--show-domain-editor", "test-clone-simple"])
lib.utils.check(lambda: "test-clone-simple on" in app.topwin.name)
rlabel = app.topwin.find_fuzzy("Guest is not running", "label")
lib.utils.check(lambda: not rlabel.showing)
addhw = app.topwin.find_fuzzy("add-hardware", "button")
lib.utils.check(lambda: addhw.showing)
app.topwin.keyCombo("<alt>F4")
app.wait_for_exit()
def testShowPerformance(app):
domid = "1"
app.open(
uri="test:///default",
extra_opts=["--show-domain-performance", domid])
lib.utils.check(lambda: "test on" in app.topwin.name)
cpulabel = app.topwin.find_fuzzy("CPU usage", "label")
lib.utils.check(lambda: cpulabel.showing)
def testShowConsole(app):
# UUID of test-clone-simple
uuid = "12345678-1234-ffff-1234-12345678ffff"
app.open(
extra_opts=["--show-domain-console", uuid])
lib.utils.check(lambda: "test-clone-simple on" in app.topwin.name)
rlabel = app.topwin.find_fuzzy("Guest is not running", "label")
lib.utils.check(lambda: rlabel.showing)
addhw = app.topwin.find_fuzzy("add-hardware", "button")
lib.utils.check(lambda: not addhw.showing)
def testShowDelete(app):
app.open(
uri="test:///default",
extra_opts=["--show-domain-delete", "test"],
window_name="Delete")
# Ensure details opened too
app.root.find("test on", "frame", check_active=False)
delete = app.topwin
delete.find_fuzzy("Delete", "button").click()
app.wait_for_exit()
def testShowRemoteDBusConnect(app):
"""
UI tests for virt-manager's command line --show options
Test the remote app dbus connection
"""
app.open()
lib.utils.check(lambda: "testdriver" in app.topwin.fmt_nodes())
lib.utils.check(lambda: "test default" not in app.topwin.fmt_nodes())
##############
# Test cases #
##############
def _run_remote(opts):
newapp = lib.app.VMMDogtailApp("test:///default")
newapp.open(check_already_running=False,
extra_opts=opts)
lib.utils.check(lambda: not newapp.is_running())
vapps = [a for a in newapp.tree.root.applications() if
a.name == "virt-manager"]
lib.utils.check(lambda: len(vapps) == 1)
# Ensure connection showed up
app.topwin.find("test default", "table cell")
def testShowNewVM(self):
self.app.open(
uri="test:///default",
extra_opts=["--show-domain-creator"])
lib.utils.check(lambda: self.app.topwin.name == "New VM")
self.app.topwin.keyCombo("<alt>F4")
self.app.wait_for_exit()
def testShowHost(self):
self.app.open(
uri="test:///default",
extra_opts=["--show-host-summary"])
lib.utils.check(lambda: self.app.topwin.name == "test default - Connection Details")
nametext = self.app.topwin.find_fuzzy("Name:", "text")
lib.utils.check(lambda: nametext.text == "test default")
self.app.topwin.keyCombo("<alt>F4")
self.app.wait_for_exit()
def testShowDetails(self):
self.app.open(
extra_opts=["--show-domain-editor", "test-clone-simple"])
lib.utils.check(lambda: "test-clone-simple on" in self.app.topwin.name)
rlabel = self.app.topwin.find_fuzzy("Guest is not running", "label")
lib.utils.check(lambda: not rlabel.showing)
addhw = self.app.topwin.find_fuzzy("add-hardware", "button")
lib.utils.check(lambda: addhw.showing)
self.app.topwin.keyCombo("<alt>F4")
self.app.wait_for_exit()
def testShowPerformance(self):
domid = "1"
self.app.open(
uri="test:///default",
extra_opts=["--show-domain-performance", domid])
lib.utils.check(lambda: "test on" in self.app.topwin.name)
cpulabel = self.app.topwin.find_fuzzy("CPU usage", "label")
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])
lib.utils.check(lambda: "test-clone-simple on" in self.app.topwin.name)
rlabel = self.app.topwin.find_fuzzy("Guest is not running", "label")
lib.utils.check(lambda: rlabel.showing)
addhw = self.app.topwin.find_fuzzy("add-hardware", "button")
lib.utils.check(lambda: not addhw.showing)
def testShowDelete(self):
self.app.open(
uri="test:///default",
extra_opts=["--show-domain-delete", "test"],
window_name="Delete")
# Ensure details opened too
self.app.root.find("test on", "frame",
check_active=False)
delete = self.app.topwin
delete.find_fuzzy("Delete", "button").click()
self.app.wait_for_exit()
_run_remote([])
# Run remote again to trigger engine.py code when a connection
# is already there and connected
_run_remote(["--show-domain-console=test"])
def testShowRemoteDBusConnect(self):
"""
Test the remote app dbus connection
"""
self.app.open()
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 testShowCLIError(app):
# Unknown option
app.open(
extra_opts=["--idontexist"])
app.click_alert_button("Unhandled command line", "Close")
lib.utils.check(lambda: not app.is_running())
def _run_remote(opts):
newapp = lib.app.VMMDogtailApp("test:///default")
newapp.open(check_already_running=False,
extra_opts=opts)
lib.utils.check(lambda: not newapp.is_running())
vapps = [a for a in newapp.tree.root.applications() if
a.name == "virt-manager"]
lib.utils.check(lambda: len(vapps) == 1)
# Ensure connection showed up
self.app.topwin.find("test default", "table cell")
# Missing VM
app.open(
uri="test:///default",
extra_opts=["--show-domain-delete", "IDONTEXIST"])
app.click_alert_button("does not have VM", "Close")
lib.utils.check(lambda: not app.is_running())
_run_remote([])
# Run remote again to trigger engine.py code when a connection
# is already there and connected
_run_remote(["--show-domain-console=test"])
# Bad URI
baduri = "fribfrobfroo"
app = lib.app.VMMDogtailApp(baduri)
app.click_alert_button(baduri, "Close")
lib.utils.check(lambda: not app.is_running())
def testShowCLIError(self):
# Unknown option
self.app.open(
extra_opts=["--idontexist"])
self.app.click_alert_button("Unhandled command line", "Close")
lib.utils.check(lambda: not self.app.is_running())
# Missing VM
self.app.open(
uri="test:///default",
extra_opts=["--show-domain-delete", "IDONTEXIST"])
self.app.click_alert_button("does not have VM", "Close")
lib.utils.check(lambda: not self.app.is_running())
def testCLIFirstRunURIGood(app):
# Emulate first run with a URI that will succeed
app.open(use_uri=False, firstrun_uri="test:///default")
app.sleep(1)
app.root.find("test default", "table cell")
# Bad URI
baduri = "fribfrobfroo"
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
self.app.open(use_uri=False, firstrun_uri="test:///default")
self.app.sleep(1)
self.app.root.find("test default", "table cell")
def testCLIFirstRunURIBad(app):
# Emulate first run with a URI that will not succeed
app.open(use_uri=False, firstrun_uri="bad:///uri")
app.sleep(1)
app.topwin.find("bad uri", "table cell")
app.click_alert_button("bad:///uri", "Close")
def testCLIFirstRunURIBad(self):
# Emulate first run with a URI that will not succeed
self.app.open(use_uri=False, firstrun_uri="bad:///uri")
self.app.sleep(1)
self.app.topwin.find("bad uri", "table cell")
self.app.click_alert_button("bad:///uri", "Close")
def testCLIFirstRunNoLibvirtd(self):
# Emulate first run with no libvirtd detected
self.app.open(use_uri=False, firstrun_uri="bad:///uri",
extra_opts=["--test-options=fake-no-libvirtd"])
errlabel = self.app.topwin.find("error-label")
lib.utils.check(
lambda: "Checking for virtualization" in errlabel.text)
lib.utils.check(
lambda: "libvirtd service does not appear" in errlabel.text)
lib.utils.check(
lambda: "detect a default hypervisor" in errlabel.text)
def testCLIFirstRunNoLibvirtd(app):
# Emulate first run with no libvirtd detected
app.open(use_uri=False, firstrun_uri="bad:///uri",
extra_opts=["--test-options=fake-no-libvirtd"])
errlabel = app.topwin.find("error-label")
lib.utils.check(
lambda: "Checking for virtualization" in errlabel.text)
lib.utils.check(
lambda: "libvirtd service does not appear" in errlabel.text)
lib.utils.check(
lambda: "detect a default hypervisor" in errlabel.text)
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.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.app.sleep(2)
# Give it a little time to work
lib.utils.check(lambda: self.app.topwin.active)
self.app.topwin.keyCombo("<alt>F4")
self.app.wait_for_exit()
def testCLITraceLibvirt(app):
# Just test this for code coverage
app.open(keyfile="allstats.ini",
extra_opts=["--trace-libvirt=mainloop"])
# Give it a little time to work
app.sleep(2)
lib.utils.check(lambda: app.topwin.active)
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.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)
self.app.wait_for_exit()
lib.utils.check(lambda: self.app.topwin.showing)
self.app.topwin.keyCombo("<alt>F4")
# Wait for app to exit, we don't have any other way
self.app.sleep(2)
def testCLILeakDebug(app):
# Just test this for code coverage
app.open(keyfile="allstats.ini",
extra_opts=["--test-options=leak-debug"])
app.sleep(2)
# Give it a little time to work
lib.utils.check(lambda: app.topwin.active)
app.topwin.keyCombo("<alt>F4")
app.wait_for_exit()
def testCLIGTKArgs(self):
# Ensure gtk arg passthrough works
self.app.open(extra_opts=["--gtk-debug=misc"])
lib.utils.check(lambda: self.app.topwin.showing)
@unittest.mock.patch.dict('os.environ', {"DISPLAY": ""})
def testCLINoDisplay(self):
# Ensure missing display exits
self.app.open(will_fail=True)
self.app.wait_for_exit()
def testCLINoFirstRun(app):
# Test a simple case of loading without any config override
app.open(first_run=False, enable_libguestfs=None, use_uri=False)
app.sleep(2)
lib.utils.check(lambda: app.topwin.showing)
def testCLINoFork(app):
# Test app without forking
app.open(first_run=False, enable_libguestfs=None,
use_uri=False, no_fork=False)
app.wait_for_exit()
lib.utils.check(lambda: app.topwin.showing)
app.topwin.keyCombo("<alt>F4")
# Wait for app to exit, we don't have any other way
app.sleep(2)
def testCLIGTKArgs(app):
# Ensure gtk arg passthrough works
app.open(extra_opts=["--gtk-debug=misc"])
lib.utils.check(lambda: app.topwin.showing)
@unittest.mock.patch.dict('os.environ', {"DISPLAY": ""})
def testCLINoDisplay(app):
# Ensure missing display exits
app.open(will_fail=True)
app.wait_for_exit()

View File

@ -27,240 +27,225 @@ class _CloneRow:
self.txtcell.click()
class CloneVM(lib.testcase.UITestCase):
"""
UI tests for virt-manager's CloneVM wizard
"""
def _get_all_rows(win):
slist = win.find("storage-list")
def pred(node):
return node.roleName == "table cell"
cells = slist.findChildren(pred, isLambda=True)
###################
# Private helpers #
###################
def _open_window(self, vmname):
# Launch wizard via right click menu
manager = self.app.topwin
manager.click_title()
lib.utils.check(lambda: manager.active)
c = manager.find_fuzzy(vmname, "table cell")
self.app.sleep(.3)
c.click()
c.click(button=3)
item = self.app.root.find("Clone...", "menu item")
item.point()
self.app.sleep(.5)
item.click()
return self.app.root.find("Clone Virtual Machine", "frame")
def _get_all_rows(self, win):
slist = win.find("storage-list")
def pred(node):
return node.roleName == "table cell"
cells = slist.findChildren(pred, isLambda=True)
idx = 0
rows = []
cellcount = 6
while idx < len(cells):
rows.append(_CloneRow(*cells[idx:idx + cellcount]))
idx += cellcount
# Skip the next row which is always a separator
idx += cellcount
return rows
idx = 0
rows = []
cellcount = 6
while idx < len(cells):
rows.append(_CloneRow(*cells[idx:idx + cellcount]))
idx += cellcount
# Skip the next row which is always a separator
idx += cellcount
return rows
##############
# Test cases #
##############
##############################################
# UI tests for virt-manager's CloneVM wizard #
##############################################
def testCloneSimple(self):
# Disable predictable so UUID generation doesn't collide
uri = tests.utils.URIs.test_full.replace(",predictable", "")
self.app.uri = uri
def testCloneSimple(app):
# Disable predictable so UUID generation doesn't collide
uri = tests.utils.URIs.test_full.replace(",predictable", "")
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()
lib.utils.check(lambda: not win.showing)
# Clone 'test-clone-simple' which is the most basic case
# Cancel, and reopen
win = app.manager_open_clone("test-clone-simple")
win.find("Cancel", "push button").click()
lib.utils.check(lambda: not win.showing)
# Do default clone
win = self._open_window("test-clone-simple")
rows = self._get_all_rows(win)
assert len(rows) == 1
assert rows[0].is_clone_requested
rows[0].check_in_text("test-clone-simple.img")
# Do default clone
win = app.manager_open_clone("test-clone-simple")
rows = _get_all_rows(win)
assert len(rows) == 1
assert rows[0].is_clone_requested
rows[0].check_in_text("test-clone-simple.img")
win.find("Clone", "push button").click()
lib.utils.check(lambda: not win.showing)
win.find("Clone", "push button").click()
lib.utils.check(lambda: not win.showing)
# Check path was generated correctly
win = self._open_window("test-clone-simple-clone")
rows = self._get_all_rows(win)
assert len(rows) == 1
assert rows[0].is_clone_requested
rows[0].check_in_text("test-clone-simple-clone.img")
# Check path was generated correctly
win = app.manager_open_clone("test-clone-simple-clone")
rows = _get_all_rows(win)
assert len(rows) == 1
assert rows[0].is_clone_requested
rows[0].check_in_text("test-clone-simple-clone.img")
# Share storage and deal with warnings
rows[0].chkcell.click()
rows[0].check_in_text("Share disk with")
# Do 'cancel' first
win.find("Clone", "push button").click()
self.app.click_alert_button("cause data to be overwritten", "Cancel")
lib.utils.check(lambda: win.active)
win.find("Clone", "push button").click()
self.app.click_alert_button("cause data to be overwritten", "OK")
lib.utils.check(lambda: not win.active)
# Share storage and deal with warnings
rows[0].chkcell.click()
rows[0].check_in_text("Share disk with")
# Do 'cancel' first
win.find("Clone", "push button").click()
app.click_alert_button("cause data to be overwritten", "Cancel")
lib.utils.check(lambda: win.active)
win.find("Clone", "push button").click()
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")
rows = self._get_all_rows(win)
assert len(rows) == 1
rows[0].check_in_text("test-clone-simple-clone.img")
def testCloneMulti(self):
# Clone 'test-clone', check some results, make sure clone works
win = self._open_window("test-clone\n")
win.find("Clone", "push button").click()
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
# it errors gracefully
self.app.topwin.find("test-many-devices").click()
sbutton = self.app.topwin.find("Shut Down", "push button")
sbutton.click()
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.app.click_alert_button("No such file or", "Close")
win.keyCombo("<alt>F4")
lib.utils.check(lambda: not win.showing)
def testCloneStorageChange(self):
# Disable predictable so UUID generation doesn't collide
uri = tests.utils.URIs.test_full.replace(",predictable", "")
self.app.uri = uri
# Trigger some error handling scenarios
win = self._open_window("test-clone-simple")
newname = "test-aaabbb"
win.find("Name:", "text").set_text(newname)
win.find("Clone", "push button").click()
lib.utils.check(lambda: not win.showing)
win = self._open_window(newname)
row = self._get_all_rows(win)[0]
row.check_in_text(newname)
oldnewname = newname
newname = "test-aaazzzzbbb"
win.find("Name:", "text").set_text(newname)
row.select()
win.find("Details", "push button").click()
stgwin = self.app.root.find("Change storage path", "dialog")
pathtxt = stgwin.find(None, "text", "New Path:")
lib.utils.check(lambda: newname in pathtxt.text)
stgwin.find("Browse", "push button").click()
self.app.select_storagebrowser_volume("default-pool", "iso-vol")
lib.utils.check(lambda: "iso-vol" in pathtxt.text)
stgwin.find("OK").click()
self.app.click_alert_button("overwrite the existing", "No")
lib.utils.check(lambda: stgwin.showing)
stgwin.find("OK").click()
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.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")
lib.utils.check(lambda: chkbox.checked)
chkbox.click()
# Cancel and reopen, confirm changes didn't stick
stgwin.find("Cancel").click()
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")
lib.utils.check(lambda: chkbox.checked)
# Requesting sharing again and exit
chkbox.click()
stgwin.find("OK").click()
lib.utils.check(lambda: not stgwin.active)
# Finish install, verify storage was shared
win.find("Clone", "push button").click()
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)
# Verify the new VM shared storage
win = app.manager_open_clone("test-clone-simple-clone1")
rows = _get_all_rows(win)
assert len(rows) == 1
rows[0].check_in_text("test-clone-simple-clone.img")
def testCloneError(self):
# Trigger some error handling scenarios
win = self._open_window("test-clone-full\n")
win.find("Clone", "push button").click()
self.app.click_alert_button("not enough free space", "Close")
lib.utils.check(lambda: win.showing)
win.keyCombo("<alt>F4")
def testCloneMulti(app):
# Clone 'test-clone', check some results, make sure clone works
manager = app.topwin
manager.window_maximize()
win = app.manager_open_clone("test-clone")
win.find("Clone", "push button").click()
lib.utils.check(lambda: not win.showing)
app.topwin.find("test-clone1", "table cell")
win = self._open_window("test-clone-simple")
badname = "test/foo"
win.find("Name:", "text").set_text(badname)
rows = self._get_all_rows(win)
rows[0].chkcell.click()
rows[0].check_in_text("Share disk with")
win.find("Clone", "push button").click()
win.find("Clone", "push button").click()
self.app.click_alert_button("cause data to be overwritten", "OK")
self.app.click_alert_button(badname, "Close")
lib.utils.check(lambda: win.active)
# Check test-many-devices which will not work, but confirm
# it errors gracefully
app.topwin.find("test-many-devices").click()
sbutton = app.topwin.find("Shut Down", "push button")
sbutton.click()
lib.utils.check(lambda: not sbutton.sensitive)
app.sleep(.5)
win = app.manager_open_clone("test-many-devices")
win.find("Clone", "push button").click()
app.click_alert_button("No such file or", "Close")
# Ensure disconnecting will close the dialog
manager.click_title()
app.manager_conn_disconnect("test testdriver.xml")
lib.utils.check(lambda: not win.showing)
def testCloneNonmanaged(self):
# Verify unmanaged clone actual works
import tempfile
tmpsrc = tempfile.NamedTemporaryFile()
tmpdst = tempfile.NamedTemporaryFile()
def testCloneStorageChange(app):
# Disable predictable so UUID generation doesn't collide
uri = tests.utils.URIs.test_full.replace(",predictable", "")
app.uri = uri
open(tmpsrc.name, "w").write(__file__)
# Trigger some error handling scenarios
win = app.manager_open_clone("test-clone-simple")
newname = "test-aaabbb"
win.find("Name:", "text").set_text(newname)
win.find("Clone", "push button").click()
lib.utils.check(lambda: not win.showing)
self.app.open(xmleditor_enabled=True)
manager = self.app.topwin
win = app.manager_open_clone(newname)
row = _get_all_rows(win)[0]
row.check_in_text(newname)
oldnewname = newname
newname = "test-aaazzzzbbb"
win.find("Name:", "text").set_text(newname)
row.select()
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")
origpath = "/dev/default-pool/test-clone-simple.img"
newpath = tmpsrc.name
xmleditor.set_text(xmleditor.text.replace(origpath, newpath))
win.find("config-apply").click()
win.find("Details", "page tab").click()
disksrc = win.find("disk-source-path")
lib.utils.check(lambda: disksrc.text == newpath)
win.keyCombo("<alt>F4")
lib.utils.check(lambda: not win.active)
win.find("Details", "push button").click()
stgwin = app.root.find("Change storage path", "dialog")
pathtxt = stgwin.find(None, "text", "New Path:")
lib.utils.check(lambda: newname in pathtxt.text)
stgwin.find("Browse", "push button").click()
app.select_storagebrowser_volume("default-pool", "iso-vol")
lib.utils.check(lambda: "iso-vol" in pathtxt.text)
stgwin.find("OK").click()
app.click_alert_button("overwrite the existing", "No")
lib.utils.check(lambda: stgwin.showing)
stgwin.find("OK").click()
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()
app.click_alert_button(".*Clone onto existing.*", "Close")
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)
row.select()
# Reopen dialog and request to share it
win.find("Details", "push button").click()
stgwin = app.root.find("Change storage path", "dialog")
chkbox = stgwin.find("Create a new", "check")
lib.utils.check(lambda: chkbox.checked)
chkbox.click()
win.find("Details", "push button").click()
stgwin = self.app.root.find("Change storage path", "dialog")
pathtxt = stgwin.find(None, "text", "New Path:")
os.unlink(tmpdst.name)
pathtxt.set_text(tmpdst.name)
stgwin.find("OK").click()
win.find("Clone", "push button").click()
lib.utils.check(lambda: not win.active)
lib.utils.check(lambda: os.path.exists(tmpdst.name))
# Cancel and reopen, confirm changes didn't stick
stgwin.find("Cancel").click()
lib.utils.check(lambda: not stgwin.showing)
win.find("Details", "push button").click()
stgwin = app.root.find("Change storage path", "dialog")
chkbox = stgwin.find("Create a new", "check")
lib.utils.check(lambda: chkbox.checked)
# Requesting sharing again and exit
chkbox.click()
stgwin.find("OK").click()
lib.utils.check(lambda: not stgwin.active)
assert open(tmpsrc.name).read() == open(tmpdst.name).read()
# Finish install, verify storage was shared
win.find("Clone", "push button").click()
app.click_alert_button("cause data to be overwritten", "OK")
lib.utils.check(lambda: not win.active)
win = app.manager_open_clone(newname)
row = _get_all_rows(win)[0].check_in_text(oldnewname)
def testCloneError(app):
# Trigger some error handling scenarios
win = app.manager_open_clone("test-clone-full")
win.find("Clone", "push button").click()
app.click_alert_button("not enough free space", "Close")
lib.utils.check(lambda: win.showing)
win.keyCombo("<alt>F4")
win = app.manager_open_clone("test-clone-simple")
badname = "test/foo"
win.find("Name:", "text").set_text(badname)
rows = _get_all_rows(win)
rows[0].chkcell.click()
rows[0].check_in_text("Share disk with")
win.find("Clone", "push button").click()
win.find("Clone", "push button").click()
app.click_alert_button("cause data to be overwritten", "OK")
app.click_alert_button(badname, "Close")
lib.utils.check(lambda: win.active)
def testCloneNonmanaged(app):
# Verify unmanaged clone actual works
import tempfile
tmpsrc = tempfile.NamedTemporaryFile()
tmpdst = tempfile.NamedTemporaryFile()
open(tmpsrc.name, "w").write(__file__)
app.open(xmleditor_enabled=True)
manager = app.topwin
win = app.manager_open_details("test-clone-simple")
win.find("IDE Disk 1", "table cell").click()
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
origpath = "/dev/default-pool/test-clone-simple.img"
newpath = tmpsrc.name
xmleditor.set_text(xmleditor.text.replace(origpath, newpath))
win.find("config-apply").click()
win.find("Details", "page tab").click()
disksrc = win.find("disk-source-path")
lib.utils.check(lambda: disksrc.text == newpath)
win.keyCombo("<alt>F4")
lib.utils.check(lambda: not win.active)
lib.utils.check(lambda: manager.active)
win = app.manager_open_clone("test-clone-simple")
row = _get_all_rows(win)[0]
row.check_in_text(tmpsrc.name)
row.select()
win.find("Details", "push button").click()
stgwin = app.root.find("Change storage path", "dialog")
pathtxt = stgwin.find(None, "text", "New Path:")
os.unlink(tmpdst.name)
pathtxt.set_text(tmpdst.name)
stgwin.find("OK").click()
win.find("Clone", "push button").click()
lib.utils.check(lambda: not win.active)
lib.utils.check(lambda: os.path.exists(tmpdst.name))
assert open(tmpsrc.name).read() == open(tmpdst.name).read()

View File

@ -4,109 +4,97 @@
from . import lib
class UITestConnection(lib.testcase.UITestCase):
"""
UI tests for various connection.py related bits
"""
###################################################
# UI tests for various connection.py related bits #
###################################################
##############
# Test cases #
##############
def testConnectionBlacklist(app):
app.open(
extra_opts=["--test-options=object-blacklist=test-many-devices"])
manager = app.topwin
def testConnectionBlacklist(self):
self.app.open(
extra_opts=["--test-options=object-blacklist=test-many-devices"])
manager = self.app.topwin
def _delete_vm(vmname):
cell = manager.find(vmname, "table cell")
cell.click()
cell.click(button=3)
menu = self.app.root.find("vm-action-menu")
menu.find("Delete", "menu item").click()
delete = self.app.root.find_fuzzy("Delete", "frame")
delete.find("Delete associated", "check box").click()
delete.find("Delete", "push button").click()
lib.utils.check(lambda: cell.dead)
lib.utils.check(lambda: manager.active)
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.app.sleep(.5)
lib.utils.check(
lambda: "test-many-devices" not in self.app.topwin.fmt_nodes())
def testConnectionConnCrash(self):
self.app.open(
extra_opts=["--test-options=conn-crash"])
manager = self.app.topwin
self.app.sleep(1)
manager.find(r"^test testdriver.xml - Not Connected", "table cell")
def _delete_vm(vmname):
app.manager_vm_action(vmname, delete=True)
delete = app.find_window("Delete")
delete.find("Delete associated", "check box").click()
delete.find("Delete", "push button").click()
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.app.sleep(2.5)
lib.utils.check(lambda: manager.active)
def testConnectionOpenauth(self):
self.app.open(
extra_opts=["--test-options=fake-openauth"],
window_name="Authentication required")
dialog = self.app.root.find("Authentication required")
def _run():
username = dialog.find("Username:.*entry")
password = dialog.find("Password:.*entry")
username.click()
username.text = "foo"
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: password.focused)
password.typeText("bar")
lib.utils.check(
lambda: "test-many-devices" not in app.topwin.fmt_nodes())
_delete_vm("test-arm-kernel")
_delete_vm("test-clone-full")
_delete_vm("test-clone-simple")
app.sleep(.5)
lib.utils.check(
lambda: "test-many-devices" not in app.topwin.fmt_nodes())
_run()
dialog.find("OK", "push button").click()
lib.utils.check(lambda: not dialog.showing)
manager = self.app.root.find("Virtual Machine Manager", "frame")
manager.find("^test testdriver.xml$", "table cell")
def testConnectionConnCrash(app):
app.open(
extra_opts=["--test-options=conn-crash"])
manager = app.topwin
# Disconnect and reconnect to trigger it again
def _retrigger_connection():
manager.click()
c = manager.find_fuzzy("testdriver.xml", "table cell")
c.click()
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
manager.click()
c = manager.find_fuzzy("testdriver.xml", "table cell")
c.click()
c.click(button=3)
self.app.root.find("conn-connect", "menu item").click()
app.sleep(1)
manager.find(r"^test testdriver.xml - Not Connected", "table cell")
lib.utils.check(lambda: manager.active)
_retrigger_connection()
dialog = self.app.root.find("Authentication required")
_run()
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()
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 testConnectionFakeEvents(app):
app.open(
extra_opts=["--test-options=fake-nodedev-event=computer",
"--test-options=fake-agent-event=test-many-devices"])
manager = app.topwin
app.sleep(2.5)
lib.utils.check(lambda: manager.active)
def testConnectionSessionError(self):
self.app.open(
extra_opts=["--test-options=fake-session-error"])
self.app.click_alert_button("Could not detect a local session", "Close")
def testConnectionOpenauth(app):
app.open(
extra_opts=["--test-options=fake-openauth"],
window_name="Authentication required")
dialog = app.root.find("Authentication required")
def _run():
username = dialog.find("Username:.*entry")
password = dialog.find("Password:.*entry")
username.click()
username.text = "foo"
app.rawinput.pressKey("Enter")
lib.utils.check(lambda: password.focused)
password.typeText("bar")
_run()
dialog.find("OK", "push button").click()
lib.utils.check(lambda: not dialog.showing)
manager = app.find_window("Virtual Machine Manager")
manager.find("^test testdriver.xml$", "table cell")
# Disconnect and reconnect to trigger it again
def _retrigger_connection():
manager.click()
app.manager_conn_disconnect("test testdriver.xml")
manager.click()
app.manager_conn_connect("test testdriver.xml")
_retrigger_connection()
dialog = app.root.find("Authentication required")
_run()
app.rawinput.pressKey("Enter")
lib.utils.check(lambda: not dialog.showing)
manager = app.find_window("Virtual Machine Manager")
manager.find("^test testdriver.xml$", "table cell")
_retrigger_connection()
dialog = app.root.find("Authentication required")
dialog.find("Cancel", "push button").click()
lib.utils.check(lambda: not dialog.showing)
app.click_alert_button("Unable to connect", "Close")
manager.find("test testdriver.xml - Not Connected", "table cell")
def testConnectionSessionError(app):
app.open(
extra_opts=["--test-options=fake-session-error"])
app.click_alert_button("Could not detect a local session", "Close")

View File

@ -4,144 +4,100 @@
from . import lib
class VMMConnect(lib.testcase.UITestCase):
"""
UI tests for the 'open connection' dialog
"""
#############################################
# UI tests for the 'open connection' dialog #
#############################################
##############
# Test cases #
##############
def testConnect(self):
# Start with connection delete
c = self.app.root.find("test testdriver.xml", "table cell")
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
lib.utils.check(lambda: "Not Connected" in c.text)
c.click(button=3)
self.app.root.find("conn-delete", "menu item").click()
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.app.click_alert_button("will remove the connection", "Yes")
lib.utils.check(lambda: c.dead)
def testConnect(app):
# Start with connection delete
c = app.manager_conn_disconnect("test testdriver.xml")
c.click(button=3)
app.root.find("conn-delete", "menu item").click()
app.click_alert_button("will remove the connection", "No")
lib.utils.check(lambda: not c.dead)
app.manager_conn_delete("test testdriver.xml")
# Launch the dialog, grab some UI pointers
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")
# Launch the dialog, grab some UI pointers
win = app.manager_open_createconn()
connect = win.find("Connect", "push button")
remote = win.find_fuzzy("Connect to remote", "check box")
user = win.find("Username", "text")
host = win.find("Hostname", "text")
urilabel = win.find("uri-label", "label")
lib.utils.check(lambda: user.showing is host.showing is True)
connect = win.find("Connect", "push button")
remote = win.find_fuzzy("Connect to remote", "check box")
user = win.find("Username", "text")
host = win.find("Hostname", "text")
urilabel = win.find("uri-label", "label")
urientry = win.find("uri-entry", "text")
lib.utils.check(lambda: user.showing is host.showing is True)
# Select all HV options
win.combo_select("Hypervisor", "QEMU/KVM user session")
win.combo_select("Hypervisor", r"^QEMU/KVM$")
win.combo_select("Hypervisor", "Xen")
win.combo_select("Hypervisor", "Bhyve")
win.combo_select("Hypervisor", "Virtuozzo")
win.combo_select("Hypervisor", r".*LXC.*")
# Select all HV options
win.combo_select("Hypervisor", "QEMU/KVM user session")
win.combo_select("Hypervisor", r"^QEMU/KVM$")
win.combo_select("Hypervisor", "Xen")
win.combo_select("Hypervisor", "Bhyve")
win.combo_select("Hypervisor", "Virtuozzo")
win.combo_select("Hypervisor", r".*LXC.*")
# Test a simple selection
win.combo_select("Hypervisor", "QEMU/KVM user session")
lib.utils.check(lambda: user.showing is host.showing is False)
lib.utils.check(lambda: urilabel.text == "qemu:///session")
# Test a simple selection
win.combo_select("Hypervisor", "QEMU/KVM user 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()
lib.utils.check(lambda: not win.showing)
# Cancel the dialog
win.find_fuzzy("Cancel", "push button").click()
lib.utils.check(lambda: not win.showing)
# Reopen it, confirm content changed
win = app.manager_open_createconn()
lib.utils.check(lambda: ":///session" not in urilabel.text)
# 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")
lib.utils.check(lambda: ":///session" not in urilabel.text)
# Relaunch the dialog, confirm it doesn't overwrite content
win.combo_select("Hypervisor", ".*LXC.*")
lib.utils.check(lambda: "lxc" in urilabel.text)
win = app.manager_open_createconn()
lib.utils.check(lambda: win.active)
lib.utils.check(lambda: "lxc" in urilabel.text)
# Relaunch the dialog, confirm it doesn't overwrite content
win.combo_select("Hypervisor", ".*LXC.*")
lib.utils.check(lambda: "lxc" in urilabel.text)
self.app.root.find("File", "menu").click()
self.app.root.find("Add Connection...", "menu item").click()
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
win.combo_select("Hypervisor", "Xen")
remote.click()
user.set_text("fribuser")
connect.click()
app.click_alert_button("hostname is required", "OK")
fakeipv6 = "fe80::1"
host.set_text(fakeipv6)
lib.utils.check(lambda: urilabel.text == "xen+ssh://fribuser@[%s]/" % fakeipv6)
fakehost = "ix8khfyidontexistkdjur.com"
host.set_text(fakehost + ":12345")
lib.utils.check(lambda: urilabel.text == "xen+ssh://fribuser@%s:12345/" % fakehost)
connect.click()
# Enter a failing URI, make sure error is raised, and we can
# fall back to the dialog
win.combo_select("Hypervisor", "Xen")
remote.click()
user.set_text("fribuser")
connect.click()
self.app.click_alert_button("hostname is required", "OK")
fakeipv6 = "fe80::1"
host.set_text(fakeipv6)
lib.utils.check(lambda: urilabel.text == "xen+ssh://fribuser@[%s]/" % fakeipv6)
fakehost = "ix8khfyidontexistkdjur.com"
host.set_text(fakehost + ":12345")
lib.utils.check(lambda: urilabel.text == "xen+ssh://fribuser@%s:12345/" % fakehost)
connect.click()
lib.utils.check(lambda: win.showing is True)
c = app.root.find_fuzzy(fakehost, "table cell")
lib.utils.check(lambda: "Connecting..." not in c.text, timeout=10)
app.click_alert_button("Unable to connect", "No")
lib.utils.check(lambda: win.showing is True)
c = self.app.root.find_fuzzy(fakehost, "table cell")
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
lib.utils.check(lambda: win.showing)
lib.utils.check(lambda: fakehost in host.text)
# Ensure dialog shows old contents for editing
lib.utils.check(lambda: win.showing)
lib.utils.check(lambda: fakehost in host.text)
# This time say 'yes'
connect.click()
lib.utils.check(lambda: win.showing is True)
c = app.root.find_fuzzy(fakehost, "table cell")
lib.utils.check(lambda: "Connecting..." not in c.text, timeout=10)
app.click_alert_button("Unable to connect", "Yes")
c = app.root.find_fuzzy(fakehost, "table cell")
lib.utils.check(lambda: win.showing is False)
# This time say 'yes'
connect.click()
lib.utils.check(lambda: win.showing is True)
c = self.app.root.find_fuzzy(fakehost, "table cell")
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
app.manager_createconn("test:///default")
# Do it again to make sure things don't explode
app.manager_createconn("test:///default")
# Test with custom test:///default connection
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")
win.combo_select("Hypervisor", "Custom URI")
urientry.set_text("test:///default")
connect.click()
# Test connection double click
c = app.manager_conn_disconnect("test default")
c.doubleClick()
lib.utils.check(lambda: "Not Connected" not in c.text)
# Do it again to make sure things don't explode
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")
win.combo_select("Hypervisor", "Custom URI")
urientry.set_text("test:///default")
connect.click()
# Try various connect/disconnect routines
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()
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()
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()
lib.utils.check(lambda: "Not Connected" in c.text)
c.click(button=3)
self.app.root.find("conn-delete", "menu item").click()
self.app.click_alert_button("will remove the connection", "Yes")
lib.utils.check(lambda: c.dead)
# Delete it
app.manager_conn_disconnect("test default")
app.manager_conn_delete("test default")

View File

@ -4,169 +4,166 @@
from . import lib
class CreateNet(lib.testcase.UITestCase):
#####################################
# UI tests for the createnet wizard #
#####################################
def _open_netadd(app, hostwin):
hostwin.find("net-add", "push button").click()
win = app.find_window("Create a new virtual network")
return win
def testCreateNet(app):
"""
UI tests for the createnet wizard
Basic test with object state management afterwards
"""
hostwin = app.manager_open_host("Virtual Networks")
win = _open_netadd(app, hostwin)
def _open_create_win(self, hostwin):
hostwin.find("net-add", "push button").click()
win = self.app.root.find(
"Create a new virtual network", "frame")
return win
# Create a simple default network
name = win.find("Name:", "text")
finish = win.find("Finish", "push button")
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
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")
stop = hostwin.find("net-stop", "push button")
cell.click()
stop.click()
lib.utils.check(lambda: start.sensitive)
start.click()
lib.utils.check(lambda: stop.sensitive)
stop.click()
lib.utils.check(lambda: delete.sensitive)
# Delete it, clicking No first
delete.click()
app.click_alert_button("permanently delete the network", "No")
lib.utils.check(lambda: not cell.dead)
delete.click()
app.click_alert_button("permanently delete the network", "Yes")
# Ensure it's gone
lib.utils.check(lambda: cell.dead)
##############
# Test cases #
##############
def testCreateNet(self):
"""
Basic test with object state management afterwards
"""
hostwin = self.app.open_host_window("Virtual Networks")
win = self._open_create_win(hostwin)
def testCreateNetXMLEditor(app):
"""
Test the XML editor
"""
app.open(xmleditor_enabled=True)
hostwin = app.manager_open_host("Virtual Networks")
win = _open_netadd(app, hostwin)
name = win.find("Name:", "text")
finish = win.find("Finish", "push button")
# Create a simple default network
name = win.find("Name:", "text")
finish = win.find("Finish", "push button")
lib.utils.check(lambda: name.text == "network")
newname = "a-test-new-net"
name.set_text(newname)
finish.click()
# Create a new obj with XML edited name, verify it worked
tmpname = "objtmpname"
newname = "froofroo"
name.set_text(tmpname)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
newtext = xmleditor.text.replace(">%s<" % tmpname, ">%s<" % newname)
xmleditor.set_text(newtext)
finish.click()
lib.utils.check(lambda: hostwin.active)
cell = hostwin.find(newname, "table cell")
cell.click()
# Select the new network in the host window, then do
# stop->start->stop->delete, for lifecycle testing
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")
stop = hostwin.find("net-stop", "push button")
# Do standard xmleditor tests
win = _open_netadd(app, hostwin)
lib.utils.test_xmleditor_interactions(app, win, finish)
win.find("Cancel", "push button").click()
lib.utils.check(lambda: not win.visible)
cell.click()
stop.click()
lib.utils.check(lambda: start.sensitive)
start.click()
lib.utils.check(lambda: stop.sensitive)
stop.click()
lib.utils.check(lambda: delete.sensitive)
# Delete it, clicking No first
delete.click()
self.app.click_alert_button("permanently delete the network", "No")
lib.utils.check(lambda: not cell.dead)
delete.click()
self.app.click_alert_button("permanently delete the network", "Yes")
# Ensure it's gone
lib.utils.check(lambda: cell.dead)
# Ensure host window closes fine
hostwin.click()
hostwin.keyCombo("<ctrl>w")
lib.utils.check(lambda: not hostwin.showing and
not hostwin.active)
def testCreateNetXMLEditor(self):
"""
Test the XML editor
"""
self.app.open(xmleditor_enabled=True)
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")
def testCreateNetMulti(app):
"""
Test remaining create options
"""
app.uri = "test:///default"
hostwin = app.manager_open_host(
"Virtual Networks", conn_label="test default")
win = _open_netadd(app, hostwin)
finish = win.find("Finish", "push button")
# Create a new obj with XML edited name, verify it worked
tmpname = "objtmpname"
newname = "froofroo"
name.set_text(tmpname)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
newtext = xmleditor.text.replace(">%s<" % tmpname, ">%s<" % newname)
xmleditor.set_text(newtext)
finish.click()
lib.utils.check(lambda: hostwin.active)
cell = hostwin.find(newname, "table cell")
cell.click()
# Create a network with a bunch of options
win.find("Name:", "text").set_text("default")
win.find("net-mode").click()
win.find("Isolated", "menu item").click()
win.find("IPv4 configuration").click_expander()
win.find("ipv4-network").set_text("192.168.100.0/25")
ipv4start = win.find("ipv4-start")
ipv4end = win.find("ipv4-end")
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()
win.find("Enable IPv6").click()
win.find("Enable DHCPv6").click()
win.find("ipv6-network").set_text("fd00:beef:10:6::1/64")
win.find("ipv6-start").set_text("fd00:beef:10:6::1:1")
win.find("ipv6-end").set_text("bad")
win.find("DNS domain name").click_expander()
win.find("Custom").click()
win.find("domain-custom").set_text("mydomain")
finish.click()
# Name collision validation
app.click_alert_button("in use by another network", "Close")
win.find("Name:", "text").set_text("newnet1")
finish.click()
# XML define error
app.click_alert_button("Error creating virtual network", "Close")
win.find("ipv6-end").set_text("fd00:beef:10:6::1:f1")
finish.click()
lib.utils.check(lambda: hostwin.active)
# Do standard xmleditor tests
win = self._open_create_win(hostwin)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
win.find("Cancel", "push button").click()
lib.utils.check(lambda: not win.visible)
# More option work
win = _open_netadd(app, hostwin)
win.find("Name:", "text").set_text("newnet2")
devicelist = win.find("net-devicelist")
lib.utils.check(lambda: not devicelist.visible)
win.find("net-mode").click()
win.find("SR-IOV", "menu item").click()
lib.utils.check(lambda: devicelist.visible)
# Just confirm this is here
win.find("No available device", "menu item")
win.find("net-mode").click()
win.find("Routed", "menu item").click()
win.find("net-forward").click()
win.find("Physical device", "menu item").click()
win.find("net-device").set_text("fakedev0")
finish.click()
lib.utils.check(lambda: hostwin.active)
# Ensure host window closes fine
hostwin.click()
hostwin.keyCombo("<ctrl>w")
lib.utils.check(lambda: not hostwin.showing and
not hostwin.active)
def testCreateNetMulti(self):
"""
Test remaining create options
"""
self.app.uri = "test:///default"
hostwin = self.app.open_host_window(
"Virtual Networks", conn_label="test default")
win = self._open_create_win(hostwin)
finish = win.find("Finish", "push button")
def testCreateNetSRIOV(app):
"""
We need the full URI to test the SRIOV method
"""
app.open(xmleditor_enabled=True)
hostwin = app.manager_open_host("Virtual Networks")
win = _open_netadd(app, hostwin)
finish = win.find("Finish", "push button")
# Create a network with a bunch of options
win.find("Name:", "text").set_text("default")
win.find("net-mode").click()
win.find("Isolated", "menu item").click()
win.find("IPv4 configuration").click_expander()
win.find("ipv4-network").set_text("192.168.100.0/25")
ipv4start = win.find("ipv4-start")
ipv4end = win.find("ipv4-end")
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()
win.find("Enable IPv6").click()
win.find("Enable DHCPv6").click()
win.find("ipv6-network").set_text("fd00:beef:10:6::1/64")
win.find("ipv6-start").set_text("fd00:beef:10:6::1:1")
win.find("ipv6-end").set_text("bad")
win.find("DNS domain name").click_expander()
win.find("Custom").click()
win.find("domain-custom").set_text("mydomain")
finish.click()
# Name collision validation
self.app.click_alert_button("in use by another network", "Close")
win.find("Name:", "text").set_text("newnet1")
finish.click()
# XML define error
self.app.click_alert_button("Error creating virtual network", "Close")
win.find("ipv6-end").set_text("fd00:beef:10:6::1:f1")
finish.click()
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")
lib.utils.check(lambda: not devicelist.visible)
win.find("net-mode").click()
win.find("SR-IOV", "menu item").click()
lib.utils.check(lambda: devicelist.visible)
# Just confirm this is here
win.find("No available device", "menu item")
win.find("net-mode").click()
win.find("Routed", "menu item").click()
win.find("net-forward").click()
win.find("Physical device", "menu item").click()
win.find("net-device").set_text("fakedev0")
finish.click()
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.app.open_host_window("Virtual Networks")
win = self._open_create_win(hostwin)
finish = win.find("Finish", "push button")
win.find("net-mode").click()
win.find("SR-IOV", "menu item").click()
win.find("net-devicelist").click()
win.find_fuzzy("eth3", "menu item").click()
finish.click()
win.find("net-mode").click()
win.find("SR-IOV", "menu item").click()
win.find("net-devicelist").click()
win.find_fuzzy("eth3", "menu item").click()
finish.click()

View File

@ -4,157 +4,152 @@
from . import lib
class CreatePool(lib.testcase.UITestCase):
"""
UI tests for the createpool wizard
"""
######################################
# UI tests for the createpool wizard #
######################################
def _open_create_win(self, hostwin):
hostwin.find("pool-add", "push button").click()
win = self.app.root.find(
"Add a New Storage Pool", "frame")
def _open_createpool(app, hostwin):
hostwin.find("pool-add", "push button").click()
win = app.find_window("Add a New Storage Pool")
lib.utils.check(lambda: win.active)
return win
def testCreatePools(app):
hostwin = app.manager_open_host("Storage")
win = _open_createpool(app, hostwin)
finish = win.find("Finish", "push button")
name = win.find("Name:", "text")
def _browse_local_path(winlabel, usepath):
chooser = app.root.find(winlabel, "file chooser")
# Enter the filename and select it
chooser.find(usepath, "table cell").click()
obutton = chooser.find("Open", "push button")
lib.utils.check(lambda: obutton.sensitive)
obutton.click()
lib.utils.check(lambda: not chooser.showing)
lib.utils.check(lambda: win.active)
return win
# Create a simple default dir 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
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")
stop = hostwin.find("pool-stop", "push button")
cell.click()
stop.click()
lib.utils.check(lambda: start.sensitive)
start.click()
lib.utils.check(lambda: stop.sensitive)
stop.click()
lib.utils.check(lambda: delete.sensitive)
# Delete it, clicking 'No' first
delete.click()
app.click_alert_button("permanently delete the pool", "No")
lib.utils.check(lambda: not cell.dead)
delete.click()
app.click_alert_button("permanently delete the pool", "Yes")
# Ensure it's gone
lib.utils.check(lambda: cell.dead)
# Test a disk pool
win = _open_createpool(app, hostwin)
win.combo_select("Type:", "disk:")
newname = "a-disk-pool"
name.set_text("a-disk-pool")
win.find("source-browse").click()
_browse_local_path("Choose source path", "console")
finish.click()
hostwin.find(newname, "table cell")
# Test a iscsi pool
win = _open_createpool(app, hostwin)
win.combo_select("Type:", "iscsi:")
newname = "a-iscsi-pool"
name.set_text("a-iscsi-pool")
win.find("target-browse").click()
_browse_local_path("Choose target directory", "by-path")
finish.click()
# Catch example error
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()
win.find("iqn-text", "text").set_text("initiator-foo")
finish.click()
hostwin.find(newname, "table cell")
# Test a logical pool
win = _open_createpool(app, hostwin)
win.combo_select("Type:", "logical:")
newname = "a-lvm-pool"
name.set_text("a-lvm-pool")
win.combo_check_default("Volgroup", "testvg1")
win.combo_select("Volgroup", "testvg2")
finish.click()
hostwin.find(newname, "table cell")
# Test a scsi pool
win = _open_createpool(app, hostwin)
win.combo_select("Type:", "scsi:")
newname = "a-scsi-pool"
name.set_text("a-scsi-pool")
win.combo_select("Source Adapter:", "host2")
finish.click()
hostwin.find(newname, "table cell")
# Test a ceph pool
win = _open_createpool(app, hostwin)
newname = "a-ceph-pool"
name.set_text("a-ceph-pool")
win.combo_select("Type:", "rbd:")
win.find_fuzzy("Host Name:", "text").set_text("example.com:1234")
win.find_fuzzy("pool-source-name-text", "text").typeText("frob")
finish.click()
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")
lib.utils.check(lambda: not hostwin.showing)
##############
# Test cases #
##############
def testCreatePools(self):
hostwin = self.app.open_host_window("Storage")
win = self._open_create_win(hostwin)
finish = win.find("Finish", "push button")
name = win.find("Name:", "text")
def testCreatePoolXMLEditor(app):
app.open(xmleditor_enabled=True)
hostwin = app.manager_open_host("Storage")
win = _open_createpool(app, hostwin)
finish = win.find("Finish", "push button")
name = win.find("Name:", "text")
def _browse_local_path(winlabel, usepath):
chooser = self.app.root.find(winlabel, "file chooser")
# Enter the filename and select it
chooser.find(usepath, "table cell").click()
obutton = chooser.find("Open", "push button")
lib.utils.check(lambda: obutton.sensitive)
obutton.click()
lib.utils.check(lambda: not chooser.showing)
lib.utils.check(lambda: win.active)
# Create a new obj with XML edited name, verify it worked
tmpname = "objtmpname"
newname = "froofroo"
name.set_text(tmpname)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
newtext = xmleditor.text.replace(">%s<" % tmpname, ">%s<" % newname)
xmleditor.set_text(newtext)
finish.click()
lib.utils.check(lambda: hostwin.active)
cell = hostwin.find(newname, "table cell")
cell.click()
# Create a simple default dir 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
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")
stop = hostwin.find("pool-stop", "push button")
cell.click()
stop.click()
lib.utils.check(lambda: start.sensitive)
start.click()
lib.utils.check(lambda: stop.sensitive)
stop.click()
lib.utils.check(lambda: delete.sensitive)
# Delete it, clicking 'No' first
delete.click()
self.app.click_alert_button("permanently delete the pool", "No")
lib.utils.check(lambda: not cell.dead)
delete.click()
self.app.click_alert_button("permanently delete the pool", "Yes")
# Ensure it's gone
lib.utils.check(lambda: cell.dead)
# Test a disk pool
win = self._open_create_win(hostwin)
win.combo_select("Type:", "disk:")
newname = "a-disk-pool"
name.set_text("a-disk-pool")
win.find("source-browse").click()
_browse_local_path("Choose source path", "console")
finish.click()
hostwin.find(newname, "table cell")
# Test a iscsi pool
win = self._open_create_win(hostwin)
win.combo_select("Type:", "iscsi:")
newname = "a-iscsi-pool"
name.set_text("a-iscsi-pool")
win.find("target-browse").click()
_browse_local_path("Choose target directory", "by-path")
finish.click()
# Catch example error
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()
win.find("iqn-text", "text").set_text("initiator-foo")
finish.click()
hostwin.find(newname, "table cell")
# Test a logical pool
win = self._open_create_win(hostwin)
win.combo_select("Type:", "logical:")
newname = "a-lvm-pool"
name.set_text("a-lvm-pool")
win.combo_check_default("Volgroup", "testvg1")
win.combo_select("Volgroup", "testvg2")
finish.click()
hostwin.find(newname, "table cell")
# Test a scsi pool
win = self._open_create_win(hostwin)
win.combo_select("Type:", "scsi:")
newname = "a-scsi-pool"
name.set_text("a-scsi-pool")
win.combo_select("Source Adapter:", "host2")
finish.click()
hostwin.find(newname, "table cell")
# Test a ceph pool
win = self._open_create_win(hostwin)
newname = "a-ceph-pool"
name.set_text("a-ceph-pool")
win.combo_select("Type:", "rbd:")
win.find_fuzzy("Host Name:", "text").set_text("example.com:1234")
win.find_fuzzy("pool-source-name-text", "text").typeText("frob")
finish.click()
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")
lib.utils.check(lambda: not hostwin.showing)
def testCreatePoolXMLEditor(self):
self.app.open(xmleditor_enabled=True)
hostwin = self.app.open_host_window("Storage")
win = self._open_create_win(hostwin)
finish = win.find("Finish", "push button")
name = win.find("Name:", "text")
# Create a new obj with XML edited name, verify it worked
tmpname = "objtmpname"
newname = "froofroo"
name.set_text(tmpname)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
newtext = xmleditor.text.replace(">%s<" % tmpname, ">%s<" % newname)
xmleditor.set_text(newtext)
finish.click()
lib.utils.check(lambda: hostwin.active)
cell = hostwin.find(newname, "table cell")
cell.click()
# Do standard xmleditor tests
win = self._open_create_win(hostwin)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
win.find("Cancel", "push button").click()
lib.utils.check(lambda: not win.visible)
# Do standard xmleditor tests
win = _open_createpool(app, hostwin)
lib.utils.test_xmleditor_interactions(app, win, finish)
win.find("Cancel", "push button").click()
lib.utils.check(lambda: not win.visible)

File diff suppressed because it is too large Load Diff

View File

@ -4,158 +4,154 @@
from . import lib
class CreateVol(lib.testcase.UITestCase):
#####################################
# UI tests for the createvol wizard #
#####################################
def _open_createvol(app, hostwin):
hostwin.find("vol-new", "push button").click()
win = app.find_window("Add a Storage Volume")
lib.utils.check(lambda: win.active)
return win
def testCreateVolDefault(app):
"""
UI tests for the createvol wizard
Create default volume, clean it up
"""
hostwin = app.manager_open_host("Storage")
poolcell = hostwin.find("default-pool", "table cell")
poolcell.click()
vollist = hostwin.find("vol-list", "table")
win = _open_createvol(app, hostwin)
finish = win.find("Finish", "push button")
name = win.find("Name:", "text")
def _open_create_win(self, hostwin):
hostwin.find("vol-new", "push button").click()
win = self.app.root.find(
"Add a Storage Volume", "frame")
lib.utils.check(lambda: win.active)
return win
# Create a default qcow2 volume
lib.utils.check(lambda: name.text == "vol")
newname = "a-newvol"
name.set_text(newname)
win.find("Max Capacity:", "spin button").set_text("10.5")
finish.click()
# Delete it, clicking 'No' first
volcell = vollist.find(newname + ".qcow2")
volcell.click()
hostwin.find("vol-refresh", "push button").click()
hostwin.find("vol-delete", "push button").click()
app.click_alert_button("permanently delete the volume", "No")
volcell = vollist.find(newname + ".qcow2")
hostwin.find("vol-delete", "push button").click()
app.click_alert_button("permanently delete the volume", "Yes")
lib.utils.check(lambda: volcell.dead)
# Ensure host window closes fine
hostwin.keyCombo("<ctrl>w")
lib.utils.check(lambda: not hostwin.showing and
not hostwin.active)
##############
# Test cases #
##############
def testCreateVolMisc(app):
"""
Cover all createvol options
"""
hostwin = app.manager_open_host("Storage")
poolcell = hostwin.find("default-pool", "table cell")
poolcell.click()
win = _open_createvol(app, hostwin)
name = win.find("Name:", "text")
finish = win.find("Finish", "push button")
vollist = hostwin.find("vol-list", "table")
def testCreateVolDefault(self):
"""
Create default volume, clean it up
"""
hostwin = self.app.open_host_window("Storage")
poolcell = hostwin.find("default-pool", "table cell")
poolcell.click()
vollist = hostwin.find("vol-list", "table")
win = self._open_create_win(hostwin)
finish = win.find("Finish", "push button")
name = win.find("Name:", "text")
# Create a qcow2 with backing file
newname = "aaa-qcow2-backing.qcow2"
name.set_text(newname)
win.combo_select("Format:", "qcow2")
win.find("Backing store").click_expander()
win.find("Browse...").click()
browsewin = app.root.find("vmm-storage-browser")
# Test cancel button
browsewin.find("Cancel", "push button").click()
lib.utils.check(lambda: not browsewin.active)
win.find("Browse...").click()
browsewin = app.root.find("vmm-storage-browser")
# Test browse local opening
browsewin.find("Browse Local", "push button").click()
chooser = app.root.find(
"Locate existing storage", "file chooser")
chooser.keyCombo("<alt>F4")
app.select_storagebrowser_volume(
"default-pool", "bochs-vol", doubleclick=True)
backingstore = win.find("backing-store")
lib.utils.check(lambda: "bochs-vol" in backingstore.text)
finish.click()
vollist.find(newname)
# Create a default qcow2 volume
lib.utils.check(lambda: name.text == "vol")
newname = "a-newvol"
name.set_text(newname)
win.find("Max Capacity:", "spin button").set_text("10.5")
finish.click()
# Create a raw volume with some size tweaking
win = _open_createvol(app, hostwin)
# Using previous name so we collide
name.set_text(newname)
win.combo_select("Format:", "raw")
cap = win.find("Max Capacity:", "spin button")
alloc = win.find("Allocation:", "spin button")
alloc.set_text("50.0")
alloc.click()
app.rawinput.pressKey("Enter")
lib.utils.check(lambda: cap.text == "50.0")
cap.set_text("1.0")
cap.click()
app.rawinput.pressKey("Enter")
lib.utils.check(lambda: alloc.text == "1.0")
alloc.set_text("0.5")
alloc.click()
app.rawinput.pressKey("Enter")
lib.utils.check(lambda: cap.text == "1.0")
# Delete it, clicking 'No' first
volcell = vollist.find(newname + ".qcow2")
volcell.click()
hostwin.find("vol-refresh", "push button").click()
hostwin.find("vol-delete", "push button").click()
self.app.click_alert_button("permanently delete the volume", "No")
volcell = vollist.find(newname + ".qcow2")
hostwin.find("vol-delete", "push button").click()
self.app.click_alert_button("permanently delete the volume", "Yes")
lib.utils.check(lambda: volcell.dead)
finish.click()
app.click_alert_button("Error validating volume", "Close")
newname = "a-newvol.raw"
name.set_text(newname)
finish.click()
vollist.find(newname)
# Ensure host window closes fine
hostwin.keyCombo("<ctrl>w")
lib.utils.check(lambda: not hostwin.showing and
not hostwin.active)
def testCreateVolMisc(self):
"""
Cover all createvol options
"""
hostwin = self.app.open_host_window("Storage")
poolcell = hostwin.find("default-pool", "table cell")
poolcell.click()
win = self._open_create_win(hostwin)
name = win.find("Name:", "text")
finish = win.find("Finish", "push button")
vollist = hostwin.find("vol-list", "table")
# Create a qcow2 with backing file
newname = "aaa-qcow2-backing.qcow2"
name.set_text(newname)
win.combo_select("Format:", "qcow2")
win.find("Backing store").click_expander()
win.find("Browse...").click()
browsewin = self.app.root.find("vmm-storage-browser")
# Test cancel button
browsewin.find("Cancel", "push button").click()
lib.utils.check(lambda: not browsewin.active)
win.find("Browse...").click()
browsewin = self.app.root.find("vmm-storage-browser")
# Test browse local opening
browsewin.find("Browse Local", "push button").click()
chooser = self.app.root.find(
"Locate existing storage", "file chooser")
chooser.keyCombo("<alt>F4")
self.app.select_storagebrowser_volume(
"default-pool", "bochs-vol", doubleclick=True)
backingstore = win.find("backing-store")
lib.utils.check(lambda: "bochs-vol" in backingstore.text)
finish.click()
vollist.find(newname)
# Create a raw volume with some size tweaking
win = self._open_create_win(hostwin)
# Using previous name so we collide
name.set_text(newname)
win.combo_select("Format:", "raw")
cap = win.find("Max Capacity:", "spin button")
alloc = win.find("Allocation:", "spin button")
alloc.set_text("50.0")
alloc.click()
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: cap.text == "50.0")
cap.set_text("1.0")
cap.click()
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: alloc.text == "1.0")
alloc.set_text("0.5")
alloc.click()
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: cap.text == "1.0")
finish.click()
self.app.click_alert_button("Error validating volume", "Close")
newname = "a-newvol.raw"
name.set_text(newname)
finish.click()
vollist.find(newname)
# Create LVM backing store
hostwin.find("disk-pool", "table cell").click()
win = self._open_create_win(hostwin)
newname = "aaa-lvm"
name.set_text(newname)
win.find("Backing store").click_expander()
win.find("Browse...").click()
self.app.select_storagebrowser_volume("disk-pool", "diskvol7")
finish.click()
vollist.find(newname)
# Create LVM backing store
hostwin.find("disk-pool", "table cell").click()
win = _open_createvol(app, hostwin)
newname = "aaa-lvm"
name.set_text(newname)
win.find("Backing store").click_expander()
win.find("Browse...").click()
app.select_storagebrowser_volume("disk-pool", "diskvol7")
finish.click()
vollist.find(newname)
def testCreateVolXMLEditor(self):
self.app.open(xmleditor_enabled=True)
hostwin = self.app.open_host_window("Storage")
poolcell = hostwin.find("default-pool", "table cell")
poolcell.click()
win = self._open_create_win(hostwin)
finish = win.find("Finish", "push button")
name = win.find("Name:", "text")
vollist = hostwin.find("vol-list", "table")
# Create a new obj with XML edited name, verify it worked
tmpname = "objtmpname"
newname = "aafroofroo"
name.set_text(tmpname)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
newtext = xmleditor.text.replace(
">%s.qcow2<" % tmpname, ">%s<" % newname)
xmleditor.set_text(newtext)
finish.click()
lib.utils.check(lambda: hostwin.active)
vollist.find(newname)
def testCreateVolXMLEditor(app):
app.open(xmleditor_enabled=True)
hostwin = app.manager_open_host("Storage")
poolcell = hostwin.find("default-pool", "table cell")
poolcell.click()
win = _open_createvol(app, hostwin)
finish = win.find("Finish", "push button")
name = win.find("Name:", "text")
vollist = hostwin.find("vol-list", "table")
# Do standard xmleditor tests
win = self._open_create_win(hostwin)
lib.utils.test_xmleditor_interactions(self.app, win, finish)
win.find("Cancel", "push button").click()
lib.utils.check(lambda: not win.visible)
# Create a new obj with XML edited name, verify it worked
tmpname = "objtmpname"
newname = "aafroofroo"
name.set_text(tmpname)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
newtext = xmleditor.text.replace(
">%s.qcow2<" % tmpname, ">%s<" % newname)
xmleditor.set_text(newtext)
finish.click()
lib.utils.check(lambda: hostwin.active)
vollist.find(newname)
# Do standard xmleditor tests
win = _open_createvol(app, hostwin)
lib.utils.test_xmleditor_interactions(app, win, finish)
win.find("Cancel", "push button").click()
lib.utils.check(lambda: not win.visible)

View File

@ -23,7 +23,7 @@ class _DeleteRow:
def _create_testdriver_path(fn):
def wrapper(self, *args, **kwargs):
def wrapper(app, *args, **kwargs):
# This special path is hardcoded in test-many-devices
tmppath = "/tmp/virt-manager-uitests/tmp1"
tmpdir = os.path.dirname(tmppath)
@ -32,7 +32,7 @@ def _create_testdriver_path(fn):
os.mkdir(tmpdir)
open(tmppath, "w").write("foo")
os.chmod(tmppath, 0o444)
return fn(self, tmppath, *args, **kwargs)
return fn(app, tmppath, *args, **kwargs)
finally:
if os.path.exists(tmpdir):
os.chmod(tmpdir, 0o777)
@ -40,267 +40,276 @@ def _create_testdriver_path(fn):
return wrapper
class Delete(lib.testcase.UITestCase):
"""
UI tests for virt-manager's VM delete window
"""
def _open_storage_browser(self):
self.app.root.find("New", "push button").click()
newvm = self.app.root.find("New VM", "frame")
newvm.find_fuzzy("Local install media", "radio").click()
newvm.find_fuzzy("Forward", "button").click()
newvm.find_fuzzy("install-iso-browse", "button").click()
return self.app.root.find("vmm-storage-browser")
def _open_storage_browser(app):
app.root.find("New", "push button").click()
newvm = app.find_window("New VM")
newvm.find_fuzzy("Local install media", "radio").click()
newvm.find_fuzzy("Forward", "button").click()
newvm.find_fuzzy("install-iso-browse", "button").click()
return app.root.find("vmm-storage-browser")
def _open_delete(self, vmname):
manager = self.app.topwin
cell = manager.find(vmname, "table cell")
cell.click()
cell.click(button=3)
menu = self.app.root.find("vm-action-menu")
menu.find("Delete", "menu item").click()
return self.app.root.find_fuzzy("Delete", "frame")
def _open_delete(app, vmname):
app.manager_vm_action(vmname, delete=True)
return app.find_window("Delete")
def _finish(self, delete, paths, expect_fail=False, click_no=False):
delete.find_fuzzy("Delete", "button").click()
if paths:
alert = self.app.root.find("vmm dialog", "alert")
alert.find_fuzzy("Are you sure")
for path in paths:
alert.find_fuzzy(path)
if click_no:
alert.find("No", "push button").click()
return
alert.find("Yes", "push button").click()
if not expect_fail:
lib.utils.check(lambda: not delete.showing)
def _get_all_rows(self, delete):
def _finish(app, delete, paths, expect_fail=False, click_no=False):
delete.find_fuzzy("Delete", "button").click()
if paths:
alert = app.root.find("vmm dialog", "alert")
alert.find_fuzzy("Are you sure")
for path in paths:
alert.find_fuzzy(path)
if click_no:
alert.find("No", "push button").click()
return
alert.find("Yes", "push button").click()
if not expect_fail:
lib.utils.check(lambda: not delete.showing)
def _get_all_rows(delete):
slist = delete.find("storage-list")
def pred(node):
return node.roleName == "table cell"
cells = slist.findChildren(pred, isLambda=True)
idx = 0
rows = []
while idx < len(cells):
rows.append(_DeleteRow(*cells[idx:idx + 4]))
idx += 4
return rows
################################################
# UI tests for virt-manager's VM delete window #
################################################
def _testDeleteManyDevices(app,
nondefault_path=None, delete_nondefault=False,
skip_finish=False):
delete = _open_delete(app, "test-many-devices")
rows = _get_all_rows(delete)
selected_rows = [r.path for r in rows if r.default]
undeletable_rows = [r.path for r in rows if r.undeletable]
notdefault_rows = [r.path for r in rows if r.notdefault]
defpath = "/dev/default-pool/overlay.img"
nondefault_path2 = "/dev/default-pool/sharevol.img"
assert selected_rows == [defpath]
if nondefault_path:
assert nondefault_path in notdefault_rows
assert nondefault_path2 in notdefault_rows
assert "/dev/fda" in undeletable_rows
if delete_nondefault:
# Click the selector for the nondefault path
found = [r for r in rows if r.path == nondefault_path]
assert len(found) == 1
slist = delete.find("storage-list")
def pred(node):
return node.roleName == "table cell"
cells = slist.findChildren(pred, isLambda=True)
slist.click()
chkcell = found[0].chkcell
chkcell.bring_on_screen()
chkcell.click()
chkcell.click()
chkcell.click()
lib.utils.check(lambda: chkcell.checked)
idx = 0
rows = []
while idx < len(cells):
rows.append(_DeleteRow(*cells[idx:idx + 4]))
idx += 4
return rows
paths = []
if defpath:
paths.append(defpath)
if delete_nondefault:
paths.append(nondefault_path)
if skip_finish:
return paths
_finish(app, delete, paths)
# Confirm
browser = _open_storage_browser(app)
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
lib.utils.check(lambda: "overlay.img" not in browser.fmt_nodes())
browser.find("sharevol.img", "table cell")
##############
# Test cases #
##############
@_create_testdriver_path
def testDeleteManyDevices(app, tmppath):
"""
Hit a specific case of a path not selected by default
because the permissions are readonly
"""
_testDeleteManyDevices(app, nondefault_path=tmppath)
def _testDeleteManyDevices(self,
nondefault_path=None, delete_nondefault=False,
skip_finish=False):
delete = self._open_delete("test-many-devices")
rows = self._get_all_rows(delete)
selected_rows = [r.path for r in rows if r.default]
undeletable_rows = [r.path for r in rows if r.undeletable]
notdefault_rows = [r.path for r in rows if r.notdefault]
@_create_testdriver_path
def testDeleteNondefaultOverride(app, tmppath):
"""
Path not selected by default, but we select it,
which will cause it to be manually unlinked
"""
_testDeleteManyDevices(app,
nondefault_path=tmppath,
delete_nondefault=True)
assert not os.path.exists(tmppath)
defpath = "/dev/default-pool/overlay.img"
nondefault_path2 = "/dev/default-pool/sharevol.img"
assert selected_rows == [defpath]
if nondefault_path:
assert nondefault_path in notdefault_rows
assert nondefault_path2 in notdefault_rows
assert "/dev/fda" in undeletable_rows
@_create_testdriver_path
def testDeleteFailure(app, tmppath):
"""
After launching the wizard we change permissions to make
file deletion fail
"""
paths = _testDeleteManyDevices(app,
nondefault_path=tmppath,
delete_nondefault=True,
skip_finish=True)
os.chmod(os.path.dirname(tmppath), 0o555)
delete = app.find_window("Delete")
_finish(app, delete, paths, expect_fail=True, click_no=True)
lib.utils.check(lambda: delete.active)
_finish(app, delete, paths, expect_fail=True)
assert os.path.exists(tmppath)
app.click_alert_button("Errors encountered", "Close")
if delete_nondefault:
# Click the selector for the nondefault path
found = [r for r in rows if r.path == nondefault_path]
assert len(found) == 1
slist = delete.find("storage-list")
slist.click()
chkcell = found[0].chkcell
chkcell.bring_on_screen()
chkcell.click()
chkcell.click()
chkcell.click()
lib.utils.check(lambda: chkcell.checked)
# Ensure disconnecting will close the dialog
manager = app.topwin
manager.window_maximize()
win = _open_delete(app, "test-clone")
manager.click_title()
app.manager_conn_disconnect("test testdriver.xml")
lib.utils.check(lambda: not win.showing)
paths = []
if defpath:
paths.append(defpath)
if delete_nondefault:
paths.append(nondefault_path)
if skip_finish:
return paths
self._finish(delete, paths)
# Confirm
browser = self._open_storage_browser()
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
lib.utils.check(lambda: "overlay.img" not in browser.fmt_nodes())
browser.find("sharevol.img", "table cell")
def testDeleteRemoteManyDevices(app):
"""
Test with a remote VM to hit a certain code path
"""
app.uri = tests.utils.URIs.kvm_remote
_testDeleteManyDevices(app)
@_create_testdriver_path
def testDeleteManyDevices(self, tmppath):
"""
Hit a specific case of a path not selected by default
because the permissions are readonly
"""
self._testDeleteManyDevices(nondefault_path=tmppath)
@_create_testdriver_path
def testDeleteNondefaultOverride(self, tmppath):
"""
Path not selected by default, but we select it,
which will cause it to be manually unlinked
"""
self._testDeleteManyDevices(
nondefault_path=tmppath,
delete_nondefault=True)
assert not os.path.exists(tmppath)
def testDeleteSkipStorage(app):
"""
Test VM delete with all storage skipped
"""
delete = _open_delete(app, "test-many-devices")
chk = delete.find("Delete associated", "check box")
slist = delete.find("storage-list")
@_create_testdriver_path
def testDeleteFailure(self, tmppath):
"""
After launching the wizard we change permissions to make
file deletion fail
"""
paths = self._testDeleteManyDevices(
nondefault_path=tmppath,
delete_nondefault=True,
skip_finish=True)
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)
lib.utils.check(lambda: delete.active)
self._finish(delete, paths, expect_fail=True)
assert os.path.exists(tmppath)
self.app.click_alert_button("Errors encountered", "Close")
lib.utils.check(lambda: chk.checked)
chk.click()
lib.utils.check(lambda: not chk.checked)
lib.utils.check(lambda: not slist.showing)
def testDeleteRemoteManyDevices(self):
"""
Test with a remote VM to hit a certain code path
"""
self.app.uri = tests.utils.URIs.kvm_remote
self._testDeleteManyDevices()
_finish(app, delete, None)
def testDeleteSkipStorage(self):
"""
Test VM delete with all storage skipped
"""
delete = self._open_delete("test-many-devices")
chk = delete.find("Delete associated", "check box")
slist = delete.find("storage-list")
# Confirm nothing was deleted compare to the default selections
browser = _open_storage_browser(app)
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
app.sleep(.5)
browser.find("overlay.img", "table cell")
browser.find("sharevol.img", "table cell")
lib.utils.check(lambda: chk.checked)
chk.click()
lib.utils.check(lambda: not chk.checked)
lib.utils.check(lambda: not slist.showing)
self._finish(delete, None)
def testDeleteDeviceNoStorage(app):
"""
Verify successful device remove with storage doesn't
touch host storage
"""
details = app.manager_open_details("test-many-devices",
shutdown=True)
# Confirm nothing was deleted compare to the default selections
browser = self._open_storage_browser()
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
self.app.sleep(.5)
browser.find("overlay.img", "table cell")
browser.find("sharevol.img", "table cell")
hwlist = details.find("hw-list")
hwlist.click()
c = hwlist.find("USB Disk 1")
c.bring_on_screen()
c.click()
tab = details.find("disk-tab")
lib.utils.check(lambda: tab.showing)
details.find("config-remove").click()
def testDeleteDeviceNoStorage(self):
"""
Verify successful device remove with storage doesn't
touch host storage
"""
details = self.app.open_details_window("test-many-devices",
shutdown=True)
delete = app.find_window("Remove Disk")
chk = delete.find("Delete associated", "check box")
lib.utils.check(lambda: not chk.checked)
_finish(app, delete, [])
details.click()
details.keyCombo("<alt>F4")
hwlist = details.find("hw-list")
hwlist.click()
c = hwlist.find("USB Disk 1")
c.bring_on_screen()
c.click()
tab = details.find("disk-tab")
lib.utils.check(lambda: tab.showing)
details.find("config-remove").click()
browser = _open_storage_browser(app)
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
app.sleep(.5)
browser.find("overlay.img", "table cell")
delete = self.app.root.find_fuzzy("Remove Disk", "frame")
chk = delete.find("Delete associated", "check box")
lib.utils.check(lambda: not chk.checked)
self._finish(delete, [])
details.click()
details.keyCombo("<alt>F4")
browser = self._open_storage_browser()
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
self.app.sleep(.5)
browser.find("overlay.img", "table cell")
def testDeleteDeviceWithStorage(app):
"""
Verify successful device remove deletes storage
"""
details = app.manager_open_details("test-many-devices",
shutdown=True)
def testDeleteDeviceWithStorage(self):
"""
Verify successful device remove deletes storage
"""
details = self.app.open_details_window("test-many-devices",
shutdown=True)
hwlist = details.find("hw-list")
hwlist.click()
c = hwlist.find("USB Disk 1")
c.bring_on_screen()
c.click()
tab = details.find("disk-tab")
lib.utils.check(lambda: tab.showing)
details.find("config-remove").click()
hwlist = details.find("hw-list")
hwlist.click()
c = hwlist.find("USB Disk 1")
c.bring_on_screen()
c.click()
tab = details.find("disk-tab")
lib.utils.check(lambda: tab.showing)
details.find("config-remove").click()
delete = app.find_window("Remove Disk")
chk = delete.find("Delete associated", "check box")
lib.utils.check(lambda: not chk.checked)
chk.click()
lib.utils.check(lambda: chk.checked)
path = "/dev/default-pool/overlay.img"
delete.find_fuzzy(path)
_finish(app, delete, [path])
details.click()
details.keyCombo("<alt>F4")
delete = self.app.root.find_fuzzy("Remove Disk", "frame")
chk = delete.find("Delete associated", "check box")
lib.utils.check(lambda: not chk.checked)
chk.click()
lib.utils.check(lambda: chk.checked)
path = "/dev/default-pool/overlay.img"
delete.find_fuzzy(path)
self._finish(delete, [path])
details.click()
details.keyCombo("<alt>F4")
browser = _open_storage_browser(app)
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
lib.utils.check(lambda: "overlay.img" not in browser.fmt_nodes())
browser = self._open_storage_browser()
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
lib.utils.check(lambda: "overlay.img" not in browser.fmt_nodes())
def testDeleteDeviceFail(self):
"""
Verify failed device remove does not touch storage
"""
details = self.app.open_details_window("test-many-devices")
def testDeleteDeviceFail(app):
"""
Verify failed device remove does not touch storage
"""
details = app.manager_open_details("test-many-devices")
hwlist = details.find("hw-list")
hwlist.click()
c = hwlist.find("USB Disk 1")
c.bring_on_screen()
c.click()
tab = details.find("disk-tab")
lib.utils.check(lambda: tab.showing)
details.find("config-remove").click()
hwlist = details.find("hw-list")
hwlist.click()
c = hwlist.find("USB Disk 1")
c.bring_on_screen()
c.click()
tab = details.find("disk-tab")
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")
lib.utils.check(lambda: not chk.checked)
chk.click()
lib.utils.check(lambda: chk.checked)
path = "/dev/default-pool/overlay.img"
delete.find_fuzzy(path)
self._finish(delete, [path], expect_fail=True)
self.app.click_alert_button("Storage will not be.*deleted", "OK")
details.click()
details.keyCombo("<alt>F4")
delete = app.find_window("Remove Disk")
chk = delete.find("Delete associated", "check box")
lib.utils.check(lambda: not chk.checked)
chk.click()
lib.utils.check(lambda: chk.checked)
path = "/dev/default-pool/overlay.img"
delete.find_fuzzy(path)
_finish(app, delete, [path], expect_fail=True)
app.click_alert_button("Storage will not be.*deleted", "OK")
details.click()
details.keyCombo("<alt>F4")
# Verify file still exists
browser = self._open_storage_browser()
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
self.app.sleep(.5)
browser.find("overlay.img", "table cell")
# Verify file still exists
browser = _open_storage_browser(app)
browser.find_fuzzy("default-pool", "table cell").click()
browser.find("vol-refresh", "push button").click()
app.sleep(.5)
browser.find("overlay.img", "table cell")

File diff suppressed because it is too large Load Diff

View File

@ -4,182 +4,180 @@
from . import lib
class Host(lib.testcase.UITestCase):
#################################################
# UI tests for virt-manager's VM details window #
#################################################
def testHostNetworkSmokeTest(app):
"""
UI tests for virt-manager's VM details window
Verify that each virtual network displays, without error.
"""
win = app.manager_open_host("Virtual Networks")
lst = win.find("net-list", "table")
errlabel = win.find("net-error-label", "label")
lib.utils.walkUIList(app, win, lst, lambda: errlabel.showing)
##############
# Test cases #
##############
def testHostNetworkSmokeTest(self):
"""
Verify that each virtual network displays, without error.
"""
win = self.app.open_host_window("Virtual Networks")
lst = win.find("net-list", "table")
errlabel = win.find("net-error-label", "label")
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()
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.app.open_host_window("Virtual Networks").find("network-grid")
finish = win.find("Apply", "push button")
# Shut it off, do an XML edit, verify it
win.find("default", "table cell").click()
delete = win.find("net-delete", "push button")
stop = win.find("net-stop", "push button")
stop.click()
lib.utils.check(lambda: delete.sensitive)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
origdev = "virbr0"
newdev = "virbr77"
xmleditor.set_text(xmleditor.text.replace(origdev, newdev))
finish.click()
win.find("Details", "page tab").click()
netdev = win.find("net-device")
lib.utils.check(lambda: netdev.text == newdev)
# Rename it
win.find("default", "table cell").click()
win.find("net-name").set_text("newsort-default")
finish.click()
# Change autostart, trigger it by clicking away
win.find("newsort-default", "table cell").click()
win.find("net-autostart").click()
win.find("netboot", "table cell").click()
self.app.click_alert_button("There are unapplied changes", "Yes")
# Do standard xmleditor tests
lib.utils.test_xmleditor_interactions(self.app, win, finish)
# Select XML editor, and reverse walk the list
win.find("network-grid").find("XML", "page tab").click()
lib.utils.walkUIList(app, win, lst, lambda: errlabel.showing, reverse=True)
def testHostStorageSmokeTest(self):
"""
Verify that each storage pool displays, without error.
"""
win = self.app.open_host_window("Storage")
lst = win.find("pool-list", "table")
errlabel = win.find("pool-error-label", "label")
lib.utils.walkUIList(self.app, win, lst, lambda: errlabel.showing)
def testHostNetworkEdit(app):
"""
Test edits to net config
"""
app.open(xmleditor_enabled=True)
win = app.manager_open_host("Virtual Networks").find("network-grid")
finish = win.find("Apply", "push button")
# Select XML editor, and reverse walk the list
win.find("storage-grid").find("XML", "page tab").click()
lib.utils.walkUIList(self.app, win, lst, lambda: errlabel.showing, reverse=True)
# Shut it off, do an XML edit, verify it
win.find("default", "table cell").click()
delete = win.find("net-delete", "push button")
stop = win.find("net-stop", "push button")
stop.click()
lib.utils.check(lambda: delete.sensitive)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
origdev = "virbr0"
newdev = "virbr77"
xmleditor.set_text(xmleditor.text.replace(origdev, newdev))
finish.click()
win.find("Details", "page tab").click()
netdev = win.find("net-device")
lib.utils.check(lambda: netdev.text == newdev)
def testHostStorageEdit(self):
"""
Test edits to pool config
"""
self.app.open(xmleditor_enabled=True)
win = self.app.open_host_window("Storage").find("storage-grid")
finish = win.find("Apply", "push button")
# Rename it
win.find("default", "table cell").click()
win.find("net-name").set_text("newsort-default")
finish.click()
# Shut off a pool, do an XML edit, verify it
win.find("default-pool", "table cell").click()
delete = win.find("pool-delete", "push button")
stop = win.find("pool-stop", "push button")
stop.click()
lib.utils.check(lambda: delete.sensitive)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
origpath = "/dev/default-pool"
newpath = "/dev/foo/bar/baz"
xmleditor.set_text(xmleditor.text.replace(origpath, newpath))
finish.click()
win.find("Details", "page tab").click()
poolloc = win.find("pool-location")
lib.utils.check(lambda: poolloc.text == newpath)
# Change autostart, trigger it by clicking away
win.find("newsort-default", "table cell").click()
win.find("net-autostart").click()
win.find("netboot", "table cell").click()
app.click_alert_button("There are unapplied changes", "Yes")
# Rename it
win.find("default", "table cell").click()
win.find("pool-name").set_text("newsort-default")
finish.click()
# Do standard xmleditor tests
lib.utils.test_xmleditor_interactions(app, win, finish)
# Change autostart. Trigger it by clicking on new cell
win.find("newsort-default", "table cell").click()
win.find("pool-autostart").click()
win.find("disk-pool", "table cell").click()
self.app.click_alert_button("There are unapplied changes", "Yes")
# Do standard xmleditor tests
lib.utils.test_xmleditor_interactions(self.app, win, finish)
def testHostStorageVolMisc(self):
"""
Misc actions involving volumes
"""
win = self.app.open_host_window("Storage").find("storage-grid")
win.find_fuzzy("default-pool", "table cell").click()
vollist = win.find("vol-list", "table")
def testHostStorageSmokeTest(app):
"""
Verify that each storage pool displays, without error.
"""
win = app.manager_open_host("Storage")
lst = win.find("pool-list", "table")
errlabel = win.find("pool-error-label", "label")
lib.utils.walkUIList(app, win, lst, lambda: errlabel.showing)
vol1 = vollist.find("backingl1.img", "table cell")
vol2 = vollist.find("UPPER", "table cell")
vol1.check_onscreen()
vol2.check_not_onscreen()
win.find("Size", "table column header").click()
win.find("Size", "table column header").click()
vol1.check_not_onscreen()
vol2.check_onscreen()
# Select XML editor, and reverse walk the list
win.find("storage-grid").find("XML", "page tab").click()
lib.utils.walkUIList(app, win, lst, lambda: errlabel.showing, reverse=True)
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())
lib.utils.check(lambda: clipboard.wait_for_text() == "/dev/default-pool/UPPER")
def testHostConn(self):
"""
Change some connection parameters
"""
manager = self.app.topwin
# Disconnect the connection
c = manager.find_fuzzy("testdriver.xml", "table cell")
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
lib.utils.check(lambda: "Not Connected" in c.text)
def testHostStorageEdit(app):
"""
Test edits to pool config
"""
app.open(xmleditor_enabled=True)
win = app.manager_open_host("Storage").find("storage-grid")
finish = win.find("Apply", "push button")
# Open Host Details from right click menu
c.click(button=3)
self.app.root.find("conn-details", "menu item").click()
win = self.app.root.find_fuzzy("Connection Details", "frame")
# Shut off a pool, do an XML edit, verify it
win.find("default-pool", "table cell").click()
delete = win.find("pool-delete", "push button")
stop = win.find("pool-stop", "push button")
stop.click()
lib.utils.check(lambda: delete.sensitive)
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
origpath = "/dev/default-pool"
newpath = "/dev/foo/bar/baz"
xmleditor.set_text(xmleditor.text.replace(origpath, newpath))
finish.click()
win.find("Details", "page tab").click()
poolloc = win.find("pool-location")
lib.utils.check(lambda: poolloc.text == newpath)
# Click the tabs and then back
win.find_fuzzy("Storage", "tab").click()
win.find_fuzzy("Network", "tab").click()
win.find_fuzzy("Overview", "tab").click()
# Rename it
win.find("default", "table cell").click()
win.find("pool-name").set_text("newsort-default")
finish.click()
# Toggle autoconnect
win.find("Autoconnect:", "check box").click()
win.find("Autoconnect:", "check box").click()
# Change autostart. Trigger it by clicking on new cell
win.find("newsort-default", "table cell").click()
win.find("pool-autostart").click()
win.find("disk-pool", "table cell").click()
app.click_alert_button("There are unapplied changes", "Yes")
# Change the name, verify that title bar changed
win.find("Name:", "text").set_text("FOOBAR")
self.app.root.find("FOOBAR - Connection Details", "frame")
# Do standard xmleditor tests
lib.utils.test_xmleditor_interactions(app, win, finish)
# Open the manager window
win.find("File", "menu").click()
win.find("View Manager", "menu item").click()
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")
lib.utils.check(lambda: win.active)
def testHostStorageVolMisc(app):
"""
Misc actions involving volumes
"""
win = app.manager_open_host("Storage").find("storage-grid")
win.find_fuzzy("default-pool", "table cell").click()
vollist = win.find("vol-list", "table")
# Quit app from the file menu
win.find("File", "menu").click()
win.find("Quit", "menu item").click()
lib.utils.check(lambda: not self.app.is_running())
vol1 = vollist.find("backingl1.img", "table cell")
vol2 = vollist.find("UPPER", "table cell")
vol1.check_onscreen()
vol2.check_not_onscreen()
win.find("Size", "table column header").click()
win.find("Size", "table column header").click()
vol1.check_not_onscreen()
vol2.check_onscreen()
vol2.click(button=3)
app.root.find("Copy Volume Path", "menu item").click()
from gi.repository import Gdk, Gtk
clipboard = Gtk.Clipboard.get_default(Gdk.Display.get_default())
lib.utils.check(lambda: clipboard.wait_for_text() == "/dev/default-pool/UPPER")
def testHostConn(app):
"""
Change some connection parameters
"""
manager = app.topwin
# Disconnect the connection
app.manager_conn_disconnect("test testdriver.xml")
# Open Host Details from right click menu
c = manager.find("test testdriver.xml", "table cell")
c.click(button=3)
app.root.find("conn-details", "menu item").click()
win = app.find_window("test testdriver.xml - Connection Details")
# Click the tabs and then back
win.find_fuzzy("Storage", "tab").click()
win.find_fuzzy("Network", "tab").click()
win.find_fuzzy("Overview", "tab").click()
# Toggle autoconnect
win.find("Autoconnect:", "check box").click()
win.find("Autoconnect:", "check box").click()
# Change the name, verify that title bar changed
win.find("Name:", "text").set_text("FOOBAR")
app.find_window("FOOBAR - Connection Details")
# Open the manager window
win.find("File", "menu").click()
win.find("View Manager", "menu item").click()
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")
lib.utils.check(lambda: win.active)
# Quit app from the file menu
win.find("File", "menu").click()
win.find("Quit", "menu item").click()
lib.utils.check(lambda: not app.is_running())

View File

@ -13,60 +13,48 @@ except Exception:
HAS_LIBGUESTFS = False
class VMMInspection(lib.testcase.UITestCase):
"""
UI tests for the libguestfs inspection infrastructure
"""
#########################################################
# UI tests for the libguestfs inspection infrastructure #
#########################################################
##############
# Test cases #
##############
def testInspectionMock(app):
if not HAS_LIBGUESTFS:
pytest.skip("libguestfs python not installed")
def testInspectionMock(self):
if not HAS_LIBGUESTFS:
pytest.skip("libguestfs python not installed")
# Use the test suite inspection mocking to test parts
# of the UI that interact with inspection data
app.open(enable_libguestfs=True)
manager = app.topwin
# Use the test suite inspection mocking to test parts
# of the UI that interact with inspection data
self.app.open(enable_libguestfs=True)
manager = self.app.topwin
details = app.manager_open_details("test-clone")
details.find("OS information", "table cell").click()
tab = details.find("os-tab")
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")
apps.check_onscreen()
apps.click_expander()
tab.find("Application", "toggle").click_expander()
apps = tab.find("inspection-apps")
apps.check_onscreen()
apps.click_expander()
nodestr1 = apps.fmt_nodes()
assert "test_app1_summary" in nodestr1
tab.find("Refresh", "push button").click()
lib.utils.check(lambda: apps.fmt_nodes() != nodestr1)
nodestr1 = apps.fmt_nodes()
assert "test_app1_summary" in nodestr1
tab.find("Refresh", "push button").click()
lib.utils.check(lambda: apps.fmt_nodes() != nodestr1)
details.keyCombo("<alt>F4")
lib.utils.check(lambda: not details.showing)
details.keyCombo("<alt>F4")
lib.utils.check(lambda: not details.showing)
# Open a VM with no disks which will report an inspection error
app.root.find_fuzzy("test\n", "table cell").doubleClick()
details = app.find_window("test on")
details.find("Details", "radio button").click()
details.find("OS information", "table cell").click()
tab = details.find("os-tab")
tab.find_fuzzy("Fake test error no disks")
# Open a VM with no disks which will report an inspection error
self.app.root.find_fuzzy("test\n", "table cell").doubleClick()
details = self.app.root.find("test on", "frame")
details.find("Details", "radio button").click()
details.find("OS information", "table cell").click()
tab = details.find("os-tab")
tab.find_fuzzy("Fake test error no disks")
# Closing and reopening a connection triggers some libguest
# cache reading
details.keyCombo("<alt>F4")
manager.click()
c = manager.find_fuzzy("testdriver.xml", "table cell")
c.click()
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
manager.click()
c = manager.find_fuzzy("testdriver.xml", "table cell")
c.click()
c.click(button=3)
self.app.root.find("conn-connect", "menu item").click()
self.app.sleep(2)
# Closing and reopening a connection triggers some libguest
# cache reading
details.keyCombo("<alt>F4")
manager.click()
app.manager_conn_disconnect("test testdriver.xml")
app.manager_conn_connect("test testdriver.xml")
app.sleep(2)

View File

@ -16,24 +16,24 @@ def _vm_wrapper(vmname, uri="qemu:///system", opts=None):
Decorator to define+start a VM and clean it up on exit
"""
def wrap1(fn):
def wrapper(self, *args, **kwargs):
self.app.error_if_already_running()
def wrapper(app, *args, **kwargs):
app.error_if_already_running()
xmlfile = "%s/live/%s.xml" % (tests.utils.UITESTDATADIR, vmname)
conn = libvirt.open(uri)
dom = conn.defineXML(open(xmlfile).read())
try:
dom.create()
self.app.uri = uri
self.conn = conn
app.uri = uri
app.conn = conn
extra_opts = (opts or [])
extra_opts += ["--show-domain-console", vmname]
# Enable stats for more code coverage
keyfile = "statsonly.ini"
self.app.open(extra_opts=extra_opts, keyfile=keyfile)
fn(self, dom, *args, **kwargs)
app.open(extra_opts=extra_opts, keyfile=keyfile)
fn(app, dom, *args, **kwargs)
finally:
try:
self.app.stop()
app.stop()
except Exception:
pass
try:
@ -45,399 +45,404 @@ def _vm_wrapper(vmname, uri="qemu:///system", opts=None):
return wrap1
class Console(lib.testcase.UITestCase):
def _destroy(app, win):
smenu = win.find("Menu", "toggle button")
smenu.click()
smenu.find("Force Off", "menu item").click()
app.click_alert_button("you sure", "Yes")
run = win.find("Run", "push button")
lib.utils.check(lambda: run.sensitive)
###############################################
# Test live console connections with stub VMs #
###############################################
def _checkConsoleStandard(app, dom):
"""
Test live console connections with stub VMs
Shared logic for general console handling
"""
win = app.topwin
con = win.find("console-gfx-viewport")
lib.utils.check(lambda: con.showing)
conn = None
extraopts = None
win.find("Virtual Machine", "menu").click()
win.find("Take Screenshot", "menu item").click()
chooser = app.root.find(None, "file chooser")
fname = chooser.find("Name", "text").text
app.rawinput.pressKey("Enter")
lib.utils.check(lambda: os.path.exists(fname))
os.unlink(fname)
lib.utils.check(lambda: win.active)
def _destroy(self, win):
smenu = win.find("Menu", "toggle button")
smenu.click()
smenu.find("Force Off", "menu item").click()
self.app.click_alert_button("you sure", "Yes")
run = win.find("Run", "push button")
lib.utils.check(lambda: run.sensitive)
win.find("Send Key", "menu").click()
win.find(r"Ctrl\+Alt\+F1", "menu item").click()
win.find("Send Key", "menu").click()
win.find(r"Ctrl\+Alt\+F10", "menu item").click()
win.find("Send Key", "menu").click()
win.find(r"Ctrl\+Alt\+Delete", "menu item").click()
# 'Resize to VM' testing
oldsize = win.size
win.find("^View$", "menu").click()
win.find("Resize to VM", "menu item").click()
newsize = win.size
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")
lib.utils.check(lambda: fstb.showing)
lib.utils.check(lambda: win.size != newsize)
# Wait for toolbar to hide, then reveal it again
lib.utils.check(lambda: not fstb.showing, timeout=5)
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()
lib.utils.check(lambda: not fstb.showing, timeout=5)
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()
app.rawinput.pressKey("Escape")
win.find("Fullscreen Exit").click()
lib.utils.check(lambda: win.size == newsize)
# Trigger pointer grab, verify title was updated
win.click()
lib.utils.check(lambda: "Control_L" in win.name)
# Ungrab
win.keyCombo("<ctrl><alt>")
lib.utils.check(lambda: "Control_L" not in win.name)
# Tweak scaling
win.window_maximize()
win.find("^View$", "menu").click()
scalemenu = win.find("Scale Display", "menu")
scalemenu.point()
scalemenu.find("Always", "radio menu item").click()
win.find("^View$", "menu").click()
scalemenu = win.find("Scale Display", "menu")
scalemenu.point()
scalemenu.find("Never", "radio menu item").click()
win.find("^View$", "menu").click()
scalemenu = win.find("Scale Display", "menu")
scalemenu.point()
scalemenu.find("Only", "radio menu item").click()
# Check that modifiers don't work
win.click()
app.sleep(1)
win.keyCombo("<ctrl>w")
lib.utils.check(lambda: win.showing)
dom.destroy()
win.find("Guest is not running.")
win.click_title()
app.sleep(1)
win.keyCombo("<ctrl>w")
lib.utils.check(lambda: not win.showing)
##############
# Test cases #
##############
@_vm_wrapper("uitests-vnc-standard")
def testConsoleVNCStandard(app, dom):
return _checkConsoleStandard(app, dom)
def _checkConsoleStandard(self, dom):
"""
Shared logic for general console handling
"""
win = self.app.topwin
con = win.find("console-gfx-viewport")
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.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: os.path.exists(fname))
os.unlink(fname)
lib.utils.check(lambda: win.active)
@_vm_wrapper("uitests-spice-standard")
def testConsoleSpiceStandard(app, dom):
return _checkConsoleStandard(app, dom)
win.find("Send Key", "menu").click()
win.find(r"Ctrl\+Alt\+F1", "menu item").click()
win.find("Send Key", "menu").click()
win.find(r"Ctrl\+Alt\+F10", "menu item").click()
win.find("Send Key", "menu").click()
win.find(r"Ctrl\+Alt\+Delete", "menu item").click()
# 'Resize to VM' testing
oldsize = win.size
win.find("^View$", "menu").click()
win.find("Resize to VM", "menu item").click()
newsize = win.size
lib.utils.check(lambda: oldsize != newsize)
def _checkPassword(app):
"""
Shared logic for password handling
"""
win = app.topwin
con = win.find("console-gfx-viewport")
lib.utils.check(lambda: not con.showing)
passwd = win.find("Password:", "password text")
lib.utils.check(lambda: passwd.showing)
# Fullscreen testing
win.find("^View$", "menu").click()
win.find("Fullscreen", "check menu item").click()
fstb = win.find("Fullscreen Toolbar")
lib.utils.check(lambda: fstb.showing)
lib.utils.check(lambda: win.size != newsize)
# Wait for toolbar to hide, then reveal it again
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()
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.app.rawinput.pressKey("Escape")
win.find("Fullscreen Exit").click()
lib.utils.check(lambda: win.size == newsize)
# Trigger pointer grab, verify title was updated
win.click()
lib.utils.check(lambda: "Control_L" in win.name)
# Ungrab
win.keyCombo("<ctrl><alt>")
lib.utils.check(lambda: "Control_L" not in win.name)
# Tweak scaling
win.click_title()
win.click_title()
win.find("^View$", "menu").click()
scalemenu = win.find("Scale Display", "menu")
scalemenu.point()
scalemenu.find("Always", "radio menu item").click()
win.find("^View$", "menu").click()
scalemenu = win.find("Scale Display", "menu")
scalemenu.point()
scalemenu.find("Never", "radio menu item").click()
win.find("^View$", "menu").click()
scalemenu = win.find("Scale Display", "menu")
scalemenu.point()
scalemenu.find("Only", "radio menu item").click()
# Check that modifiers don't work
win.click()
self.app.sleep(1)
win.keyCombo("<ctrl>w")
lib.utils.check(lambda: win.showing)
dom.destroy()
win.find("Guest is not running.")
win.click_title()
self.app.sleep(1)
win.keyCombo("<ctrl>w")
lib.utils.check(lambda: not win.showing)
@_vm_wrapper("uitests-vnc-standard")
def testConsoleVNCStandard(self, dom):
return self._checkConsoleStandard(dom)
@_vm_wrapper("uitests-spice-standard")
def testConsoleSpiceStandard(self, dom):
return self._checkConsoleStandard(dom)
def _checkPassword(self):
"""
Shared logic for password handling
"""
win = self.app.topwin
con = win.find("console-gfx-viewport")
lib.utils.check(lambda: not con.showing)
passwd = win.find("Password:", "password text")
lib.utils.check(lambda: passwd.showing)
# Check wrong password handling
passwd.typeText("xx")
win.find("Login", "push button").click()
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.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()
lib.utils.check(lambda: con.showing)
# Restart VM to retrigger console connect
self._destroy(win)
win.find("Run", "push button").click()
lib.utils.check(lambda: passwd.showing)
# Password should be filled in
lib.utils.check(lambda: bool(passwd.text))
# Uncheck 'Save password' and login, which will delete it from keyring
# Check wrong password handling
passwd.typeText("xx")
win.find("Login", "push button").click()
app.click_alert_button("Viewer authentication error", "OK")
savecheck = win.find("Save this password", "check box")
if not savecheck.checked:
savecheck.click()
win.find("Login", "push button").click()
lib.utils.check(lambda: con.showing)
passwd.typeText("yy")
app.rawinput.pressKey("Enter")
app.click_alert_button("Viewer authentication error", "OK")
# Restart VM to retrigger console connect
self._destroy(win)
win.find("Run", "push button").click()
lib.utils.check(lambda: passwd.showing)
# Password should be empty now
lib.utils.check(lambda: not bool(passwd.text))
# Check proper password
passwd.text = ""
passwd.typeText("goodp")
win.find("Login", "push button").click()
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-vnc-password")
def testConsoleVNCPassword(self, dom):
ignore = dom
return self._checkPassword()
@_vm_wrapper("uitests-spice-password")
def testConsoleSpicePassword(self, dom):
ignore = dom
return self._checkPassword()
# Restart VM to retrigger console connect
_destroy(app, win)
win.find("Run", "push button").click()
lib.utils.check(lambda: passwd.showing)
# Password should be filled in
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()
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-vnc-password",
opts=["--test-options=fake-vnc-username"])
def testConsoleVNCPasswordUsername(self, dom):
ignore = dom
win = self.app.topwin
con = win.find("console-gfx-viewport")
lib.utils.check(lambda: not con.showing)
passwd = win.find("Password:", "password text")
lib.utils.check(lambda: passwd.showing)
username = win.find("Username:", "text")
lib.utils.check(lambda: username.showing)
# Restart VM to retrigger console connect
_destroy(app, win)
win.find("Run", "push button").click()
lib.utils.check(lambda: passwd.showing)
# Password should be empty now
lib.utils.check(lambda: not bool(passwd.text))
# 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()
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")
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-vnc-password")
def testConsoleVNCPassword(app, dom):
ignore = dom
return _checkPassword(app)
def _click_textconsole_menu(msg):
vmenu = win.find("^View$", "menu")
vmenu.click()
tmenu = win.find("Consoles", "menu")
tmenu.point()
tmenu.find(msg, "radio menu item").click()
# A bit of an extra test, make sure selecting Graphical Console works
_click_textconsole_menu("Serial 1")
lib.utils.check(lambda: not con.showing)
_click_textconsole_menu("Graphical Console")
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-spice-password")
def testConsoleSpicePassword(app, dom):
ignore = dom
return _checkPassword(app)
@_vm_wrapper("uitests-spice-standard")
def testConsoleAutoconnect(self, dom):
ignore = dom
win = self.app.topwin
con = win.find("console-gfx-viewport")
lib.utils.check(lambda: con.showing)
# Disable autoconnect
@_vm_wrapper("uitests-vnc-password",
opts=["--test-options=fake-vnc-username"])
def testConsoleVNCPasswordUsername(app, dom):
ignore = dom
win = app.topwin
con = win.find("console-gfx-viewport")
lib.utils.check(lambda: not con.showing)
passwd = win.find("Password:", "password text")
lib.utils.check(lambda: passwd.showing)
username = win.find("Username:", "text")
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()
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-vnc-socket")
def testConsoleVNCSocket(app, dom):
ignore = dom
win = app.topwin
con = win.find("console-gfx-viewport")
lib.utils.check(lambda: con.showing)
def _click_textconsole_menu(msg):
vmenu = win.find("^View$", "menu")
vmenu.click()
vmenu.find("Autoconnect").click()
dom.destroy()
self.app.sleep(1)
dom.create()
lib.utils.check(lambda: not con.showing)
win.find("Connect to console", "push button").click()
lib.utils.check(lambda: con.showing)
tmenu = win.find("Consoles", "menu")
tmenu.point()
# We need to sleep to give the menu time to dynamically populate
app.sleep(.5)
tmenu.find(msg, "radio menu item").click()
@_vm_wrapper("uitests-lxc-serial", uri="lxc:///")
def testConsoleLXCSerial(self, dom):
"""
Ensure LXC has serial open, and we can send some data
"""
ignore = dom
win = self.app.topwin
term = win.find("Serial Terminal")
lib.utils.check(lambda: term.showing)
term.typeText("help\n")
lib.utils.check(lambda: "COMMANDS" in term.text)
term.doubleClick()
term.click(button=3)
menu = self.app.root.find("serial-popup-menu")
menu.find("Copy", "menu item").click()
term.click()
term.click(button=3)
menu = self.app.root.find("serial-popup-menu")
menu.find("Paste", "menu item").click()
win.find("Details", "radio button").click()
win.find("Console", "radio button").click()
self._destroy(win)
view = self.app.root.find("^View$", "menu")
view.click()
# Triggers some tooltip cases
textmenu = view.find("Consoles", "menu")
textmenu.point()
lib.utils.check(lambda: textmenu.showing)
item = textmenu.find("Text Console 1")
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")
lib.utils.check(lambda: term.showing)
# Ensure ctrl+w doesn't close the window, modifiers are disabled
term.click()
win.keyCombo("<ctrl>w")
lib.utils.check(lambda: win.showing)
# Shut it down, ensure <ctrl>w works again
self._destroy(win)
win.click_title()
self.app.sleep(1)
win.keyCombo("<ctrl>w")
lib.utils.check(lambda: not win.showing)
# A bit of an extra test, make sure selecting Graphical Console works
_click_textconsole_menu("Serial 1")
lib.utils.check(lambda: not con.showing)
_click_textconsole_menu("Graphical Console")
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-spice-specific",
opts=["--test-options=spice-agent",
"--test-options=fake-console-resolution"])
def testConsoleSpiceSpecific(self, dom):
"""
Spice specific behavior. Has lots of devices that will open
channels, spice GL + local config, and usbredir
"""
ignore = dom
win = self.app.topwin
con = win.find("console-gfx-viewport")
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-spice-standard")
def testConsoleAutoconnect(app, dom):
ignore = dom
win = app.topwin
con = win.find("console-gfx-viewport")
lib.utils.check(lambda: con.showing)
# Just ensure the dialog pops up, can't really test much more
# than that
win.find("Virtual Machine", "menu").click()
win.find("Redirect USB", "menu item").click()
usbwin = self.app.root.find("vmm dialog", "alert")
usbwin.find("Select USB devices for redirection", "label")
usbwin.find("SPICE CD", "check box").click()
chooser = self.app.root.find(None, "file chooser")
# Find the cwd bookmark on the left
chooser.find("virt-manager", "label").click()
chooser.find("virt-manager", "label").click()
chooser.find("COPYING").click()
self.app.rawinput.pressKey("Enter")
lib.utils.check(lambda: not chooser.showing)
usbwin.find("Close", "push button").click()
# Test fake guest resize behavior
def _click_auto():
vmenu = win.find("^View$", "menu")
vmenu.click()
smenu = vmenu.find("Scale Display", "menu")
smenu.point()
smenu.find("Auto resize VM", "check menu item").click()
_click_auto()
win.click_title()
win.click_title()
_click_auto()
win.click_title()
win.click_title()
def _testLiveHotplug(self, fname):
win = self.app.topwin
win.find("Details", "radio button").click()
# Add a scsi disk, importing the passed path
win.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)
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.app.click_alert_button(
"The emulator may not have search permissions", "Yes")
# Verify no errors
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)
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()
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")
lib.utils.check(lambda: tab.showing)
entry.set_text(fname)
appl.click()
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: entry.text == fname)
entry.click_secondary_icon()
appl.click()
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not entry.text)
# Disable autoconnect
vmenu = win.find("^View$", "menu")
vmenu.click()
vmenu.find("Autoconnect").click()
dom.destroy()
app.sleep(1)
dom.create()
lib.utils.check(lambda: not con.showing)
win.find("Connect to console", "push button").click()
lib.utils.check(lambda: con.showing)
@_vm_wrapper("uitests-hotplug")
def testLiveHotplug(self, dom):
"""
Live test for basic hotplugging and media change, as well as
testing our auto-poolify magic
"""
ignore = dom
import tempfile
tmpdir = tempfile.TemporaryDirectory(prefix="uitests-tmp")
dname = tmpdir.name
@_vm_wrapper("uitests-lxc-serial", uri="lxc:///")
def testConsoleLXCSerial(app, dom):
"""
Ensure LXC has serial open, and we can send some data
"""
ignore = dom
win = app.topwin
term = win.find("Serial Terminal")
lib.utils.check(lambda: term.showing)
term.typeText("help\n")
lib.utils.check(lambda: "COMMANDS" in term.text)
term.doubleClick()
term.click(button=3)
menu = app.root.find("serial-popup-menu")
menu.find("Copy", "menu item").click()
term.click()
term.click(button=3)
menu = app.root.find("serial-popup-menu")
menu.find("Paste", "menu item").click()
win.find("Details", "radio button").click()
win.find("Console", "radio button").click()
_destroy(app, win)
view = app.root.find("^View$", "menu")
view.click()
# Triggers some tooltip cases
textmenu = view.find("Consoles", "menu")
textmenu.point()
lib.utils.check(lambda: textmenu.showing)
app.sleep(.5)
item = textmenu.find("Text Console 1")
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")
lib.utils.check(lambda: term.showing)
# Ensure ctrl+w doesn't close the window, modifiers are disabled
term.click()
win.keyCombo("<ctrl>w")
lib.utils.check(lambda: win.showing)
# Shut it down, ensure <ctrl>w works again
_destroy(app, win)
win.click_title()
app.sleep(1)
win.keyCombo("<ctrl>w")
lib.utils.check(lambda: not win.showing)
@_vm_wrapper("uitests-spice-specific",
opts=["--test-options=spice-agent",
"--test-options=fake-console-resolution"])
def testConsoleSpiceSpecific(app, dom):
"""
Spice specific behavior. Has lots of devices that will open
channels, spice GL + local config, and usbredir
"""
ignore = dom
win = app.topwin
con = win.find("console-gfx-viewport")
lib.utils.check(lambda: con.showing)
# Just ensure the dialog pops up, can't really test much more
# than that
win.find("Virtual Machine", "menu").click()
win.find("Redirect USB", "menu item").click()
usbwin = app.root.find("vmm dialog", "alert")
usbwin.find("Select USB devices for redirection", "label")
usbwin.find("SPICE CD", "check box").click()
chooser = app.root.find(None, "file chooser")
# Find the cwd bookmark on the left
chooser.find("virt-manager", "label").click()
chooser.find("virt-manager", "label").click()
chooser.find("COPYING").click()
app.rawinput.pressKey("Enter")
lib.utils.check(lambda: not chooser.showing)
usbwin.find("Close", "push button").click()
# Test fake guest resize behavior
def _click_auto():
vmenu = win.find("^View$", "menu")
vmenu.click()
smenu = vmenu.find("Scale Display", "menu")
smenu.point()
smenu.find("Auto resize VM", "check menu item").click()
_click_auto()
win.window_maximize()
_click_auto()
win.click_title()
win.click_title()
def _testLiveHotplug(app, fname):
win = app.topwin
win.find("Details", "radio button").click()
# Add a scsi disk, importing the passed path
win.find("add-hardware", "push button").click()
addhw = app.find_window("Add New Virtual Hardware")
addhw.find("Storage", "table cell").click()
tab = addhw.find("storage-tab", None)
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
app.click_alert_button(
"The emulator may not have search permissions", "Yes")
# Verify no errors
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)
lib.utils.check(lambda: tab.showing)
win.find("config-remove").click()
delete = app.find_window("Remove Disk")
delete.find_fuzzy("Delete", "button").click()
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")
lib.utils.check(lambda: tab.showing)
entry.set_text(fname)
appl.click()
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: entry.text == fname)
entry.click_secondary_icon()
appl.click()
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not entry.text)
@_vm_wrapper("uitests-hotplug")
def testLiveHotplug(app, dom):
"""
Live test for basic hotplugging and media change, as well as
testing our auto-poolify magic
"""
ignore = dom
import tempfile
tmpdir = tempfile.TemporaryDirectory(prefix="uitests-tmp")
dname = tmpdir.name
try:
fname = os.path.join(dname, "test.img")
os.system("qemu-img create -f qcow2 %s 1M > /dev/null" % fname)
os.system("chmod 700 %s" % dname)
_testLiveHotplug(app, fname)
finally:
poolname = os.path.basename(dname)
try:
fname = os.path.join(dname, "test.img")
os.system("qemu-img create -f qcow2 %s 1M > /dev/null" % fname)
os.system("chmod 700 %s" % dname)
self._testLiveHotplug(fname)
finally:
poolname = os.path.basename(dname)
try:
pool = self.conn.storagePoolLookupByName(poolname)
pool.destroy()
pool.undefine()
except Exception:
log.debug("Error cleaning up pool", exc_info=True)
pool = app.conn.storagePoolLookupByName(poolname)
pool.destroy()
pool.undefine()
except Exception:
log.debug("Error cleaning up pool", exc_info=True)

View File

@ -5,358 +5,331 @@ import tests.utils
from . import lib
class Manager(lib.testcase.UITestCase):
#############################################################
# UI tests for manager window, and basic VM lifecycle stuff #
#############################################################
def _testVMLifecycle(app):
"""
UI tests for manager window, and basic VM lifecycle stuff
Basic VM lifecycle test, shared between standard and no-events
testing
"""
manager = app.topwin
shutdown = manager.find("Shut Down", "push button")
pause = manager.find("Pause", "toggle button")
run = manager.find("Run", "push button")
force = manager.find("Force Off", "menu item")
smenu = manager.find("Menu", "toggle button")
save = manager.find("Save", "menu item")
##############
# Test cases #
##############
c = manager.find("test-many-devices", "table cell")
c.click()
smenu.click()
force.click()
app.click_alert_button("Are you sure you want", "Yes")
lib.utils.check(lambda: run.sensitive, timeout=5)
def _testVMLifecycle(self):
"""
Basic VM lifecycle test, shared between standard and no-events
testing
"""
manager = self.app.topwin
shutdown = manager.find("Shut Down", "push button")
pause = manager.find("Pause", "toggle button")
run = manager.find("Run", "push button")
force = manager.find("Force Off", "menu item")
smenu = manager.find("Menu", "toggle button")
save = manager.find("Save", "menu item")
c = manager.find("test-many-devices", "table cell")
c.click()
smenu.click()
force.click()
self.app.click_alert_button("Are you sure you want", "Yes")
lib.utils.check(lambda: run.sensitive, timeout=5)
run.click()
lib.utils.check(lambda: not run.sensitive, timeout=5)
pause.click()
lib.utils.check(lambda: pause.checked, timeout=5)
pause.click()
lib.utils.check(lambda: not pause.checked, timeout=5)
smenu.click()
save.click()
lib.utils.check(lambda: run.sensitive, timeout=5)
lib.utils.check(lambda: "Saved" in c.text)
run.click()
lib.utils.check(lambda: shutdown.sensitive, timeout=5)
def testVMLifecycle(self):
# qemu hits some different domain code paths for setTime
self.app.uri = tests.utils.URIs.kvm
self._testVMLifecycle()
def testVMNoEventsLifecycle(self):
self.app.open(extra_opts=["--test-options=no-events"])
# Change preferences timeout to 1 second
self.app.root.find("Edit", "menu").click()
self.app.root.find("Preferences", "menu item").click()
win = self.app.root.find_fuzzy("Preferences", "frame")
win.find("Polling", "page tab").click()
win.find("cpu-poll").set_text("1")
win.find("Close", "push button").click()
self._testVMLifecycle()
def testVMLifecycleExtra(self):
"""
Test vmmenu lifecycle options
"""
self.app.open(keyfile="confirm-all.ini")
manager = self.app.topwin
run = manager.find("Run", "push button")
shutdown = manager.find("Shut Down", "push button")
pause = manager.find("Pause", "toggle button")
def confirm_is_running():
lib.utils.check(lambda: not run.sensitive)
def confirm_is_shutdown():
lib.utils.check(lambda: not shutdown.sensitive)
def confirm_is_paused():
lib.utils.check(lambda: pause.checked)
def confirm_not_paused():
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")
menu.check_onscreen()
if shutdown:
smenu = menu.find("Shut Down", "menu")
smenu.point()
smenu.check_onscreen()
item = smenu.find(action, "menu item")
else:
item = menu.find(action, "menu item")
item.check_onscreen()
item.point()
self.app.sleep(.3)
item.click()
_select()
if confirm:
self.app.click_alert_button("Are you sure", "No")
_select()
self.app.click_alert_button("Are you sure", "Yes")
run.click()
lib.utils.check(lambda: not run.sensitive, timeout=5)
pause.click()
lib.utils.check(lambda: pause.checked, timeout=5)
pause.click()
lib.utils.check(lambda: not pause.checked, timeout=5)
smenu.click()
save.click()
lib.utils.check(lambda: run.sensitive, timeout=5)
lib.utils.check(lambda: "Saved" in c.text)
run.click()
lib.utils.check(lambda: shutdown.sensitive, timeout=5)
test_action("Force Reset")
confirm_is_running()
test_action("Reboot")
confirm_is_running()
test_action("Shut Down")
confirm_is_shutdown()
test_action("Run", shutdown=False, confirm=False)
confirm_is_running()
test_action("Force Off")
confirm_is_shutdown()
test_action("Run", shutdown=False, confirm=False)
confirm_is_running()
test_action("Pause", shutdown=False)
confirm_is_paused()
test_action("Resume", shutdown=False, confirm=False)
confirm_not_paused()
test_action("Save")
confirm_is_shutdown()
test_action("Restore", shutdown=False, confirm=False)
confirm_is_running()
def testVMLifecycle(app):
# qemu hits some different domain code paths for setTime
app.uri = tests.utils.URIs.kvm
_testVMLifecycle(app)
def testManagerSaveCancelError(self):
"""
Test managed save special behavior
"""
self.app.open(extra_opts=["--test-options=test-managed-save"])
manager = self.app.topwin
run = manager.find("Run", "push button")
smenu = manager.find("Menu", "toggle button")
save = manager.find("Save", "menu item")
def testVMNoEventsLifecycle(app):
app.open(extra_opts=["--test-options=no-events"])
c = manager.find("test-many-devices", "table cell")
c.click()
# Change preferences timeout to 1 second
app.root.find("Edit", "menu").click()
app.root.find("Preferences", "menu item").click()
win = app.find_window("Preferences")
win.find("Polling", "page tab").click()
win.find("cpu-poll").set_text("1")
win.find("Close", "push button").click()
# Save it, attempt a cancel operation
smenu.click()
save.click()
progwin = self.app.root.find("Saving Virtual Machine", "frame")
# Attempt cancel which will fail, then find the error message
progwin.find("Cancel", "push button").click()
progwin.find("Error cancelling save job")
lib.utils.check(lambda: not progwin.showing, timeout=5)
lib.utils.check(lambda: run.sensitive)
_testVMLifecycle(app)
# Restore will fail and offer to remove managed save
run.click()
self.app.click_alert_button("remove the saved state", "No")
lib.utils.check(lambda: run.sensitive)
run.click()
self.app.click_alert_button("remove the saved state", "Yes")
def testVMLifecycleExtra(app):
"""
Test vmmenu lifecycle options
"""
app.open(keyfile="confirm-all.ini")
manager = app.topwin
run = manager.find("Run", "push button")
shutdown = manager.find("Shut Down", "push button")
pause = manager.find("Pause", "toggle button")
def confirm_is_running():
lib.utils.check(lambda: not run.sensitive)
def testManagerQEMUSetTime(self):
def confirm_is_shutdown():
lib.utils.check(lambda: not shutdown.sensitive)
def confirm_is_paused():
lib.utils.check(lambda: pause.checked)
def confirm_not_paused():
lib.utils.check(lambda: not pause.checked)
def test_action(**kwargs):
app.manager_vm_action("test", confirm_click_no=True, **kwargs)
confirm_is_running()
test_action(reset=True)
confirm_is_running()
test_action(reboot=True)
confirm_is_running()
test_action(shutdown=True)
confirm_is_shutdown()
test_action(run=True)
confirm_is_running()
test_action(destroy=True)
confirm_is_shutdown()
test_action(run=True)
confirm_is_running()
test_action(pause=True)
confirm_is_paused()
test_action(resume=True)
confirm_not_paused()
test_action(save=True)
confirm_is_shutdown()
test_action(restore=True)
confirm_is_running()
def testManagerSaveCancelError(app):
"""
Test managed save special behavior
"""
app.open(extra_opts=["--test-options=test-managed-save"])
manager = app.topwin
run = manager.find("Run", "push button")
smenu = manager.find("Menu", "toggle button")
save = manager.find("Save", "menu item")
c = manager.find("test-many-devices", "table cell")
c.click()
# Save it, attempt a cancel operation
smenu.click()
save.click()
progwin = app.find_window("Saving Virtual Machine")
# Attempt cancel which will fail, then find the error message
progwin.find("Cancel", "push button").click()
progwin.find("Error cancelling save job")
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()
app.click_alert_button("remove the saved state", "No")
lib.utils.check(lambda: run.sensitive)
run.click()
app.click_alert_button("remove the saved state", "Yes")
lib.utils.check(lambda: not run.sensitive)
def testManagerQEMUSetTime(app):
"""
Fake qemu setTime behavior for code coverage
"""
app.uri = tests.utils.URIs.kvm
manager = app.topwin
run = manager.find("Run", "push button")
smenu = manager.find("Menu", "toggle button")
save = manager.find("Save", "menu item")
c = manager.find("test alternate devs title", "table cell")
c.click()
# Save -> resume -> save
smenu.click()
save.click()
lib.utils.check(lambda: run.sensitive)
app.sleep(1)
run.click()
lib.utils.check(lambda: not run.sensitive)
app.sleep(1)
smenu.click()
save.click()
lib.utils.check(lambda: run.sensitive)
app.sleep(1)
def testManagerVMRunFail(app):
# Force VM startup to fail so we can test the error path
app.open(extra_opts=["--test-options=test-vm-run-fail"])
manager = app.topwin
c = manager.find("test-clone-simple", "table cell")
c.click()
manager.find("Run", "push button").click()
app.click_alert_button("fake error", "Close")
def testManagerColumns(app):
# Enable all stat options
# Need to expand the window size so all columns are onscreen
app.open(keyfile="winsize.ini")
app.root.find("Edit", "menu").click()
app.root.find("Preferences", "menu item").click()
win = app.find_window("Preferences")
win.find("Polling", "page tab").click()
win.find_fuzzy("Poll Disk", "check").click()
win.find_fuzzy("Poll Network", "check").click()
win.find_fuzzy("Poll Memory", "check").click()
win.find("Close", "push button").click()
manager = app.topwin
def _test_sort(name):
col = manager.find(name, "table column header")
col.check_onscreen()
# Trigger sorting
col.click()
col.click()
def _click_column_menu(name):
manager.find("View", "menu").click()
menu = manager.find("Graph", "menu")
menu.point()
menu.find_fuzzy(name, "check menu item").click()
def _test_column(name):
_click_column_menu(name)
_test_sort(name)
_test_sort("Name")
_click_column_menu("Guest CPU")
_click_column_menu("Guest CPU")
_test_sort("CPU usage")
_test_column("Host CPU")
_test_column("Memory")
_test_column("Disk I/O")
_test_column("Network I/O")
def testManagerWindowReposition(app):
"""
Restore previous position when window is reopened
"""
manager = app.topwin
host = app.manager_open_host("Storage")
fmenu = host.find("File", "menu")
fmenu.click()
fmenu.find("View Manager", "menu item").click()
lib.utils.check(lambda: manager.active)
manager.window_maximize()
newx = manager.position[0]
newy = manager.position[1]
manager.keyCombo("<alt>F4")
host.click_title()
host.find("File", "menu").click()
host.find("View Manager", "menu item").click()
lib.utils.check(lambda: manager.showing)
assert manager.position == (newx, newy)
def testManagerWindowCleanup(app):
"""
Open migrate, clone, delete, newvm, details, host windows, close the
connection, make sure they all disappear
"""
def _drag(win):
"""
Fake qemu setTime behavior for code coverage
Drag a window so it's not obscuring the manager window
"""
self.app.uri = tests.utils.URIs.kvm
manager = self.app.topwin
run = manager.find("Run", "push button")
smenu = manager.find("Menu", "toggle button")
save = manager.find("Save", "menu item")
win.drag(1000, 1000)
c = manager.find("test alternate devs title", "table cell")
c.click()
manager = app.topwin
app.sleep(1)
manager.window_maximize()
# Save -> resume -> save
smenu.click()
save.click()
lib.utils.check(lambda: run.sensitive)
self.app.sleep(1)
run.click()
lib.utils.check(lambda: not run.sensitive)
self.app.sleep(1)
smenu.click()
save.click()
lib.utils.check(lambda: run.sensitive)
self.app.sleep(1)
# Open delete window hitting a special code path, then close it
manager.find("test-many-devices", "table cell").click()
manager.find("Edit", "menu").click()
manager.find("Delete", "menu item").click()
delete = app.root.find_fuzzy("Delete", "frame")
app.sleep(.5)
delete.click_title()
delete.window_close()
def testManagerVMRunFail(self):
# Force VM startup to fail so we can test the error path
self.app.open(extra_opts=["--test-options=test-vm-run-fail"])
# Open Clone window hitting a special code path, then close it
manager.find("test-clone", "table cell").click()
app.rawinput.pressKey("Menu")
app.root.find("Clone...", "menu item").click()
clone = app.find_window("Clone Virtual Machine")
app.sleep(.5)
clone.click_title()
clone.window_close()
manager = self.app.topwin
# Open host
c = manager.find_fuzzy("testdriver.xml", "table cell")
c.click()
app.sleep(.5)
c.doubleClick()
host = app.find_window("test testdriver.xml - Connection Details")
_drag(host)
c = manager.find("test-clone-simple", "table cell")
c.click()
manager.find("Run", "push button").click()
self.app.click_alert_button("fake error", "Close")
# Open details
c = manager.find("test-many-devices", "table cell")
c.click()
app.sleep(.5)
c.doubleClick()
details = app.find_details_window("test-many-devices")
_drag(details)
# Close the connection
app.sleep(.5)
manager.click_title()
app.sleep(.5)
app.manager_conn_disconnect("test testdriver.xml")
# Ensure all those windows aren't showing
lib.utils.check(lambda: not details.showing)
# Delete the connection, ensure the host dialog disappears
app.manager_conn_delete("test testdriver.xml")
lib.utils.check(lambda: not host.showing)
def testManagerColumns(self):
# Enable all stat options
# Need to expand the window size so all columns are onscreen
self.app.open(keyfile="winsize.ini")
self.app.root.find("Edit", "menu").click()
self.app.root.find("Preferences", "menu item").click()
win = self.app.root.find_fuzzy("Preferences", "frame")
win.find("Polling", "page tab").click()
win.find_fuzzy("Poll Disk", "check").click()
win.find_fuzzy("Poll Network", "check").click()
win.find_fuzzy("Poll Memory", "check").click()
win.find("Close", "push button").click()
def testManagerDefaultStartup(app):
app.open(use_uri=False)
manager = app.topwin
errlabel = manager.find("error-label")
lib.utils.check(
lambda: "Checking for virtualization" in errlabel.text)
lib.utils.check(
lambda: "File->Add Connection" in errlabel.text)
lib.utils.check(
lambda: "appropriate QEMU/KVM" in errlabel.text)
manager = self.app.topwin
def _test_sort(name):
col = manager.find(name, "table column header")
col.check_onscreen()
# Trigger sorting
col.click()
col.click()
def _click_column_menu(name):
manager.find("View", "menu").click()
menu = manager.find("Graph", "menu")
menu.point()
menu.find_fuzzy(name, "check menu item").click()
def _test_column(name):
_click_column_menu(name)
_test_sort(name)
_test_sort("Name")
_click_column_menu("Guest CPU")
_click_column_menu("Guest CPU")
_test_sort("CPU usage")
_test_column("Host CPU")
_test_column("Memory")
_test_column("Disk I/O")
_test_column("Network I/O")
def testManagerWindowReposition(self):
"""
Restore previous position when window is reopened
"""
manager = self.app.topwin
host = self.app.open_host_window("Storage")
fmenu = host.find("File", "menu")
fmenu.click()
fmenu.find("View Manager", "menu item").click()
lib.utils.check(lambda: manager.active)
# Double click title to maximize
manager.click_title()
manager.click_title()
newx = manager.position[0]
newy = manager.position[1]
manager.keyCombo("<alt>F4")
host.click_title()
host.find("File", "menu").click()
host.find("View Manager", "menu item").click()
lib.utils.check(lambda: manager.showing)
assert manager.position == (newx, newy)
manager.find("File", "menu").click()
manager.find("Quit", "menu item").click()
def testManagerWindowCleanup(self):
"""
Open migrate, clone, delete, newvm, details, host windows, close the
connection, make sure they all disappear
"""
def _drag(win):
"""
Drag a window so it's not obscuring the manager window
"""
win.drag(1000, 1000)
manager = self.app.topwin
# Open migrate dialog
c = manager.find("test-many-devices", "table cell")
c.click(button=3)
self.app.root.find("Migrate...", "menu item").click()
migrate = self.app.root.find("Migrate the virtual machine", "frame")
_drag(migrate)
# Open clone dialog
c = manager.find("test-clone", "table cell")
c.click()
self.app.rawinput.pressKey("Menu")
self.app.root.find("Clone...", "menu item").click()
clone = self.app.root.find("Clone Virtual Machine", "frame")
_drag(clone)
# Open delete dialog
c.click()
manager.find("Edit", "menu").click()
manager.find("Delete", "menu item").click()
delete = self.app.root.find_fuzzy("Delete", "frame")
_drag(delete)
# Open NewVM
self.app.root.find("New", "push button").click()
create = self.app.root.find("New VM", "frame")
_drag(create)
# Open host
c = manager.find_fuzzy("testdriver.xml", "table cell")
c.doubleClick()
host = self.app.root.find_fuzzy("Connection Details", "frame")
_drag(host)
# Open details
details = self.app.open_details_window("test-many-devices")
_drag(details)
# Close the connection
self.app.sleep(1)
manager.click()
c = manager.find_fuzzy("testdriver.xml", "table cell")
c.click()
c.click(button=3)
self.app.root.find("conn-disconnect", "menu item").click()
# Ensure all those windows aren't 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.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")
lib.utils.check(
lambda: "Checking for virtualization" in errlabel.text)
lib.utils.check(
lambda: "File->Add Connection" in errlabel.text)
lib.utils.check(
lambda: "appropriate QEMU/KVM" in errlabel.text)
manager.find("File", "menu").click()
manager.find("Quit", "menu item").click()
def testManagerConnOpenFail(self):
self.app.open(keyfile="baduri.ini")
manager = self.app.topwin
manager.find_fuzzy("bad uri", "table cell").doubleClick()
lib.utils.check(lambda: not manager.active)
self.app.click_alert_button("Unable to connect", "Close")
lib.utils.check(lambda: manager.active)
def testManagerConnOpenFail(app):
app.open(keyfile="baduri.ini")
manager = app.topwin
manager.find_fuzzy("bad uri", "table cell").doubleClick()
lib.utils.check(lambda: not manager.active)
app.click_alert_button("Unable to connect", "Close")
lib.utils.check(lambda: manager.active)

View File

@ -4,100 +4,101 @@
from . import lib
class MediaChange(lib.testcase.UITestCase):
#############################################
# UI tests for details storage media change #
#############################################
def testMediaChange(app):
vmname = "test-many-devices"
app.open(show_console=vmname)
win = app.find_details_window(vmname,
click_details=True, shutdown=True)
hw = win.find("hw-list")
tab = win.find("disk-tab")
combo = win.find("media-combo")
entry = win.find("media-entry")
appl = win.find("config-apply")
# Floppy + physical
hw.find("Floppy 1", "table cell").click()
combo.click_combo_entry()
combo.find(r"Floppy_install_label \(/dev/fdb\)")
lib.utils.check(lambda: entry.text == "No media detected (/dev/fda)")
entry.click()
entry.click_secondary_icon()
lib.utils.check(lambda: not entry.text)
appl.click()
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()
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()
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()
combo.click_combo_entry()
combo.find(path)
entry.click()
# Use the storage browser to select new floppy storage
tab.find("Browse", "push button").click()
app.select_storagebrowser_volume("default-pool", "iso-vol")
appl.click()
# Browse for image
hw.find("IDE CDROM 1", "table cell").click()
combo.click_combo_entry()
combo.find(r"Fedora12_media \(/dev/sr0\)")
entry.click()
tab.find("Browse", "push button").click()
app.select_storagebrowser_volume("default-pool", "backingl1.img")
# Check 'already in use' dialog
appl.click()
app.click_alert_button("already in use by", "No")
lib.utils.check(lambda: appl.sensitive)
appl.click()
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()
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not entry.text)
def testMediaHotplug(app):
"""
UI tests for details storage media change
Test in the case of a running VM
"""
vmname = "test-many-devices"
app.open(show_console=vmname)
win = app.find_details_window(vmname, click_details=True)
hw = win.find("hw-list")
entry = win.find("media-entry")
appl = win.find("config-apply")
##############
# Test cases #
##############
# CDROM + physical
hw.find("IDE CDROM 1", "table cell").click()
lib.utils.check(lambda: not entry.text)
entry.set_text("/dev/sr0")
appl.click()
app.click_alert_button("changes will take effect", "OK")
lib.utils.check(lambda: not appl.sensitive)
lib.utils.check(lambda: not entry.text)
def testMediaChange(self):
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")
entry = win.find("media-entry")
appl = win.find("config-apply")
# Floppy + physical
hw.find("Floppy 1", "table cell").click()
combo.click_combo_entry()
combo.find(r"Floppy_install_label \(/dev/fdb\)")
lib.utils.check(lambda: entry.text == "No media detected (/dev/fda)")
entry.click()
entry.click_secondary_icon()
lib.utils.check(lambda: not entry.text)
appl.click()
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()
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()
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()
combo.click_combo_entry()
combo.find(path)
entry.click()
# Use the storage browser to select new floppy storage
tab.find("Browse", "push button").click()
self.app.select_storagebrowser_volume("default-pool", "iso-vol")
appl.click()
# Browse for image
hw.find("IDE CDROM 1", "table cell").click()
combo.click_combo_entry()
combo.find(r"Fedora12_media \(/dev/sr0\)")
entry.click()
tab.find("Browse", "push button").click()
self.app.select_storagebrowser_volume("default-pool", "backingl1.img")
# Check 'already in use' dialog
appl.click()
self.app.click_alert_button("already in use by", "No")
lib.utils.check(lambda: appl.sensitive)
appl.click()
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()
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.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()
lib.utils.check(lambda: not entry.text)
entry.set_text("/dev/sr0")
appl.click()
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")
lib.utils.check(lambda: run.sensitive)
lib.utils.check(lambda: entry.text == "Fedora12_media (/dev/sr0)")
# Shutdown the VM, verify change shows up
win.find("Shut Down", "push button").click()
run = win.find("Run", "push button")
lib.utils.check(lambda: run.sensitive)
lib.utils.check(lambda: entry.text == "Fedora12_media (/dev/sr0)")

View File

@ -5,149 +5,147 @@ import tests.utils
from . import lib
class VMMMigrate(lib.testcase.UITestCase):
###################################
# UI tests for the migrate dialog #
###################################
def _open_migrate(app, vmname):
app.manager_vm_action(vmname, migrate=True)
return app.find_window("Migrate the virtual machine")
def testMigrateQemu(app):
# Use fake qemu connections
app.uri = tests.utils.URIs.kvm
newuri = (tests.utils.URIs.test_default +
",fakeuri=qemu+tcp://fakehost/system")
app.manager_createconn(newuri)
# Run default migrate
mig = _open_migrate(app, "test-many-devices")
mig.find("Migrate", "push button").click()
app.click_alert_button(
"the.connection.driver:.virDomainMigrate", "Close")
mig.find("Cancel", "push button").click()
lib.utils.check(lambda: not mig.showing)
# Run with deselected URI
mig = _open_migrate(app, "test-many-devices")
mig.find("address-check").click()
label = mig.find("Let libvirt decide")
label.check_onscreen()
mig.find("Migrate", "push button").click()
app.click_alert_button(
"the.connection.driver:.virDomainMigrate", "Close")
mig.find("Cancel", "push button").click()
lib.utils.check(lambda: not mig.showing)
# Run with tunnelled and other options
mig = _open_migrate(app, "test-many-devices")
mig.combo_select("Mode:", "Tunnelled")
mig.find("Advanced", "toggle button").click_expander()
mig.find("Allow unsafe:", "check box").click()
mig.find("Temporary", "check box").click()
mig.find("Migrate", "push button").click()
app.click_alert_button("p2p migration", "Close")
mig.find("Cancel", "push button").click()
lib.utils.check(lambda: not mig.showing)
def testMigrateXen(app):
# Use fake xen connections
app.uri = tests.utils.URIs.test_full + ",fakeuri=xen:///"
fakeremotexen = (tests.utils.URIs.test_default +
",fakeuri=xen+tcp://fakehost/")
app.manager_createconn(fakeremotexen)
# Run default migrate
mig = _open_migrate(app, "test-many-devices")
mig.find("Migrate", "push button").click()
app.click_alert_button(
"the.connection.driver:.virDomainMigrate", "Close")
mig.find("Cancel", "push button").click()
lib.utils.check(lambda: not mig.showing)
def testMigrateMock(app):
"""
UI tests for the migrate dialog
Trigger the mock migration testing we have to emulate success
"""
# Add an additional connection
app.manager_createconn("test:///default")
##############
# Test cases #
##############
# Run it and check some values
mig = _open_migrate(app, "test-many-devices")
mig.find("address-text").set_text("TESTSUITE-FAKE")
def _add_conn(self, uri):
manager = self.app.root
manager.find("File", "menu").click()
manager.find("Add Connection...", "menu item").click()
win = manager.find_fuzzy("Add Connection", "dialog")
win.combo_select("Hypervisor", "Custom URI")
win.find("uri-entry", "text").set_text(uri)
win.find("Connect", "push button").click()
lib.utils.check(lambda: win.showing is False)
mig.find("Migrate", "push button").click()
progwin = app.find_window("Migrating VM")
# Attempt cancel which will fail, then find the error message
progwin.find("Cancel", "push button").click()
progwin.find("Error cancelling migrate job")
lib.utils.check(lambda: not progwin.showing, timeout=5)
lib.utils.check(lambda: not mig.showing)
def _open_migrate(self, vmname):
c = self.app.root.find(vmname, "table cell")
c.click(button=3)
self.app.root.find("Migrate...", "menu item").click()
return self.app.root.find("Migrate the virtual machine", "frame")
def testMigrateQemu(self):
# Use fake qemu connections
self.app.uri = tests.utils.URIs.kvm
self._add_conn(tests.utils.URIs.test_default +
",fakeuri=qemu+tcp://fakehost/system")
def testMigrateConnMismatch(app):
# Add a possible target but disconnect it
app.uri = tests.utils.URIs.test_default
manager = app.topwin
manager.window_maximize()
manager.click()
app.manager_conn_disconnect("test default")
# Run default migrate
mig = self._open_migrate("test-many-devices")
mig.find("Migrate", "push button").click()
self.app.click_alert_button(
"the.connection.driver:.virDomainMigrate", "Close")
mig.find("Cancel", "push button").click()
lib.utils.check(lambda: not mig.showing)
# Add a mismatched hv connection
fakexen = tests.utils.URIs.test_empty + ",fakeuri=xen:///"
app.manager_createconn(fakexen)
# Run with deselected URI
mig = self._open_migrate("test-many-devices")
mig.find("address-check").click()
label = mig.find("Let libvirt decide")
label.check_onscreen()
mig.find("Migrate", "push button").click()
self.app.click_alert_button(
"the.connection.driver:.virDomainMigrate", "Close")
mig.find("Cancel", "push button").click()
lib.utils.check(lambda: not mig.showing)
# Open dialog and confirm no conns are available
app.manager_createconn(tests.utils.URIs.test_full)
mig = _open_migrate(app, "test-many-devices")
mig.find("conn-combo").find("No usable", "menu item")
# Run with tunnelled and other options
mig = self._open_migrate("test-many-devices")
mig.combo_select("Mode:", "Tunnelled")
mig.find("Advanced", "toggle button").click_expander()
mig.find("Allow unsafe:", "check box").click()
mig.find("Temporary", "check box").click()
# Test explicit dialog 'delete'
mig.keyCombo("<alt>F4")
lib.utils.check(lambda: not mig.showing)
mig.find("Migrate", "push button").click()
self.app.click_alert_button("p2p migration", "Close")
mig.find("Cancel", "push button").click()
lib.utils.check(lambda: not mig.showing)
# Ensure disconnecting will close the dialog
manager.click_title()
mig = _open_migrate(app, "test-many-devices")
app.manager_conn_disconnect("test testdriver.xml")
lib.utils.check(lambda: not mig.showing)
def testMigrateXen(self):
# Use fake xen connections
self.app.uri = tests.utils.URIs.test_full + ",fakeuri=xen:///"
fakeremotexen = (tests.utils.URIs.test_default +
",fakeuri=xen+tcp://fakehost/")
self._add_conn(fakeremotexen)
def testMigrateXMLEditor(app):
app.open(xmleditor_enabled=True)
manager = app.topwin
# Run default migrate
mig = self._open_migrate("test-many-devices")
mig.find("Migrate", "push button").click()
self.app.click_alert_button(
"the.connection.driver:.virDomainMigrate", "Close")
mig.find("Cancel", "push button").click()
lib.utils.check(lambda: not mig.showing)
# Add an additional connection
app.manager_createconn("test:///default")
def testMigrateMock(self):
"""
Trigger the mock migration testing we have to emulate success
"""
# Add an additional connection
self._add_conn("test:///default")
# Run it and check some values
vmname = "test-many-devices"
win = _open_migrate(app, vmname)
win.find("address-text").set_text("TESTSUITE-FAKE")
# Run it and check some values
mig = self._open_migrate("test-many-devices")
mig.find("address-text").set_text("TESTSUITE-FAKE")
# Create a new obj with XML edited name, verify it worked
newname = "aafroofroo"
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
newtext = xmleditor.text.replace(
">%s<" % vmname, ">%s<" % newname)
xmleditor.set_text(newtext)
win.find("Migrate", "push button").click()
lib.utils.check(lambda: not win.showing, timeout=10)
mig.find("Migrate", "push button").click()
progwin = self.app.root.find("Migrating VM", "frame")
# Attempt cancel which will fail, then find the error message
progwin.find("Cancel", "push button").click()
progwin.find("Error cancelling migrate job")
lib.utils.check(lambda: not progwin.showing, timeout=5)
lib.utils.check(lambda: not mig.showing)
manager.find(newname, "table cell")
def testMigrateConnMismatch(self):
# Add a possible target but disconnect it
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 = tests.utils.URIs.test_empty + ",fakeuri=xen:///"
self._add_conn(fakexen)
# Open dialog and confirm no conns are available
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")
lib.utils.check(lambda: not mig.showing)
def testMigrateXMLEditor(self):
self.app.open(xmleditor_enabled=True)
manager = self.app.topwin
# Add an additional connection
self._add_conn("test:///default")
# Run it and check some values
vmname = "test-many-devices"
win = self._open_migrate(vmname)
win.find("address-text").set_text("TESTSUITE-FAKE")
# Create a new obj with XML edited name, verify it worked
newname = "aafroofroo"
win.find("XML", "page tab").click()
xmleditor = win.find("XML editor")
newtext = xmleditor.text.replace(
">%s<" % vmname, ">%s<" % newname)
xmleditor.set_text(newtext)
win.find("Migrate", "push button").click()
lib.utils.check(lambda: not win.showing, timeout=10)
manager.find(newname, "table cell")
# Do standard xmleditor tests
win = self._open_migrate(vmname)
win.find("address-text").set_text("TESTSUITE-FAKE")
finish = win.find("Migrate", "push button")
lib.utils.test_xmleditor_interactions(self.app, win, finish)
win.find("Cancel", "push button").click()
lib.utils.check(lambda: not win.visible)
# Do standard xmleditor tests
win = _open_migrate(app, vmname)
win.find("address-text").set_text("TESTSUITE-FAKE")
finish = win.find("Migrate", "push button")
lib.utils.test_xmleditor_interactions(app, win, finish)
win.find("Cancel", "push button").click()
lib.utils.check(lambda: not win.visible)

View File

@ -4,137 +4,134 @@
from . import lib
class VMMPrefs(lib.testcase.UITestCase):
#######################################
# UI tests for the preferences dialog #
#######################################
def testPrefsAll(app):
app.root.find("Edit", "menu").click()
app.root.find("Preferences", "menu item").click()
win = app.find_window("Preferences")
generaltab = win.find("general-tab")
pollingtab = win.find("polling-tab")
newvmtab = win.find("newvm-tab")
consoletab = win.find("console-tab")
feedbacktab = win.find("feedback-tab")
feedbacktab.check_not_onscreen()
tab = generaltab
tab.check_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
tab.check_onscreen()
tab.find("Poll CPU", "check box").click()
tab.find("Poll Disk", "check box").click()
tab.find("Poll Memory", "check box").click()
tab.find("Poll Network", "check box").click()
period = tab.find_fuzzy("cpu-poll", "spin button")
period.click()
period.set_text("5")
win.find("New VM", "page tab").click()
tab = newvmtab
tab.check_onscreen()
tab.find("Add sound device", "check box").click()
tab.combo_select("CPU default:", "Copy host")
tab.combo_select("Storage format:", "Raw")
tab.combo_select("prefs-add-spice-usbredir", "No")
tab.combo_select("Graphics type", "VNC")
win.find("Console", "page tab").click()
tab = consoletab
tab.check_onscreen()
tab.combo_select("SPICE USB", "Manual redirect")
tab.combo_select("Resize guest", "On")
tab.combo_select("Graphical console scaling", "Always")
tab.find("Console autoconnect", "check box").click()
tab.find("Change...", "push button").click()
keyframe = app.find_window("Configure grab")
# On certain environments pressing "Alt_L" and
# clicking a window starts window drag operation.
# Work around by pushing both Control and Alt.
app.rawinput.holdKey("Control_L")
app.rawinput.holdKey("Alt_L")
app.rawinput.holdKey("Z")
# Test releasekey handler
app.rawinput.releaseKey("Z")
app.rawinput.holdKey("Z")
try:
keyframe.find_fuzzy("OK", "push button").click()
finally:
app.rawinput.releaseKey("Z")
app.rawinput.releaseKey("Alt_L")
app.rawinput.releaseKey("Control_L")
win.find("Feedback", "page tab").click()
tab = feedbacktab
tab.check_onscreen()
tab.find("Force Poweroff", "check box").click()
tab.find("Poweroff/Reboot", "check box").click()
tab.find("Pause", "check box").click()
tab.find("Device removal", "check box").click()
tab.find("Unapplied changes", "check box").click()
tab.find("Deleting storage", "check box").click()
win.find("General", "page tab").click()
win.find_fuzzy("Enable system tray", "check").click()
win.find_fuzzy("Close", "push button").click()
lib.utils.check(lambda: win.visible is False)
def testPrefsXMLEditor(app):
managerwin = app.topwin
managerwin.drag(0, 200)
detailswin = app.manager_open_details("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")
lib.utils.check(lambda: warnlabel.visible)
origtext = xmleditor.text
xmleditor.typeText("1234abcd")
lib.utils.check(lambda: xmleditor.text == origtext)
managerwin.click_title()
managerwin.grabFocus()
managerwin.find("Edit", "menu").click()
managerwin.find("Preferences", "menu item").click()
prefswin = app.find_window("Preferences")
prefswin.find_fuzzy("Enable XML").click()
prefswin.find_fuzzy("Close", "push button").click()
lib.utils.check(lambda: prefswin.visible is False)
managerwin.keyCombo("<alt>F4")
detailswin.click()
newtext = xmleditor.text.replace(">", "><title>FOOTITLE</title>", 1)
xmleditor.set_text(newtext)
finish.click()
detailswin.find("Details", "page tab").click()
lib.utils.check(lambda:
detailswin.find("Title:", "text").text == "FOOTITLE")
def testPrefsKeyfile(app):
"""
UI tests for the preferences dialog
Preload some keyfile settings and verify they work as expected
"""
app.open(use_uri=False, keyfile="defaultconn.ini")
managerwin = app.topwin
##############
# Test cases #
##############
def testPrefsAll(self):
self.app.root.find("Edit", "menu").click()
self.app.root.find("Preferences", "menu item").click()
win = self.app.root.find_fuzzy("Preferences", "frame")
generaltab = win.find("general-tab")
pollingtab = win.find("polling-tab")
newvmtab = win.find("newvm-tab")
consoletab = win.find("console-tab")
feedbacktab = win.find("feedback-tab")
feedbacktab.check_not_onscreen()
tab = generaltab
tab.check_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
tab.check_onscreen()
tab.find("Poll CPU", "check box").click()
tab.find("Poll Disk", "check box").click()
tab.find("Poll Memory", "check box").click()
tab.find("Poll Network", "check box").click()
period = tab.find_fuzzy("cpu-poll", "spin button")
period.click()
period.set_text("5")
win.find("New VM", "page tab").click()
tab = newvmtab
tab.check_onscreen()
tab.find("Add sound device", "check box").click()
tab.combo_select("CPU default:", "Copy host")
tab.combo_select("Storage format:", "Raw")
tab.combo_select("prefs-add-spice-usbredir", "No")
tab.combo_select("Graphics type", "VNC")
win.find("Console", "page tab").click()
tab = consoletab
tab.check_onscreen()
tab.combo_select("SPICE USB", "Manual redirect")
tab.combo_select("Resize guest", "On")
tab.combo_select("Graphical console scaling", "Always")
tab.find("Console autoconnect", "check box").click()
tab.find("Change...", "push button").click()
keyframe = self.app.root.find_fuzzy("Configure grab", "dialog")
# On certain environments pressing "Alt_L" and
# clicking a window starts window drag operation.
# Work around by pushing both Control and Alt.
self.app.rawinput.holdKey("Control_L")
self.app.rawinput.holdKey("Alt_L")
self.app.rawinput.holdKey("Z")
# Test releasekey handler
self.app.rawinput.releaseKey("Z")
self.app.rawinput.holdKey("Z")
try:
keyframe.find_fuzzy("OK", "push button").click()
finally:
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
tab.check_onscreen()
tab.find("Force Poweroff", "check box").click()
tab.find("Poweroff/Reboot", "check box").click()
tab.find("Pause", "check box").click()
tab.find("Device removal", "check box").click()
tab.find("Unapplied changes", "check box").click()
tab.find("Deleting storage", "check box").click()
win.find("General", "page tab").click()
win.find_fuzzy("Enable system tray", "check").click()
win.find_fuzzy("Close", "push button").click()
lib.utils.check(lambda: win.visible is False)
def testPrefsXMLEditor(self):
managerwin = self.app.topwin
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")
lib.utils.check(lambda: warnlabel.visible)
origtext = xmleditor.text
xmleditor.typeText("1234abcd")
lib.utils.check(lambda: xmleditor.text == origtext)
managerwin.click_title()
managerwin.grabFocus()
managerwin.find("Edit", "menu").click()
managerwin.find("Preferences", "menu item").click()
prefswin = self.app.root.find_fuzzy("Preferences", "frame")
prefswin.find_fuzzy("Enable XML").click()
prefswin.find_fuzzy("Close", "push button").click()
lib.utils.check(lambda: prefswin.visible is False)
managerwin.keyCombo("<alt>F4")
detailswin.click()
newtext = xmleditor.text.replace(">", "><title>FOOTITLE</title>", 1)
xmleditor.set_text(newtext)
finish.click()
detailswin.find("Details", "page tab").click()
lib.utils.check(lambda:
detailswin.find("Title:", "text").text == "FOOTITLE")
def testPrefsKeyfile(self):
"""
Preload some keyfile settings and verify they work as expected
"""
self.app.open(use_uri=False, keyfile="defaultconn.ini")
managerwin = self.app.topwin
# test:///default should be connected
managerwin.find("test default", "table cell")
managerwin.find("foo - Not Connected", "table cell")
# test:///default should be connected
managerwin.find("test default", "table cell")
managerwin.find("foo - Not Connected", "table cell")

View File

@ -4,189 +4,177 @@
from . import lib
class Snapshots(lib.testcase.UITestCase):
############################################
# UI tests for virt-manager's VM snapshots #
############################################
_DEFAULT_VMNAME = "test-snapshots"
def _open_snapshots_window(app, vmname=_DEFAULT_VMNAME):
if not app.is_running():
app.open(show_console=vmname)
win = app.find_details_window(vmname)
win.find("Snapshots", "radio button").click()
return win
def testSnapshotsSmokeTest(app):
"""
UI tests for virt-manager's VM snapshots
Smoke test to ensure all snapshots show correctly
"""
###################
# Private helpers #
###################
def _open_snapshots_window(self, vmname="test-snapshots"):
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("Snapshots", "radio button").click()
return win
win = _open_snapshots_window(app)
errlabel = win.find("snapshot-error-label", "label")
lst = win.find("snapshot-list", "table")
lib.utils.walkUIList(app, win, lst, lambda: errlabel.showing)
##############
# Test cases #
##############
def testSnapshotLifecycle(app):
"""
Create/delete/start/stop snapshots
"""
win = _open_snapshots_window(app)
vmrun = win.find("Run", "push button")
vmpause = win.find("Pause", "toggle button")
snaprun = win.find("snapshot-start", "push button")
def testSnapshotsSmokeTest(self):
"""
Smoke test to ensure all snapshots show correctly
"""
win = self._open_snapshots_window()
errlabel = win.find("snapshot-error-label", "label")
lst = win.find("snapshot-list", "table")
lib.utils.walkUIList(self.app, win, lst, lambda: errlabel.showing)
# Start already running snapshot
snapname = "internal-root"
win.find(snapname, "table cell").click()
snaprun.click()
app.click_alert_button("run the snapshot '%s'" % snapname, "Yes")
lib.utils.check(lambda: not vmrun.sensitive)
def testSnapshotLifecycle(self):
"""
Create/delete/start/stop snapshots
"""
win = self._open_snapshots_window()
vmrun = win.find("Run", "push button")
vmpause = win.find("Pause", "toggle button")
snaprun = win.find("snapshot-start", "push button")
# Start offline snapshot
snapname = "offline-root"
win.find(snapname, "table cell").click()
snaprun.click()
app.click_alert_button("run the snapshot '%s'" % snapname, "No")
lib.utils.check(lambda: not vmrun.sensitive)
snaprun.click()
app.click_alert_button("run the snapshot '%s'" % snapname, "Yes")
lib.utils.check(lambda: vmrun.sensitive)
# Start already running snapshot
snapname = "internal-root"
win.find(snapname, "table cell").click()
snaprun.click()
self.app.click_alert_button("run the snapshot '%s'" % snapname, "Yes")
lib.utils.check(lambda: not vmrun.sensitive)
# Start paused snapshot
snapname = "snap-paused"
win.find(snapname, "table cell").click()
snaprun.click()
app.click_alert_button("run the snapshot '%s'" % snapname, "Yes")
lib.utils.check(lambda: vmpause.checked)
# Start offline snapshot
snapname = "offline-root"
win.find(snapname, "table cell").click()
snaprun.click()
self.app.click_alert_button("run the snapshot '%s'" % snapname, "No")
lib.utils.check(lambda: not vmrun.sensitive)
snaprun.click()
self.app.click_alert_button("run the snapshot '%s'" % snapname, "Yes")
lib.utils.check(lambda: vmrun.sensitive)
# Edit snapshot
descui = win.find("snapshot-description")
desc = "TESTSNAP"
descui.set_text(desc)
win.find("snapshot-apply", "push button").click()
win.find("snapshot-refresh", "push button").click()
lib.utils.check(lambda: descui.text == desc)
# Apply by clicking away
desc += " ROUND2"
descui.set_text(desc)
win.find("internal-root", "table cell").click()
app.click_alert_button("There are unapplied changes", "Yes")
# Start paused snapshot
snapname = "snap-paused"
win.find(snapname, "table cell").click()
snaprun.click()
self.app.click_alert_button("run the snapshot '%s'" % snapname, "Yes")
lib.utils.check(lambda: vmpause.checked)
# Create new snapshot
win.find("snapshot-add", "push button").click()
newwin = app.find_window("Create snapshot")
snapname = "testnewsnap"
newwin.find("Name:", "text").set_text(snapname)
newwin.find("Description:", "text").set_text("testdesc")
newwin.find("Finish", "push button").click()
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname, "table cell")
lib.utils.check(lambda: newc.state_selected)
# Edit snapshot
descui = win.find("snapshot-description")
desc = "TESTSNAP"
descui.set_text(desc)
win.find("snapshot-apply", "push button").click()
win.find("snapshot-refresh", "push button").click()
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.app.click_alert_button("There are unapplied changes", "Yes")
# Delete it
win.find("snapshot-delete", "push button").click()
app.click_alert_button("permanently delete", "No")
lib.utils.check(lambda: not newc.dead)
win.find("snapshot-delete", "push button").click()
app.click_alert_button("permanently delete", "Yes")
lib.utils.check(lambda: newc.dead)
# Create new snapshot
win.find("snapshot-add", "push button").click()
newwin = self.app.root.find("Create snapshot", "frame")
snapname = "testnewsnap"
newwin.find("Name:", "text").set_text(snapname)
newwin.find("Description:", "text").set_text("testdesc")
newwin.find("Finish", "push button").click()
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname, "table cell")
lib.utils.check(lambda: newc.state_selected)
# Recreate another snapshot with the same name
win.find("snapshot-add", "push button").click()
newwin = app.find_window("Create snapshot")
snapname = "testnewsnap"
newwin.find("Name:", "text").set_text(snapname)
newwin.find("Finish", "push button").click()
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname, "table cell")
lib.utils.check(lambda: newc.state_selected)
# Delete it
win.find("snapshot-delete", "push button").click()
self.app.click_alert_button("permanently delete", "No")
lib.utils.check(lambda: not newc.dead)
win.find("snapshot-delete", "push button").click()
self.app.click_alert_button("permanently delete", "Yes")
lib.utils.check(lambda: newc.dead)
# Switch out of window
win.find("Details", "radio button").click()
lib.utils.check(lambda: not snaprun.showing)
# Recreate another snapshot with the same name
win.find("snapshot-add", "push button").click()
newwin = self.app.root.find("Create snapshot", "frame")
snapname = "testnewsnap"
newwin.find("Name:", "text").set_text(snapname)
newwin.find("Finish", "push button").click()
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname, "table cell")
lib.utils.check(lambda: newc.state_selected)
# Switch out of window
win.find("Details", "radio button").click()
lib.utils.check(lambda: not snaprun.showing)
def testSnapshotMisc1(app):
"""
Test snapshot corner cases
"""
vmname = "test-state-managedsave"
win = _open_snapshots_window(app, vmname)
vmrun = win.find("Restore", "push button")
def testSnapshotMisc1(self):
"""
Test snapshot corner cases
"""
manager = self.app.topwin
manager.find("vm-list").click()
for ignore in range(8):
self.app.rawinput.pressKey("Down")
vmname = "test-state-managedsave"
cell = manager.find_fuzzy(vmname, "table cell")
cell.bring_on_screen()
# Create new snapshot
win.find("snapshot-add", "push button").click()
app.click_alert_button("not become part of the snapshot", "Cancel")
lib.utils.check(lambda: win.active)
win.find("snapshot-add", "push button").click()
app.click_alert_button("not become part of the snapshot", "OK")
newwin = app.find_window("Create snapshot")
snapname1 = "testnewsnap1"
newwin.find("Name:", "text").set_text(snapname1)
newwin.find("Finish", "push button").click()
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname1, "table cell")
lib.utils.check(lambda: newc.state_selected)
win = self._open_snapshots_window(vmname=vmname)
vmrun = win.find("Restore", "push button")
# Start the VM, create another snapshot
vmrun.click()
lib.utils.check(lambda: not vmrun.sensitive)
win.find("snapshot-add", "push button").click()
newwin = app.find_window("Create snapshot")
# Force validation error
newwin.find("Name:", "text").set_text("bad name")
newwin.find("Finish", "push button").click()
app.click_alert_button("validating snapshot", "OK")
# Force name collision
newwin.find("Name:", "text").set_text(snapname1)
newwin.find("Finish", "push button").click()
app.click_alert_button(snapname1, "Close")
# Make it succeed
snapname2 = "testnewsnap2"
newwin.find("Name:", "text").set_text(snapname2)
newwin.find("Finish", "push button").click()
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname2, "table cell")
lib.utils.check(lambda: newc.state_selected)
# Create new snapshot
win.find("snapshot-add", "push button").click()
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.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()
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname1, "table cell")
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()
lib.utils.check(lambda: vmrun.sensitive)
win.find(snapname1, "table cell").click(button=3)
app.root.find("Start snapshot", "menu item").click()
app.click_alert_button("run the snapshot '%s'" % snapname1, "Yes")
app.click_alert_button("no memory state", "Cancel")
win.find("snapshot-start").click()
app.click_alert_button("run the snapshot '%s'" % snapname1, "Yes")
app.click_alert_button("no memory state", "OK")
# Start the VM, create another snapshot
vmrun.click()
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.app.click_alert_button("validating snapshot", "OK")
# Force name collision
newwin.find("Name:", "text").set_text(snapname1)
newwin.find("Finish", "push button").click()
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()
lib.utils.check(lambda: not newwin.showing)
newc = win.find(snapname2, "table cell")
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()
lib.utils.check(lambda: vmrun.sensitive)
win.find(snapname1, "table cell").click(button=3)
self.app.root.find("Start snapshot", "menu item").click()
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.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.app.rawinput.holdKey("Shift_L")
self.app.rawinput.pressKey("Down")
self.app.rawinput.releaseKey("Shift_L")
win.find("snapshot-delete").click()
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)
# Multi select
cell1 = win.find(snapname1, "table cell")
cell2 = win.find(snapname2, "table cell")
cell1.click()
app.rawinput.holdKey("Shift_L")
app.rawinput.pressKey("Down")
app.rawinput.releaseKey("Shift_L")
win.find("snapshot-delete").click()
app.click_alert_button("permanently delete", "Yes")
lib.utils.check(lambda: cell1.dead)
lib.utils.check(lambda: cell2.dead)
lib.utils.check(lambda: win.active)

View File

@ -5,120 +5,113 @@ import tests.utils
from . import lib
class Systray(lib.testcase.UITestCase):
"""
UI tests for virt-manager's systray using a fake testing backend
"""
####################################################################
# UI tests for virt-manager's systray using a fake testing backend #
####################################################################
##############
# Test cases #
##############
def testSystrayFake(app):
app.open(
keyfile="systray.ini",
extra_opts=["--test-options=fake-systray"],
window_name="Virtual Machine Manager")
def testSystrayFake(self):
self.app.open(
keyfile="systray.ini",
extra_opts=["--test-options=fake-systray"],
window_name="Virtual Machine Manager")
manager = app.topwin
systray = app.root.find("vmm-fake-systray", check_active=False)
manager.drag(1000, 1000)
manager = self.app.topwin
systray = self.app.root.find("vmm-fake-systray", check_active=False)
manager.drag(1000, 1000)
# Add a connection to trigger systray update
uri = tests.utils.URIs.kvm
app.manager_createconn(uri=uri)
# Add a connection to trigger systray update
uri = tests.utils.URIs.kvm
manager.find("File", "menu").click()
manager.find("Add Connection...", "menu item").click()
win = self.app.root.find_fuzzy("Add Connection", "dialog")
win.combo_select("Hypervisor", "Custom URI")
win.find("uri-entry", "text").set_text(uri)
win.find("Connect", "push button").click()
# Hide the manager
systray.click_title()
systray.click()
lib.utils.check(lambda: not manager.showing)
lib.utils.check(lambda: app.is_running())
# Hide the manager
systray.click_title()
systray.click()
lib.utils.check(lambda: not manager.showing)
lib.utils.check(lambda: self.app.is_running())
systray.click(button=3)
menu = app.root.find("vmm-systray-menu")
systray.click(button=3)
menu = self.app.root.find("vmm-systray-menu")
def _get_conn_action(connstr, actionstr):
if not menu.showing:
systray.click(button=3)
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)
lib.utils.check(lambda: item.showing)
def _get_conn_action(connstr, actionstr):
if not menu.showing:
systray.click(button=3)
lib.utils.check(lambda: not menu.showing)
lib.utils.check(lambda: menu.showing)
connmenu = menu.find(connstr, "menu")
connmenu.point()
ret = connmenu.find(actionstr, "menu")
ret.check_onscreen()
return ret
def _do_conn_action(connstr, actionstr):
item = _get_conn_action(connstr, actionstr)
item.click()
lib.utils.check(lambda: not menu.showing)
def _check_conn_action(connstr, actionstr):
item = _get_conn_action(connstr, actionstr)
lib.utils.check(lambda: item.showing)
app.rawinput.pressKey("Escape")
lib.utils.check(lambda: not menu.showing)
def _get_vm_action(connstr, vmname, action):
vmenu = _get_conn_action(connstr, vmname)
vmenu.point()
return vmenu.find(action, "menu")
def _do_conn_action(connstr, actionstr):
item = _get_conn_action(connstr, actionstr)
item.click()
lib.utils.check(lambda: not menu.showing)
def _check_vm_action(connstr, vmname, action):
item = _get_vm_action(connstr, vmname, action)
lib.utils.check(lambda: item.showing)
systray.click(button=3)
lib.utils.check(lambda: not menu.showing)
def _get_vm_action(connstr, vmname, action):
vmenu = _get_conn_action(connstr, vmname)
vmenu.point()
return vmenu.find(action, "menu")
def _do_vm_action(connstr, vmname, action):
item = _get_vm_action(connstr, vmname, action)
item.click()
lib.utils.check(lambda: not menu.showing)
def _check_vm_action(connstr, vmname, action):
item = _get_vm_action(connstr, vmname, action)
lib.utils.check(lambda: item.showing)
app.rawinput.pressKey("Escape")
lib.utils.check(lambda: not menu.showing)
# Right click start a connection
_check_conn_action("QEMU/KVM", "Disconnect")
_do_conn_action("test default", "Connect")
_check_conn_action("test default", "Disconnect")
_do_conn_action("test testdriver", "Disconnect")
_check_conn_action("test testdriver", "Connect")
def _do_vm_action(connstr, vmname, action):
item = _get_vm_action(connstr, vmname, action)
item.click()
lib.utils.check(lambda: not menu.showing)
# Trigger VM change
_do_vm_action("QEMU/KVM", "test-arm-kernel", "Pause")
_check_vm_action("QEMU/KVM", "test-arm-kernel", "Resume")
# Right click start a connection
_check_conn_action("QEMU/KVM", "Disconnect")
_do_conn_action("test default", "Connect")
_check_conn_action("test default", "Disconnect")
_do_conn_action("test testdriver", "Disconnect")
_check_conn_action("test testdriver", "Connect")
# Reshow the manager
systray.click()
lib.utils.check(lambda: manager.showing)
lib.utils.check(lambda: self.app.is_running())
# Trigger VM change
_do_vm_action("QEMU/KVM", "test-arm-kernel", "Pause")
_check_vm_action("QEMU/KVM", "test-arm-kernel", "Resume")
# Close from the menu
systray.click_title()
systray.click(button=3)
menu = self.app.root.find("vmm-systray-menu")
menu.find("Quit", "menu item").click()
# Reshow the manager
systray.click()
lib.utils.check(lambda: manager.showing)
lib.utils.check(lambda: app.is_running())
lib.utils.check(lambda: not self.app.is_running())
# Close from the menu
systray.click_title()
systray.click(button=3)
menu = app.root.find("vmm-systray-menu")
menu.find("Quit", "menu item").click()
def testSystrayToggle(self):
self.app.open(
keyfile="systray.ini",
extra_opts=["--test-options=fake-systray"],
window_name="Virtual Machine Manager")
lib.utils.check(lambda: not app.is_running())
manager = self.app.topwin
systray = self.app.root.find("vmm-fake-systray", check_active=False)
manager.find("Edit", "menu").click()
manager.find("Preferences", "menu item").click()
prefs = self.app.root.find_fuzzy("Preferences", "frame")
# Close the system tray
prefs.click_title()
prefs.find_fuzzy("Enable system tray", "check").click()
lib.utils.check(lambda: not systray.showing)
def testSystrayToggle(app):
app.open(
keyfile="systray.ini",
extra_opts=["--test-options=fake-systray"],
window_name="Virtual Machine Manager")
# Close the manager
manager.click_title()
manager.keyCombo("<alt>F4")
lib.utils.check(lambda: not self.app.is_running())
manager = app.topwin
systray = app.root.find("vmm-fake-systray", check_active=False)
manager.find("Edit", "menu").click()
manager.find("Preferences", "menu item").click()
prefs = app.find_window("Preferences")
# Close the system tray
prefs.click_title()
prefs.find_fuzzy("Enable system tray", "check").click()
lib.utils.check(lambda: not systray.showing)
# Close the manager
manager.click_title()
manager.keyCombo("<alt>F4")
lib.utils.check(lambda: not app.is_running())

View File

@ -1185,7 +1185,7 @@ class vmmConnection(vmmGObject):
if self.is_disconnected():
return # pragma: no cover
if self.is_connecting() and not force:
return
return # pragma: no cover
# We need to set this before the event check, since stats polling
# is independent of events

View File

@ -1377,7 +1377,7 @@ class vmmDomain(vmmLibvirtObject):
start_job_progress_thread(self, meter, _("Saving domain to disk"))
if self.config.CLITestOptions.test_managed_save:
time.sleep(3)
time.sleep(1.2)
self._backend.managedSave(0)
def has_managed_save(self):
@ -1437,7 +1437,7 @@ class vmmDomain(vmmLibvirtObject):
if self.conn.is_test() and "TESTSUITE-FAKE" in (dest_uri or ""):
# If using the test driver and a special URI, fake successful
# migration so we can test more of the migration wizard
time.sleep(3)
time.sleep(1.2)
if not xml:
xml = self.get_xml_to_define()
destconn.define_domain(xml).create()