rufus-scheduler 2.0.6 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,63 +5,198 @@
5
5
  # Sat Mar 21 12:55:27 JST 2009
6
6
  #
7
7
 
8
- require File.dirname(__FILE__) + '/spec_base'
9
-
10
-
11
- def cl (cronline_string)
12
- Rufus::CronLine.new(cronline_string)
13
- end
8
+ require File.join(File.dirname(__FILE__), 'spec_base')
14
9
 
15
10
 
16
11
  describe Rufus::CronLine do
17
12
 
18
- def should (line, array)
13
+ def cl(cronline_string)
14
+ Rufus::CronLine.new(cronline_string)
15
+ end
19
16
 
20
- cl(line).to_array.should.equal(array)
17
+ def match(line, time)
18
+ cl(line).matches?(time).should == true
19
+ end
20
+ def to_a(line, array)
21
+ cl(line).to_array.should == array
21
22
  end
22
23
 
23
- it 'should interpret cron strings correctly' do
24
-
25
- should '* * * * *', [ [0], nil, nil, nil, nil, nil ]
26
- should '10-12 * * * *', [ [0], [10, 11, 12], nil, nil, nil, nil ]
27
- should '* * * * sun,mon', [ [0], nil, nil, nil, nil, [0, 1] ]
28
- should '* * * * mon-wed', [ [0], nil, nil, nil, nil, [1, 2, 3] ]
29
- should '* * * * 7', [ [0], nil, nil, nil, nil, [0] ]
30
- should '* * * * 0', [ [0], nil, nil, nil, nil, [0] ]
31
- should '* * * * 0,1', [ [0], nil, nil, nil, nil, [0,1] ]
32
- should '* * * * 7,1', [ [0], nil, nil, nil, nil, [0,1] ]
33
- should '* * * * 7,0', [ [0], nil, nil, nil, nil, [0] ]
34
- should '* * * * sun,2-4', [ [0], nil, nil, nil, nil, [0, 2, 3, 4] ]
35
-
36
- should '* * * * sun,mon-tue', [ [0], nil, nil, nil, nil, [0, 1, 2] ]
37
-
38
- should '* * * * * *', [ nil, nil, nil, nil, nil, nil ]
39
- should '1 * * * * *', [ [1], nil, nil, nil, nil, nil ]
40
- should '7 10-12 * * * *', [ [7], [10, 11, 12], nil, nil, nil, nil ]
41
- should '1-5 * * * * *', [ [1,2,3,4,5], nil, nil, nil, nil, nil ]
24
+ def local(*args)
25
+ Time.local(*args)
42
26
  end
