chef 12.11.18 → 12.12.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -4
  3. data/Rakefile +3 -2
  4. data/VERSION +1 -1
  5. data/acceptance/Gemfile.lock +22 -23
  6. data/acceptance/data-collector/test/integration/default/serverspec/default_spec.rb +2 -41
  7. data/lib/chef/application/solo.rb +7 -0
  8. data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +1 -1
  9. data/lib/chef/data_collector.rb +79 -43
  10. data/lib/chef/data_collector/messages.rb +4 -33
  11. data/lib/chef/data_collector/messages/helpers.rb +2 -2
  12. data/lib/chef/data_collector/resource_report.rb +21 -11
  13. data/lib/chef/decorator/unchain.rb +43 -0
  14. data/lib/chef/exceptions.rb +5 -0
  15. data/lib/chef/http.rb +5 -5
  16. data/lib/chef/knife/cookbook_create.rb +4 -0
  17. data/lib/chef/knife/cookbook_site_download.rb +8 -1
  18. data/lib/chef/knife/cookbook_site_install.rb +8 -0
  19. data/lib/chef/knife/cookbook_site_list.rb +8 -1
  20. data/lib/chef/knife/cookbook_site_search.rb +8 -1
  21. data/lib/chef/knife/cookbook_site_share.rb +8 -1
  22. data/lib/chef/knife/cookbook_site_show.rb +14 -3
  23. data/lib/chef/knife/cookbook_site_unshare.rb +8 -1
  24. data/lib/chef/knife/core/bootstrap_context.rb +1 -1
  25. data/lib/chef/knife/supermarket_download.rb +33 -0
  26. data/lib/chef/knife/supermarket_install.rb +33 -0
  27. data/lib/chef/knife/supermarket_list.rb +33 -0
  28. data/lib/chef/knife/supermarket_search.rb +33 -0
  29. data/lib/chef/knife/supermarket_share.rb +33 -0
  30. data/lib/chef/knife/supermarket_show.rb +33 -0
  31. data/lib/chef/knife/supermarket_unshare.rb +33 -0
  32. data/lib/chef/node.rb +13 -32
  33. data/lib/chef/node/attribute.rb +123 -70
  34. data/lib/chef/node/attribute_collections.rb +9 -130
  35. data/lib/chef/node/common_api.rb +124 -0
  36. data/lib/chef/node/immutable_collections.rb +27 -2
  37. data/lib/chef/property.rb +6 -2
  38. data/lib/chef/provider.rb +4 -5
  39. data/lib/chef/provider/batch.rb +1 -1
  40. data/lib/chef/provider/directory.rb +3 -1
  41. data/lib/chef/provider/package/openbsd.rb +1 -1
  42. data/lib/chef/provider/package/rubygems.rb +9 -3
  43. data/lib/chef/provider/package/windows/exe.rb +2 -5
  44. data/lib/chef/provider/powershell_script.rb +1 -1
  45. data/lib/chef/provider/remote_directory.rb +2 -0
  46. data/lib/chef/resource.rb +22 -17
  47. data/lib/chef/resource_builder.rb +9 -4
  48. data/lib/chef/shell.rb +1 -1
  49. data/lib/chef/version.rb +1 -1
  50. data/spec/data/run_context/cookbooks/circular-dep1/attributes/default.rb +2 -4
  51. data/spec/data/run_context/cookbooks/circular-dep2/attributes/default.rb +2 -3
  52. data/spec/data/run_context/cookbooks/dependency1/attributes/aa_first.rb +2 -2
  53. data/spec/data/run_context/cookbooks/dependency1/attributes/default.rb +2 -2
  54. data/spec/data/run_context/cookbooks/dependency1/attributes/zz_last.rb +2 -3
  55. data/spec/data/run_context/cookbooks/dependency2/attributes/default.rb +2 -3
  56. data/spec/data/run_context/cookbooks/no-default-attr/attributes/server.rb +2 -3
  57. data/spec/data/run_context/cookbooks/test-with-circular-deps/attributes/default.rb +2 -3
  58. data/spec/data/run_context/cookbooks/test-with-deps/attributes/default.rb +2 -3
  59. data/spec/functional/assets/chocolatey_feed/test-A.1.0.nupkg +0 -0
  60. data/spec/functional/assets/chocolatey_feed/test-A.1.5.nupkg +0 -0
  61. data/spec/functional/assets/chocolatey_feed/test-A.2.0.nupkg +0 -0
  62. data/spec/functional/assets/chocolatey_feed/test-B.1.0.nupkg +0 -0
  63. data/spec/functional/resource/dsc_script_spec.rb +1 -0
  64. data/spec/functional/resource/package_spec.rb +1 -1
  65. data/spec/functional/resource/template_spec.rb +3 -3
  66. data/spec/functional/shell_spec.rb +1 -1
  67. data/spec/integration/knife/client_bulk_delete_spec.rb +130 -0
  68. data/spec/integration/knife/client_create_spec.rb +69 -0
  69. data/spec/integration/knife/client_delete_spec.rb +63 -0
  70. data/spec/integration/knife/client_key_create_spec.rb +65 -0
  71. data/spec/integration/knife/client_key_delete_spec.rb +42 -0
  72. data/spec/integration/knife/client_key_list_spec.rb +60 -0
  73. data/spec/integration/knife/client_key_show_spec.rb +44 -0
  74. data/spec/integration/knife/client_list_spec.rb +48 -0
  75. data/spec/integration/knife/client_show_spec.rb +36 -0
  76. data/spec/integration/knife/cookbook_bulk_delete_spec.rb +64 -0
  77. data/spec/integration/knife/cookbook_download_spec.rb +95 -0
  78. data/spec/integration/knife/cookbook_list_spec.rb +54 -0
  79. data/spec/integration/knife/cookbook_show_spec.rb +159 -0
  80. data/spec/integration/knife/cookbook_upload_spec.rb +90 -0
  81. data/spec/integration/knife/data_bag_create_spec.rb +58 -0
  82. data/spec/integration/knife/data_bag_delete_spec.rb +58 -0
  83. data/spec/integration/knife/data_bag_from_file_spec.rb +115 -0
  84. data/spec/integration/knife/data_bag_list_spec.rb +43 -0
  85. data/spec/integration/knife/data_bag_show_spec.rb +53 -0
  86. data/spec/integration/knife/environment_compare_spec.rb +74 -0
  87. data/spec/integration/knife/environment_create_spec.rb +40 -0
  88. data/spec/integration/knife/environment_delete_spec.rb +36 -0
  89. data/spec/integration/knife/environment_from_file_spec.rb +115 -0
  90. data/spec/integration/knife/environment_list_spec.rb +41 -0
  91. data/spec/integration/knife/environment_show_spec.rb +56 -0
  92. data/spec/integration/knife/node_bulk_delete_spec.rb +51 -0
  93. data/spec/integration/knife/node_create_spec.rb +46 -0
  94. data/spec/integration/knife/node_delete_spec.rb +47 -0
  95. data/spec/integration/knife/node_environment_set_spec.rb +42 -0
  96. data/spec/integration/knife/node_from_file_spec.rb +58 -0
  97. data/spec/integration/knife/node_list_spec.rb +44 -0
  98. data/spec/integration/knife/node_run_list_add_spec.rb +53 -0
  99. data/spec/integration/knife/node_run_list_remove_spec.rb +35 -0
  100. data/spec/integration/knife/node_run_list_set_spec.rb +40 -0
  101. data/spec/integration/knife/node_show_spec.rb +35 -0
  102. data/spec/integration/knife/role_bulk_delete_spec.rb +51 -0
  103. data/spec/integration/knife/role_create_spec.rb +40 -0
  104. data/spec/integration/knife/role_delete_spec.rb +47 -0
  105. data/spec/integration/knife/role_from_file_spec.rb +95 -0
  106. data/spec/integration/knife/role_list_spec.rb +44 -0
  107. data/spec/integration/knife/role_show_spec.rb +50 -0
  108. data/spec/support/shared/integration/knife_support.rb +10 -3
  109. data/spec/unit/application/solo_spec.rb +7 -0
  110. data/spec/unit/cookbook_version_spec.rb +4 -4
  111. data/spec/unit/data_collector/messages/helpers_spec.rb +3 -7
  112. data/spec/unit/data_collector/messages_spec.rb +28 -45
  113. data/spec/unit/data_collector_spec.rb +40 -47
  114. data/spec/unit/knife/cookbook_create_spec.rb +1 -0
  115. data/spec/unit/knife/cookbook_site_download_spec.rb +1 -0
  116. data/spec/unit/knife/node_environment_set_spec.rb +0 -24
  117. data/spec/unit/knife/node_run_list_set_spec.rb +0 -25
  118. data/spec/unit/node/attribute_spec.rb +7 -9
  119. data/spec/unit/node/immutable_collections_spec.rb +4 -0
  120. data/spec/unit/node/vivid_mash_spec.rb +344 -0
  121. data/spec/unit/node_spec.rb +115 -26
  122. data/spec/unit/provider/directory_spec.rb +11 -1
  123. data/spec/unit/provider/package/windows/exe_spec.rb +14 -9
  124. data/spec/unit/provider/powershell_script_spec.rb +4 -4
  125. data/spec/unit/provider/remote_directory_spec.rb +15 -0
  126. data/spec/unit/recipe_spec.rb +31 -6
  127. data/spec/unit/run_context_spec.rb +2 -2
  128. data/spec/unit/shell/shell_session_spec.rb +1 -1
  129. data/tasks/dependencies.rb +0 -2
  130. metadata +55 -786
  131. data/acceptance/.bundle/config +0 -2
  132. data/acceptance/basics/.kitchen/logs/chef-current-install-ubuntu-1404.log +0 -2
  133. data/acceptance/basics/.kitchen/logs/kitchen.log +0 -3
  134. data/acceptance/fips/.kitchen/logs/fips-integration-centos-6.log +0 -3
  135. data/acceptance/fips/.kitchen/logs/fips-integration-windows-2012r2.log +0 -3
  136. data/acceptance/fips/.kitchen/logs/fips-unit-functional-centos-6.log +0 -3
  137. data/acceptance/fips/.kitchen/logs/fips-unit-functional-windows-2012r2.log +0 -3
  138. data/acceptance/fips/.kitchen/logs/kitchen.log +0 -6
  139. data/acceptance/trivial/.kitchen/logs/chef-current-install-windows-2012r2.log +0 -2
  140. data/acceptance/trivial/.kitchen/logs/kitchen.log +0 -3
  141. data/acceptance/windows-service/.kitchen/logs/chef-windows-service-windows-2012r2.log +0 -2
  142. data/acceptance/windows-service/.kitchen/logs/kitchen.log +0 -3
