No longer change the level of any logger unless requested explicitly
Ref: #3013
This commit is contained in:
parent
5ad1313b8a
commit
8dcd2718aa
|
@ -82,13 +82,14 @@ def pytest_addoption(parser):
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def catching_logs(handler, formatter=None, level=logging.NOTSET):
|
def catching_logs(handler, formatter=None, level=None):
|
||||||
"""Context manager that prepares the whole logging machinery properly."""
|
"""Context manager that prepares the whole logging machinery properly."""
|
||||||
root_logger = logging.getLogger()
|
root_logger = logging.getLogger()
|
||||||
|
|
||||||
if formatter is not None:
|
if formatter is not None:
|
||||||
handler.setFormatter(formatter)
|
handler.setFormatter(formatter)
|
||||||
handler.setLevel(level)
|
if level is not None:
|
||||||
|
handler.setLevel(level)
|
||||||
|
|
||||||
# Adding the same handler twice would confuse logging system.
|
# Adding the same handler twice would confuse logging system.
|
||||||
# Just don't do that.
|
# Just don't do that.
|
||||||
|
@ -96,12 +97,14 @@ def catching_logs(handler, formatter=None, level=logging.NOTSET):
|
||||||
|
|
||||||
if add_new_handler:
|
if add_new_handler:
|
||||||
root_logger.addHandler(handler)
|
root_logger.addHandler(handler)
|
||||||
orig_level = root_logger.level
|
if level is not None:
|
||||||
root_logger.setLevel(min(orig_level, level))
|
orig_level = root_logger.level
|
||||||
|
root_logger.setLevel(level)
|
||||||
try:
|
try:
|
||||||
yield handler
|
yield handler
|
||||||
finally:
|
finally:
|
||||||
root_logger.setLevel(orig_level)
|
if level is not None:
|
||||||
|
root_logger.setLevel(orig_level)
|
||||||
if add_new_handler:
|
if add_new_handler:
|
||||||
root_logger.removeHandler(handler)
|
root_logger.removeHandler(handler)
|
||||||
|
|
||||||
|
@ -166,14 +169,10 @@ class LogCaptureFixture(object):
|
||||||
def set_level(self, level, logger=None):
|
def set_level(self, level, logger=None):
|
||||||
"""Sets the level for capturing of logs.
|
"""Sets the level for capturing of logs.
|
||||||
|
|
||||||
By default, the level is set on the handler used to capture
|
:param int level: the logger to level.
|
||||||
logs. Specify a logger name to instead set the level of any
|
:param str logger: the logger to update the level. If not given, the root logger level is updated.
|
||||||
logger.
|
|
||||||
"""
|
"""
|
||||||
if logger is None:
|
logger = logging.getLogger(logger)
|
||||||
logger = self.handler
|
|
||||||
else:
|
|
||||||
logger = logging.getLogger(logger)
|
|
||||||
logger.setLevel(level)
|
logger.setLevel(level)
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
@ -259,6 +258,7 @@ class LoggingPlugin(object):
|
||||||
self.formatter = logging.Formatter(
|
self.formatter = logging.Formatter(
|
||||||
get_option_ini(config, 'log_format'),
|
get_option_ini(config, 'log_format'),
|
||||||
get_option_ini(config, 'log_date_format'))
|
get_option_ini(config, 'log_date_format'))
|
||||||
|
self.log_level = get_actual_log_level(config, 'log_level')
|
||||||
|
|
||||||
if config.getini('log_cli'):
|
if config.getini('log_cli'):
|
||||||
log_cli_handler = logging.StreamHandler(sys.stderr)
|
log_cli_handler = logging.StreamHandler(sys.stderr)
|
||||||
|
@ -269,8 +269,7 @@ class LoggingPlugin(object):
|
||||||
log_cli_formatter = logging.Formatter(
|
log_cli_formatter = logging.Formatter(
|
||||||
log_cli_format,
|
log_cli_format,
|
||||||
datefmt=log_cli_date_format)
|
datefmt=log_cli_date_format)
|
||||||
log_cli_level = get_actual_log_level(
|
log_cli_level = get_actual_log_level(config, 'log_cli_level', 'log_level')
|
||||||
config, 'log_cli_level', 'log_level') or logging.WARNING
|
|
||||||
self.log_cli_handler = log_cli_handler # needed for a single unittest
|
self.log_cli_handler = log_cli_handler # needed for a single unittest
|
||||||
self.live_logs_context = catching_logs(log_cli_handler,
|
self.live_logs_context = catching_logs(log_cli_handler,
|
||||||
formatter=log_cli_formatter,
|
formatter=log_cli_formatter,
|
||||||
|
@ -281,8 +280,7 @@ class LoggingPlugin(object):
|
||||||
|
|
||||||
log_file = get_option_ini(config, 'log_file')
|
log_file = get_option_ini(config, 'log_file')
|
||||||
if log_file:
|
if log_file:
|
||||||
self.log_file_level = get_actual_log_level(
|
self.log_file_level = get_actual_log_level(config, 'log_file_level')
|
||||||
config, 'log_file_level') or logging.WARNING
|
|
||||||
|
|
||||||
log_file_format = get_option_ini(
|
log_file_format = get_option_ini(
|
||||||
config, 'log_file_format', 'log_format')
|
config, 'log_file_format', 'log_format')
|
||||||
|
@ -303,7 +301,7 @@ class LoggingPlugin(object):
|
||||||
def _runtest_for(self, item, when):
|
def _runtest_for(self, item, when):
|
||||||
"""Implements the internals of pytest_runtest_xxx() hook."""
|
"""Implements the internals of pytest_runtest_xxx() hook."""
|
||||||
with catching_logs(LogCaptureHandler(),
|
with catching_logs(LogCaptureHandler(),
|
||||||
formatter=self.formatter) as log_handler:
|
formatter=self.formatter, level=self.log_level) as log_handler:
|
||||||
if not hasattr(item, 'catch_log_handlers'):
|
if not hasattr(item, 'catch_log_handlers'):
|
||||||
item.catch_log_handlers = {}
|
item.catch_log_handlers = {}
|
||||||
item.catch_log_handlers[when] = log_handler
|
item.catch_log_handlers[when] = log_handler
|
||||||
|
|
|
@ -35,7 +35,7 @@ def test_messages_logged(testdir):
|
||||||
logger.info('text going to logger')
|
logger.info('text going to logger')
|
||||||
assert False
|
assert False
|
||||||
''')
|
''')
|
||||||
result = testdir.runpytest()
|
result = testdir.runpytest('--log-level=INFO')
|
||||||
assert result.ret == 1
|
assert result.ret == 1
|
||||||
result.stdout.fnmatch_lines(['*- Captured *log call -*',
|
result.stdout.fnmatch_lines(['*- Captured *log call -*',
|
||||||
'*text going to logger*'])
|
'*text going to logger*'])
|
||||||
|
@ -58,7 +58,7 @@ def test_setup_logging(testdir):
|
||||||
logger.info('text going to logger from call')
|
logger.info('text going to logger from call')
|
||||||
assert False
|
assert False
|
||||||
''')
|
''')
|
||||||
result = testdir.runpytest()
|
result = testdir.runpytest('--log-level=INFO')
|
||||||
assert result.ret == 1
|
assert result.ret == 1
|
||||||
result.stdout.fnmatch_lines(['*- Captured *log setup -*',
|
result.stdout.fnmatch_lines(['*- Captured *log setup -*',
|
||||||
'*text going to logger from setup*',
|
'*text going to logger from setup*',
|
||||||
|
@ -79,7 +79,7 @@ def test_teardown_logging(testdir):
|
||||||
logger.info('text going to logger from teardown')
|
logger.info('text going to logger from teardown')
|
||||||
assert False
|
assert False
|
||||||
''')
|
''')
|
||||||
result = testdir.runpytest()
|
result = testdir.runpytest('--log-level=INFO')
|
||||||
assert result.ret == 1
|
assert result.ret == 1
|
||||||
result.stdout.fnmatch_lines(['*- Captured *log call -*',
|
result.stdout.fnmatch_lines(['*- Captured *log call -*',
|
||||||
'*text going to logger from call*',
|
'*text going to logger from call*',
|
||||||
|
@ -168,9 +168,9 @@ def test_log_cli_default_level(testdir):
|
||||||
import logging
|
import logging
|
||||||
def test_log_cli(request):
|
def test_log_cli(request):
|
||||||
plugin = request.config.pluginmanager.getplugin('logging-plugin')
|
plugin = request.config.pluginmanager.getplugin('logging-plugin')
|
||||||
assert plugin.log_cli_handler.level == logging.WARNING
|
assert plugin.log_cli_handler.level == logging.NOTSET
|
||||||
logging.getLogger('catchlog').info("This log message won't be shown")
|
logging.getLogger('catchlog').info("INFO message won't be shown")
|
||||||
logging.getLogger('catchlog').warning("This log message will be shown")
|
logging.getLogger('catchlog').warning("WARNING message will be shown")
|
||||||
print('PASSED')
|
print('PASSED')
|
||||||
''')
|
''')
|
||||||
testdir.makeini('''
|
testdir.makeini('''
|
||||||
|
@ -185,15 +185,9 @@ def test_log_cli_default_level(testdir):
|
||||||
'test_log_cli_default_level.py PASSED',
|
'test_log_cli_default_level.py PASSED',
|
||||||
])
|
])
|
||||||
result.stderr.fnmatch_lines([
|
result.stderr.fnmatch_lines([
|
||||||
"* This log message will be shown"
|
'*WARNING message will be shown*',
|
||||||
])
|
])
|
||||||
for line in result.errlines:
|
assert "INFO message won't be shown" not in result.stderr.str()
|
||||||
try:
|
|
||||||
assert "This log message won't be shown" in line
|
|
||||||
pytest.fail("A log message was shown and it shouldn't have been")
|
|
||||||
except AssertionError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# make sure that that we get a '0' exit code for the testsuite
|
# make sure that that we get a '0' exit code for the testsuite
|
||||||
assert result.ret == 0
|
assert result.ret == 0
|
||||||
|
|
||||||
|
@ -307,7 +301,7 @@ def test_log_file_cli(testdir):
|
||||||
|
|
||||||
log_file = testdir.tmpdir.join('pytest.log').strpath
|
log_file = testdir.tmpdir.join('pytest.log').strpath
|
||||||
|
|
||||||
result = testdir.runpytest('-s', '--log-file={0}'.format(log_file))
|
result = testdir.runpytest('-s', '--log-file={0}'.format(log_file), '--log-file-level=WARNING')
|
||||||
|
|
||||||
# fnmatch_lines does an assertion internally
|
# fnmatch_lines does an assertion internally
|
||||||
result.stdout.fnmatch_lines([
|
result.stdout.fnmatch_lines([
|
||||||
|
@ -356,6 +350,16 @@ def test_log_file_cli_level(testdir):
|
||||||
assert "This log message won't be shown" not in contents
|
assert "This log message won't be shown" not in contents
|
||||||
|
|
||||||
|
|
||||||
|
def test_log_level_not_changed_by_default(testdir):
|
||||||
|
testdir.makepyfile('''
|
||||||
|
import logging
|
||||||
|
def test_log_file():
|
||||||
|
assert logging.getLogger().level == logging.WARNING
|
||||||
|
''')
|
||||||
|
result = testdir.runpytest('-s')
|
||||||
|
result.stdout.fnmatch_lines('* 1 passed in *')
|
||||||
|
|
||||||
|
|
||||||
def test_log_file_ini(testdir):
|
def test_log_file_ini(testdir):
|
||||||
log_file = testdir.tmpdir.join('pytest.log').strpath
|
log_file = testdir.tmpdir.join('pytest.log').strpath
|
||||||
|
|
||||||
|
@ -363,6 +367,7 @@ def test_log_file_ini(testdir):
|
||||||
"""
|
"""
|
||||||
[pytest]
|
[pytest]
|
||||||
log_file={0}
|
log_file={0}
|
||||||
|
log_file_level=WARNING
|
||||||
""".format(log_file))
|
""".format(log_file))
|
||||||
testdir.makepyfile('''
|
testdir.makepyfile('''
|
||||||
import pytest
|
import pytest
|
||||||
|
|
Loading…
Reference in New Issue