5f742d3339a55f0da6da88acc78a2e6020be5121
[catagits/Catalyst-Plugin-Scheduler.git] / t / 04schedule.t
1 #!perl
2 use strict;
3 use warnings;
4
5 use FindBin;
6 use lib             "$FindBin::Bin/lib";
7 use Test::More      'no_plan';
8 use Catalyst::Test 'TestApp';
9
10 our $HOME   = "$FindBin::Bin/lib/TestApp";
11 our $STATE  = "$HOME/scheduler.state";
12 our $URL    = 'http://localhost/';
13 our $BASE   = 'Catalyst::Plugin::Scheduler::Base';
14 our $Error  = 'oops';
15 our $Filter = 0;
16 our @Map    = (
17     # at               # event              # output
18     [ '* * * * *'   , '/cron/every_minute'  , qr/every_minute/  ],
19     [ '@hourly'     , \&every_hour          , qr/every_hour/    ],
20     [ '*/2 * * * *' , '/cron/test_errors'   , qr/$Error/        ],
21     [ '0 * * * *'   , \&broken_event        , qr/$Error/        ],
22 );
23
24 ### clean up
25 END { 1 while unlink $STATE }
26
27 ### filter expected error messages, when needed...
28 {   my $org = Catalyst::Log->can('_send_to_log');
29
30     no warnings 'redefine';
31     *Catalyst::Log::_send_to_log = sub {
32         return if $Filter and "@_" =~ /Scheduler: Error executing/;
33         $org->( @_ );
34     };
35 }
36
37 ### set up some schedules
38 {   for my $aref ( @Map ) {
39         my($at,$event) = @$aref;
40
41         TestApp->schedule(
42             at    => $at,
43             event => $event,
44         );
45     }
46     
47     sub every_hour {
48         my $c = shift;
49         
50         # write out a file so the test knows we did something
51         my $fh = IO::File->new( $c->path_to( 'every_hour.log' ), 'w' )
52             or die "Unable to write log file: $!";
53         close $fh;
54         return 'every_hour';
55     }
56     
57     sub broken_event { die $Error; }
58 }
59
60
61 # hack the last event check to make all events execute immediately
62 $BASE->_last_check_time( 0 );
63
64 ### test that all events execute, and that the error test doesn't break the app
65 {   ### there's an event that dies on purpose. dont have the error message
66     ### appear on the terminal
67     {   local $Filter = 1;
68         ok( my $res = request($URL), 'request ok' );
69         is( $res->content, 'default','   response ok' );
70     }
71
72     ok( -e "$HOME/every_minute.log",    '   every_minute executed ok' );
73     1 while unlink "$HOME/every_minute.log";
74
75     ok( -e "$HOME/every_hour.log",      '   every_hour executed ok' );
76     1 while unlink "$HOME/every_hour.log";
77 }
78
79
80
81 ### run again, the events should not execute
82 {   ok( request($URL),                  'request ok' );
83
84     ok( !-e "$HOME/every_minute.log",   '   every_minute did not execute, ok' );
85     1 while unlink "$HOME/every_minute.log";
86     
87     ok( !-e "$HOME/every_hour.log",     '   every_hour did not execute, ok' );
88     1 while unlink "$HOME/every_hour.log";
89 }
90
91 ### jump back in time by 2 hours, make sure both events run
92 {   $BASE->_last_check_time( time - 60 * 120 );
93    
94     ### there's an event that dies on purpose. dont have the error message
95     ### appear on the terminal
96     {   local $Filter = 1;
97         ok( request($URL),              'request ok' );
98     }
99     
100     ok( -e "$HOME/every_minute.log",    '   every_minute executed ok' );
101     1 while unlink "$HOME/every_minute.log";
102
103     ok( -e "$HOME/every_hour.log",      '   every_hour executed ok' );
104     1 while unlink "$HOME/every_hour.log";
105 }
106
107 ### check the scheduler state
108 {   my $ss = TestApp->scheduler_state;
109
110     ok( $ss,                            'Scheduler state retrieved' );
111     isa_ok( $ss,                        'ARRAY' );
112     is( scalar(@$ss), scalar(@Map),     "   All events found" );
113
114     ### key entries on 'event';
115     my %map = map { $_->{event} => $_ } @$ss;
116
117     for my $aref ( @Map ) {
118         my($at,$event,$expect) = @$aref;
119         
120         my $entry = $map{$event};
121         ok( $entry,                     "   Event found for $event" );
122         ok( $entry->{'last_run'},       "       Event was run" );
123         like( $entry->{'last_output'}, $expect,
124                                         "       Output as expected" );
125     }
126 }
127
128 ### extended API tests
129 ### test event listing
130 {   my @events = TestApp->scheduler->list_events;
131     is( scalar(@events), scalar(@Map),  "list_events() returns all events" );
132     isa_ok( $_,                         "Catalyst::Plugin::Scheduler::Event" )
133         for @events;
134 }
135
136 ### test pending events
137 {   ### all events should have run now
138
139     {   my @pending = TestApp->scheduler->list_pending_events;
140         is( scalar(@pending), 0,        "No more pending events" );
141     }
142
143     # hack the last event check to make all events execute immediately
144     {   $BASE->_last_check_time( 0 );
145     
146         my @pending = TestApp->scheduler->list_pending_events;
147         is( scalar(@pending), scalar(@Map),
148                                         "   Events found after state reset" );
149     }
150 }
151
152 ### clean up
153 {   ok( -e $STATE,                      "State file exists" );
154     1 while unlink $STATE;
155     ok(!-e $STATE,                      "   State file removed" );
156 }
157
158
159
160
161
162
163
164
165