[repo test] Avoid hangs in zmq repo unit test
authorJulien Cristau <julien.cristau@logilab.fr>
Wed, 09 May 2012 15:06:43 +0200
changeset 8388 c6c624cea870
parent 8387 b59af20a868d
child 8389 94f26e3b09bf
[repo test] Avoid hangs in zmq repo unit test - interaction through the zmq event loop from a different thread is only allowed through add_callback - notify the background thread when the client dies with an exception so it doesn't spin forever
server/cwzmq.py
server/test/unittest_repository.py
--- a/server/cwzmq.py	Thu May 03 15:52:01 2012 +0200
+++ b/server/cwzmq.py	Wed May 09 15:06:43 2012 +0200
@@ -117,7 +117,7 @@
         self.repo = repository
         self.socket = None
         self.stream = None
-        self.loop = None
+        self.loop = ioloop.IOLoop()
 
         # event queue
         self.events = []
@@ -129,7 +129,6 @@
         """enter the service loop"""
         # start repository looping tasks
         self.socket = ctx.socket(zmq.REP)
-        self.loop = ioloop.IOLoop()
         self.stream = zmq.eventloop.zmqstream.ZMQStream(self.socket, io_loop=self.loop)
         self.stream.bind(self.address)
         self.info('ZMQ server bound on: %s', self.address)
@@ -209,7 +208,7 @@
         """stop the server"""
         self.info('Quitting ZMQ server')
         try:
-            self.loop.stop()
+            self.loop.add_callback(self.loop.stop)
             self.stream.on_recv(None)
             self.stream.close()
         except Exception, e:
--- a/server/test/unittest_repository.py	Thu May 03 15:52:01 2012 +0200
+++ b/server/test/unittest_repository.py	Wed May 09 15:06:43 2012 +0200
@@ -413,28 +413,31 @@
 
     def _zmq_client(self, done):
         cnxprops = ConnectionProperties('zmq')
-        cnx = connect(self.repo.config.appid, u'admin', password=u'gingkow',
-                      host='tcp://127.0.0.1:41415',
-                      cnxprops=cnxprops,
-                      initlog=False) # don't reset logging configuration
         try:
-            cnx.load_appobjects(subpath=('entities',))
-            # check we can get the schema
-            schema = cnx.get_schema()
-            self.assertTrue(cnx.vreg)
-            self.assertTrue('etypes'in cnx.vreg)
-            cu = cnx.cursor()
-            rset = cu.execute('Any U,G WHERE U in_group G')
-            user = iter(rset.entities()).next()
-            self.assertTrue(user._cw)
-            self.assertTrue(user._cw.vreg)
-            from cubicweb.entities import authobjs
-            self.assertIsInstance(user._cw.user, authobjs.CWUser)
-            cnx.close()
-            done.append(True)
+            cnx = connect(self.repo.config.appid, u'admin', password=u'gingkow',
+                          host='tcp://127.0.0.1:41415',
+                          cnxprops=cnxprops,
+                          initlog=False) # don't reset logging configuration
+            try:
+                cnx.load_appobjects(subpath=('entities',))
+                # check we can get the schema
+                schema = cnx.get_schema()
+                self.assertTrue(cnx.vreg)
+                self.assertTrue('etypes'in cnx.vreg)
+                cu = cnx.cursor()
+                rset = cu.execute('Any U,G WHERE U in_group G')
+                user = iter(rset.entities()).next()
+                self.assertTrue(user._cw)
+                self.assertTrue(user._cw.vreg)
+                from cubicweb.entities import authobjs
+                self.assertIsInstance(user._cw.user, authobjs.CWUser)
+                cnx.close()
+                done.append(True)
+            finally:
+                # connect monkey patch some method by default, remove them
+                multiple_connections_unfix()
         finally:
-            # connect monkey patch some method by default, remove them
-            multiple_connections_unfix()
+            done.append(False)
 
     def test_internal_api(self):
         repo = self.repo