sidekiq-cron 0.6.3 → 1.10.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +145 -0
- data/Gemfile +3 -29
- data/README.md +175 -121
- data/Rakefile +3 -42
- data/lib/sidekiq/cron/job.rb +273 -144
- data/lib/sidekiq/cron/launcher.rb +39 -43
- data/lib/sidekiq/cron/locales/de.yml +2 -2
- data/lib/sidekiq/cron/locales/en.yml +6 -2
- data/lib/sidekiq/cron/locales/it.yml +23 -0
- data/lib/sidekiq/cron/locales/ja.yml +18 -0
- data/lib/sidekiq/cron/locales/pt.yml +22 -0
- data/lib/sidekiq/cron/locales/ru.yml +2 -2
- data/lib/sidekiq/cron/locales/zh-CN.yml +19 -0
- data/lib/sidekiq/cron/poller.rb +22 -12
- data/lib/sidekiq/cron/schedule_loader.rb +22 -0
- data/lib/sidekiq/cron/support.rb +8 -1
- data/lib/sidekiq/cron/version.rb +7 -0
- data/lib/sidekiq/cron/views/cron.erb +38 -28
- data/lib/sidekiq/cron/views/cron_show.erb +88 -0
- data/lib/sidekiq/cron/web.rb +1 -7
- data/lib/sidekiq/cron/web_extension.rb +19 -15
- data/lib/sidekiq/cron.rb +1 -0
- data/lib/sidekiq/options.rb +25 -0
- data/sidekiq-cron.gemspec +23 -108
- data/test/integration/performance_test.rb +13 -19
- data/test/models/person.rb +21 -0
- data/test/test_helper.rb +37 -38
- data/test/unit/fixtures/schedule_array.yml +13 -0
- data/test/unit/fixtures/schedule_erb.yml +6 -0
- data/test/unit/fixtures/schedule_hash.yml +12 -0
- data/test/unit/fixtures/schedule_string.yml +1 -0
- data/test/unit/job_test.rb +450 -35
- data/test/unit/launcher_test.rb +33 -0
- data/test/unit/poller_test.rb +28 -37
- data/test/unit/schedule_loader_test.rb +58 -0
- data/test/unit/web_extension_test.rb +59 -41
- metadata +72 -191
- data/.document +0 -5
- data/.travis.yml +0 -19
- data/Changes.md +0 -50
- data/Dockerfile +0 -32
- data/VERSION +0 -1
- data/config.ru +0 -14
- data/docker-compose.yml +0 -21
- data/examples/web-cron-ui.png +0 -0
- data/lib/sidekiq/cron/views/cron.slim +0 -69
@@ -0,0 +1,33 @@
|
|
1
|
+
require './test/test_helper'
|
2
|
+
|
3
|
+
describe 'Cron launcher' do
|
4
|
+
describe 'initialization' do
|
5
|
+
before do
|
6
|
+
Sidekiq::Options[:cron_poll_interval] = nil
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'initializes poller with default poll interval when not configured' do
|
10
|
+
Sidekiq::Cron::Poller.expects(:new).with do |options|
|
11
|
+
assert_equal Sidekiq::Cron::Launcher::DEFAULT_POLL_INTERVAL, options[:cron_poll_interval]
|
12
|
+
end
|
13
|
+
|
14
|
+
Sidekiq::Launcher.new(Sidekiq.respond_to?(:default_configuration) ? Sidekiq.default_configuration : Sidekiq)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'initializes poller with the configured poll interval' do
|
18
|
+
Sidekiq::Cron::Poller.expects(:new).with do |options|
|
19
|
+
assert_equal 99, options[:cron_poll_interval]
|
20
|
+
end
|
21
|
+
|
22
|
+
Sidekiq::Options[:cron_poll_interval] = 99
|
23
|
+
Sidekiq::Launcher.new(Sidekiq.respond_to?(:default_configuration) ? Sidekiq.default_configuration : Sidekiq)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does not initialize the poller when interval is 0' do
|
27
|
+
Sidekiq::Cron::Poller.expects(:new).never
|
28
|
+
|
29
|
+
Sidekiq::Options[:cron_poll_interval] = 0
|
30
|
+
Sidekiq::Launcher.new(Sidekiq.respond_to?(:default_configuration) ? Sidekiq.default_configuration : Sidekiq)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/unit/poller_test.rb
CHANGED
@@ -1,22 +1,12 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
require './test/test_helper'
|
3
2
|
|
4
|
-
|
5
3
|
describe 'Cron Poller' do
|
6
4
|
before do
|
7
|
-
|
5
|
+
# Clear all previous saved data from Redis.
|
8
6
|
Sidekiq.redis do |conn|
|
9
7
|
conn.flushdb
|
10
8
|
end
|
11
9
|
|
12
|
-
#clear all previous saved data from redis
|
13
|
-
Sidekiq.redis do |conn|
|
14
|
-
conn.keys("cron_job*").each do |key|
|
15
|
-
conn.del(key)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
|
20
10
|
@args = {
|
21
11
|
name: "Test",
|
22
12
|
cron: "*/2 * * * *",
|
@@ -24,14 +14,14 @@ describe 'Cron Poller' do
|
|
24
14
|
}
|
25
15
|
@args2 = @args.merge(name: 'with_queue', klass: 'CronTestClassWithQueue', cron: "*/10 * * * *")
|
26
16
|
|
27
|
-
@poller = Sidekiq::Cron::Poller.new
|
17
|
+
@poller = Sidekiq::Cron::Poller.new(Sidekiq.const_defined?(:Config) ? Sidekiq::Config.new : {})
|
28
18
|
end
|
29
19
|
|
30
20
|
it 'not enqueue any job - new jobs' do
|
31
|
-
now = Time.now.utc
|
32
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
21
|
+
now = Time.now.utc + 3600
|
22
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 5, 1)
|
33
23
|
Time.stubs(:now).returns(enqueued_time)
|
34
|
-
|
24
|
+
|
35
25
|
Sidekiq::Cron::Job.create(@args)
|
36
26
|
Sidekiq::Cron::Job.create(@args2)
|
37
27
|
|
@@ -42,22 +32,23 @@ describe 'Cron Poller' do
|
|
42
32
|
assert_equal 0, conn.llen("queue:super")
|
43
33
|
end
|
44
34
|
|
45
|
-
#30 seconds after!
|
46
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
35
|
+
# 30 seconds after!
|
36
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 5, 30)
|
47
37
|
Time.stubs(:now).returns(enqueued_time)
|
48
|
-
@poller.enqueue
|
49
38
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
39
|
+
@poller.enqueue
|
40
|
+
|
41
|
+
Sidekiq.redis do |conn|
|
42
|
+
assert_equal 0, conn.llen("queue:default")
|
43
|
+
assert_equal 0, conn.llen("queue:super")
|
44
|
+
end
|
54
45
|
end
|
55
46
|
|
56
47
|
it 'should enqueue only job with cron */2' do
|
57
|
-
now = Time.now.utc
|
58
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
48
|
+
now = Time.now.utc + 3600
|
49
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 5, 1)
|
59
50
|
Time.stubs(:now).returns(enqueued_time)
|
60
|
-
|
51
|
+
|
61
52
|
Sidekiq::Cron::Job.create(@args)
|
62
53
|
Sidekiq::Cron::Job.create(@args2)
|
63
54
|
|
@@ -68,7 +59,7 @@ describe 'Cron Poller' do
|
|
68
59
|
assert_equal 0, conn.llen("queue:super")
|
69
60
|
end
|
70
61
|
|
71
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
62
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 6, 1)
|
72
63
|
Time.stubs(:now).returns(enqueued_time)
|
73
64
|
@poller.enqueue
|
74
65
|
|
@@ -79,10 +70,10 @@ describe 'Cron Poller' do
|
|
79
70
|
end
|
80
71
|
|
81
72
|
it 'should enqueue both jobs' do
|
82
|
-
now = Time.now.utc
|
83
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
73
|
+
now = Time.now.utc + 3600
|
74
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 8, 1)
|
84
75
|
Time.stubs(:now).returns(enqueued_time)
|
85
|
-
|
76
|
+
|
86
77
|
Sidekiq::Cron::Job.create(@args)
|
87
78
|
Sidekiq::Cron::Job.create(@args2)
|
88
79
|
|
@@ -93,7 +84,7 @@ describe 'Cron Poller' do
|
|
93
84
|
assert_equal 0, conn.llen("queue:super")
|
94
85
|
end
|
95
86
|
|
96
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
87
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 10, 5)
|
97
88
|
Time.stubs(:now).returns(enqueued_time)
|
98
89
|
@poller.enqueue
|
99
90
|
|
@@ -104,10 +95,10 @@ describe 'Cron Poller' do
|
|
104
95
|
end
|
105
96
|
|
106
97
|
it 'should enqueue both jobs but only one time each' do
|
107
|
-
now = Time.now.utc
|
108
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
98
|
+
now = Time.now.utc + 3600
|
99
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 8, 1)
|
109
100
|
Time.stubs(:now).returns(enqueued_time)
|
110
|
-
|
101
|
+
|
111
102
|
Sidekiq::Cron::Job.create(@args)
|
112
103
|
Sidekiq::Cron::Job.create(@args2)
|
113
104
|
|
@@ -118,7 +109,7 @@ describe 'Cron Poller' do
|
|
118
109
|
assert_equal 0, conn.llen("queue:super")
|
119
110
|
end
|
120
111
|
|
121
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
112
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 20, 1)
|
122
113
|
Time.stubs(:now).returns(enqueued_time)
|
123
114
|
@poller.enqueue
|
124
115
|
Sidekiq.redis do |conn|
|
@@ -126,7 +117,7 @@ describe 'Cron Poller' do
|
|
126
117
|
assert_equal 1, conn.llen("queue:super")
|
127
118
|
end
|
128
119
|
|
129
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
120
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 20, 2)
|
130
121
|
Time.stubs(:now).returns(enqueued_time)
|
131
122
|
@poller.enqueue
|
132
123
|
Sidekiq.redis do |conn|
|
@@ -134,7 +125,7 @@ describe 'Cron Poller' do
|
|
134
125
|
assert_equal 1, conn.llen("queue:super")
|
135
126
|
end
|
136
127
|
|
137
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
128
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 20, 20)
|
138
129
|
Time.stubs(:now).returns(enqueued_time)
|
139
130
|
@poller.enqueue
|
140
131
|
Sidekiq.redis do |conn|
|
@@ -142,7 +133,7 @@ describe 'Cron Poller' do
|
|
142
133
|
assert_equal 1, conn.llen("queue:super")
|
143
134
|
end
|
144
135
|
|
145
|
-
enqueued_time = Time.new(now.year, now.month, now.day, now.hour
|
136
|
+
enqueued_time = Time.new(now.year, now.month, now.day, now.hour, 20, 50)
|
146
137
|
Time.stubs(:now).returns(enqueued_time)
|
147
138
|
@poller.enqueue
|
148
139
|
Sidekiq.redis do |conn|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require './test/test_helper'
|
2
|
+
|
3
|
+
describe 'ScheduleLoader' do
|
4
|
+
before do
|
5
|
+
Sidekiq::Options[:lifecycle_events][:startup].clear
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'Schedule is defined in hash' do
|
9
|
+
before do
|
10
|
+
Sidekiq::Options[:cron_schedule_file] = 'test/unit/fixtures/schedule_hash.yml'
|
11
|
+
load 'sidekiq/cron/schedule_loader.rb'
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'calls Sidekiq::Cron::Job.load_from_hash' do
|
15
|
+
Sidekiq::Cron::Job.expects(:load_from_hash!)
|
16
|
+
Sidekiq::Options[:lifecycle_events][:startup].first.call
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'Schedule is defined in array' do
|
21
|
+
before do
|
22
|
+
Sidekiq::Options[:cron_schedule_file] = 'test/unit/fixtures/schedule_array.yml'
|
23
|
+
load 'sidekiq/cron/schedule_loader.rb'
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'calls Sidekiq::Cron::Job.load_from_array' do
|
27
|
+
Sidekiq::Cron::Job.expects(:load_from_array!)
|
28
|
+
Sidekiq::Options[:lifecycle_events][:startup].first.call
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'Schedule is not defined in hash nor array' do
|
33
|
+
before do
|
34
|
+
Sidekiq::Options[:cron_schedule_file] = 'test/unit/fixtures/schedule_string.yml'
|
35
|
+
load 'sidekiq/cron/schedule_loader.rb'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'raises an error' do
|
39
|
+
e = assert_raises StandardError do
|
40
|
+
Sidekiq::Options[:lifecycle_events][:startup].first.call
|
41
|
+
end
|
42
|
+
assert_equal 'Not supported schedule format. Confirm your test/unit/fixtures/schedule_string.yml', e.message
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'Schedule is defined using ERB' do
|
47
|
+
it 'properly parses the schedule file' do
|
48
|
+
Sidekiq::Options[:cron_schedule_file] = 'test/unit/fixtures/schedule_erb.yml'
|
49
|
+
load 'sidekiq/cron/schedule_loader.rb'
|
50
|
+
|
51
|
+
Sidekiq::Options[:lifecycle_events][:startup].first.call
|
52
|
+
|
53
|
+
job = Sidekiq::Cron::Job.find("daily_job")
|
54
|
+
assert_equal job.klass, "DailyJob"
|
55
|
+
assert_equal job.cron, "every day at 5 pm"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,37 +1,38 @@
|
|
1
1
|
require './test/test_helper'
|
2
2
|
|
3
|
-
def app
|
4
|
-
Sidekiq::Web
|
5
|
-
end
|
6
|
-
|
7
3
|
describe 'Cron web' do
|
8
4
|
include Rack::Test::Methods
|
9
5
|
|
6
|
+
TOKEN = SecureRandom.base64(32).freeze
|
7
|
+
|
8
|
+
def app
|
9
|
+
Sidekiq::Web
|
10
|
+
end
|
11
|
+
|
10
12
|
before do
|
11
|
-
|
12
|
-
|
13
|
+
env 'rack.session', { csrf: TOKEN }
|
14
|
+
env 'HTTP_X_CSRF_TOKEN', TOKEN
|
15
|
+
Sidekiq.redis { |c| c.flushdb }
|
16
|
+
end
|
13
17
|
|
14
|
-
|
15
|
-
|
16
|
-
conn.keys("cron_job*").each do |key|
|
17
|
-
conn.del(key)
|
18
|
-
end
|
19
|
-
end
|
18
|
+
let(:job_name) { "TestNameOfCronJob" }
|
19
|
+
let(:cron_job_name) { "TesQueueNameOfCronJob" }
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
let(:args) do
|
22
|
+
{
|
23
|
+
name: job_name,
|
23
24
|
cron: "*/2 * * * *",
|
24
25
|
klass: "CronTestClass"
|
25
26
|
}
|
27
|
+
end
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
name:
|
29
|
+
let(:cron_args) do
|
30
|
+
{
|
31
|
+
name: cron_job_name,
|
30
32
|
cron: "*/2 * * * *",
|
31
33
|
klass: "CronQueueTestClass",
|
32
34
|
queue: "cron"
|
33
35
|
}
|
34
|
-
|
35
36
|
end
|
36
37
|
|
37
38
|
it 'display cron web' do
|
@@ -41,45 +42,62 @@ describe 'Cron web' do
|
|
41
42
|
|
42
43
|
it 'display cron web with message - no cron jobs' do
|
43
44
|
get '/cron'
|
44
|
-
assert last_response.body.include?('No cron jobs found')
|
45
|
+
assert last_response.body.include?('No cron jobs were found')
|
45
46
|
end
|
46
47
|
|
47
48
|
it 'display cron web with cron jobs table' do
|
48
|
-
Sidekiq::Cron::Job.create(
|
49
|
+
Sidekiq::Cron::Job.create(args)
|
49
50
|
|
50
51
|
get '/cron'
|
51
52
|
assert_equal 200, last_response.status
|
52
|
-
refute last_response.body.include?('No cron jobs found')
|
53
|
+
refute last_response.body.include?('No cron jobs were found')
|
53
54
|
assert last_response.body.include?('table')
|
54
55
|
assert last_response.body.include?("TestNameOfCronJob")
|
55
56
|
end
|
56
57
|
|
57
58
|
describe "work with cron job" do
|
58
|
-
|
59
59
|
before do
|
60
|
-
@job = Sidekiq::Cron::Job.new(
|
61
|
-
@job.save
|
62
|
-
|
60
|
+
@job = Sidekiq::Cron::Job.new(args.merge(status: "enabled"))
|
61
|
+
assert @job.save
|
62
|
+
|
63
|
+
@cron_job = Sidekiq::Cron::Job.new(cron_args.merge(status: "enabled"))
|
64
|
+
assert @cron_job.save
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'shows history of a cron job' do
|
68
|
+
@job.enque!
|
69
|
+
get "/cron/#{job_name}"
|
70
|
+
|
71
|
+
jid =
|
72
|
+
Sidekiq.redis do |conn|
|
73
|
+
history = conn.lrange Sidekiq::Cron::Job.jid_history_key(job_name), 0, -1
|
74
|
+
Sidekiq.load_json(history.last)['jid']
|
75
|
+
end
|
76
|
+
|
77
|
+
assert jid
|
78
|
+
assert last_response.body.include?(jid)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'redirects to cron path when name not found' do
|
82
|
+
get '/cron/some-fake-name'
|
63
83
|
|
64
|
-
|
65
|
-
@cron_job.save
|
66
|
-
@cron_job_name = "TesQueueNameOfCronJob"
|
84
|
+
assert_match %r{\/cron\z}, last_response['Location']
|
67
85
|
end
|
68
86
|
|
69
87
|
it "disable and enable all cron jobs" do
|
70
88
|
post "/cron/__all__/disable"
|
71
|
-
assert_equal Sidekiq::Cron::Job.find(
|
89
|
+
assert_equal Sidekiq::Cron::Job.find(job_name).status, "disabled"
|
72
90
|
|
73
91
|
post "/cron/__all__/enable"
|
74
|
-
assert_equal Sidekiq::Cron::Job.find(
|
92
|
+
assert_equal Sidekiq::Cron::Job.find(job_name).status, "enabled"
|
75
93
|
end
|
76
94
|
|
77
95
|
it "disable and enable cron job" do
|
78
|
-
post "/cron/#{
|
79
|
-
assert_equal Sidekiq::Cron::Job.find(
|
96
|
+
post "/cron/#{job_name}/disable"
|
97
|
+
assert_equal Sidekiq::Cron::Job.find(job_name).status, "disabled"
|
80
98
|
|
81
|
-
post "/cron/#{
|
82
|
-
assert_equal Sidekiq::Cron::Job.find(
|
99
|
+
post "/cron/#{job_name}/enable"
|
100
|
+
assert_equal Sidekiq::Cron::Job.find(job_name).status, "enabled"
|
83
101
|
end
|
84
102
|
|
85
103
|
it "enqueue all jobs" do
|
@@ -100,21 +118,21 @@ describe 'Cron web' do
|
|
100
118
|
assert_equal 0, conn.llen("queue:default"), "Queue should have no jobs"
|
101
119
|
end
|
102
120
|
|
103
|
-
post "/cron/#{
|
121
|
+
post "/cron/#{job_name}/enque"
|
104
122
|
|
105
123
|
Sidekiq.redis do |conn|
|
106
124
|
assert_equal 1, conn.llen("queue:default"), "Queue should have 1 job"
|
107
125
|
end
|
108
126
|
|
109
|
-
#
|
110
|
-
post "/cron/#{
|
127
|
+
# Should enqueue more times.
|
128
|
+
post "/cron/#{job_name}/enque"
|
111
129
|
|
112
130
|
Sidekiq.redis do |conn|
|
113
131
|
assert_equal 2, conn.llen("queue:default"), "Queue should have 2 job"
|
114
132
|
end
|
115
133
|
|
116
|
-
#
|
117
|
-
post "/cron/#{
|
134
|
+
# Should enqueue to cron job queue.
|
135
|
+
post "/cron/#{cron_job_name}/enque"
|
118
136
|
|
119
137
|
Sidekiq.redis do |conn|
|
120
138
|
assert_equal 1, conn.llen("queue:cron"), "Queue should have 1 cron job"
|
@@ -123,8 +141,8 @@ describe 'Cron web' do
|
|
123
141
|
|
124
142
|
it "destroy job" do
|
125
143
|
assert_equal Sidekiq::Cron::Job.all.size, 2, "Should have 2 job"
|
126
|
-
post "/cron/#{
|
127
|
-
post "/cron/#{
|
144
|
+
post "/cron/#{job_name}/delete"
|
145
|
+
post "/cron/#{cron_job_name}/delete"
|
128
146
|
assert_equal Sidekiq::Cron::Job.all.size, 0, "Should have zero jobs"
|
129
147
|
end
|
130
148
|
|