[pygobject] tests: Reduce usage of timeout_add() and sleep()



commit f47027d6abde392fff03ce9b49e42a0c6f7d83cd
Author: Christoph Reiter <creiter src gnome org>
Date:   Tue Mar 21 12:48:27 2017 +0100

    tests: Reduce usage of timeout_add() and sleep()
    
    * Instead of waiting for a fixed time, use a timeout and stop the main
      loop right after the test has succeeded.
    * Replace time.sleep to sync processes with os.pipe communication
    * Chain idle sources instead of using multiple timeout sources
    * Replace sleeps with unbufferd communication
    
    https://bugzilla.gnome.org/show_bug.cgi?id=698548

 tests/test_glib.py          |   37 ++++++++++++------
 tests/test_iochannel.py     |   86 +++++++++++++++++++++++++++++++-----------
 tests/test_mainloop.py      |   13 +++++-
 tests/test_overrides_gtk.py |    4 +-
 tests/test_source.py        |   10 ++--
 tests/test_thread.py        |    6 ++-
 6 files changed, 111 insertions(+), 45 deletions(-)
---
diff --git a/tests/test_glib.py b/tests/test_glib.py
index ec0f87f..75d9e6a 100644
--- a/tests/test_glib.py
+++ b/tests/test_glib.py
@@ -134,18 +134,24 @@ https://my.org/q?x=1&y=2
 
         def cb(fd, condition):
             call_data.append((fd, condition, os.read(fd, 1)))
+            if len(call_data) == 2:
+                ml.quit()
             return True
 
         # io_add_watch() takes an IOChannel, calling with an fd is deprecated
         with warnings.catch_warnings(record=True) as warn:
             warnings.simplefilter('always')
-            GLib.io_add_watch(r, GLib.IOCondition.IN, cb)
+            GLib.io_add_watch(r, GLib.IOCondition.IN, cb,
+                              priority=GLib.PRIORITY_HIGH)
             self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
 
+        def write():
+            os.write(w, b'a')
+            GLib.idle_add(lambda: os.write(w, b'b') and False)
+
         ml = GLib.MainLoop()
-        GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
-        GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
-        GLib.timeout_add(200, ml.quit)
+        GLib.idle_add(write)
+        GLib.timeout_add(2000, ml.quit)
         ml.run()
 
         self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a'),
@@ -158,18 +164,24 @@ https://my.org/q?x=1&y=2
 
         def cb(fd, condition, data):
             call_data.append((fd, condition, os.read(fd, 1), data))
+            if len(call_data) == 2:
+                ml.quit()
             return True
 
         # io_add_watch() takes an IOChannel, calling with an fd is deprecated
         with warnings.catch_warnings(record=True) as warn:
             warnings.simplefilter('always')
-            GLib.io_add_watch(r, GLib.IOCondition.IN, cb, 'moo')
+            GLib.io_add_watch(r, GLib.IOCondition.IN, cb, 'moo',
+                              priority=GLib.PRIORITY_HIGH)
             self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
 
+        def write():
+            os.write(w, b'a')
+            GLib.idle_add(lambda: os.write(w, b'b') and False)
+
         ml = GLib.MainLoop()
-        GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
-        GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
-        GLib.timeout_add(200, ml.quit)
+        GLib.idle_add(write)
+        GLib.timeout_add(2000, ml.quit)
         ml.run()
 
         self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a', 'moo'),
@@ -182,6 +194,7 @@ https://my.org/q?x=1&y=2
 
         def cb(fd, condition, *user_data):
             call_data.append((fd, condition, os.read(fd, 1), user_data))
+            ml.quit()
             return True
 
         # io_add_watch() takes an IOChannel, calling with an fd is deprecated
@@ -191,8 +204,8 @@ https://my.org/q?x=1&y=2
             self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
 
         ml = GLib.MainLoop()
-        GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
-        GLib.timeout_add(100, ml.quit)
+        GLib.idle_add(lambda: os.write(w, b'a') and False)
+        GLib.timeout_add(2000, ml.quit)
         ml.run()
 
         self.assertEqual(call_data, [(r, GLib.IOCondition.IN, b'a', ('moo', 'foo'))])
