Browse Source

AppCase now makes sure tests do not redirect stdouts

Ask Solem 11 years ago
parent
commit
9d49fe4ba0
2 changed files with 33 additions and 14 deletions
  1. 13 13
      celery/tests/bin/test_beat.py
  2. 20 1
      celery/tests/case.py

+ 13 - 13
celery/tests/bin/test_beat.py

@@ -38,7 +38,6 @@ class MockService(beat.Service):
 
 class MockBeat(beatapp.Beat):
     running = False
-    redirect_stdouts = False
 
     def run(self):
         MockBeat.running = True
@@ -46,7 +45,6 @@ class MockBeat(beatapp.Beat):
 
 class MockBeat2(beatapp.Beat):
     Service = MockService
-    redirect_stdouts = False
 
     def install_sync_handler(self, b):
         pass
@@ -54,7 +52,6 @@ class MockBeat2(beatapp.Beat):
 
 class MockBeat3(beatapp.Beat):
     Service = MockService
-    redirect_stdouts = False
 
     def install_sync_handler(self, b):
         raise TypeError('xxx')
@@ -63,29 +60,32 @@ class MockBeat3(beatapp.Beat):
 class test_Beat(AppCase):
 
     def test_loglevel_string(self):
-        b = beatapp.Beat(app=self.app, loglevel='DEBUG')
+        b = beatapp.Beat(app=self.app, loglevel='DEBUG',
+                         redirect_stdouts=False)
         self.assertEqual(b.loglevel, logging.DEBUG)
 
-        b2 = beatapp.Beat(app=self.app, loglevel=logging.DEBUG)
+        b2 = beatapp.Beat(app=self.app, loglevel=logging.DEBUG,
+                          redirect_stdouts=False)
         self.assertEqual(b2.loglevel, logging.DEBUG)
 
     def test_colorize(self):
         self.app.log.setup = Mock()
-        b = beatapp.Beat(app=self.app, no_color=True)
+        b = beatapp.Beat(app=self.app, no_color=True,
+                         redirect_stdouts=False)
         b.setup_logging()
         self.assertTrue(self.app.log.setup.called)
         self.assertEqual(self.app.log.setup.call_args[1]['colorize'], False)
 
     def test_init_loader(self):
-        b = beatapp.Beat(app=self.app)
+        b = beatapp.Beat(app=self.app, redirect_stdouts=False)
         b.init_loader()
 
     def test_process_title(self):
-        b = beatapp.Beat(app=self.app)
+        b = beatapp.Beat(app=self.app, redirect_stdouts=False)
         b.set_process_title()
 
     def test_run(self):
-        b = MockBeat2(app=self.app)
+        b = MockBeat2(app=self.app, redirect_stdouts=False)
         MockService.started = False
         b.run()
         self.assertTrue(MockService.started)
@@ -106,7 +106,7 @@ class test_Beat(AppCase):
             platforms.signals = p
 
     def test_install_sync_handler(self):
-        b = beatapp.Beat(app=self.app)
+        b = beatapp.Beat(app=self.app, redirect_stdouts=False)
         clock = MockService(app=self.app)
         MockService.in_sync = False
         handlers = self.psig(b.install_sync_handler, clock)
@@ -122,7 +122,7 @@ class test_Beat(AppCase):
                 delattr(sys.stdout, 'logger')
             except AttributeError:
                 pass
-            b = beatapp.Beat(app=self.app)
+            b = beatapp.Beat(app=self.app, redirect_stdouts=False)
             b.redirect_stdouts = False
             b.app.log.already_setup = False
             b.setup_logging()
@@ -133,7 +133,7 @@ class test_Beat(AppCase):
     @patch('celery.apps.beat.logger')
     def test_logs_errors(self, logger, stdout, stderr):
         with restore_logging():
-            b = MockBeat3(app=self.app, socket_timeout=None)
+            b = MockBeat3(app=self.app, redirect_stdouts=False, socket_timeout=None)
             b.start_scheduler()
             self.assertTrue(logger.critical.called)
 
@@ -141,7 +141,7 @@ class test_Beat(AppCase):
     @patch('celery.platforms.create_pidlock')
     def test_use_pidfile(self, create_pidlock, stdout, stderr):
         b = MockBeat2(app=self.app, pidfile='pidfilelockfilepid',
-                      socket_timeout=None)
+                      socket_timeout=None, redirect_stdouts=False)
         b.start_scheduler()
         self.assertTrue(create_pidlock.called)
 

+ 20 - 1
celery/tests/case.py

@@ -318,6 +318,20 @@ class AppCase(Case):
             raise
 
     def _teardown_app(self):
+        from celery.utils.log import LoggingProxy
+        assert sys.stdout
+        assert sys.stderr
+        assert sys.__stdout__
+        assert sys.__stderr__
+        this = self._get_test_name()
+        if isinstance(sys.stdout, LoggingProxy) or \
+                isinstance(sys.__stdout__, LoggingProxy):
+            raise RuntimeError(
+                'Test {0} did not disable LoggingProxy for stdout'.format(this))
+        if isinstance(sys.stderr, LoggingProxy) or \
+                isinstance(sys.__stderr__, LoggingProxy):
+            raise RuntimeError(
+                'Test {0} did not disable LoggingProxy for stderr'.format(this))
         backend = self.app.__dict__.get('backend')
         if backend is not None:
             if isinstance(backend, CacheBackend):
@@ -331,6 +345,9 @@ class AppCase(Case):
             self.app.close()
         self.app = None
 
+    def _get_test_name(self):
+        return '.'.join([self.__class__.__name__, self._testMethodName])
+
     def tearDown(self):
         try:
             self.teardown()
@@ -339,8 +356,8 @@ class AppCase(Case):
         self.assert_no_logging_side_effect()
 
     def assert_no_logging_side_effect(self):
+        this = self._get_test_name()
         root = logging.getLogger()
-        this = '.'.join([self.__class__.__name__, self._testMethodName])
         if root.level != self.__rootlevel:
             raise RuntimeError('Test {0} changed root loglevel'.format(this))
         if root.handlers != self.__roothandlers:
@@ -718,6 +735,7 @@ def body_from_sig(app, sig, utc=True):
 
 @contextmanager
 def restore_logging():
+    outs = sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__
     root = logging.getLogger()
     level = root.level
     handlers = root.handlers
@@ -725,5 +743,6 @@ def restore_logging():
     try:
         yield
     finally:
+        sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__ = outs
         root.level = level
         root.handlers[:] = handlers