Skip to content

Commit

Permalink
Convert tests to py.test
Browse files Browse the repository at this point in the history
  • Loading branch information
vmalloc committed Jul 6, 2014
1 parent 7e56d76 commit 0ebfdc7
Show file tree
Hide file tree
Showing 27 changed files with 1,585 additions and 1,522 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ test_setup:
@python scripts/test_setup.py

test:
@nosetests -w tests
@py.test tests

toxtest:
@tox
Expand Down
4 changes: 1 addition & 3 deletions scripts/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ def _execute(*args, **kwargs):

deps = [
"execnet>=1.0.9",
"nose",
"pytest",
"pyzmq",
"sqlalchemy",
]

if python_version < (2, 7):
deps.append("unittest2")
if (3, 2) <= python_version < (3, 3):
deps.append("markupsafe==0.15")
deps.append("Jinja2==2.6")
Expand Down
70 changes: 70 additions & 0 deletions tests/conftest.py
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'))
121 changes: 121 additions & 0 deletions tests/test_file_handler.py
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'
75 changes: 75 additions & 0 deletions tests/test_fingers_crossed_handler.py
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!']
31 changes: 31 additions & 0 deletions tests/test_flags.py
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
15 changes: 15 additions & 0 deletions tests/test_groups.py
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'
44 changes: 44 additions & 0 deletions tests/test_handler_errors.py
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)
Loading

0 comments on commit 0ebfdc7

Please sign in to comment.