43
- end
27
+ def utc(*args)
28
+ Time.utc(*args)
29
+ end
30
+
31
+ describe '.new' do
32
+
33
+ it 'interprets cron strings correctly' do
34
+
35
+ to_a '* * * * *', [ [0], nil, nil, nil, nil, nil, nil ]
36
+ to_a '10-12 * * * *', [ [0], [10, 11, 12], nil, nil, nil, nil, nil ]
37
+ to_a '* * * * sun,mon', [ [0], nil, nil, nil, nil, [0, 1], nil ]
38
+ to_a '* * * * mon-wed', [ [0], nil, nil, nil, nil, [1, 2, 3], nil ]
39
+ to_a '* * * * 7', [ [0], nil, nil, nil, nil, [0], nil ]
40
+ to_a '* * * * 0', [ [0], nil, nil, nil, nil, [0], nil ]
41
+ to_a '* * * * 0,1', [ [0], nil, nil, nil, nil, [0,1], nil ]
42
+ to_a '* * * * 7,1', [ [0], nil, nil, nil, nil, [0,1], nil ]
43
+ to_a '* * * * 7,0', [ [0], nil, nil, nil, nil, [0], nil ]
44
+ to_a '* * * * sun,2-4', [ [0], nil, nil, nil, nil, [0, 2, 3, 4], nil ]
45
+
46
+ to_a '* * * * sun,mon-tue', [ [0], nil, nil, nil, nil, [0, 1, 2], nil ]
47
+
48
+ to_a '* * * * * *', [ nil, nil, nil, nil, nil, nil, nil ]
49
+ to_a '1 * * * * *', [ [1], nil, nil, nil, nil, nil, nil ]
50
+ to_a '7 10-12 * * * *', [ [7], [10, 11, 12], nil, nil, nil, nil, nil ]
51
+ to_a '1-5 * * * * *', [ [1,2,3,4,5], nil, nil, nil, nil, nil, nil ]
52
+ end
53
+
54
+ it 'interprets cron strings with TZ correctly' do
55
+
56
+ to_a '* * * * * EST', [ [0], nil, nil, nil, nil, nil, 'EST' ]
57
+ to_a '* * * * * * EST', [ nil, nil, nil, nil, nil, nil, 'EST' ]
58
+
59
+ lambda { cl '* * * * * NotATimeZone' }.should raise_error
60
+ lambda { cl '* * * * * * NotATimeZone' }.should raise_error
61
+ end
62
+ end
63
+
64
+ describe '#next_time' do
65
+
66
+ def nt(cronline, now)
67
+ Rufus::CronLine.new(cronline).next_time(now)
68
+ end
69
+
70
+ it 'computes the next occurence correctly' do
71
+
72
+ now = Time.at(0).getutc # Thu Jan 01 00:00:00 UTC 1970
73
+
74
+ nt('* * * * *', now).should == now + 60
75
+ nt('* * * * sun', now).should == now + 259200
76
+ nt('* * * * * *', now).should == now + 1
77
+ nt('* * 13 * fri', now).should == now + 3715200
78
+
79
+ nt('10 12 13 12 *', now).should == now + 29938200
80
+ # this one is slow (1 year == 3 seconds)
81
+
82
+ nt('0 0 * * thu', now).should == now + 604800
83
+
84
+ now = local(2008, 12, 31, 23, 59, 59, 0)
85
+
86
+ nt('* * * * *', now).should == now + 1
87
+ end
44
88
 
45
- describe 'Rufus::CronLine#next_time' do
89
+ #
90
+ # the specs that follow are from Tanzeeb Khalili
91
+ #
92
+
93
+ it 'computes the next occurence correctly in UTC (TZ not specified)' do
94
+
95
+ now = utc(1970, 1, 1)
96
+
97
+ nt('* * * * *', now).should == utc(1970, 1, 1, 0, 1)
98
+ nt('* * * * sun', now).should == utc(1970, 1, 4)
99
+ nt('* * * * * *', now).should == utc(1970, 1, 1, 0, 0, 1)
100
+ nt('* * 13 * fri', now).should == utc(1970, 2, 13)
101
+
102
+ nt('10 12 13 12 *', now).should == utc(1970, 12, 13, 12, 10)
103
+ # this one is slow (1 year == 3 seconds)
104
+ nt('* * 1 6 *', now).should == utc(1970, 6, 1)
105
+
106
+ nt('0 0 * * thu', now).should == utc(1970, 1, 8)
107
+ end
46
108
 
47
- it 'should compute next occurence correctly' do
109
+ it 'computes the next occurence correctly in local TZ (TZ not specified)' do
48
110
 
49
- now = Time.at(0).utc # Thu Jan 01 00:00:00 UTC 1970
111
+ now = local(1970, 1, 1)
50
112
 
51
- cl('* * * * *').next_time(now).should.equal(now + 60)
52
- cl('* * * * sun').next_time(now).should.equal(now + 259200)
53
- cl('* * * * * *').next_time(now).should.equal(now + 1)
54
- cl('* * 13 * fri').next_time(now).should.equal(now + 3715200)
113
+ nt('* * * * *', now).should == local(1970, 1, 1, 0, 1)
114
+ nt('* * * * sun', now).should == local(1970, 1, 4)
115
+ nt('* * * * * *', now).should == local(1970, 1, 1, 0, 0, 1)
116
+ nt('* * 13 * fri', now).should == local(1970, 2, 13)
55
117
 
56
- cl('10 12 13 12 *').next_time(now).should.equal(now + 29938200)
57
- # this one is slow (1 year == 3 seconds)
118
+ nt('10 12 13 12 *', now).should == local(1970, 12, 13, 12, 10)
119
+ # this one is slow (1 year == 3 seconds)
120
+ nt('* * 1 6 *', now).should == local(1970, 6, 1)
58
121
 
