chef 12.2.0.rc.1 → 12.2.0.rc.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,6 +21,7 @@ class Chef
21
21
  class MacportsPackage < Chef::Resource::Package
22
22
 
23
23
  provides :macports_package
24
+ provides :package, os: "darwin"
24
25
 
25
26
  def initialize(name, run_context=nil)
26
27
  super
@@ -17,7 +17,7 @@
17
17
 
18
18
  class Chef
19
19
  CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__)))
20
- VERSION = '12.2.0.rc.1'
20
+ VERSION = '12.2.0.rc.2'
21
21
  end
22
22
 
23
23
  #
@@ -201,41 +201,6 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
201
201
  end
202
202
  end
203
203
 
204
- describe "setting default parameters to nil" do
205
- before do
206
- FileUtils.mkdir_p(rel_path("releases"))
207
- FileUtils.mkdir_p(rel_path("shared"))
208
- end
209
-
210
- it "supports setting symlink_before_migrate to nil" do
211
- deploy_to_latest_rev.symlink_before_migrate(nil)
212
- expect(deploy_to_latest_rev.symlink_before_migrate).to eql(nil)
213
- deploy_to_latest_rev.run_action(:deploy)
214
- expect(deploy_to_latest_rev).to be_updated_by_last_action
215
- end
216
-
217
- it "supports setting symlinks to nil" do
218
- deploy_to_latest_rev.symlinks(nil)
219
- expect(deploy_to_latest_rev.symlinks).to eql(nil)
220
- deploy_to_latest_rev.run_action(:deploy)
221
- expect(deploy_to_latest_rev).to be_updated_by_last_action
222
- end
223
-
224
- it "supports setting purge_before_symlink to nil" do
225
- deploy_to_latest_rev.purge_before_symlink(nil)
226
- expect(deploy_to_latest_rev.purge_before_symlink).to eql(nil)
227
- deploy_to_latest_rev.run_action(:deploy)
228
- expect(deploy_to_latest_rev).to be_updated_by_last_action
229
- end
230
-
231
- it "supports setting create_dirs_before_symlink to nil" do
232
- deploy_to_latest_rev.create_dirs_before_symlink(nil)
233
- expect(deploy_to_latest_rev.create_dirs_before_symlink).to eql(nil)
234
- deploy_to_latest_rev.run_action(:deploy)
235
- expect(deploy_to_latest_rev).to be_updated_by_last_action
236
- end
237
- end
238
-
239
204
  describe "back to a previously deployed revision, with the directory structure precreated" do
240
205
  before do
241
206
  FileUtils.mkdir_p(rel_path("releases"))
@@ -21,9 +21,6 @@ describe Chef::Cookbook::FileVendor do
21
21
 
22
22
  let(:file_vendor_class) { Class.new(described_class) }
23
23
 
24
- # A manifest is a Hash of the format defined by Chef::CookbookVersion#manifest
25
- let(:manifest) { {:cookbook_name => "bob"} }
26
-
27
24
  context "when configured to fetch files over http" do
28
25
 
29
26
  let(:http) { double("Chef::REST") }
@@ -40,19 +37,42 @@ describe Chef::Cookbook::FileVendor do
40
37
  expect(file_vendor_class.initialization_options).to eq(http)
41
38
  end
42
39
 
43
- it "creates a RemoteFileVendor for a given manifest" do
44
- file_vendor = file_vendor_class.create_from_manifest(manifest)
45
- expect(file_vendor).to be_a_kind_of(Chef::Cookbook::RemoteFileVendor)
46
- expect(file_vendor.rest).to eq(http)
47
- expect(file_vendor.cookbook_name).to eq("bob")
40
+ context "with a manifest from a cookbook version" do
41
+
42
+ # A manifest is a Hash of the format defined by Chef::CookbookVersion#manifest
43
+ let(:manifest) { {:cookbook_name => "bob", :name => "bob-1.2.3"} }
44
+
45
+ it "creates a RemoteFileVendor for a given manifest" do
46
+ file_vendor = file_vendor_class.create_from_manifest(manifest)
47
+ expect(file_vendor).to be_a_kind_of(Chef::Cookbook::RemoteFileVendor)
48
+ expect(file_vendor.rest).to eq(http)
49
+ expect(file_vendor.cookbook_name).to eq("bob")
50
+ end
51
+
48
52
  end
49
53
 
