ui: Add createnet/pool/vol/interface tests

This commit is contained in:
Cole Robinson 2018-01-11 15:32:18 -05:00
parent 570ee90c4d
commit d8d71bddfb
12 changed files with 443 additions and 29 deletions

View File

@ -19,7 +19,7 @@ class VMMConnect(uiutils.UITestCase):
uiutils.check_in_loop(lambda: "Not Connected" in c.text)
c.click(button=3)
self.app.root.find_pattern("conn-delete", "menu item").click()
err = self.app.root.find_pattern("vmm simple dialog", "alert")
err = self.app.root.find_pattern("vmm dialog", "alert")
err.find_fuzzy("will remove the connection", "label")
err.find_fuzzy("Yes", "push button").click()
uiutils.check_in_loop(lambda: c.dead)
@ -56,7 +56,7 @@ class VMMConnect(uiutils.UITestCase):
urilabel.text == "xen+tcp://fribuser@redhat.com:12345/")
connect.click()
err = self.app.root.find_fuzzy("vmm error dialog", "alert")
err = self.app.root.find_fuzzy("vmm dialog", "alert")
err.find_fuzzy("No", "push button").click()
# Test with custom test:///default connection

View File

@ -0,0 +1,97 @@
from tests.uitests import utils as uiutils
class CreateInterface(uiutils.UITestCase):
"""
UI tests for the createinterface wizard
"""
##############
# Test cases #
##############
def testCreateInterface(self):
# Open the createnet dialog
hostwin = self._open_host_window("Network Interfaces")
hostwin.find_pattern("interface-add", "push button").click()
win = self.app.root.find_pattern(
"Configure network interface", "frame")
# Create a simple default object
newname = "a-test-new-iface"
forward = win.find_pattern("Forward", "push button")
finish = win.find_pattern("Finish", "push button")
forward.click()
win.find_pattern("bridge-configure", "push button").click()
bridgewin = self.app.root.find_pattern(
"Bridge configuration", "dialog")
bridgewin.find_pattern(None,
"spin button", "Forward delay:").text = "0.05"
bridgewin.find_pattern("OK", "push button").click()
name = win.find_pattern(None, "text", "Name:")
name.text = newname
finish.click()
# Select the new object in the host window, then do
# start->stop->delete, for lifecycle testing
uiutils.check_in_loop(lambda: hostwin.active)
cell = hostwin.find_pattern(newname, "table cell")
delete = hostwin.find_pattern("interface-delete", "push button")
start = hostwin.find_pattern("interface-start", "push button")
stop = hostwin.find_pattern("interface-stop", "push button")
cell.click()
start.click()
alert = self.app.root.find_pattern("vmm dialog", "alert")
alert.find_fuzzy("sure you want to start the interface", "label")
alert.find_pattern("Yes", "push button").click()
uiutils.check_in_loop(lambda: stop.sensitive)
stop.click()
alert = self.app.root.find_pattern("vmm dialog", "alert")
alert.find_fuzzy("sure you want to stop the interface", "label")
alert.find_fuzzy("Don't ask me again", "check box").click()
alert.find_pattern("Yes", "push button").click()
# Delete it
uiutils.check_in_loop(lambda: delete.sensitive)
delete.click()
alert = self.app.root.find_pattern("vmm dialog", "alert")
alert.find_fuzzy("permanently delete the interface", "label")
alert.find_pattern("Yes", "push button").click()
# Ensure it's gone
uiutils.check_in_loop(lambda: cell.dead)
# Click some more UI, but just cancel it, it's a pain to
# figure out clicking checked cell renderers for bond interfaces...
hostwin.find_pattern("interface-add", "push button").click()
uiutils.check_in_loop(lambda: win.active)
typ = win.find_pattern(None, "combo box", "Interface type:")
typ.click()
typ.find_pattern("Bond", "menu item").click()
forward.click()
win.find_pattern("ip-configure", "push button").click()
ipwin = self.app.root.find_pattern("IP Configuration", "dialog")
ipwin.find_pattern("IPv6", "page tab").click()
combo = ipwin.find_pattern("ipv6-mode", "combo box")
combo.click()
combo.find_pattern("DHCP", "menu item").click()
ipwin.find_pattern("OK", "push button").click()
win.find_pattern("bond-configure", "push button").click()
bondwin = self.app.root.find_pattern("Bonding configuration", "dialog")
combo = bondwin.find_pattern(None, "combo box", "Bond monitor mode:")
combo.click()
combo.find_pattern("miimon", "menu item").click()
bondwin.find_pattern("OK", "push button").click()
forward = win.find_pattern("Cancel", "push button").click()
uiutils.check_in_loop(lambda: not win.active)
uiutils.check_in_loop(lambda: hostwin.active)
# Ensure host window closes fine
hostwin.click()
hostwin.keyCombo("<ctrl>w")
uiutils.check_in_loop(lambda: not hostwin.showing and
not hostwin.active)