@@ -233,60 +233,63 @@ describe Chef::Node do
233
233
  end
234
234
 
235
235
  it "should let you go deep with attribute?" do
236
- node.set["battles"]["people"]["wonkey"] = true
236
+ node.normal["battles"]["people"]["wonkey"] = true
237
237
  expect(node["battles"]["people"].attribute?("wonkey")).to eq(true)
238
238
  expect(node["battles"]["people"].attribute?("snozzberry")).to eq(false)
239
239
  end
240
240
 
241
241
  it "does not allow you to set an attribute via method_missing" do
242
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
242
243
  expect { node.sunshine = "is bright" }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
243
244
  end
244
245
 
245
246
  it "should allow you get get an attribute via method_missing" do
247
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
246
248
  node.default.sunshine = "is bright"
247
249
  expect(node.sunshine).to eql("is bright")
248
250
  end
249
251
 
250
252
  describe "normal attributes" do
251
253
  it "should allow you to set an attribute with set, without pre-declaring a hash" do
252
- node.set[:snoopy][:is_a_puppy] = true
254
+ node.normal[:snoopy][:is_a_puppy] = true
253
255
  expect(node[:snoopy][:is_a_puppy]).to eq(true)
254
256
  end
255
257
 
256
258
  it "should allow you to set an attribute with set_unless" do
