Changes:
[catagits/Catalyst-Plugin-Scheduler.git] / t / 04schedule.t
index f5fab3c..5f742d3 100644 (file)
 #!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" );
 }
+
+
+
+
+
+
+
+
+