-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
bpo-41818: Updated tests for the standard pty library #22962
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
Conversation
Signed-off-by: Soumendra Ganguly <[email protected]>
Sir, thank you very much for being patient. Please run the tests when you have time. I welcome suggestions/criticism. I have also sent a message to the teaching email thread. |
…FILENO is a tty Signed-off-by: Soumendra Ganguly <[email protected]>
…nBSD Signed-off-by: Soumendra Ganguly <[email protected]>
🤖 New build scheduled with the buildbot fleet by @gpshead for commit 2a3cba4d8e906af233fc22b1be648bae05e7f08b 🤖 If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i kicked off a test on the buildbots for some additional platform coverage out out curiosity. Note: our buildbot fleet may generate a lot of noise, they aren't all reliably and some were already failing on the main branch to begin with right now. so don't fret if it claims there are failures. only look for obviously related things within them if you go looking at those. :)
Signed-off-by: Soumendra Ganguly <[email protected]>
@gpshead I have removed those comments :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've completed a preliminary review of the test changes. Most of the suggested changes are fairly minor, for the most part I think this is good to go (although for the final approval/merge, I'd prefer to leave it to @ethanfurman or @Yhg1s since I'm no expert with pty
or tty
).
Lib/test/test_pty.py
Outdated
"pty.STDIN_FILENO window size unchanged") | ||
except OSError: | ||
# pty.STDIN_FILENO not a tty? | ||
debug("Failed to set pty.STDIN_FILENO window size") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this at least result in a warning via warnings.warn()
? I suspect it would get buried otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are absolutely correct. I will change this. I have one question before I change this. If I use warnings.warn() here, then it will always generate warnings when the test is not run with stdin being a tty; for example the automated tests done by GitHub. Is that going to be an issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may cause a slight bit of extra noise on the tests, but it shouldn't cause the GitHub CI to fail when the warning is emitted (I don't believe we have any of our CI set to fail on warning, but it can be ran with that setting locally).
Lib/test/test_pty.py
Outdated
@@ -318,7 +407,6 @@ def test__copy_eof_on_all(self): | |||
with self.assertRaises(IndexError): | |||
pty._copy(masters[0]) | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This existing whitespace line should be re-added, since generally there are two lines in between the last line of a class's body and functions after it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for teaching me this. I will make this change.
@@ -0,0 +1 @@ | |||
Updated tests for the pty library. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The news entry should optimally refer to the tests that were changed (in this case test_opentty
was updated and a new test_master_read()
was added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
Lib/test/test_pty.py
Outdated
current_stdin_winsz.columns, 0, 0) | ||
fcntl.ioctl(pty.STDIN_FILENO, TIOCSWINSZ, winsz) | ||
|
||
# pty.openpty() passed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this comment adds any additional context for the reader, and can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha. I did this because the test_fork() function also has a similar comment at the end thereof. Should I remove that one as well?
Lib/test/test_pty.py
Outdated
|
||
# RELEVANT ANYMORE? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe @ethanfurman or @Yhg1s could clarify, but I don't think we should add a new "RELEVANT ANYMORE?" comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for noticing this. I agree that they are annoying; I apologize for this. Yes, I need clarification. The plan was to remove the annoying "RELEVANT ANYMORE?" comments after clarification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I myself actually did not put much thought into the blocks that I marked with "RELEVANT ANYMORE?"; I will think about them in greater detail on Saturday. They were just supposed to be there as reminders; anyway, they do not hurt the tests :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aah. Now I realize why I added the extra "RELEVANT ANYMORE" here. Notice that the following comment mentions pty.master_open()
, which opens the slave and subsequently closes it. As a result, the original test_basic()
function was having to call pty.slave_open()
to re-open the slave. However, the new test_openpty()
calls pty.openpty()
, which, unlike pty.master_open()
, does not close the slave end. Anyway, that part does not seem to affect the test on Linux and FreeBSD.
Lib/test/test_pty.py
Outdated
|
||
|
||
# Marginal testing of pty suite. Cannot do extensive 'do or fail' testing | ||
# because pty code is not too portable. | ||
# XXX(nnorwitz): these tests leak fds when there is an error. | ||
# Soumendra: test_openpty may leave tty in abnormal state upon failure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we potentially surround with a try...finally
to avoid this? A single test failure should really not result in the other tests within test_pty
being unreliable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Thank you. I will work on this.
@aeros I am grateful for the reviews. I will keep working on this with the hope that we can finally put these old bugs to rest. |
Signed-off-by: Soumendra Ganguly <[email protected]>
@aeros Thank you for being patient. I have made the following changes as per your suggestions:
|
Signed-off-by: Soumendra Ganguly <[email protected]>
Signed-off-by: Soumendra Ganguly <[email protected]>
Signed-off-by: Soumendra Ganguly <[email protected]>
Lib/test/test_pty.py
Outdated
debug("Got slave_fd '%d'" % slave_fd) | ||
mode = tty.tcgetattr(pty.STDIN_FILENO) | ||
except tty.error: | ||
# possible reason: current stdin is not a tty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been away from the code, so this might be a dumb question, but can't we determine if stdin
is a tty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the late reply. That is actually a great question. tcgetattr()
can fail due to 2 reasons: errno == EBADF
( not a valid file descriptor ), errno == ENOTTY
( not a tty ). See https://pubs.opengroup.org/onlinepubs/9699919799/. In either case, your stdin is not a tty. In fact, all glibc's isatty()
does is call tcgetattr()
to see if it fails; see https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/isatty.c.
I have verified that Linux, FreeBSD, and NetBSD follow this approach for their isatty()
implementations, while OpenBSD calls fcntl()+F_ISATTY
. Anyway, the tcgetattr()
approach works on all the above platforms. I avoid isatty()
, which is often followed by a separate tcgetattr()
call, thereby avoiding an extra tcgetattr()
call [ OCD :D ].
In our code, if tcgetattr()
fails, then either pty.STDIN_FILENO
, which is 0
, is a valid fd but not a tty (ENOTTY), or it is not a valid fd at all (EBADF). EBADF will not happen unless something closes 0
[ uncommon scenario ]; for example, by using [ p close(0)
] in gdb
, or if your script itself voluntarily closes 0
for some reason.
The "possible" in the comment # possible reason: current stdin is not a tty
is not because of lack of confidence, but because I did not want to discount the (uncommon) chance of an EBADF, in which case 0
is not a valid fd at all [ OCD ]. Anyway, that comment can be safely removed. Do you want me to remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say update it:
# possible reason ...
to # not a tty or bad/closed fd
and, of course, make that change throughout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Signed-off-by: Soumendra Ganguly <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I think we can merge the PR and unblock @8vasu to work on future PTY improvements.
|
|
The test fails with 'unexpected success' error, perhaps |
Or perhaps Gentoo is one of the cases where it succeeds, and the the expected failure wrapper should not be applied in that case. |
#23514 is created for fix |
This converts the test for pty.master_open() to a test for pty.openpty() with additional tests such as checking slave termios, slave winsize; these additional tests are expected to fail.
This also adds a small test that is expected to fail on FreeBSD and should pass on Linux; reflecting pty.spawn()'s FreeBSD hang issue [ bpo-26228 ].
Solutions to these problems have been implemented here: https://github.com/8vasu/pypty2
If and when these tests are acknowledged, the solutions will be submitted in parts.
This follows the conversation here: #21861
Signed-off-by: Soumendra Ganguly [email protected]
https://bugs.python.org/issue41818