Skip to content

Commit

Permalink
Add Yuval Kogman's test to ensure proper signal dispatch order.
Browse files Browse the repository at this point in the history
  • Loading branch information
rcaputo committed Aug 16, 2008
1 parent be6e9be commit d44790f
Show file tree
Hide file tree
Showing 2 changed files with 391 additions and 0 deletions.
1 change: 1 addition & 0 deletions MANIFEST
Expand Up @@ -136,6 +136,7 @@ t/90_regression/bingos-followtail.t
t/90_regression/broeren-win32-nbio.t
t/90_regression/cfedde-filter-httpd.t
t/90_regression/ferrari-server-unix.t
t/90_regression/kogman-sig-order.t
t/90_regression/merijn-sigchld-system.t
t/90_regression/neyuki_detach.t
t/90_regression/rt14444-arg1.t
Expand Down
390 changes: 390 additions & 0 deletions t/90_regression/kogman-sig-order.t
@@ -0,0 +1,390 @@
# $Id: $
# vim: filetype=perl

# Tests propagation of signals through the session ancestry

use warnings;
use strict;

use Test::More;

plan 'no_plan';

sub POE::Kernel::ASSERT_DEFAULT () { 1 }
use POE;

{
my @log;

my $session = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$_[KERNEL]->sig("foo" => "foo");
$_[KERNEL]->signal( $_[SESSION], "foo" );
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[STATE, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);

POE::Kernel->run;

is_deeply(
\@log,
[
[ enter_start => $session ],
[ leave_start => $session ],
[ foo => $session ],
[ stop => $session ],
],
"simple signal on one session",
);
}

{
my @log;

my $child;
my $session = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$child = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$_[KERNEL]->delay("bar" => 0.1);
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);
$_[KERNEL]->sig("foo" => "foo");
$_[KERNEL]->signal( $_[SESSION], "foo" );
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);

POE::Kernel->run;

is_deeply(
\@log,
[
[ enter_start => $session ],
[ enter_start => $child ],
[ leave_start => $child ],
[ child => $session ],
[ leave_start => $session ],
[ foo => $session ],
[ default => bar => $child ],
[ stop => $child ],
[ child => $session ],
[ stop => $session ],
],
"signal on parent, oblivious child",
);
}

{
my @log;

my $child;
my $session = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$child = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$_[KERNEL]->delay("bar" => 0.1);
$_[KERNEL]->sig("foo" => "foo");
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);
$_[KERNEL]->sig("foo" => "foo");
$_[KERNEL]->signal( $_[SESSION], "foo" );
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);

POE::Kernel->run;

is_deeply(
\@log,
[
[ enter_start => $session ],
[ enter_start => $child ],
[ leave_start => $child ],
[ child => $session ],
[ leave_start => $session ],
[ foo => $child ],
[ foo => $session ],
[ default => bar => $child ],
[ stop => $child ],
[ child => $session ],
[ stop => $session ],
],
"signal on child, then parent",
);
}

{
my @log;

my $child;
my $session = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$child = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$_[KERNEL]->delay("bar" => 1);
$_[KERNEL]->sig("TERM" => "TERM");
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);
$_[KERNEL]->sig("TERM" => "TERM");
$_[KERNEL]->signal( $_[SESSION], "TERM" );
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);

POE::Kernel->run;

is_deeply(
\@log,
[
[ enter_start => $session ],
[ enter_start => $child ],
[ leave_start => $child ],
[ child => $session ],
[ leave_start => $session ],
[ default => TERM => $child ],
[ default => TERM => $session ],
[ stop => $child ],
[ child => $session ],
[ stop => $session ],
],
"TERM signal on child, then parent",
);
}

{
my @log;

my $child;
my $session = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$child = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$_[KERNEL]->delay("bar" => 1);
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);
$_[KERNEL]->signal( $_[SESSION], "TERM" );
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);

POE::Kernel->run;

is_deeply(
\@log,
[
[ enter_start => $session ],
[ enter_start => $child ],
[ leave_start => $child ],
[ child => $session ],
[ leave_start => $session ],
[ stop => $child ],
[ child => $session ],
[ stop => $session ],
],
"TERM signal with no handlers on child, then parent",
);
}

{
my @log;

my ( $child, $grandchild );
my $session = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$child = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$grandchild = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$_[KERNEL]->delay("bar" => 1);
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);
$_[KERNEL]->sig( TERM => "TERM" );
$_[KERNEL]->delay("bar" => 1);
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);
$_[KERNEL]->signal( $_[SESSION], "TERM" );
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);

POE::Kernel->run;

is_deeply(
\@log,
[
[ enter_start => $session ],
[ enter_start => $child ],
[ enter_start => $grandchild ],
[ leave_start => $grandchild ],
[ child => $child ],
[ leave_start => $child ],
[ child => $session ],
[ leave_start => $session ],
[ default => TERM => $child ],
[ stop => $grandchild ],
[ child => $child ],
[ stop => $child ],
[ child => $session ],
[ stop => $session ],
],
"TERM signal on granchild, then child (with handler), then parent",
);
}

{
my @log;

my ( $child, $grandchild );
my $session = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$child = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$grandchild = POE::Session->create(
inline_states => {
_start => sub {
push @log, [ enter_start => $_[SESSION] ];
$_[KERNEL]->delay("bar" => 1);
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);
$_[KERNEL]->delay("bar" => 1);
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);
$_[KERNEL]->signal( $_[SESSION], "TERM" );
push @log, [ leave_start => $_[SESSION] ];
},
_child => sub { push @log, [ child => $_[SESSION] ] },
_stop => sub { push @log, [ stop => $_[SESSION] ] },
_default => sub { push @log, [ default => @_[ARG0, SESSION] ] },
foo => sub { push @log, [ foo => $_[SESSION] ] },
},
);

POE::Kernel->run;

is_deeply(
\@log,
[
[ enter_start => $session ],
[ enter_start => $child ],
[ enter_start => $grandchild ],
[ leave_start => $grandchild ],
[ child => $child ],
[ leave_start => $child ],
[ child => $session ],
[ leave_start => $session ],
[ stop => $grandchild ],
[ child => $child ],
[ stop => $child ],
[ child => $session ],
[ stop => $session ],
],
"TERM signal with no handlers on granchild, then child, then parent",
);
}

0 comments on commit d44790f

Please sign in to comment.