/celery/tests/test_log.py

https://github.com/coderanger/celery · Python · 208 lines · 162 code · 46 blank · 0 comment · 11 complexity · 307dd78daf29cf97d0464e0a776eb82d MD5 · raw file

  1. from __future__ import generators
  2. import sys
  3. import logging
  4. import unittest2 as unittest
  5. from tempfile import mktemp
  6. from StringIO import StringIO
  7. try:
  8. from contextlib import contextmanager
  9. except ImportError:
  10. from celery.tests.utils import fallback_contextmanager as contextmanager
  11. from celery import log
  12. from celery.log import (setup_logger, setup_task_logger,
  13. get_default_logger, get_task_logger,
  14. redirect_stdouts_to_logger, LoggingProxy)
  15. from celery.tests.utils import override_stdouts, execute_context
  16. from celery.utils import gen_unique_id
  17. from celery.utils.compat import LoggerAdapter
  18. from celery.utils.compat import _CompatLoggerAdapter
  19. def get_handlers(logger):
  20. if isinstance(logger, LoggerAdapter):
  21. return logger.logger.handlers
  22. return logger.handlers
  23. def set_handlers(logger, new_handlers):
  24. if isinstance(logger, LoggerAdapter):
  25. logger.logger.handlers = new_handlers
  26. logger.handlers = new_handlers
  27. @contextmanager
  28. def wrap_logger(logger, loglevel=logging.ERROR):
  29. old_handlers = get_handlers(logger)
  30. sio = StringIO()
  31. siohandler = logging.StreamHandler(sio)
  32. set_handlers(logger, [siohandler])
  33. yield sio
  34. set_handlers(logger, old_handlers)
  35. class test_default_logger(unittest.TestCase):
  36. def setUp(self):
  37. self.setup_logger = setup_logger
  38. self.get_logger = get_default_logger
  39. log._setup = False
  40. def _assertLog(self, logger, logmsg, loglevel=logging.ERROR):
  41. def with_wrap_logger(sio):
  42. logger.log(loglevel, logmsg)
  43. return sio.getvalue().strip()
  44. context = wrap_logger(logger, loglevel=loglevel)
  45. execute_context(context, with_wrap_logger)
  46. def assertDidLogTrue(self, logger, logmsg, reason, loglevel=None):
  47. val = self._assertLog(logger, logmsg, loglevel=loglevel)
  48. return self.assertEqual(val, logmsg, reason)
  49. def assertDidLogFalse(self, logger, logmsg, reason, loglevel=None):
  50. val = self._assertLog(logger, logmsg, loglevel=loglevel)
  51. return self.assertFalse(val, reason)
  52. def test_setup_logger(self):
  53. logger = self.setup_logger(loglevel=logging.ERROR, logfile=None,
  54. root=False)
  55. set_handlers(logger, [])
  56. logger = self.setup_logger(loglevel=logging.ERROR, logfile=None,
  57. root=False)
  58. self.assertIs(get_handlers(logger)[0].stream, sys.__stderr__,
  59. "setup_logger logs to stderr without logfile argument.")
  60. self.assertDidLogFalse(logger, "Logging something",
  61. "Logger doesn't info when loglevel is ERROR",
  62. loglevel=logging.INFO)
  63. def test_setup_logger_no_handlers_stream(self):
  64. l = self.get_logger()
  65. set_handlers(l, [])
  66. def with_override_stdouts(outs):
  67. stdout, stderr = outs
  68. l = self.setup_logger(logfile=stderr, loglevel=logging.INFO,
  69. root=False)
  70. l.info("The quick brown fox...")
  71. self.assertIn("The quick brown fox...", stderr.getvalue())
  72. context = override_stdouts()
  73. execute_context(context, with_override_stdouts)
  74. def test_setup_logger_no_handlers_file(self):
  75. l = self.get_logger()
  76. set_handlers(l, [])
  77. tempfile = mktemp(suffix="unittest", prefix="celery")
  78. l = self.setup_logger(logfile=tempfile, loglevel=0, root=False)
  79. self.assertIsInstance(get_handlers(l)[0],
  80. logging.FileHandler)
  81. def test_redirect_stdouts(self):
  82. logger = self.setup_logger(loglevel=logging.ERROR, logfile=None,
  83. root=False)
  84. try:
  85. def with_wrap_logger(sio):
  86. redirect_stdouts_to_logger(logger, loglevel=logging.ERROR)
  87. logger.error("foo")
  88. self.assertIn("foo", sio.getvalue())
  89. context = wrap_logger(logger)
  90. execute_context(context, with_wrap_logger)
  91. finally:
  92. sys.stdout, sys.stderr = sys.__stdout__, sys.__stderr__
  93. def test_logging_proxy(self):
  94. logger = self.setup_logger(loglevel=logging.ERROR, logfile=None,
  95. root=False)
  96. def with_wrap_logger(sio):
  97. p = LoggingProxy(logger)
  98. p.close()
  99. p.write("foo")
  100. self.assertNotIn("foo", sio.getvalue())
  101. p.closed = False
  102. p.write("foo")
  103. self.assertIn("foo", sio.getvalue())
  104. lines = ["baz", "xuzzy"]
  105. p.writelines(lines)
  106. for line in lines:
  107. self.assertIn(line, sio.getvalue())
  108. p.flush()
  109. p.close()
  110. self.assertFalse(p.isatty())
  111. self.assertIsNone(p.fileno())
  112. context = wrap_logger(logger)
  113. execute_context(context, with_wrap_logger)
  114. class test_task_logger(test_default_logger):
  115. def setUp(self):
  116. self.setup_logger = setup_task_logger
  117. self.get_logger = get_task_logger
  118. class MockLogger(logging.Logger):
  119. _records = None
  120. def __init__(self, *args, **kwargs):
  121. self._records = []
  122. logging.Logger.__init__(self, *args, **kwargs)
  123. def handle(self, record):
  124. self._records.append(record)
  125. def isEnabledFor(self, level):
  126. return True
  127. class test_CompatLoggerAdapter(unittest.TestCase):
  128. levels = ("debug",
  129. "info",
  130. "warn", "warning",
  131. "error",
  132. "fatal", "critical")
  133. def setUp(self):
  134. self.logger, self.adapter = self.createAdapter()
  135. def createAdapter(self, name=None, extra={"foo": "bar"}):
  136. logger = MockLogger(name=name or gen_unique_id())
  137. return logger, _CompatLoggerAdapter(logger, extra)
  138. def test_levels(self):
  139. for level in self.levels:
  140. msg = "foo bar %s" % (level, )
  141. logger, adapter = self.createAdapter()
  142. getattr(adapter, level)(msg)
  143. self.assertEqual(logger._records[0].msg, msg)
  144. def test_exception(self):
  145. try:
  146. raise KeyError("foo")
  147. except KeyError:
  148. self.adapter.exception("foo bar exception")
  149. self.assertEqual(self.logger._records[0].msg, "foo bar exception")
  150. def test_setLevel(self):
  151. self.adapter.setLevel(logging.INFO)
  152. self.assertEqual(self.logger.level, logging.INFO)
  153. def test_process(self):
  154. msg, kwargs = self.adapter.process("foo bar baz", {"exc_info": 1})
  155. self.assertDictEqual(kwargs, {"exc_info": 1,
  156. "extra": {"foo": "bar"}})
  157. def test_add_remove_handlers(self):
  158. handler = logging.StreamHandler()
  159. self.adapter.addHandler(handler)
  160. self.assertIs(self.logger.handlers[0], handler)
  161. self.adapter.removeHandler(handler)
  162. self.assertListEqual(self.logger.handlers, [])