virt-manager/tests/uitests/test_delete.py

306 lines
9.2 KiB
Python
Raw Normal View History

# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import os
import shutil
import tests.utils
from . import lib
class _DeleteRow:
"""
Helper class for interacting with the delete dialog rows
"""
def __init__(self, cell1, cell2, cell3, cell4):
ignore = cell4
self.chkcell = cell1
self.path = cell2.text
self.target = cell3.text
self.undeletable = not self.chkcell.sensitive
self.default = self.chkcell.checked
self.notdefault = not self.undeletable and not self.default
def _create_testdriver_path(fn):
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)
try:
if not os.path.exists(tmpdir):
os.mkdir(tmpdir)
open(tmppath, "w").write("foo")
os.chmod(tmppath, 0o444)
return fn(app, tmppath, *args, **kwargs)
finally:
if os.path.exists(tmpdir):
os.chmod(tmpdir, 0o777)
shutil.rmtree(tmpdir)
return wrapper
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(app, vmname):
app.manager_vm_action(vmname, delete=True)
return app.find_window("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 = "/pool-dir/overlay.img"
nondefault_path2 = "/pool-dir/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")
slist.click()
chkcell = found[0].chkcell
chkcell.bring_on_screen()
chkcell.click()
chkcell.click()
chkcell.click()
lib.utils.check(lambda: chkcell.checked)
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("pool-dir", "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")
@_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)
@_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)
@_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")
# Ensure disconnecting will close the dialog
win = _open_delete(app, "test-clone")
app.manager_test_conn_window_cleanup("test testdriver.xml", win)
def testDeleteRemoteManyDevices(app):
"""
Test with a remote VM to hit a certain code path
"""
app.uri = tests.utils.URIs.kvm_x86_remote
_testDeleteManyDevices(app)
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")
lib.utils.check(lambda: chk.checked)
chk.click()
lib.utils.check(lambda: not chk.checked)
lib.utils.check(lambda: not slist.showing)
_finish(app, delete, None)
# Confirm nothing was deleted compare to the default selections
browser = _open_storage_browser(app)
browser.find_fuzzy("pool-dir", "table cell").click()
browser.find("vol-refresh", "push button").click()
browser.find("overlay.img", "table cell")
browser.find("sharevol.img", "table cell")
def testDeleteDeviceNoStorage(app):
"""
Verify successful device remove with storage doesn't
touch host storage
"""
details = app.manager_open_details("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()
delete = app.find_window("Remove Disk")
chk = delete.find("Delete associated", "check box")
lib.utils.check(lambda: not chk.checked)
_finish(app, delete, [])
details.window_close()
browser = _open_storage_browser(app)
browser.find_fuzzy("pool-dir", "table cell").click()
browser.find("vol-refresh", "push button").click()
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)
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 = "/pool-dir/overlay.img"
delete.find_fuzzy(path)
_finish(app, delete, [path])
details.window_close()
browser = _open_storage_browser(app)
browser.find_fuzzy("pool-dir", "table cell").click()
browser.find("vol-refresh", "push button").click()
lib.utils.check(lambda: "overlay.img" not in browser.fmt_nodes())
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()
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 = "/pool-dir/overlay.img"
delete.find_fuzzy(path)
_finish(app, delete, [path], expect_fail=True)
app.click_alert_button("Storage will not be.*deleted", "OK")
details.window_close()
# Verify file still exists
browser = _open_storage_browser(app)
browser.find_fuzzy("pool-dir", "table cell").click()
browser.find("vol-refresh", "push button").click()
browser.find("overlay.img", "table cell")