say_when 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +5 -0
- data/Guardfile +50 -0
- data/README.md +135 -2
- data/Rakefile +1 -0
- data/lib/say_when.rb +33 -18
- data/lib/say_when/configuration.rb +16 -0
- data/lib/say_when/cron_expression.rb +19 -21
- data/lib/say_when/poller/base_poller.rb +108 -0
- data/lib/say_when/poller/celluloid_poller.rb +30 -0
- data/lib/say_when/poller/concurrent_poller.rb +31 -0
- data/lib/say_when/poller/simple_poller.rb +37 -0
- data/lib/say_when/processor/active_job_strategy.rb +35 -0
- data/lib/say_when/processor/simple_strategy.rb +13 -0
- data/lib/say_when/processor/test_strategy.rb +21 -0
- data/lib/say_when/scheduler.rb +67 -101
- data/lib/say_when/storage/active_record_strategy.rb +204 -0
- data/lib/say_when/storage/base_job.rb +96 -0
- data/lib/say_when/storage/memory_strategy.rb +140 -0
- data/lib/say_when/tasks.rb +15 -3
- data/lib/say_when/triggers/base.rb +3 -3
- data/lib/say_when/triggers/cron_strategy.rb +2 -3
- data/lib/say_when/triggers/instance_strategy.rb +3 -4
- data/lib/say_when/triggers/once_strategy.rb +3 -4
- data/lib/say_when/utils.rb +16 -0
- data/lib/say_when/version.rb +1 -1
- data/say_when.gemspec +10 -5
- data/test/minitest_helper.rb +45 -15
- data/test/say_when/configuration_test.rb +14 -0
- data/test/say_when/cron_expression_test.rb +140 -0
- data/test/say_when/poller/base_poller_test.rb +42 -0
- data/test/say_when/poller/celluloid_poller_test.rb +17 -0
- data/test/say_when/poller/concurrent_poller_test.rb +19 -0
- data/test/say_when/poller/simple_poller_test.rb +27 -0
- data/test/say_when/processor/active_job_strategy_test.rb +31 -0
- data/test/say_when/processor/simple_strategy_test.rb +15 -0
- data/test/say_when/scheduler_test.rb +41 -57
- data/test/say_when/storage/active_record_strategy_test.rb +134 -0
- data/test/say_when/storage/memory_strategy_test.rb +96 -0
- data/test/say_when/triggers/cron_strategy_test.rb +11 -0
- data/test/say_when/triggers/instance_strategy_test.rb +13 -0
- data/test/say_when/triggers/once_strategy_test.rb +2 -2
- data/test/say_when_test.rb +20 -0
- metadata +110 -36
- data/lib/say_when/base_job.rb +0 -96
- data/lib/say_when/processor/active_messaging.rb +0 -21
- data/lib/say_when/processor/base.rb +0 -19
- data/lib/say_when/processor/shoryuken.rb +0 -14
- data/lib/say_when/processor/simple.rb +0 -17
- data/lib/say_when/storage/active_record/acts.rb +0 -92
- data/lib/say_when/storage/active_record/job.rb +0 -100
- data/lib/say_when/storage/active_record/job_execution.rb +0 -14
- data/lib/say_when/storage/memory/base.rb +0 -36
- data/lib/say_when/storage/memory/job.rb +0 -53
- data/test/say_when/cron_expression_spec.rb +0 -74
- data/test/say_when/processor/active_messaging_test.rb +0 -41
- data/test/say_when/storage/active_record/job_test.rb +0 -90
- data/test/say_when/storage/memory/job_test.rb +0 -32
- data/test/say_when/storage/memory/trigger_test.rb +0 -54
- data/test/support/models.rb +0 -33
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'minitest_helper'
|
4
|
+
|
5
|
+
describe SayWhen::Configuration do
|
6
|
+
it 'has default values' do
|
7
|
+
dos = SayWhen::Configuration.default_options
|
8
|
+
dos.wont_be_nil
|
9
|
+
dos[:processor_strategy].must_equal :simple
|
10
|
+
dos[:storage_strategy].must_equal :memory
|
11
|
+
dos[:tick_length].must_equal 5
|
12
|
+
dos[:queue].must_equal "default"
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'minitest_helper'
|
3
|
+
|
4
|
+
require 'active_support/all'
|
5
|
+
require 'say_when/cron_expression'
|
6
|
+
|
7
|
+
describe SayWhen::CronExpression do
|
8
|
+
|
9
|
+
it 'should create with defaults' do
|
10
|
+
ce = SayWhen::CronExpression.new
|
11
|
+
ce.expression.must_equal "* * * ? * ? *"
|
12
|
+
ce.time_zone.must_equal Time.zone.try(:name) || "UTC"
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should set the time_zone' do
|
16
|
+
ce = SayWhen::CronExpression.new("0 0 12 ? * 1#1 *", 'Pacific Time (US & Canada)')
|
17
|
+
ce.time_zone.must_equal 'Pacific Time (US & Canada)'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'has a pretty to_s' do
|
21
|
+
ce = SayWhen::CronExpression.new("1 1 1 1 1 ? 2000")
|
22
|
+
ce.to_s.must_match(/s:.*/)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'handles #/# numbers' do
|
26
|
+
ce = SayWhen::CronExpression.new("*/10 1 1 1 1 ? 2000")
|
27
|
+
ce.seconds.values.must_equal([0, 10, 20, 30, 40, 50])
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'handles #,# numbers' do
|
31
|
+
ce = SayWhen::CronExpression.new("1,2 1 1 1 1 ? 2000")
|
32
|
+
ce.seconds.values.must_equal([1, 2])
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'handles #-# numbers' do
|
36
|
+
ce = SayWhen::CronExpression.new("1-3 1 1 1 1 ? 2000")
|
37
|
+
ce.seconds.values.must_equal([1, 2, 3])
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'no values when no match' do
|
41
|
+
ce = SayWhen::CronExpression.new("na 1 1 1 1 ? 2000")
|
42
|
+
ce.seconds.values.must_equal([])
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'handles changes in seconds' do
|
46
|
+
ce = SayWhen::CronExpression.new("1-3 1 1 1 1 ? 2000", "UTC")
|
47
|
+
n = ce.next_fire_at(Time.utc(1999,1,1))
|
48
|
+
n.must_equal Time.parse("Sat, 01 Jan 2000 01:01:01 UTC")
|
49
|
+
|
50
|
+
n = ce.next_fire_at(Time.parse("Sat, 01 Jan 2000 01:00:59 UTC"))
|
51
|
+
n.must_equal(Time.parse("Sat, 01 Jan 2000 01:01:01 UTC"))
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "Day of the month" do
|
55
|
+
it "gets the last day of the month" do
|
56
|
+
ce = SayWhen::CronExpression.new("0 0 0 L 1 ? 2004", 'UTC')
|
57
|
+
ce.next_fire_at(Time.utc(1999,1,1)).must_equal(Time.parse('Sat, 31 Jan 2004 00:00:00 UTC +00:00'))
|
58
|
+
end
|
59
|
+
|
60
|
+
it "gets the last weekday of the month" do
|
61
|
+
ce = SayWhen::CronExpression.new("0 0 0 LW 1 ? 2004", 'UTC')
|
62
|
+
ce.next_fire_at(Time.utc(1999,1,1)).must_equal(Time.parse('Fri, 30 Jan 2004 00:00:00 UTC +00:00'))
|
63
|
+
end
|
64
|
+
|
65
|
+
it "gets a weekday in the month" do
|
66
|
+
ce = SayWhen::CronExpression.new("0 0 0 W 1 ? 2000", 'UTC')
|
67
|
+
ce.next_fire_at(Time.utc(1999,1,1)).must_equal(Time.parse('Mon, 03 Jan 2000 00:00:00 UTC +00:00'))
|
68
|
+
end
|
69
|
+
|
70
|
+
it "gets the closest weekday in the month" do
|
71
|
+
ce = SayWhen::CronExpression.new("0 0 0 1W 1 ? 2000", 'UTC')
|
72
|
+
ce.next_fire_at(Time.utc(1999,1,1)).must_equal(Time.parse('Tue, 03 Jan 2000 00:00:00 UTC +00:00'))
|
73
|
+
|
74
|
+
ce = SayWhen::CronExpression.new("0 0 0 10W 1 ? 2000", 'UTC')
|
75
|
+
ce.next_fire_at(Time.utc(1999,1,1)).must_equal(Time.parse('Mon, 10 Jan 2000 00:00:00 UTC +00:00'))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'get first sunday in the month with "1#1' do
|
80
|
+
|
81
|
+
before do
|
82
|
+
@ce = SayWhen::CronExpression.new("0 0 12 ? * 1#1 *", 'Pacific Time (US & Canada)')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'finds first sunday in the same month' do
|
86
|
+
@ce.next_fire_at(Time.utc(2008,1,1)).must_equal(Time.parse('2008-01-06 12:00:00 -0800'))
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
it 'finds first sunday in the next month' do
|
91
|
+
@ce.next_fire_at(Time.utc(2008,1,7)).must_equal(Time.parse('2008-02-03 12:00:00 -0800'))
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'finds last sunday in the same month' do
|
95
|
+
@ce.last_fire_at(Time.utc(2008,1,10)).must_equal(Time.parse('2008-01-06 12:00:00 -0800'))
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'finds sundays in the prior months and years' do
|
99
|
+
@ce.last_fire_at(Time.utc(2008,1,5)).must_equal Time.parse('2007-12-02 12:00:00 -0800')
|
100
|
+
@ce.last_fire_at(Time.parse('2007-12-02 12:00:00 -0800') - 1.second).must_equal(Time.parse('2007-11-04 12:00:00 -0800'))
|
101
|
+
@ce.last_fire_at(Time.parse('2007-11-04 12:00:00 -0800') - 1.second).must_equal(Time.parse('2007-10-07 12:00:00 -0700'))
|
102
|
+
@ce.next_fire_at(Time.parse('2007-10-07 12:00:00 -0700') + 1.second).must_equal(Time.parse('2007-11-04 12:00:00 -0800'))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe 'get last sunday in the month with "1L"' do
|
107
|
+
before do
|
108
|
+
@ce = SayWhen::CronExpression.new("0 0 12 ? * 1L *", 'Pacific Time (US & Canada)')
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'gets next final sunday for same month' do
|
112
|
+
@ce.next_fire_at(Time.utc(2008,1,1)).must_equal(Time.parse('2008-01-27 12:00:00 -0800'))
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
it 'gets next final sunday for next month' do
|
117
|
+
@ce.next_fire_at(Time.utc(2008,1,28)).must_equal(Time.parse('2008-02-24 12:00:00 -0800'))
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'gets last final sunday for same month' do
|
121
|
+
@ce.last_fire_at(Time.utc(2008,1,28)).must_equal(Time.parse('2008-01-27 12:00:00 -0800'))
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'gets last sunday for prior month and year' do
|
125
|
+
@ce.last_fire_at(Time.utc(2008,1,1)).must_equal(Time.parse('2007-12-30 12:00:00 -0800'))
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
it 'gets last sunday for prior month and year' do
|
130
|
+
nfa = @ce.last_fire_at(Time.utc(2007,12,1))
|
131
|
+
nfa.must_equal(Time.parse('2007-11-25 12:00:00 -0800'))
|
132
|
+
|
133
|
+
nfa = @ce.last_fire_at(nfa - 1.second)
|
134
|
+
nfa.must_equal(Time.parse('2007-10-28 12:00:00 -0700'))
|
135
|
+
|
136
|
+
nfa = @ce.next_fire_at(nfa + 1.second)
|
137
|
+
nfa.must_equal(Time.parse('2007-11-25 12:00:00 -0800'))
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'minitest_helper'
|
3
|
+
require 'say_when/poller/base_poller'
|
4
|
+
|
5
|
+
describe SayWhen::Poller::BasePoller do
|
6
|
+
|
7
|
+
class TestPoller; include(SayWhen::Poller::BasePoller); end
|
8
|
+
|
9
|
+
let (:poller) { TestPoller.new }
|
10
|
+
let (:time_now) { Time.now }
|
11
|
+
|
12
|
+
it 'handles errors' do
|
13
|
+
job = Minitest::Mock.new
|
14
|
+
job.expect(:release, true)
|
15
|
+
err = nil
|
16
|
+
begin
|
17
|
+
raise RuntimeError.new('bad')
|
18
|
+
rescue RuntimeError => ex
|
19
|
+
err = ex
|
20
|
+
end
|
21
|
+
|
22
|
+
poller.job_error("oh noes", job, err)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "can acquire a job" do
|
26
|
+
poller.acquire(time_now)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can process a job" do
|
30
|
+
job = Minitest::Mock.new
|
31
|
+
job.expect(:fired, true, [Object])
|
32
|
+
poller.process(job, time_now)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "can process jobs" do
|
36
|
+
poller.process_jobs
|
37
|
+
end
|
38
|
+
|
39
|
+
it "defines an error tick length" do
|
40
|
+
poller.error_tick_length.must_equal 0
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'minitest_helper'
|
3
|
+
require 'say_when/poller/celluloid_poller'
|
4
|
+
|
5
|
+
describe SayWhen::Poller::CelluloidPoller do
|
6
|
+
let (:poller) { SayWhen::Poller::CelluloidPoller.new(100) }
|
7
|
+
|
8
|
+
it 'should instantiate the poller' do
|
9
|
+
poller.tick_length.must_equal 100
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should start the poller running, and can stop it' do
|
13
|
+
poller.start
|
14
|
+
sleep(0.2)
|
15
|
+
poller.stop
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'minitest_helper'
|
4
|
+
require 'say_when/poller/concurrent_poller'
|
5
|
+
|
6
|
+
describe SayWhen::Poller::ConcurrentPoller do
|
7
|
+
|
8
|
+
let (:poller) { SayWhen::Poller::ConcurrentPoller.new(100) }
|
9
|
+
|
10
|
+
it 'should instantiate the poller' do
|
11
|
+
poller.tick_length.must_equal 100
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should start the poller running, and can stop it' do
|
15
|
+
poller.start
|
16
|
+
sleep(0.2)
|
17
|
+
poller.stop
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'minitest_helper'
|
3
|
+
require 'say_when/poller/simple_poller'
|
4
|
+
|
5
|
+
describe SayWhen::Poller::SimplePoller do
|
6
|
+
|
7
|
+
let (:poller) { SayWhen::Poller::SimplePoller.new }
|
8
|
+
|
9
|
+
it 'should instantiate the poller' do
|
10
|
+
poller.wont_be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can check if poller is running' do
|
14
|
+
poller.wont_be :running?
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should start the poller running, and can stop it' do
|
18
|
+
poller.wont_be :running
|
19
|
+
|
20
|
+
Thread.start{ poller.start }
|
21
|
+
sleep(0.2)
|
22
|
+
poller.must_be :running
|
23
|
+
|
24
|
+
poller.stop
|
25
|
+
poller.wont_be :running
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'minitest_helper'
|
4
|
+
require 'active_job'
|
5
|
+
require 'say_when/processor/active_job_strategy'
|
6
|
+
|
7
|
+
describe SayWhen::Processor::ActiveJobStrategy do
|
8
|
+
|
9
|
+
let(:processor) { SayWhen::Processor::ActiveJobStrategy }
|
10
|
+
|
11
|
+
before {
|
12
|
+
SayWhen::Test::TestTask.reset
|
13
|
+
}
|
14
|
+
|
15
|
+
it 'process a memory stored job' do
|
16
|
+
options = {
|
17
|
+
name: 'Test',
|
18
|
+
group: 'Test',
|
19
|
+
data: { foo: 'bar', result: 1 },
|
20
|
+
job_class: 'SayWhen::Test::TestTask',
|
21
|
+
job_method: 'execute'
|
22
|
+
}
|
23
|
+
|
24
|
+
SayWhen::Test::TestTask.wont_be :executed?
|
25
|
+
|
26
|
+
job = SayWhen::Storage::MemoryStrategy.create(options)
|
27
|
+
processor.process(job)
|
28
|
+
|
29
|
+
SayWhen::Test::TestTask.must_be :executed?
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'minitest_helper'
|
4
|
+
require 'say_when/processor/simple_strategy'
|
5
|
+
|
6
|
+
describe SayWhen::Processor::SimpleStrategy do
|
7
|
+
|
8
|
+
let(:processor) { SayWhen::Processor::SimpleStrategy }
|
9
|
+
|
10
|
+
it 'process a job by sending a message' do
|
11
|
+
job = Minitest::Mock.new
|
12
|
+
job.expect(:execute, 'done!')
|
13
|
+
processor.process(job).must_equal 'done!'
|
14
|
+
end
|
15
|
+
end
|
@@ -4,72 +4,56 @@ require 'minitest_helper'
|
|
4
4
|
|
5
5
|
describe SayWhen::Scheduler do
|
6
6
|
|
7
|
-
|
8
|
-
SayWhen::logger = Logger.new('/dev/null')
|
9
|
-
}
|
10
|
-
|
11
|
-
describe 'class methods' do
|
12
|
-
|
13
|
-
it 'can return singleton' do
|
14
|
-
s = SayWhen::Scheduler.scheduler
|
15
|
-
s.wont_be_nil
|
16
|
-
s.must_equal SayWhen::Scheduler.scheduler
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'can be configured' do
|
20
|
-
SayWhen::Scheduler.configure do |scheduler|
|
21
|
-
scheduler.storage_strategy = :memory
|
22
|
-
scheduler.processor_class = SayWhen::Test::TestProcessor
|
23
|
-
end
|
24
|
-
SayWhen::Scheduler.scheduler.storage_strategy.must_equal :memory
|
25
|
-
SayWhen::Scheduler.scheduler.processor_class.must_equal SayWhen::Test::TestProcessor
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'can schedule a new job' do
|
29
|
-
SayWhen::Scheduler.configure do |scheduler|
|
30
|
-
scheduler.storage_strategy = :memory
|
31
|
-
scheduler.processor_class = SayWhen::Test::TestProcessor
|
32
|
-
end
|
33
|
-
|
34
|
-
job = SayWhen::Scheduler.schedule(
|
35
|
-
trigger_strategy: 'once',
|
36
|
-
trigger_options: { at: 10.second.since },
|
37
|
-
job_class: 'SayWhen::Test::TestTask',
|
38
|
-
job_method: 'execute'
|
39
|
-
)
|
40
|
-
job.wont_be_nil
|
41
|
-
end
|
7
|
+
let (:scheduler) { SayWhen::Scheduler.new }
|
42
8
|
|
9
|
+
it 'has a logger' do
|
10
|
+
scheduler.logger.must_be_instance_of Logger
|
43
11
|
end
|
44
12
|
|
45
|
-
|
13
|
+
it 'extracts data' do
|
14
|
+
scheduler.extract_data({}).must_be_nil
|
15
|
+
scheduler.extract_data(data: 'data').must_equal 'data'
|
16
|
+
end
|
46
17
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
18
|
+
it 'extracts job method' do
|
19
|
+
scheduler.extract_job_method({}).must_equal 'execute'
|
20
|
+
scheduler.extract_job_method(job_method: 'just_doit').must_equal 'just_doit'
|
21
|
+
scheduler.extract_job_method(method: 'doit').must_equal 'doit'
|
22
|
+
end
|
53
23
|
|
54
|
-
|
24
|
+
it 'extracts job class' do
|
25
|
+
scheduler.extract_job_class(job_class: 'foo').must_equal 'foo'
|
26
|
+
scheduler.extract_job_class(class: 'foo').must_equal 'foo'
|
27
|
+
scheduler.extract_job_class(SayWhen::Test::TestTask).must_equal 'SayWhen::Test::TestTask'
|
28
|
+
scheduler.extract_job_class('SayWhen::Test::TestTask').must_equal 'SayWhen::Test::TestTask'
|
55
29
|
|
56
|
-
|
57
|
-
scheduler.
|
58
|
-
end
|
30
|
+
lambda do
|
31
|
+
scheduler.extract_job_class(bar: 'foo')
|
32
|
+
end.must_raise RuntimeError
|
33
|
+
end
|
59
34
|
|
60
|
-
|
61
|
-
|
62
|
-
|
35
|
+
it 'gets job options' do
|
36
|
+
keys = [:job_class, :job_method, :data]
|
37
|
+
opts = scheduler.job_options(keys.inject({}) { |s, k| s[k] = k.to_s; s } )
|
38
|
+
keys.each{|k| opts[k].must_equal k.to_s }
|
39
|
+
end
|
63
40
|
|
64
|
-
|
65
|
-
|
41
|
+
it 'can schedule a new job' do
|
42
|
+
job = scheduler.schedule(
|
43
|
+
trigger_strategy: 'once',
|
44
|
+
trigger_options: { at: 10.second.since },
|
45
|
+
job_class: 'SayWhen::Test::TestTask',
|
46
|
+
job_method: 'execute'
|
47
|
+
)
|
48
|
+
job.wont_be_nil
|
49
|
+
end
|
66
50
|
|
67
|
-
|
68
|
-
|
69
|
-
|
51
|
+
it 'can schedule a cron job' do
|
52
|
+
job = scheduler.schedule_cron("0 0 12 ? * * *", SayWhen::Test::TestTask)
|
53
|
+
job.wont_be_nil
|
54
|
+
end
|
70
55
|
|
71
|
-
|
72
|
-
|
73
|
-
end
|
56
|
+
it 'should provide the storage strategy' do
|
57
|
+
scheduler.storage.must_equal SayWhen::Storage::MemoryStrategy
|
74
58
|
end
|
75
59
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'minitest_helper'
|
4
|
+
require 'active_record_helper'
|
5
|
+
require 'say_when/storage/active_record_strategy'
|
6
|
+
|
7
|
+
describe SayWhen::Storage::ActiveRecordStrategy do
|
8
|
+
let(:valid_attributes) {
|
9
|
+
{
|
10
|
+
trigger_strategy: :cron,
|
11
|
+
trigger_options: { expression: '0 0 12 ? * * *', time_zone: 'Pacific Time (US & Canada)' },
|
12
|
+
data: { foo: 'bar', result: 1 },
|
13
|
+
job_class: 'SayWhen::Test::TestTask',
|
14
|
+
job_method: 'execute'
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
let(:strategy) { SayWhen::Storage::ActiveRecordStrategy }
|
19
|
+
|
20
|
+
let(:job) { strategy.create(valid_attributes) }
|
21
|
+
|
22
|
+
it 'job can be created' do
|
23
|
+
j = strategy.create(valid_attributes)
|
24
|
+
j.wont_be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'job can be serialized' do
|
28
|
+
strategy.serialize(job).must_equal job
|
29
|
+
strategy.deserialize(job).must_equal job
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'can execute the task for the job' do
|
33
|
+
job.execute_job( { result: 1 } ).must_equal 1
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'can execute the job' do
|
37
|
+
j = strategy.create(valid_attributes)
|
38
|
+
j.execute.must_equal 1
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'derives a trigger from the attributes' do
|
42
|
+
t = strategy.create(valid_attributes)
|
43
|
+
t.trigger.wont_be_nil
|
44
|
+
t.trigger.must_be_instance_of SayWhen::Triggers::CronStrategy
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'has a waiting state on create' do
|
48
|
+
t = strategy.create(valid_attributes)
|
49
|
+
t.status.must_equal SayWhen::Storage::BaseJob::STATE_WAITING
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'has a next fire at set on create' do
|
53
|
+
opts = valid_attributes[:trigger_options]
|
54
|
+
ce = SayWhen::CronExpression.new(opts[:expression], opts[:time_zone])
|
55
|
+
j = strategy.create(valid_attributes)
|
56
|
+
j.status.must_equal SayWhen::Storage::BaseJob::STATE_WAITING
|
57
|
+
j.next_fire_at.must_equal ce.next_fire_at
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'can acquire and release the next job' do
|
61
|
+
SayWhen::Storage::ActiveRecordStrategy::Job.delete_all
|
62
|
+
|
63
|
+
j2_opts = {
|
64
|
+
trigger_strategy: :cron,
|
65
|
+
trigger_options: { expression: '0 0 10 ? * * *', time_zone: 'Pacific Time (US & Canada)' },
|
66
|
+
data: { foo: 'bar', result: 2 },
|
67
|
+
job_class: 'SayWhen::Test::TestTask',
|
68
|
+
job_method: 'execute'
|
69
|
+
}
|
70
|
+
|
71
|
+
now = Time.now.change(hour: 0)
|
72
|
+
Time.stub(:now, now) do
|
73
|
+
j1 = strategy.create(valid_attributes)
|
74
|
+
j1.wont_be_nil
|
75
|
+
j2 = strategy.create(j2_opts)
|
76
|
+
|
77
|
+
next_job = strategy.acquire_next(2.days.since)
|
78
|
+
next_job.status.must_equal "acquired"
|
79
|
+
next_job.must_equal j2
|
80
|
+
strategy.release(next_job)
|
81
|
+
next_job.status.must_equal "waiting"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'resets acquired jobs' do
|
86
|
+
old = 2.hours.ago
|
87
|
+
j = strategy.create(valid_attributes)
|
88
|
+
j.update_attributes(status: 'acquired', updated_at: old, created_at: old)
|
89
|
+
|
90
|
+
j.status.must_equal 'acquired'
|
91
|
+
|
92
|
+
strategy.reset_acquired(3600)
|
93
|
+
|
94
|
+
j.reload
|
95
|
+
j.status.must_equal 'waiting'
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'can be fired' do
|
99
|
+
opts = valid_attributes[:trigger_options]
|
100
|
+
ce = SayWhen::CronExpression.new(opts[:expression], opts[:time_zone])
|
101
|
+
j = strategy.create(valid_attributes)
|
102
|
+
nfa = ce.last_fire_at(j.created_at - 1.second)
|
103
|
+
lfa = ce.last_fire_at(nfa - 1.second)
|
104
|
+
j.next_fire_at = nfa
|
105
|
+
j.last_fire_at = lfa
|
106
|
+
|
107
|
+
now = Time.now
|
108
|
+
Time.stub(:now, now) do
|
109
|
+
strategy.fired(j, now)
|
110
|
+
j.next_fire_at.must_equal ce.next_fire_at(now)
|
111
|
+
j.last_fire_at.must_equal now
|
112
|
+
j.status.must_equal SayWhen::Storage::BaseJob::STATE_WAITING
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "acts_as_scheduled" do
|
117
|
+
it "acts_as_scheduled calls has_many" do
|
118
|
+
SayWhen::Test::TestActsAsScheduled.must_be :has_many_called?
|
119
|
+
end
|
120
|
+
|
121
|
+
it "includes schedule methods" do
|
122
|
+
taas = SayWhen::Test::TestActsAsScheduled.new
|
123
|
+
[:schedule, :schedule_instance, :schedule_cron, :schedule_once, :schedule_in].each do |m|
|
124
|
+
taas.respond_to?(m).must_equal true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
it "sets the scheduled value" do
|
129
|
+
taas = SayWhen::Test::TestActsAsScheduled.new
|
130
|
+
job = taas.set_scheduled({})
|
131
|
+
job[:scheduled].must_equal taas
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|