From 5e8d5ee7d755edc84118464197d570bdd7c31434 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Tue, 12 Jun 2018 13:43:33 +0100 Subject: [PATCH 1/4] Fix race condition in `Lib/test/test_posix.py:TestPosixSpawn.test_open_file` --- Lib/test/test_posix.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 4f6abc6f7d6fd93..060ae92f32a1347 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1529,6 +1529,7 @@ def test_open_file(self): script = """if 1: import sys sys.stdout.write("hello") + sys.stdout.flush() """ file_actions = [ (os.POSIX_SPAWN_OPEN, 1, outfile, @@ -1539,6 +1540,12 @@ def test_open_file(self): [sys.executable, '-c', script], os.environ, file_actions) self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + + max_tries = 3 + while not os.path.exists(outfile) and max_tries: + max_tries -= 1 + time.sleep(0.1) + with open(outfile) as f: self.assertEqual(f.read(), 'hello') From 28a8ced06fe3e40607feebb67760870ea199e6d4 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Tue, 12 Jun 2018 15:07:35 +0100 Subject: [PATCH 2/4] fixup! Fix race condition in `Lib/test/test_posix.py:TestPosixSpawn.test_open_file` --- Lib/test/test_posix.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 060ae92f32a1347..d7873b8f8e9a229 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1541,9 +1541,10 @@ def test_open_file(self): os.environ, file_actions) self.assertEqual(os.waitpid(pid, 0), (pid, 0)) - max_tries = 3 - while not os.path.exists(outfile) and max_tries: - max_tries -= 1 + deadline = time.monotonic() + 0.3 + while not os.path.exists(outfile): + if time.monotonic() > deadline: + break time.sleep(0.1) with open(outfile) as f: From 1ad0a0808ebd3cdb9f825fe54e8f18acc85a63d3 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Tue, 12 Jun 2018 15:55:21 +0100 Subject: [PATCH 3/4] Fix race condition when the file is created but nothing is written into it --- Lib/test/test_posix.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index d7873b8f8e9a229..05682e961a2071c 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1544,11 +1544,19 @@ def test_open_file(self): deadline = time.monotonic() + 0.3 while not os.path.exists(outfile): if time.monotonic() > deadline: - break + raise TimeoutError time.sleep(0.1) + deadline = time.monotonic() + 0.3 with open(outfile) as f: - self.assertEqual(f.read(), 'hello') + while True: + if time.monotonic() > deadline: + raise TimeoutError + f.seek(0) + data = f.read() + if data: + break + self.assertEqual(data, 'hello') def test_close_file(self): closefile = support.TESTFN From 5110fa282a7bb5fe5d0aa75cb88ac219417b5a17 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 15 Jun 2018 13:00:31 +0100 Subject: [PATCH 4/4] Use fsync in the child to force writing to disk --- Lib/test/test_posix.py | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 05682e961a2071c..6942ded1e6adc91 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1527,9 +1527,10 @@ def test_open_file(self): outfile = support.TESTFN self.addCleanup(support.unlink, outfile) script = """if 1: - import sys + import sys, os sys.stdout.write("hello") sys.stdout.flush() + os.fsync(sys.stdout.fileno()) """ file_actions = [ (os.POSIX_SPAWN_OPEN, 1, outfile, @@ -1540,23 +1541,8 @@ def test_open_file(self): [sys.executable, '-c', script], os.environ, file_actions) self.assertEqual(os.waitpid(pid, 0), (pid, 0)) - - deadline = time.monotonic() + 0.3 - while not os.path.exists(outfile): - if time.monotonic() > deadline: - raise TimeoutError - time.sleep(0.1) - - deadline = time.monotonic() + 0.3 with open(outfile) as f: - while True: - if time.monotonic() > deadline: - raise TimeoutError - f.seek(0) - data = f.read() - if data: - break - self.assertEqual(data, 'hello') + self.assertEqual(f.read(), 'hello') def test_close_file(self): closefile = support.TESTFN