cronicle 0.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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/.travis.yml +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +127 -0
- data/Rakefile +5 -0
- data/Vagrantfile +56 -0
- data/bin/cronicle +6 -0
- data/cronicle.gemspec +31 -0
- data/cronicle.us-east-1.pem.enc +0 -0
- data/lib/cronicle.rb +28 -0
- data/lib/cronicle/cli.rb +105 -0
- data/lib/cronicle/client.rb +161 -0
- data/lib/cronicle/driver.rb +157 -0
- data/lib/cronicle/dsl.rb +7 -0
- data/lib/cronicle/dsl/context.rb +48 -0
- data/lib/cronicle/dsl/context/job.rb +58 -0
- data/lib/cronicle/exporter.rb +56 -0
- data/lib/cronicle/ext/hash_ext.rb +8 -0
- data/lib/cronicle/ext/sshkit_ext.rb +147 -0
- data/lib/cronicle/ext/string_ext.rb +11 -0
- data/lib/cronicle/host_list.rb +89 -0
- data/lib/cronicle/logger.rb +92 -0
- data/lib/cronicle/utils.rb +43 -0
- data/lib/cronicle/version.rb +3 -0
- data/spec/cronicle_create_spec.rb +295 -0
- data/spec/cronicle_delete_spec.rb +334 -0
- data/spec/cronicle_exec_spec.rb +159 -0
- data/spec/cronicle_update_spec.rb +365 -0
- data/spec/host_list_spec.rb +162 -0
- data/spec/spec_helper.rb +150 -0
- metadata +223 -0
@@ -0,0 +1,334 @@
|
|
1
|
+
describe 'Cronicle::Client#apply (update)' do
|
2
|
+
before do
|
3
|
+
on TARGET_HOSTS do |ssh_options|
|
4
|
+
user = ssh_options[:user]
|
5
|
+
|
6
|
+
set_crontab user, <<-CRON.undent
|
7
|
+
FOO=bar
|
8
|
+
ZOO=baz
|
9
|
+
1 1 1 1 1 echo #{user} > /dev/null
|
10
|
+
CRON
|
11
|
+
|
12
|
+
set_crontab :root, <<-CRON.undent
|
13
|
+
FOO=bar
|
14
|
+
ZOO=baz
|
15
|
+
1 1 1 1 1 echo root > /dev/null
|
16
|
+
CRON
|
17
|
+
end
|
18
|
+
|
19
|
+
cronicle(:apply) { <<-RUBY.undent }
|
20
|
+
on servers: /.*/ do
|
21
|
+
job :foo, user: :root, schedule: '1 2 * * *' do
|
22
|
+
puts `uname`
|
23
|
+
puts `whoami`
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
on servers: /.*/ do
|
28
|
+
job :bar, user: :root, schedule: :@hourly, content: <<-SH.undent
|
29
|
+
#!/bin/sh
|
30
|
+
echo hello
|
31
|
+
SH
|
32
|
+
end
|
33
|
+
|
34
|
+
on servers: /amazon_linux/ do
|
35
|
+
job :foo, user: 'ec2-user', schedule: '1 * * * *' do
|
36
|
+
puts 100
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
on servers: /ubuntu/ do
|
41
|
+
job :foo, user: :ubuntu, schedule: :@daily do
|
42
|
+
puts 200
|
43
|
+
end
|
44
|
+
end
|
45
|
+
RUBY
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:amzn_crontab_orig) do
|
49
|
+
{
|
50
|
+
"/var/spool/cron/ec2-user" =>
|
51
|
+
"FOO=bar
|
52
|
+
ZOO=baz
|
53
|
+
1 1 1 1 1 echo ec2-user > /dev/null
|
54
|
+
1 * * * *\t/var/lib/cronicle/libexec/ec2-user/foo 2>&1 | logger -t cronicle/ec2-user/foo
|
55
|
+
",
|
56
|
+
"/var/spool/cron/root" =>
|
57
|
+
"FOO=bar
|
58
|
+
ZOO=baz
|
59
|
+
1 1 1 1 1 echo root > /dev/null
|
60
|
+
1 2 * * *\t/var/lib/cronicle/libexec/root/foo 2>&1 | logger -t cronicle/root/foo
|
61
|
+
@hourly\t/var/lib/cronicle/libexec/root/bar 2>&1 | logger -t cronicle/root/bar
|
62
|
+
"
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:ubuntu_crontab_orig) do
|
67
|
+
{
|
68
|
+
"/var/spool/cron/crontabs/root" =>
|
69
|
+
"FOO=bar
|
70
|
+
ZOO=baz
|
71
|
+
1 1 1 1 1 echo root > /dev/null
|
72
|
+
1 2 * * *\t/var/lib/cronicle/libexec/root/foo 2>&1 | logger -t cronicle/root/foo
|
73
|
+
@hourly\t/var/lib/cronicle/libexec/root/bar 2>&1 | logger -t cronicle/root/bar
|
74
|
+
",
|
75
|
+
"/var/spool/cron/crontabs/ubuntu" =>
|
76
|
+
"FOO=bar
|
77
|
+
ZOO=baz
|
78
|
+
1 1 1 1 1 echo ubuntu > /dev/null
|
79
|
+
@daily\t/var/lib/cronicle/libexec/ubuntu/foo 2>&1 | logger -t cronicle/ubuntu/foo
|
80
|
+
"
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
let(:jobfile) do
|
85
|
+
<<-RUBY.undent
|
86
|
+
on servers: /.*/ do
|
87
|
+
job :foo, user: :root, schedule: '1 2 * * *' do
|
88
|
+
puts `uname`
|
89
|
+
puts `whoami`
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
on servers: /amazon_linux/ do
|
94
|
+
job :foo, user: 'ec2-user', schedule: '2 * * * *' do
|
95
|
+
puts 100
|
96
|
+
end
|
97
|
+
end
|
98
|
+
RUBY
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when cron is deleted' do
|
102
|
+
let(:amzn_crontab) do
|
103
|
+
{
|
104
|
+
"/var/spool/cron/ec2-user" =>
|
105
|
+
"FOO=bar
|
106
|
+
ZOO=baz
|
107
|
+
1 1 1 1 1 echo ec2-user > /dev/null
|
108
|
+
2 * * * *\t/var/lib/cronicle/libexec/ec2-user/foo 2>&1 | logger -t cronicle/ec2-user/foo
|
109
|
+
",
|
110
|
+
"/var/spool/cron/root" =>
|
111
|
+
"FOO=bar
|
112
|
+
ZOO=baz
|
113
|
+
1 1 1 1 1 echo root > /dev/null
|
114
|
+
1 2 * * *\t/var/lib/cronicle/libexec/root/foo 2>&1 | logger -t cronicle/root/foo
|
115
|
+
"
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
119
|
+
let(:ubuntu_crontab) do
|
120
|
+
{
|
121
|
+
"/var/spool/cron/crontabs/root" =>
|
122
|
+
"FOO=bar
|
123
|
+
ZOO=baz
|
124
|
+
1 1 1 1 1 echo root > /dev/null
|
125
|
+
1 2 * * *\t/var/lib/cronicle/libexec/root/foo 2>&1 | logger -t cronicle/root/foo
|
126
|
+
",
|
127
|
+
"/var/spool/cron/crontabs/ubuntu" =>
|
128
|
+
"FOO=bar
|
129
|
+
ZOO=baz
|
130
|
+
1 1 1 1 1 echo ubuntu > /dev/null
|
131
|
+
"
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
it do
|
136
|
+
on :amazon_linux do
|
137
|
+
expect(get_uname).to match /amzn/
|
138
|
+
expect(get_crontabs).to eq amzn_crontab_orig
|
139
|
+
|
140
|
+
expect(get_file('/var/lib/cronicle/libexec/root/foo')).to eq <<-EOS.undent
|
141
|
+
#!/usr/bin/env ruby
|
142
|
+
puts `uname`
|
143
|
+
puts `whoami`
|
144
|
+
EOS
|
145
|
+
|
146
|
+
expect(get_file('/var/lib/cronicle/libexec/root/bar')).to eq <<-EOS.undent
|
147
|
+
#!/bin/sh
|
148
|
+
echo hello
|
149
|
+
EOS
|
150
|
+
|
151
|
+
expect(get_file('/var/lib/cronicle/libexec/ec2-user/foo')).to eq <<-EOS.undent
|
152
|
+
#!/usr/bin/env ruby
|
153
|
+
puts 100
|
154
|
+
EOS
|
155
|
+
end
|
156
|
+
|
157
|
+
on :ubuntu do
|
158
|
+
expect(get_uname).to match /Ubuntu/
|
159
|
+
expect(get_crontabs).to eq ubuntu_crontab_orig
|
160
|
+
|
161
|
+
expect(get_file('/var/lib/cronicle/libexec/root/foo')).to eq <<-EOS.undent
|
162
|
+
#!/usr/bin/env ruby
|
163
|
+
puts `uname`
|
164
|
+
puts `whoami`
|
165
|
+
EOS
|
166
|
+
|
167
|
+
expect(get_file('/var/lib/cronicle/libexec/root/bar')).to eq <<-EOS.undent
|
168
|
+
#!/bin/sh
|
169
|
+
echo hello
|
170
|
+
EOS
|
171
|
+
|
172
|
+
expect(get_file('/var/lib/cronicle/libexec/ubuntu/foo')).to eq <<-EOS.undent
|
173
|
+
#!/usr/bin/env ruby
|
174
|
+
puts 200
|
175
|
+
EOS
|
176
|
+
end
|
177
|
+
|
178
|
+
cronicle(:apply) { jobfile }
|
179
|
+
|
180
|
+
on :amazon_linux do
|
181
|
+
expect(get_uname).to match /amzn/
|
182
|
+
expect(get_crontabs).to eq amzn_crontab
|
183
|
+
|
184
|
+
expect(get_file('/var/lib/cronicle/libexec/root/foo')).to eq <<-EOS.undent
|
185
|
+
#!/usr/bin/env ruby
|
186
|
+
puts `uname`
|
187
|
+
puts `whoami`
|
188
|
+
EOS
|
189
|
+
|
190
|
+
expect(get_file('/var/lib/cronicle/libexec/ec2-user/foo')).to eq <<-EOS.undent
|
191
|
+
#!/usr/bin/env ruby
|
192
|
+
puts 100
|
193
|
+
EOS
|
194
|
+
end
|
195
|
+
|
196
|
+
on :ubuntu do
|
197
|
+
expect(get_uname).to match /Ubuntu/
|
198
|
+
expect(get_crontabs).to eq ubuntu_crontab
|
199
|
+
|
200
|
+
expect(get_file('/var/lib/cronicle/libexec/root/foo')).to eq <<-EOS.undent
|
201
|
+
#!/usr/bin/env ruby
|
202
|
+
puts `uname`
|
203
|
+
puts `whoami`
|
204
|
+
EOS
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'when cron is deleted (dry-run)' do
|
210
|
+
let(:amzn_crontab) do
|
211
|
+
{
|
212
|
+
"/var/spool/cron/ec2-user" =>
|
213
|
+
"FOO=bar
|
214
|
+
ZOO=baz
|
215
|
+
1 1 1 1 1 echo ec2-user > /dev/null
|
216
|
+
2 * * * *\t/var/lib/cronicle/libexec/ec2-user/foo 2>&1 | logger -t cronicle/ec2-user/foo
|
217
|
+
",
|
218
|
+
"/var/spool/cron/root" =>
|
219
|
+
"FOO=bar
|
220
|
+
ZOO=baz
|
221
|
+
1 1 1 1 1 echo root > /dev/null
|
222
|
+
@hourly\t/var/lib/cronicle/libexec/root/bar 2>&1 | logger -t cronicle/root/bar
|
223
|
+
1 2 * * *\t/var/lib/cronicle/libexec/root/foo 2>&1 | logger -t cronicle/root/foo
|
224
|
+
"
|
225
|
+
}
|
226
|
+
end
|
227
|
+
|
228
|
+
let(:ubuntu_crontab) do
|
229
|
+
{
|
230
|
+
"/var/spool/cron/crontabs/root" =>
|
231
|
+
"FOO=bar
|
232
|
+
ZOO=baz
|
233
|
+
1 1 1 1 1 echo root > /dev/null
|
234
|
+
@hourly\t/var/lib/cronicle/libexec/root/bar 2>&1 | logger -t cronicle/root/bar
|
235
|
+
1 2 * * *\t/var/lib/cronicle/libexec/root/foo 2>&1 | logger -t cronicle/root/foo
|
236
|
+
",
|
237
|
+
"/var/spool/cron/crontabs/ubuntu" =>
|
238
|
+
"FOO=bar
|
239
|
+
ZOO=baz
|
240
|
+
1 1 1 1 1 echo ubuntu > /dev/null
|
241
|
+
@daily\t/var/lib/cronicle/libexec/ubuntu/foo2 2>&1 | logger -t cronicle/ubuntu/foo2
|
242
|
+
"
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
246
|
+
it do
|
247
|
+
on :amazon_linux do
|
248
|
+
expect(get_uname).to match /amzn/
|
249
|
+
expect(get_crontabs).to eq amzn_crontab_orig
|
250
|
+
|
251
|
+
expect(get_file('/var/lib/cronicle/libexec/root/foo')).to eq <<-EOS.undent
|
252
|
+
#!/usr/bin/env ruby
|
253
|
+
puts `uname`
|
254
|
+
puts `whoami`
|
255
|
+
EOS
|
256
|
+
|
257
|
+
expect(get_file('/var/lib/cronicle/libexec/root/bar')).to eq <<-EOS.undent
|
258
|
+
#!/bin/sh
|
259
|
+
echo hello
|
260
|
+
EOS
|
261
|
+
|
262
|
+
expect(get_file('/var/lib/cronicle/libexec/ec2-user/foo')).to eq <<-EOS.undent
|
263
|
+
#!/usr/bin/env ruby
|
264
|
+
puts 100
|
265
|
+
EOS
|
266
|
+
end
|
267
|
+
|
268
|
+
on :ubuntu do
|
269
|
+
expect(get_uname).to match /Ubuntu/
|
270
|
+
expect(get_crontabs).to eq ubuntu_crontab_orig
|
271
|
+
|
272
|
+
expect(get_file('/var/lib/cronicle/libexec/root/foo')).to eq <<-EOS.undent
|
273
|
+
#!/usr/bin/env ruby
|
274
|
+
puts `uname`
|
275
|
+
puts `whoami`
|
276
|
+
EOS
|
277
|
+
|
278
|
+
expect(get_file('/var/lib/cronicle/libexec/root/bar')).to eq <<-EOS.undent
|
279
|
+
#!/bin/sh
|
280
|
+
echo hello
|
281
|
+
EOS
|
282
|
+
|
283
|
+
expect(get_file('/var/lib/cronicle/libexec/ubuntu/foo')).to eq <<-EOS.undent
|
284
|
+
#!/usr/bin/env ruby
|
285
|
+
puts 200
|
286
|
+
EOS
|
287
|
+
end
|
288
|
+
|
289
|
+
cronicle(:apply, dry_run: true) { jobfile }
|
290
|
+
|
291
|
+
on :amazon_linux do
|
292
|
+
expect(get_uname).to match /amzn/
|
293
|
+
expect(get_crontabs).to eq amzn_crontab_orig
|
294
|
+
|
295
|
+
expect(get_file('/var/lib/cronicle/libexec/root/foo')).to eq <<-EOS.undent
|
296
|
+
#!/usr/bin/env ruby
|
297
|
+
puts `uname`
|
298
|
+
puts `whoami`
|
299
|
+
EOS
|
300
|
+
|
301
|
+
expect(get_file('/var/lib/cronicle/libexec/root/bar')).to eq <<-EOS.undent
|
302
|
+
#!/bin/sh
|
303
|
+
echo hello
|
304
|
+
EOS
|
305
|
+
|
306
|
+
expect(get_file('/var/lib/cronicle/libexec/ec2-user/foo')).to eq <<-EOS.undent
|
307
|
+
#!/usr/bin/env ruby
|
308
|
+
puts 100
|
309
|
+
EOS
|
310
|
+
end
|
311
|
+
|
312
|
+
on :ubuntu do
|
313
|
+
expect(get_uname).to match /Ubuntu/
|
314
|
+
expect(get_crontabs).to eq ubuntu_crontab_orig
|
315
|
+
|
316
|
+
expect(get_file('/var/lib/cronicle/libexec/root/foo')).to eq <<-EOS.undent
|
317
|
+
#!/usr/bin/env ruby
|
318
|
+
puts `uname`
|
319
|
+
puts `whoami`
|
320
|
+
EOS
|
321
|
+
|
322
|
+
expect(get_file('/var/lib/cronicle/libexec/root/bar')).to eq <<-EOS.undent
|
323
|
+
#!/bin/sh
|
324
|
+
echo hello
|
325
|
+
EOS
|
326
|
+
|
327
|
+
expect(get_file('/var/lib/cronicle/libexec/ubuntu/foo')).to eq <<-EOS.undent
|
328
|
+
#!/usr/bin/env ruby
|
329
|
+
puts 200
|
330
|
+
EOS
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
describe 'Cronicle::Client#exec' do
|
2
|
+
let(:logger_out) { StringIO.new }
|
3
|
+
|
4
|
+
let(:logger) do
|
5
|
+
logger = Logger.new(logger_out)
|
6
|
+
|
7
|
+
logger.formatter = proc {|severity, datetime, progname, msg|
|
8
|
+
"#{msg}\n"
|
9
|
+
}
|
10
|
+
|
11
|
+
logger
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:amzn_out) { logger_out.string.each_line.select {|i| i =~ /amazon_linux/ }.join }
|
15
|
+
let(:ubuntu_out) {logger_out.string.each_line.select {|i| i =~ /ubuntu/ }.join }
|
16
|
+
|
17
|
+
context 'run as root' do
|
18
|
+
let(:jobfile) do
|
19
|
+
<<-RUBY.undent
|
20
|
+
on servers: /.*/ do
|
21
|
+
job :foo, user: :root do
|
22
|
+
puts `uname`
|
23
|
+
puts `whoami`
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
on servers: /.*/ do
|
28
|
+
job :bar, user: :root, content: <<-SH.undent
|
29
|
+
#!/bin/sh
|
30
|
+
echo hello
|
31
|
+
SH
|
32
|
+
end
|
33
|
+
RUBY
|
34
|
+
end
|
35
|
+
|
36
|
+
before do
|
37
|
+
cronicle(:exec, :foo, logger: logger) { jobfile }
|
38
|
+
cronicle(:exec, :bar, logger: logger) { jobfile }
|
39
|
+
end
|
40
|
+
|
41
|
+
it do
|
42
|
+
expect(amzn_out).to eq <<-EOS.undent
|
43
|
+
foo on amazon_linux/root> Execute job
|
44
|
+
foo on amazon_linux/root> Linux
|
45
|
+
foo on amazon_linux/root> root
|
46
|
+
bar on amazon_linux/root> Execute job
|
47
|
+
bar on amazon_linux/root> hello
|
48
|
+
EOS
|
49
|
+
end
|
50
|
+
|
51
|
+
it do
|
52
|
+
expect(ubuntu_out).to eq <<-EOS.undent
|
53
|
+
foo on ubuntu/root> Execute job
|
54
|
+
foo on ubuntu/root> Linux
|
55
|
+
foo on ubuntu/root> root
|
56
|
+
bar on ubuntu/root> Execute job
|
57
|
+
bar on ubuntu/root> hello
|
58
|
+
EOS
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'run as root (dry-run)' do
|
63
|
+
let(:jobfile) do
|
64
|
+
<<-RUBY.undent
|
65
|
+
on servers: /.*/ do
|
66
|
+
job :foo, user: :root do
|
67
|
+
puts `uname`
|
68
|
+
puts `whoami`
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
on servers: /.*/ do
|
73
|
+
job :bar, user: :root, content: <<-SH.undent
|
74
|
+
#!/bin/sh
|
75
|
+
echo hello
|
76
|
+
SH
|
77
|
+
end
|
78
|
+
RUBY
|
79
|
+
end
|
80
|
+
|
81
|
+
before do
|
82
|
+
cronicle(:exec, :foo, logger: logger, dry_run: true) { jobfile }
|
83
|
+
cronicle(:exec, :bar, logger: logger, dry_run: true) { jobfile }
|
84
|
+
end
|
85
|
+
|
86
|
+
it do
|
87
|
+
expect(amzn_out).to eq <<-EOS.undent
|
88
|
+
foo on amazon_linux/root> Execute job (dry-run)
|
89
|
+
bar on amazon_linux/root> Execute job (dry-run)
|
90
|
+
EOS
|
91
|
+
end
|
92
|
+
|
93
|
+
it do
|
94
|
+
expect(ubuntu_out).to eq <<-EOS.undent
|
95
|
+
foo on ubuntu/root> Execute job (dry-run)
|
96
|
+
bar on ubuntu/root> Execute job (dry-run)
|
97
|
+
EOS
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'run as non-root user' do
|
102
|
+
let(:jobfile) do
|
103
|
+
<<-RUBY.undent
|
104
|
+
on servers: /amazon_linux/ do
|
105
|
+
job :foo, user: 'ec2-user' do
|
106
|
+
puts `uname`
|
107
|
+
puts `whoami`
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
on servers: /ubuntu/ do
|
112
|
+
job :foo, user: :ubuntu do
|
113
|
+
puts `uname`
|
114
|
+
puts `whoami`
|
115
|
+
end
|
116
|
+
end
|
117
|
+
RUBY
|
118
|
+
end
|
119
|
+
|
120
|
+
before do
|
121
|
+
cronicle(:exec, :foo, logger: logger) { jobfile }
|
122
|
+
end
|
123
|
+
|
124
|
+
it do
|
125
|
+
expect(amzn_out).to eq <<-EOS.undent
|
126
|
+
foo on amazon_linux/ec2-user> Execute job
|
127
|
+
foo on amazon_linux/ec2-user> Linux
|
128
|
+
foo on amazon_linux/ec2-user> ec2-user
|
129
|
+
EOS
|
130
|
+
end
|
131
|
+
|
132
|
+
it do
|
133
|
+
expect(ubuntu_out).to eq <<-EOS.undent
|
134
|
+
foo on ubuntu/ubuntu> Execute job
|
135
|
+
foo on ubuntu/ubuntu> Linux
|
136
|
+
foo on ubuntu/ubuntu> ubuntu
|
137
|
+
EOS
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'jon is not defined' do
|
142
|
+
let(:jobfile) do
|
143
|
+
<<-RUBY.undent
|
144
|
+
on servers: /.*/ do
|
145
|
+
job :foo, user: :root do
|
146
|
+
puts `uname`
|
147
|
+
puts `whoami`
|
148
|
+
end
|
149
|
+
end
|
150
|
+
RUBY
|
151
|
+
end
|
152
|
+
|
153
|
+
it do
|
154
|
+
expect {
|
155
|
+
cronicle(:exec, :bar, logger: logger) { jobfile }
|
156
|
+
}.to raise_error('Definition cannot be found: Job `bar`')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|