54
+ context "with a manifest from a cookbook artifact" do
55
+
56
+ # A manifest is a Hash of the format defined by Chef::CookbookVersion#manifest
57
+ let(:manifest) { {:name => "bob"} }
58
+
59
+ it "creates a RemoteFileVendor for a given manifest" do
60
+ file_vendor = file_vendor_class.create_from_manifest(manifest)
61
+ expect(file_vendor).to be_a_kind_of(Chef::Cookbook::RemoteFileVendor)
62
+ expect(file_vendor.rest).to eq(http)
63
+ expect(file_vendor.cookbook_name).to eq("bob")
64
+ end
65
+
66
+ end
50
67
  end
51
68
 
52
69
  context "when configured to load files from disk" do
53
70
 
54
71
  let(:cookbook_path) { %w[/var/chef/cookbooks /var/chef/other_cookbooks] }
55
72
 
73
+ # A manifest is a Hash of the format defined by Chef::CookbookVersion#manifest
74
+ let(:manifest) { {:cookbook_name => "bob"} }
75
+
56
76
  before do
57
77
  file_vendor_class.fetch_from_disk(cookbook_path)
58
78
  end
@@ -24,6 +24,8 @@ describe Chef::CookbookManifest do
24
24
 
25
25
  let(:version) { "1.2.3" }
26
26
 
27
+ let(:identifier) { "9e10455ce2b4a4e29424b7064b1d67a1a25c9d3b" }
28
+
27
29
  let(:metadata) do
28
30
  Chef::Cookbook::Metadata.new.tap do |m|
29
31
  m.version(version)
@@ -35,6 +37,7 @@ describe Chef::CookbookManifest do
35
37
  let(:cookbook_version) do
36
38
  Chef::CookbookVersion.new("tatft", cookbook_root).tap do |c|
37
39
  c.metadata = metadata
40
+ c.identifier = identifier
38
41
  end
39
42
  end
40
43
 
@@ -212,12 +215,26 @@ describe Chef::CookbookManifest do
212
215
 
213
216
  let(:policy_mode) { true }
214
217
 
218
+ let(:cookbook_manifest_hash) { cookbook_manifest.to_hash }
219
+
220
+ it "sets the identifier in the manifest data" do
221
+ expect(cookbook_manifest_hash["identifier"]).to eq("9e10455ce2b4a4e29424b7064b1d67a1a25c9d3b")
222
+ end
223
+
224
+ it "sets the name to just the name" do
225
+ expect(cookbook_manifest_hash["name"]).to eq("tatft")
226
+ end
227
+
228
+ it "does not set a 'cookbook_name' field" do
229
+ expect(cookbook_manifest_hash).to_not have_key("cookbook_name")
230
+ end
231
+
215
232
  it "gives the save URL" do
216
- expect(cookbook_manifest.save_url).to eq("cookbook_artifacts/tatft/1.2.3")
233
+ expect(cookbook_manifest.save_url).to eq("cookbook_artifacts/tatft/9e10455ce2b4a4e29424b7064b1d67a1a25c9d3b")
217
234
  end
218
235
 
219
236
  it "gives the force save URL" do
220
- expect(cookbook_manifest.force_save_url).to eq("cookbook_artifacts/tatft/1.2.3?force=true")
237
+ expect(cookbook_manifest.force_save_url).to eq("cookbook_artifacts/tatft/9e10455ce2b4a4e29424b7064b1d67a1a25c9d3b?force=true")
221
238
  end
222
239
 
223
240
  end
@@ -25,11 +25,17 @@ describe Chef::CookbookUploader do
25
25
  let(:cookbook_loader) do
26
26
  loader = Chef::CookbookLoader.new(File.join(CHEF_SPEC_DATA, "cookbooks"))
27
27
  loader.load_cookbooks
28
+ loader.cookbooks_by_name["apache2"].identifier = apache2_identifier
29
+ loader.cookbooks_by_name["java"].identifier = java_identifier
28
30
  loader
29
31
  end
30
32
 
33
+ let(:apache2_identifier) { "6644e6cb2ade90b8aff2ebb44728958fbc939ebf" }
34
+
31
35
  let(:apache2_cookbook) { cookbook_loader.cookbooks_by_name["apache2"] }
32
36
 
37
+ let(:java_identifier) { "edd40c30c4e0ebb3658abde4620597597d2e9c17" }
38
+
33
39
  let(:java_cookbook) { cookbook_loader.cookbooks_by_name["java"] }
34
40
 
35
41
  let(:cookbooks_to_upload) { [apache2_cookbook, java_cookbook] }
@@ -175,7 +181,7 @@ describe Chef::CookbookUploader do
175
181
  let(:policy_mode) { true }
176
182
 
177
183
  def expected_save_url(cookbook)
178
- "cookbook_artifacts/#{cookbook.name}/#{cookbook.version}"
184
+ "cookbook_artifacts/#{cookbook.name}/#{cookbook.identifier}"
179
185
  end
