summaryrefslogtreecommitdiffstats
path: root/scripts/generic/t/22-testrunner-sync-output.t
blob: 35ae55b7bf1919ed9caede8d7fb3c47533deadca (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;

=head1 NAME

22-testrunner-sync-output.t - test testrunner's --sync-output option

=head1 SYNOPSIS

  perl ./22-testrunner-sync-output.t

This test will run the testrunner.pl script with and without sync-output
and verify the order in which subprocess output is printed.

=cut

use File::Spec::Functions;
use FindBin;
use Readonly;
use Test::More;
use Data::Dumper;
use English qw( -no_match_vars );

# Testrunner script
Readonly my $TESTRUNNER => catfile( $FindBin::Bin, '..', 'testrunner.pl' );

# This script
Readonly my $THIS_SCRIPT => catfile( $FindBin::Bin, $FindBin::Script );

# Test output of concurrent processes with no syncing
sub test_concurrent_unsynced
{
    # Run 4 async delayed-output through testrunner with no attempt to sync output
    my $cmd_unsynced = qq{"$EXECUTABLE_NAME" "$THIS_SCRIPT" -run-children};

    # With no --sync-output, verify the output is interleaved
    my $out_unsynced = qx( $cmd_unsynced 2>&1 );
    is( $out_unsynced, <<'END_OUT', 'output is interleaved by default' );
Line 1
Line 1
Line 1
Line 1
Line 2
Line 2
Line 2
Line 2
Line 3
Line 3
Line 3
Line 3
All children done.
END_OUT

    return;
}

# Test output of concurrent processes with syncing
sub test_concurrent_synced
{
    # Run 4 async delayed-output through testrunner and sync output
    my $cmd_synced = qq{"$EXECUTABLE_NAME" "$THIS_SCRIPT" -run-children --sync-output};

    # With --sync-output, verify the output is NOT interleaved
    my $out_synced = qx( $cmd_synced 2>&1 );
    is( $out_synced, <<'END_OUT', 'output with --sync-output is not interleaved' );
Line 1
Line 2
Line 3
Line 1
Line 2
Line 3
Line 1
Line 2
Line 3
Line 1
Line 2
Line 3
All children done.
END_OUT

    return;
}

sub main
{
    test_concurrent_unsynced;
    test_concurrent_synced;

    done_testing;
    return;
}

# Spawn a few concurrent delayed-output processes through testrunner.
# Anything in @ARGV is passed to the testrunner.
sub run_children
{
    my @pids;
    for my $i (1..4) {
        my $pid = fork();
        if (0 == $pid) {
            exec($EXECUTABLE_NAME, $TESTRUNNER, @ARGV, '--',
                 $EXECUTABLE_NAME, $THIS_SCRIPT, '-delayed-output');
            die "exec failed: $!";
        }
        else {
            push @pids, $pid;
        }
    }
    while (@pids) {
        shift @pids;
        waitpid(-1, 0);
    }
    print "All children done.\n";
    return;
}

# Write a few lines with a sleep between them
sub delayed_output
{
    local $| = 1;   # flushed output
    for my $i (1..3) {
        sleep 1;
        if ($i == 2) {
            print STDERR "Line $i\n";
        }
        else {
            print "Line $i\n";
        }
    }
    return;
}

if (my $cmd = shift @ARGV) {
    if ($cmd eq '-run-children') {
        run_children;
    }
    elsif ($cmd eq '-delayed-output') {
        delayed_output;
    }
    else {
        die "Unexpected argument `$cmd'";
    }
}
else {
    main;
}