Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes | Static Public Attributes
test.test_logging.ConfigFileTest Class Reference
Inheritance diagram for test.test_logging.ConfigFileTest:
Inheritance graph
[legend]
Collaboration diagram for test.test_logging.ConfigFileTest:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def apply_config
def test_config0_ok
def test_config1_ok
def test_config2_failure
def test_config3_failure
def test_config4_ok
def test_config5_ok
def test_config6_ok
def test_config7_ok
def setUp
def tearDown
def assert_log_lines
def next_message

Public Attributes

 saved_handlers
 saved_handler_list
 saved_loggers
 saved_level_names
 logger_states
 logger1
 logger2
 root_logger
 original_logging_level
 stream
 root_hdlr
 root_formatter

Static Public Attributes

string expected_log_pat = r"^([\w]+) \+\+ ([\w]+)$"
string config0
string config1
string config1a
tuple config2 = config1.replace("sys.stdout", "sys.stbout")
tuple config3 = config1.replace("formatter=form1", "formatter=misspelled_name")
string config4
tuple config5 = config1.replace('class=StreamHandler', 'class=logging.StreamHandler')
string config6
string config7
string log_format = "%(name)s -> %(levelname)s: %(message)s"
int message_num = 0

Detailed Description

Reading logging config from a .ini-style config file.

Definition at line 551 of file test_logging.py.


Member Function Documentation

Definition at line 763 of file test_logging.py.

00763 
00764     def apply_config(self, conf):
00765         file = io.StringIO(textwrap.dedent(conf))
00766         logging.config.fileConfig(file)

Here is the call graph for this function:

Here is the caller graph for this function:

def test.test_logging.BaseTest.assert_log_lines (   self,
  expected_values,
  stream = None 
) [inherited]
Match the collected log lines against the regular expression
self.expected_log_pat, and compare the extracted group values to
the expected_values list of tuples.

Definition at line 131 of file test_logging.py.

00131 
00132     def assert_log_lines(self, expected_values, stream=None):
00133         """Match the collected log lines against the regular expression
00134         self.expected_log_pat, and compare the extracted group values to
00135         the expected_values list of tuples."""
00136         stream = stream or self.stream
00137         pat = re.compile(self.expected_log_pat)
00138         try:
00139             stream.reset()
00140             actual_lines = stream.readlines()
00141         except AttributeError:
00142             # StringIO.StringIO lacks a reset() method.
00143             actual_lines = stream.getvalue().splitlines()
00144         self.assertEqual(len(actual_lines), len(expected_values),
00145                           '%s vs. %s' % (actual_lines, expected_values))
00146         for actual, expected in zip(actual_lines, expected_values):
00147             match = pat.search(actual)
00148             if not match:
00149                 self.fail("Log line does not match expected pattern:\n" +
00150                             actual)
00151             self.assertEqual(tuple(match.groups()), expected)
00152         s = stream.read()
00153         if s:
00154             self.fail("Remaining output at end of log stream:\n" + s)

Here is the call graph for this function:

Here is the caller graph for this function:

def test.test_logging.BaseTest.next_message (   self) [inherited]
Generate a message consisting solely of an auto-incrementing
integer.

Definition at line 155 of file test_logging.py.

00155 
00156     def next_message(self):
00157         """Generate a message consisting solely of an auto-incrementing
00158         integer."""
00159         self.message_num += 1
00160         return "%d" % self.message_num
00161 

Here is the caller graph for this function:

def test.test_logging.BaseTest.setUp (   self) [inherited]
Setup the default logging stream to an internal StringIO instance,
so that we can examine log output as we want.

Reimplemented in test.test_logging.BaseFileTest, test.test_logging.QueueHandlerTest, test.test_logging.LogRecordFactoryTest, test.test_logging.MemoryTest, test.test_logging.SocketHandlerTest, test.test_logging.MemoryHandlerTest, and test.test_logging.CustomLevelsAndFiltersTest.

