Skip to content

Commit 98d462c

Browse files
authored
gh-137179: Fix flaky test_history_survive_crash test (gh-137180)
Kill the REPL subprocess once it prints the output from the command immediately before the `time.sleep()`.
1 parent 0b4e13c commit 98d462c

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

Lib/test/test_pyrepl/test_pyrepl.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def run_repl(
5151
cwd: str | None = None,
5252
skip: bool = False,
5353
timeout: float = SHORT_TIMEOUT,
54+
exit_on_output: str | None = None,
5455
) -> tuple[str, int]:
5556
temp_dir = None
5657
if cwd is None:
@@ -64,6 +65,7 @@ def run_repl(
6465
cwd=cwd,
6566
skip=skip,
6667
timeout=timeout,
68+
exit_on_output=exit_on_output,
6769
)
6870
finally:
6971
if temp_dir is not None:
@@ -78,6 +80,7 @@ def _run_repl(
7880
cwd: str,
7981
skip: bool,
8082
timeout: float,
83+
exit_on_output: str | None,
8184
) -> tuple[str, int]:
8285
assert pty
8386
master_fd, slave_fd = pty.openpty()
@@ -123,6 +126,11 @@ def _run_repl(
123126
except OSError:
124127
break
125128
output.append(data)
129+
if exit_on_output is not None:
130+
output = ["".join(output)]
131+
if exit_on_output in output[0]:
132+
process.kill()
133+
break
126134
else:
127135
os.close(master_fd)
128136
process.kill()
@@ -1718,18 +1726,24 @@ def test_history_survive_crash(self):
17181726

17191727
commands = "1\n2\n3\nexit()\n"
17201728
output, exit_code = self.run_repl(commands, env=env, skip=True)
1729+
self.assertEqual(exit_code, 0)
17211730

1722-
commands = "spam\nimport time\ntime.sleep(1000)\nquit\n"
1723-
try:
1724-
self.run_repl(commands, env=env, timeout=3)
1725-
except AssertionError:
1726-
pass
1731+
# Run until "0xcafe" is printed (as "51966") and then kill the
1732+
# process to simulate a crash. Note that the output also includes
1733+
# the echoed input commands.
1734+
commands = "spam\nimport time\n0xcafe\ntime.sleep(1000)\nquit\n"
1735+
output, exit_code = self.run_repl(commands, env=env,
1736+
exit_on_output="51966")
1737+
self.assertNotEqual(exit_code, 0)
17271738

17281739
history = pathlib.Path(hfile.name).read_text()
17291740
self.assertIn("2", history)
17301741
self.assertIn("exit()", history)
17311742
self.assertIn("spam", history)
17321743
self.assertIn("import time", history)
1744+
# History is written after each command's output is printed to the
1745+
# console, so depending on how quickly the process is killed,
1746+
# the last command may or may not be written to the history file.
17331747
self.assertNotIn("sleep", history)
17341748
self.assertNotIn("quit", history)
17351749

0 commit comments

Comments
 (0)