forked from getlogbook/logbook
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
1,585 additions
and
1,522 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ test_setup: | |
@python scripts/test_setup.py | ||
|
||
test: | ||
@nosetests -w tests | ||
@py.test tests | ||
|
||
toxtest: | ||
@tox | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import logbook | ||
import pytest | ||
|
||
|
||
@pytest.fixture | ||
def logger(): | ||
return logbook.Logger('testlogger') | ||
|
||
@pytest.fixture | ||
def active_handler(request, test_handler, activation_strategy): | ||
|
||
s = activation_strategy(test_handler) | ||
s.activate() | ||
|
||
@request.addfinalizer | ||
def deactivate(): | ||
s.deactivate() | ||
|
||
return test_handler | ||
|
||
@pytest.fixture | ||
def test_handler(): | ||
return logbook.TestHandler() | ||
|
||
|
||
class ActivationStrategy(object): | ||
|
||
def __init__(self, handler): | ||
super(ActivationStrategy, self).__init__() | ||
self.handler = handler | ||
|
||
def activate(self): | ||
raise NotImplementedError() # pragma: no cover | ||
|
||
def deactivate(self): | ||
raise NotImplementedError() # pragma: no cover | ||
|
||
def __enter__(self): | ||
self.activate() | ||
return self.handler | ||
|
||
def __exit__(self, *_): | ||
self.deactivate() | ||
|
||
class ContextEnteringStrategy(ActivationStrategy): | ||
|
||
def activate(self): | ||
self.handler.__enter__() | ||
|
||
def deactivate(self): | ||
self.handler.__exit__(None, None, None) | ||
|
||
class PushingStrategy(ActivationStrategy): | ||
|
||
def activate(self): | ||
self.handler.push_thread() | ||
|
||
def deactivate(self): | ||
self.handler.pop_thread() | ||
|
||
|
||
|
||
@pytest.fixture(params=[ContextEnteringStrategy, PushingStrategy]) | ||
def activation_strategy(request): | ||
return request.param | ||
|
||
|
||
@pytest.fixture | ||
def logfile(tmpdir): | ||
return str(tmpdir.join('logfile.log')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import os | ||
from datetime import datetime | ||
|
||
import logbook | ||
from logbook.helpers import u, xrange | ||
|
||
from .utils import capturing_stderr_context, LETTERS | ||
|
||
|
||
def test_file_handler(logfile, activation_strategy, logger): | ||
handler = logbook.FileHandler(logfile, | ||
format_string='{record.level_name}:{record.channel}:' | ||
'{record.message}',) | ||
with activation_strategy(handler): | ||
logger.warn('warning message') | ||
handler.close() | ||
with open(logfile) as f: | ||
assert f.readline() == 'WARNING:testlogger:warning message\n' | ||
|
||
|
||
def test_file_handler_unicode(logfile, activation_strategy, logger): | ||
with capturing_stderr_context() as captured: | ||
with activation_strategy(logbook.FileHandler(logfile)): | ||
logger.info(u('\u0431')) | ||
assert (not captured.getvalue()) | ||
|
||
|
||
def test_file_handler_delay(logfile, activation_strategy, logger): | ||
handler = logbook.FileHandler(logfile, | ||
format_string='{record.level_name}:{record.channel}:' | ||
'{record.message}', delay=True) | ||
assert (not os.path.isfile(logfile)) | ||
with activation_strategy(handler): | ||
logger.warn('warning message') | ||
handler.close() | ||
|
||
with open(logfile) as f: | ||
assert f.readline() == 'WARNING:testlogger:warning message\n' | ||
|
||
|
||
def test_monitoring_file_handler(logfile, activation_strategy, logger): | ||
if os.name == "nt": | ||
pytest.skip( | ||
"unsupported on windows due to different IO (also unneeded)") | ||
handler = logbook.MonitoringFileHandler(logfile, | ||
format_string='{record.level_name}:{record.channel}:' | ||
'{record.message}', delay=True) | ||
with activation_strategy(handler): | ||
logger.warn('warning message') | ||
os.rename(logfile, logfile + '.old') | ||
logger.warn('another warning message') | ||
handler.close() | ||
with open(logfile) as f: | ||
assert f.read().strip() == 'WARNING:testlogger:another warning message' | ||
|
||
|
||
def test_custom_formatter(activation_strategy, logfile, logger): | ||
def custom_format(record, handler): | ||
return record.level_name + ':' + record.message | ||
|
||
handler = logbook.FileHandler(logfile) | ||
with activation_strategy(handler): | ||
handler.formatter = custom_format | ||
logger.warn('Custom formatters are awesome') | ||
|
||
with open(logfile) as f: | ||
assert f.readline() == 'WARNING:Custom formatters are awesome\n' | ||
|
||
|
||
def test_rotating_file_handler(logfile, activation_strategy, logger): | ||
basename = os.path.basename(logfile) | ||
handler = logbook.RotatingFileHandler(logfile, max_size=2048, | ||
backup_count=3, | ||
) | ||
handler.format_string = '{record.message}' | ||
with activation_strategy(handler): | ||
for c, x in zip(LETTERS, xrange(32)): | ||
logger.warn(c * 256) | ||
files = [x for x in os.listdir(os.path.dirname(logfile)) | ||
if x.startswith(basename)] | ||
files.sort() | ||
|
||
assert files == [basename, basename + '.1', basename + '.2', basename + '.3'] | ||
with open(logfile) as f: | ||
assert f.readline().rstrip() == ('C' * 256) | ||
assert f.readline().rstrip() == ('D' * 256) | ||
assert f.readline().rstrip() == ('E' * 256) | ||
assert f.readline().rstrip() == ('F' * 256) | ||
|
||
def test_timed_rotating_file_handler(tmpdir, activation_strategy): | ||
basename = str(tmpdir.join('trot.log')) | ||
handler = logbook.TimedRotatingFileHandler(basename, backup_count=3) | ||
handler.format_string = '[{record.time:%H:%M}] {record.message}' | ||
|
||
def fake_record(message, year, month, day, hour=0, | ||
minute=0, second=0): | ||
lr = logbook.LogRecord('Test Logger', logbook.WARNING, | ||
message) | ||
lr.time = datetime(year, month, day, hour, minute, second) | ||
return lr | ||
|
||
with activation_strategy(handler): | ||
for x in xrange(10): | ||
handler.handle(fake_record('First One', 2010, 1, 5, x + 1)) | ||
for x in xrange(20): | ||
handler.handle(fake_record('Second One', 2010, 1, 6, x + 1)) | ||
for x in xrange(10): | ||
handler.handle(fake_record('Third One', 2010, 1, 7, x + 1)) | ||
for x in xrange(20): | ||
handler.handle(fake_record('Last One', 2010, 1, 8, x + 1)) | ||
|
||
files = sorted( | ||
x for x in os.listdir(str(tmpdir)) if x.startswith('trot') | ||
) | ||
assert files == ['trot-2010-01-06.log', 'trot-2010-01-07.log', 'trot-2010-01-08.log'] | ||
with open(str(tmpdir.join('trot-2010-01-08.log'))) as f: | ||
assert f.readline().rstrip() == '[01:00] Last One' | ||
assert f.readline().rstrip() == '[02:00] Last One' | ||
with open(str(tmpdir.join('trot-2010-01-07.log'))) as f: | ||
assert f.readline().rstrip() == '[01:00] Third One' | ||
assert f.readline().rstrip() == '[02:00] Third One' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import logbook | ||
|
||
from .utils import capturing_stderr_context | ||
|
||
|
||
def test_fingerscrossed(activation_strategy, logger): | ||
handler = logbook.FingersCrossedHandler(logbook.default_handler, | ||
logbook.WARNING) | ||
|
||
# if no warning occurs, the infos are not logged | ||
with activation_strategy(handler): | ||
with capturing_stderr_context() as captured: | ||
logger.info('some info') | ||
assert captured.getvalue() == '' | ||
assert (not handler.triggered) | ||
|
||
# but if it does, all log messages are output | ||
with activation_strategy(handler): | ||
with capturing_stderr_context() as captured: | ||
logger.info('some info') | ||
logger.warning('something happened') | ||
logger.info('something else happened') | ||
logs = captured.getvalue() | ||
assert 'some info' in logs | ||
assert 'something happened' in logs | ||
assert 'something else happened' in logs | ||
assert handler.triggered | ||
|
||
|
||
def test_fingerscrossed_factory(activation_strategy, logger): | ||
handlers = [] | ||
|
||
def handler_factory(record, fch): | ||
handler = logbook.TestHandler() | ||
handlers.append(handler) | ||
return handler | ||
|
||
def make_fch(): | ||
return logbook.FingersCrossedHandler(handler_factory, | ||
logbook.WARNING) | ||
|
||
fch = make_fch() | ||
with activation_strategy(fch): | ||
logger.info('some info') | ||
assert len(handlers) == 0 | ||
logger.warning('a warning') | ||
assert len(handlers) == 1 | ||
logger.error('an error') | ||
assert len(handlers) == 1 | ||
assert handlers[0].has_infos | ||
assert handlers[0].has_warnings | ||
assert handlers[0].has_errors | ||
assert (not handlers[0].has_notices) | ||
assert (not handlers[0].has_criticals) | ||
assert (not handlers[0].has_debugs) | ||
|
||
fch = make_fch() | ||
with activation_strategy(fch): | ||
logger.info('some info') | ||
logger.warning('a warning') | ||
assert len(handlers) == 2 | ||
|
||
|
||
def test_fingerscrossed_buffer_size(activation_strategy): | ||
logger = logbook.Logger('Test') | ||
test_handler = logbook.TestHandler() | ||
handler = logbook.FingersCrossedHandler(test_handler, buffer_size=3) | ||
|
||
with activation_strategy(handler): | ||
logger.info('Never gonna give you up') | ||
logger.warn('Aha!') | ||
logger.warn('Moar!') | ||
logger.error('Pure hate!') | ||
|
||
assert test_handler.formatted_records == ['[WARNING] Test: Aha!', '[WARNING] Test: Moar!', '[ERROR] Test: Pure hate!'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import logbook | ||
|
||
import pytest | ||
|
||
from .utils import capturing_stderr_context | ||
|
||
|
||
def test_error_flag(logger): | ||
with capturing_stderr_context() as captured: | ||
with logbook.Flags(errors='print'): | ||
with logbook.Flags(errors='silent'): | ||
logger.warn('Foo {42}', 'aha') | ||
assert captured.getvalue() == '' | ||
|
||
with logbook.Flags(errors='silent'): | ||
with logbook.Flags(errors='print'): | ||
logger.warn('Foo {42}', 'aha') | ||
assert captured.getvalue() != '' | ||
|
||
with pytest.raises(Exception) as caught: | ||
with logbook.Flags(errors='raise'): | ||
logger.warn('Foo {42}', 'aha') | ||
assert 'Could not format message with provided arguments' in str(caught.value) | ||
|
||
def test_disable_introspection(logger): | ||
with logbook.Flags(introspection=False): | ||
with logbook.TestHandler() as h: | ||
logger.warn('Testing') | ||
assert h.records[0].frame is None | ||
assert h.records[0].calling_frame is None | ||
assert h.records[0].module is None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import logbook | ||
|
||
|
||
def test_groups(logger): | ||
def inject_extra(record): | ||
record.extra['foo'] = 'bar' | ||
group = logbook.LoggerGroup(processor=inject_extra) | ||
group.level = logbook.ERROR | ||
group.add_logger(logger) | ||
with logbook.TestHandler() as handler: | ||
logger.warn('A warning') | ||
logger.error('An error') | ||
assert (not handler.has_warning('A warning')) | ||
assert handler.has_error('An error') | ||
assert handler.records[0].extra['foo'] == 'bar' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import re | ||
import sys | ||
|
||
import logbook | ||
|
||
import pytest | ||
|
||
from .utils import capturing_stderr_context | ||
|
||
__file_without_pyc__ = __file__ | ||
if __file_without_pyc__.endswith(".pyc"): | ||
__file_without_pyc__ = __file_without_pyc__[:-1] | ||
|
||
|
||
def test_handler_exception(activation_strategy, logger): | ||
class ErroringHandler(logbook.TestHandler): | ||
|
||
def emit(self, record): | ||
raise RuntimeError('something bad happened') | ||
|
||
with capturing_stderr_context() as stderr: | ||
with activation_strategy(ErroringHandler()): | ||
logger.warn('I warn you.') | ||
assert 'something bad happened' in stderr.getvalue() | ||
assert 'I warn you' not in stderr.getvalue() | ||
|
||
def test_formatting_exception(): | ||
def make_record(): | ||
return logbook.LogRecord('Test Logger', logbook.WARNING, | ||
'Hello {foo:invalid}', | ||
kwargs={'foo': 42}, | ||
frame=sys._getframe()) | ||
record = make_record() | ||
with pytest.raises(TypeError) as caught: | ||
record.message | ||
|
||
errormsg = str(caught.value) | ||
assert re.search( | ||
"Could not format message with provided arguments: Invalid (?:format specifier)|(?:conversion specification)|(?:format spec)", | ||
errormsg, re.M | re.S) | ||
assert "msg='Hello {foo:invalid}'" in errormsg | ||
assert 'args=()' in errormsg | ||
assert "kwargs={'foo': 42}" in errormsg | ||
assert re.search(r'Happened in file .*%s, line \d+' % __file_without_pyc__, errormsg, re.M | re.S) |
Oops, something went wrong.