180
186
 
181
187
  it "uploads all files in a sandbox transaction, then creates cookbooks on the server using cookbook_artifacts API" do
@@ -339,83 +339,69 @@ describe Chef::Mixin::ParamsValidate do
339
339
  end.to raise_error(Chef::Exceptions::ValidationFailed)
340
340
  end
341
341
 
342
- def self.test_set_or_return_method(method)
343
- # caller is responsible for passing in the right arg to get 'return' behavior
344
- return_arg = method == :nillable_set_or_return ? TinyClass::NULL_ARG : nil
345
-
346
- it "#{method} should set and return a value, then return the same value" do
347
- value = "meow"
348
- expect(@vo.send(method,:test, value, {}).object_id).to eq(value.object_id)
349
- expect(@vo.send(method,:test, return_arg, {}).object_id).to eq(value.object_id)
350
- end
351
-
352
- it "#{method} should set and return a default value when the argument is nil, then return the same value" do
353
- value = "meow"
354
- expect(@vo.send(method,:test, return_arg, { :default => value }).object_id).to eq(value.object_id)
355
- expect(@vo.send(method,:test, return_arg, {}).object_id).to eq(value.object_id)
356
- end
357
-
358
- it "#{method} should raise an ArgumentError when argument is nil and required is true" do
359
- expect {
360
- @vo.send(method,:test, return_arg, { :required => true })
361
- }.to raise_error(ArgumentError)
362
- end
363
-
364
- it "#{method} should not raise an error when argument is nil and required is false" do
365
- expect {
366
- @vo.send(method,:test, return_arg, { :required => false })
367
- }.not_to raise_error
368
- end
369
-
370
- it "#{method} should set and return @name, then return @name for foo when argument is nil" do
371
- value = "meow"
372
- expect(@vo.send(method,:name, value, { }).object_id).to eq(value.object_id)
373
- expect(@vo.send(method,:foo, return_arg, { :name_attribute => true }).object_id).to eq(value.object_id)
374
- end
375
-
376
- it "#{method} should allow DelayedEvaluator instance to be set for value regardless of restriction" do
377
- value = Chef::DelayedEvaluator.new{ 'test' }
378
- @vo.send(method,:test, value, {:kind_of => Numeric})
379
- end
380
-
381
- it "#{method} should raise an error when delayed evaluated attribute is not valid" do
382
- value = Chef::DelayedEvaluator.new{ 'test' }
383
- @vo.send(method,:test, value, {:kind_of => Numeric})
384
- expect do
385
- @vo.send(method,:test, return_arg, {:kind_of => Numeric})
386
- end.to raise_error(Chef::Exceptions::ValidationFailed)
387
- end
388
-
389
- it "#{method} should create DelayedEvaluator instance when #lazy is used" do
390
- @vo.send(method,:delayed, @vo.lazy{ 'test' }, {})
391
- expect(@vo.instance_variable_get(:@delayed)).to be_a(Chef::DelayedEvaluator)
392
- end
393
-
394
- it "#{method} should execute block on each call when DelayedEvaluator" do
395
- value = 'fubar'
396
- @vo.send(method,:test, @vo.lazy{ value }, {})
397
- expect(@vo.send(method,:test, return_arg, {})).to eq('fubar')
398
- value = 'foobar'
399
- expect(@vo.send(method,:test, return_arg, {})).to eq('foobar')
400
- value = 'fauxbar'
401
- expect(@vo.send(method,:test, return_arg, {})).to eq('fauxbar')
402
- end
403
-
404
- it "#{method} should not evaluate non DelayedEvaluator instances" do
405
- value = lambda{ 'test' }
406
- @vo.send(method,:test, value, {})
407
- expect(@vo.send(method,:test, return_arg, {}).object_id).to eq(value.object_id)
408
- expect(@vo.send(method,:test, return_arg, {})).to be_a(Proc)
409
- end
342
+ it "should set and return a value, then return the same value" do
343
+ value = "meow"
344
+ expect(@vo.set_or_return(:test, value, {}).object_id).to eq(value.object_id)
345
+ expect(@vo.set_or_return(:test, nil, {}).object_id).to eq(value.object_id)
410
346
  end
411
347
 
