You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
4.1 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2016-2017 Versada <https://versada.eu/>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  4. import logging
  5. import sys
  6. import unittest
  7. import raven
  8. from odoo import exceptions
  9. from .. import initialize_raven
  10. from ..logutils import OdooSentryHandler
  11. def log_handler_by_class(logger, handler_cls):
  12. for handler in logger.handlers:
  13. if isinstance(handler, handler_cls):
  14. yield handler
  15. def remove_logging_handler(logger_name, handler_cls):
  16. '''Removes handlers of specified classes from a :class:`logging.Logger`
  17. with a given name.
  18. :param string logger_name: name of the logger
  19. :param handler_cls: class of the handler to remove. You can pass a tuple of
  20. classes to catch several classes
  21. '''
  22. logger = logging.getLogger(logger_name)
  23. for handler in log_handler_by_class(logger, handler_cls):
  24. logger.removeHandler(handler)
  25. class InMemoryClient(raven.Client):
  26. '''A :class:`raven.Client` subclass which simply stores events in a list.
  27. Extended based on the one found in raven-python to avoid additional testing
  28. dependencies: https://git.io/vyGO3
  29. '''
  30. def __init__(self, **kwargs):
  31. self.events = []
  32. super(InMemoryClient, self).__init__(**kwargs)
  33. def is_enabled(self):
  34. return True
  35. def send(self, **kwargs):
  36. self.events.append(kwargs)
  37. def has_event(self, event_level, event_msg):
  38. for event in self.events:
  39. if (event.get('level') == event_level and
  40. event.get('message') == event_msg):
  41. return True
  42. return False
  43. class TestClientSetup(unittest.TestCase):
  44. def setUp(self):
  45. super(TestClientSetup, self).setUp()
  46. self.logger = logging.getLogger(__name__)
  47. # Sentry is enabled by default, so the default handler will be added
  48. # when the module is loaded. After that, subsequent calls to
  49. # setup_logging will not re-add our handler. We explicitly remove
  50. # OdooSentryHandler handler so we can test with our in-memory client.
  51. remove_logging_handler('', OdooSentryHandler)
  52. def assertEventCaptured(self, client, event_level, event_msg):
  53. self.assertTrue(
  54. client.has_event(event_level, event_msg),
  55. msg='Event: "%s" was not captured' % event_msg
  56. )
  57. def assertEventNotCaptured(self, client, event_level, event_msg):
  58. self.assertFalse(
  59. client.has_event(event_level, event_msg),
  60. msg='Event: "%s" was captured' % event_msg
  61. )
  62. def test_initialize_raven_sets_dsn(self):
  63. config = {
  64. 'sentry_enabled': True,
  65. 'sentry_dsn': 'http://public:secret@example.com/1',
  66. }
  67. client = initialize_raven(config, client_cls=InMemoryClient)
  68. self.assertEqual(client.remote.base_url, 'http://example.com')
  69. def test_capture_event(self):
  70. config = {
  71. 'sentry_enabled': True,
  72. 'sentry_dsn': 'http://public:secret@example.com/1',
  73. }
  74. level, msg = logging.WARNING, 'Test event, can be ignored'
  75. client = initialize_raven(config, client_cls=InMemoryClient)
  76. self.logger.log(level, msg)
  77. self.assertEventCaptured(client, level, msg)
  78. def test_ignore_exceptions(self):
  79. config = {
  80. 'sentry_enabled': True,
  81. 'sentry_dsn': 'http://public:secret@example.com/1',
  82. 'sentry_ignore_exceptions': 'odoo.exceptions.UserError',
  83. }
  84. level, msg = logging.WARNING, 'Test UserError'
  85. client = initialize_raven(config, client_cls=InMemoryClient)
  86. handlers = list(
  87. log_handler_by_class(logging.getLogger(), OdooSentryHandler)
  88. )
  89. self.assertTrue(handlers)
  90. handler = handlers[0]
  91. try:
  92. raise exceptions.UserError(msg)
  93. except exceptions.UserError:
  94. exc_info = sys.exc_info()
  95. record = logging.LogRecord(
  96. __name__, level, __file__, 42, msg, (), exc_info)
  97. handler.emit(record)
  98. self.assertEventNotCaptured(client, level, msg)