View File

@ -0,0 +1,60 @@
from tests.uitests import utils as uiutils
class CreateNet(uiutils.UITestCase):
"""
UI tests for the createnet wizard
"""
##############
# Test cases #
##############
def testCreateNet(self):
# Open the createnet dialog
hostwin = self._open_host_window("Virtual Networks")
hostwin.find_pattern("net-add", "push button").click()
win = self.app.root.find_pattern(
"Create a new virtual network", "frame")
# Create a simple default network
newname = "a-test-new-net"
forward = win.find_pattern("Forward", "push button")
finish = win.find_pattern("Finish", "push button")
name = win.find_pattern(None, "text", "Network Name:")
name.text = newname
forward.click()
forward.click()
forward.click()
finish.click()
# Select the new network in the host window, then do
# stop->start->stop->delete, for lifecycle testing
uiutils.check_in_loop(lambda: hostwin.active)
cell = hostwin.find_pattern(newname, "table cell")
delete = hostwin.find_pattern("net-delete", "push button")
start = hostwin.find_pattern("net-start", "push button")
stop = hostwin.find_pattern("net-stop", "push button")
cell.click()
stop.click()
uiutils.check_in_loop(lambda: start.sensitive)
start.click()
uiutils.check_in_loop(lambda: stop.sensitive)
stop.click()
uiutils.check_in_loop(lambda: delete.sensitive)
# Delete it
delete.click()
alert = self.app.root.find_pattern("vmm dialog", "alert")
alert.find_fuzzy("permanently delete the network", "label")
alert.find_pattern("Yes", "push button").click()
# Ensure it's gone
uiutils.check_in_loop(lambda: cell.dead)
# Ensure host window closes fine
hostwin.click()
hostwin.keyCombo("<ctrl>w")
uiutils.check_in_loop(lambda: not hostwin.showing and
not hostwin.active)

View File

