Bot-Net

 view release on metacpan or  search on metacpan

lib/Bot/Net/Test.pm  view on Meta::CPAN

    my $class = shift;
    my $bot   = shift;

    $class->bots->{ $bot } = undef;
}

=head2 stop_bot BOT

Stops the named bot.

=cut

sub stop_bot {
    my $class = shift;
    my $bot   = shift;

    my $wheel = delete $class->bots->{ $bot }{ 'wheel' };
    if ($wheel) {
        Bot::Net::Test->log->info("Terminating bot $bot (pid:@{[$wheel->PID]})");
        $class->waiting->{ $wheel->PID } = 1;
        $wheel->kill;
    }
}

=head2 run_test

Tells the test to setup the bot or server and tell the L<POE> kernel to start the event loop.

=cut

sub run_test {
    my $class = shift;
    my $test  = caller;

    my @configs;
    for my $mixin (@{ Bot::Net::Mixin::_mixins_for_package($test) }) {
        push @configs, $mixin->default_configuration($test)
            if $mixin->can('default_configuration');
    }

    my $config = Hash::Merge::merge( @configs );

    # XXX This is a hack, I need to find a better way...
    $config->{auto_connect} = 0;

    {
        no strict 'refs';
        ${ $test . '::CONFIG' } = $config;
    }

    Bot::Net::Test->log->info("Starting test");

    $test->setup;
    POE::Kernel->run;
}

=head1 POE STATES

=head2 on _start

Sets up a timer which kills the whole test if it doesn't receive any messages within 30 seconds.

If you have a test that may run for longer than 30 seconds, make sure your events yield "something_happened":

  on bot message_to_me => run {
      yield 'something_happened';

      # do whatever else you like...
  };

=cut

sub _run_that {
    my @program = @_;

    sub {
        $ENV{PERL5LIB} = join ':', @INC;
        $ENV{BOT_NET_CONFIG_PATH} = File::Spec->catfile(
            $FindBin::Bin, '..', 't', 'etc'
        );
        exec(@program);
    };
}

on _start => run {
    yield 'spawn_all_servers';
    yield 'spawn_all_bots_after_servers';
    yield 'connect_after_bots';

    delay 'shutdown_unless_something_happened', 30;

    remember something_happened => 0;

    get(KERNEL)->sig(CHLD => 'child_reaper');
};

=head2 on spawn_all_servers

For each server added in the test file, tell those servers to start.

=cut

on spawn_all_servers => run {
    for my $server (keys %{ Bot::Net::Test->servers }) {
        Bot::Net::Test->log->info("Starting server $server");

        my $server_name = $server;
        $server_name =~ s/\W+/_/g;

        my $wheel = POE::Wheel::Run->new(
            Program      => _run_that(
                File::Spec->catfile('bin', 'botnet'),
                qw/ run --server /, $server,
            ),

            StdinEvent   => "server_${server_name}_stdin",
            StdoutEvent  => "server_${server_name}_stdout",
            StderrEvent  => "server_${server_name}_stderr",

            ErrorEvent   => "server_${server_name}_error",
            CloseEvent   => "server_${server_name}_close",



( run in 1.624 second using v1.01-cache-2.11-cpan-13bb782fe5a )