59
- cl('0 0 * * thu').next_time(now).should.equal(now + 604800)
122
+ nt('0 0 * * thu', now).should == local(1970, 1, 8)
123
+ end
60
124
 
61
- now = Time.local(2008, 12, 31, 23, 59, 59, 0)
125
+ it 'computes the next occurence correctly in UTC (TZ specified)' do
62
126
 
63
- cl('* * * * *').next_time(now).should.equal(now + 1)
127
+ zone = 'Europe/Stockholm'
128
+ tz = TZInfo::Timezone.get(zone)
129
+ now = tz.local_to_utc(local(1970, 1, 1))
130
+ # Midnight in zone, UTC
131
+
132
+ nt("* * * * * #{zone}", now).should == utc(1969, 12, 31, 23, 1)
133
+ nt("* * * * sun #{zone}", now).should == utc(1970, 1, 3, 23)
134
+ nt("* * * * * * #{zone}", now).should == utc(1969, 12, 31, 23, 0, 1)
135
+ nt("* * 13 * fri #{zone}", now).should == utc(1970, 2, 12, 23)
136
+
137
+ nt("10 12 13 12 * #{zone}", now).should == utc(1970, 12, 13, 11, 10)
138
+ nt("* * 1 6 * #{zone}", now).should == utc(1970, 5, 31, 23)
139
+
140
+ nt("0 0 * * thu #{zone}", now).should == utc(1970, 1, 7, 23)
141
+ end
142
+
143
+ #it 'computes the next occurence correctly in local TZ (TZ specified)' do
144
+ # zone = 'Europe/Stockholm'
145
+ # tz = TZInfo::Timezone.get(zone)
146
+ # now = tz.local_to_utc(utc(1970, 1, 1)).localtime
147
+ # # Midnight in zone, local time
148
+ # nt("* * * * * #{zone}", now).should == local(1969, 12, 31, 18, 1)
149
+ # nt("* * * * sun #{zone}", now).should == local(1970, 1, 3, 18)
150
+ # nt("* * * * * * #{zone}", now).should == local(1969, 12, 31, 18, 0, 1)
151
+ # nt("* * 13 * fri #{zone}", now).should == local(1970, 2, 12, 18)
152
+ # nt("10 12 13 12 * #{zone}", now).should == local(1970, 12, 13, 6, 10)
153
+ # nt("* * 1 6 * #{zone}", now).should == local(1970, 5, 31, 19)
154
+ # nt("0 0 * * thu #{zone}", now).should == local(1970, 1, 7, 18)
155
+ #end
64
156
  end
65
157
 
158
+ describe '#matches?' do
159
+
160
+ it 'matches correctly in UTC (TZ not specified)' do
161
+
162
+ match '* * * * *', utc(1970, 1, 1, 0, 1)
163
+ match '* * * * sun', utc(1970, 1, 4)
164
+ match '* * * * * *', utc(1970, 1, 1, 0, 0, 1)
165
+ match '* * 13 * fri', utc(1970, 2, 13)
166
+
167
+ match '10 12 13 12 *', utc(1970, 12, 13, 12, 10)
168
+ match '* * 1 6 *', utc(1970, 6, 1)
169
+
170
+ match '0 0 * * thu', utc(1970, 1, 8)
171
+ end
172
+
173
+ it 'matches correctly in local TZ (TZ not specified)' do
174
+
175
+ match '* * * * *', local(1970, 1, 1, 0, 1)
176
+ match '* * * * sun', local(1970, 1, 4)
177
+ match '* * * * * *', local(1970, 1, 1, 0, 0, 1)
178
+ match '* * 13 * fri', local(1970, 2, 13)
179
+
180
+ match '10 12 13 12 *', local(1970, 12, 13, 12, 10)
181
+ match '* * 1 6 *', local(1970, 6, 1)
182
+
183
+ match '0 0 * * thu', local(1970, 1, 8)
184
+ end
185
+
186
+ it 'matches correctly in UTC (TZ specified)' do
187
+
188
+ zone = 'Europe/Stockholm'
189
+
190
+ match "* * * * * #{zone}", utc(1969, 12, 31, 23, 1)
191
+ match "* * * * sun #{zone}", utc(1970, 1, 3, 23)
192
+ match "* * * * * * #{zone}", utc(1969, 12, 31, 23, 0, 1)
193
+ match "* * 13 * fri #{zone}", utc(1970, 2, 12, 23)
194
+
195
+ match "10 12 13 12 * #{zone}", utc(1970, 12, 13, 11, 10)
196
+ match "* * 1 6 * #{zone}", utc(1970, 5, 31, 23)
197
+
198
+ match "0 0 * * thu #{zone}", utc(1970, 1, 7, 23)
199
+ end
200
+ end
66
201
  end
