r10k 3.9.1 → 3.11.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec_tests.yml +1 -1
  3. data/.travis.yml +0 -10
  4. data/CHANGELOG.mkd +28 -0
  5. data/README.mkd +6 -0
  6. data/doc/dynamic-environments/configuration.mkd +21 -0
  7. data/doc/puppetfile.mkd +15 -1
  8. data/integration/Rakefile +3 -1
  9. data/integration/tests/user_scenario/basic_workflow/negative/neg_specify_deleted_forge_module.rb +3 -9
  10. data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +21 -25
  11. data/integration/tests/user_scenario/complex_workflow/multi_env_add_change_remove.rb +3 -3
  12. data/integration/tests/user_scenario/complex_workflow/multi_env_remove_re-add.rb +3 -3
  13. data/integration/tests/user_scenario/complex_workflow/multi_env_unamanaged.rb +3 -3
  14. data/lib/r10k/action/base.rb +6 -3
  15. data/lib/r10k/action/deploy/display.rb +6 -3
  16. data/lib/r10k/action/deploy/environment.rb +15 -4
  17. data/lib/r10k/action/deploy/module.rb +37 -8
  18. data/lib/r10k/action/runner.rb +45 -10
  19. data/lib/r10k/cli/deploy.rb +4 -0
  20. data/lib/r10k/git.rb +3 -0
  21. data/lib/r10k/git/cache.rb +1 -1
  22. data/lib/r10k/git/rugged/credentials.rb +77 -0
  23. data/lib/r10k/git/stateful_repository.rb +1 -0
  24. data/lib/r10k/initializers.rb +10 -0
  25. data/lib/r10k/module/base.rb +37 -0
  26. data/lib/r10k/module/forge.rb +7 -2
  27. data/lib/r10k/module/git.rb +2 -1
  28. data/lib/r10k/module/svn.rb +2 -1
  29. data/lib/r10k/module_loader/puppetfile.rb +206 -0
  30. data/lib/r10k/module_loader/puppetfile/dsl.rb +37 -0
  31. data/lib/r10k/puppetfile.rb +83 -160
  32. data/lib/r10k/settings.rb +47 -2
  33. data/lib/r10k/settings/definition.rb +1 -1
  34. data/lib/r10k/source/base.rb +10 -0
  35. data/lib/r10k/source/git.rb +5 -0
  36. data/lib/r10k/source/svn.rb +4 -0
  37. data/lib/r10k/util/purgeable.rb +70 -8
  38. data/lib/r10k/version.rb +1 -1
  39. data/locales/r10k.pot +129 -57
  40. data/r10k.gemspec +2 -0
  41. data/spec/fixtures/unit/action/r10k_forge_auth.yaml +4 -0
  42. data/spec/fixtures/unit/action/r10k_forge_auth_no_url.yaml +3 -0
  43. data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_subdir_2/ignored_1 +0 -0
  44. data/spec/fixtures/unit/util/purgeable/managed_two/.hidden/unmanaged_3 +0 -0
  45. data/spec/unit/action/deploy/environment_spec.rb +25 -0
  46. data/spec/unit/action/deploy/module_spec.rb +216 -14
  47. data/spec/unit/action/runner_spec.rb +129 -25
  48. data/spec/unit/git/cache_spec.rb +14 -0
  49. data/spec/unit/git/rugged/credentials_spec.rb +29 -0
  50. data/spec/unit/git/stateful_repository_spec.rb +5 -0
  51. data/spec/unit/module/base_spec.rb +46 -0
  52. data/spec/unit/module/forge_spec.rb +27 -1
  53. data/spec/unit/module/git_spec.rb +17 -8
  54. data/spec/unit/module/svn_spec.rb +18 -0
  55. data/spec/unit/module_loader/puppetfile_spec.rb +343 -0
  56. data/spec/unit/module_spec.rb +28 -0
  57. data/spec/unit/puppetfile_spec.rb +127 -191
  58. data/spec/unit/settings_spec.rb +24 -2
  59. data/spec/unit/util/purgeable_spec.rb +38 -6
  60. metadata +23 -2
