Search code examples
perlgradletimeout

What is the best way to run gradle from perl with a timeout on a Windows platform?


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.


Solution

  • 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.