#!/usr/bin/perl
# vim: ts=2 sw=2 expandtab
use warnings;
use strict;
use Test::More;
if ($^O eq "MSWin32" and not $ENV{POE_DANTIC}) {
plan skip_all => "Perl crashes on $^O";
}
plan tests => 14;
my $port;
use POE;
use POE::Wheel::Run;
SKIP: {
skip("The underlying event loop has trouble with ptys on $^O", 6)
if $^O eq "darwin" and (
exists $INC{"POE/Loop/IO_Poll.pm"} or
exists $INC{"POE/Loop/Event.pm"} or
$ENV{POE_LOOP_USES_POLL}
) and not $ENV{POE_DANTIC};
eval "use IO::Pty";
skip("IO::Pty is not available; skipping pty tests", 6) if $@;
PoeTestWorker->spawn( 'pty' );
PoeTestWorker->spawn( 'pty-pipe' );
}
PoeTestWorker->spawn( 'socketpair' );
PoeTestWorker->spawn( 'inet' );
pass( "Start" );
$poe_kernel->run;
pass( "Done" );
#############################################################################
package
PoeTestWorker;
use strict;
use warnings;
use POE;
use Test::More;
sub DEBUG () { 0 }
sub seen
{
my( $heap, $what ) = @_;
$heap->{seen}{$what}++;
DEBUG and diag "$$: seen $what\n";
if( 3==keys %{$heap->{seen}} ) {
delete $heap->{wheel};
$poe_kernel->alarm_remove( delete $heap->{tid} ) if $heap->{tid};
}
}
sub spawn
{
my( $package, $conduit ) = @_;
POE::Session->create(
args => [ $conduit ],
inline_states => {
_start => sub {
my( $heap, $kernel, $conduit ) = @_[ HEAP, KERNEL, ARG0 ];
$heap->{conduit} = $conduit;
$heap->{seen} = {};
$kernel->sig_child( TERM => 'TERM' );
$heap->{wheel} = POE::Wheel::Run->new(
StderrEvent => (
$conduit eq 'pty' ? undef() : 'stderr'
),
StdoutEvent => 'stdout',
#ErrorEvent => 'error',
CloseEvent => 'closeE',
Conduit => $conduit,
Program => sub {
print "hello\n";
sleep 1;
print "hello world" x 1024, "\n";
print "done\n";
}
);
$kernel->sig_child( $heap->{wheel}->PID, 'CHLD' );
$heap->{tid} = $kernel->delay_set( timeout => 600 );
},
_stop => sub {
my( $heap, $kernel ) = @_[ HEAP, KERNEL ];
## This is the money shot
foreach my $need ( qw( done close CHLD ) ) {
is( $heap->{seen}{$need}, 1, "$heap->{conduit}: $need" );
}
},
timeout => sub {
my( $heap, $kernel ) = @_[ HEAP, KERNEL ];
$poe_kernel->alarm_remove( delete $heap->{tid} ) if $heap->{tid};
delete $heap->{wheel};
delete $heap->{tid};
},
TERM => sub {
my( $heap, $kernel ) = @_[ HEAP, KERNEL ];
$poe_kernel->alarm_remove( delete $heap->{tid} ) if $heap->{tid};
delete $heap->{wheel};
$kernel->sig_handled;
},
closeE => sub {
my( $heap, $kernel ) = @_[ HEAP, KERNEL ];
seen( $heap, 'close' );
},
CHLD => sub {
my( $heap, $kernel ) = @_[ HEAP, KERNEL ];
seen( $heap, 'CHLD' );
$kernel->sig_handled;
},
stdout => sub {
my( $heap, $kernel, $line, $wid ) = @_[ HEAP, KERNEL, ARG0..$#_ ];
seen( $heap, 'done' ) if $line eq 'done';
},
stderr => sub {
my( $heap, $kernel, $line, $wid ) = @_[ HEAP, KERNEL, ARG0..$#_ ];
warn "ERROR [$$]: $line\n";
seen( $heap, 'error' );
$poe_kernel->alarm_remove( delete $heap->{tid} ) if $heap->{tid};
},
}
);
}
1;