-
Notifications
You must be signed in to change notification settings - Fork 56
/
Copy pathjob_spec.rb
194 lines (163 loc) · 5.35 KB
/
job_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
require 'spec_helper'
class TestJob
def perform(*args)
puts 'Test!'
end
end
class TestFailingJob
def perform(*args)
raise 'Some error'
end
end
class TestNoArgsJob
def perform
puts 'Test!'
end
end
describe Crono::Job do
let(:period) { Crono::Period.new(2.day, at: '15:00') }
let(:job_args) {[{some: 'data'}]}
let(:job) { Crono::Job.new(TestJob, period, []) }
let(:job_with_args) { Crono::Job.new(TestJob, period, job_args) }
let(:failing_job) { Crono::Job.new(TestFailingJob, period, []) }
let(:not_args_job) { Crono::Job.new(TestJob, period) }
it 'should contain performer and period' do
expect(job.performer).to be TestJob
expect(job.period).to be period
end
it 'should contain data as JSON String' do
expect(job_with_args.job_args).to eq '[{"some":"data"}]'
end
describe '#next' do
it 'should return next performing time according to period' do
expect(job.next).to be_eql period.next
end
end
describe '#perform' do
after { job.send(:model).destroy }
it 'should run performer in separate thread' do
expect(job).to receive(:save)
thread = job.perform.join
expect(thread).to be_stop
end
it 'should save performin errors to log' do
thread = failing_job.perform.join
expect(thread).to be_stop
saved_log = Crono::CronoJob.find_by(job_id: failing_job.job_id).log
expect(saved_log).to include 'Some error'
end
it 'should set Job#healthy to false if perform with error' do
failing_job.perform.join
expect(failing_job.healthy).to be false
end
it 'should execute one' do
job.execution_interval = 5.minutes
expect(job).to receive(:perform_job).once
job.perform.join
thread = job.perform.join
expect(thread).to be_stop
end
it 'should execute twice' do
job.execution_interval = 0.minutes
test_preform_job_twice
end
it 'should execute twice without args' do
test_preform_job_twice not_args_job
end
it 'should execute twice without initialize execution_interval' do
test_preform_job_twice
end
it 'should call perform of performer' do
expect(TestJob).to receive(:new).with(no_args)
thread = job.perform.join
expect(thread).to be_stop
end
it 'should call perform of performer with data' do
test_job = double()
expect(TestJob).to receive(:new).and_return(test_job)
expect(test_job).to receive(:perform).with([{ 'some' => 'data' }])
thread = job_with_args.perform.join
expect(thread).to be_stop
end
def test_preform_job_twice(jon_instance = job)
expect(jon_instance).to receive(:perform_job).twice
jon_instance.perform.join
thread = jon_instance.perform.join
expect(thread).to be_stop
end
end
describe '#description' do
it 'should return job identificator' do
expect(job.description).to be_eql('Perform TestJob every 2 days at 15:00')
end
end
describe '#save' do
it 'should save new job to DB' do
expect(Crono::CronoJob.where(job_id: job.job_id)).to_not exist
job.save
expect(Crono::CronoJob.where(job_id: job.job_id)).to exist
end
it 'should update saved job' do
job.last_performed_at = Time.zone.now
job.healthy = true
job.job_args = JSON.generate([{some: 'data'}])
job.save
@crono_job = Crono::CronoJob.find_by(job_id: job.job_id)
expect(@crono_job.last_performed_at.utc.to_s).to be_eql job.last_performed_at.utc.to_s
expect(@crono_job.healthy).to be true
end
it 'should save log' do
message = 'test message'
job.send(:log, message)
job.save
expect(job.send(:model).reload.log).to include message
expect(job.job_log.string).to be_empty
end
it 'should not truncate log if not specified' do
log = (1..100).map {|n| "line #{n}" }.join("\n")
job = Crono::Job.new(TestJob, period, [])
job.send(:log, log)
job.save
expect(job.send(:model).reload.log.lines.size).to be >= log.lines.size
end
it 'should truncate log if specified' do
log = (1..100).map {|n| "line #{n}" }.join("\n")
job = Crono::Job.new(TestJob, period, [], truncate_log: 50)
job.send(:log, log)
job.save
expect(job.send(:model).reload.log.lines.size).to be 50
end
end
describe '#load' do
before do
@saved_last_performed_at = job.last_performed_at = Time.zone.now
job.save
end
it 'should load last_performed_at from DB' do
@job = Crono::Job.new(TestJob, period, job_args)
@job.load
expect(@job.last_performed_at.utc.to_s).to be_eql @saved_last_performed_at.utc.to_s
end
end
describe '#log' do
it 'should write log messages to both common and job log' do
message = 'Test message'
job.logfile = "/dev/null"
expect(job.logger).to receive(:log).with(Logger::INFO, message)
expect(job.job_logger).to receive(:log).with(Logger::INFO, message)
job.send(:log, message)
end
it 'should write job log to Job#job_log' do
message = 'Test message'
job.send(:log, message)
expect(job.job_log.string).to include(message)
end
end
describe '#log_error' do
it 'should call log with ERROR severity' do
message = 'Test message'
expect(job).to receive(:log).with(message, Logger::ERROR)
job.send(:log_error, message)
end
end
end