File: 31loop-spawnchild.t

package info (click to toggle)
libio-async-perl 0.29-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 684 kB
  • ctags: 239
  • sloc: perl: 6,439; makefile: 2
file content (162 lines) | stat: -rw-r--r-- 5,213 bytes parent folder | download
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/perl -w

use strict;

use IO::Async::Test;

use Test::More tests => 36;
use Test::Exception;

use POSIX qw( WIFEXITED WEXITSTATUS ENOENT EBADF );

use IO::Async::Loop::Poll;

# Need to look this up, so we don't hardcode the message in the test script
# This might cause locale issues
use constant ENOENT_MESSAGE => do { local $! = ENOENT; "$!" };

my $loop = IO::Async::Loop::Poll->new();

testing_loop( $loop );

my $exited_pid;
my $exitcode;
my $dollarbang;
my $dollarat;

sub on_exit
{
   ( $exited_pid, $exitcode, $dollarbang, $dollarat ) = @_;
}

sub wait_for_exit
{
   undef $exitcode;
   return wait_for { defined $exitcode };
}

dies_ok( sub { $loop->spawn_child( badoption => 1 ); },
         'Bad option to spawn fails' );

dies_ok( sub { $loop->spawn_child( code => sub { 1 }, command => "hello" ); },
         'Both code and command options to spawn fails' );

dies_ok( sub { $loop->spawn_child( on_exit => sub { 1 } ); },
         'Bad option to spawn fails' );

my $spawned_pid;

$spawned_pid = $loop->spawn_child(
   code => sub { return 42; },
   on_exit => \&on_exit,
);

wait_for_exit;

is( $exited_pid, $spawned_pid,  '$exited_pid == $spawned_pid after spawn CODE' );
ok( WIFEXITED($exitcode),       'WIFEXITED($exitcode) after spawn CODE' );
is( WEXITSTATUS($exitcode), 42, 'WEXITSTATUS($exitcode) after spawn CODE' );
# dollarbang isn't interesting here
is( $dollarat,              '', '$dollarat after spawn CODE' );

my $ENDEXIT = 10;
END { exit $ENDEXIT if defined $ENDEXIT; }

$spawned_pid = $loop->spawn_child(
   code => sub { return 0; },
   on_exit => \&on_exit,
);

wait_for_exit;

is( $exited_pid, $spawned_pid, '$exited_pid == $spawned_pid after spawn CODE with END' );
ok( WIFEXITED($exitcode),      'WIFEXITED($exitcode) after spawn CODE with END' );
# If this comes out as 10 then the END block ran and we fail.
is( WEXITSTATUS($exitcode), 0, 'WEXITSTATUS($exitcode) after spawn CODE with END' );
# dollarbang isn't interesting here
is( $dollarat,             '', '$dollarat after spawn CODE with END' );

$spawned_pid = $loop->spawn_child(
   code => sub { die "An exception here\n"; },
   on_exit => \&on_exit,
);

wait_for_exit;

is( $exited_pid, $spawned_pid,   '$exited_pid == $spawned_pid after spawn CODE with die with END' );
ok( WIFEXITED($exitcode),        'WIFEXITED($exitcode) after spawn CODE with die with END' );
is( WEXITSTATUS($exitcode), 255, 'WEXITSTATUS($exitcode) after spawn CODE with die with END' );
# dollarbang isn't interesting here
is( $dollarat, "An exception here\n", '$dollarat after spawn CODE with die with END' );

undef $ENDEXIT;

# We need a command that just exits immediately with 0
my $true;
foreach (qw( /bin/true /usr/bin/true )) {
   $true = $_, last if -x $_;
}

# Didn't find a likely-looking candidate. We'll fake one using perl itself
$true = "$^X -e 1" if !defined $true;

$spawned_pid = $loop->spawn_child(
   command => $true,
   on_exit => \&on_exit,
);

wait_for_exit;

is( $exited_pid, $spawned_pid, '$exited_pid == $spawned_pid after spawn '.$true );
ok( WIFEXITED($exitcode),      'WIFEXITED($exitcode) after spawn '.$true );
is( WEXITSTATUS($exitcode), 0, 'WEXITSTATUS($exitcode) after spawn '.$true );
is( $dollarbang+0,          0, '$dollarbang after spawn '.$true );
is( $dollarat,             '', '$dollarat after spawn '.$true );

# Just be paranoid in case anyone actually has this
my $donotexist = "/bin/donotexist";
$donotexist .= "X" while -e $donotexist;

$spawned_pid = $loop->spawn_child(
   command => $donotexist,
   on_exit => \&on_exit,
);

wait_for_exit;

is( $exited_pid, $spawned_pid,   '$exited_pid == $spawned_pid after spawn donotexist' );
ok( WIFEXITED($exitcode),        'WIFEXITED($exitcode) after spawn donotexist' );
is( WEXITSTATUS($exitcode), 255, 'WEXITSTATUS($exitcode) after spawn donotexist' );
is( $dollarbang+0, ENOENT,         '$dollarbang numerically after spawn donotexist' ); 
is( "$dollarbang", ENOENT_MESSAGE, '$dollarbang string after spawn donotexist' );
is( $dollarat,             '', '$dollarat after spawn donotexist' );

$spawned_pid = $loop->spawn_child(
   command => [ $^X, "-e", "exit 14" ],
   on_exit => \&on_exit,
);

wait_for_exit;

is( $exited_pid, $spawned_pid,  '$exited_pid == $spawned_pid after spawn ARRAY' );
ok( WIFEXITED($exitcode),       'WIFEXITED($exitcode) after spawn ARRAY' );
is( WEXITSTATUS($exitcode), 14, 'WEXITSTATUS($exitcode) after spawn ARRAY' );
is( $dollarbang+0,           0, '$dollarbang after spawn ARRAY' );
is( $dollarat,              '', '$dollarat after spawn ARRAY' );

{
   my( $pipe_r, $pipe_w ) = $loop->pipepair() or die "Cannot pipepair - $!";

   $spawned_pid = $loop->spawn_child(
      code => sub { return $pipe_w->syswrite( "test" ); },
      on_exit => \&on_exit,
   );

   wait_for_exit;

   is( $exited_pid, $spawned_pid,   '$exited_pid == $spawned_pid after pipe close test' );
   ok( WIFEXITED($exitcode),        'WIFEXITED($exitcode) after pipe close test' );
   is( WEXITSTATUS($exitcode), 255, 'WEXITSTATUS($exitcode) after pipe close test' );
   is( $dollarbang+0,        EBADF, '$dollarbang numerically after pipe close test' );
   is( $dollarat,               '', '$dollarat after pipe close test' );
}