~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_test_server.py

  • Committer: Patch Queue Manager
  • Date: 2011-12-02 12:02:54 UTC
  • mfrom: (6015.42.8 test-server-races)
  • Revision ID: pqm@pqm.ubuntu.com-20111202120254-kccrfj6buuqt1iui
(vila) Properly synchronize connection thread start with test server main
 thread. (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
212
212
 
213
213
        class FailingDuringResponseHandler(TCPConnectionHandler):
214
214
 
 
215
            # We use 'request' instead of 'self' below because the test matters
 
216
            # more and we need a container to properly set connection_thread.
215
217
            def handle_connection(request):
216
218
                req = request.readline()
217
219
                # Capture the thread and make it use 'caught' so we can wait on
218
 
                # the even that will be set when the exception is caught. We
 
220
                # the event that will be set when the exception is caught. We
219
221
                # also capture the thread to know where to look.
220
222
                self.connection_thread = threading.currentThread()
221
223
                self.connection_thread.set_sync_event(caught)
232
234
        # Check that the connection thread did catch the exception,
233
235
        # http://pad.lv/869366 was wrongly checking the server thread which
234
236
        # works for TestingTCPServer where the connection is handled in the
235
 
        # same thread than the server one but is racy for
236
 
        # TestingThreadingTCPServer where the server thread may be in a
237
 
        # blocking accept() call (or not).
238
 
        try:
239
 
            self.connection_thread.pending_exception()
240
 
        except FailToRespond:
241
 
            # Great, the test succeeded
242
 
            pass
243
 
        else:
244
 
            # If the exception is not in the connection thread anymore, it's in
245
 
            # the server's one. 
246
 
            server.server.stopped.wait()
247
 
            # The exception is available now
248
 
            self.assertRaises(FailToRespond, server.pending_exception)
 
237
        # same thread than the server one but was racy for
 
238
        # TestingThreadingTCPServer. Since the connection thread detaches
 
239
        # itself before handling the request, we are guaranteed that the
 
240
        # exception won't leak into the server thread anymore.
 
241
        self.assertRaises(FailToRespond,
 
242
                          self.connection_thread.pending_exception)
249
243
 
250
244
    def test_exception_swallowed_while_serving(self):
251
245
        # We need to ensure the exception has been caught
260
254
 
261
255
        class FailingWhileServingConnectionHandler(TCPConnectionHandler):
262
256
 
 
257
            # We use 'request' instead of 'self' below because the test matters
 
258
            # more and we need a container to properly set connection_thread.
263
259
            def handle(request):
264
260
                # Capture the thread and make it use 'caught' so we can wait on
265
 
                # the even that will be set when the exception is caught. We
 
261
                # the event that will be set when the exception is caught. We
266
262
                # also capture the thread to know where to look.
267
263
                self.connection_thread = threading.currentThread()
268
264
                self.connection_thread.set_sync_event(caught)
270
266
 
271
267
        server = self.get_server(
272
268
            connection_handler_class=FailingWhileServingConnectionHandler)
 
269
        self.assertEquals(True, server.server.serving)
273
270
        # Install the exception swallower
274
271
        server.set_ignored_exceptions(CantServe)
275
272
        client = self.get_client()
284
281
        # here). More precisely, the exception *has* been caught and captured
285
282
        # but it is cleared when joining the thread (or trying to acquire the
286
283
        # exception) and as such won't propagate to the server thread.
287
 
        self.connection_thread.pending_exception()
288
 
        server.pending_exception()
 
284
        self.assertIs(None, self.connection_thread.pending_exception())
 
285
        self.assertIs(None, server.pending_exception())
289
286
 
290
287
    def test_handle_request_closes_if_it_doesnt_process(self):
291
288
        server = self.get_server()