gio/tests/memory-monitor-*.py.in: skip if 3rd party modules not available

The GIO tests memory-monitor-dbus and memory-monitor-portal use a number
of third party Python modules that may not be present when running the
test case.

Instead of failing due to missing imports, catch the ImportError and
mock a test case that skips.  This can't use the usual unittest.skip
logic because the test case class itself uses a 3rd party module.

Closes #2083.
This commit is contained in:
Ross Burton 2020-04-09 15:28:12 +01:00
parent de8708cd95
commit 2709d5e1bb
2 changed files with 162 additions and 146 deletions

View File

@ -14,90 +14,98 @@ __license__ = 'LGPL 3+'
import unittest import unittest
import sys import sys
import subprocess import subprocess
import dbus
import dbus.mainloop.glib
import dbusmock
import fcntl import fcntl
import os import os
import time import time
import taptestrunner import taptestrunner
from gi.repository import GLib try:
from gi.repository import Gio # Do all non-standard imports here so we can skip the tests if any
# needed packages are not available.
import dbus
import dbus.mainloop.glib
import dbusmock
from gi.repository import GLib
from gi.repository import Gio
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
# XDG_DESKTOP_PORTAL_PATH = os.path.expanduser("~/.cache/jhbuild/build/xdg-desktop-portal/xdg-desktop-portal") # XDG_DESKTOP_PORTAL_PATH = os.path.expanduser("~/.cache/jhbuild/build/xdg-desktop-portal/xdg-desktop-portal")
XDG_DESKTOP_PORTAL_PATH = "@libexecdir@/xdg-desktop-portal" XDG_DESKTOP_PORTAL_PATH = "@libexecdir@/xdg-desktop-portal"
class TestLowMemoryMonitor(dbusmock.DBusTestCase): class TestLowMemoryMonitor(dbusmock.DBusTestCase):
'''Test GMemoryMonitorDBus''' '''Test GMemoryMonitorDBus'''
@classmethod @classmethod
def setUpClass(klass): def setUpClass(klass):
klass.start_system_bus() klass.start_system_bus()
klass.dbus_con = klass.get_dbus(True) klass.dbus_con = klass.get_dbus(True)
def setUp(self): def setUp(self):
try: try:
Gio.MemoryMonitor Gio.MemoryMonitor
except AttributeError: except AttributeError:
raise unittest.SkipTest('Low memory monitor not in ' raise unittest.SkipTest('Low memory monitor not in '
'introspection data. Requires ' 'introspection data. Requires '
'GObject-Introspection ≥ 1.63.2') 'GObject-Introspection ≥ 1.63.2')
try: try:
(self.p_mock, self.obj_lmm) = self.spawn_server_template( (self.p_mock, self.obj_lmm) = self.spawn_server_template(
'low_memory_monitor', {}, stdout=subprocess.PIPE) 'low_memory_monitor', {}, stdout=subprocess.PIPE)
except ModuleNotFoundError: except ModuleNotFoundError:
raise unittest.SkipTest("Low memory monitor dbusmock template not " raise unittest.SkipTest("Low memory monitor dbusmock template not "
"found. Requires dbusmock ≥ 0.18.4.") "found. Requires dbusmock ≥ 0.18.4.")
# set log to nonblocking # set log to nonblocking
flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL)
fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK)
self.last_warning = -1 self.last_warning = -1
self.dbusmock = dbus.Interface(self.obj_lmm, dbusmock.MOCK_IFACE) self.dbusmock = dbus.Interface(self.obj_lmm, dbusmock.MOCK_IFACE)
self.memory_monitor = Gio.MemoryMonitor.dup_default() self.memory_monitor = Gio.MemoryMonitor.dup_default()
self.memory_monitor.connect("low-memory-warning", self.memory_warning_cb) self.memory_monitor.connect("low-memory-warning", self.memory_warning_cb)
self.mainloop = GLib.MainLoop() self.mainloop = GLib.MainLoop()
self.main_context = self.mainloop.get_context() self.main_context = self.mainloop.get_context()
def tearDown(self): def tearDown(self):
self.p_mock.terminate() self.p_mock.terminate()
self.p_mock.wait() self.p_mock.wait()
def memory_warning_cb(self, monitor, level): def memory_warning_cb(self, monitor, level):
self.last_warning = level self.last_warning = level
self.main_context.wakeup() self.main_context.wakeup()
def test_low_memory_warning_signal(self): def test_low_memory_warning_signal(self):
'''LowMemoryWarning signal''' '''LowMemoryWarning signal'''
# Wait 2 seconds # Wait 2 seconds
timeout = 2 timeout = 2
while timeout > 0: while timeout > 0:
time.sleep(0.5) time.sleep(0.5)
timeout -= 0.5 timeout -= 0.5
self.main_context.iteration(False) self.main_context.iteration(False)
self.dbusmock.EmitWarning(100) self.dbusmock.EmitWarning(100)
# Wait 2 seconds or until warning # Wait 2 seconds or until warning
timeout = 2 timeout = 2
while timeout > 0 and self.last_warning != 100: while timeout > 0 and self.last_warning != 100:
time.sleep(0.5) time.sleep(0.5)
timeout -= 0.5 timeout -= 0.5
self.main_context.iteration(False) self.main_context.iteration(False)
self.assertEqual(self.last_warning, 100) self.assertEqual(self.last_warning, 100)
self.dbusmock.EmitWarning(255) self.dbusmock.EmitWarning(255)
# Wait 2 seconds or until warning # Wait 2 seconds or until warning
timeout = 2 timeout = 2
while timeout > 0 and self.last_warning != 255: while timeout > 0 and self.last_warning != 255:
time.sleep(0.5) time.sleep(0.5)
timeout -= 0.5 timeout -= 0.5
self.main_context.iteration(False) self.main_context.iteration(False)
self.assertEqual(self.last_warning, 255) self.assertEqual(self.last_warning, 255)
except ImportError as e:
@unittest.skip("Cannot import %s" % e.name)
class TestLowMemoryMonitor(unittest.TestCase):
def test_low_memory_warning_signal(self):
pass
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(testRunner=taptestrunner.TAPTestRunner()) unittest.main(testRunner=taptestrunner.TAPTestRunner())

