1

I am teaching a high school computer science class, and am trying to automate the execution of JUnit tests against all of my student submissions. I am using a perl script wrapper to clone the student repositories and originally used system("gradle test") to run the tests within each repository.

I found that I needed to add a timeout mechanism because a number of my students created circular loops in their code, so I switched to using IPC::Cmd as follows:

$cmd = "gradle test";
my ($success, $error, $full_buf,$stdout_buf,$stderr_buf) = 
     run (command =>$cmd, verbose => 1, timeout => 20);

This works great on a Mac, but on Windows, I get the following error from gradle: Could not determine if Stdout is a console: could not get handle file information (errno 1)

I have tried redirecting both stdout and stderr, but then it fails for stdin... Any ideas would be greatly appreciated.

  • 1
    Can you try using [IPC::Run](https://metacpan.org/pod/IPC::Run) instead of `IPC::Cmd` like in [this](https://stackoverflow.com/q/65894141/2173773) question? – Håkon Hægland Jan 26 '21 at 00:29
  • Thank you for the idea - I will try it. I am running ActivePerl 5.28 - I forgot to put that in the original question. I was able to hack this to run by actually creating an empty file for stdin, and redirecting both stdout and stderr to a file, but I had the same issue with the timeout not firing.... I will try IPC::Run instead... – Scott Murray Jan 26 '21 at 15:13

1 Answers1

1

Could not determine if Stdout is a console

I was not able to reproduce that error (Windows 10, Strawberry Perl version 5.30.1) when I replace your $cmd = "gradle test" with the below perl script. However, the timeout does not work as expected. Here is my simple test program:

use strict;
use warnings;
use feature qw(say);
use Data::Dumper;
use IPC::Cmd qw(run);

my $timeout = shift @ARGV;
#my $cmd = ['perl', '-E', "sleep 4; exit 1"];
my $cmd = ['perl', '-E', "sleep 4; say 'stdout_text'; say STDERR 'stderr_text'"];
my ($success, $error, $full_buf,$stdout,$stderr) = 
     run (command =>$cmd, verbose => 1, timeout => $timeout);
say "success = $success" if $success;
say "error = $error" if $error;
print Dumper({ stdout => $stdout, stderr => $stderr});

If I run this with a timeout of 1, I get

> perl p.pl 1
Running [perl -E sleep 4; say 'stdout_text'; say STDERR 'stderr_text']...
stderr_text
stdout_text
error = IPC::Cmd::TimeOut: Command 'perl -E sleep 4; say 'stdout_text'; say STDERR 'stderr_text'' aborted by alarm after 1 seconds
$VAR1 = {
          'stdout' => [
                        'stdout_text
'
                      ],
          'stderr' => [
                        'stderr_text',
                        '
'
                      ]
        };

So even though it reports that it timed out after one second, it actually ran the program to the end. I am looking into this issue.

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174