comparison test/test_config.py @ 8447:d06be9346c68

bug, test: fix tests for trace_id; readd import logging.config Made save_restore_logging a test level fixture. It was a class level which worked fine until I started using caplog for tests in the same class. Due to loading config from dict, the roundup channel was set to not propagate which broke the new formatting test used for trace_id. Forgot to update some tests due to change in default format adding %(trace_id). Also re-added logging.config import which broke loading logging config files in configuration.py.
author John Rouillard <rouilj@ieee.org>
date Wed, 17 Sep 2025 00:45:04 -0400
parents 14c7c07b32d8
children 401c6f0be6c5
comparison
equal deleted inserted replaced
8446:14c7c07b32d8 8447:d06be9346c68
420 420
421 @pytest.fixture(autouse=True) 421 @pytest.fixture(autouse=True)
422 def inject_fixtures(self, caplog): 422 def inject_fixtures(self, caplog):
423 self._caplog = caplog 423 self._caplog = caplog
424 424
425 @pytest.fixture(scope="class") 425 @pytest.fixture(autouse=True)
426 def save_restore_logging(self): 426 def save_restore_logging(self):
427 """Save logger state and try to restore it after all tests in 427 """Save logger state and try to restore it after all tests in
428 this class have finished. 428 this class have finished.
429 429
430 The primary test is testDictLoggerConfigViaJson which 430 The primary test is testDictLoggerConfigViaJson which
459 if name.startswith("roundup")] 459 if name.startswith("roundup")]
460 460
461 # cribbed from configuration.py:init_loggers 461 # cribbed from configuration.py:init_loggers
462 hdlr = logging.StreamHandler(sys.stdout) 462 hdlr = logging.StreamHandler(sys.stdout)
463 formatter = logging.Formatter( 463 formatter = logging.Formatter(
464 '%(asctime)s %(levelname)s %(message)s') 464 '%(asctime)s %(trace_id)s %(levelname)s %(message)s')
465 hdlr.setFormatter(formatter) 465 hdlr.setFormatter(formatter)
466 466
467 for logger in roundup_loggers: 467 for logger in roundup_loggers:
468 # no logging API to remove all existing handlers!?! 468 # no logging API to remove all existing handlers!?!
469 for h in logger.handlers: 469 for h in logger.handlers:
1017 """Depends on using default logging format with %(trace_id)""" 1017 """Depends on using default logging format with %(trace_id)"""
1018 1018
1019 def find_file_occurances(string): 1019 def find_file_occurances(string):
1020 return len(re.findall(r'\bFile\b', string)) 1020 return len(re.findall(r'\bFile\b', string))
1021 1021
1022 config = configuration.CoreConfig() 1022 config = configuration.CoreConfig(settings={"LOGGING_LEVEL": "DEBUG"})
1023
1024 config.LOGGING_LEVEL = "DEBUG"
1025 config.init_logging()
1026
1027 1023
1028 # format the record and verify the logformat/trace_id. 1024 # format the record and verify the logformat/trace_id.
1029 config._logging_test(None, msg="message") 1025 config._logging_test(None, msg="message")
1030 tuple = self._caplog.record_tuples[0] 1026 tuple = self._caplog.record_tuples[0]
1031 self.assertEqual(tuple[1], 20) 1027 self.assertEqual(tuple[1], 20)
1034 hdlr = logger.handlers[0] 1030 hdlr = logger.handlers[0]
1035 log = hdlr.format(self._caplog.records[0]) 1031 log = hdlr.format(self._caplog.records[0])
1036 # verify that %(trace_id) was set and substituted 1032 # verify that %(trace_id) was set and substituted
1037 # Note: trace_id is not initialized in this test case 1033 # Note: trace_id is not initialized in this test case
1038 log_parts = log.split() 1034 log_parts = log.split()
1039 self.assertRegex(log_parts[2], r'^[A-Za-z0-9]{22}') 1035 # testing len(shorten_int_uuid(uuid.uuid4().int))
1036 # for 20000 tests gives range [19,22]
1037 self.assertRegex(log_parts[2], r'^[A-Za-z0-9]{19,22}')
1040 self._caplog.clear() 1038 self._caplog.clear()
1041 1039
1042 # the rest check various values of sinfo and msg formating. 1040 # the rest check various values of sinfo and msg formating.
1043 1041
1044 # sinfo = 1 - one line of stack starting with log call 1042 # sinfo = 1 - one line of stack starting with log call
1248 def testLoggerFormat(self): 1246 def testLoggerFormat(self):
1249 config = configuration.CoreConfig() 1247 config = configuration.CoreConfig()
1250 1248
1251 # verify config is initalized to defaults 1249 # verify config is initalized to defaults
1252 self.assertEqual(config['LOGGING_FORMAT'], 1250 self.assertEqual(config['LOGGING_FORMAT'],
1253 '%(asctime)s %(levelname)s %(message)s') 1251 '%(asctime)s %(trace_id)s %(levelname)s %(message)s')
1254 1252
1255 # load config 1253 # load config
1256 config.load(self.dirname) 1254 config.load(self.dirname)
1257 self.assertEqual(config['LOGGING_FORMAT'], 1255 self.assertEqual(config['LOGGING_FORMAT'],
1258 '%(asctime)s %(levelname)s %(message)s') 1256 '%(asctime)s %(trace_id)s %(levelname)s %(message)s')
1259 1257
1260 # break config using an incomplete format specifier (no trailing 's') 1258 # break config using an incomplete format specifier (no trailing 's')
1261 self.munge_configini(mods=[ ("format = ", "%%(asctime)s %%(levelname) %%(message)s") ], section="[logging]") 1259 self.munge_configini(mods=[ ("format = ", "%%(asctime)s %%(trace_id)s %%(levelname) %%(message)s") ], section="[logging]")
1262 1260
1263 # load config 1261 # load config
1264 with self.assertRaises(configuration.OptionValueError) as cm: 1262 with self.assertRaises(configuration.OptionValueError) as cm:
1265 config.load(self.dirname) 1263 config.load(self.dirname)
1266 1264
1267 self.assertIn('Unrecognized use of %(...) in: %(levelname)', 1265 self.assertIn('Unrecognized use of %(...) in: %(levelname)',
1268 cm.exception.args[2]) 1266 cm.exception.args[2])
1269 1267
1270 # break config by not dubling % sign to quote it from configparser 1268 # break config by not doubling % sign to quote it from configparser
1271 self.munge_configini(mods=[ ("format = ", "%(asctime)s %%(levelname) %%(message)s") ], section="[logging]") 1269 self.munge_configini(mods=[ ("format = ", "%(asctime)s %%(trace_id)s %%(levelname) %%(message)s") ], section="[logging]")
1272 1270
1273 with self.assertRaises( 1271 with self.assertRaises(
1274 configuration.ParsingOptionError) as cm: 1272 configuration.ParsingOptionError) as cm:
1275 config.load(self.dirname) 1273 config.load(self.dirname)
1276 1274
1277 self.assertEqual(cm.exception.args[0], 1275 self.assertEqual(cm.exception.args[0],
1278 "Error in _test_instance/config.ini with section " 1276 "Error in _test_instance/config.ini with section "
1279 "[logging] at option format: Bad value substitution: " 1277 "[logging] at option format: Bad value substitution: "
1280 "option 'format' in section 'logging' contains an " 1278 "option 'format' in section 'logging' contains an "
1281 "interpolation key 'asctime' which is not a valid " 1279 "interpolation key 'asctime' which is not a valid "
1282 "option name. Raw value: '%(asctime)s %%(levelname) " 1280 "option name. Raw value: '%(asctime)s %%(trace_id)s "
1283 "%%(message)s'") 1281 "%%(levelname) %%(message)s'")
1284 1282
1285 def testDictLoggerConfigViaJson(self): 1283 def testDictLoggerConfigViaJson(self):
1286 1284
1287 # good base test case 1285 # good base test case
1288 config1 = dedent(""" 1286 config1 = dedent("""

Roundup Issue Tracker: http://roundup-tracker.org/