Extensive POE Testing PT. 7 - Testing, Event Parameters PT.2

xsawyerx on 2009-11-04T15:47:36

There is actually a limit on the length of the subject, this should actually be entitled: Extensive POE Testing PT. 7 - Testing, Unordered Event Parameters

Last post talked about Ordered Event Parameter testing which is basically setting a set of parameters that should be for each event, in the order in which they are suppose to be run.

A weak point that remains in this rather strong testing feature is the ability to make it unordered. That is, to say "I know the event next will be called with each of these parameter sets, but I don't know which one will come before the other.

A good example would be two events (one could even be an alarm) were to reach the same event, each with different parameters:

package Session;
use MooseX::POE;
sub START {
    $_[KERNEL]->alarm( 'mine_alarmz', time() + int rand 2 );
    # ... other stuff
    $_[KERNEL]->yield( 'next', 'from START' );
}

event 'mine_alarmz' => sub {
    $_[KERNEL]->yield( 'next', 'from alarmz' );
};

The race condition here manifests by having two codes (START, alarm) running the same event (next) and not knowing for sure which will reach it first.

In this case, testing for the set of parameters next will be called with (especially in a specific order) will be worthless. Taking into account that we don't really care what set of parameters is called first, setting possible sets of parameters for next will make sure that when it is called, it will not be called with anything that isn't defined as a set of parameters and will allow this race condition to exist, without causing trouble. This is actually the preferable method of testing event parameters for most people.

When using POE::Test::Helpers to do it, you merely have to override another attribute to set it. Here is a sample:

package Session;
use Test::More tests => 4;
use MooseX::POE;
with 'POE::Test::Helpers';
has '+event_params' => (
    default => sub { {
        'next' => [ [ 'hello', 'world' ], [ 'goodbye' ] ],
        'more' => [ [] ],
} } );

# this is the new attribute to override
has '+event_params_type' => ( default => 'unordered' );

my $flag = 0;
sub START           { $_[KERNEL]->yield( 'next', 'goodbye' ) }
event 'next' => sub { $_[KERNEL]->yield( 'more'            ) };
event 'more' => sub {
    $flag++ || $_[KERNEL]->yield( 'next', 'hello', 'world' );
};

package main;
use POE::Kernel;
Session->new();
POE::Kernel->run();

Next post (hopefully won't be in too long) will cover writing some tests with POE::Test::Helpers