uitests: Add live console tests

Using transient VMs connecting to real qemu:///system. uitests are
already system invasive so I think this is okay
This commit is contained in:
Cole Robinson 2018-01-21 10:56:35 -05:00
parent 2fdf0c7ebe
commit d774d01e1c
8 changed files with 196 additions and 0 deletions

125
tests/uitests/console.py Normal file
View File

@ -0,0 +1,125 @@
import os
import libvirt
from tests.uitests import utils as uiutils
def _vm_wrapper(vmname, uri="qemu:///system"):
"""
Decorator to open a transient VM and clean it up
"""
def wrap1(fn):
def wrapper(self, *args, **kwargs):
dom = None
try:
xmlfile = "%s/xml/%s.xml" % (os.path.dirname(__file__), vmname)
conn = libvirt.open(uri)
dom = conn.createXML(open(xmlfile).read(), 0)
self.app.uri = uri
self.app.open(extra_opts=["--show-domain-console", vmname])
fn(self, *args, **kwargs)
finally:
self.app.stop()
if dom:
dom.destroy()
return wrapper
return wrap1
class Console(uiutils.UITestCase):
"""
Test live console connections with stub VMs
"""
##############
# Test cases #
##############
def _checkConsoleStandard(self):
"""
Shared logic for general console handling
"""
win = self.app.topwin
con = win.find("console-gfx-viewport")
self.assertTrue(con.showing)
win.find("Virtual Machine", "menu").click()
win.find("Take Screenshot", "menu item").click()
chooser = self.app.root.find(None, "file chooser")
fname = chooser.find("Name", "text").text
self.pressKey("Enter")
uiutils.check_in_loop(lambda: os.path.exists(fname))
os.unlink(fname)
self.assertTrue(lambda: win.active)
win.find("Send Key", "menu").click()
win.find("Ctrl\+Alt\+F1", "menu item").click()
win.find("Send Key", "menu").click()
win.find("Ctrl\+Alt\+F10", "menu item").click()
win.find("Send Key", "menu").click()
win.find("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
self.assertTrue(oldsize != newsize)
# Fullscreen testing
win.find("^View$", "menu").click()
win.find("Fullscreen", "check menu item").click()
fstb = win.find("Fullscreen Toolbar")
self.assertTrue(fstb.showing)
self.assertTrue(win.size != newsize)
# Wait for toolbar to hide, then reveal it again
uiutils.check_in_loop(lambda: not fstb.showing, timeout=5)
self.point(win.size[0] / 2, 0)
uiutils.check_in_loop(lambda: fstb.showing)
# Click stuff and exit fullscreen
win.find("Fullscreen Send Key").click()
self.pressKey("Escape")
win.find("Fullscreen Exit").click()
self.assertTrue(win.size == newsize)
@_vm_wrapper("uitests-vnc-standard")
def testConsoleVNCStandard(self):
return self._checkConsoleStandard()
@_vm_wrapper("uitests-spice-standard")
def testConsoleSpiceStandard(self):
return self._checkConsoleStandard()
def _checkPassword(self):
"""
Shared logic for password handling
"""
win = self.app.topwin
con = win.find("console-gfx-viewport")
self.assertTrue(not con.showing)
passwd = win.find("Password:", "password text")
uiutils.check_in_loop(lambda: passwd.showing)
# Check wrong password handling
passwd.typeText("xx")
win.find("Login", "push button").click()
alert = self.app.root.find("vmm dialog", "alert")
alert.find_fuzzy("Viewer authentication error", "label")
alert.find("OK", "push button").click()
# Check proper password
passwd.typeText("goodp")
win.find("Login", "push button").click()
uiutils.check_in_loop(lambda: con.showing)
@_vm_wrapper("uitests-vnc-password")
def testConsoleVNCPassword(self):
return self._checkPassword()
@_vm_wrapper("uitests-spice-password")
def testConsoleSpicePassword(self):
return self._checkPassword()

View File

@ -369,12 +369,14 @@ class VMMDogtailApp(object):
self._proc.send_signal(signal.SIGINT)
except Exception:
logging.debug("Error terminating process", exc_info=True)
self._proc = None
return
# Wait for shutdown for 1 second, with 20 checks
for ignore in range(20):
time.sleep(.05)
if self._proc.poll() is not None:
self._proc = None
return
logging.warning("App didn't exit gracefully from SIGINT. Killing...")
@ -382,3 +384,4 @@ class VMMDogtailApp(object):
self._proc.kill()
finally:
time.sleep(1)
self._proc = None

View File

@ -0,0 +1,15 @@
<domain type="kvm">
<name>uitests-spice-password</name>
<memory>65536</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch="x86_64">hvm</type>
<boot dev="hd"/>
</os>
<devices>
<emulator>/usr/bin/qemu-kvm</emulator>
<graphics type="spice" passwd="goodp"/>
</devices>
</domain>

View File

@ -0,0 +1,15 @@
<domain type="kvm">
<name>uitests-spice-standard</name>
<memory>65536</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch="x86_64">hvm</type>
<boot dev="hd"/>
</os>
<devices>
<emulator>/usr/bin/qemu-kvm</emulator>
<graphics type="spice"/>
</devices>
</domain>

View File

@ -0,0 +1,15 @@
<domain type="kvm">
<name>uitests-vnc-password</name>
<memory>65536</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch="x86_64">hvm</type>
<boot dev="hd"/>
</os>
<devices>
<emulator>/usr/bin/qemu-kvm</emulator>
<graphics type="vnc" port="-1" passwd="goodp"/>
</devices>
</domain>

View File

@ -0,0 +1,15 @@
<domain type="kvm">
<name>uitests-vnc-standard</name>
<memory>65536</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch="x86_64">hvm</type>
<boot dev="hd"/>
</os>
<devices>
<emulator>/usr/bin/qemu-kvm</emulator>
<graphics type="vnc"/>
</devices>
</domain>

View File

@ -6198,6 +6198,11 @@
<child>
<placeholder/>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="console-gfx-viewport-atkobject">
<property name="AtkObject::accessible-name">console-gfx-viewport</property>
</object>
</child>
</object>
</child>
</object>

View File

@ -232,11 +232,13 @@ class vmmConsolePages(vmmGObjectUI):
self._overlay_toolbar = Gtk.Toolbar()
self._overlay_toolbar.set_show_arrow(False)
self._overlay_toolbar.set_style(Gtk.ToolbarStyle.BOTH_HORIZ)
self._overlay_toolbar.get_accessible().set_name("Fullscreen Toolbar")
# Exit fullscreen button
button = Gtk.ToolButton.new_from_stock(Gtk.STOCK_LEAVE_FULLSCREEN)
button.set_tooltip_text(_("Leave fullscreen"))
button.show()
button.get_accessible().set_name("Fullscreen Exit")
self._overlay_toolbar.add(button)
button.connect("clicked", self._leave_fullscreen)
@ -265,6 +267,7 @@ class vmmConsolePages(vmmGObjectUI):
self._send_key_button.set_tooltip_text(_("Send key combination"))
self._send_key_button.show_all()
self._send_key_button.connect("clicked", keycombo_menu_clicked)
self._send_key_button.get_accessible().set_name("Fullscreen Send Key")
self._overlay_toolbar.add(self._send_key_button)
self._timed_revealer = _TimedRevealer(self._overlay_toolbar)