Definition at line 63 of file test_logging.py.

00063 
00064     def setUp(self):
00065         """Setup the default logging stream to an internal StringIO instance,
00066         so that we can examine log output as we want."""
00067         logger_dict = logging.getLogger().manager.loggerDict
00068         logging._acquireLock()
00069         try:
00070             self.saved_handlers = logging._handlers.copy()
00071             self.saved_handler_list = logging._handlerList[:]
00072             self.saved_loggers = saved_loggers = logger_dict.copy()
00073             self.saved_level_names = logging._levelNames.copy()
00074             self.logger_states = logger_states = {}
00075             for name in saved_loggers:
00076                 logger_states[name] = getattr(saved_loggers[name],
00077                                               'disabled', None)
00078         finally:
00079             logging._releaseLock()
00080 
00081         # Set two unused loggers: one non-ASCII and one Unicode.
00082         # This is to test correct operation when sorting existing
00083         # loggers in the configuration code. See issue 8201.
00084         self.logger1 = logging.getLogger("\xab\xd7\xbb")
00085         self.logger2 = logging.getLogger("\u013f\u00d6\u0047")
00086 
00087         self.root_logger = logging.getLogger("")
00088         self.original_logging_level = self.root_logger.getEffectiveLevel()
00089 
00090         self.stream = io.StringIO()
00091         self.root_logger.setLevel(logging.DEBUG)
00092         self.root_hdlr = logging.StreamHandler(self.stream)
00093         self.root_formatter = logging.Formatter(self.log_format)
00094         self.root_hdlr.setFormatter(self.root_formatter)
00095         if self.logger1.hasHandlers():
00096             hlist = self.logger1.handlers + self.root_logger.handlers
00097             raise AssertionError('Unexpected handlers: %s' % hlist)
00098         if self.logger2.hasHandlers():
00099             hlist = self.logger2.handlers + self.root_logger.handlers
00100             raise AssertionError('Unexpected handlers: %s' % hlist)
00101         self.root_logger.addHandler(self.root_hdlr)
00102         self.assertTrue(self.logger1.hasHandlers())
00103         self.assertTrue(self.logger2.hasHandlers())

Here is the call graph for this function:

Here is the caller graph for this function:

def test.test_logging.BaseTest.tearDown (   self) [inherited]
Remove our logging stream, and restore the original logging
level.

Reimplemented in test.test_logging.BaseFileTest, test.test_logging.QueueHandlerTest, test.test_logging.LogRecordFactoryTest, test.test_logging.SocketHandlerTest, and test.test_logging.MemoryHandlerTest.

Definition at line 104 of file test_logging.py.

00104 
00105     def tearDown(self):
00106         """Remove our logging stream, and restore the original logging
00107         level."""
00108         self.stream.close()
00109         self.root_logger.removeHandler(self.root_hdlr)
00110         while self.root_logger.handlers:
00111             h = self.root_logger.handlers[0]
00112             self.root_logger.removeHandler(h)
00113             h.close()
00114         self.root_logger.setLevel(self.original_logging_level)
00115         logging._acquireLock()
00116         try:
00117             logging._levelNames.clear()
00118             logging._levelNames.update(self.saved_level_names)
00119             logging._handlers.clear()
00120             logging._handlers.update(self.saved_handlers)
00121             logging._handlerList[:] = self.saved_handler_list
00122             loggerDict = logging.getLogger().manager.loggerDict
00123             loggerDict.clear()
00124             loggerDict.update(self.saved_loggers)
00125             logger_states = self.logger_states
00126             for name in self.logger_states:
00127                 if logger_states[name] is not None:
00128                     self.saved_loggers[name].disabled = logger_states[name]
00129         finally:
00130             logging._releaseLock()

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 767 of file test_logging.py.

