#!perl
-
use strict;
use warnings;
use FindBin;
-use lib "$FindBin::Bin/lib";
-use Test::More;
-use Storable qw/lock_store lock_retrieve/;
-
-plan tests => 10;
+use lib "$FindBin::Bin/lib";
+use Test::More 'no_plan';
use Catalyst::Test 'TestApp';
-our $STATE = "$FindBin::Bin/lib/TestApp/scheduler.state";
-
-TestApp->schedule(
- at => '* * * * *',
- event => '/cron/every_minute',
+our $HOME = "$FindBin::Bin/lib/TestApp";
+our $STATE = "$HOME/scheduler.state";
+our $URL = 'http://localhost/';
+our $BASE = 'Catalyst::Plugin::Scheduler::Base';
+our $Error = 'oops';
+our $Filter = 0;
+our @Map = (
+ # at # event # output
+ [ '* * * * *' , '/cron/every_minute' , qr/every_minute/ ],
+ [ '@hourly' , \&every_hour , qr/every_hour/ ],
+ [ '*/2 * * * *' , '/cron/test_errors' , qr/$Error/ ],
+ [ '0 * * * *' , \&broken_event , qr/$Error/ ],
);
-TestApp->schedule(
- at => '@hourly',
- event => \&every_hour,
-);
+### clean up
+END { 1 while unlink $STATE }
-# events with errors to test the error handling
-TestApp->schedule(
- at => '*/2 * * * *',
- event => '/cron/test_errors',
-);
+### filter expected error messages, when needed...
+{ my $org = Catalyst::Log->can('_send_to_log');
+
+ no warnings 'redefine';
+ *Catalyst::Log::_send_to_log = sub {
+ return if $Filter and "@_" =~ /Scheduler: Error executing/;
+ $org->( @_ );
+ };
+}
+
+### set up some schedules
+{ for my $aref ( @Map ) {
+ my($at,$event) = @$aref;
+
+ TestApp->schedule(
+ at => $at,
+ event => $event,
+ );
+ }
+
+ sub every_hour {
+ my $c = shift;
+
+ # write out a file so the test knows we did something
+ my $fh = IO::File->new( $c->path_to( 'every_hour.log' ), 'w' )
+ or die "Unable to write log file: $!";
+ close $fh;
+ return 'every_hour';
+ }
+
+ sub broken_event { die $Error; }
+}
-TestApp->schedule(
- at => '0 * * * *',
- event => \&broken_event,
-);
# hack the last event check to make all events execute immediately
-my $state = { last_check => 0 };
-lock_store $state, $STATE;
-
-# test that all events execute, and that the error test doesn't break the app
-{
- open STDERR, '>/dev/null';
- ok( my $res = request('http://localhost/'), 'request ok' );
- is( $res->content, 'default', 'response ok' );
- is( -e "$FindBin::Bin/lib/TestApp/every_minute.log", 1, 'every_minute executed ok' );
- unlink "$FindBin::Bin/lib/TestApp/every_minute.log";
- is( -e "$FindBin::Bin/lib/TestApp/every_hour.log", 1, 'every_hour executed ok' );
- unlink "$FindBin::Bin/lib/TestApp/every_hour.log";
+$BASE->_last_check_time( 0 );
+
+### test that all events execute, and that the error test doesn't break the app
+{ ### there's an event that dies on purpose. dont have the error message
+ ### appear on the terminal
+ { local $Filter = 1;
+ ok( my $res = request($URL), 'request ok' );
+ is( $res->content, 'default',' response ok' );
+ }
+
+ ok( -e "$HOME/every_minute.log", ' every_minute executed ok' );
+ 1 while unlink "$HOME/every_minute.log";
+
+ ok( -e "$HOME/every_hour.log", ' every_hour executed ok' );
+ 1 while unlink "$HOME/every_hour.log";
}
-# run again, the events should not execute
-{
- ok( my $res = request('http://localhost/'), 'request ok' );
- is( -e "$FindBin::Bin/lib/TestApp/every_minute.log", undef, 'every_minute did not execute, ok' );
- unlink "$FindBin::Bin/lib/TestApp/every_minute.log";
- is( -e "$FindBin::Bin/lib/TestApp/every_hour.log", undef, 'every_hour did not execute, ok' );
- unlink "$FindBin::Bin/lib/TestApp/every_hour.log";
+
+
+### run again, the events should not execute
+{ ok( request($URL), 'request ok' );
+
+ ok( !-e "$HOME/every_minute.log", ' every_minute did not execute, ok' );
+ 1 while unlink "$HOME/every_minute.log";
+
+ ok( !-e "$HOME/every_hour.log", ' every_hour did not execute, ok' );
+ 1 while unlink "$HOME/every_hour.log";
}
-# jump back in time by 2 hours, make sure both events run
-{
- my $state = lock_retrieve $STATE;
- $state->{last_check} -= 60 * 120;
- lock_store $state, $STATE;
+### jump back in time by 2 hours, make sure both events run
+{ $BASE->_last_check_time( time - 60 * 120 );
+
+ ### there's an event that dies on purpose. dont have the error message
+ ### appear on the terminal
+ { local $Filter = 1;
+ ok( request($URL), 'request ok' );
+ }
- ok( my $res = request('http://localhost/'), 'request ok' );
- is( -e "$FindBin::Bin/lib/TestApp/every_minute.log", 1, 'every_minute executed ok' );
- unlink "$FindBin::Bin/lib/TestApp/every_minute.log";
- is( -e "$FindBin::Bin/lib/TestApp/every_hour.log", 1, 'every_hour executed ok' );
- unlink "$FindBin::Bin/lib/TestApp/every_hour.log";
+ ok( -e "$HOME/every_minute.log", ' every_minute executed ok' );
+ 1 while unlink "$HOME/every_minute.log";
+
+ ok( -e "$HOME/every_hour.log", ' every_hour executed ok' );
+ 1 while unlink "$HOME/every_hour.log";
}
-###
+### check the scheduler state
+{ my $ss = TestApp->scheduler_state;
-sub every_hour {
- my $c = shift;
-
- # write out a file so the test knows we did something
- my $fh = IO::File->new( $c->path_to( 'every_hour.log' ), 'w' )
- or die "Unable to write log file: $!";
- close $fh;
+ ok( $ss, 'Scheduler state retrieved' );
+ isa_ok( $ss, 'ARRAY' );
+ is( scalar(@$ss), scalar(@Map), " All events found" );
+
+ ### key entries on 'event';
+ my %map = map { $_->{event} => $_ } @$ss;
+
+ for my $aref ( @Map ) {
+ my($at,$event,$expect) = @$aref;
+
+ my $entry = $map{$event};
+ ok( $entry, " Event found for $event" );
+ ok( $entry->{'last_run'}, " Event was run" );
+ like( $entry->{'last_output'}, $expect,
+ " Output as expected" );
+ }
+}
+
+### extended API tests
+### test event listing
+{ my @events = TestApp->scheduler->list_events;
+ is( scalar(@events), scalar(@Map), "list_events() returns all events" );
+ isa_ok( $_, "Catalyst::Plugin::Scheduler::Event" )
+ for @events;
}
-sub broken_event {
- my $c = shift;
+### test pending events
+{ ### all events should have run now
+
+ { my @pending = TestApp->scheduler->list_pending_events;
+ is( scalar(@pending), 0, "No more pending events" );
+ }
+
+ # hack the last event check to make all events execute immediately
+ { $BASE->_last_check_time( 0 );
- die 'oops';
+ my @pending = TestApp->scheduler->list_pending_events;
+ is( scalar(@pending), scalar(@Map),
+ " Events found after state reset" );
+ }
+}
+
+### clean up
+{ ok( -e $STATE, "State file exists" );
+ 1 while unlink $STATE;
+ ok(!-e $STATE, " State file removed" );
}
+
+
+
+
+
+
+
+
+