67
202
 
@@ -5,32 +5,32 @@
5
5
  # Sun Mar 22 12:26:07 JST 2009
6
6
  #
7
7
 
8
- require File.dirname(__FILE__) + '/spec_base'
8
+ require File.join(File.dirname(__FILE__), 'spec_base')
9
9
 
10
10
 
11
11
  describe "#{SCHEDULER_CLASS}#every" do
12
12
 
13
- before do
13
+ before(:each) do
14
14
  @s = start_scheduler
15
15
  end
16
- after do
16
+ after(:each) do
17
17
  stop_scheduler(@s)
18
18
  end
19
19
 
20
- it 'should have job ids with the class name in it' do
20
+ it 'has job ids with the class name in it' do
21
21
 
22
22
  j0 = @s.every(1) {}
23
- j0.job_id.should.match(/Rufus::Scheduler::EveryJob/)
23
+ j0.job_id.should match(/Rufus::Scheduler::EveryJob/)
24
24
  end
25
25
 
26
- it 'should compute frequency' do
26
+ it 'computes frequency' do
27
27
 
28
28
  job = @s.every '2h1m' do
29
29
  end
30
- job.frequency.should.equal(7260)
30
+ job.frequency.should == 7260
31
31
  end
32
32
 
33
- it 'should schedule every 1s' do
33
+ it 'schedules every 1s' do
34
34
 
35
35
  var = 0
36
36
 
@@ -40,10 +40,10 @@ describe "#{SCHEDULER_CLASS}#every" do
40
40
 
41
41
  sleep 3.7
42
42
 
43
- var.should.equal(3)
43
+ var.should == 3
44
44
  end
45
45
 
46
- it 'should be punctilious' do
46
+ it 'is punctilious' do
47
47
 
48
48
  hits = []
49
49
 
@@ -58,10 +58,10 @@ describe "#{SCHEDULER_CLASS}#every" do
58
58
  hits.each { |h| f = h; deltas << (f - hh) if hh; hh = f }
59
59
 
60
60
  #puts; p deltas
61
- deltas.max.should.satisfy { |d| d < 1.200 }
61
+ deltas.max.should satisfy { |d| d < 1.200 }
62
62
  end
63
63
 
64
- it 'should unschedule' do
64
+ it 'unschedules' do
65
65
 
66
66
  var = 0
67
67
 
@@ -73,25 +73,25 @@ describe "#{SCHEDULER_CLASS}#every" do
73
73
 
74
74
  @s.unschedule(job.job_id)
75
75
 
76
- var.should.equal(2)
76
+ var.should == 2
77
77
 
78
78
  sleep 1.7
79
79
 
80
- var.should.equal(2)
80
+ var.should == 2
81
81
  end
82
82
 
83
- it 'should accept tags for jobs' do
83
+ it 'accepts tags for jobs' do
84
84
 
85
85
  job = @s.every '1s', :tags => 'spec' do
86
86
  end
87
87
 
88
88
  wait_next_tick
89
89
 
90
- @s.find_by_tag('spec').size.should.equal(1)
91
- @s.find_by_tag('spec').first.job_id.should.equal(job.job_id)
90
+ @s.find_by_tag('spec').size.should == 1
91
+ @s.find_by_tag('spec').first.job_id.should == job.job_id
92
92
  end
93
93
 
