Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.6] bpo-31158: Fix nondeterministic read in test_pty (GH-3808) #3852

Merged
merged 1 commit into from
Oct 2, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions Lib/test/test_pty.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import select
import signal
import socket
import io # readline
import unittest

TEST_STRING_1 = b"I wish to buy a fish license.\n"
Expand All @@ -23,6 +24,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 @@ -44,6 +55,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 @@ -98,14 +115,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(b'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(b'For my pet fish, Eric.\n', normalize_output(s2))

os.close(slave_fd)
Expand Down