257
- node.set_unless[:snoopy][:is_a_puppy] = false
259
+ node.normal_unless[:snoopy][:is_a_puppy] = false
258
260
  expect(node[:snoopy][:is_a_puppy]).to eq(false)
259
261
  end
260
262
 
261
263
  it "should not allow you to set an attribute with set_unless if it already exists" do
262
- node.set[:snoopy][:is_a_puppy] = true
263
- node.set_unless[:snoopy][:is_a_puppy] = false
264
+ node.normal[:snoopy][:is_a_puppy] = true
265
+ node.normal_unless[:snoopy][:is_a_puppy] = false
264
266
  expect(node[:snoopy][:is_a_puppy]).to eq(true)
265
267
  end
266
268
 
267
269
  it "should allow you to set an attribute with set_unless if is a nil value" do
268
270
  node.attributes.normal = { snoopy: { is_a_puppy: nil } }
269
- node.set_unless[:snoopy][:is_a_puppy] = false
271
+ node.normal_unless[:snoopy][:is_a_puppy] = false
270
272
  expect(node[:snoopy][:is_a_puppy]).to eq(false)
271
273
  end
272
274
 
273
275
  it "should allow you to set a value after a set_unless" do
274
276
  # this tests for set_unless_present state bleeding between statements CHEF-3806
275
- node.set_unless[:snoopy][:is_a_puppy] = false
276
- node.set[:snoopy][:is_a_puppy] = true
277
+ node.normal_unless[:snoopy][:is_a_puppy] = false
278
+ node.normal[:snoopy][:is_a_puppy] = true
277
279
  expect(node[:snoopy][:is_a_puppy]).to eq(true)
278
280
  end
279
281
 
280
282
  it "should let you set a value after a 'dangling' set_unless" do