00767 
00768     def test_config0_ok(self):
00769         # A simple config file which overrides the default settings.
00770         with captured_stdout() as output:
00771             self.apply_config(self.config0)
00772             logger = logging.getLogger()
00773             # Won't output anything
00774             logger.info(self.next_message())
00775             # Outputs a message
00776             logger.error(self.next_message())
00777             self.assert_log_lines([
00778                 ('ERROR', '2'),
00779             ], stream=output)
00780             # Original logger output is empty.
00781             self.assert_log_lines([])

Here is the call graph for this function:

Definition at line 782 of file test_logging.py.

00782 
00783     def test_config1_ok(self, config=config1):
00784         # A config file defining a sub-parser as well.
00785         with captured_stdout() as output:
00786             self.apply_config(config)
00787             logger = logging.getLogger("compiler.parser")
00788             # Both will output a message
00789             logger.info(self.next_message())
00790             logger.error(self.next_message())
00791             self.assert_log_lines([
00792                 ('INFO', '1'),
00793                 ('ERROR', '2'),
00794             ], stream=output)
00795             # Original logger output is empty.
00796             self.assert_log_lines([])

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 797 of file test_logging.py.

00797 
00798     def test_config2_failure(self):
00799         # A simple config file which overrides the default settings.
00800         self.assertRaises(Exception, self.apply_config, self.config2)

Here is the call graph for this function:

Definition at line 801 of file test_logging.py.

00801 
00802     def test_config3_failure(self):
00803         # A simple config file which overrides the default settings.
00804         self.assertRaises(Exception, self.apply_config, self.config3)

Here is the call graph for this function:

Definition at line 805 of file test_logging.py.

00805 
00806     def test_config4_ok(self):
00807         # A config file specifying a custom formatter class.
00808         with captured_stdout() as output:
00809             self.apply_config(self.config4)
00810             logger = logging.getLogger()
00811             try:
00812                 raise RuntimeError()
00813             except RuntimeError:
00814                 logging.exception("just testing")
00815             sys.stdout.seek(0)
00816             self.assertEqual(output.getvalue(),
00817                 "ERROR:root:just testing\nGot a [RuntimeError]\n")
00818             # Original logger output is empty
00819             self.assert_log_lines([])

Here is the call graph for this function:

Definition at line 820 of file test_logging.py.

00820 
00821     def test_config5_ok(self):
00822         self.test_config1_ok(config=self.config5)

Here is the call graph for this function:

Definition at line 823 of file test_logging.py.

00823 
00824     def test_config6_ok(self):
00825         self.test_config1_ok(config=self.config6)

Here is the call graph for this function:

Definition at line 826 of file test_logging.py.

00826 
00827     def test_config7_ok(self):
00828         with captured_stdout() as output:
00829             self.apply_config(self.config1a)
00830             logger = logging.getLogger("compiler.parser")
00831             # See issue #11424. compiler-hyphenated sorts
00832             # between compiler and compiler.xyz and this
00833             # was preventing compiler.xyz from being included
00834             # in the child loggers of compiler because of an
00835             # overzealous loop termination condition.
00836             hyphenated = logging.getLogger('compiler-hyphenated')
00837             # All will output a message
00838             logger.info(self.next_message())
00839             logger.error(self.next_message())
00840             hyphenated.critical(self.next_message())
00841             self.assert_log_lines([
00842                 ('INFO', '1'),
00843                 ('ERROR', '2'),
00844                 ('CRITICAL', '3'),
00845             ], stream=output)
00846             # Original logger output is empty.
00847             self.assert_log_lines([])
00848         with captured_stdout() as output:
00849             self.apply_config(self.config7)
00850             logger = logging.getLogger("compiler.parser")
00851             self.assertFalse(logger.disabled)
00852             # Both will output a message
00853             logger.info(self.next_message())
00854             logger.error(self.next_message())
00855             logger = logging.getLogger("compiler.lexer")
00856             # Both will output a message
00857             logger.info(self.next_message())
00858             logger.error(self.next_message())
00859             # Will not appear
00860             hyphenated.critical(self.next_message())
00861             self.assert_log_lines([
00862                 ('INFO', '4'),
00863                 ('ERROR', '5'),
00864                 ('INFO', '6'),
00865                 ('ERROR', '7'),
00866             ], stream=output)
00867             # Original logger output is empty.
00868             self.assert_log_lines([])

