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