summaryrefslogtreecommitdiff
path: root/tests/test_util_logging.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_util_logging.py')
-rw-r--r--tests/test_util_logging.py245
1 files changed, 245 insertions, 0 deletions
diff --git a/tests/test_util_logging.py b/tests/test_util_logging.py
index d8ab27b47..ca46b8328 100644
--- a/tests/test_util_logging.py
+++ b/tests/test_util_logging.py
@@ -10,7 +10,96 @@
"""
from __future__ import print_function
+import codecs
+from docutils import nodes
+
+from sphinx.errors import SphinxWarning
+from sphinx.util import logging
+from sphinx.util.console import colorize
from sphinx.util.logging import is_suppressed_warning
+from sphinx.util.parallel import ParallelTasks
+
+import pytest
+from util import strip_escseq
+
+
+def test_info_and_warning(app, status, warning):
+ app.verbosity = 2
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ logger.debug('message1')
+ logger.info('message2')
+ logger.warning('message3')
+ logger.critical('message4')
+ logger.error('message5')
+
+ assert 'message1' in status.getvalue()
+ assert 'message2' in status.getvalue()
+ assert 'message3' not in status.getvalue()
+ assert 'message4' not in status.getvalue()
+ assert 'message5' not in status.getvalue()
+
+ assert 'message1' not in warning.getvalue()
+ assert 'message2' not in warning.getvalue()
+ assert 'message3' in warning.getvalue()
+ assert 'message4' in warning.getvalue()
+ assert 'message5' in warning.getvalue()
+
+
+def test_verbosity_filter(app, status, warning):
+ # verbosity = 0: INFO
+ app.verbosity = 0
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ logger.info('message1')
+ logger.verbose('message2')
+ logger.debug('message3')
+
+ assert 'message1' in status.getvalue()
+ assert 'message2' not in status.getvalue()
+ assert 'message3' not in status.getvalue()
+ assert 'message4' not in status.getvalue()
+
+ # verbosity = 1: VERBOSE
+ app.verbosity = 1
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ logger.info('message1')
+ logger.verbose('message2')
+ logger.debug('message3')
+
+ assert 'message1' in status.getvalue()
+ assert 'message2' in status.getvalue()
+ assert 'message3' not in status.getvalue()
+ assert 'message4' not in status.getvalue()
+
+ # verbosity = 2: DEBUG
+ app.verbosity = 2
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ logger.info('message1')
+ logger.verbose('message2')
+ logger.debug('message3')
+
+ assert 'message1' in status.getvalue()
+ assert 'message2' in status.getvalue()
+ assert 'message3' in status.getvalue()
+ assert 'message4' not in status.getvalue()
+
+
+def test_nonl_info_log(app, status, warning):
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ logger.info('message1', nonl=True)
+ logger.info('message2')
+ logger.info('message3')
+
+ assert 'message1message2\nmessage3' in status.getvalue()
def test_is_suppressed_warning():
@@ -24,3 +113,159 @@ def test_is_suppressed_warning():
assert is_suppressed_warning("files", "stylesheet", suppress_warnings) is True
assert is_suppressed_warning("rest", "syntax", suppress_warnings) is False
assert is_suppressed_warning("rest", "duplicated_labels", suppress_warnings) is True
+
+
+def test_suppress_warnings(app, status, warning):
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ app._warncount = 0 # force reset
+
+ app.config.suppress_warnings = []
+ warning.truncate(0)
+ logger.warning('message1', type='test', subtype='logging')
+ logger.warning('message2', type='test', subtype='crash')
+ logger.warning('message3', type='actual', subtype='logging')
+ assert 'message1' in warning.getvalue()
+ assert 'message2' in warning.getvalue()
+ assert 'message3' in warning.getvalue()
+ assert app._warncount == 3
+
+ app.config.suppress_warnings = ['test']
+ warning.truncate(0)
+ logger.warning('message1', type='test', subtype='logging')
+ logger.warning('message2', type='test', subtype='crash')
+ logger.warning('message3', type='actual', subtype='logging')
+ assert 'message1' not in warning.getvalue()
+ assert 'message2' not in warning.getvalue()
+ assert 'message3' in warning.getvalue()
+ assert app._warncount == 4
+
+ app.config.suppress_warnings = ['test.logging']
+ warning.truncate(0)
+ logger.warning('message1', type='test', subtype='logging')
+ logger.warning('message2', type='test', subtype='crash')
+ logger.warning('message3', type='actual', subtype='logging')
+ assert 'message1' not in warning.getvalue()
+ assert 'message2' in warning.getvalue()
+ assert 'message3' in warning.getvalue()
+ assert app._warncount == 6
+
+
+def test_warningiserror(app, status, warning):
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ # if False, warning is not error
+ app.warningiserror = False
+ logger.warning('message')
+
+ # if True, warning raises SphinxWarning exception
+ app.warningiserror = True
+ with pytest.raises(SphinxWarning):
+ logger.warning('message')
+
+
+def test_warning_location(app, status, warning):
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ logger.warning('message1', location='index')
+ assert 'index.txt: WARNING: message1' in warning.getvalue()
+
+ logger.warning('message2', location=('index', 10))
+ assert 'index.txt:10: WARNING: message2' in warning.getvalue()
+
+ logger.warning('message3', location=None)
+ assert colorize('darkred', 'WARNING: message3') in warning.getvalue()
+
+ node = nodes.Node()
+ node.source, node.line = ('index.txt', 10)
+ logger.warning('message4', location=node)
+ assert 'index.txt:10: WARNING: message4' in warning.getvalue()
+
+ node.source, node.line = ('index.txt', None)
+ logger.warning('message5', location=node)
+ assert 'index.txt:: WARNING: message5' in warning.getvalue()
+
+ node.source, node.line = (None, 10)
+ logger.warning('message6', location=node)
+ assert '<unknown>:10: WARNING: message6' in warning.getvalue()
+
+ node.source, node.line = (None, None)
+ logger.warning('message7', location=node)
+ assert colorize('darkred', 'WARNING: message7') in warning.getvalue()
+
+
+def test_pending_warnings(app, status, warning):
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ logger.warning('message1')
+ with logging.pending_warnings():
+ # not logged yet (bufferred) in here
+ logger.warning('message2')
+ logger.warning('message3')
+ assert 'WARNING: message1' in warning.getvalue()
+ assert 'WARNING: message2' not in warning.getvalue()
+ assert 'WARNING: message3' not in warning.getvalue()
+
+ # actually logged as ordered
+ assert 'WARNING: message2\nWARNING: message3' in strip_escseq(warning.getvalue())
+
+
+def test_colored_logs(app, status, warning):
+ app.verbosity = 2
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ # default colors
+ logger.debug('message1')
+ logger.verbose('message2')
+ logger.info('message3')
+ logger.warning('message4')
+ logger.critical('message5')
+ logger.error('message6')
+
+ assert colorize('darkgray', 'message1') in status.getvalue()
+ assert 'message2\n' in status.getvalue() # not colored
+ assert 'message3\n' in status.getvalue() # not colored
+ assert colorize('darkred', 'WARNING: message4') in warning.getvalue()
+ assert 'WARNING: message5\n' in warning.getvalue() # not colored
+ assert 'WARNING: message6\n' in warning.getvalue() # not colored
+
+ # color specification
+ logger.debug('message7', color='white')
+ logger.info('message8', color='red')
+ assert colorize('white', 'message7') in status.getvalue()
+ assert colorize('red', 'message8') in status.getvalue()
+
+
+def test_logging_in_ParallelTasks(app, status, warning):
+ logging.setup(app, status, warning)
+ logger = logging.getLogger(__name__)
+
+ def child_process():
+ logger.info('message1')
+ logger.warning('message2', location='index')
+
+ tasks = ParallelTasks(1)
+ tasks.add_task(child_process)
+ tasks.join()
+ assert 'message1' in status.getvalue()
+ assert 'index.txt: WARNING: message2' in warning.getvalue()
+
+
+def test_output_with_unencodable_char(app, status, warning):
+ class StreamWriter(codecs.StreamWriter):
+ def write(self, object):
+ self.stream.write(object.encode('cp1252').decode('cp1252'))
+
+ logging.setup(app, StreamWriter(status), warning)
+ logger = logging.getLogger(__name__)
+
+ # info with UnicodeEncodeError
+ status.truncate(0)
+ status.seek(0)
+ logger.info(u"unicode \u206d...")
+ assert status.getvalue() == "unicode ?...\n"