Skip to content

Commit b70f085

Browse files
authored
Merge pull request #3816 from grossag/topic/grossag/testrace
Fix occasional test failures when running multiple jobs
2 parents fb03ae9 + 01ac999 commit b70f085

File tree

2 files changed

+25
-14
lines changed

2 files changed

+25
-14
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
3333
From Adam Gross:
3434
- Fix minor bug affecting SCons.Node.FS.File.get_csig()'s usage of the MD5 chunksize.
3535
User-facing behavior does not change with this fix (GH Issue #3726).
36+
- Fix occasional test failures caused by not being able to find a file or directory fixture
37+
when running multiple tests with multiple jobs.
3638

3739
From Joachim Kuebart:
3840
- Suppress missing SConscript deprecation warning if `must_exist=False`

runtest.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,8 @@ def escape(s):
293293
if not catch_output:
294294
# Without any output suppressed, we let the subprocess
295295
# write its stuff freely to stdout/stderr.
296-
def spawn_it(command_args):
297-
cp = subprocess.run(command_args, shell=False)
296+
def spawn_it(command_args, env):
297+
cp = subprocess.run(command_args, shell=False, env=env)
298298
return cp.stdout, cp.stderr, cp.returncode
299299
else:
300300
# Else, we catch the output of both pipes...
@@ -310,15 +310,16 @@ def spawn_it(command_args):
310310
# http://http://thraxil.org/users/anders/posts/2008/03/13/Subprocess-Hanging-PIPE-is-your-enemy/
311311
# and pass temp file objects to Popen() instead of the ubiquitous
312312
# subprocess.PIPE.
313-
def spawn_it(command_args):
313+
def spawn_it(command_args, env):
314314
# Create temporary files
315315
tmp_stdout = tempfile.TemporaryFile(mode='w+t')
316316
tmp_stderr = tempfile.TemporaryFile(mode='w+t')
317317
# Start subprocess...
318318
cp = subprocess.run(command_args,
319319
stdout=tmp_stdout,
320320
stderr=tmp_stderr,
321-
shell=False)
321+
shell=False,
322+
env=env)
322323

323324
try:
324325
# Rewind to start of files
@@ -348,11 +349,12 @@ def spawn_it(command_args):
348349
# (but the subprocess isn't writing anything there).
349350
# Hence a deadlock.
350351
# Be dragons here! Better don't use this!
351-
def spawn_it(command_args):
352+
def spawn_it(command_args, env):
352353
cp = subprocess.run(command_args,
353354
stdout=subprocess.PIPE,
354355
stderr=subprocess.PIPE,
355-
shell=False)
356+
shell=False,
357+
env=env)
356358
return cp.stdout, cp.stderr, cp.returncode
357359

358360

@@ -380,8 +382,8 @@ def execute(self):
380382

381383
class SystemExecutor(RuntestBase):
382384
""" Test class for tests executed with spawn_it() """
383-
def execute(self):
384-
self.stderr, self.stdout, s = spawn_it(self.command_args)
385+
def execute(self, env):
386+
self.stderr, self.stdout, s = spawn_it(self.command_args, env)
385387
self.status = s
386388
if s < 0 or s > 2:
387389
sys.stdout.write("Unexpected exit status %d\n" % s)
@@ -400,15 +402,16 @@ class PopenExecutor(RuntestBase):
400402
# and the 'allow_pipe_files' option, please check out the
401403
# definition of spawn_it() above.
402404
if allow_pipe_files:
403-
def execute(self):
405+
def execute(self, env):
404406
# Create temporary files
405407
tmp_stdout = tempfile.TemporaryFile(mode='w+t')
406408
tmp_stderr = tempfile.TemporaryFile(mode='w+t')
407409
# Start subprocess...
408410
cp = subprocess.run(self.command_str.split(),
409411
stdout=tmp_stdout,
410412
stderr=tmp_stderr,
411-
shell=False)
413+
shell=False,
414+
env=env)
412415
self.status = cp.returncode
413416

414417
try:
@@ -423,11 +426,12 @@ def execute(self):
423426
tmp_stdout.close()
424427
tmp_stderr.close()
425428
else:
426-
def execute(self):
429+
def execute(self, env):
427430
cp = subprocess.run(self.command_str.split(),
428431
stdout=subprocess.PIPE,
429432
stderr=subprocess.PIPE,
430-
shell=False)
433+
shell=False,
434+
env=env)
431435
self.status = cp.returncode
432436
self.stdout = cp.stdout
433437
self.stderr = cp.stderr
@@ -756,11 +760,16 @@ def run_test(t, io_lock=None, run_async=True):
756760
if head:
757761
fixture_dirs.append(head)
758762
fixture_dirs.append(os.path.join(scriptpath, 'test', 'fixture'))
759-
os.environ['FIXTURE_DIRS'] = os.pathsep.join(fixture_dirs)
763+
764+
# Set the list of fixture dirs directly in the environment. Just putting
765+
# it in os.environ and spawning the process is racy. Make it reliable by
766+
# overriding the environment passed to execute().
767+
env = dict(os.environ)
768+
env['FIXTURE_DIRS'] = os.pathsep.join(fixture_dirs)
760769

761770
test_start_time = time_func()
762771
if execute_tests:
763-
t.execute()
772+
t.execute(env)
764773

765774
t.test_time = time_func() - test_start_time
766775
log_result(t, io_lock=io_lock)

0 commit comments

Comments
 (0)