Skip to content

Commit e6f62f6

Browse files
diekmannvstinner
authored andcommitted
bpo-31158: Fix nondeterministic read in test_pty (#3808)
* bpo-31158: Fix nondeterministic read in test_pty * Reuse existing readline implementation from io. Thx to @pitrou * Updated comment Ideally, this commit is fixuped into the previous commit. Since there is already a comment on github, I won't rebase.
1 parent b75a228 commit e6f62f6

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

Lib/test/test_pty.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import select
1111
import signal
1212
import socket
13+
import io # readline
1314
import unittest
1415

1516
TEST_STRING_1 = b"I wish to buy a fish license.\n"
@@ -23,6 +24,16 @@ def debug(msg):
2324
pass
2425

2526

27+
# Note that os.read() is nondeterministic so we need to be very careful
28+
# to make the test suite deterministic. A normal call to os.read() may
29+
# give us less than expected.
30+
#
31+
# Beware, on my Linux system, if I put 'foo\n' into a terminal fd, I get
32+
# back 'foo\r\n' at the other end. The behavior depends on the termios
33+
# setting. The newline translation may be OS-specific. To make the
34+
# test suite deterministic and OS-independent, the functions _readline
35+
# and normalize_output can be used.
36+
2637
def normalize_output(data):
2738
# Some operating systems do conversions on newline. We could possibly fix
2839
# that by doing the appropriate termios.tcsetattr()s. I couldn't figure out
@@ -43,6 +54,12 @@ def normalize_output(data):
4354

4455
return data
4556

57+
def _readline(fd):
58+
"""Read one line. May block forever if no newline is read."""
59+
reader = io.FileIO(fd, mode='rb', closefd=False)
60+
return reader.readline()
61+
62+
4663

4764
# Marginal testing of pty suite. Cannot do extensive 'do or fail' testing
4865
# because pty code is not too portable.
@@ -94,14 +111,14 @@ def test_basic(self):
94111

95112
debug("Writing to slave_fd")
96113
os.write(slave_fd, TEST_STRING_1)
97-
s1 = os.read(master_fd, 1024)
114+
s1 = _readline(master_fd)
98115
self.assertEqual(b'I wish to buy a fish license.\n',
99116
normalize_output(s1))
100117

101118
debug("Writing chunked output")
102119
os.write(slave_fd, TEST_STRING_2[:5])
103120
os.write(slave_fd, TEST_STRING_2[5:])
104-
s2 = os.read(master_fd, 1024)
121+
s2 = _readline(master_fd)
105122
self.assertEqual(b'For my pet fish, Eric.\n', normalize_output(s2))
106123

107124
os.close(slave_fd)

0 commit comments

Comments
 (0)