@@ -201,8 +214,8 @@ https://my.org/q?x=1&y=2
     def test_io_add_watch_pyfile(self):
         call_data = []
 
-        cmd = subprocess.Popen('sleep 0.1; echo hello; sleep 0.2; echo world',
-                               shell=True, stdout=subprocess.PIPE)
+        cmd = subprocess.Popen('echo hello; echo world',
+                               shell=True, bufsize=0, stdout=subprocess.PIPE)
 
         def cb(file, condition):
             call_data.append((file, condition, file.readline()))
diff --git a/tests/test_iochannel.py b/tests/test_iochannel.py
index bba01e3..241b9e2 100644
--- a/tests/test_iochannel.py
+++ b/tests/test_iochannel.py
@@ -225,19 +225,23 @@ second line
             self.assertEqual(channel, ch)
             self.assertEqual(condition, GLib.IOCondition.IN)
             cb_reads.append(channel.read())
+            if len(cb_reads) == 2:
+                ml.quit()
             return True
 
         # io_add_watch() method is deprecated, use GLib.io_add_watch
         with warnings.catch_warnings(record=True) as warn:
             warnings.simplefilter('always')
-            ch.add_watch(GLib.IOCondition.IN, cb)
+            ch.add_watch(GLib.IOCondition.IN, cb, priority=GLib.PRIORITY_HIGH)
             self.assertTrue(issubclass(warn[0].category, PyGIDeprecationWarning))
 
-        ml = GLib.MainLoop()
+        def write():
+            os.write(w, b'a')
+            GLib.idle_add(lambda: os.write(w, b'b') and False)
 
-        GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
-        GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
-        GLib.timeout_add(200, ml.quit)
+        ml = GLib.MainLoop()
+        GLib.idle_add(write)
+        GLib.timeout_add(2000, ml.quit)
         ml.run()
 
         self.assertEqual(cb_reads, [b'a', b'b'])
@@ -257,6 +261,8 @@ second line
             self.assertEqual(condition, GLib.IOCondition.IN)
             self.assertEqual(data, 'hello')
             cb_reads.append(channel.read())
+            if len(cb_reads) == 2:
+                ml.quit()
             return True
 
         ml = GLib.MainLoop()
@@ -269,9 +275,12 @@ second line
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_HIGH)
 
-        GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
-        GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
-        GLib.timeout_add(200, ml.quit)
+        def write():
+            os.write(w, b'a')
+            GLib.idle_add(lambda: os.write(w, b'b') and False)
+
+        GLib.idle_add(write)
+        GLib.timeout_add(2000, ml.quit)
         ml.run()
 
         self.assertEqual(cb_reads, [b'a', b'b'])
@@ -290,6 +299,8 @@ second line
             self.assertEqual(channel, ch)
             self.assertEqual(condition, GLib.IOCondition.IN)
             cb_reads.append(channel.read())
+            if len(cb_reads) == 2:
+                ml.quit()
             return True
 
         id = GLib.io_add_watch(ch, GLib.PRIORITY_HIGH, GLib.IOCondition.IN, cb)
@@ -297,9 +308,13 @@ second line
         ml = GLib.MainLoop()
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_HIGH)
-        GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
-        GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
-        GLib.timeout_add(200, ml.quit)
+
+        def write():
+            os.write(w, b'a')
+            GLib.idle_add(lambda: os.write(w, b'b') and False)
+
+        GLib.idle_add(write)
+        GLib.timeout_add(2000, ml.quit)
         ml.run()
 
         self.assertEqual(cb_reads, [b'a', b'b'])
@@ -319,6 +334,8 @@ second line
             self.assertEqual(condition, GLib.IOCondition.IN)
             self.assertEqual(data, 'hello')
             cb_reads.append(channel.read())
+            if len(cb_reads) == 2:
+                ml.quit()
             return True
 
         id = GLib.io_add_watch(ch, GLib.PRIORITY_HIGH, GLib.IOCondition.IN, cb, 'hello')
