http://www.perlmonks.org?node_id=639718

Ovid has asked for the wisdom of the Perl Monks concerning the following question:

One of feature which has been requested a few times for the prove utility which ships with Test::Harness is the ability to run a test directly in the debugger. It would be nice to do this:

prove -d t/some_test.t

Admittedly, you can do some hacking in your code to include blib/lib and not use prove directly, but anyone who has had to do this often enough knows that this can sometimes mask bugs caused by the interaction of the test framework and the code being tested. Since we're working on the new version of Test::Harness, I decided to add this feature. Unfortunately, this failed because the code is unable to fetch the terminal size. I've managed to reduce the problem down to a one-liner:

perl -e '`perl -d -le "print 1"`'

This spits out:

Loading DB routines from perl5db.pl version 1.28 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(-e:1): print 1 Unable to get Terminal Size. The TIOCGWINSZ ioctl didn't work. The COL +UMNS and LINES environment variables didn't work. The resize program +didn't work. at /Library/Perl/5.8.6/darwin-thread-multi-2level/Term/R +eadKey.pm line 362. Compilation failed in require at /Library/Perl/5.8.6/Term/ReadLine/Per +l.pm line 63. at /Library/Perl/5.8.6/Term/ReadLine/Perl.pm line 63 Term::ReadLine::Perl::new('Term::ReadLine', 'perldb', 'GLOB(0x +1849f68)', 'GLOB(0x181100c)') called at /System/Library/Perl/5.8.6/pe +rl5db.pl line 6029 DB::setterm called at /System/Library/Perl/5.8.6/perl5db.pl li +ne 2203 DB::DB called at -e line 1 Debugged program terminated. Use q to quit or R to restart, use O inhibit_exit to avoid stopping after program termination, h q, h R or h O to get additional info. DB<1> q

As it turns out, there are other problems with adding the -d switch to prove (insecure $ENV{PATH} when using taint checking), but this appears to be the biggest obstacle. In order to meet our design goals, we'd like to solve this with the following constraints:

If those constraints cannot be met, we'll still consider making this an optional feature if this can be solved, but meeting the constraints would be wonderful. Help!

Cheers,
Ovid

New address of my CGI Course.

Replies are listed 'Best First'.
Re: Unable to get terminal size
by ikegami (Patriarch) on Sep 18, 2007 at 18:32 UTC

    Sounds like perl -d expects a terminal. You can provide it a fake terminal using IO::Pty. However, it only supports Windows under Cygwin.

      It looks to me like "perl -d" has a terminal in the above scenario. And, no, "perl -d" does not expect/require that STDIN nor STDOUT be terminals. The default Perl debugger opens its own handles for input and output to "the terminal" (by opening "/dev/tty" or "con:" or such) which means it doesn't mind if at least some of STDIN, STDOUT, and STDERR are redirected. My guess is that "/dev/tty" doesn't "work" when all three of those handles are redirected while "con:" works even if all three are redirected. In the above example, it appears to me that STDIN is still connected to the tty (as is STDERR but not STDOUT).

      It is unfortunate that Term::ReadKey::GetTerminalSize() destroys any evidence about why most of the listed attempts failed. Doing a little debugging of the debugger's start-up in order to recover exactly why each of the attempts failed seems the obvious next step. An easy way to do that is simply to edit ReadKey.pm to correct its silence.

      It looks to me like this is a bug in the Perl debugger that wasn't there last time I worked on it. I certainly noticed this type of complaint a lot after some upgrade (likely perl 5.6 or 5.6.1) and have succeeded in mostly ignoring it.

      My testing of the example invocation on a Unix system shows that, despite all of the code to the contrary, GetTerminalSize() is trying to get the terminal size of STDOUT (which isn't a terminal).

      The crux of the problem is that $readline::term_OUT isn't being set to $DB::OUT despite $IN and $OUT being passed in $term = new Term::ReadLine 'perldb', $IN, $OUT;

      - tye        

      Reading the error message more carefully (duh!) gets me this:

      perl -e '`COLUMNS=80 LINES=24 perl -d -le "print 1"`'

      That may not be cross-platform (vms?) and causes other problems upon integration.

      Cheers,
      Ovid

      New address of my CGI Course.

Re: Unable to get terminal size
by quester (Vicar) on Sep 19, 2007 at 07:08 UTC
    Another tactic is to tell the terminal handling code that you have some sort of hard copy terminal, so it won't try to impose a "screen geometry" on devices that simply don't have one, such as a pty or a pipe. For instance,
    TERM=la120 perl -e '`perl -d -le "print 1"`'
    or
    perl -e '`TERM=la120 perl -d -le "print 1"`'
Re: Unable to get terminal size
by danmcb (Monk) on Sep 20, 2007 at 08:40 UTC

    I am in the habit of doing :

    perl -Ilib t/mytests.t

    and adding the -d switch to this is fine. I've never yet seen a case where this passes but "make test" fails - if such things do exist, wouldn't a better approach be to fix that - if possible?

    To be honest, I've not yet seen a benefit to doing "prove" in place of this. Which doesn't mean that there aren't any, of course ...

      prove has many benefits that people don't always appreciate. It's easy to do recursive tests, shuffle tests, run all tests in a particular directory, etc. However, with Test::Harness 3.0, you get much more. You can:

      • Switch in your own test harness
      • Have greater control over what you do and do not see (quiet output, only failures, etc.)
      • Get colored test output
      • Run tests in parallel
      • Create TAP archives
      • ... or any other custom test behavior you need.

      In short, the current prove is useful, the upcoming version is even more useful.

      As for adding the -d switch, that becomes very handy when you think there might be a problem with test/code interaction (ever seen code fail in the test suite but not when run directly?).

      Cheers,
      Ovid

      New address of my CGI Course.