281
283
  # this tests for set_unless_present state bleeding between statements CHEF-3806
282
- node.set[:snoopy][:is_a_puppy] = "what"
283
- node.set_unless[:snoopy][:is_a_puppy]
284
- node.set[:snoopy][:is_a_puppy] = true
284
+ node.normal[:snoopy][:is_a_puppy] = "what"
285
+ node.normal_unless[:snoopy][:is_a_puppy]
286
+ node.normal[:snoopy][:is_a_puppy] = true
285
287
  expect(node[:snoopy][:is_a_puppy]).to eq(true)
286
288
  end
287
289
 
288
290
  it "auto-vivifies attributes created via method syntax" do
289
- node.set.fuu.bahrr.baz = "qux"
291
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
292
+ node.normal.fuu.bahrr.baz = "qux"
290
293
  expect(node.fuu.bahrr.baz).to eq("qux")
291
294
  end
292
295
 
@@ -295,6 +298,20 @@ describe Chef::Node do
295
298
  node.tag("three", "four")
296
299
  expect(node["tags"]).to eq(%w{one two three four})
297
300
  end
301
+
302
+ it "set is a deprecated alias for normal" do
303
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
304
+ expect(Chef).to receive(:log_deprecation).with(/set is deprecated/)
305
+ node.set[:snoopy][:is_a_puppy] = true
306
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
307
+ end
308
+
309
+ it "set_unless is a deprecated alias for normal_unless" do
310
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
311
+ expect(Chef).to receive(:log_deprecation).with(/set_unless is deprecated/)
312
+ node.set_unless[:snoopy][:is_a_puppy] = false
313
+ expect(node[:snoopy][:is_a_puppy]).to eq(false)
314
+ end
298
315
  end
299
316
 
300
317
  describe "default attributes" do
@@ -329,7 +346,14 @@ describe Chef::Node do
329
346
  expect(node[:snoopy][:is_a_puppy]).to eq(true)
330
347
  end
331
348
 
349
+ it "does not exhibit chef/chef/issues/5005 bug" do
350
+ node.env_default["a"]["r1"]["g"]["u"] = "u1"
351
+ node.default_unless["a"]["r1"]["g"]["r"] = "r"
352
+ expect(node["a"]["r1"]["g"]["u"]).to eql("u1")
353
+ end
354
+
332
355
  it "auto-vivifies attributes created via method syntax" do
356
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
333
357
  node.default.fuu.bahrr.baz = "qux"
334
358
  expect(node.fuu.bahrr.baz).to eq("qux")
335
359
  end
@@ -368,6 +392,7 @@ describe Chef::Node do
368
392
  end
369
393
 
370
394
  it "auto-vivifies attributes created via method syntax" do
395
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
371
396
  node.override.fuu.bahrr.baz = "qux"
372
397
  expect(node.fuu.bahrr.baz).to eq("qux")
373
398
  end
@@ -453,8 +478,9 @@ describe Chef::Node do
453
478
  expect( node["mysql"]["server"][0]["port"] ).to be_nil
454
479
  end
455
480
 
456
- it "does not have a horrible error message when mistaking arrays for hashes" do
457
- expect { node.rm("mysql", "server", "port") }.to raise_error(TypeError, "Wrong type in index of attribute (did you use a Hash index on an Array?)")
481
+ it "when mistaking arrays for hashes, it considers the value removed and does nothing" do
482
+ node.rm("mysql", "server", "port")
483
+ expect(node["mysql"]["server"][0]["port"]).to eql(3456)
458
484
  end
459
485
  end
460
486
  end
@@ -706,6 +732,7 @@ describe Chef::Node do
706
732
  #
707
733
  describe "deep merge attribute cache edge conditions" do
708
734
  it "does not error with complicated attribute substitution" do
735
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
709
736
  node.default["chef_attribute_hell"]["attr1"] = "attribute1"
710
737
  node.default["chef_attribute_hell"]["attr2"] = "#{node.chef_attribute_hell.attr1}/attr2"
711
738
  expect { node.default["chef_attribute_hell"]["attr3"] = "#{node.chef_attribute_hell.attr2}/attr3" }.not_to raise_error
@@ -720,6 +747,7 @@ describe Chef::Node do
720
747
  end
721
748
 
722
749
  it "method interpolation syntax also works" do
750
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
723
751
  node.default["passenger"]["version"] = "4.0.57"
724
752
  node.default["passenger"]["root_path"] = "passenger-#{node['passenger']['version']}"
725
753
  node.default["passenger"]["root_path_2"] = "passenger-#{node.passenger['version']}"
@@ -729,6 +757,7 @@ describe Chef::Node do
729
757
  end
