@@ -6737,6 +6737,75 @@ def test_rollover_at_midnight(self, weekly=False):
67376737 def test_rollover_at_weekday(self):
67386738 self.test_rollover_at_midnight(weekly=True)
67396739
6740+ def _make_fake_time_handler(self, now, when='S', **kwargs):
6741+ dirname = tempfile.mkdtemp()
6742+ self.addCleanup(os_helper.rmtree, dirname)
6743+ fn = os.path.join(dirname, 'test.log')
6744+ with patch('time.time', lambda: now[0]):
6745+ fh = logging.handlers.TimedRotatingFileHandler(
6746+ fn, when=when, encoding='utf-8', delay=True, **kwargs)
6747+ self.addCleanup(fh.close)
6748+ return fh
6749+
6750+ def test_rollover_after_failed_rollover(self):
6751+ for target in 'os.remove', '_open':
6752+ with self.subTest(target=target):
6753+ now = [1_000_000_000]
6754+ fh = self._make_fake_time_handler(now, backupCount=1)
6755+ fn = fh.baseFilename
6756+ emit = lambda msg: fh.emit(logging.makeLogRecord({'msg': msg}))
6757+ with patch('time.time', lambda: now[0]):
6758+ for msg in 'a', 'b':
6759+ now[0] += 2
6760+ emit(msg)
6761+ now[0] += 2
6762+ if target == '_open':
6763+ failure = patch.object(fh, '_open', side_effect=OSError)
6764+ fh.delay = False
6765+ else:
6766+ failure = patch('os.remove', side_effect=OSError)
6767+ with failure as failed, support.captured_stderr():
6768+ emit('c')
6769+ failed.assert_called_once()
6770+ self.assertGreater(fh.rolloverAt, now[0])
6771+ fh.delay = True
6772+ for msg in 'd', 'e':
6773+ now[0] += 2
6774+ emit(msg)
6775+ fh.close()
6776+ with open(fn, encoding='utf-8') as f:
6777+ self.assertEqual(f.read(), 'e\n')
6778+ backups = [f for f in os.listdir(os.path.dirname(fn))
6779+ if f != 'test.log']
6780+ self.assertEqual(len(backups), 1)
6781+
6782+ def test_rollover_existing_backup(self):
6783+ now = [1_000_000_000]
6784+ fh = self._make_fake_time_handler(now)
6785+ fn = fh.baseFilename
6786+ with patch('time.time', lambda: now[0]):
6787+ fh.emit(logging.makeLogRecord({'msg': 'a'}))
6788+ t = fh.rolloverAt - fh.interval
6789+ dfn = fh.rotation_filename(
6790+ fn + '.' + time.strftime(fh.suffix, time.localtime(t)))
6791+ with open(dfn, 'w', encoding='utf-8') as f:
6792+ f.write('existing\n')
6793+ now[0] += 2
6794+ fh.emit(logging.makeLogRecord({'msg': 'b'}))
6795+ self.assertGreater(fh.rolloverAt, now[0])
6796+ t = fh.rolloverAt - fh.interval
6797+ next_dfn = fh.rotation_filename(
6798+ fn + '.' + time.strftime(fh.suffix, time.localtime(t)))
6799+ now[0] += 2
6800+ fh.emit(logging.makeLogRecord({'msg': 'c'}))
6801+ fh.close()
6802+ with open(dfn, encoding='utf-8') as f:
6803+ self.assertEqual(f.read(), 'existing\n')
6804+ with open(next_dfn, encoding='utf-8') as f:
6805+ self.assertEqual(f.read(), 'a\nb\n')
6806+ with open(fn, encoding='utf-8') as f:
6807+ self.assertEqual(f.read(), 'c\n')
6808+
67406809 def test_invalid(self):
67416810 assertRaises = self.assertRaises
67426811 assertRaises(ValueError, logging.handlers.TimedRotatingFileHandler,
0 commit comments