test_logging.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import logging
  2. from django.template import Context, Engine, Variable, VariableDoesNotExist
  3. from django.test import SimpleTestCase, ignore_warnings
  4. from django.utils.deprecation import RemovedInDjango21Warning
  5. class TestHandler(logging.Handler):
  6. def __init__(self):
  7. super(TestHandler, self).__init__()
  8. self.log_record = None
  9. def emit(self, record):
  10. self.log_record = record
  11. class BaseTemplateLoggingTestCase(SimpleTestCase):
  12. def setUp(self):
  13. self.test_handler = TestHandler()
  14. self.logger = logging.getLogger('django.template')
  15. self.original_level = self.logger.level
  16. self.logger.addHandler(self.test_handler)
  17. self.logger.setLevel(self.loglevel)
  18. def tearDown(self):
  19. self.logger.removeHandler(self.test_handler)
  20. self.logger.level = self.original_level
  21. class VariableResolveLoggingTests(BaseTemplateLoggingTestCase):
  22. loglevel = logging.DEBUG
  23. def test_log_on_variable_does_not_exist_silent(self):
  24. class TestObject:
  25. class SilentDoesNotExist(Exception):
  26. silent_variable_failure = True
  27. @property
  28. def template_name(self):
  29. return "template_name"
  30. @property
  31. def template(self):
  32. return Engine().from_string('')
  33. @property
  34. def article(self):
  35. raise TestObject.SilentDoesNotExist("Attribute does not exist.")
  36. def __iter__(self):
  37. return iter(attr for attr in dir(TestObject) if attr[:2] != "__")
  38. def __getitem__(self, item):
  39. return self.__dict__[item]
  40. Variable('article').resolve(TestObject())
  41. self.assertEqual(
  42. self.test_handler.log_record.getMessage(),
  43. "Exception while resolving variable 'article' in template 'template_name'."
  44. )
  45. self.assertIsNotNone(self.test_handler.log_record.exc_info)
  46. raised_exception = self.test_handler.log_record.exc_info[1]
  47. self.assertEqual(str(raised_exception), 'Attribute does not exist.')
  48. def test_log_on_variable_does_not_exist_not_silent(self):
  49. with self.assertRaises(VariableDoesNotExist):
  50. Variable('article.author').resolve({'article': {'section': 'News'}})
  51. self.assertEqual(
  52. self.test_handler.log_record.getMessage(),
  53. "Exception while resolving variable 'author' in template 'unknown'."
  54. )
  55. self.assertIsNotNone(self.test_handler.log_record.exc_info)
  56. raised_exception = self.test_handler.log_record.exc_info[1]
  57. self.assertEqual(
  58. str(raised_exception),
  59. 'Failed lookup for key [author] in %r' % ("{%r: %r}" % ('section', 'News'))
  60. )
  61. def test_no_log_when_variable_exists(self):
  62. Variable('article.section').resolve({'article': {'section': 'News'}})
  63. self.assertIsNone(self.test_handler.log_record)
  64. class IncludeNodeLoggingTests(BaseTemplateLoggingTestCase):
  65. loglevel = logging.WARN
  66. @classmethod
  67. def setUpClass(cls):
  68. super(IncludeNodeLoggingTests, cls).setUpClass()
  69. cls.engine = Engine(loaders=[
  70. ('django.template.loaders.locmem.Loader', {
  71. 'child': '{{ raises_exception }}',
  72. }),
  73. ], debug=False)
  74. def error_method():
  75. raise IndexError("some generic exception")
  76. cls.ctx = Context({'raises_exception': error_method})
  77. def test_logs_exceptions_during_rendering_with_debug_disabled(self):
  78. template = self.engine.from_string('{% include "child" %}')
  79. template.name = 'template_name'
  80. with ignore_warnings(category=RemovedInDjango21Warning):
  81. self.assertEqual(template.render(self.ctx), '')
  82. self.assertEqual(
  83. self.test_handler.log_record.getMessage(),
  84. "Exception raised while rendering {% include %} for template "
  85. "'template_name'. Empty string rendered instead."
  86. )
  87. self.assertIsNotNone(self.test_handler.log_record.exc_info)
  88. self.assertEqual(self.test_handler.log_record.levelno, logging.WARN)
  89. def test_logs_exceptions_during_rendering_with_no_template_name(self):
  90. template = self.engine.from_string('{% include "child" %}')
  91. with ignore_warnings(category=RemovedInDjango21Warning):
  92. self.assertEqual(template.render(self.ctx), '')
  93. self.assertEqual(
  94. self.test_handler.log_record.getMessage(),
  95. "Exception raised while rendering {% include %} for template "
  96. "'unknown'. Empty string rendered instead."
  97. )
  98. self.assertIsNotNone(self.test_handler.log_record.exc_info)
  99. self.assertEqual(self.test_handler.log_record.levelno, logging.WARN)