94
- it 'should honour :first_at' do
94
+ it 'honours :first_at' do
95
95
 
96
96
  counter = 0
97
97
 
@@ -100,13 +100,13 @@ describe "#{SCHEDULER_CLASS}#every" do
100
100
  end
101
101
 
102
102
  sleep 1
103
- counter.should.equal(0)
103
+ counter.should == 0
104
104
 
105
105
  sleep 2.5
106
- counter.should.equal(2)
106
+ counter.should == 2
107
107
  end
108
108
 
109
- it 'should honour :first_in' do
109
+ it 'honours :first_in' do
110
110
 
111
111
  counter = 0
112
112
 
@@ -115,13 +115,13 @@ describe "#{SCHEDULER_CLASS}#every" do
115
115
  end
116
116
 
117
117
  sleep 1
118
- counter.should.equal(0)
118
+ counter.should == 0
119
119
 
120
120
  sleep 2.5
121
- counter.should.equal(2)
121
+ counter.should == 2
122
122
  end
123
123
 
124
- #it 'should honour :dont_reschedule' do
124
+ #it 'honours :dont_reschedule' do
125
125
  # stack = []
126
126
  # @s.every 0.400 do |job|
127
127
  # if stack.size > 3
@@ -136,7 +136,7 @@ describe "#{SCHEDULER_CLASS}#every" do
136
136
  # stack.should.equal(%w[ ok ok ok ok done ])
137
137
  #end
138
138
 
139
- it 'should accept job.unschedule within the job' do
139
+ it 'accepts job.unschedule within the job' do
140
140
 
141
141
  stack = []
142
142
 
@@ -151,11 +151,11 @@ describe "#{SCHEDULER_CLASS}#every" do
151
151
 
152
152
  sleep 4
153
153
 
154
- @s.jobs.size.should.equal(0)
155
- stack.should.equal(%w[ ok ok ok ok done ])
154
+ @s.jobs.size.should == 0
155
+ stack.should == %w[ ok ok ok ok done ]
156
156
  end
157
157
 
158
- it 'should respect :blocking => true' do
158
+ it 'respects :blocking => true' do
159
159
 
160
160
  stack = []
161
161
 
@@ -166,28 +166,66 @@ describe "#{SCHEDULER_CLASS}#every" do
166
166
 
167
167
  sleep 5
168
168
 
169
- stack.should.equal(%w[ ok ok ])
169
+ stack.should == %w[ ok ok ]
170
170
  end
171
171
 
172
+ it 'lists the "trigger threads"' do
173
+
174
+ @s.every '1s' do
175
+ sleep 10
176
+ end
177
+ sleep 5
178
+
179
+ @s.trigger_threads.size.should == 4
180
+ end
172
181
  end
173
182
 
174
183
  describe Rufus::Scheduler::EveryJob do
175
184
 
176
- before do
185
+ before(:each) do
177
186
  @s = start_scheduler
178
187
  end
179
- after do
188
+ after(:each) do
180
189
  stop_scheduler(@s)
181
190
  end
182
191
 
183
- it 'should respond to #next_time' do
192
+ it 'responds to #next_time' do
184
193
 
185
194
  t = Time.now + 3 * 3600
186
195
 
187
196
  job = @s.every '3h' do
188
197
  end
189
198
 
190
- job.next_time.to_i.should.equal(t.to_i)
199
+ job.next_time.to_i.should == t.to_i
200
+ end
201
+
202
+
203
+ it 'does not allow a job to overlap execution if set !allow_overlapping' do
204
+
205
+ stack = []
206
+
207
+ @s.every '1s', :allow_overlapping => false do |job|
208
+ stack << 'ok'
209
+ sleep 2
210
+ end
211
+
212
+ sleep 5
213
+
214
+ stack.size.should == 2
215
+ end
216
+
217
+ it 'allows a job to overlap execution (backward compatibility?)' do
218
+
219
+ stack = []
220
+
221
+ @s.every '1s' do |job|
222
+ stack << 'ok'
223
+ sleep 2
224
+ end
225
+
226
+ sleep 5
227
+
228
+ stack.size.should == 4
191
229
  end
192
230
  end
193
231