412
- test_set_or_return_method(:set_or_return)
413
- test_set_or_return_method(:nillable_set_or_return)
348
+ it "should set and return a default value when the argument is nil, then return the same value" do
349
+ value = "meow"
350
+ expect(@vo.set_or_return(:test, nil, { :default => value }).object_id).to eq(value.object_id)
351
+ expect(@vo.set_or_return(:test, nil, {}).object_id).to eq(value.object_id)
352
+ end
353
+
354
+ it "should raise an ArgumentError when argument is nil and required is true" do
355
+ expect {
356
+ @vo.set_or_return(:test, nil, { :required => true })
357
+ }.to raise_error(ArgumentError)
358
+ end
359
+
360
+ it "should not raise an error when argument is nil and required is false" do
361
+ expect {
362
+ @vo.set_or_return(:test, nil, { :required => false })
363
+ }.not_to raise_error
364
+ end
365
+
366
+ it "should set and return @name, then return @name for foo when argument is nil" do
367
+ value = "meow"
368
+ expect(@vo.set_or_return(:name, value, { }).object_id).to eq(value.object_id)
369
+ expect(@vo.set_or_return(:foo, nil, { :name_attribute => true }).object_id).to eq(value.object_id)
370
+ end
414
371
 
415
- it "nillable_set_or_return supports nilling values" do
416
- expect(@vo.nillable_set_or_return(:test, "meow", {})).to eq("meow")
417
- expect(@vo.nillable_set_or_return(:test, TinyClass::NULL_ARG, {})).to eq("meow")
418
- expect(@vo.nillable_set_or_return(:test, nil, {})).to be_nil
419
- expect(@vo.nillable_set_or_return(:test, TinyClass::NULL_ARG, {})).to be_nil
372
+ it "should allow DelayedEvaluator instance to be set for value regardless of restriction" do
373
+ value = Chef::DelayedEvaluator.new{ 'test' }
374
+ @vo.set_or_return(:test, value, {:kind_of => Numeric})
420
375
  end
376
+
377
+ it "should raise an error when delayed evaluated attribute is not valid" do
378
+ value = Chef::DelayedEvaluator.new{ 'test' }
379
+ @vo.set_or_return(:test, value, {:kind_of => Numeric})
380
+ expect do
381
+ @vo.set_or_return(:test, nil, {:kind_of => Numeric})
382
+ end.to raise_error(Chef::Exceptions::ValidationFailed)
383
+ end
384
+
385
+ it "should create DelayedEvaluator instance when #lazy is used" do
386
+ @vo.set_or_return(:delayed, @vo.lazy{ 'test' }, {})
387
+ expect(@vo.instance_variable_get(:@delayed)).to be_a(Chef::DelayedEvaluator)
388
+ end
389
+
390
+ it "should execute block on each call when DelayedEvaluator" do
391
+ value = 'fubar'
392
+ @vo.set_or_return(:test, @vo.lazy{ value }, {})
393
+ expect(@vo.set_or_return(:test, nil, {})).to eq('fubar')
394
+ value = 'foobar'
395
+ expect(@vo.set_or_return(:test, nil, {})).to eq('foobar')
396
+ value = 'fauxbar'
397
+ expect(@vo.set_or_return(:test, nil, {})).to eq('fauxbar')
398
+ end
399
+
400
+ it "should not evaluate non DelayedEvaluator instances" do
401
+ value = lambda{ 'test' }
402
+ @vo.set_or_return(:test, value, {})
403
+ expect(@vo.set_or_return(:test, nil, {}).object_id).to eq(value.object_id)
404
+ expect(@vo.set_or_return(:test, nil, {})).to be_a(Proc)
405
+ end
406
+
421
407
  end
@@ -256,7 +256,7 @@ describe Chef::PolicyBuilder::Policyfile do
256
256
 
257
257
  context "and policy_name and policy_group are configured" do
258
258
 
259
- let(:policy_relative_url) { "policies/policy-stage/example" }
259
+ let(:policy_relative_url) { "policy_groups/policy-stage/policies/example" }
260
260
 
261
261
  before do
262
262
  expect(http_api).to receive(:get).with(policy_relative_url).and_return(parsed_policyfile_json)
@@ -386,6 +386,9 @@ describe Chef::PolicyBuilder::Policyfile do
386
386
 
387
387
  describe "fetching the desired cookbook set" do
388
388
 
389
+ let(:example1_cookbook_data) { double("CookbookVersion Hash for example1 cookbook") }
390
+ let(:example2_cookbook_data) { double("CookbookVersion Hash for example2 cookbook") }
391
+
389
392
  let(:example1_cookbook_object) { double("Chef::CookbookVersion for example1 cookbook") }
390
393
  let(:example2_cookbook_object) { double("Chef::CookbookVersion for example2 cookbook") }
391
394
 
@@ -396,9 +399,12 @@ describe Chef::PolicyBuilder::Policyfile do
396
399
  let(:example1_xyz_version) { example1_lock_data["dotted_decimal_identifier"] }
