chef 12.11.18-universal-mingw32 → 12.12.13-universal-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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
|