@@ -326,9 +343,13 @@ second line
         ml = GLib.MainLoop()
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_HIGH)
-        GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
-        GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
-        GLib.timeout_add(200, ml.quit)
+
+        def write():
+            os.write(w, b'a')
+            GLib.idle_add(lambda: os.write(w, b'b') and False)
+
+        GLib.idle_add(write)
+        GLib.timeout_add(2000, ml.quit)
         ml.run()
 
         self.assertEqual(cb_reads, [b'a', b'b'])
@@ -350,6 +371,8 @@ second line
             self.assertEqual(data2, 'b')
             self.assertEqual(data3, 'c')
             cb_reads.append(channel.read())
+            if len(cb_reads) == 2:
+                ml.quit()
             return True
 
         id = GLib.io_add_watch(ch, GLib.PRIORITY_HIGH, GLib.IOCondition.IN, cb,
@@ -358,9 +381,13 @@ second line
         ml = GLib.MainLoop()
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_HIGH)
-        GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
-        GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
-        GLib.timeout_add(200, ml.quit)
+
+        def write():
+            os.write(w, b'a')
+            GLib.idle_add(lambda: os.write(w, b'b') and False)
+
+        GLib.idle_add(write)
+        GLib.timeout_add(2000, ml.quit)
         ml.run()
 
         self.assertEqual(cb_reads, [b'a', b'b'])
@@ -379,6 +406,8 @@ second line
             self.assertEqual(channel, ch)
             self.assertEqual(condition, GLib.IOCondition.IN)
             cb_reads.append(channel.read())
+            if len(cb_reads) == 2:
+                ml.quit()
             return True
 
         with warnings.catch_warnings(record=True) as warn:
@@ -389,9 +418,13 @@ second line
         ml = GLib.MainLoop()
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_HIGH)
-        GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
-        GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
-        GLib.timeout_add(200, ml.quit)
+
+        def write():
+            os.write(w, b'a')
+            GLib.idle_add(lambda: os.write(w, b'b') and False)
+
+        GLib.idle_add(write)
+        GLib.timeout_add(2000, ml.quit)
         ml.run()
 
         self.assertEqual(cb_reads, [b'a', b'b'])
@@ -411,6 +444,8 @@ second line
             self.assertEqual(condition, GLib.IOCondition.IN)
             self.assertEqual(data, 'hello')
             cb_reads.append(channel.read())
+            if len(cb_reads) == 2:
+                ml.quit()
             return True
 
         with warnings.catch_warnings(record=True) as warn:
@@ -422,9 +457,14 @@ second line
         ml = GLib.MainLoop()
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_HIGH)
-        GLib.timeout_add(10, lambda: os.write(w, b'a') and False)
-        GLib.timeout_add(100, lambda: os.write(w, b'b') and False)
-        GLib.timeout_add(200, ml.quit)
+
+        def write():
+            os.write(w, b'a')
+            GLib.idle_add(lambda: os.write(w, b'b') and False)
+
+        GLib.idle_add(write)
+
+        GLib.timeout_add(2000, ml.quit)
         ml.run()
 
         self.assertEqual(cb_reads, [b'a', b'b'])
diff --git a/tests/test_mainloop.py b/tests/test_mainloop.py
index 5a90387..ae3919e 100644
--- a/tests/test_mainloop.py
+++ b/tests/test_mainloop.py
@@ -4,7 +4,6 @@ import os
 import sys
 import select
 import signal
-import time
 import unittest
 
 from gi.repository import GLib
@@ -58,12 +57,22 @@ class TestMainLoop(unittest.TestCase):
 
     @unittest.skipUnless(hasattr(os, "fork"), "no os.fork available")
     def test_sigint(self):
+        r, w = os.pipe()
         pid = os.fork()
         if pid == 0:
-            time.sleep(0.5)
+            # wait for the parent process loop to start
+            os.read(r, 1)
+            os.close(r)
+
             os.kill(os.getppid(), signal.SIGINT)
             os._exit(0)
 