730
758
 
731
759
  it "should raise an ArgumentError if you ask for an attribute that doesn't exist via method_missing" do
760
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
732
761
  expect { node.sunshine }.to raise_error(NoMethodError)
733
762
  end
734
763
 
@@ -744,6 +773,51 @@ describe Chef::Node do
744
773
  expect(seen_attributes["sunshine"]).to eq("is bright")
745
774
  expect(seen_attributes["canada"]).to eq("is a nice place")
746
775
  end
776
+
777
+ describe "functional attribute API" do
778
+ # deeper functional testing of this API is in the VividMash spec tests
779
+ it "should have an exist? function" do
780
+ node.default["foo"]["bar"] = "baz"
781
+ expect(node.exist?("foo", "bar")).to be true
782
+ expect(node.exist?("bar", "foo")).to be false
783
+ end
784
+
785
+ it "should have a read function" do
786
+ node.override["foo"]["bar"] = "baz"
787
+ expect(node.read("foo", "bar")).to eql("baz")
788
+ expect(node.read("bar", "foo")).to eql(nil)
789
+ end
790
+
791
+ it "should have a read! function" do
792
+ node.override["foo"]["bar"] = "baz"
793
+ expect(node.read!("foo", "bar")).to eql("baz")
794
+ expect { node.read!("bar", "foo") }.to raise_error(Chef::Exceptions::NoSuchAttribute)
795
+ end
796
+
797
+ it "delegates write(:level) to node.level.write()" do
798
+ node.write(:default, "foo", "bar", "baz")
799
+ expect(node.default["foo"]["bar"]).to eql("baz")
800
+ end
801
+
802
+ it "delegates write!(:level) to node.level.write!()" do
803
+ node.write!(:default, "foo", "bar", "baz")
804
+ expect(node.default["foo"]["bar"]).to eql("baz")
805
+ node.default["bar"] = true
806
+ expect { node.write!(:default, "bar", "foo", "baz") }.to raise_error(Chef::Exceptions::AttributeTypeMismatch)
807
+ end
808
+
809
+ it "delegates unlink(:level) to node.level.unlink()" do
810
+ node.default["foo"]["bar"] = "baz"
811
+ expect(node.unlink(:default, "foo", "bar")).to eql("baz")
812
+ expect(node.unlink(:default, "bar", "foo")).to eql(nil)
813
+ end
814
+
815
+ it "delegates unlink!(:level) to node.level.unlink!()" do
816
+ node.default["foo"]["bar"] = "baz"
817
+ expect(node.unlink!(:default, "foo", "bar")).to eql("baz")
818
+ expect { node.unlink!(:default, "bar", "foo") }.to raise_error(Chef::Exceptions::NoSuchAttribute)
819
+ end
820
+ end
747
821
  end
748
822
 
749
823
  describe "consuming json" do
@@ -789,8 +863,8 @@ describe Chef::Node do
789
863
 
790
864
  it "should add json attributes to the node" do
791
865
  node.consume_external_attrs(@ohai_data, { "one" => "two", "three" => "four" })
792
- expect(node.one).to eql("two")
793
- expect(node.three).to eql("four")
866
+ expect(node["one"]).to eql("two")
867
+ expect(node["three"]).to eql("four")
794
868
  end
795
869
 
796
870
  it "should set the tags attribute to an empty array if it is not already defined" do
@@ -824,17 +898,17 @@ describe Chef::Node do
824
898
 
825
899
  it "deep merges attributes instead of overwriting them" do
826
900
  node.consume_external_attrs(@ohai_data, "one" => { "two" => { "three" => "four" } })
827
- expect(node.one.to_hash).to eq({ "two" => { "three" => "four" } })
901
+ expect(node["one"].to_hash).to eq({ "two" => { "three" => "four" } })
828
902
  node.consume_external_attrs(@ohai_data, "one" => { "abc" => "123" })
829
903
  node.consume_external_attrs(@ohai_data, "one" => { "two" => { "foo" => "bar" } })
830
- expect(node.one.to_hash).to eq({ "two" => { "three" => "four", "foo" => "bar" }, "abc" => "123" })
904
+ expect(node["one"].to_hash).to eq({ "two" => { "three" => "four", "foo" => "bar" }, "abc" => "123" })
831
905
  end
832
906
 
833
907
  it "gives attributes from JSON priority when deep merging" do
834
908
  node.consume_external_attrs(@ohai_data, "one" => { "two" => { "three" => "four" } })
835
- expect(node.one.to_hash).to eq({ "two" => { "three" => "four" } })
909
+ expect(node["one"].to_hash).to eq({ "two" => { "three" => "four" } })
836
910
  node.consume_external_attrs(@ohai_data, "one" => { "two" => { "three" => "forty-two" } })
