Coverage for tests/test_logging.py: 12%

85 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-01-10 02:25 -0800

1# This file is part of utils. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# Use of this source code is governed by a 3-clause BSD-style 

10# license that can be found in the LICENSE file. 

11 

12"""Simple unit test for Task logging. 

13""" 

14 

15import logging 

16import time 

17import unittest 

18 

19from lsst.utils.logging import PeriodicLogger, getLogger, trace_set_at 

20 

21 

22class TestLogging(unittest.TestCase): 

23 def testLogLevels(self): 

24 """Check that the new log levels look reasonable.""" 

25 

26 root = getLogger() 

27 

28 self.assertEqual(root.DEBUG, logging.DEBUG) 

29 self.assertGreater(root.VERBOSE, logging.DEBUG) 

30 self.assertLess(root.VERBOSE, logging.INFO) 

31 self.assertLess(root.TRACE, logging.DEBUG) 

32 

33 def testLogCommands(self): 

34 """Check that all the log commands work.""" 

35 

36 root = getLogger() 

37 

38 with self.assertLogs(level=root.TRACE) as cm: 

39 root.trace("Trace") 

40 root.debug("Debug") 

41 root.verbose("Verbose") 

42 root.info("Info") 

43 root.warning("Warning") 

44 root.fatal("Fatal") 

45 root.critical("Critical") 

46 root.error("Error") 

47 

48 self.assertEqual(len(cm.records), 8) 

49 

50 # Check that each record has an explicit level name rather than 

51 # "Level N" and comes from this file (and not the logging.py). 

52 for record in cm.records: 

53 self.assertRegex(record.levelname, "^[A-Z]+$") 

54 self.assertEqual(record.filename, "test_logging.py") 

55 

56 with self.assertLogs(level=root.DEBUG) as cm: 

57 # Should only issue the INFO message. 

58 with root.temporary_log_level(root.INFO): 

59 root.info("Info") 

60 root.debug("Debug") 

61 self.assertEqual(len(cm.records), 1) 

62 

63 child = root.getChild("child") 

64 self.assertEqual(child.getEffectiveLevel(), root.getEffectiveLevel()) 

65 child.setLevel(root.DEBUG) 

66 self.assertNotEqual(child.getEffectiveLevel(), root.getEffectiveLevel()) 

67 

68 def testTraceSetAt(self): 

69 log_name = "lsst.afw" 

70 trace_set_at(log_name, 2) 

71 trace2_log = getLogger(f"TRACE2.{log_name}") 

72 trace3_log = getLogger(f"TRACE3.{log_name}") 

73 self.assertEqual(trace2_log.getEffectiveLevel(), logging.DEBUG) 

74 self.assertEqual(trace3_log.getEffectiveLevel(), logging.INFO) 

75 

76 # Check that child loggers are affected. 

77 log_name = "lsst.daf" 

78 child3_log = getLogger("TRACE3.lsst.daf") 

79 child2_log = getLogger("TRACE2.lsst.daf") 

80 self.assertEqual(child3_log.getEffectiveLevel(), logging.WARNING) 

81 self.assertEqual(child2_log.getEffectiveLevel(), logging.WARNING) 

82 trace_set_at("lsst", 2) 

83 self.assertEqual(child3_log.getEffectiveLevel(), logging.INFO) 

84 self.assertEqual(child2_log.getEffectiveLevel(), logging.DEBUG) 

85 

86 # Also check the root logger. 

87 trace_set_at("", 3) 

88 self.assertEqual(trace3_log.getEffectiveLevel(), logging.INFO) 

89 self.assertEqual(getLogger("TRACE3.test").getEffectiveLevel(), logging.DEBUG) 

90 

91 def test_periodic(self): 

92 logger = getLogger("test.periodicity") 

93 periodic = PeriodicLogger(logger) 

94 

95 # First message will not be issued. 

96 periodic.log("Message") 

97 self.assertEqual(periodic.num_issued, 0) 

98 

99 # Create a new periodic logger with no delay. 

100 # Every message should be issued. 

101 periodic = PeriodicLogger(logger, interval=0.0) 

102 with self.assertLogs(logger.name, level=logger.VERBOSE) as cm: 

103 periodic.log("Message") 

104 periodic.log("Message %d", 1) 

105 self.assertEqual(len(cm.output), 2) 

106 self.assertEqual(periodic.num_issued, 2) 

107 self.assertEqual(cm.output[0], f"VERBOSE:{logger.name}:Message") 

108 self.assertEqual(cm.output[1], f"VERBOSE:{logger.name}:Message 1") 

109 self.assertEqual(cm.records[0].filename, "test_logging.py", str(cm.records[0])) 

110 

111 # Create a new periodic logger with small delay. 

112 # One message should be issued. 

113 periodic = PeriodicLogger(logger, interval=0.2, level=logger.INFO) 

114 with self.assertLogs(logger.name, level=logger.INFO) as cm: 

115 periodic.log("Message") 

116 time.sleep(0.5) 

117 issued = periodic.log("Message %d", 1) 

118 self.assertTrue(issued) 

119 issued = periodic.log("Message %d", 2) 

120 self.assertFalse(issued) 

121 self.assertEqual(periodic.num_issued, 1) 

122 self.assertEqual(cm.output[0], f"INFO:{logger.name}:Message 1") 

123 

124 # Again with a standard python Logger. 

125 pylog = logging.getLogger("python.logger") 

126 periodic = PeriodicLogger(pylog, interval=0.0, level=logging.DEBUG) 

127 with self.assertLogs(pylog.name, level=logging.DEBUG) as cm: 

128 periodic.log("Message") 

129 self.assertEqual(cm.records[0].filename, "test_logging.py", str(cm.records[0])) 

130 

131 

132if __name__ == "__main__": 132 ↛ 133line 132 didn't jump to line 133, because the condition on line 132 was never true

133 unittest.main()