@ -0,0 +1,84 @@
from tests.uitests import utils as uiutils
class CreatePool(uiutils.UITestCase):
"""
UI tests for the createpool wizard
"""
##############
# Test cases #
##############
def testCreatePool(self):
# Open the createnet dialog
hostwin = self._open_host_window("Storage")
hostwin.find_pattern("pool-add", "push button").click()
win = self.app.root.find_pattern(
"Add a New Storage Pool", "frame")
# Create a simple default dir pool
newname = "a-test-new-pool"
forward = win.find_pattern("Forward", "push button")
finish = win.find_pattern("Finish", "push button")
name = win.find_pattern(None, "text", "Name:")
name.text = newname
forward.click()
finish.click()
# Select the new object in the host window, then do
# stop->start->stop->delete, for lifecycle testing
uiutils.check_in_loop(lambda: hostwin.active)
cell = hostwin.find_pattern(newname, "table cell")
delete = hostwin.find_pattern("pool-delete", "push button")
start = hostwin.find_pattern("pool-start", "push button")
stop = hostwin.find_pattern("pool-stop", "push button")
cell.click()
stop.click()
uiutils.check_in_loop(lambda: start.sensitive)
start.click()
uiutils.check_in_loop(lambda: stop.sensitive)
stop.click()
uiutils.check_in_loop(lambda: delete.sensitive)
# Delete it
delete.click()
alert = self.app.root.find_pattern("vmm dialog", "alert")
alert.find_fuzzy("permanently delete the pool", "label")
alert.find_pattern("Yes", "push button").click()
# Ensure it's gone
uiutils.check_in_loop(lambda: cell.dead)
# Test a scsi pool
hostwin.find_pattern("pool-add", "push button").click()
uiutils.check_in_loop(lambda: win.active)
typ = win.find_pattern(None, "combo box", "Type:")
newname = "a-scsi-pool"
name.text = "a-scsi-pool"
typ.click()
win.find_fuzzy("SCSI Host Adapter", "menu item").click()
forward.click()
finish.click()
hostwin.find_pattern(newname, "table cell")
# Test a ceph pool
hostwin.find_pattern("pool-add", "push button").click()
uiutils.check_in_loop(lambda: win.active)
newname = "a-ceph-pool"
name.text = "a-ceph-pool"
typ.click()
win.find_fuzzy("RADOS Block", "menu item").click()
forward.click()
win.find_fuzzy(None, "text", "Host Name:").text = "example.com:1234"
win.find_fuzzy(None, "text", "Source Name:").typeText("frob")
finish.click()
hostwin.find_pattern(newname, "table cell")
# Ensure host window closes fine
hostwin.click()
hostwin.keyCombo("<ctrl>w")
uiutils.check_in_loop(lambda: not hostwin.showing and
not hostwin.active)

View File

@ -0,0 +1,57 @@
from tests.uitests import utils as uiutils
class CreateVol(uiutils.UITestCase):
"""
UI tests for the createvol wizard
"""
##############
# Test cases #
##############
def testCreateVol(self):
# Open the createnet dialog
hostwin = self._open_host_window("Storage")
poolcell = hostwin.find_pattern("default-pool", "table cell")
poolcell.click()
hostwin.find_pattern("vol-new", "push button").click()
win = self.app.root.find_pattern(
"Add a Storage Volume", "frame")
# Create a default qcow2 volume
newname = "a-newvol"
finish = win.find_pattern("Finish", "push button")
name = win.find_pattern(None, "text", "Name:")
name.text = newname
win.find_pattern(None, "spin button", "Max Capacity:").text = "10.5"
finish.click()
# Delete it
vollist = hostwin.find_pattern("vol-list", "table")
volcell = vollist.find_pattern(newname + ".qcow2")
volcell.click()
hostwin.find_pattern("vol-refresh", "push button").click()
hostwin.find_pattern("vol-delete", "push button").click()
alert = self.app.root.find_pattern("vmm dialog", "alert")
alert.find_fuzzy("permanently delete the volume", "label")
alert.find_pattern("Yes", "push button").click()
uiutils.check_in_loop(lambda: volcell.dead)
# Create a raw volume too
hostwin.find_pattern("vol-new", "push button").click()
uiutils.check_in_loop(lambda: win.active)
newname = "a-newvol.raw"
name.text = newname
combo = win.find_pattern(None, "combo box", "Format:")
combo.click()
combo.find_pattern("raw", "menu item").click()
win.find_pattern(None, "spin button", "Allocation:").text = "0.5"
finish.click()
vollist.find_pattern(newname)
# Ensure host window closes fine
hostwin.keyCombo("<ctrl>w")
uiutils.check_in_loop(lambda: not hostwin.showing and
not hostwin.active)

View File