837
- expect(node.one.to_hash).to eq({ "two" => { "three" => "forty-two" } })
911
+ expect(node["one"].to_hash).to eq({ "two" => { "three" => "forty-two" } })
838
912
  end
839
913
 
840
914
  end
@@ -1036,10 +1110,10 @@ describe Chef::Node do
1036
1110
  end
1037
1111
 
1038
1112
  it "sets attributes from the files" do
1039
- expect(node.ldap_server).to eql("ops1prod")
1040
- expect(node.ldap_basedn).to eql("dc=hjksolutions,dc=com")
1041
- expect(node.ldap_replication_password).to eql("forsure")
1042
- expect(node.smokey).to eql("robinson")
1113
+ expect(node["ldap_server"]).to eql("ops1prod")
1114
+ expect(node["ldap_basedn"]).to eql("dc=hjksolutions,dc=com")
1115
+ expect(node["ldap_replication_password"]).to eql("forsure")
1116
+ expect(node["smokey"]).to eql("robinson")
1043
1117
  end
1044
1118
 
1045
1119
  it "gives a sensible error when attempting to load a missing attributes file" do
@@ -1083,8 +1157,8 @@ describe Chef::Node do
1083
1157
  it "should load a node from a ruby file" do
1084
1158
  node.from_file(File.expand_path(File.join(CHEF_SPEC_DATA, "nodes", "test.rb")))
1085
1159
  expect(node.name).to eql("test.example.com-short")
1086
- expect(node.sunshine).to eql("in")
1087
- expect(node.something).to eql("else")
1160
+ expect(node["sunshine"]).to eql("in")
1161
+ expect(node["something"]).to eql("else")
1088
1162
  expect(node.run_list).to eq(["operations-master", "operations-monitoring"])
1089
1163
  end
1090
1164
 
@@ -1562,4 +1636,19 @@ describe Chef::Node do
1562
1636
  end
1563
1637
  end
1564
1638
 
1639
+ describe "method_missing handling" do
1640
+ it "should have an #empty? method via Chef::Node::Attribute" do
1641
+ node.default["foo"] = "bar"
1642
+ expect(node.empty?).to be false
1643
+ end
1644
+
1645
+ it "it should correctly implement #respond_to?" do
1646
+ expect(node.respond_to?(:empty?)).to be true
1647
+ end
1648
+
1649
+ it "it should correctly retrieve the method with #method" do
1650
+ expect(node.method(:empty?)).to be_kind_of(Method)
1651
+ end
1652
+ end
1653
+
1565
1654
  end
@@ -227,7 +227,7 @@ describe Chef::Provider::Directory do
227
227
  end
228
228
  end
229
229
 
230
- describe "#run_action(:create)" do
230
+ describe "#run_action(:delete)" do
231
231
  describe "when the directory exists" do
232
232
  it "deletes the directory" do
233
233
  directory.run_action(:delete)
@@ -238,6 +238,16 @@ describe Chef::Provider::Directory do
238
238
  directory.run_action(:delete)
239
239
  expect(new_resource).to be_updated
240
240
  end
241
+
242
+ it "does not use rm_rf which silently consumes errors" do
243
+ expect(FileUtils).not_to receive(:rm_rf)
244
+ expect(FileUtils).to receive(:rm_r)
245
+ # set recursive or FileUtils isn't used at all.
246
+ new_resource.recursive(true)
247
+ directory.run_action(:delete)
248
+ # reset back...
249
+ new_resource.recursive(false)
250
+ end
241
251
  end
242
252
 
243
253
  describe "when the directory does not exist" do
@@ -110,23 +110,28 @@ describe Chef::Provider::Package::Windows::Exe do
110
110
  end
111
111
 
112
112
  describe "remove_package" do
113
- context "no version given and one package installed" do
114
- it "removes installed package" do
115
- expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \/d\"uninst_dir\" uninst_file \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
113
+ before do
114
+ allow(::File).to receive(:exist?).and_return(false)
115
+ end
116
+
117
+ context "no version given and one package installed with unquoted uninstall string" do
118
+ it "removes installed package and quotes uninstall string" do
119
+ allow(::File).to receive(:exist?).with("uninst_dir/uninst_file").and_return(true)
120
+ expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \"uninst_dir\/uninst_file\" \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
116
121
  provider.remove_package
117
122
  end
118
123
  end
119
124
 
120
- context "several packages installed" do
125
+ context "several packages installed with quoted uninstall strings" do
121
126
  let(:uninstall_hash) do
122
127
  [
123
128
  {
124
129
  "DisplayVersion" => "v1",
125
- "UninstallString" => File.join("uninst_dir1", "uninst_file1"),
130
+ "UninstallString" => "\"#{File.join("uninst_dir1", "uninst_file1")}\"",
126
131
  },
127
132
  {
128
133
  "DisplayVersion" => "v2",
129
- "UninstallString" => File.join("uninst_dir2", "uninst_file2"),
134
+ "UninstallString" => "\"#{File.join("uninst_dir2", "uninst_file2")}\"",
130
135
  },
131
136
  ]
132
137
  end
@@ -134,15 +139,15 @@ describe Chef::Provider::Package::Windows::Exe do
134
139
  context "version given and installed" do
135
140
  it "removes given version" do
136
141
  new_resource.version("v2")
137
- expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \/d\"uninst_dir2\" uninst_file2 \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
142
+ expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \"uninst_dir2\/uninst_file2\" \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
138
143
  provider.remove_package
139
144
  end
140
145
  end
141
146
 
142
147
  context "no version given" do
143
148
  it "removes both versions" do
144
- expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \/d\"uninst_dir1\" uninst_file1 \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
145
- expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \/d\"uninst_dir2\" uninst_file2 \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
149
+ expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \"uninst_dir1\/uninst_file1\" \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
150
+ expect(provider).to receive(:shell_out!).with(/start \"\" \/wait \"uninst_dir2\/uninst_file2\" \/S \/NCRC & exit %%%%ERRORLEVEL%%%%/, kind_of(Hash))
146
151
  provider.remove_package
147
152
  end
148
153
  end
@@ -43,8 +43,8 @@ describe Chef::Provider::PowershellScript, "action_run" do
43
43
  allow(Chef::Platform).to receive(:windows_nano_server?).and_return(true)
44
44
  allow(provider).to receive(:is_forced_32bit).and_return(false)
45
45
  os_info_double = double("os_info")
46
- allow(provider.run_context.node.kernel).to receive(:os_info).and_return(os_info_double)
47
- allow(os_info_double).to receive(:system_directory).and_return("C:\\Windows\\system32")
46
+ allow(provider.run_context.node["kernel"]).to receive(:[]).with("os_info").and_return(os_info_double)
47
+ allow(os_info_double).to receive(:[]).with("system_directory").and_return("C:\\Windows\\system32")
48
48
  end
49
49
 
50
50
  it "sets the -Command flag as the last flag" do
@@ -58,8 +58,8 @@ describe Chef::Provider::PowershellScript, "action_run" do
58
58
  allow(Chef::Platform).to receive(:windows_nano_server?).and_return(false)
59
59
  allow(provider).to receive(:is_forced_32bit).and_return(false)
60
60
  os_info_double = double("os_info")
61
- allow(provider.run_context.node.kernel).to receive(:os_info).and_return(os_info_double)
62
- allow(os_info_double).to receive(:system_directory).and_return("C:\\Windows\\system32")
61
+ allow(provider.run_context.node["kernel"]).to receive(:[]).with("os_info").and_return(os_info_double)
62
+ allow(os_info_double).to receive(:[]).with("system_directory").and_return("C:\\Windows\\system32")
63
63
  end
64
64
 
65
65
  it "sets the -File flag as the last flag" do
@@ -99,6 +99,21 @@ describe Chef::Provider::RemoteDirectory do
99
99
  expect(cookbook_file.owner).to eq("toor")
100
100
  expect(cookbook_file.backup).to eq(23)
101
101
  end
102
+
103
+ it "respects sensitive flag" do
104
+ @resource.cookbook "gondola_rides"
105
+ @resource.sensitive true
106
+ cookbook_file = @provider.send(:cookbook_file_resource,
107
+ "/target/destination/path.txt",
108
+ "relative/source/path.txt")
109
+ expect(cookbook_file.sensitive).to eq(true)
110
+
111
+ @resource.sensitive false
112
+ cookbook_file = @provider.send(:cookbook_file_resource,
113
+ "/target/destination/path.txt",
114
+ "relative/source/path.txt")
115
+ expect(cookbook_file.sensitive).to eq(false)
116
+ end
102
117
  end
103
118
 
104
119
  describe "when creating the remote directory" do
@@ -195,9 +195,7 @@ describe Chef::Recipe do
195
195
 
196
196
  describe "when cloning resources" do
197
197
  def expect_warning
198
- expect(Chef::Log).to receive(:warn).with(/3694/)
199
- expect(Chef::Log).to receive(:warn).with(/Previous/)
200
- expect(Chef::Log).to receive(:warn).with(/Current/)
198
+ expect(Chef).to receive(:log_deprecation).with(/^Cloning resource attributes for zen_master\[klopp\]/)
201
199
  end
202
200
 
203
201
  it "should emit a 3694 warning when attributes change" do
@@ -244,7 +242,7 @@ describe Chef::Recipe do
244
242
 
245
243
  it "should not emit a 3694 warning for completely trivial resource cloning" do
246
244
  recipe.zen_master "klopp"
247
- expect(Chef::Log).to_not receive(:warn)
245
+ expect(Chef).to_not receive(:log_deprecation)
248
246
  recipe.zen_master "klopp"
249
247
  end
250
248
 
@@ -252,7 +250,7 @@ describe Chef::Recipe do
252
250
  recipe.zen_master "klopp" do
253
251
  action :nothing
254
252
  end
255
- expect(Chef::Log).to_not receive(:warn)
253
+ expect(Chef).to_not receive(:log_deprecation)
256
254
  recipe.zen_master "klopp" do
257
255
  action :score
258
256
  end
@@ -262,12 +260,33 @@ describe Chef::Recipe do
262
260
  recipe.zen_master "klopp" do
263
261
  action :score
264
262
  end
265
- expect(Chef::Log).to_not receive(:warn)
263
+ expect(Chef).to_not receive(:log_deprecation)
266
264
  recipe.zen_master "klopp" do
267
265
  action :nothing
268
266
  end
269
267
  end
270
268
 
269
+ class Coerced < Chef::Resource
270
+ resource_name :coerced
271
+ provides :coerced
272
+ default_action :whatever
273
+ property :package_name, [String, Array], coerce: proc { |x| [x].flatten }, name_property: true
274
+ def after_created
275
+ Array(action).each do |action|
276
+ run_action(action)
277
+ end
278
+ end
279
+ action :whatever do
280
+ package_name # unlazy the package_name
281
+ end
282
+ end
283
+
284
+ it "does not emit 3694 when the name_property is unlazied by running it at compile_time" do
285
+ recipe.coerced "string"
286
+ expect(Chef).to_not receive(:log_deprecation)
287
+ recipe.coerced "string"
288
+ end
289
+
271
290
  it "validating resources via build_resource" do
272
291
  expect {recipe.build_resource(:remote_file, "klopp") do
273
292
  source Chef::DelayedEvaluator.new { "http://chef.io" }
@@ -299,6 +318,7 @@ describe Chef::Recipe do
299
318
  end
300
319
 
301
320
  it "will insert another resource if create_if_missing is not set (cloned resource as of Chef-12)" do
321
+ expect(Chef).to receive(:log_deprecation).with(/^Cloning resource attributes for zen_master\[klopp\]/)
302
322
  zm_resource
303
323
  recipe.declare_resource(:zen_master, "klopp")
304
324
  expect(run_context.resource_collection.count).to eql(2)
@@ -421,15 +441,18 @@ describe Chef::Recipe do
421
441
  end
422
442
 
423
443
  it "copies attributes from the first resource" do
444
+ expect(Chef).to receive(:log_deprecation).with(/^Cloning resource attributes for zen_master\[klopp\]/)
424
445
  expect(duplicated_resource.something).to eq("bvb09")
425
446
  end
426
447
 
427
448
  it "does not copy the action from the first resource" do
449
+ expect(Chef).to receive(:log_deprecation).with(/^Cloning resource attributes for zen_master\[klopp\]/)
428
450
  expect(original_resource.action).to eq([:score])
429
451
  expect(duplicated_resource.action).to eq([:nothing])
430
452
  end
431
453
 
432
454
  it "does not copy the source location of the first resource" do
455
+ expect(Chef).to receive(:log_deprecation).with(/^Cloning resource attributes for zen_master\[klopp\]/)
433
456
  # sanity check source location:
434
457
  expect(original_resource.source_line).to include(__FILE__)
435
458
  expect(duplicated_resource.source_line).to include(__FILE__)
@@ -438,10 +461,12 @@ describe Chef::Recipe do
438
461
  end
439
462
 
440
463
  it "sets the cookbook name on the cloned resource to that resource's cookbook" do
464
+ expect(Chef).to receive(:log_deprecation).with(/^Cloning resource attributes for zen_master\[klopp\]/)
441
465
  expect(duplicated_resource.cookbook_name).to eq("second_cb")
442
466
  end
443
467
 
444
468
  it "sets the recipe name on the cloned resource to that resoure's recipe" do
469
+ expect(Chef).to receive(:log_deprecation).with(/^Cloning resource attributes for zen_master\[klopp\]/)
445
470
  expect(duplicated_resource.recipe_name).to eq("second_recipe")
446
471
  end
447
472