Skip to content

Commit f8c3413

Browse files
author
Vasileios Karakasis
committed
Work around Python 3.6/3.7 inconsistency in treating unknown format directives
- Add unit tests for testing the formatting of `check_job_completion_time`. - Minor refactoring in logging unit tests
1 parent 688155b commit f8c3413

File tree

2 files changed

+30
-11
lines changed

2 files changed

+30
-11
lines changed

reframe/core/logging.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
import numbers
66
import os
77
import pprint
8+
import re
89
import shutil
910
import sys
1011
import socket
1112
import time
12-
from datetime import datetime
1313

1414
import reframe
1515
import reframe.utility.color as color
@@ -136,7 +136,9 @@ def close(self):
136136
def _format_time_rfc3339(timestamp, datefmt):
137137
tz_suffix = time.strftime('%z', timestamp)
138138
tz_rfc3339 = tz_suffix[:-2] + ':' + tz_suffix[-2:]
139-
return time.strftime(datefmt, timestamp).replace('%:z', tz_rfc3339)
139+
140+
# Python < 3.7 truncates the `%`, whereas later versions don't
141+
return re.sub(r'(%)?\:z', tz_rfc3339, time.strftime(datefmt, timestamp))
140142

141143

142144
class RFC3339Formatter(logging.Formatter):
@@ -207,8 +209,7 @@ def _create_file_handler(handler_config):
207209
timestamp = handler_config.get('timestamp', None)
208210
if timestamp:
209211
basename, ext = os.path.splitext(filename)
210-
filename = '%s_%s%s' % (basename,
211-
datetime.now().strftime(timestamp), ext)
212+
filename = '%s_%s%s' % (basename, time.strftime(timestamp), ext)
212213

213214
append = handler_config.get('append', False)
214215
return logging.handlers.RotatingFileHandler(filename,

unittests/test_logging.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,32 @@
44
import sys
55
import re
66
import tempfile
7+
import time
78
import unittest
89
from datetime import datetime
910

1011
import reframe as rfm
1112
import reframe.core.logging as rlog
1213
from reframe.core.exceptions import ConfigError, ReframeError
14+
from reframe.core.launchers.registry import getlauncher
15+
from reframe.core.schedulers import Job
16+
from reframe.core.schedulers.registry import getscheduler
1317

1418

15-
class RandomCheck(rfm.RegressionTest):
19+
class _FakeCheck(rfm.RegressionTest):
1620
pass
1721

1822

23+
def _setup_fake_check():
24+
# A bit hacky, but we don't want to run a full test every time
25+
test = _FakeCheck()
26+
test._job = Job.create(getscheduler('local')(),
27+
getlauncher('local')(),
28+
'fakejob')
29+
test.job._completion_time = time.time()
30+
return test
31+
32+
1933
class TestLogger(unittest.TestCase):
2034
def setUp(self):
2135
tmpfd, self.logfile = tempfile.mkstemp()
@@ -34,7 +48,8 @@ def setUp(self):
3448
self.logger_without_check = rlog.LoggerAdapter(self.logger)
3549

3650
# Logger adapter with an associated check
37-
self.logger_with_check = rlog.LoggerAdapter(self.logger, RandomCheck())
51+
self.logger_with_check = rlog.LoggerAdapter(self.logger,
52+
_setup_fake_check())
3853

3954
def tearDown(self):
4055
os.remove(self.logfile)
@@ -66,7 +81,7 @@ def test_check_logger(self):
6681
self.assertTrue(os.path.exists(self.logfile))
6782
self.assertTrue(self.found_in_logfile('info'))
6883
self.assertTrue(self.found_in_logfile('verbose'))
69-
self.assertTrue(self.found_in_logfile('RandomCheck'))
84+
self.assertTrue(self.found_in_logfile('_FakeCheck'))
7085

7186
def test_handler_types(self):
7287
self.assertTrue(issubclass(logging.Handler, rlog.Handler))
@@ -100,12 +115,15 @@ def test_logger_levels(self):
100115

101116
def test_rfc3339_timezone_extension(self):
102117
self.formatter = rlog.RFC3339Formatter(
103-
fmt='[%(asctime)s] %(levelname)s: %(check_name)s: %(message)s',
118+
fmt=('[%(asctime)s] %(levelname)s: %(check_name)s: '
119+
'ct:%(check_job_completion_time)s: %(message)s'),
104120
datefmt='%FT%T%:z')
105121
self.handler.setFormatter(self.formatter)
122+
self.logger_with_check.info('foo')
106123
self.logger_without_check.info('foo')
107124
assert not self.found_in_logfile(r'%%:z')
108-
assert self.found_in_logfile(r'(\+|-)\d\d:\d\d')
125+
assert self.found_in_logfile(r'\[.+(\+|-)\d\d:\d\d\]')
126+
assert self.found_in_logfile(r'ct:.+(\+|-)\d\d:\d\d')
109127

110128
def test_rfc3339_timezone_wrong_directive(self):
111129
self.formatter = rlog.RFC3339Formatter(
@@ -134,7 +152,7 @@ def setUp(self):
134152
}
135153
]
136154
}
137-
self.check = RandomCheck()
155+
self.check = _FakeCheck()
138156

139157
def tearDown(self):
140158
if os.path.exists(self.logfile):
@@ -421,7 +439,7 @@ def test_logging_context_check(self):
421439

422440
rlog.getlogger().error('error outside context')
423441
self.assertTrue(self.found_in_logfile(
424-
'RandomCheck: %s: error from context' % sys.argv[0]))
442+
'_FakeCheck: %s: error from context' % sys.argv[0]))
425443
self.assertTrue(self.found_in_logfile(
426444
'reframe: %s: error outside context' % sys.argv[0]))
427445

0 commit comments

Comments
 (0)