classification
Title: test_curses skipped on buildbots
Type: behavior Stage: needs patch
Components: Tests Versions: Python 3.4, Python 3.5
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: ezio.melotti, martin.panter, michael.foord, nadeem.vawda, pitrou, python-dev, r.david.murray, ronaldoussoren, vstinner
Priority: normal Keywords:

Created on 2011-07-31 21:52 by nadeem.vawda, last changed 2016-05-16 03:32 by martin.panter.

Messages (10)
msg141477 - (view) Author: Nadeem Vawda (nadeem.vawda) * (Python committer) Date: 2011-07-31 21:52
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 issue7096 (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?
msg141479 - (view) Author: Nadeem Vawda (nadeem.vawda) * (Python committer) Date: 2011-07-31 22:37
Correction: the offending options are -j and *-W* (display test output on
failure), not -w (re-run failed tests in verbose mode).
msg141772 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-08-08 11:39
> 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()?
msg141798 - (view) Author: Nadeem Vawda (nadeem.vawda) * (Python committer) Date: 2011-08-08 20:26
> 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.
msg142021 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011-08-13 13:45
New changeset 4358909ee221 by Nadeem Vawda in branch 'default':
Issue #12669: Fix test_curses so that it can run on the buildbots.
http://hg.python.org/cpython/rev/4358909ee221
msg168289 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2012-08-15 13:01
As noted in Issue15664 this issue also affects "make test".
msg168291 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2012-08-15 13:03
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.
msg168293 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2012-08-15 13:24
BTW. the documentation for curses.setupterm says:

curses.setupterm([termstr, fd])

The first argument is actually named "term" in the C code.
msg168338 - (view) Author: Nadeem Vawda (nadeem.vawda) * (Python committer) Date: 2012-08-15 21:00
> 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().
msg265663 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-05-16 03:32
FYI I just added a reasonably generic function pty_run(script, input) -> output to Lib/test/test_readline.py:120 for Issue 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.
History
Date User Action Args
2016-05-16 03:32:56martin.pantersetnosy: + martin.panter
messages: + msg265663
2014-07-11 21:28:14BreamoreBoysetversions: + Python 3.5, - Python 3.3
2013-07-22 16:17:41ronaldoussorensetversions: + Python 3.4
2012-08-15 21:00:45nadeem.vawdasetstage: needs patch
2012-08-15 21:00:21nadeem.vawdasetmessages: + msg168338
2012-08-15 20:23:39nadeem.vawdalinkissue15664 superseder
2012-08-15 13:24:14ronaldoussorensetmessages: + msg168293
2012-08-15 13:03:49ronaldoussorensetmessages: + msg168291
2012-08-15 13:01:06ronaldoussorensetnosy: + ronaldoussoren
messages: + msg168289
2011-08-13 13:45:46python-devsetnosy: + python-dev
messages: + msg142021
2011-08-08 20:26:02nadeem.vawdasetmessages: + msg141798
2011-08-08 11:39:31vstinnersetmessages: + msg141772
2011-07-31 22:37:35nadeem.vawdasetmessages: + msg141479
2011-07-31 21:52:15nadeem.vawdacreate