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

143 lines
3.8 KiB
Python

import logging
import sys
import unittest
try:
from unittest import mock
except ImportError:
import mock
import testlib
import mitogen.core
import mitogen.master
import mitogen.parent
import mitogen.utils
from mitogen.core import b
PY2 = sys.version_info[0] == 2
if PY2:
def logging_getLogRecordFactory():
return logging.LogRecord
def logging_setLogRecordFactory(factory):
logging.LogRecord = factory
else:
logging_getLogRecordFactory = logging.getLogRecordFactory
logging_setLogRecordFactory = logging.setLogRecordFactory
def ping():
pass
def log_test():
logging.getLogger(__name__).info("This is a test")
class BufferingTest(testlib.TestCase):
klass = mitogen.core.LogHandler
def record(self):
return logging.LogRecord(
name='name',
level=99,
pathname='pathname',
lineno=123,
msg='msg',
args=(),
exc_info=None,
)
def build(self):
context = mock.Mock()
return context, self.klass(context)
def test_initially_buffered(self):
context, handler = self.build()
rec = self.record()
handler.emit(rec)
self.assertEqual(0, context.send.call_count)
self.assertEqual(1, len(handler._buffer))
def test_uncork(self):
context, handler = self.build()
rec = self.record()
handler.emit(rec)
handler.uncork()
self.assertEqual(1, context.send.call_count)
self.assertEqual(None, handler._buffer)
_, args, _ = context.send.mock_calls[0]
msg, = args
self.assertEqual(mitogen.core.FORWARD_LOG, msg.handle)
self.assertEqual(b('name\x0099\x00msg'), msg.data)
class StartupTest(testlib.RouterMixin, testlib.TestCase):
def test_earliest_messages_logged(self):
log = testlib.LogCapturer()
log.start()
c1 = self.router.local()
c1.shutdown(wait=True)
logs = log.stop()
self.assertIn('Python version is', logs)
self.assertIn('Parent is context 0 (master)', logs)
def test_earliest_messages_logged_via(self):
c1 = self.router.local(name='c1')
# ensure any c1-related msgs are processed before beginning capture
c1.call(ping)
log = testlib.LogCapturer()
log.start()
c2 = self.router.local(via=c1, name='c2', debug=True)
c2.shutdown(wait=True)
logs = log.stop()
self.assertIn('Python version is', logs)
expect = 'Parent is context %s (%s)' % (c1.context_id, 'parent')
self.assertIn(expect, logs)
class LogRecordFactoryTest(testlib.RouterMixin, testlib.TestCase):
def setUp(self):
super(LogRecordFactoryTest, self).setUp()
self.original_factory = logging_getLogRecordFactory()
def tearDown(self):
logging_setLogRecordFactory(self.original_factory)
super(LogRecordFactoryTest, self).tearDown()
def test_logrecordfactory(self):
# Change logging factory and add a custom attribute
old_factory = logging_getLogRecordFactory()
def record_factory(*args, **kwargs):
record = old_factory(*args, **kwargs)
record.custom_attribute = 0xDEADBEEF
return record
logging_setLogRecordFactory(record_factory)
c1 = self.router.local(name="c1")
log = testlib.LogCapturer(
__name__, formatter=logging.Formatter("%(custom_attribute)x - %(message)s")
)
log.start()
c1.call(log_test)
logs = log.stop()
self.assertIn("deadbeef - This is a test", logs)
StartupTest = unittest.skipIf(
condition=sys.version_info < (2, 7) or sys.version_info >= (3, 6),
reason="Message log flaky on Python < 2.7 or >= 3.6"
)(StartupTest)