Here is the call graph for this function:


Member Data Documentation

Initial value:
"""
[loggers]
keys=root

[handlers]
keys=hand1

[formatters]
keys=form1

[logger_root]
level=WARNING
handlers=hand1

[handler_hand1]
class=StreamHandler
level=NOTSET
formatter=form1
args=(sys.stdout,)

[formatter_form1]
format=%(levelname)s ++ %(message)s
datefmt=
"""

Definition at line 558 of file test_logging.py.

Initial value:
"""
[loggers]
keys=root,parser

[handlers]
keys=hand1

[formatters]
keys=form1

[logger_root]
level=WARNING
handlers=

[logger_parser]
level=DEBUG
handlers=hand1
propagate=1
qualname=compiler.parser

[handler_hand1]
class=StreamHandler
level=NOTSET
formatter=form1
args=(sys.stdout,)

[formatter_form1]
format=%(levelname)s ++ %(message)s
datefmt=
"""

Definition at line 584 of file test_logging.py.

Initial value:
"""
[loggers]
keys=root,parser

[handlers]
keys=hand1

[formatters]
keys=form1

[logger_root]
level=WARNING
handlers=hand1

[logger_parser]
level=DEBUG
handlers=
propagate=1
qualname=compiler.parser

[handler_hand1]
class=StreamHandler
level=NOTSET
formatter=form1
args=(sys.stdout,)

[formatter_form1]
format=%(levelname)s ++ %(message)s
datefmt=
"""

Definition at line 616 of file test_logging.py.

tuple test.test_logging.ConfigFileTest.config2 = config1.replace("sys.stdout", "sys.stbout") [static]

Definition at line 648 of file test_logging.py.

tuple test.test_logging.ConfigFileTest.config3 = config1.replace("formatter=form1", "formatter=misspelled_name") [static]

Definition at line 651 of file test_logging.py.

Initial value:
"""
[loggers]
keys=root

[handlers]
keys=hand1

[formatters]
keys=form1

[logger_root]
level=NOTSET
handlers=hand1

[handler_hand1]
class=StreamHandler
level=NOTSET
formatter=form1
args=(sys.stdout,)

[formatter_form1]
class="""

Definition at line 654 of file test_logging.py.

tuple test.test_logging.ConfigFileTest.config5 = config1.replace('class=StreamHandler', 'class=logging.StreamHandler') [static]

Definition at line 681 of file test_logging.py.

Definition at line 684 of file test_logging.py.

Definition at line 726 of file test_logging.py.

string test.test_logging.ConfigFileTest.expected_log_pat = r"^([\w]+) \+\+ ([\w]+)$" [static]

Reimplemented from test.test_logging.BaseTest.

Definition at line 555 of file test_logging.py.

string test.test_logging.BaseTest.log_format = "%(name)s -> %(levelname)s: %(message)s" [static, inherited]

Definition at line 59 of file test_logging.py.

Definition at line 83 of file test_logging.py.

Definition at line 84 of file test_logging.py.

Definition at line 73 of file test_logging.py.

Definition at line 61 of file test_logging.py.

Definition at line 87 of file test_logging.py.

Definition at line 92 of file test_logging.py.

Definition at line 91 of file test_logging.py.

Definition at line 86 of file test_logging.py.

Definition at line 70 of file test_logging.py.

Definition at line 69 of file test_logging.py.

Definition at line 72 of file test_logging.py.

Definition at line 71 of file test_logging.py.

Definition at line 89 of file test_logging.py.


The documentation for this class was generated from the following file: