chef 12.11.18-universal-mingw32 → 12.12.13-universal-mingw32
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 +4 -4
- data/Gemfile +4 -4
- data/Rakefile +3 -2
- data/VERSION +1 -1
- data/acceptance/Gemfile.lock +22 -23
- data/acceptance/data-collector/test/integration/default/serverspec/default_spec.rb +2 -41
- data/lib/chef/application/solo.rb +7 -0
- data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +1 -1
- data/lib/chef/data_collector.rb +79 -43
- data/lib/chef/data_collector/messages.rb +4 -33
- data/lib/chef/data_collector/messages/helpers.rb +2 -2
- data/lib/chef/data_collector/resource_report.rb +21 -11
- data/lib/chef/decorator/unchain.rb +43 -0
- data/lib/chef/exceptions.rb +5 -0
- data/lib/chef/http.rb +5 -5
- data/lib/chef/knife/cookbook_create.rb +4 -0
- data/lib/chef/knife/cookbook_site_download.rb +8 -1
- data/lib/chef/knife/cookbook_site_install.rb +8 -0
- data/lib/chef/knife/cookbook_site_list.rb +8 -1
- data/lib/chef/knife/cookbook_site_search.rb +8 -1
- data/lib/chef/knife/cookbook_site_share.rb +8 -1
- data/lib/chef/knife/cookbook_site_show.rb +14 -3
- data/lib/chef/knife/cookbook_site_unshare.rb +8 -1
- data/lib/chef/knife/core/bootstrap_context.rb +1 -1
- data/lib/chef/knife/supermarket_download.rb +33 -0
- data/lib/chef/knife/supermarket_install.rb +33 -0
- data/lib/chef/knife/supermarket_list.rb +33 -0
- data/lib/chef/knife/supermarket_search.rb +33 -0
- data/lib/chef/knife/supermarket_share.rb +33 -0
- data/lib/chef/knife/supermarket_show.rb +33 -0
- data/lib/chef/knife/supermarket_unshare.rb +33 -0
- data/lib/chef/node.rb +13 -32
- data/lib/chef/node/attribute.rb +123 -70
- data/lib/chef/node/attribute_collections.rb +9 -130
- data/lib/chef/node/common_api.rb +124 -0
- data/lib/chef/node/immutable_collections.rb +27 -2
- data/lib/chef/property.rb +6 -2
- data/lib/chef/provider.rb +4 -5
- data/lib/chef/provider/batch.rb +1 -1
- data/lib/chef/provider/directory.rb +3 -1
- data/lib/chef/provider/package/openbsd.rb +1 -1
- data/lib/chef/provider/package/rubygems.rb +9 -3
- data/lib/chef/provider/package/windows/exe.rb +2 -5
- data/lib/chef/provider/powershell_script.rb +1 -1
- data/lib/chef/provider/remote_directory.rb +2 -0
- data/lib/chef/resource.rb +22 -17
- data/lib/chef/resource_builder.rb +9 -4
- data/lib/chef/shell.rb +1 -1
- data/lib/chef/version.rb +1 -1
- data/spec/data/run_context/cookbooks/circular-dep1/attributes/default.rb +2 -4
- data/spec/data/run_context/cookbooks/circular-dep2/attributes/default.rb +2 -3
- data/spec/data/run_context/cookbooks/dependency1/attributes/aa_first.rb +2 -2
- data/spec/data/run_context/cookbooks/dependency1/attributes/default.rb +2 -2
- data/spec/data/run_context/cookbooks/dependency1/attributes/zz_last.rb +2 -3
- data/spec/data/run_context/cookbooks/dependency2/attributes/default.rb +2 -3
- data/spec/data/run_context/cookbooks/no-default-attr/attributes/server.rb +2 -3
- data/spec/data/run_context/cookbooks/test-with-circular-deps/attributes/default.rb +2 -3
- data/spec/data/run_context/cookbooks/test-with-deps/attributes/default.rb +2 -3
- data/spec/functional/assets/chocolatey_feed/test-A.1.0.nupkg +0 -0
- data/spec/functional/assets/chocolatey_feed/test-A.1.5.nupkg +0 -0
- data/spec/functional/assets/chocolatey_feed/test-A.2.0.nupkg +0 -0
- data/spec/functional/assets/chocolatey_feed/test-B.1.0.nupkg +0 -0
- data/spec/functional/resource/dsc_script_spec.rb +1 -0
- data/spec/functional/resource/package_spec.rb +1 -1
- data/spec/functional/resource/template_spec.rb +3 -3
- data/spec/functional/shell_spec.rb +1 -1
- data/spec/integration/knife/client_bulk_delete_spec.rb +130 -0
- data/spec/integration/knife/client_create_spec.rb +69 -0
- data/spec/integration/knife/client_delete_spec.rb +63 -0
- data/spec/integration/knife/client_key_create_spec.rb +65 -0
- data/spec/integration/knife/client_key_delete_spec.rb +42 -0
- data/spec/integration/knife/client_key_list_spec.rb +60 -0
- data/spec/integration/knife/client_key_show_spec.rb +44 -0
- data/spec/integration/knife/client_list_spec.rb +48 -0
- data/spec/integration/knife/client_show_spec.rb +36 -0
- data/spec/integration/knife/cookbook_bulk_delete_spec.rb +64 -0
- data/spec/integration/knife/cookbook_download_spec.rb +95 -0
- data/spec/integration/knife/cookbook_list_spec.rb +54 -0
- data/spec/integration/knife/cookbook_show_spec.rb +159 -0
- data/spec/integration/knife/cookbook_upload_spec.rb +90 -0
- data/spec/integration/knife/data_bag_create_spec.rb +58 -0
- data/spec/integration/knife/data_bag_delete_spec.rb +58 -0
- data/spec/integration/knife/data_bag_from_file_spec.rb +115 -0
- data/spec/integration/knife/data_bag_list_spec.rb +43 -0
- data/spec/integration/knife/data_bag_show_spec.rb +53 -0
- data/spec/integration/knife/environment_compare_spec.rb +74 -0
- data/spec/integration/knife/environment_create_spec.rb +40 -0
- data/spec/integration/knife/environment_delete_spec.rb +36 -0
- data/spec/integration/knife/environment_from_file_spec.rb +115 -0
- data/spec/integration/knife/environment_list_spec.rb +41 -0
- data/spec/integration/knife/environment_show_spec.rb +56 -0
- data/spec/integration/knife/node_bulk_delete_spec.rb +51 -0
- data/spec/integration/knife/node_create_spec.rb +46 -0
- data/spec/integration/knife/node_delete_spec.rb +47 -0
- data/spec/integration/knife/node_environment_set_spec.rb +42 -0
- data/spec/integration/knife/node_from_file_spec.rb +58 -0
- data/spec/integration/knife/node_list_spec.rb +44 -0
- data/spec/integration/knife/node_run_list_add_spec.rb +53 -0
- data/spec/integration/knife/node_run_list_remove_spec.rb +35 -0
- data/spec/integration/knife/node_run_list_set_spec.rb +40 -0
- data/spec/integration/knife/node_show_spec.rb +35 -0
- data/spec/integration/knife/role_bulk_delete_spec.rb +51 -0
- data/spec/integration/knife/role_create_spec.rb +40 -0
- data/spec/integration/knife/role_delete_spec.rb +47 -0
- data/spec/integration/knife/role_from_file_spec.rb +95 -0
- data/spec/integration/knife/role_list_spec.rb +44 -0
- data/spec/integration/knife/role_show_spec.rb +50 -0
- data/spec/support/shared/integration/knife_support.rb +10 -3
- data/spec/unit/application/solo_spec.rb +7 -0
- data/spec/unit/cookbook_version_spec.rb +4 -4
- data/spec/unit/data_collector/messages/helpers_spec.rb +3 -7
- data/spec/unit/data_collector/messages_spec.rb +28 -45
- data/spec/unit/data_collector_spec.rb +40 -47
- data/spec/unit/knife/cookbook_create_spec.rb +1 -0
- data/spec/unit/knife/cookbook_site_download_spec.rb +1 -0
- data/spec/unit/knife/node_environment_set_spec.rb +0 -24
- data/spec/unit/knife/node_run_list_set_spec.rb +0 -25
- data/spec/unit/node/attribute_spec.rb +7 -9
- data/spec/unit/node/immutable_collections_spec.rb +4 -0
- data/spec/unit/node/vivid_mash_spec.rb +344 -0
- data/spec/unit/node_spec.rb +115 -26
- data/spec/unit/provider/directory_spec.rb +11 -1
- data/spec/unit/provider/package/windows/exe_spec.rb +14 -9
- data/spec/unit/provider/powershell_script_spec.rb +4 -4
- data/spec/unit/provider/remote_directory_spec.rb +15 -0
- data/spec/unit/recipe_spec.rb +31 -6
- data/spec/unit/run_context_spec.rb +2 -2
- data/spec/unit/shell/shell_session_spec.rb +1 -1
- data/tasks/dependencies.rb +0 -2
- metadata +55 -786
- data/acceptance/.bundle/config +0 -2
- data/acceptance/basics/.kitchen/logs/chef-current-install-ubuntu-1404.log +0 -2
- data/acceptance/basics/.kitchen/logs/kitchen.log +0 -3
- data/acceptance/fips/.kitchen/logs/fips-integration-centos-6.log +0 -3
- data/acceptance/fips/.kitchen/logs/fips-integration-windows-2012r2.log +0 -3
- data/acceptance/fips/.kitchen/logs/fips-unit-functional-centos-6.log +0 -3
- data/acceptance/fips/.kitchen/logs/fips-unit-functional-windows-2012r2.log +0 -3
- data/acceptance/fips/.kitchen/logs/kitchen.log +0 -6
- data/acceptance/trivial/.kitchen/logs/chef-current-install-windows-2012r2.log +0 -2
- data/acceptance/trivial/.kitchen/logs/kitchen.log +0 -3
- data/acceptance/windows-service/.kitchen/logs/chef-windows-service-windows-2012r2.log +0 -2
- data/acceptance/windows-service/.kitchen/logs/kitchen.log +0 -3
@@ -20,6 +20,7 @@
|
|
20
20
|
|
21
21
|
require "spec_helper"
|
22
22
|
require "chef/data_collector"
|
23
|
+
require "chef/resource_builder"
|
23
24
|
|
24
25
|
describe Chef::DataCollector do
|
25
26
|
describe ".register_reporter?" do
|
@@ -193,10 +194,32 @@ describe Chef::DataCollector::Reporter do
|
|
193
194
|
end
|
194
195
|
end
|
195
196
|
|
197
|
+
describe '#converge_start' do
|
198
|
+
it "stashes the run_context for later use" do
|
199
|
+
reporter.converge_start("test_context")
|
200
|
+
expect(reporter.run_context).to eq("test_context")
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe '#converge_complete' do
|
205
|
+
it "detects and processes any unprocessed resources" do
|
206
|
+
expect(reporter).to receive(:detect_unprocessed_resources)
|
207
|
+
reporter.converge_complete
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe '#converge_failed' do
|
212
|
+
it "detects and processes any unprocessed resources" do
|
213
|
+
expect(reporter).to receive(:detect_unprocessed_resources)
|
214
|
+
reporter.converge_failed("exception")
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
196
218
|
describe '#resource_current_state_loaded' do
|
197
219
|
let(:new_resource) { double("new_resource") }
|
198
220
|
let(:action) { double("action") }
|
199
221
|
let(:current_resource) { double("current_resource") }
|
222
|
+
let(:resource_report) { double("resource_report") }
|
200
223
|
|
201
224
|
context "when resource is a nested resource" do
|
202
225
|
it "does not update the resource report" do
|
@@ -207,14 +230,12 @@ describe Chef::DataCollector::Reporter do
|
|
207
230
|
end
|
208
231
|
|
209
232
|
context "when resource is not a nested resource" do
|
210
|
-
it "
|
233
|
+
it "creates the resource report and stores it as the current one" do
|
211
234
|
allow(reporter).to receive(:nested_resource?).and_return(false)
|
212
|
-
expect(
|
213
|
-
new_resource,
|
214
|
-
|
215
|
-
|
216
|
-
.and_return("resource_report")
|
217
|
-
expect(reporter).to receive(:update_current_resource_report).with("resource_report")
|
235
|
+
expect(reporter).to receive(:create_resource_report)
|
236
|
+
.with(new_resource, action, current_resource)
|
237
|
+
.and_return(resource_report)
|
238
|
+
expect(reporter).to receive(:update_current_resource_report).with(resource_report)
|
218
239
|
reporter.resource_current_state_loaded(new_resource, action, current_resource)
|
219
240
|
end
|
220
241
|
end
|
@@ -226,17 +247,11 @@ describe Chef::DataCollector::Reporter do
|
|
226
247
|
let(:resource_report) { double("resource_report") }
|
227
248
|
|
228
249
|
before do
|
229
|
-
allow(reporter).to receive(:increment_resource_count)
|
230
250
|
allow(reporter).to receive(:nested_resource?)
|
231
251
|
allow(reporter).to receive(:current_resource_report).and_return(resource_report)
|
232
252
|
allow(resource_report).to receive(:up_to_date)
|
233
253
|
end
|
234
254
|
|
235
|
-
it "increments the resource count" do
|
236
|
-
expect(reporter).to receive(:increment_resource_count)
|
237
|
-
reporter.resource_up_to_date(new_resource, action)
|
238
|
-
end
|
239
|
-
|
240
255
|
context "when the resource is a nested resource" do
|
241
256
|
it "does not mark the resource report as up-to-date" do
|
242
257
|
allow(reporter).to receive(:nested_resource?).with(new_resource).and_return(true)
|
@@ -261,17 +276,11 @@ describe Chef::DataCollector::Reporter do
|
|
261
276
|
let(:resource_report) { double("resource_report") }
|
262
277
|
|
263
278
|
before do
|
264
|
-
allow(reporter).to receive(:increment_resource_count)
|
265
279
|
allow(reporter).to receive(:nested_resource?)
|
266
|
-
allow(reporter).to receive(:
|
280
|
+
allow(reporter).to receive(:create_resource_report).and_return(resource_report)
|
267
281
|
allow(resource_report).to receive(:skipped)
|
268
282
|
end
|
269
283
|
|
270
|
-
it "increments the resource count" do
|
271
|
-
expect(reporter).to receive(:increment_resource_count)
|
272
|
-
reporter.resource_skipped(new_resource, action, conditional)
|
273
|
-
end
|
274
|
-
|
275
284
|
context "when the resource is a nested resource" do
|
276
285
|
it "does not mark the resource report as skipped" do
|
277
286
|
allow(reporter).to receive(:nested_resource?).with(new_resource).and_return(true)
|
@@ -281,13 +290,12 @@ describe Chef::DataCollector::Reporter do
|
|
281
290
|
end
|
282
291
|
|
283
292
|
context "when the resource is not a nested resource" do
|
284
|
-
it "
|
293
|
+
it "creates the resource report and stores it as the current one" do
|
285
294
|
allow(reporter).to receive(:nested_resource?).and_return(false)
|
286
|
-
expect(
|
287
|
-
new_resource,
|
288
|
-
|
289
|
-
.
|
290
|
-
expect(reporter).to receive(:update_current_resource_report).with("resource_report")
|
295
|
+
expect(reporter).to receive(:create_resource_report)
|
296
|
+
.with(new_resource, action)
|
297
|
+
.and_return(resource_report)
|
298
|
+
expect(reporter).to receive(:update_current_resource_report).with(resource_report)
|
291
299
|
reporter.resource_skipped(new_resource, action, conditional)
|
292
300
|
end
|
293
301
|
|
@@ -307,11 +315,6 @@ describe Chef::DataCollector::Reporter do
|
|
307
315
|
allow(resource_report).to receive(:updated)
|
308
316
|
end
|
309
317
|
|
310
|
-
it "increments the resource count" do
|
311
|
-
expect(reporter).to receive(:increment_resource_count)
|
312
|
-
reporter.resource_updated("new_resource", "action")
|
313
|
-
end
|
314
|
-
|
315
318
|
it "marks the resource report as updated" do
|
316
319
|
expect(resource_report).to receive(:updated)
|
317
320
|
reporter.resource_updated("new_resource", "action")
|
@@ -326,7 +329,6 @@ describe Chef::DataCollector::Reporter do
|
|
326
329
|
let(:resource_report) { double("resource_report") }
|
327
330
|
|
328
331
|
before do
|
329
|
-
allow(reporter).to receive(:increment_resource_count)
|
330
332
|
allow(reporter).to receive(:update_error_description)
|
331
333
|
allow(reporter).to receive(:current_resource_report).and_return(resource_report)
|
332
334
|
allow(resource_report).to receive(:failed)
|
@@ -334,11 +336,6 @@ describe Chef::DataCollector::Reporter do
|
|
334
336
|
allow(error_mapper).to receive(:for_json)
|
335
337
|
end
|
336
338
|
|
337
|
-
it "increments the resource count" do
|
338
|
-
expect(reporter).to receive(:increment_resource_count)
|
339
|
-
reporter.resource_failed(new_resource, action, exception)
|
340
|
-
end
|
341
|
-
|
342
339
|
it "updates the error description" do
|
343
340
|
expect(Chef::Formatters::ErrorMapper).to receive(:resource_failed).with(
|
344
341
|
new_resource,
|
@@ -372,15 +369,16 @@ describe Chef::DataCollector::Reporter do
|
|
372
369
|
let(:resource_report) { double("resource_report") }
|
373
370
|
|
374
371
|
before do
|
375
|
-
allow(reporter).to receive(:add_updated_resource)
|
376
372
|
allow(reporter).to receive(:update_current_resource_report)
|
373
|
+
allow(reporter).to receive(:add_resource_report)
|
374
|
+
allow(reporter).to receive(:current_resource_report)
|
377
375
|
allow(resource_report).to receive(:finish)
|
378
376
|
end
|
379
377
|
|
380
378
|
context "when there is no current resource report" do
|
381
|
-
it "does not
|
379
|
+
it "does not touch the current resource report" do
|
382
380
|
allow(reporter).to receive(:current_resource_report).and_return(nil)
|
383
|
-
expect(reporter).not_to receive(:
|
381
|
+
expect(reporter).not_to receive(:update_current_resource_report)
|
384
382
|
reporter.resource_completed(new_resource)
|
385
383
|
end
|
386
384
|
end
|
@@ -391,9 +389,9 @@ describe Chef::DataCollector::Reporter do
|
|
391
389
|
end
|
392
390
|
|
393
391
|
context "when the resource is a nested resource" do
|
394
|
-
it "does not
|
392
|
+
it "does not mark the resource as finished" do
|
395
393
|
allow(reporter).to receive(:nested_resource?).with(new_resource).and_return(true)
|
396
|
-
expect(
|
394
|
+
expect(resource_report).not_to receive(:finish)
|
397
395
|
reporter.resource_completed(new_resource)
|
398
396
|
end
|
399
397
|
end
|
@@ -408,11 +406,6 @@ describe Chef::DataCollector::Reporter do
|
|
408
406
|
reporter.resource_completed(new_resource)
|
409
407
|
end
|
410
408
|
|
411
|
-
it "adds the resource to the updated resource list" do
|
412
|
-
expect(reporter).to receive(:add_updated_resource).with(resource_report)
|
413
|
-
reporter.resource_completed(new_resource)
|
414
|
-
end
|
415
|
-
|
416
409
|
it "nils out the current resource report" do
|
417
410
|
expect(reporter).to receive(:update_current_resource_report).with(nil)
|
418
411
|
reporter.resource_completed(new_resource)
|
@@ -22,6 +22,7 @@ require "tmpdir"
|
|
22
22
|
describe Chef::Knife::CookbookCreate do
|
23
23
|
before(:each) do
|
24
24
|
Chef::Config[:node_name] = "webmonkey.example.com"
|
25
|
+
Chef::Config[:treat_deprecation_warnings_as_errors] = false
|
25
26
|
@knife = Chef::Knife::CookbookCreate.new
|
26
27
|
@knife.config = {}
|
27
28
|
@knife.name_args = ["foobar"]
|
@@ -52,29 +52,5 @@ describe Chef::Knife::NodeEnvironmentSet do
|
|
52
52
|
@knife.run
|
53
53
|
end
|
54
54
|
|
55
|
-
describe "with no environment" do
|
56
|
-
# Set up outputs for inspection later
|
57
|
-
before(:each) do
|
58
|
-
@stdout = StringIO.new
|
59
|
-
@stderr = StringIO.new
|
60
|
-
|
61
|
-
allow(@knife.ui).to receive(:stdout).and_return(@stdout)
|
62
|
-
allow(@knife.ui).to receive(:stderr).and_return(@stderr)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "should exit" do
|
66
|
-
@knife.name_args = [ "adam" ]
|
67
|
-
expect { @knife.run }.to raise_error SystemExit
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should show the user the usage and an error" do
|
71
|
-
@knife.name_args = [ "adam" ]
|
72
|
-
|
73
|
-
begin ; @knife.run ; rescue SystemExit ; end
|
74
|
-
|
75
|
-
expect(@stdout.string).to eq "USAGE: knife node environment set NODE ENVIRONMENT\n"
|
76
|
-
expect(@stderr.string).to eq "FATAL: You must specify a node name and an environment.\n"
|
77
|
-
end
|
78
|
-
end
|
79
55
|
end
|
80
56
|
end
|
@@ -111,30 +111,5 @@ describe Chef::Knife::NodeRunListSet do
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
describe "with no role or recipe" do
|
115
|
-
# Set up outputs for inspection later
|
116
|
-
before(:each) do
|
117
|
-
@stdout = StringIO.new
|
118
|
-
@stderr = StringIO.new
|
119
|
-
|
120
|
-
allow(@knife.ui).to receive(:stdout).and_return(@stdout)
|
121
|
-
allow(@knife.ui).to receive(:stderr).and_return(@stderr)
|
122
|
-
end
|
123
|
-
|
124
|
-
it "should exit" do
|
125
|
-
@knife.name_args = [ "adam" ]
|
126
|
-
expect { @knife.run }.to raise_error SystemExit
|
127
|
-
end
|
128
|
-
|
129
|
-
it "should show the user" do
|
130
|
-
@knife.name_args = [ "adam" ]
|
131
|
-
|
132
|
-
begin ; @knife.run ; rescue SystemExit ; end
|
133
|
-
|
134
|
-
expect(@stdout.string).to eq "USAGE: knife node run_list set NODE ENTRIES (options)\n"
|
135
|
-
expect(@stderr.string).to eq "FATAL: You must supply both a node name and a run list.\n"
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
114
|
end
|
140
115
|
end
|
@@ -218,7 +218,7 @@ describe Chef::Node::Attribute do
|
|
218
218
|
end
|
219
219
|
|
220
220
|
it "gives the value at each level of precedence for a path spec" do
|
221
|
-
expected = [
|
221
|
+
expected = [
|
222
222
|
%w{default default},
|
223
223
|
%w{env_default env_default},
|
224
224
|
%w{role_default role_default},
|
@@ -417,12 +417,6 @@ describe Chef::Node::Attribute do
|
|
417
417
|
expect(@attributes.normal["foo"]["bar"]).to eq(:baz)
|
418
418
|
end
|
419
419
|
|
420
|
-
it "should optionally skip setting the value if one already exists" do
|
421
|
-
@attributes.set_unless_value_present = true
|
422
|
-
@attributes.normal["hostname"] = "bar"
|
423
|
-
expect(@attributes["hostname"]).to eq("latte")
|
424
|
-
end
|
425
|
-
|
426
420
|
it "does not support ||= when setting" do
|
427
421
|
# This is a limitation of auto-vivification.
|
428
422
|
# Users who need this behavior can use set_unless and friends
|
@@ -493,6 +487,7 @@ describe Chef::Node::Attribute do
|
|
493
487
|
end
|
494
488
|
|
495
489
|
it "should return true if an attribute exists but is set to nil using dot notation" do
|
490
|
+
Chef::Config[:treat_deprecation_warnings_as_errors] = false
|
496
491
|
expect(@attributes.music.deeper.has_key?("gates_of_ishtar")).to eq(true)
|
497
492
|
end
|
498
493
|
|
@@ -533,10 +528,12 @@ describe Chef::Node::Attribute do
|
|
533
528
|
|
534
529
|
describe "method_missing" do
|
535
530
|
it "should behave like a [] lookup" do
|
531
|
+
Chef::Config[:treat_deprecation_warnings_as_errors] = false
|
536
532
|
expect(@attributes.music.mastodon).to eq("rocks")
|
537
533
|
end
|
538
534
|
|
539
535
|
it "should allow the last method to set a value if it has an = sign on the end" do
|
536
|
+
Chef::Config[:treat_deprecation_warnings_as_errors] = false
|
540
537
|
@attributes.normal.music.mastodon = %w{dream still shining}
|
541
538
|
expect(@attributes.normal.music.mastodon).to eq(%w{dream still shining})
|
542
539
|
end
|
@@ -577,7 +574,7 @@ describe Chef::Node::Attribute do
|
|
577
574
|
|
578
575
|
it "should yield lower if we go deeper" do
|
579
576
|
collect = Array.new
|
580
|
-
@attributes
|
577
|
+
@attributes["one"].keys.each do |k|
|
581
578
|
collect << k
|
582
579
|
end
|
583
580
|
expect(collect.include?("two")).to eq(true)
|
@@ -587,7 +584,7 @@ describe Chef::Node::Attribute do
|
|
587
584
|
end
|
588
585
|
|
589
586
|
it "should not raise an exception if one of the hashes has a nil value on a deep lookup" do
|
590
|
-
expect { @attributes
|
587
|
+
expect { @attributes["place"].keys { |k| } }.not_to raise_error
|
591
588
|
end
|
592
589
|
end
|
593
590
|
|
@@ -1171,6 +1168,7 @@ describe Chef::Node::Attribute do
|
|
1171
1168
|
end
|
1172
1169
|
|
1173
1170
|
it "raises an error when using `attr=value`" do
|
1171
|
+
Chef::Config[:treat_deprecation_warnings_as_errors] = false
|
1174
1172
|
expect { @attributes.new_key = "new value" }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
|
1175
1173
|
end
|
1176
1174
|
|
@@ -95,6 +95,10 @@ describe Chef::Node::ImmutableMash do
|
|
95
95
|
:replace,
|
96
96
|
:select!,
|
97
97
|
:shift,
|
98
|
+
:write,
|
99
|
+
:write!,
|
100
|
+
:unlink,
|
101
|
+
:unlink!,
|
98
102
|
].each do |mutator|
|
99
103
|
it "doesn't allow mutation via `#{mutator}'" do
|
100
104
|
expect { @immutable_mash.send(mutator) }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
|
@@ -0,0 +1,344 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright 2016, Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require "spec_helper"
|
19
|
+
require "chef/node/attribute_collections"
|
20
|
+
|
21
|
+
describe Chef::Node::VividMash do
|
22
|
+
class Root
|
23
|
+
attr_accessor :top_level_breadcrumb
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:root) { Root.new }
|
27
|
+
|
28
|
+
let(:vivid) do
|
29
|
+
expect(root).to receive(:reset_cache).at_least(:once).with(nil)
|
30
|
+
Chef::Node::VividMash.new(root,
|
31
|
+
{ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil }
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
context "#read" do
|
36
|
+
before do
|
37
|
+
# vivify the vividmash, then we're read-only so the cache should never be cleared afterwards
|
38
|
+
vivid
|
39
|
+
expect(root).not_to receive(:reset_cache)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "reads hashes deeply" do
|
43
|
+
expect(root).to receive(:top_level_breadcrumb=).with("one").and_call_original
|
44
|
+
expect(vivid.read("one", "two", "three")).to eql("four")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "does not trainwreck when hitting hash keys that do not exist" do
|
48
|
+
expect(root).to receive(:top_level_breadcrumb=).with("one").and_call_original
|
49
|
+
expect(vivid.read("one", "five", "six")).to eql(nil)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "does not trainwreck when hitting an array with an out of bounds index" do
|
53
|
+
expect(root).to receive(:top_level_breadcrumb=).with("array").and_call_original
|
54
|
+
expect(vivid.read("array", 5, "one")).to eql(nil)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "does not trainwreck when hitting an array with a string key" do
|
58
|
+
expect(root).to receive(:top_level_breadcrumb=).with("array").and_call_original
|
59
|
+
expect(vivid.read("array", "one", "two")).to eql(nil)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "does not trainwreck when traversing a nil" do
|
63
|
+
expect(root).to receive(:top_level_breadcrumb=).with("nil").and_call_original
|
64
|
+
expect(vivid.read("nil", "one", "two")).to eql(nil)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "#exist?" do
|
69
|
+
before do
|
70
|
+
# vivify the vividmash, then we're read-only so the cache should never be cleared afterwards
|
71
|
+
vivid
|
72
|
+
expect(root).not_to receive(:reset_cache)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "true if there's a hash key there" do
|
76
|
+
expect(root).to receive(:top_level_breadcrumb=).with("one").and_call_original
|
77
|
+
expect(vivid.exist?("one", "two", "three")).to be true
|
78
|
+
end
|
79
|
+
|
80
|
+
it "true for intermediate hashes" do
|
81
|
+
expect(root).to receive(:top_level_breadcrumb=).with("one").and_call_original
|
82
|
+
expect(vivid.exist?("one")).to be true
|
83
|
+
end
|
84
|
+
|
85
|
+
it "true for arrays that exist" do
|
86
|
+
expect(root).to receive(:top_level_breadcrumb=).with("array").and_call_original
|
87
|
+
expect(vivid.exist?("array", 1)).to be true
|
88
|
+
end
|
89
|
+
|
90
|
+
it "true when the value of the key is nil" do
|
91
|
+
expect(root).to receive(:top_level_breadcrumb=).with("nil").and_call_original
|
92
|
+
expect(vivid.exist?("nil")).to be true
|
93
|
+
end
|
94
|
+
|
95
|
+
it "false when attributes don't exist" do
|
96
|
+
expect(root).to receive(:top_level_breadcrumb=).with("one").and_call_original
|
97
|
+
expect(vivid.exist?("one", "five", "six")).to be false
|
98
|
+
end
|
99
|
+
|
100
|
+
it "false when traversing a non-container" do
|
101
|
+
expect(root).to receive(:top_level_breadcrumb=).with("one").and_call_original
|
102
|
+
expect(vivid.exist?("one", "two", "three", "four")).to be false
|
103
|
+
end
|
104
|
+
|
105
|
+
it "false when an array index does not exist" do
|
106
|
+
expect(root).to receive(:top_level_breadcrumb=).with("array").and_call_original
|
107
|
+
expect(vivid.exist?("array", 3)).to be false
|
108
|
+
end
|
109
|
+
|
110
|
+
it "false when traversing a nil" do
|
111
|
+
expect(root).to receive(:top_level_breadcrumb=).with("nil").and_call_original
|
112
|
+
expect(vivid.exist?("nil", "foo", "bar")).to be false
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "#read!" do
|
117
|
+
before do
|
118
|
+
# vivify the vividmash, then we're read-only so the cache should never be cleared afterwards
|
119
|
+
vivid
|
120
|
+
expect(root).not_to receive(:reset_cache)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "reads hashes deeply" do
|
124
|
+
expect(root).to receive(:top_level_breadcrumb=).with("one").and_call_original
|
125
|
+
expect(vivid.read!("one", "two", "three")).to eql("four")
|
126
|
+
end
|
127
|
+
|
128
|
+
it "reads arrays deeply" do
|
129
|
+
expect(root).to receive(:top_level_breadcrumb=).with("array").and_call_original
|
130
|
+
expect(vivid.read!("array", 1)).to eql(1)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "throws an exception when attributes do not exist" do
|
134
|
+
expect(root).to receive(:top_level_breadcrumb=).with("one").and_call_original
|
135
|
+
expect { vivid.read!("one", "five", "six") }.to raise_error(Chef::Exceptions::NoSuchAttribute)
|
136
|
+
end
|
137
|
+
|
138
|
+
it "throws an exception when traversing a non-container" do
|
139
|
+
expect(root).to receive(:top_level_breadcrumb=).with("one").and_call_original
|
140
|
+
expect { vivid.read!("one", "two", "three", "four") }.to raise_error(Chef::Exceptions::NoSuchAttribute)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "throws an exception when an array element does not exist" do
|
144
|
+
expect(root).to receive(:top_level_breadcrumb=).with("array").and_call_original
|
145
|
+
expect { vivid.read!("array", 3) }.to raise_error(Chef::Exceptions::NoSuchAttribute)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "#write" do
|
150
|
+
before do
|
151
|
+
vivid
|
152
|
+
expect(root).not_to receive(:reset_cache).with(nil)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should write into hashes" do
|
156
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("one")
|
157
|
+
vivid.write("one", "five", "six")
|
158
|
+
expect(vivid["one"]["five"]).to eql("six")
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should deeply autovivify" do
|
162
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("one")
|
163
|
+
vivid.write("one", "five", "six", "seven", "eight", "nine", "ten")
|
164
|
+
expect(vivid["one"]["five"]["six"]["seven"]["eight"]["nine"]).to eql("ten")
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should raise an exception if you overwrite an array with a hash" do
|
168
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("array")
|
169
|
+
vivid.write("array", "five", "six")
|
170
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => { "five" => "six" }, "nil" => nil })
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should raise an exception if you traverse through an array with a hash" do
|
174
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("array")
|
175
|
+
vivid.write("array", "five", "six", "seven")
|
176
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => { "five" => { "six" => "seven" } }, "nil" => nil })
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should raise an exception if you overwrite a string with a hash" do
|
180
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("one")
|
181
|
+
vivid.write("one", "two", "three", "four", "five")
|
182
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => { "four" => "five" } } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should raise an exception if you traverse through a string with a hash" do
|
186
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("one")
|
187
|
+
vivid.write("one", "two", "three", "four", "five", "six")
|
188
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => { "four" => { "five" => "six" } } } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should raise an exception if you overwrite a nil with a hash" do
|
192
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("nil")
|
193
|
+
vivid.write("nil", "one", "two")
|
194
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => { "one" => "two" } })
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should raise an exception if you traverse through a nil with a hash" do
|
198
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("nil")
|
199
|
+
vivid.write("nil", "one", "two", "three")
|
200
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => { "one" => { "two" => "three" } } })
|
201
|
+
end
|
202
|
+
|
203
|
+
it "writes with a block" do
|
204
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("one")
|
205
|
+
vivid.write("one", "five") { "six" }
|
206
|
+
expect(vivid["one"]["five"]).to eql("six")
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context "#write!" do
|
211
|
+
before do
|
212
|
+
vivid
|
213
|
+
expect(root).not_to receive(:reset_cache).with(nil)
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should write into hashes" do
|
217
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("one")
|
218
|
+
vivid.write!("one", "five", "six")
|
219
|
+
expect(vivid["one"]["five"]).to eql("six")
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should deeply autovivify" do
|
223
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("one")
|
224
|
+
vivid.write!("one", "five", "six", "seven", "eight", "nine", "ten")
|
225
|
+
expect(vivid["one"]["five"]["six"]["seven"]["eight"]["nine"]).to eql("ten")
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should raise an exception if you overwrite an array with a hash" do
|
229
|
+
expect(root).not_to receive(:reset_cache)
|
230
|
+
expect { vivid.write!("array", "five", "six") }.to raise_error(Chef::Exceptions::AttributeTypeMismatch)
|
231
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should raise an exception if you traverse through an array with a hash" do
|
235
|
+
expect(root).not_to receive(:reset_cache)
|
236
|
+
expect { vivid.write!("array", "five", "six", "seven") }.to raise_error(Chef::Exceptions::AttributeTypeMismatch)
|
237
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should raise an exception if you overwrite a string with a hash" do
|
241
|
+
expect(root).not_to receive(:reset_cache)
|
242
|
+
expect { vivid.write!("one", "two", "three", "four", "five") }.to raise_error(Chef::Exceptions::AttributeTypeMismatch)
|
243
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should raise an exception if you traverse through a string with a hash" do
|
247
|
+
expect(root).not_to receive(:reset_cache)
|
248
|
+
expect { vivid.write!("one", "two", "three", "four", "five", "six") }.to raise_error(Chef::Exceptions::AttributeTypeMismatch)
|
249
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
250
|
+
end
|
251
|
+
|
252
|
+
it "should raise an exception if you overwrite a nil with a hash" do
|
253
|
+
expect(root).not_to receive(:reset_cache)
|
254
|
+
expect { vivid.write!("nil", "one", "two") }.to raise_error(Chef::Exceptions::AttributeTypeMismatch)
|
255
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should raise an exception if you traverse through a nil with a hash" do
|
259
|
+
expect(root).not_to receive(:reset_cache)
|
260
|
+
expect { vivid.write!("nil", "one", "two", "three") }.to raise_error(Chef::Exceptions::AttributeTypeMismatch)
|
261
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
262
|
+
end
|
263
|
+
|
264
|
+
it "writes with a block" do
|
265
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("one")
|
266
|
+
vivid.write!("one", "five") { "six" }
|
267
|
+
expect(vivid["one"]["five"]).to eql("six")
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
context "#unlink" do
|
272
|
+
before do
|
273
|
+
vivid
|
274
|
+
expect(root).not_to receive(:reset_cache).with(nil)
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should return nil if the keys already don't exist" do
|
278
|
+
expect(root).not_to receive(:reset_cache)
|
279
|
+
expect(vivid.unlink("five", "six", "seven", "eight")).to eql(nil)
|
280
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should unlink hashes" do
|
284
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("one")
|
285
|
+
expect( vivid.unlink("one") ).to eql({ "two" => { "three" => "four" } })
|
286
|
+
expect(vivid).to eql({ "array" => [ 0, 1, 2 ], "nil" => nil })
|
287
|
+
end
|
288
|
+
|
289
|
+
it "should unlink array elements" do
|
290
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("array")
|
291
|
+
expect(vivid.unlink("array", 2)).to eql(2)
|
292
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1 ], "nil" => nil })
|
293
|
+
end
|
294
|
+
|
295
|
+
it "should unlink nil" do
|
296
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("nil")
|
297
|
+
expect(vivid.unlink("nil")).to eql(nil)
|
298
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ] })
|
299
|
+
end
|
300
|
+
|
301
|
+
it "should traverse a nil and safely do nothing" do
|
302
|
+
expect(root).not_to receive(:reset_cache)
|
303
|
+
expect(vivid.unlink("nil", "foo")).to eql(nil)
|
304
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
context "#unlink!" do
|
309
|
+
before do
|
310
|
+
vivid
|
311
|
+
expect(root).not_to receive(:reset_cache).with(nil)
|
312
|
+
end
|
313
|
+
|
314
|
+
it "should raise an exception if the keys already don't exist" do
|
315
|
+
expect(root).not_to receive(:reset_cache)
|
316
|
+
expect { vivid.unlink!("five", "six", "seven", "eight") }.to raise_error(Chef::Exceptions::NoSuchAttribute)
|
317
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
318
|
+
end
|
319
|
+
|
320
|
+
it "should unlink! hashes" do
|
321
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("one")
|
322
|
+
expect( vivid.unlink!("one") ).to eql({ "two" => { "three" => "four" } })
|
323
|
+
expect(vivid).to eql({ "array" => [ 0, 1, 2 ], "nil" => nil })
|
324
|
+
end
|
325
|
+
|
326
|
+
it "should unlink! array elements" do
|
327
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("array")
|
328
|
+
expect(vivid.unlink!("array", 2)).to eql(2)
|
329
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1 ], "nil" => nil })
|
330
|
+
end
|
331
|
+
|
332
|
+
it "should unlink! nil" do
|
333
|
+
expect(root).to receive(:reset_cache).at_least(:once).with("nil")
|
334
|
+
expect(vivid.unlink!("nil")).to eql(nil)
|
335
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ] })
|
336
|
+
end
|
337
|
+
|
338
|
+
it "should raise an exception if it traverses a nil" do
|
339
|
+
expect(root).not_to receive(:reset_cache)
|
340
|
+
expect { vivid.unlink!("nil", "foo") }.to raise_error(Chef::Exceptions::NoSuchAttribute)
|
341
|
+
expect(vivid).to eql({ "one" => { "two" => { "three" => "four" } }, "array" => [ 0, 1, 2 ], "nil" => nil })
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|