View File

@ -14,106 +14,114 @@ __license__ = 'LGPL 3+'
import unittest import unittest
import sys import sys
import subprocess import subprocess
import dbus
import dbus.mainloop.glib
import dbusmock
import fcntl import fcntl
import os import os
import time import time
import taptestrunner import taptestrunner
from gi.repository import GLib try:
from gi.repository import Gio # Do all non-standard imports here so we can skip the tests if any
# needed packages are not available.
import dbus
import dbus.mainloop.glib
import dbusmock
from gi.repository import GLib
from gi.repository import Gio
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
# XDG_DESKTOP_PORTAL_PATH = os.path.expanduser("~/.cache/jhbuild/build/xdg-desktop-portal/xdg-desktop-portal") # XDG_DESKTOP_PORTAL_PATH = os.path.expanduser("~/.cache/jhbuild/build/xdg-desktop-portal/xdg-desktop-portal")
XDG_DESKTOP_PORTAL_PATH = "@libexecdir@/xdg-desktop-portal" XDG_DESKTOP_PORTAL_PATH = "@libexecdir@/xdg-desktop-portal"
class TestLowMemoryMonitorPortal(dbusmock.DBusTestCase): class TestLowMemoryMonitorPortal(dbusmock.DBusTestCase):
'''Test GMemoryMonitorPortal''' '''Test GMemoryMonitorPortal'''
@classmethod @classmethod
def setUpClass(klass): def setUpClass(klass):
klass.start_system_bus() klass.start_system_bus()
klass.dbus_con = klass.get_dbus(True) klass.dbus_con = klass.get_dbus(True)
# Start session bus so that xdg-desktop-portal can run on it # Start session bus so that xdg-desktop-portal can run on it
klass.start_session_bus() klass.start_session_bus()
def setUp(self): def setUp(self):
try: try:
Gio.MemoryMonitor Gio.MemoryMonitor
except AttributeError: except AttributeError:
raise unittest.SkipTest('Low memory monitor not in ' raise unittest.SkipTest('Low memory monitor not in '
'introspection data. Requires ' 'introspection data. Requires '
'GObject-Introspection ≥ 1.63.2') 'GObject-Introspection ≥ 1.63.2')
try: try:
(self.p_mock, self.obj_lmm) = self.spawn_server_template( (self.p_mock, self.obj_lmm) = self.spawn_server_template(
'low_memory_monitor', {}, stdout=subprocess.PIPE) 'low_memory_monitor', {}, stdout=subprocess.PIPE)
except ModuleNotFoundError: except ModuleNotFoundError:
raise unittest.SkipTest("Low memory monitor dbusmock template not " raise unittest.SkipTest("Low memory monitor dbusmock template not "
"found. Requires dbusmock ≥ 0.18.4.") "found. Requires dbusmock ≥ 0.18.4.")
# set log to nonblocking # set log to nonblocking
flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL) flags = fcntl.fcntl(self.p_mock.stdout, fcntl.F_GETFL)
fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) fcntl.fcntl(self.p_mock.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK)
self.last_warning = -1 self.last_warning = -1
self.dbusmock = dbus.Interface(self.obj_lmm, dbusmock.MOCK_IFACE) self.dbusmock = dbus.Interface(self.obj_lmm, dbusmock.MOCK_IFACE)
try: try:
self.xdp = subprocess.Popen([XDG_DESKTOP_PORTAL_PATH]) self.xdp = subprocess.Popen([XDG_DESKTOP_PORTAL_PATH])
except FileNotFoundError: except FileNotFoundError:
raise unittest.SkipTest("xdg-desktop-portal not available") raise unittest.SkipTest("xdg-desktop-portal not available")
try: try:
self.wait_for_bus_object('org.freedesktop.portal.Desktop', self.wait_for_bus_object('org.freedesktop.portal.Desktop',
'/org/freedesktop/portal/desktop') '/org/freedesktop/portal/desktop')
except: except:
raise raise
# subprocess.Popen(['gdbus', 'monitor', '--session', '--dest', 'org.freedesktop.portal.Desktop']) # subprocess.Popen(['gdbus', 'monitor', '--session', '--dest', 'org.freedesktop.portal.Desktop'])
os.environ['GTK_USE_PORTAL'] = "1" os.environ['GTK_USE_PORTAL'] = "1"
self.memory_monitor = Gio.MemoryMonitor.dup_default() self.memory_monitor = Gio.MemoryMonitor.dup_default()
assert("GMemoryMonitorPortal" in str(self.memory_monitor)) assert("GMemoryMonitorPortal" in str(self.memory_monitor))
self.memory_monitor.connect("low-memory-warning", self.portal_memory_warning_cb) self.memory_monitor.connect("low-memory-warning", self.portal_memory_warning_cb)
self.mainloop = GLib.MainLoop() self.mainloop = GLib.MainLoop()
self.main_context = self.mainloop.get_context() self.main_context = self.mainloop.get_context()
def tearDown(self): def tearDown(self):
self.p_mock.terminate() self.p_mock.terminate()
self.p_mock.wait() self.p_mock.wait()
def portal_memory_warning_cb(self, monitor, level): def portal_memory_warning_cb(self, monitor, level):
self.last_warning = level self.last_warning = level
self.main_context.wakeup() self.main_context.wakeup()
def test_low_memory_warning_portal_signal(self): def test_low_memory_warning_portal_signal(self):
'''LowMemoryWarning signal''' '''LowMemoryWarning signal'''
# Wait 2 seconds # Wait 2 seconds
timeout = 2 timeout = 2
while timeout > 0: while timeout > 0:
time.sleep(0.5) time.sleep(0.5)
timeout -= 0.5 timeout -= 0.5
self.main_context.iteration(False) self.main_context.iteration(False)
self.dbusmock.EmitWarning(100) self.dbusmock.EmitWarning(100)
# Wait 2 seconds or until warning # Wait 2 seconds or until warning
timeout = 2 timeout = 2
while timeout > 0 and self.last_warning != 100: while timeout > 0 and self.last_warning != 100:
time.sleep(0.5) time.sleep(0.5)
timeout -= 0.5 timeout -= 0.5
self.main_context.iteration(False) self.main_context.iteration(False)
self.assertEqual(self.last_warning, 100) self.assertEqual(self.last_warning, 100)
self.dbusmock.EmitWarning(255) self.dbusmock.EmitWarning(255)
# Wait 2 seconds or until warning # Wait 2 seconds or until warning
timeout = 2 timeout = 2
while timeout > 0 and self.last_warning != 255: while timeout > 0 and self.last_warning != 255:
time.sleep(0.5) time.sleep(0.5)
timeout -= 0.5 timeout -= 0.5
self.main_context.iteration(False) self.main_context.iteration(False)
self.assertEqual(self.last_warning, 255) self.assertEqual(self.last_warning, 255)
except ImportError as e:
@unittest.skip("Cannot import %s" % e.name)
class TestLowMemoryMonitorPortal(unittest.TestCase):
def test_low_memory_warning_portal_signal(self):
pass
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(testRunner=taptestrunner.TAPTestRunner()) unittest.main(testRunner=taptestrunner.TAPTestRunner())