@ -6,21 +6,6 @@ class Host(uiutils.UITestCase):
UI tests for virt-manager's VM details window
"""
###################
# Private helpers #
###################
def _open_host_window(self, tab):
conn_label = "test testdriver.xml"
self.app.root.find_fuzzy(conn_label, "table cell").click()
self.app.root.find_fuzzy("Edit", "menu").click()
self.app.root.find_fuzzy("Connection Details", "menu item").click()
win = self.app.root.find_fuzzy(
"%s Connection Details" % conn_label, "frame")
win.find_fuzzy(tab, "page tab").click()
return win
##############
# Test cases #
##############

View File

@ -56,7 +56,7 @@ class NewVM(uiutils.UITestCase):
delete = self.app.root.find_fuzzy("Delete", "frame")
delete.find_fuzzy("Delete", "button").click()
alert = self.app.root.find_pattern("vmm error dialog", "alert")
alert = self.app.root.find_pattern("vmm dialog", "alert")
alert.find_fuzzy("Yes", "push button").click()
# Verify delete dialog and VM dialog are now gone
@ -212,7 +212,7 @@ class NewVM(uiutils.UITestCase):
newvm.find_fuzzy("Forward", "button").click()
# Disk collision box pops up, hit ok
alert = self.app.root.find_pattern("vmm simple dialog", "alert")
alert = self.app.root.find_pattern("vmm dialog", "alert")
alert.find_fuzzy("Yes", "push button").click()
newvm.find_fuzzy("Forward", "button").click()

View File

@ -24,6 +24,21 @@ class UITestCase(unittest.TestCase):
def tearDown(self):
self.app.stop()
# A little helper to save test files from having to import time
sleep = time.sleep
def _open_host_window(self, tab, conn_label="test testdriver.xml"):
"""
Helper to open host connection window and switch to a tab
"""
self.app.root.find_fuzzy(conn_label, "table cell").click()
self.app.root.find_fuzzy("Edit", "menu").click()
self.app.root.find_fuzzy("Connection Details", "menu item").click()
win = self.app.root.find_fuzzy(
"%s Connection Details" % conn_label, "frame")
win.find_fuzzy(tab, "page tab").click()
return win
def _walkUIList(self, win, lst, error_cb):
"""
Toggle down through a UI list like addhardware, net/storage/iface

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<!-- Generated with glade 3.20.2 -->
<interface>
<requires lib="gtk+" version="3.14"/>
<object class="GtkAdjustment" id="adjustment1">
@ -177,6 +177,9 @@
<action-widgets>
<action-widget response="0">bridge-ok</action-widget>
</action-widgets>
<child>
<placeholder/>
</child>
</object>
<object class="GtkAdjustment" id="adjustment3">
<property name="upper">1024</property>
@ -272,7 +275,9 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Bond monitor mode:</property>
<property name="label" translatable="yes">B_ond monitor mode:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">bond-monitor-mode</property>
</object>
<packing>
<property name="left_attach">0</property>
@ -305,7 +310,9 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Bond mode:</property>
<property name="label" translatable="yes">_Bond mode:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">bond-mode</property>
</object>
<packing>
<property name="left_attach">0</property>
@ -758,6 +765,9 @@
<action-widgets>
<action-widget response="0">bond-ok</action-widget>
</action-widgets>
<child>
<placeholder/>
</child>
</object>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
@ -1183,6 +1193,11 @@
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_bridge_config_button_clicked" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="bridge-config-button-atkobject">
<property name="AtkObject::accessible-name">bridge-configure</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -1223,6 +1238,11 @@
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_bond_config_button_clicked" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="bond-config-button-atkobject">
<property name="AtkObject::accessible-name">bond-configure</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -1282,6 +1302,11 @@
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_ip_config_button_clicked" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="ip-config-button-atkobject">
<property name="AtkObject::accessible-name">ip-configure</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -1455,6 +1480,9 @@
</child>
</object>
</child>
<child type="titlebar">
<placeholder/>
</child>
</object>
<object class="GtkDialog" id="ip-config">
<property name="can_focus">False</property>
@ -1646,6 +1674,11 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="changed" handler="on_ipv4_mode_changed" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="ipv4-mode-atkobject">
<property name="AtkObject::accessible-name">ipv4-mode</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -1805,6 +1838,11 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="changed" handler="on_ipv6_mode_changed" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="ipv6-mode-atkobject">
<property name="AtkObject::accessible-name">ipv6-mode</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -2093,5 +2131,8 @@
<action-widgets>
<action-widget response="0">ip-ok</action-widget>
</action-widgets>
<child>
<placeholder/>
</child>
</object>
</interface>

