Skip to content

Commit d54f137

Browse files
committed
fix: address comments
Signed-off-by: yihong0618 <zouzou0208@gmail.com>
1 parent 9658e5f commit d54f137

1 file changed

Lines changed: 33 additions & 48 deletions

File tree

Lib/test/test_pyrepl/test_unix_console.py

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
import termios
77
from functools import partial
88
from test.support import os_helper, force_not_colorized_test_class
9+
from test.support.strace_helper import requires_strace
910
import subprocess
10-
import time
1111
import shutil
1212
import signal
13+
import textwrap
1314

1415
from unittest import TestCase
1516
from unittest.mock import MagicMock, call, patch, ANY, Mock
@@ -313,29 +314,6 @@ def test_getheightwidth_with_invalid_environ(self, _os_write):
313314

314315
class TestUnixConsoleEIOHandling(TestCase):
315316

316-
@patch('_pyrepl.unix_console.tcsetattr')
317-
@patch('_pyrepl.unix_console.tcgetattr')
318-
def test_eio_error_handling_in_prepare(self, mock_tcgetattr, mock_tcsetattr):
319-
mock_termios = Mock()
320-
mock_termios.iflag = 0
321-
mock_termios.oflag = 0
322-
mock_termios.cflag = 0
323-
mock_termios.lflag = 0
324-
mock_termios.cc = [0] * 32
325-
mock_termios.copy.return_value = mock_termios
326-
mock_tcgetattr.return_value = mock_termios
327-
328-
mock_tcsetattr.side_effect = termios.error(errno.EIO, "Input/output error")
329-
330-
console = UnixConsole(term="xterm")
331-
332-
try:
333-
console.prepare()
334-
except termios.error as e:
335-
if e.args[0] == errno.EIO:
336-
self.fail("EIO error should have been handled gracefully in prepare()")
337-
raise
338-
339317
@patch('_pyrepl.unix_console.tcsetattr')
340318
@patch('_pyrepl.unix_console.tcgetattr')
341319
def test_eio_error_handling_in_restore(self, mock_tcgetattr, mock_tcsetattr):
@@ -361,48 +339,56 @@ def test_eio_error_handling_in_restore(self, mock_tcgetattr, mock_tcsetattr):
361339
self.fail("EIO error should have been handled gracefully in restore()")
362340
raise
363341

342+
@requires_strace()
364343
class TestEIOWithStrace(unittest.TestCase):
365-
def setUp(self):
366-
self.strace = shutil.which("strace")
367-
if not self.strace:
368-
self.skipTest("strace")
369-
370344
def _attach_strace(self, pid):
371-
cmd = [self.strace, "-qq", "-p", str(pid), "-e", "inject=read:error=EIO:when=1", "-o", "/dev/null"]
345+
strace = shutil.which("strace")
346+
cmd = [strace, "-qq", "-p", str(pid), "-e", "inject=read:error=EIO:when=1", "-o", "/dev/null"]
372347
try:
373348
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
374-
time.sleep(0.15)
375-
if p.poll() is None:
349+
try:
350+
p.communicate(timeout=0.15)
351+
except subprocess.TimeoutExpired:
376352
return p
377-
except Exception:
353+
except (OSError, subprocess.SubprocessError):
354+
pass
355+
except (OSError, subprocess.SubprocessError):
378356
pass
379357

380-
cmd = [self.strace, "-qq", "-p", str(pid), "-e", "fault=read:error=EIO:when=1", "-o", "/dev/null"]
358+
# Fallback command
359+
cmd = [strace, "-qq", "-p", str(pid), "-e", "fault=read:error=EIO:when=1", "-o", "/dev/null"]
381360
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
382-
time.sleep(0.15)
361+
try:
362+
p.communicate(timeout=0.15)
363+
except subprocess.TimeoutExpired:
364+
pass
383365
return p
384366

385367
def test_repl_eio(self):
386-
pybin = sys.executable
387-
388-
child_code = r"""
389-
import signal, sys
390-
signal.signal(signal.SIGUSR1, lambda *a: None)
391-
print("READY", flush=True)
392-
signal.pause()
393-
input()
394-
"""
368+
child_code = textwrap.dedent("""
369+
import signal, sys
370+
signal.signal(signal.SIGUSR1, lambda *a: None)
371+
print("READY", flush=True)
372+
signal.pause()
373+
input()
374+
""").strip()
395375

396376
proc = subprocess.Popen(
397-
[pybin, "-S", "-c", child_code],
377+
[sys.executable, "-S", "-c", child_code],
398378
stdin=subprocess.PIPE,
399379
stdout=subprocess.PIPE,
400380
stderr=subprocess.PIPE,
401381
text=True
402382
)
403383

404-
line = proc.stdout.readline().strip()
405-
self.assertEqual(line, "READY")
384+
ready = False
385+
while not ready:
386+
line = proc.stdout.readline().strip()
387+
if line == "READY":
388+
ready = True
389+
break
390+
if proc.poll() is not None:
391+
self.fail("Child process exited unexpectedly")
406392

407393
tracer = self._attach_strace(proc.pid)
408394

@@ -412,6 +398,5 @@ def test_repl_eio(self):
412398
finally:
413399
if tracer and tracer.poll() is None:
414400
tracer.terminate()
415-
416401
self.assertNotEqual(proc.returncode, 0)
417402
self.assertTrue("Errno 5" in err or "Input/output error" in err or "EOFError" in err, err)

0 commit comments

Comments
 (0)