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

test_curses skipped on buildbots #56878

Closed
nadeemvawda mannequin opened this issue Jul 31, 2011 · 11 comments
Closed

test_curses skipped on buildbots #56878

nadeemvawda mannequin opened this issue Jul 31, 2011 · 11 comments
Labels
tests Tests in the Lib/test dir type-bug An unexpected behavior, bug, or error

Comments

@nadeemvawda
Copy link
Mannequin

nadeemvawda mannequin commented Jul 31, 2011

BPO 12669
Nosy @ronaldoussoren, @pitrou, @vstinner, @ezio-melotti, @bitdancer, @voidspace, @vadmium, @serhiy-storchaka

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2021-01-31.17:47:25.955>
created_at = <Date 2011-07-31.21:52:15.187>
labels = ['type-bug', 'tests']
title = 'test_curses skipped on buildbots'
updated_at = <Date 2021-01-31.17:47:25.954>
user = 'https://bugs.python.org/nadeemvawda'

bugs.python.org fields:

activity = <Date 2021-01-31.17:47:25.954>
actor = 'serhiy.storchaka'
assignee = 'none'
closed = True
closed_date = <Date 2021-01-31.17:47:25.955>
closer = 'serhiy.storchaka'
components = ['Tests']
creation = <Date 2011-07-31.21:52:15.187>
creator = 'nadeem.vawda'
dependencies = []
files = []
hgrepos = []
issue_num = 12669
keywords = []
message_count = 11.0
messages = ['141477', '141479', '141772', '141798', '142021', '168289', '168291', '168293', '168338', '265663', '385630']
nosy_count = 10.0
nosy_names = ['ronaldoussoren', 'pitrou', 'vstinner', 'nadeem.vawda', 'ezio.melotti', 'r.david.murray', 'michael.foord', 'python-dev', 'martin.panter', 'serhiy.storchaka']
pr_nums = []
priority = 'normal'
resolution = 'out of date'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue12669'
versions = ['Python 3.4', 'Python 3.5']

@nadeemvawda
Copy link
Mannequin Author

nadeemvawda mannequin commented Jul 31, 2011

When running regrtest with the -j and/or -w options, test_curses gets skipped,
complaining that stdout is not a tty. This means that the buildbots never run
this test, which is obviously a Bad Thing.

For the -w case (which applies to the buildbots), this is caused by sys.stdout
(and sys.stderr) being replaced with a StringIO instance. We can work around
this in the test by using sys.__stdout__ instead. This is perhaps ugly, but it
seems to work, and is much better than doing nothing. For the record, this has
already been proposed in bpo-7096 (now dead).

For the -j case things aren't quite so straightforward - each test is run in a
subprocess, with stdout and stderr redirected to pipes, so there isn't an easy
way to access the terminal the process is associated with. Off the top of my
head, the only way I can think of to work around this is to special-case
test_curses so that it runs in the main process, and I'd really much rather not
do that. Thankfully this case doesn't apply to the buildbots at present, but it
is still bothersome when running tests locally.

TLDR:

  1. Is there any reason for test_curses not to use sys.__stdout__?
  2. Any ideas on how to get test_curses working with regrtest.py -j?

@nadeemvawda nadeemvawda mannequin added tests Tests in the Lib/test dir type-bug An unexpected behavior, bug, or error labels Jul 31, 2011
@nadeemvawda
Copy link
Mannequin Author

nadeemvawda mannequin commented Jul 31, 2011

Correction: the offending options are -j and *-W* (display test output on
failure), not -w (re-run failed tests in verbose mode).

@vstinner
Copy link
Member

vstinner commented Aug 8, 2011

Correction: the offending options are -j and *-W*

I changed regrtest -W recently to only run the tests once using StringIO as stdout. So it's a regression in Python 3.3.

Can't we create a dummy/temporary TTY for the curses tests using pty.openpty()?

@nadeemvawda
Copy link
Mannequin Author

nadeemvawda mannequin commented Aug 8, 2011

Can't we create a dummy/temporary TTY for the curses tests using pty.openpty()?

