Commit | Line | Data |
cbf1ecfe |
1 | #!perl |
cbf1ecfe |
2 | use strict; |
3 | use warnings; |
4 | |
5 | use FindBin; |
ba2735b6 |
6 | use lib "$FindBin::Bin/lib"; |
7 | use Test::More 'no_plan'; |
cbf1ecfe |
8 | use Catalyst::Test 'TestApp'; |
9 | |
ba2735b6 |
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/ ], |
cbf1ecfe |
22 | ); |
23 | |
ba2735b6 |
24 | ### clean up |
25 | END { 1 while unlink $STATE } |
cbf1ecfe |
26 | |
ba2735b6 |
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 | } |
cbf1ecfe |
59 | |
cbf1ecfe |
60 | |
61 | # hack the last event check to make all events execute immediately |
ba2735b6 |
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"; |
cbf1ecfe |
77 | } |
78 | |
ba2735b6 |
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"; |
cbf1ecfe |
89 | } |
90 | |
ba2735b6 |
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 | } |
cbf1ecfe |
99 | |
ba2735b6 |
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"; |
cbf1ecfe |
105 | } |
106 | |
ba2735b6 |
107 | ### check the scheduler state |
108 | { my $ss = TestApp->scheduler_state; |
cbf1ecfe |
109 | |
ba2735b6 |
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; |
cbf1ecfe |
134 | } |
135 | |
ba2735b6 |
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 ); |
cbf1ecfe |
145 | |
ba2735b6 |
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" ); |
cbf1ecfe |
156 | } |
ba2735b6 |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |