Skip to content

Commit

Permalink
bpo-31158: Fix nondeterministic read in test_pty (#3808) (#3853)
Browse files Browse the repository at this point in the history
(cherry picked from commit e6f62f6)
  • Loading branch information
vstinner authored Oct 2, 2017
1 parent 1163fb9 commit 20cbc1d
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions Lib/test/test_pty.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import select
import signal
import socket
import io # readline
import unittest

TEST_STRING_1 = "I wish to buy a fish license.\n"
Expand All @@ -24,6 +25,16 @@ def debug(msg):
pass


# Note that os.read() is nondeterministic so we need to be very careful
# to make the test suite deterministic. A normal call to os.read() may
# give us less than expected.
#
# Beware, on my Linux system, if I put 'foo\n' into a terminal fd, I get
# back 'foo\r\n' at the other end. The behavior depends on the termios
# setting. The newline translation may be OS-specific. To make the
# test suite deterministic and OS-independent, the functions _readline
# and normalize_output can be used.

def normalize_output(data):
# Some operating systems do conversions on newline. We could possibly
# fix that by doing the appropriate termios.tcsetattr()s. I couldn't
Expand All @@ -45,6 +56,12 @@ def normalize_output(data):

return data

def _readline(fd):
"""Read one line. May block forever if no newline is read."""
reader = io.FileIO(fd, mode='rb', closefd=False)
return reader.readline()



# Marginal testing of pty suite. Cannot do extensive 'do or fail' testing
# because pty code is not too portable.
Expand Down Expand Up @@ -97,14 +114,14 @@ def test_basic(self):

debug("Writing to slave_fd")
os.write(slave_fd, TEST_STRING_1)
s1 = os.read(master_fd, 1024)
s1 = _readline(master_fd)
self.assertEqual('I wish to buy a fish license.\n',
normalize_output(s1))

debug("Writing chunked output")
os.write(slave_fd, TEST_STRING_2[:5])
os.write(slave_fd, TEST_STRING_2[5:])
s2 = os.read(master_fd, 1024)
s2 = _readline(master_fd)
self.assertEqual('For my pet fish, Eric.\n', normalize_output(s2))

os.close(slave_fd)
Expand Down

0 comments on commit 20cbc1d

Please sign in to comment.