8000 gh-110932: Fix regrtest for SOURCE_DATE_EPOCH · vstinner/cpython@c090758 · GitHub
[go: up one dir, main page]

Skip to content

Commit c090758

Browse files
committed
pythongh-110932: Fix regrtest for SOURCE_DATE_EPOCH
If the SOURCE_DATE_EPOCH environment variable is defined, use its value as a string as the random seed.
1 parent 5dfa717 commit c090758

File tree

4 files changed

+63
-19
lines changed

4 files changed

+63
-19
lines changed

Lib/test/libregrtest/main.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,16 @@ def __init__(self, ns: Namespace, _add_python_opts: bool = False):
129129

130130
# Randomize
131131
self.randomize: bool = ns.randomize
132-
self.random_seed: int | None = (
133-
ns.random_seed
134-
if ns.random_seed is not None
135-
else random.getrandbits(32)
136-
)
137132
if 'SOURCE_DATE_EPOCH' in os.environ:
138133
self.randomize = False
139-
self.random_seed = None
134+
# SOURCE_DATE_EPOCH should be an integer, but use a string to not
135+
# fail if it's not integer. random.seed() accepts a string.
136+
# https://reproducible-builds.org/docs/source-date-epoch/
137+
self.random_seed: int | str = os.environ['SOURCE_DATE_EPOCH']
138+
elif ns.random_seed is None:
139+
self.random_seed = random.getrandbits(32)
140+
else:
141+
self.random_seed = ns.random_seed
140142

141143
# tests
142144
self.first_runtests: RunTests | None = None
@@ -441,7 +443,7 @@ def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
441443
or tests or self.cmdline_args)):
442444
display_header(self.use_resources, self.python_cmd)
443445

444-
print("Using random seed", self.random_seed)
446+
print("Using random seed:", self.random_seed)
445447

446448
runtests = self.create_run_tests(selected)
447449
self.first_runtests = runtests

Lib/test/libregrtest/runtests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class RunTests:
9191
use_resources: tuple[str, ...]
9292
python_cmd: tuple[str, ...] | None
9393
randomize: bool
94-
random_seed: int | None
94+
random_seed: int | str
9595
json_file: JsonFile | None
9696

9797
def copy(self, **override):

Lib/test/test_regrtest.py

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,12 @@ def test_randomize(self):
149149
self.assertTrue(ns.randomize)
150150

151151
with os_helper.EnvironmentVarGuard() as env:
152-
env['SOURCE_DATE_EPOCH'] = '1'
152+
env['SOURCE_DATE_EPOCH'] = '1697839080'
153153

154154
ns = self.parse_args(['--randomize'])
155155
regrtest = main.Regrtest(ns)
156156
self.assertFalse(regrtest.randomize)
157-
self.assertIsNone(regrtest.random_seed)
157+
self.assertEqual(regrtest.random_seed, '1697839080')
158158

159159
def test_randseed(self):
160160
ns = self.parse_args(['--randseed', '12345'])
@@ -388,7 +388,13 @@ def check_ci_mode(self, args, use_resources, rerun=True):
388388

389389
# Check Regrtest attributes which are more reliable than Namespace
390390
# which has an unclear API
391-
regrtest = main.Regrtest(ns)
391+
with os_helper.EnvironmentVarGuard() as env:
392+
# Ignore SOURCE_DATE_EPOCH env var if it's set
393+
if 'SOURCE_DATE_EPOCH' in env:
394+
del env['SOURCE_DATE_EPOCH']
395+
396+
regrtest = main.Regrtest(ns)
397+
392398
self.assertEqual(regrtest.num_workers, -1)
393399
self.assertEqual(regrtest.want_rerun, rerun)
394400
self.assertTrue(regrtest.randomize)
@@ -661,21 +667,26 @@ def list_regex(line_format, tests):
661667
state = f'{state} then {new_state}'
662668
self.check_line(output, f'Result: {state}', full=True)
663669

664-
def parse_random_seed(self, output):
665-
match = self.regex_search(r'Using random seed ([0-9]+)', output)
666-
randseed = int(match.group(1))
667-
self.assertTrue(0 <= randseed, randseed)
668-
return randseed
670+
def parse_random_seed(self, output: str) -> str:
671+
match = self.regex_search(r'Using random seed: (.*)', output)
672+
return match.group(1)
669673

670674
def run_command(self, args, input=None, exitcode=0, **kw):
671675
if not input:
672676
input = ''
673677
if 'stderr' not in kw:
674678
kw['stderr'] = subprocess.STDOUT
679+
680+
env = kw.pop('env', None)
681+
if env is None:
682+
env = dict(os.environ)
683+
env.pop('SOURCE_DATE_EPOCH', None)
684+
675685
proc = subprocess.run(args,
676686
text=True,
677687
input=input,
678688
stdout=subprocess.PIPE,
689+
env=env,
679690
**kw)
680691
if proc.returncode != exitcode:
681692
msg = ("Command %s failed with exit code %s, but exit code %s expected!\n"
@@ -751,7 +762,9 @@ def setUp(self):
751762
self.regrtest_args.append('-n')
752763

753764
def check_output(self, output):
754-
self.parse_random_seed(output)
765+
randseed = self.parse_random_seed(output)
766+
self.assertTrue(randseed.isdigit(), randseed)
767+
755768
self.check_executed_tests(output, self.tests,
756769
randomize=True, stats=len(self.tests))
757770

@@ -942,7 +955,7 @@ def test_random(self):
942955
test_random = int(match.group(1))
943956

944957
# try to reproduce with the random seed
945-
output = self.run_tests('-r', '--randseed=%s' % randseed, test,
958+
output = self.run_tests('-r', f'--randseed={randseed}', test,
946959
exitcode=EXITCODE_NO_TESTS_RAN)
947960
randseed2 = self.parse_random_seed(output)
948961
self.assertEqual(randseed2, randseed)
@@ -953,7 +966,33 @@ def test_random(self):
953966

954967
# check that random.seed is used by default
955968
output = self.run_tests(test, exitcode=EXITCODE_NO_TESTS_RAN)
956-
self.assertIsInstance(self.parse_random_seed(output), int)
969+
randseed = self.parse_random_seed(output)
970+
self.assertTrue(randseed.isdigit(), randseed)
971+
972+
# check SOURCE_DATE_EPOCH (integer)
973+
timestamp = '1697839080'
974+
env = dict(os.environ, SOURCE_DATE_EPOCH=timestamp)
975+
output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN,
976+
env=env)
977+
randseed = self.parse_random_seed(output)
978+
self.assertEqual(randseed, timestamp)
979+
self.check_line(output, 'TESTRANDOM: 520')
980+
981+
# check SOURCE_DATE_EPOCH (string)
982+
env = dict(os.environ, SOURCE_DATE_EPOCH='XYZ')
983+
output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN,
984+
env=env)
985+
randseed = self.parse_random_seed(output)
986+
self.assertEqual(randseed, 'XYZ')
987+
self.check_line(output, 'TESTRANDOM: 22')
988+
989+
# check SOURCE_DATE_EPOCH (empty string)
990+
env = dict(os.environ, SOURCE_DATE_EPOCH='')
991+
output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN,
992+
env=env)
993+
randseed = self.parse_random_seed(output)
994+
self.assertEqual(randseed, '')
995+
self.check_line(output, 'TESTRANDOM: 984')
957996

958997
def test_fromfile(self):
959998
# test --fromfile
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix regrtest if the ``SOURCE_DATE_EPOCH`` environment variable is defined:
2+
use the variable value as a string as the random seed. Patch by Victor
3+
Stinner.

0 commit comments

Comments
 (0)
0