data/r10k.gemspec CHANGED
@@ -36,6 +36,8 @@ Gem::Specification.new do |s|
36
36
  s.add_dependency 'fast_gettext', '~> 1.1.0'
37
37
  s.add_dependency 'gettext', ['>= 3.0.2', '< 3.3.0']
38
38
 
39
+ s.add_dependency 'jwt', '~> 2.2.3'
40
+
39
41
  s.add_development_dependency 'rspec', '~> 3.1'
40
42
 
41
43
  s.add_development_dependency 'rake'
@@ -0,0 +1,4 @@
1
+ ---
2
+ forge:
3
+ baseurl: 'http://private-forge.com'
4
+ authorization_token: 'faketoken'
@@ -0,0 +1,3 @@
1
+ ---
2
+ forge:
3
+ authorization_token: 'faketoken'
@@ -47,6 +47,22 @@ describe R10K::Action::Deploy::Environment do
47
47
  described_class.new({ 'oauth-token': '/nonexistent' }, [], {})
48
48
  end
49
49
 
50
+ it 'can accept an app id option' do
51
+ described_class.new({ 'github-app-id': '/nonexistent' }, [], {})
52
+ end
53
+
54
+ it 'can accept a ttl option' do
55
+ described_class.new({ 'github-app-ttl': '/nonexistent' }, [], {})
56
+ end
57
+
58
+ it 'can accept a ssl private key option' do
59
+ described_class.new({ 'github-app-key': '/nonexistent' }, [], {})
60
+ end
61
+
62
+ it 'can accept a exclude-spec option' do
63
+ described_class.new({ :'exclude-spec' => true }, [], {})
64
+ end
65
+
50
66
  describe "initializing errors" do
