Skip to content

Commit ae05792

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 ae05792

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
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: 26 additions & 4 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)
@@ -662,7 +668,7 @@ def list_regex(line_format, tests):
662668
self.check_line(output, f'Result: {state}', full=True)
663669

664670
def parse_random_seed(self, output):
665-
match = self.regex_search(r'Using random seed ([0-9]+)', output)
671+
match = self.regex_search(r'Using random seed: ([0-9]+)', output)
666672
randseed = int(match.group(1))
667673
self.assertTrue(0 <= randseed, randseed)
668674
return randseed
@@ -672,10 +678,17 @@ def run_command(self, args, input=None, exitcode=0, **kw):
672678
input = ''
673679
if 'stderr' not in kw:
674680
kw['stderr'] = subprocess.STDOUT
681+
682+
env = kw.pop('env', None)
683+
if env is None:
684+
env = dict(os.environ)
685+
env.pop('SOURCE_DATE_EPOCH', None)
686+
675687
proc = subprocess.run(args,
676688
text=True,
677689
input=input,
678690
stdout=subprocess.PIPE,
691+
env=env,
679692
**kw)
680693
if proc.returncode != exitcode:
681694
msg = ("Command %s failed with exit code %s, but exit code %s expected!\n"
@@ -955,6 +968,15 @@ def test_random(self):
955968
output = self.run_tests(test, exitcode=EXITCODE_NO_TESTS_RAN)
956969
self.assertIsInstance(self.parse_random_seed(output), int)
957970

971+
# check SOURCE_DATE_EPOCH
972+
timestamp = 1697839080
973+
env = dict(os.environ, SOURCE_DATE_EPOCH=str(timestamp))
974+
output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN,
975+
env=env)
976+
randseed = self.parse_random_seed(output)
977+
self.assertEqual(randseed, timestamp)
978+
self.check_line(output, 'TESTRANDOM: 520')
979+
958980
def test_fromfile(self):
959981
# test --fromfile
960982
tests = [self.create_test() for index in range(5)]
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)