From d895f5d6fce13981f11cfc6c47e2c12474a3f07f Mon Sep 17 00:00:00 2001 From: Katerina Koukiou Date: Wed, 14 Mar 2018 09:44:58 +0100 Subject: [PATCH] logging.py: Don't change log level of the root logger to bigger numeric value --- AUTHORS | 1 + _pytest/logging.py | 2 +- changelog/3307.feature.rst | 3 ++ testing/logging/test_reporting.py | 62 ++++++++++++++++++++++++++++++- 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 changelog/3307.feature.rst diff --git a/AUTHORS b/AUTHORS index b61969ff4..9401acf85 100644 --- a/AUTHORS +++ b/AUTHORS @@ -105,6 +105,7 @@ Jurko Gospodnetić Justyna Janczyszyn Kale Kundert Katarzyna Jachim +Katerina Koukiou Kevin Cox Kodi B. Arfer Lawrence Mitchell diff --git a/_pytest/logging.py b/_pytest/logging.py index 7234bdeb0..fe4cbd478 100644 --- a/_pytest/logging.py +++ b/_pytest/logging.py @@ -153,7 +153,7 @@ def catching_logs(handler, formatter=None, level=None): root_logger.addHandler(handler) if level is not None: orig_level = root_logger.level - root_logger.setLevel(level) + root_logger.setLevel(min(orig_level, level)) try: yield handler finally: diff --git a/changelog/3307.feature.rst b/changelog/3307.feature.rst new file mode 100644 index 000000000..181f81cc2 --- /dev/null +++ b/changelog/3307.feature.rst @@ -0,0 +1,3 @@ +pytest should not change the log level of the root logger when the +``log-level`` parameter has greater numeric value than that of the level of +the root logger. diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index f84f7e459..699df0e60 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -49,6 +49,66 @@ def test_messages_logged(testdir): 'text going to stderr']) +def test_root_logger_affected(testdir): + testdir.makepyfile(""" + import logging + logger = logging.getLogger() + def test_foo(): + logger.info('info text ' + 'going to logger') + logger.warning('warning text ' + 'going to logger') + logger.error('error text ' + 'going to logger') + + assert 0 + """) + log_file = testdir.tmpdir.join('pytest.log').strpath + result = testdir.runpytest('--log-level=ERROR', '--log-file=pytest.log') + assert result.ret == 1 + + # the capture log calls in the stdout section only contain the + # logger.error msg, because --log-level=ERROR + result.stdout.fnmatch_lines(['*error text going to logger*']) + with pytest.raises(pytest.fail.Exception): + result.stdout.fnmatch_lines(['*warning text going to logger*']) + with pytest.raises(pytest.fail.Exception): + result.stdout.fnmatch_lines(['*info text going to logger*']) + + # the log file should contain the warning and the error log messages and + # not the info one, because the default level of the root logger is + # WARNING. + assert os.path.isfile(log_file) + with open(log_file) as rfh: + contents = rfh.read() + assert "info text going to logger" not in contents + assert "warning text going to logger" in contents + assert "error text going to logger" in contents + + +def test_log_cli_level_log_level_interaction(testdir): + testdir.makepyfile(""" + import logging + logger = logging.getLogger() + + def test_foo(): + logger.debug('debug text ' + 'going to logger') + logger.info('info text ' + 'going to logger') + logger.warning('warning text ' + 'going to logger') + logger.error('error text ' + 'going to logger') + assert 0 + """) + + result = testdir.runpytest('--log-cli-level=INFO', '--log-level=ERROR') + assert result.ret == 1 + + result.stdout.fnmatch_lines([ + '*-- live log call --*', + '*INFO*info text going to logger', + '*WARNING*warning text going to logger', + '*ERROR*error text going to logger', + '=* 1 failed in *=', + ]) + assert 'DEBUG' not in result.stdout.str() + + def test_setup_logging(testdir): testdir.makepyfile(''' import logging @@ -61,7 +121,7 @@ def test_setup_logging(testdir): def test_foo(): logger.info('text going to logger from call') assert False - ''') + ''') result = testdir.runpytest('--log-level=INFO') assert result.ret == 1 result.stdout.fnmatch_lines(['*- Captured *log setup -*',