View File

@ -1302,6 +1302,11 @@
<property name="stock">gtk-add</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="net-add-atkobject">
<property name="AtkObject::accessible-name">net-add</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -1324,6 +1329,11 @@
<property name="stock">gtk-media-play</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="net-start-atkobject">
<property name="AtkObject::accessible-name">net-start</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -1346,6 +1356,11 @@
<property name="stock">gtk-stop</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="net-stop-atkobject">
<property name="AtkObject::accessible-name">net-stop</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -1368,6 +1383,11 @@
<property name="stock">gtk-delete</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="net-delete-atkobject">
<property name="AtkObject::accessible-name">net-delete</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -1978,6 +1998,11 @@ here</property>
<property name="stock">gtk-add</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="interface-add-atkobject">
<property name="AtkObject::accessible-name">interface-add</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -2000,6 +2025,11 @@ here</property>
<property name="stock">gtk-media-play</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="interface-start-atkobject">
<property name="AtkObject::accessible-name">interface-start</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -2022,6 +2052,11 @@ here</property>
<property name="stock">gtk-stop</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="interface-stop-atkobject">
<property name="AtkObject::accessible-name">interface-stop</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -2044,6 +2079,11 @@ here</property>
<property name="stock">gtk-delete</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="interface-delete-atkobject">
<property name="AtkObject::accessible-name">interface-delete</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -2121,9 +2161,4 @@ here</property>
<placeholder/>
</child>
</object>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-open</property>
</object>
</interface>

View File

@ -35,6 +35,11 @@
<property name="stock">gtk-add</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="pool-add-atkobject">
<property name="AtkObject::accessible-name">pool-add</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -56,6 +61,11 @@
<property name="stock">gtk-media-play</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="pool-start-atkobject">
<property name="AtkObject::accessible-name">pool-start</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -77,6 +87,11 @@
<property name="stock">gtk-stop</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="pool-stop-atkobject">
<property name="AtkObject::accessible-name">pool-stop</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -98,6 +113,11 @@
<property name="stock">gtk-delete</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="pool-delete-atkobject">
<property name="AtkObject::accessible-name">pool-delete</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -466,6 +486,11 @@
<property name="stock">gtk-add</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="vol-add-atkobject">
<property name="AtkObject::accessible-name">vol-new</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -488,6 +513,11 @@
<property name="stock">gtk-refresh</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="pool-refresh-atkobject">
<property name="AtkObject::accessible-name">vol-refresh</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -510,6 +540,11 @@
<property name="stock">gtk-delete</property>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="vol-delete-atkobject">
<property name="AtkObject::accessible-name">vol-delete</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
@ -547,6 +582,11 @@
<signal name="changed" handler="on_vol_list_changed" swapped="no"/>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="vol-list-atkobject">
<property name="AtkObject::accessible-name">vol-list</property>
</object>
</child>
</object>
</child>
</object>

View File

@ -127,7 +127,7 @@ class vmmErrorDialog(vmmGObject):
if self._simple:
self._simple.destroy()
self._simple = dialog
self._simple.get_accessible().set_name("vmm simple dialog")
self._simple.get_accessible().set_name("vmm dialog")
return _launch_dialog(self._simple,
text1, text2 or "", title or "",
@ -320,7 +320,7 @@ class _errorDialog (Gtk.MessageDialog):
if hasattr(child, "set_max_width_chars"):
child.set_max_width_chars(40)
self.get_accessible().set_name("vmm error dialog")
self.get_accessible().set_name("vmm dialog")
self.chk_vbox = None
self.chk_align = None