summaryrefslogtreecommitdiffstats
path: root/scripts/generic/t/16-testrunner-capture-logs-race.t
blob: 2d39c712d76003a9d667af1b1cec1bd88c862448 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;

=head1 NAME

16-testrunner-capture-logs-race.t - test for one specific race condition

=cut

use English qw( -no_match_vars );
use File::Temp qw( tempdir );
use FindBin;
use Getopt::Long;
use Readonly;
use Test::More;

Readonly my $WINDOWS => ($OSNAME =~ m{mswin32}i);

# Directory containing some helper scripts
# Testrunner script
Readonly my @TESTRUNNER => (
    $EXECUTABLE_NAME,
    "$FindBin::Bin/../testrunner.pl",
);

# Like system(), but returns the pid and runs in the background
sub spawn
{
    my (@cmd) = @_;

    if ($WINDOWS) {
        # avoid fork() on Windows - see 'perldoc perlport'
        return system(1, @cmd);
    }

    my $pid = fork();
    if ($pid == 0) {
        exec( @cmd );
        die "exec: $!";
    } elsif ($pid < 0) {
        die "fork: $!"
    }

    return $pid
}

# main entry point
sub run
{
    my $debug;

    GetOptions(
        'debug' => \$debug,
    ) || die;

    my $tempdir = tempdir( 'qtqa-test-capture-logs.XXXXXX', TMPDIR => 1, CLEANUP => !$debug );
    if ($debug) {
        diag( "Using $tempdir as temporary directory" );
    }

    # check precondition
    my @globbed = glob( "$tempdir/*" );
    ok( @globbed == 0, "$tempdir is empty" )
        || diag "globbed: @globbed";

    # The test is: if we run multiple testrunners in parallel with --capture-logs, do they all
    # get unique output files or do some of them clobber each other?
    # Note: this is also testing concurrent creation of the "logdir" directory.
    my $MAX = 50;
    my @cmd = (@TESTRUNNER, '--capture-logs', "$tempdir/logdir", '--', $EXECUTABLE_NAME, '--version');
    my @pids = map { spawn(@cmd) } (1..$MAX);
    while (my $next = shift @pids) {
        if (waitpid( $next, 0 ) != $next) {
            die "waitpid $next: $!";
        }
    }

    # There should now be exactly $MAX files in the log directory, one per process.
    @globbed = glob( "$tempdir/logdir/*" );
    ok( @globbed == $MAX, 'one log file per process' )
        || diag "globbed: @globbed";

    done_testing( );

    return;
}

run if (!caller);
1;