+        def notify_child():
+            # tell the child that it can kill the parent
+            os.write(w, b"X")
+            os.close(w)
+
+        GLib.idle_add(notify_child)
         loop = GLib.MainLoop()
         try:
             loop.run()
diff --git a/tests/test_overrides_gtk.py b/tests/test_overrides_gtk.py
index ec6d045..86cfda4 100644
--- a/tests/test_overrides_gtk.py
+++ b/tests/test_overrides_gtk.py
@@ -622,11 +622,11 @@ class TestGtk(unittest.TestCase):
 
     def test_gtk_main(self):
         # with no arguments
-        GLib.timeout_add(100, Gtk.main_quit)
+        GLib.idle_add(Gtk.main_quit)
         Gtk.main()
 
         # overridden function ignores its arguments
-        GLib.timeout_add(100, Gtk.main_quit, 'hello')
+        GLib.idle_add(Gtk.main_quit, 'hello')
         Gtk.main()
 
     def test_widget_render_icon(self):
diff --git a/tests/test_source.py b/tests/test_source.py
index 4845157..866826e 100644
--- a/tests/test_source.py
+++ b/tests/test_source.py
@@ -300,7 +300,7 @@ class TestUserData(unittest.TestCase):
 
         def cb():
             ml.quit()
-        id = GLib.timeout_add(50, cb)
+        id = GLib.timeout_add(1, cb)
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_DEFAULT)
         ml.run()
@@ -340,7 +340,7 @@ class TestUserData(unittest.TestCase):
             data['called'] = True
             ml.quit()
         data = {}
-        id = GLib.timeout_add(50, cb, data)
+        id = GLib.timeout_add(1, cb, data)
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_DEFAULT)
         ml.run()
@@ -354,7 +354,7 @@ class TestUserData(unittest.TestCase):
             data['data2'] = data2
             ml.quit()
         data = {}
-        id = GLib.timeout_add(50, cb, data, 'hello')
+        id = GLib.timeout_add(1, cb, data, 'hello')
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_DEFAULT)
         ml.run()
@@ -376,7 +376,7 @@ class TestUserData(unittest.TestCase):
 
         def cb():
             ml.quit()
-        id = GLib.timeout_add(50, cb, priority=GLib.PRIORITY_HIGH)
+        id = GLib.timeout_add(1, cb, priority=GLib.PRIORITY_HIGH)
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_HIGH)
         ml.run()
@@ -401,7 +401,7 @@ class TestUserData(unittest.TestCase):
             data['called'] = True
             ml.quit()
         data = {}
-        id = GLib.timeout_add(50, cb, data, priority=GLib.PRIORITY_HIGH)
+        id = GLib.timeout_add(1, cb, data, priority=GLib.PRIORITY_HIGH)
         self.assertEqual(ml.get_context().find_source_by_id(id).priority,
                          GLib.PRIORITY_HIGH)
         ml.run()
diff --git a/tests/test_thread.py b/tests/test_thread.py
index 3d0557e..3da3310 100644
--- a/tests/test_thread.py
+++ b/tests/test_thread.py
@@ -9,11 +9,14 @@ from gi.repository import GLib
 class TestThread(unittest.TestCase):
     def setUp(self):
         self.main = GLib.MainLoop()
+        self.called = False
 
     def from_thread_cb(self, test, enum):
         assert test == self.obj
         assert int(enum) == 0
         assert type(enum) != int
+        self.called = True
+        GLib.idle_add(self.timeout_cb)
 
     def idle_cb(self):
         self.obj = testhelper.get_test_thread()
@@ -22,8 +25,9 @@ class TestThread(unittest.TestCase):
 
     def test_extension_module(self):
         GLib.idle_add(self.idle_cb)
-        GLib.timeout_add(50, self.timeout_cb)
+        GLib.timeout_add(2000, self.timeout_cb)
         self.main.run()
+        self.assertTrue(self.called)
 
     def timeout_cb(self):
         self.main.quit()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]