397
400
  let(:example2_xyz_version) { example2_lock_data["dotted_decimal_identifier"] }
398
401
 
402
+ let(:example1_identifier) { example1_lock_data["identifier"] }
403
+ let(:example2_identifier) { example2_lock_data["identifier"] }
404
+
399
405
  let(:cookbook_synchronizer) { double("Chef::CookbookSynchronizer") }
400
406
 
401
- shared_examples_for "fetching cookbooks" do
407
+ shared_examples "fetching cookbooks when they don't exist" do
402
408
  context "and a cookbook is missing" do
403
409
 
404
410
  let(:error404) { Net::HTTPServerException.new("404 message", :body) }
@@ -418,7 +424,9 @@ describe Chef::PolicyBuilder::Policyfile do
418
424
  end
419
425
 
420
426
  end
427
+ end
421
428
 
429
+ shared_examples_for "fetching cookbooks when they exist" do
422
430
  context "and the cookbooks can be fetched" do
423
431
  before do
424
432
  expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
@@ -426,11 +434,6 @@ describe Chef::PolicyBuilder::Policyfile do
426
434
  policy_builder.load_node
427
435
  policy_builder.build_node
428
436
 
429
- expect(http_api).to receive(:get).with(cookbook1_url).
430
- and_return(example1_cookbook_object)
431
- expect(http_api).to receive(:get).with(cookbook2_url).
432
- and_return(example2_cookbook_object)
433
-
434
437
  allow(Chef::CookbookSynchronizer).to receive(:new).
435
438
  with(expected_cookbook_hash, events).
436
439
  and_return(cookbook_synchronizer)
@@ -457,11 +460,23 @@ describe Chef::PolicyBuilder::Policyfile do
457
460
  end # shared_examples_for "fetching cookbooks"
458
461
 
459
462
  context "when using compatibility mode (policy_document_native_api == false)" do
460
- include_examples "fetching cookbooks" do
463
+ let(:cookbook1_url) { "cookbooks/example1/#{example1_xyz_version}" }
464
+ let(:cookbook2_url) { "cookbooks/example2/#{example2_xyz_version}" }
461
465
 
462
- let(:cookbook1_url) { "cookbooks/example1/#{example1_xyz_version}" }
463
- let(:cookbook2_url) { "cookbooks/example2/#{example2_xyz_version}" }
466
+ context "when the cookbooks don't exist on the server" do
467
+ include_examples "fetching cookbooks when they don't exist"
468
+ end
469
+
470
+ context "when the cookbooks exist on the server" do
471
+
472
+ before do
473
+ expect(http_api).to receive(:get).with(cookbook1_url).
474
+ and_return(example1_cookbook_object)
475
+ expect(http_api).to receive(:get).with(cookbook2_url).
476
+ and_return(example2_cookbook_object)
477
+ end
464
478
 
479
+ include_examples "fetching cookbooks when they exist"
465
480
  end
466
481
 
467
482
  end
@@ -474,13 +489,33 @@ describe Chef::PolicyBuilder::Policyfile do
474
489
  Chef::Config[:policy_name] = "example"
475
490
  end
476
491
 
477
- include_examples "fetching cookbooks" do
492
+ let(:cookbook1_url) { "cookbook_artifacts/example1/#{example1_identifier}" }
493
+ let(:cookbook2_url) { "cookbook_artifacts/example2/#{example2_identifier}" }
494
+
495
+ context "when the cookbooks don't exist on the server" do
496
+ include_examples "fetching cookbooks when they don't exist"
497
+ end
498
+
478
499
 
479
- let(:cookbook1_url) { "cookbook_artifacts/example1/#{example1_xyz_version}" }
480
- let(:cookbook2_url) { "cookbook_artifacts/example2/#{example2_xyz_version}" }
500
+ context "when the cookbooks exist on the server" do
501
+
502
+ before do
503
+ expect(http_api).to receive(:get).with(cookbook1_url).
504
+ and_return(example1_cookbook_data)
505
+ expect(http_api).to receive(:get).with(cookbook2_url).
506
+ and_return(example2_cookbook_data)
507
+
508
+ expect(Chef::CookbookVersion).to receive(:from_cb_artifact_data).with(example1_cookbook_data).
509
+ and_return(example1_cookbook_object)
510
+ expect(Chef::CookbookVersion).to receive(:from_cb_artifact_data).with(example2_cookbook_data).
511
+ and_return(example2_cookbook_object)
512
+ end
513
+
514
+ include_examples "fetching cookbooks when they exist"
481
515
 
482
516
  end
483
517
 
518
+
484
519
  end
485
520
 
486
521
  end