rufus-scheduler 3.0.8 → 3.1.0
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.
- data/CHANGELOG.txt +13 -0
- data/CREDITS.txt +5 -0
- data/LICENSE.txt +1 -1
- data/README.md +73 -13
- data/lib/rufus/scheduler/cronline.rb +78 -74
- data/lib/rufus/scheduler/job_array.rb +2 -1
- data/lib/rufus/scheduler/jobs.rb +30 -28
- data/lib/rufus/scheduler/locks.rb +95 -0
- data/lib/rufus/scheduler/util.rb +2 -25
- data/lib/rufus/scheduler/zones.rb +174 -0
- data/lib/rufus/scheduler/zotime.rb +154 -0
- data/lib/rufus/scheduler.rb +61 -61
- data/rufus-scheduler.gemspec +2 -27
- data/spec/basics_spec.rb +16 -11
- data/spec/cronline_spec.rb +152 -103
- data/spec/job_cron_spec.rb +22 -0
- data/spec/job_every_spec.rb +14 -0
- data/spec/job_repeat_spec.rb +1 -0
- data/spec/lock_flock_spec.rb +47 -0
- data/spec/lock_spec.rb +59 -0
- data/spec/parse_spec.rb +29 -27
- data/spec/schedule_at_spec.rb +1 -1
- data/spec/scheduler_spec.rb +5 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/zotime_spec.rb +396 -0
- metadata +20 -20
- /data/spec/{custom_locks_spec.rb → lock_custom_spec.rb} +0 -0
- /data/spec/{lockfile_spec.rb → lock_lockfile_spec.rb} +0 -0
data/spec/basics_spec.rb
CHANGED
|
@@ -19,17 +19,22 @@ describe 'basics' do
|
|
|
19
19
|
|
|
20
20
|
it 'accepts a timezone final argument' do
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
if jruby? or ruby18?
|
|
23
|
+
|
|
24
|
+
expect(true).to be(true)
|
|
25
|
+
|
|
26
|
+
else
|
|
27
|
+
|
|
28
|
+
expect(
|
|
29
|
+
tts(Time.new(2014, 1, 1, 1, 0, 0, '+01:00'))
|
|
30
|
+
).to eq('2014-01-01 01:00:00 +0100')
|
|
31
|
+
expect(
|
|
32
|
+
tts(Time.new(2014, 8, 1, 1, 0, 0, '+01:00'))
|
|
33
|
+
).to eq('2014-08-01 01:00:00 +0100')
|
|
34
|
+
expect(
|
|
35
|
+
tts(Time.new(2014, 8, 1, 1, 0, 0, '+01:00'))
|
|
36
|
+
).to eq('2014-08-01 01:00:00 +0100')
|
|
37
|
+
end
|
|
33
38
|
end
|
|
34
39
|
end
|
|
35
40
|
|
data/spec/cronline_spec.rb
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
# Sat Mar 21 12:55:27 JST 2009
|
|
6
6
|
#
|
|
7
7
|
|
|
8
|
-
require 'tzinfo'
|
|
9
8
|
require 'spec_helper'
|
|
10
9
|
|
|
11
10
|
|
|
@@ -15,6 +14,24 @@ describe Rufus::Scheduler::CronLine do
|
|
|
15
14
|
Rufus::Scheduler::CronLine.new(cronline_string)
|
|
16
15
|
end
|
|
17
16
|
|
|
17
|
+
def nt(cronline, now)
|
|
18
|
+
Rufus::Scheduler::CronLine.new(cronline).next_time(now)
|
|
19
|
+
end
|
|
20
|
+
def ntz(cronline, now)
|
|
21
|
+
tz = cronline.split.last
|
|
22
|
+
tu = nt(cronline, now).utc
|
|
23
|
+
in_zone(tz) { tu.getlocal }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def pt(cronline, now)
|
|
27
|
+
Rufus::Scheduler::CronLine.new(cronline).previous_time(now)
|
|
28
|
+
end
|
|
29
|
+
def ptz(cronline, now)
|
|
30
|
+
tz = cronline.split.last
|
|
31
|
+
tu = pt(cronline, now).utc
|
|
32
|
+
in_zone(tz) { tu.getlocal }
|
|
33
|
+
end
|
|
34
|
+
|
|
18
35
|
def match(line, time)
|
|
19
36
|
expect(cl(line).matches?(time)).to eq(true)
|
|
20
37
|
end
|
|
@@ -49,12 +66,20 @@ describe Rufus::Scheduler::CronLine do
|
|
|
49
66
|
|
|
50
67
|
to_a '0 0 1 1 *', [ [0], [0], [0], [1], [1], nil, nil, nil ]
|
|
51
68
|
|
|
52
|
-
|
|
69
|
+
if ruby18?
|
|
70
|
+
to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
|
|
71
|
+
else
|
|
72
|
+
to_a '0 23-24 * * *', [ [0], [0], [23, 0], nil, nil, nil, nil, nil ]
|
|
73
|
+
end
|
|
53
74
|
#
|
|
54
75
|
# as reported by Aimee Rose in
|
|
55
76
|
# https://github.com/jmettraux/rufus-scheduler/issues/56
|
|
56
77
|
|
|
57
|
-
|
|
78
|
+
if ruby18?
|
|
79
|
+
to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
|
|
80
|
+
else
|
|
81
|
+
to_a '0 23-2 * * *', [ [0], [0], [23, 0, 1, 2], nil, nil, nil, nil, nil ]
|
|
82
|
+
end
|
|
58
83
|
end
|
|
59
84
|
|
|
60
85
|
it 'rejects invalid weekday expressions' do
|
|
@@ -92,7 +117,10 @@ describe Rufus::Scheduler::CronLine do
|
|
|
92
117
|
|
|
93
118
|
to_a(
|
|
94
119
|
'0 */2 * * *',
|
|
95
|
-
[ [0], [0], (0..
|
|
120
|
+
[ [0], [0], (0..23).select { |e| e.even? }, nil, nil, nil, nil, nil ])
|
|
121
|
+
to_a(
|
|
122
|
+
'0 0-23/2 * * *',
|
|
123
|
+
[ [0], [0], (0..23).select { |e| e.even? }, nil, nil, nil, nil, nil ])
|
|
96
124
|
to_a(
|
|
97
125
|
'0 7-23/2 * * *',
|
|
98
126
|
[ [0], [0], (7..23).select { |e| e.odd? }, nil, nil, nil, nil, nil ])
|
|
@@ -189,56 +217,34 @@ describe Rufus::Scheduler::CronLine do
|
|
|
189
217
|
|
|
190
218
|
describe '#next_time' do
|
|
191
219
|
|
|
192
|
-
def nt(cronline, now)
|
|
193
|
-
Rufus::Scheduler::CronLine.new(cronline).next_time(now)
|
|
194
|
-
end
|
|
195
|
-
def ntz(cronline, now)
|
|
196
|
-
tz = cronline.split.last
|
|
197
|
-
tu = nt(cronline, now).utc
|
|
198
|
-
in_zone(tz) { tu.getlocal }
|
|
199
|
-
end
|
|
200
|
-
|
|
201
220
|
it 'computes the next occurence correctly' do
|
|
202
221
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
expect(nt('* * * * *', now)).to eq(now + 60)
|
|
206
|
-
expect(nt('* * * * sun', now)).to eq(now + 259200)
|
|
207
|
-
expect(nt('* * * * * *', now)).to eq(now + 1)
|
|
208
|
-
expect(nt('* * 13 * fri', now)).to eq(now + 3715200)
|
|
209
|
-
|
|
210
|
-
expect(nt('10 12 13 12 *', now)).to eq(now + 29938200)
|
|
211
|
-
# this one is slow (1 year == 3 seconds)
|
|
212
|
-
#
|
|
213
|
-
# historical note:
|
|
214
|
-
# (comment made in 2006 or 2007, the underlying libs got better and
|
|
215
|
-
# that slowness is gone)
|
|
216
|
-
|
|
217
|
-
expect(nt('0 0 * * thu', now)).to eq(now + 604800)
|
|
218
|
-
expect(nt('00 0 * * thu', now)).to eq(now + 604800)
|
|
222
|
+
in_zone 'Europe/Berlin' do
|
|
219
223
|
|
|
220
|
-
|
|
221
|
-
expect(nt('0 24 * * *', now)).to eq(now + 24 * 3600)
|
|
224
|
+
now = Time.at(0) - 3600
|
|
222
225
|
|
|
223
|
-
|
|
226
|
+
expect(nt('* * * * *', now)).to eq(now + 60)
|
|
227
|
+
expect(nt('* * * * sun', now)).to eq(now + 259200)
|
|
228
|
+
expect(nt('* * * * * *', now)).to eq(now + 1)
|
|
229
|
+
expect(nt('* * 13 * fri', now)).to eq(now + 3715200)
|
|
224
230
|
|
|
225
|
-
|
|
226
|
-
|
|
231
|
+
expect(nt('10 12 13 12 *', now)).to eq(now + 29938200)
|
|
232
|
+
# this one is slow (1 year == 3 seconds)
|
|
233
|
+
#
|
|
234
|
+
# historical note:
|
|
235
|
+
# (comment made in 2006 or 2007, the underlying libs got better and
|
|
236
|
+
# that slowness is gone)
|
|
227
237
|
|
|
228
|
-
|
|
238
|
+
expect(nt('0 0 * * thu', now)).to eq(now + 604800)
|
|
239
|
+
expect(nt('00 0 * * thu', now)).to eq(now + 604800)
|
|
229
240
|
|
|
230
|
-
|
|
241
|
+
expect(nt('0 0 * * *', now)).to eq(now + 24 * 3600)
|
|
242
|
+
expect(nt('0 24 * * *', now)).to eq(now + 24 * 3600)
|
|
231
243
|
|
|
232
|
-
|
|
233
|
-
expect(nt('* * * * sun', now)).to eq(utc(1970, 1, 4))
|
|
234
|
-
expect(nt('* * * * * *', now)).to eq(utc(1970, 1, 1, 0, 0, 1))
|
|
235
|
-
expect(nt('* * 13 * fri', now)).to eq(utc(1970, 2, 13))
|
|
236
|
-
|
|
237
|
-
expect(nt('10 12 13 12 *', now)).to eq(utc(1970, 12, 13, 12, 10))
|
|
238
|
-
# this one is slow (1 year == 3 seconds)
|
|
239
|
-
expect(nt('* * 1 6 *', now)).to eq(utc(1970, 6, 1))
|
|
244
|
+
now = local(2008, 12, 31, 23, 59, 59, 0)
|
|
240
245
|
|
|
241
|
-
|
|
246
|
+
expect(nt('* * * * *', now)).to eq(now + 1)
|
|
247
|
+
end
|
|
242
248
|
end
|
|
243
249
|
|
|
244
250
|
it 'computes the next occurence correctly in local TZ (TZ not specified)' do
|
|
@@ -260,9 +266,7 @@ describe Rufus::Scheduler::CronLine do
|
|
|
260
266
|
it 'computes the next occurence correctly in UTC (TZ specified)' do
|
|
261
267
|
|
|
262
268
|
zone = 'Europe/Stockholm'
|
|
263
|
-
|
|
264
|
-
now = tz.local_to_utc(local(1970, 1, 1))
|
|
265
|
-
# Midnight in zone, UTC
|
|
269
|
+
now = in_zone(zone) { Time.local(1970, 1, 1) }
|
|
266
270
|
|
|
267
271
|
expect(nt("* * * * * #{zone}", now)).to eq(utc(1969, 12, 31, 23, 1))
|
|
268
272
|
expect(nt("* * * * sun #{zone}", now)).to eq(utc(1970, 1, 3, 23))
|
|
@@ -275,20 +279,6 @@ describe Rufus::Scheduler::CronLine do
|
|
|
275
279
|
expect(nt("0 0 * * thu #{zone}", now)).to eq(utc(1970, 1, 7, 23))
|
|
276
280
|
end
|
|
277
281
|
|
|
278
|
-
#it 'computes the next occurence correctly in local TZ (TZ specified)' do
|
|
279
|
-
# zone = 'Europe/Stockholm'
|
|
280
|
-
# tz = TZInfo::Timezone.get(zone)
|
|
281
|
-
# now = tz.local_to_utc(utc(1970, 1, 1)).localtime
|
|
282
|
-
# # Midnight in zone, local time
|
|
283
|
-
# nt("* * * * * #{zone}", now).should == local(1969, 12, 31, 18, 1)
|
|
284
|
-
# nt("* * * * sun #{zone}", now).should == local(1970, 1, 3, 18)
|
|
285
|
-
# nt("* * * * * * #{zone}", now).should == local(1969, 12, 31, 18, 0, 1)
|
|
286
|
-
# nt("* * 13 * fri #{zone}", now).should == local(1970, 2, 12, 18)
|
|
287
|
-
# nt("10 12 13 12 * #{zone}", now).should == local(1970, 12, 13, 6, 10)
|
|
288
|
-
# nt("* * 1 6 * #{zone}", now).should == local(1970, 5, 31, 19)
|
|
289
|
-
# nt("0 0 * * thu #{zone}", now).should == local(1970, 1, 7, 18)
|
|
290
|
-
#end
|
|
291
|
-
|
|
292
282
|
it 'computes the next time correctly when there is a sun#2 involved' do
|
|
293
283
|
|
|
294
284
|
expect(nt('* * * * sun#1', local(1970, 1, 1))).to eq(local(1970, 1, 4))
|
|
@@ -375,15 +365,6 @@ describe Rufus::Scheduler::CronLine do
|
|
|
375
365
|
|
|
376
366
|
describe '#previous_time' do
|
|
377
367
|
|
|
378
|
-
def pt(cronline, now)
|
|
379
|
-
Rufus::Scheduler::CronLine.new(cronline).previous_time(now)
|
|
380
|
-
end
|
|
381
|
-
def ptz(cronline, now)
|
|
382
|
-
tz = cronline.split.last
|
|
383
|
-
tu = pt(cronline, now).utc
|
|
384
|
-
in_zone(tz) { tu.getlocal }
|
|
385
|
-
end
|
|
386
|
-
|
|
387
368
|
it 'returns the previous time the cron should have triggered' do
|
|
388
369
|
|
|
389
370
|
expect(
|
|
@@ -438,21 +419,21 @@ describe Rufus::Scheduler::CronLine do
|
|
|
438
419
|
|
|
439
420
|
describe '#matches?' do
|
|
440
421
|
|
|
441
|
-
it 'matches correctly in UTC (TZ not specified)' do
|
|
442
|
-
|
|
443
|
-
match '* * * * *', utc(1970, 1, 1, 0, 1)
|
|
444
|
-
match '* * * * sun', utc(1970, 1, 4)
|
|
445
|
-
match '* * * * * *', utc(1970, 1, 1, 0, 0, 1)
|
|
446
|
-
match '* * 13 * fri', utc(1970, 2, 13)
|
|
447
|
-
|
|
448
|
-
match '10 12 13 12 *', utc(1970, 12, 13, 12, 10)
|
|
449
|
-
match '* * 1 6 *', utc(1970, 6, 1)
|
|
450
|
-
|
|
451
|
-
match '0 0 * * thu', utc(1970, 1, 8)
|
|
452
|
-
|
|
453
|
-
match '0 0 1 1 *', utc(2012, 1, 1)
|
|
454
|
-
no_match '0 0 1 1 *', utc(2012, 1, 1, 1, 0)
|
|
455
|
-
end
|
|
422
|
+
# it 'matches correctly in UTC (TZ not specified)' do
|
|
423
|
+
#
|
|
424
|
+
# match '* * * * *', utc(1970, 1, 1, 0, 1)
|
|
425
|
+
# match '* * * * sun', utc(1970, 1, 4)
|
|
426
|
+
# match '* * * * * *', utc(1970, 1, 1, 0, 0, 1)
|
|
427
|
+
# match '* * 13 * fri', utc(1970, 2, 13)
|
|
428
|
+
#
|
|
429
|
+
# match '10 12 13 12 *', utc(1970, 12, 13, 12, 10)
|
|
430
|
+
# match '* * 1 6 *', utc(1970, 6, 1)
|
|
431
|
+
#
|
|
432
|
+
# match '0 0 * * thu', utc(1970, 1, 8)
|
|
433
|
+
#
|
|
434
|
+
# match '0 0 1 1 *', utc(2012, 1, 1)
|
|
435
|
+
# no_match '0 0 1 1 *', utc(2012, 1, 1, 1, 0)
|
|
436
|
+
# end
|
|
456
437
|
|
|
457
438
|
it 'matches correctly in local TZ (TZ not specified)' do
|
|
458
439
|
|
|
@@ -546,19 +527,19 @@ describe Rufus::Scheduler::CronLine do
|
|
|
546
527
|
it 'returns the shortest delta between two occurrences' do
|
|
547
528
|
|
|
548
529
|
expect(Rufus::Scheduler::CronLine.new(
|
|
549
|
-
|
|
530
|
+
'* * * * *').frequency).to eq(60)
|
|
550
531
|
expect(Rufus::Scheduler::CronLine.new(
|
|
551
|
-
|
|
532
|
+
'* * * * * *').frequency).to eq(1)
|
|
552
533
|
|
|
553
534
|
expect(Rufus::Scheduler::CronLine.new(
|
|
554
|
-
|
|
535
|
+
'5 23 * * *').frequency).to eq(24 * 3600)
|
|
555
536
|
expect(Rufus::Scheduler::CronLine.new(
|
|
556
|
-
|
|
537
|
+
'5 * * * *').frequency).to eq(3600)
|
|
557
538
|
expect(Rufus::Scheduler::CronLine.new(
|
|
558
|
-
|
|
539
|
+
'10,20,30 * * * *').frequency).to eq(600)
|
|
559
540
|
|
|
560
541
|
expect(Rufus::Scheduler::CronLine.new(
|
|
561
|
-
|
|
542
|
+
'10,20,30 * * * * *').frequency).to eq(10)
|
|
562
543
|
end
|
|
563
544
|
end
|
|
564
545
|
|
|
@@ -567,22 +548,30 @@ describe Rufus::Scheduler::CronLine do
|
|
|
567
548
|
it 'returns the shortest delta between two occurrences' do
|
|
568
549
|
|
|
569
550
|
expect(Rufus::Scheduler::CronLine.new(
|
|
570
|
-
|
|
551
|
+
'* * * * *').brute_frequency).to eq(60)
|
|
571
552
|
expect(Rufus::Scheduler::CronLine.new(
|
|
572
|
-
|
|
553
|
+
'* * * * * *').brute_frequency).to eq(1)
|
|
573
554
|
|
|
574
555
|
expect(Rufus::Scheduler::CronLine.new(
|
|
575
|
-
|
|
556
|
+
'5 23 * * *').brute_frequency).to eq(24 * 3600)
|
|
576
557
|
expect(Rufus::Scheduler::CronLine.new(
|
|
577
|
-
|
|
558
|
+
'5 * * * *').brute_frequency).to eq(3600)
|
|
578
559
|
expect(Rufus::Scheduler::CronLine.new(
|
|
579
|
-
|
|
560
|
+
'10,20,30 * * * *').brute_frequency).to eq(600)
|
|
580
561
|
|
|
581
562
|
#Rufus::Scheduler::CronLine.new(
|
|
582
563
|
# '10,20,30 * * * * *').brute_frequency.should == 10
|
|
583
564
|
#
|
|
584
565
|
# takes > 20s ...
|
|
585
566
|
end
|
|
567
|
+
|
|
568
|
+
# some combos only appear every other year...
|
|
569
|
+
#
|
|
570
|
+
it 'does not go into an infinite loop' do
|
|
571
|
+
|
|
572
|
+
expect(Rufus::Scheduler::CronLine.new(
|
|
573
|
+
'1 2 3 4 5').brute_frequency).to eq(31622400)
|
|
574
|
+
end
|
|
586
575
|
end
|
|
587
576
|
|
|
588
577
|
context 'summer time' do
|
|
@@ -593,10 +582,6 @@ describe Rufus::Scheduler::CronLine do
|
|
|
593
582
|
#
|
|
594
583
|
it 'schedules correctly through a switch into summer time' do
|
|
595
584
|
|
|
596
|
-
#j = `zdump -v Europe/Berlin | grep "Sun Mar" | grep 2014`.split("\n")[0]
|
|
597
|
-
#j = j.match(/^.+ (Sun Mar .+ UTC) /)[1]
|
|
598
|
-
# only works on system that have a zdump...
|
|
599
|
-
|
|
600
585
|
in_zone 'Europe/Berlin' do
|
|
601
586
|
|
|
602
587
|
# find the summer jump
|
|
@@ -623,14 +608,14 @@ describe Rufus::Scheduler::CronLine do
|
|
|
623
608
|
n0 = cl0.next_time(friday)
|
|
624
609
|
n1 = cl1.next_time(friday)
|
|
625
610
|
|
|
626
|
-
expect(n0.strftime('%H:%M:%S %^a')).to eq('00:02:00
|
|
611
|
+
expect(n0.strftime('%H:%M:%S %^a')).to eq('00:02:00 TUE')
|
|
627
612
|
expect(n1.strftime('%H:%M:%S %^a')).to eq('08:45:00 MON')
|
|
628
613
|
|
|
629
614
|
expect(n0.isdst).to eq(true)
|
|
630
615
|
expect(n1.isdst).to eq(true)
|
|
631
616
|
|
|
632
617
|
expect(
|
|
633
|
-
(n0 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('23:02:00
|
|
618
|
+
(n0 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('23:02:00 FRI')
|
|
634
619
|
expect(
|
|
635
620
|
(n1 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('07:45:00 FRI')
|
|
636
621
|
end
|
|
@@ -676,6 +661,70 @@ describe Rufus::Scheduler::CronLine do
|
|
|
676
661
|
(n1 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('09:45:00 FRI')
|
|
677
662
|
end
|
|
678
663
|
end
|
|
664
|
+
|
|
665
|
+
it 'correctly increments through a DST transition' do
|
|
666
|
+
|
|
667
|
+
expect(
|
|
668
|
+
nt('* * * * * America/Los_Angeles', Time.utc(2015, 3, 8, 9, 59))
|
|
669
|
+
).to eq(Time.utc(2015, 3, 8, 10, 00))
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
it 'correctly increments every minute through a DST transition' do
|
|
673
|
+
|
|
674
|
+
in_zone 'America/Los_Angeles' do
|
|
675
|
+
|
|
676
|
+
line = cl('* * * * * America/Los_Angeles')
|
|
677
|
+
|
|
678
|
+
t = Time.local(2015, 3, 8, 1, 57)
|
|
679
|
+
|
|
680
|
+
points =
|
|
681
|
+
[ 0, 1, 2, 3 ].collect do
|
|
682
|
+
t = line.next_time(t)
|
|
683
|
+
t.strftime('%H:%M:%Sl') + ' ' + t.dup.utc.strftime('%H:%M:%Su')
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
expect(points).to eq(
|
|
687
|
+
[
|
|
688
|
+
'01:58:00l 09:58:00u',
|
|
689
|
+
'01:59:00l 09:59:00u',
|
|
690
|
+
'03:00:00l 10:00:00u',
|
|
691
|
+
'03:01:00l 10:01:00u'
|
|
692
|
+
]
|
|
693
|
+
)
|
|
694
|
+
end
|
|
695
|
+
end
|
|
696
|
+
|
|
697
|
+
it 'correctly decrements through a DST transition' do
|
|
698
|
+
|
|
699
|
+
expect(
|
|
700
|
+
pt('* * * * * America/Los_Angeles', Time.utc(2015, 3, 8, 10, 00))
|
|
701
|
+
).to eq(Time.utc(2015, 3, 8, 9, 59))
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
it 'correctly decrements every minute through a DST transition' do
|
|
705
|
+
|
|
706
|
+
in_zone 'America/Los_Angeles' do
|
|
707
|
+
|
|
708
|
+
line = cl('* * * * * America/Los_Angeles')
|
|
709
|
+
|
|
710
|
+
t = Time.local(2015, 3, 8, 3, 2)
|
|
711
|
+
|
|
712
|
+
points =
|
|
713
|
+
[ 0, 1, 2, 3 ].collect do
|
|
714
|
+
t = line.previous_time(t)
|
|
715
|
+
t.strftime('%H:%M:%Sl') + ' ' + t.dup.utc.strftime('%H:%M:%Su')
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
expect(points).to eq(
|
|
719
|
+
[
|
|
720
|
+
'03:01:00l 10:01:00u',
|
|
721
|
+
'03:00:00l 10:00:00u',
|
|
722
|
+
'01:59:00l 09:59:00u',
|
|
723
|
+
'01:58:00l 09:58:00u'
|
|
724
|
+
]
|
|
725
|
+
)
|
|
726
|
+
end
|
|
727
|
+
end
|
|
679
728
|
end
|
|
680
729
|
end
|
|
681
730
|
|
data/spec/job_cron_spec.rb
CHANGED
|
@@ -102,5 +102,27 @@ describe Rufus::Scheduler::CronJob do
|
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
end
|
|
105
|
+
|
|
106
|
+
describe '.next_time' do
|
|
107
|
+
|
|
108
|
+
it 'returns the next trigger time' do
|
|
109
|
+
|
|
110
|
+
n = Time.now
|
|
111
|
+
nt = Time.parse("#{n.year}-#{n.month + 1}-01")
|
|
112
|
+
|
|
113
|
+
expect(
|
|
114
|
+
@scheduler.schedule_cron('* * 1 * *', lambda {}).next_time
|
|
115
|
+
).to eq(nt)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'returns the next trigger time (first_at => Time)' do
|
|
119
|
+
|
|
120
|
+
ft = Time.parse('2100-12-31')
|
|
121
|
+
|
|
122
|
+
job = @scheduler.schedule_cron('* * 1 * *', :first_at => ft) {}
|
|
123
|
+
|
|
124
|
+
expect(job.next_time).to eq(ft)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
105
127
|
end
|
|
106
128
|
|
data/spec/job_every_spec.rb
CHANGED
|
@@ -49,6 +49,20 @@ describe Rufus::Scheduler::EveryJob do
|
|
|
49
49
|
expect(times[2] - times[1]).to be < 3.4
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
+
context 'summer time' do
|
|
53
|
+
|
|
54
|
+
it 'triggers correctly through a DST transition' do
|
|
55
|
+
|
|
56
|
+
job = Rufus::Scheduler::EveryJob.new(@scheduler, '1m', {}, lambda {})
|
|
57
|
+
t1 = ltz('America/Los_Angeles', 2015, 3, 8, 1, 55)
|
|
58
|
+
t2 = ltz('America/Los_Angeles', 2015, 3, 8, 3, 05)
|
|
59
|
+
job.next_time = t1
|
|
60
|
+
occurrences = job.occurrences(t1, t2)
|
|
61
|
+
|
|
62
|
+
expect(occurrences.length).to eq(11)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
52
66
|
context 'first_at/in' do
|
|
53
67
|
|
|
54
68
|
it 'triggers for the first time at first_at' do
|
data/spec/job_repeat_spec.rb
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
#
|
|
3
|
+
# Specifying rufus-scheduler
|
|
4
|
+
#
|
|
5
|
+
# Sat Aug 16 05:43:06 JST 2014
|
|
6
|
+
# added by @ecin
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
require 'spec_helper'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
describe Rufus::Scheduler::FileLock do
|
|
13
|
+
|
|
14
|
+
before :each do
|
|
15
|
+
|
|
16
|
+
@lock_path = '.rufus-scheduler.lock'
|
|
17
|
+
@lock = Rufus::Scheduler::FileLock.new(@lock_path)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
after :each do
|
|
21
|
+
|
|
22
|
+
FileUtils.rm_f(@lock_path)
|
|
23
|
+
FileUtils.rm_f('lock.txt')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context ':scheduler_lock => Rufus::Scheduler::FileLock.new(path)' do
|
|
27
|
+
|
|
28
|
+
it 'writes down a .rufus-scheduler.lock file' do
|
|
29
|
+
|
|
30
|
+
@lock.lock
|
|
31
|
+
|
|
32
|
+
line = File.read(@lock_path)
|
|
33
|
+
|
|
34
|
+
expect(line).to match(/pid: #{$$}/)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it '"flocks" the lock file' do
|
|
38
|
+
|
|
39
|
+
@lock.lock
|
|
40
|
+
|
|
41
|
+
f = File.new(@lock_path, 'a')
|
|
42
|
+
|
|
43
|
+
expect(f.flock(File::LOCK_NB | File::LOCK_EX)).to eq(false)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
data/spec/lock_spec.rb
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
|
|
2
|
+
#
|
|
3
|
+
# Specifying rufus-scheduler
|
|
4
|
+
#
|
|
5
|
+
# Sat Aug 16 05:42:11 JST 2014
|
|
6
|
+
# added by @ecin
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
require 'spec_helper'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
describe Rufus::Scheduler do
|
|
13
|
+
|
|
14
|
+
context "when running multiple schedulers side-by-side" do
|
|
15
|
+
|
|
16
|
+
class AlwaysLock
|
|
17
|
+
def lock; true; end
|
|
18
|
+
def unlock; true; end
|
|
19
|
+
def locked?; true; end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class NeverLock
|
|
23
|
+
def lock; false; end
|
|
24
|
+
def unlock; true; end
|
|
25
|
+
def locked?; true; end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "only starts if it can acquire a scheduler lock" do
|
|
29
|
+
|
|
30
|
+
main = Rufus::Scheduler.new :scheduler_lock => AlwaysLock.new
|
|
31
|
+
backup = Rufus::Scheduler.new :scheduler_lock => NeverLock.new
|
|
32
|
+
|
|
33
|
+
expect(main).to be_up
|
|
34
|
+
expect(backup).to be_down
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "only triggers jobs when it can acquire a trigger lock" do
|
|
38
|
+
|
|
39
|
+
main = Rufus::Scheduler.new(:trigger_lock => AlwaysLock.new)
|
|
40
|
+
backup = Rufus::Scheduler.new(:trigger_lock => NeverLock.new)
|
|
41
|
+
|
|
42
|
+
expect(main).to be_up
|
|
43
|
+
expect(backup).to be_up
|
|
44
|
+
|
|
45
|
+
counter = 0
|
|
46
|
+
job = proc { counter += 1 }
|
|
47
|
+
main.schedule_in(0, job)
|
|
48
|
+
backup.schedule_in(0, job)
|
|
49
|
+
|
|
50
|
+
sleep 0.5
|
|
51
|
+
|
|
52
|
+
expect(main.jobs).to be_empty
|
|
53
|
+
expect(backup.jobs.count).to eq(1)
|
|
54
|
+
expect(backup.jobs.first.next_time).to be(false)
|
|
55
|
+
expect(counter).to eq(1)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|