51
67
  let (:settings) { { deploy: { purge_levels: [:environment],
52
68
  purge_whitelist: ['coolfile', 'coolfile2'],
@@ -265,6 +281,15 @@ describe R10K::Action::Deploy::Environment do
265
281
  describe "deployment purge level" do
266
282
  let(:purge_levels) { [:deployment] }
267
283
 
284
+
285
+ it "updates the source's cache before it purges environments" do
286
+ deployment.sources.each do |source|
287
+ expect(source).to receive(:reload!).ordered
288
+ end
289
+ expect(deployment).to receive(:purge!).ordered
290
+ subject.call
291
+ end
292
+
268
293
  it "only logs about purging deployment" do
269
294
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, env, &block|
270
295
  expect(env.logger).to_not receive(:debug).with(/purging unmanaged puppetfile content/i)
@@ -41,6 +41,22 @@ describe R10K::Action::Deploy::Module do
41
41
  it 'can accept a token option' do
42
42
  described_class.new({ 'oauth-token': '/nonexistent' }, [], {})
43
43
  end
44
+
45
+ it 'can accept an app id option' do
46
+ described_class.new({ 'github-app-id': '/nonexistent' }, [], {})
47
+ end
48
+
49
+ it 'can accept a ttl option' do
50
+ described_class.new({ 'github-app-ttl': '/nonexistent' }, [], {})
51
+ end
52
+
53
+ it 'can accept a ssl private key option' do
54
+ described_class.new({ 'github-app-key': '/nonexistent' }, [], {})
55
+ end
56
+
57
+ it 'can accept a exclude-spec option' do
58
+ described_class.new({ :'exclude-spec' => true }, [], {})
59
+ end
44
60
  end
45
61
 
46
62
  describe "with no-force" do
@@ -177,12 +193,39 @@ describe R10K::Action::Deploy::Module do
177
193
  end
178
194
  end
179
195
 
196
+ describe 'with github-app-id' do
197
+
198
+ subject { described_class.new({ config: '/some/nonexistent/path', 'github-app-id': '/nonexistent' }, [], {}) }
199
+
200
+ it 'sets github-app-id' do
201
+ expect(subject.instance_variable_get(:@github_app_id)).to eq('/nonexistent')
202
+ end
203
+ end
204
+
205
+ describe 'with github-app-key' do
206
+
207
+ subject { described_class.new({ config: '/some/nonexistent/path', 'github-app-key': '/nonexistent' }, [], {}) }
208
+
209
+ it 'sets github-app-key' do
210
+ expect(subject.instance_variable_get(:@github_app_key)).to eq('/nonexistent')
211
+ end
212
+ end
213
+
214
+ describe 'with github-app-ttl' do
215
+
216
+ subject { described_class.new({ config: '/some/nonexistent/path', 'github-app-ttl': '/nonexistent' }, [], {}) }
217
+
218
+ it 'sets github-app-ttl' do
219
+ expect(subject.instance_variable_get(:@github_app_ttl)).to eq('/nonexistent')
220
+ end
221
+ end
222
+
180
223
  describe 'with modules' do
181
224
 
182
225
  subject { described_class.new({ config: '/some/nonexistent/path' }, ['mod1', 'mod2'], {}) }
183
226
 
184
227
  let(:cache) { instance_double("R10K::Git::Cache", 'sanitized_dirname' => 'foo', 'cached?' => true, 'sync' => true) }
185
- let(:repo) { instance_double("R10K::Git::StatefulRepository", cache: cache, resolve: 'main') }
228
+ let(:repo) { instance_double("R10K::Git::StatefulRepository", cache: cache, resolve: 'main', tracked_paths: []) }
186
229
 
187
230
  it 'does not sync modules not given' do
188
231
  allow(R10K::Deployment).to receive(:new).and_wrap_original do |original, settings, &block|
@@ -202,14 +245,26 @@ describe R10K::Action::Deploy::Module do
202
245
  allow_any_instance_of(R10K::Source::Git).to receive(:branch_names).and_return([R10K::Environment::Name.new('first', {})])
203
246
 
204
247
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
205
- pf = environment.puppetfile
206
- expect(pf).to receive(:load) do
207
- pf.add_module('mod1', { git: 'git://remote' })
208
- pf.add_module('mod2', { git: 'git://remote' })
209
- pf.add_module('mod3', { git: 'git://remote' })
248
+ # For this test we want to have realistic Modules and access to
249
+ # their internal Repos to validate the sync. Unfortunately, to
250
+ # do so we do some invasive mocking, effectively implementing
251
+ # our own R10K::Puppetfile#load. We directly update the Puppetfile's
252
+ # internal ModuleLoader and then call `load` on it so it will create
253
+ # the correct loaded_content.
254
+ puppetfile = environment.puppetfile
255
+ loader = puppetfile.loader
256
+ expect(puppetfile).to receive(:load) do
257
+ loader.add_module('mod1', { git: 'git://remote' })
258
+ loader.add_module('mod2', { git: 'git://remote' })
259
+ loader.add_module('mod3', { git: 'git://remote' })
260
+
261
+ allow(loader).to receive(:puppetfile_content).and_return('')
262
+ loaded_content = loader.load
263
+ puppetfile.instance_variable_set(:@loaded_content, loaded_content)
264
+ puppetfile.instance_variable_set(:@loaded, true)
210
265
  end
211
266
 
212
- pf.modules.each do |mod|
267
+ puppetfile.modules.each do |mod|
213
268
  if ['mod1', 'mod2'].include?(mod.name)
214
269
  expect(mod.should_sync?).to be(true)
215
270
  else
@@ -231,7 +286,7 @@ describe R10K::Action::Deploy::Module do
231
286
  subject { described_class.new({ config: '/some/nonexistent/path', environment: 'first' }, ['mod1'], {}) }
232
287
 
233
288
  let(:cache) { instance_double("R10K::Git::Cache", 'sanitized_dirname' => 'foo', 'cached?' => true, 'sync' => true) }
234
- let(:repo) { instance_double("R10K::Git::StatefulRepository", cache: cache, resolve: 'main') }
289
+ let(:repo) { instance_double("R10K::Git::StatefulRepository", cache: cache, resolve: 'main', tracked_paths: []) }
235
290
 
236
291
  it 'only syncs to the given environments' do
237
292
  allow(R10K::Deployment).to receive(:new).and_wrap_original do |original, settings, &block|
@@ -252,15 +307,27 @@ describe R10K::Action::Deploy::Module do
252
307
  R10K::Environment::Name.new('second', {})])
253
308
 
254
309
  expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
255
- pf = environment.puppetfile
310
+ puppetfile = environment.puppetfile
256
311
 
257
312
  if environment.name == 'first'
258
- expect(pf).to receive(:load) do
259
- pf.add_module('mod1', { git: 'git://remote' })
260
- pf.add_module('mod2', { git: 'git://remote' })
313
+ # For this test we want to have realistic Modules and access to
314
+ # their internal Repos to validate the sync. Unfortunately, to
315
+ # do so we do some invasive mocking, effectively implementing
316
+ # our own R10K::Puppetfile#load. We directly update the Puppetfile's
317
+ # internal ModuleLoader and then call `load` on it so it will create
318
+ # the correct loaded_content.
319
+ loader = puppetfile.loader
320
+ expect(puppetfile).to receive(:load) do
321
+ loader.add_module('mod1', { git: 'git://remote' })
322
+ loader.add_module('mod2', { git: 'git://remote' })
323
+
324
+ allow(loader).to receive(:puppetfile_content).and_return('')
325
+ loaded_content = loader.load
326
+ puppetfile.instance_variable_set(:@loaded_content, loaded_content)
327
+ puppetfile.instance_variable_set(:@loaded, true)
261
328
  end
262
329
 
263
- pf.modules.each do |mod|
330
+ puppetfile.modules.each do |mod|
264
331
  if mod.name == 'mod1'
265
332
  expect(mod.should_sync?).to be(true)
266
333
  else
@@ -269,7 +336,7 @@ describe R10K::Action::Deploy::Module do
269
336
  expect(mod).to receive(:sync).and_call_original
270
337
  end
271
338
  else
272
- expect(pf).not_to receive(:load)
339
+ expect(puppetfile).not_to receive(:load)
273
340
  end
274
341
 
275
342
  original.call(environment, &block)
@@ -282,5 +349,140 @@ describe R10K::Action::Deploy::Module do
282
349
  subject.call
283
350
  end
284
351
  end
352
+
353
+
354
+ describe "postrun" do
355
+ let(:mock_config) do
356
+ R10K::Deployment::MockConfig.new(
357
+ :sources => {
358
+ :control => {
359
+ :type => :mock,
360
+ :basedir => '/some/nonexistent/path/control',
361
+ :environments => %w[first second third],
362
+ }
363
+ }
364
+ )
365
+ end
366
+
367
+ context "basic postrun hook" do
368
+ let(:settings) { { postrun: ["/path/to/executable", "arg1", "arg2"] } }
369
+ let(:deployment) { R10K::Deployment.new(mock_config.merge(settings)) }
370
+
371
+ before do
372
+ expect(R10K::Deployment).to receive(:new).and_return(deployment)
373
+ end
374
+
375
+ subject do
376
+ described_class.new({config: "/some/nonexistent/path" },
377
+ ['mod1'], settings)
378
+ end
379
+
380
+ it "is passed to Subprocess" do
381
+ mock_subprocess = double
382
+ allow(mock_subprocess).to receive(:logger=)
383
+ expect(mock_subprocess).to receive(:execute)
384
+
385
+ expect(R10K::Util::Subprocess).to receive(:new).
386
+ with(["/path/to/executable", "arg1", "arg2"]).
387
+ and_return(mock_subprocess)
388
+
389
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
390
+ modified = subject.instance_variable_get(:@modified_envs) << environment
391
+ subject.instance_variable_set(:modified_envs, modified)
392
+ end.exactly(3).times
393
+
394
+ subject.call
395
+ end
396
+ end
397
+
398
+ context "supports environments" do
399
+ context "with one environment" do
400
+ let(:settings) { { postrun: ["/generate/types/wrapper", "$modifiedenvs"] } }
401
+ let(:deployment) { R10K::Deployment.new(mock_config.merge(settings)) }
402
+
403
+ before do
404
+ expect(R10K::Deployment).to receive(:new).and_return(deployment)
405
+ end
406
+
407
+ subject do
408
+ described_class.new({ config: '/some/nonexistent/path',
409
+ environment: 'first' },
410
+ ['mod1'], settings)
411
+ end
412
+
413
+ it "properly substitutes the environment" do
414
+ mock_subprocess = double
415
+ allow(mock_subprocess).to receive(:logger=)
416
+ expect(mock_subprocess).to receive(:execute)
417
+
418
+ mock_mod = double('mock_mod', name: 'mod1')
419
+
420
+ expect(R10K::Util::Subprocess).to receive(:new).
421
+ with(["/generate/types/wrapper", "first"]).
422
+ and_return(mock_subprocess)
423
+
424
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
425
+ if environment.name == 'first'
426
+ expect(environment).to receive(:deploy).and_return(true)
427
+ expect(environment).to receive(:modules).and_return([mock_mod])
428
+ end
429
+ original.call(environment, &block)
430
+ end.exactly(3).times
431
+
432
+ subject.call
433
+ end
434
+ end
435
+
436
+ context "with all environments" do
437
+ let(:settings) { { postrun: ["/generate/types/wrapper", "$modifiedenvs"] } }
438
+ let(:deployment) { R10K::Deployment.new(mock_config.merge(settings)) }
439
+
440
+ before do
441
+ expect(R10K::Deployment).to receive(:new).and_return(deployment)
442
+ end
443
+
444
+ subject do
445
+ described_class.new({ config: '/some/nonexistent/path' },
446
+ ['mod1'], settings)
447
+ end
448
+
449
+ it "properly substitutes the environment where modules were deployed" do
450
+ mock_subprocess = double
451
+ allow(mock_subprocess).to receive(:logger=)
452
+ expect(mock_subprocess).to receive(:execute)
453
+
454
+ expect(R10K::Util::Subprocess).to receive(:new).
455
+ with(["/generate/types/wrapper", "first third"]).
456
+ and_return(mock_subprocess)
457
+
458
+ mock_mod = double('mock_mod', name: 'mod1')
459
+
460
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
461
+ expect(environment).to receive(:deploy).and_return(true)
462
+ if ['first', 'third'].include?(environment.name)
463
+ expect(environment).to receive(:modules).and_return([mock_mod])
464
+ end
465
+ original.call(environment, &block)
466
+ end.exactly(3).times
467
+
468
+ subject.call
469
+ end
470
+
471
+ it "does not execute the command if no envs had the module" do
472
+ expect(R10K::Util::Subprocess).not_to receive(:new)
473
+
474
+ mock_mod2 = double('mock_mod', name: 'mod2')
475
+ expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
476
+ expect(environment).to receive(:deploy).and_return(true)
477
+ # Envs have a different module than the one we asked to deploy
478
+ expect(environment).to receive(:modules).and_return([mock_mod2])
479
+ original.call(environment, &block)
480
+ end.exactly(3).times
481
+
482
+ subject.call
483
+ end
484
+ end
485
+ end
486
+ end
285
487
  end
286
488
 
@@ -171,6 +171,86 @@ describe R10K::Action::Runner do
171
171
  end
172
172
  end
173
173
 
174
+ describe "configuring github app credentials" do
175
+ it 'errors if app id is passed without ssl key' do
176
+ runner = described_class.new(
177
+ { 'github-app-id': '/nonexistent', },
178
+ %w[args yes],
179
+ action_class
180
+ )
181
+ expect{ runner.call }.to raise_error(R10K::Error, /Must specify both id and SSL private key/)
182
+ end
183
+
184
+ it 'errors if ssl key is passed without app id' do
185
+ runner = described_class.new(
186
+ { 'github-app-key': '/nonexistent', },
187
+ %w[args yes],
188
+ action_class
189
+ )
190
+ expect{ runner.call }.to raise_error(R10K::Error, /Must specify both id and SSL private key/)
191
+ end
192
+
193
+ it 'errors if both app id and token paths are passed' do
194
+ runner = described_class.new(
195
+ { 'github-app-id': '/nonexistent', 'oauth-token': '/also/fake' },
196
+ %w[args yes],
197
+ action_class
198
+ )
199
+ expect{ runner.call }.to raise_error(R10K::Error, /Cannot specify both/)
200
+ end
201
+
202
+ it 'errors if both ssl key and token paths are passed' do
203
+ runner = described_class.new(
204
+ { 'github-app-key': '/nonexistent', 'oauth-token': '/also/fake' },
205
+ %w[args yes],
206
+ action_class
207
+ )
208
+ expect{ runner.call }.to raise_error(R10K::Error, /Cannot specify both/)
209
+ end
210
+
211
+ it 'errors if both ssl key and ssh key paths are passed' do
212
+ runner = described_class.new(
213
+ { 'github-app-key': '/nonexistent', 'private-key': '/also/fake' },
214
+ %w[args yes],
215
+ action_class
216
+ )
217
+ expect{ runner.call }.to raise_error(R10K::Error, /Cannot specify both/)
218
+ end
219
+
220
+ it 'errors if both app id and ssh key are passed' do
221
+ runner = described_class.new(
222
+ { 'github-app-id': '/nonexistent', 'private-key': '/also/fake' },
223
+ %w[args yes],
224
+ action_class
225
+ )
226
+ expect{ runner.call }.to raise_error(R10K::Error, /Cannot specify both/)
227
+ end
228
+
229
+ it 'saves the parameters in settings hash' do
230
+ runner = described_class.new(
231
+ { 'github-app-id': '123456', 'github-app-key': '/my/ssl/key', 'github-app-ttl': '600' },
232
+ %w[args yes],
233
+ action_class
234
+ )
235
+ runner.call
236
+ expect(runner.instance.settings[:git][:github_app_id]).to eq('123456')
237
+ expect(runner.instance.settings[:git][:github_app_key]).to eq('/my/ssl/key')
238
+ expect(runner.instance.settings[:git][:github_app_ttl]).to eq('600')
239
+ end
240
+
241
+ it 'saves the parameters in settings hash without ttl and uses its default value' do
242
+ runner = described_class.new(
243
+ { 'github-app-id': '123456', 'github-app-key': '/my/ssl/key', },
244
+ %w[args yes],
245
+ action_class
246
+ )
247
+ runner.call
248
+ expect(runner.instance.settings[:git][:github_app_id]).to eq('123456')
249
+ expect(runner.instance.settings[:git][:github_app_key]).to eq('/my/ssl/key')
250
+ expect(runner.instance.settings[:git][:github_app_ttl]).to eq('120')
251
+ end
252
+ end
253
+
174
254
  describe "configuring git credentials" do
175
255
  it 'errors if both token and key paths are passed' do
176
256
  runner = described_class.new({ 'oauth-token': '/nonexistent',
@@ -218,42 +298,66 @@ describe R10K::Action::Runner do
218
298
  end
219
299
 
220
300
  describe "configuration authorization" do
221
- context "when license is not present" do
222
- before(:each) do
223
- expect(R10K::Util::License).to receive(:load).and_return(nil)
301
+ context "settings auth" do
302
+ it "sets the configured token as the forge authorization header" do
303
+ options = { config: "spec/fixtures/unit/action/r10k_forge_auth.yaml" }
304
+ runner = described_class.new(options, %w[args yes], action_class)
305
+
306
+ expect(PuppetForge).to receive(:host=).with('http://private-forge.com')
307
+ expect(PuppetForge::Connection).to receive(:authorization=).with('faketoken')
308
+ expect(PuppetForge::Connection).to receive(:authorization).and_return('faketoken')
309
+ expect(R10K::Util::License).not_to receive(:load)
310
+ runner.setup_settings
311
+ runner.setup_authorization
224
312
  end
225
313
 
226
- it "does not set authorization header on connection class" do
227
- expect(PuppetForge::Connection).not_to receive(:authorization=)
228
- runner.setup_authorization
314
+ it 'errors if no custom forge URL is set' do
315
+ options = { config: "spec/fixtures/unit/action/r10k_forge_auth_no_url.yaml" }
316
+ runner = described_class.new(options, %w[args yes], action_class)
317
+ expect(PuppetForge::Connection).not_to receive(:authorization=).with('faketoken')
318
+
319
+ expect { runner.setup_settings }.to raise_error(R10K::Error, /Cannot specify a Forge auth/)
229
320
  end
230
321
  end
231
322
 
232
- context "when license is present but invalid" do
233
- before(:each) do
234
- expect(R10K::Util::License).to receive(:load).and_raise(R10K::Error.new('invalid license'))
235
- end
323
+ context "license auth" do
324
+ context "when license is not present" do
325
+ before(:each) do
326
+ expect(R10K::Util::License).to receive(:load).and_return(nil)
327
+ end
236
328
 
237
- it "issues warning to logger" do
238
- expect(runner.logger).to receive(:warn).with(/invalid license/)
239
- runner.setup_authorization
329
+ it "does not set authorization header on connection class" do
330
+ expect(PuppetForge::Connection).not_to receive(:authorization=)
331
+ runner.setup_authorization
332
+ end
240
333
  end
241
334
 
242
- it "does not set authorization header on connection class" do
243
- expect(PuppetForge::Connection).not_to receive(:authorization=)
244
- runner.setup_authorization
245
- end
246
- end
335
+ context "when license is present but invalid" do
336
+ before(:each) do
337
+ expect(R10K::Util::License).to receive(:load).and_raise(R10K::Error.new('invalid license'))
338
+ end
339
+
340
+ it "issues warning to logger" do
341
+ expect(runner.logger).to receive(:warn).with(/invalid license/)
342
+ runner.setup_authorization
343
+ end
247
344
 
248
- context "when license is present and valid" do
249
- before(:each) do
250
- mock_license = double('pe-license', :authorization_token => 'test token')
251
- expect(R10K::Util::License).to receive(:load).and_return(mock_license)
345
+ it "does not set authorization header on connection class" do
346
+ expect(PuppetForge::Connection).not_to receive(:authorization=)
347
+ runner.setup_authorization
348
+ end
252
349
  end
253
350
 
254
- it "sets authorization header on connection class" do
255
- expect(PuppetForge::Connection).to receive(:authorization=).with('test token')
256
- runner.setup_authorization
351
+ context "when license is present and valid" do
352
+ before(:each) do
353
+ mock_license = double('pe-license', :authorization_token => 'test token')
354
+ expect(R10K::Util::License).to receive(:load).and_return(mock_license)
355
+ end
356
+
357
+ it "sets authorization header on connection class" do
358
+ expect(PuppetForge::Connection).to receive(:authorization=).with('test token')
359
+ runner.setup_authorization
360
+ end
257
361
  end
258
362
  end
259
363
  end