I would have thought so, but it seems that savetty() and endwin() both fail when
running under '-j0':

    test test_curses crashed -- Traceback (most recent call last):
      File "/home/nadeem/code/cpython/python/Lib/test/test_curses.py", line 289, in test_main
        main(stdscr)
      File "/home/nadeem/code/cpython/python/Lib/test/test_curses.py", line 269, in main
        curses.savetty()
    _curses.error: savetty() returned ERR

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/home/nadeem/code/cpython/python/Lib/test/regrtest.py", line 1139, in runtest_inner
        indirect_test()
      File "/home/nadeem/code/cpython/python/Lib/test/test_curses.py", line 291, in test_main
        curses.endwin()
    _curses.error: endwin() returned ERR

It might be that you need to close stdout and stderr so that there's only one
TTY associated with the process, but I suspect that'll break other things.

@python-dev
Copy link
Mannequin

python-dev mannequin commented Aug 13, 2011

New changeset 4358909ee221 by Nadeem Vawda in branch 'default':
Issue bpo-12669: Fix test_curses so that it can run on the buildbots.
http://hg.python.org/cpython/rev/4358909ee221

@ronaldoussoren
Copy link
Contributor

As noted in bpo-15664 this issue also affects "make test".

@ronaldoussoren
Copy link
Contributor

Nadeem: is the failure you show in msg141798 with a version of test_curses that uses pty.openpty?

If it isn't: I'd expect more test failures on buildbot machines where the buildbot agent is started as a system daemon, in which case the process doesn't have a tty at all. Using pty.openpty it would be possible to ensure that there is a pty that can be used for the test.

I'll work on a patch.

@ronaldoussoren
Copy link
Contributor

BTW. the documentation for curses.setupterm says:

curses.setupterm([termstr, fd])

The first argument is actually named "term" in the C code.

@nadeemvawda
Copy link
Mannequin Author

nadeemvawda mannequin commented Aug 15, 2012

Nadeem: is the failure you show in msg141798 with a version of test_curses that uses pty.openpty?

Yes, I tried the following change:

--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -328,11 +328,12 @@
         curses.resetty()
     def test_main():
    -    if not sys.__stdout__.isatty():
    -        raise unittest.SkipTest("sys.__stdout__ is not a tty")
         # testing setupterm() inside initscr/endwin
         # causes terminal breakage
    -    curses.setupterm(fd=sys.__stdout__.fileno())
    +    #curses.setupterm(fd=sys.__stdout__.fileno())
    +    import pty
    +    _, pty = pty.openpty()
    +    curses.setupterm(fd=pty)
         try:
             stdscr = curses.initscr()
             main(stdscr)

(I've never used openpty, either in Python or in C, so I can't vouch for
the correctness of this usage.)

If it isn't: I'd expect more test failures on buildbot machines where the buildbot agent is started as a system daemon, in which case the process doesn't have a tty at all. Using pty.openpty it would be possible to ensure that there is a pty that can be used for the test.

Looking at the actual buildbot results, most of the *nix bots I checked
are actually skipping this test; the only one I could find that wasn't is
the "x86 Ubuntu Shared" bot:
ttp://buildbot.python.org/all/builders/x86%20Ubuntu%20Shared%203.x/builds/6640/steps/test/logs/stdio

So it looks like on most of the bots, buildbot is running without a tty.
Then, test_main() sees that sys.__stdout__ isn't suitable to run the
test, and bails out.

It'd be great if you can come up with a fix that gets the test running
in this environment, but it'll probably be more complicated than just
slotting in a call to openpty().

@vadmium
Copy link
Member

vadmium commented May 16, 2016

FYI I just added a reasonably generic function pty_run(script, input) -> output to Lib/test/test_readline.py:120 for bpo-26870. It runs a Python script string in a child process under a pseudo-terminal. If you need to drive the curses tests with a pseudo-terminal, my code may be useful. There were about six different bugs and platform-specific quirks to work around (affecting Open BSD, Linux and various OS X versions), so I recommend learning from my experience rather than doing it all from scratch :)

Also, test_curses on Python 2 fails for me, but that is probably a separate bug.

@serhiy-storchaka
Copy link
Member

It was fixed in other way in bpo-42789. If __stdout__ is not a terminal, the code falls back to __stderr__, and it is not terminal either, it tries to open /dev/tty. If neither works, it uses a regular temporary file as terminal, but savetty()/resetty() and few tests are skipped.

It would be better to use pty, but I found that it does not work if tests output more than 2 KB. For now I do not know how to fix it.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tests Tests in the Lib/test dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

4 participants