chef 12.0.0.rc.0-x86-mingw32 → 12.0.0-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +1 -1
- data/lib/chef/api_client/registration.rb +3 -1
- data/lib/chef/chef_fs/data_handler/group_data_handler.rb +4 -0
- data/lib/chef/config.rb +46 -38
- data/lib/chef/event_loggers/windows_eventlog.rb +5 -6
- data/lib/chef/exceptions.rb +13 -1
- data/lib/chef/file_content_management/tempfile.rb +33 -5
- data/lib/chef/knife.rb +11 -3
- data/lib/chef/knife/bootstrap.rb +8 -7
- data/lib/chef/mixin/deep_merge.rb +15 -54
- data/lib/chef/mixin/which.rb +37 -0
- data/lib/chef/node.rb +14 -25
- data/lib/chef/node/attribute.rb +227 -41
- data/lib/chef/node/attribute_collections.rb +117 -3
- data/lib/chef/node/immutable_collections.rb +6 -6
- data/lib/chef/platform/provider_priority_map.rb +3 -2
- data/lib/chef/platform/service_helpers.rb +37 -8
- data/lib/chef/provider/service/aixinit.rb +1 -1
- data/lib/chef/provider/service/arch.rb +1 -1
- data/lib/chef/provider/service/debian.rb +5 -1
- data/lib/chef/provider/service/init.rb +4 -0
- data/lib/chef/provider/service/insserv.rb +5 -1
- data/lib/chef/provider/service/invokercd.rb +5 -1
- data/lib/chef/provider/service/redhat.rb +5 -1
- data/lib/chef/provider/service/systemd.rb +50 -32
- data/lib/chef/provider/service/upstart.rb +5 -2
- data/lib/chef/provider_resolver.rb +30 -16
- data/lib/chef/resource.rb +2 -1
- data/lib/chef/resources.rb +7 -0
- data/lib/chef/run_context.rb +0 -5
- data/lib/chef/run_list/run_list_expansion.rb +2 -2
- data/lib/chef/shell.rb +2 -2
- data/lib/chef/util/selinux.rb +2 -10
- data/lib/chef/version.rb +1 -1
- data/lib/chef/workstation_config_loader.rb +1 -1
- data/spec/support/shared/unit/resource/static_provider_resolution.rb +1 -6
- data/spec/unit/api_client/registration_spec.rb +22 -0
- data/spec/unit/application/knife_spec.rb +6 -2
- data/spec/unit/chef_fs/data_handler/group_handler_spec.rb +63 -0
- data/spec/unit/config_spec.rb +5 -5
- data/spec/unit/knife/bootstrap_spec.rb +27 -1
- data/spec/unit/knife_spec.rb +5 -0
- data/spec/unit/mixin/deep_merge_spec.rb +0 -40
- data/spec/unit/node/attribute_spec.rb +37 -50
- data/spec/unit/node_spec.rb +321 -13
- data/spec/unit/provider/file/content_spec.rb +23 -2
- data/spec/unit/provider/service/systemd_service_spec.rb +173 -158
- data/spec/unit/provider_resolver_spec.rb +175 -10
- data/spec/unit/resource/timestamped_deploy_spec.rb +8 -29
- data/spec/unit/runner_spec.rb +3 -1
- metadata +147 -221
- data/spec/.DS_Store +0 -0
- data/spec/data/.DS_Store +0 -0
- data/spec/data/lwrp/.DS_Store +0 -0
- data/spec/data/lwrp/providers/.DS_Store +0 -0
- data/spec/data/lwrp/resources/.DS_Store +0 -0
- data/spec/data/lwrp_override/.DS_Store +0 -0
- data/spec/data/lwrp_override/providers/.DS_Store +0 -0
- data/spec/data/lwrp_override/resources/.DS_Store +0 -0
data/spec/unit/knife_spec.rb
CHANGED
@@ -44,6 +44,10 @@ describe Chef::Knife do
|
|
44
44
|
@stderr = StringIO.new
|
45
45
|
end
|
46
46
|
|
47
|
+
after(:each) do
|
48
|
+
Chef::Knife.reset_config_loader!
|
49
|
+
end
|
50
|
+
|
47
51
|
describe "after loading a subcommand" do
|
48
52
|
before do
|
49
53
|
Chef::Knife.reset_subcommands!
|
@@ -268,6 +272,7 @@ describe Chef::Knife do
|
|
268
272
|
@knife.config[:verbosity] = 1
|
269
273
|
@knife.config[:config_file] = fake_config
|
270
274
|
config_loader = double("Chef::WorkstationConfigLoader", :load => true, :no_config_found? => false, :chef_config_dir => "/etc/chef", :config_location => fake_config)
|
275
|
+
allow(config_loader).to receive(:explicit_config_file=).with(fake_config).and_return(fake_config)
|
271
276
|
allow(Chef::WorkstationConfigLoader).to receive(:new).and_return(config_loader)
|
272
277
|
end
|
273
278
|
|
@@ -236,20 +236,6 @@ describe Chef::Mixin::DeepMerge, "deep_merge!" do
|
|
236
236
|
@dm.deep_merge!(hash_src, hash_dst)
|
237
237
|
hash_dst.should == {"item" => "orange"}
|
238
238
|
end
|
239
|
-
|
240
|
-
it 'should overwrite hashes with nil' do
|
241
|
-
hash_src = {"item" => { "1" => "2"}, "other" => true }
|
242
|
-
hash_dst = {"item" => nil }
|
243
|
-
@dm.deep_merge!(hash_src, hash_dst)
|
244
|
-
hash_dst.should == {"item" => nil, "other" => true }
|
245
|
-
end
|
246
|
-
|
247
|
-
it 'should overwrite strings with nil' do
|
248
|
-
hash_src = {"item" => "to_overwrite", "other" => false }
|
249
|
-
hash_dst = {"item" => nil }
|
250
|
-
@dm.deep_merge!(hash_src, hash_dst)
|
251
|
-
hash_dst.should == {"item" => nil, "other" => false }
|
252
|
-
end
|
253
239
|
end # deep_merge!
|
254
240
|
|
255
241
|
# Chef specific
|
@@ -304,32 +290,6 @@ describe Chef::Mixin::DeepMerge do
|
|
304
290
|
|
305
291
|
end
|
306
292
|
|
307
|
-
describe "role_merge" do
|
308
|
-
it "errors out if knockout merge use is detected in an array" do
|
309
|
-
hash_dst = {"property" => ["2","4"]}
|
310
|
-
hash_src = {"property" => ["1","!merge:4"]}
|
311
|
-
lambda {@dm.role_merge(hash_dst, hash_src)}.should raise_error(Chef::Mixin::DeepMerge::InvalidSubtractiveMerge)
|
312
|
-
end
|
313
|
-
|
314
|
-
it "errors out if knockout merge use is detected in an array (reversed merge order)" do
|
315
|
-
hash_dst = {"property" => ["1","!merge:4"]}
|
316
|
-
hash_src = {"property" => ["2","4"]}
|
317
|
-
lambda {@dm.role_merge(hash_dst, hash_src)}.should raise_error(Chef::Mixin::DeepMerge::InvalidSubtractiveMerge)
|
318
|
-
end
|
319
|
-
|
320
|
-
it "errors out if knockout merge use is detected in a string" do
|
321
|
-
hash_dst = {"property" => ["2","4"]}
|
322
|
-
hash_src = {"property" => "!merge"}
|
323
|
-
lambda {@dm.role_merge(hash_dst, hash_src)}.should raise_error(Chef::Mixin::DeepMerge::InvalidSubtractiveMerge)
|
324
|
-
end
|
325
|
-
|
326
|
-
it "errors out if knockout merge use is detected in a string (reversed merge order)" do
|
327
|
-
hash_dst = {"property" => "!merge"}
|
328
|
-
hash_src= {"property" => ["2","4"]}
|
329
|
-
lambda {@dm.role_merge(hash_dst, hash_src)}.should raise_error(Chef::Mixin::DeepMerge::InvalidSubtractiveMerge)
|
330
|
-
end
|
331
|
-
end
|
332
|
-
|
333
293
|
describe "hash-only merging" do
|
334
294
|
it "merges Hashes like normal deep merge" do
|
335
295
|
merge_ee_hash = {"top_level_a" => {"1_deep_a" => "1-a-merge-ee", "1_deep_b" => "1-deep-b-merge-ee"}, "top_level_b" => "top-level-b-merge-ee"}
|
@@ -285,7 +285,7 @@ describe Chef::Node::Attribute do
|
|
285
285
|
end
|
286
286
|
|
287
287
|
it "prefers 'forced default' over any other default" do
|
288
|
-
@attributes.
|
288
|
+
@attributes.force_default["default"] = "force default"
|
289
289
|
@attributes.role_default["default"] = "role default"
|
290
290
|
@attributes.env_default["default"] = "environment default"
|
291
291
|
@attributes["default"].should == "force default"
|
@@ -307,7 +307,7 @@ describe Chef::Node::Attribute do
|
|
307
307
|
end
|
308
308
|
|
309
309
|
it "prefers 'forced overrides' over role or cookbook overrides" do
|
310
|
-
@attributes.
|
310
|
+
@attributes.force_override["override"] = "force override"
|
311
311
|
@attributes.env_override["override"] = "environment override"
|
312
312
|
@attributes.role_override["override"] = "role override"
|
313
313
|
@attributes["override"].should == "force override"
|
@@ -554,8 +554,7 @@ describe Chef::Node::Attribute do
|
|
554
554
|
|
555
555
|
it "should allow the last method to set a value if it has an = sign on the end" do
|
556
556
|
@attributes.normal.music.mastodon = [ "dream", "still", "shining" ]
|
557
|
-
@attributes.
|
558
|
-
@attributes.normal.music.mastodon.should == [ "dream", "still", "shining" ]
|
557
|
+
expect(@attributes.normal.music.mastodon).to eq([ "dream", "still", "shining" ])
|
559
558
|
end
|
560
559
|
end
|
561
560
|
|
@@ -939,7 +938,6 @@ describe Chef::Node::Attribute do
|
|
939
938
|
|
940
939
|
end
|
941
940
|
|
942
|
-
|
943
941
|
describe "values" do
|
944
942
|
before do
|
945
943
|
@attributes = Chef::Node::Attribute.new(
|
@@ -1092,50 +1090,6 @@ describe Chef::Node::Attribute do
|
|
1092
1090
|
end
|
1093
1091
|
end
|
1094
1092
|
|
1095
|
-
# For expedience, this test is implementation-heavy.
|
1096
|
-
describe "when a component attribute is mutated" do
|
1097
|
-
[
|
1098
|
-
:clear,
|
1099
|
-
:shift
|
1100
|
-
].each do |mutator|
|
1101
|
-
it "resets the cache when the mutator #{mutator} is called" do
|
1102
|
-
@attributes.should_receive(:reset_cache)
|
1103
|
-
@attributes.default.send(mutator)
|
1104
|
-
end
|
1105
|
-
end
|
1106
|
-
|
1107
|
-
it "resets the cache when the mutator delete is called" do
|
1108
|
-
@attributes.should_receive(:reset_cache)
|
1109
|
-
@attributes.default.delete(:music)
|
1110
|
-
end
|
1111
|
-
|
1112
|
-
[
|
1113
|
-
:merge!,
|
1114
|
-
:update,
|
1115
|
-
:replace
|
1116
|
-
].each do |mutator|
|
1117
|
-
it "resets the cache when the mutator #{mutator} is called" do
|
1118
|
-
# Implementation of Mash means that this could get called many times. That's okay.
|
1119
|
-
@attributes.should_receive(:reset_cache).at_least(1).times
|
1120
|
-
@attributes.default.send(mutator, {:foo => :bar})
|
1121
|
-
end
|
1122
|
-
end
|
1123
|
-
|
1124
|
-
[
|
1125
|
-
:delete_if,
|
1126
|
-
:keep_if,
|
1127
|
-
:reject!,
|
1128
|
-
:select!,
|
1129
|
-
].each do |mutator|
|
1130
|
-
it "resets the cache when the mutator #{mutator} is called" do
|
1131
|
-
# Implementation of Mash means that this could get called many times. That's okay.
|
1132
|
-
@attributes.should_receive(:reset_cache).at_least(1).times
|
1133
|
-
block = lambda {|k,v| true }
|
1134
|
-
@attributes.default.send(mutator, &block)
|
1135
|
-
end
|
1136
|
-
end
|
1137
|
-
end
|
1138
|
-
|
1139
1093
|
describe "when not mutated" do
|
1140
1094
|
|
1141
1095
|
it "does not reset the cache when dup'd [CHEF-3680]" do
|
@@ -1173,6 +1127,40 @@ describe Chef::Node::Attribute do
|
|
1173
1127
|
end
|
1174
1128
|
end
|
1175
1129
|
|
1130
|
+
describe "when deep-merging between precedence levels" do
|
1131
|
+
it "correctly deep merges hashes and preserves the original contents" do
|
1132
|
+
@attributes.default = { "arglebargle" => { "foo" => "bar" } }
|
1133
|
+
@attributes.override = { "arglebargle" => { "fizz" => "buzz" } }
|
1134
|
+
expect(@attributes.merged_attributes[:arglebargle]).to eq({ "foo" => "bar", "fizz" => "buzz" })
|
1135
|
+
expect(@attributes.default[:arglebargle]).to eq({ "foo" => "bar" })
|
1136
|
+
expect(@attributes.override[:arglebargle]).to eq({ "fizz" => "buzz" })
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
it "does not deep merge arrays, and preserves the original contents" do
|
1140
|
+
@attributes.default = { "arglebargle" => [ 1, 2, 3 ] }
|
1141
|
+
@attributes.override = { "arglebargle" => [ 4, 5, 6 ] }
|
1142
|
+
expect(@attributes.merged_attributes[:arglebargle]).to eq([ 4, 5, 6 ])
|
1143
|
+
expect(@attributes.default[:arglebargle]).to eq([ 1, 2, 3 ])
|
1144
|
+
expect(@attributes.override[:arglebargle]).to eq([ 4, 5, 6 ])
|
1145
|
+
end
|
1146
|
+
|
1147
|
+
it "correctly deep merges hashes and preserves the original contents when merging default and role_default" do
|
1148
|
+
@attributes.default = { "arglebargle" => { "foo" => "bar" } }
|
1149
|
+
@attributes.role_default = { "arglebargle" => { "fizz" => "buzz" } }
|
1150
|
+
expect(@attributes.merged_attributes[:arglebargle]).to eq({ "foo" => "bar", "fizz" => "buzz" })
|
1151
|
+
expect(@attributes.default[:arglebargle]).to eq({ "foo" => "bar" })
|
1152
|
+
expect(@attributes.role_default[:arglebargle]).to eq({ "fizz" => "buzz" })
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
it "correctly deep merges arrays, and preserves the original contents when merging default and role_default" do
|
1156
|
+
@attributes.default = { "arglebargle" => [ 1, 2, 3 ] }
|
1157
|
+
@attributes.role_default = { "arglebargle" => [ 4, 5, 6 ] }
|
1158
|
+
expect(@attributes.merged_attributes[:arglebargle]).to eq([ 1, 2, 3, 4, 5, 6 ])
|
1159
|
+
expect(@attributes.default[:arglebargle]).to eq([ 1, 2, 3 ])
|
1160
|
+
expect(@attributes.role_default[:arglebargle]).to eq([ 4, 5, 6 ])
|
1161
|
+
end
|
1162
|
+
end
|
1163
|
+
|
1176
1164
|
describe "when attemping to write without specifying precedence" do
|
1177
1165
|
it "raises an error when using []=" do
|
1178
1166
|
lambda { @attributes[:new_key] = "new value" }.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
|
@@ -1185,4 +1173,3 @@ describe Chef::Node::Attribute do
|
|
1185
1173
|
end
|
1186
1174
|
|
1187
1175
|
end
|
1188
|
-
|
data/spec/unit/node_spec.rb
CHANGED
@@ -247,13 +247,6 @@ describe Chef::Node do
|
|
247
247
|
node.default.fuu.bahrr.baz = "qux"
|
248
248
|
node.fuu.bahrr.baz.should == "qux"
|
249
249
|
end
|
250
|
-
|
251
|
-
it "accesses force defaults via default!" do
|
252
|
-
node.default![:foo] = "wet bar"
|
253
|
-
node.default[:foo] = "bar"
|
254
|
-
node[:foo].should == "wet bar"
|
255
|
-
end
|
256
|
-
|
257
250
|
end
|
258
251
|
|
259
252
|
describe "override attributes" do
|
@@ -292,13 +285,330 @@ describe Chef::Node do
|
|
292
285
|
node.override.fuu.bahrr.baz = "qux"
|
293
286
|
node.fuu.bahrr.baz.should == "qux"
|
294
287
|
end
|
288
|
+
end
|
289
|
+
|
290
|
+
describe "globally deleting attributes" do
|
291
|
+
context "with hash values" do
|
292
|
+
before do
|
293
|
+
node.role_default["mysql"]["server"]["port"] = 1234
|
294
|
+
node.normal["mysql"]["server"]["port"] = 2345
|
295
|
+
node.override["mysql"]["server"]["port"] = 3456
|
296
|
+
end
|
297
|
+
|
298
|
+
it "deletes all the values and returns the value with the highest precidence" do
|
299
|
+
expect( node.rm("mysql", "server", "port") ).to eql(3456)
|
300
|
+
expect( node["mysql"]["server"]["port"] ).to be_nil
|
301
|
+
expect( node["mysql"]["server"] ).to eql({})
|
302
|
+
end
|
303
|
+
|
304
|
+
it "deletes nested things correctly" do
|
305
|
+
node.default["mysql"]["client"]["client_setting"] = "foo"
|
306
|
+
expect( node.rm("mysql", "server") ).to eql( {"port" => 3456} )
|
307
|
+
expect( node["mysql"] ).to eql( { "client" => { "client_setting" => "foo" } } )
|
308
|
+
end
|
309
|
+
|
310
|
+
it "returns nil if the node attribute does not exist" do
|
311
|
+
expect( node.rm("no", "such", "thing") ).to be_nil
|
312
|
+
end
|
295
313
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
node[:foo].should == "wet bar"
|
314
|
+
it "can delete the entire tree" do
|
315
|
+
expect( node.rm("mysql") ).to eql({"server"=>{"port"=>3456}})
|
316
|
+
end
|
300
317
|
end
|
301
318
|
|
319
|
+
context "when trying to delete through a thing that isn't an array-like or hash-like object" do
|
320
|
+
before do
|
321
|
+
node.default["mysql"] = true
|
322
|
+
end
|
323
|
+
|
324
|
+
it "returns nil when you're two levels deeper" do
|
325
|
+
expect( node.rm("mysql", "server", "port") ).to eql(nil)
|
326
|
+
end
|
327
|
+
|
328
|
+
it "returns nil when you're one level deeper" do
|
329
|
+
expect( node.rm("mysql", "server") ).to eql(nil)
|
330
|
+
end
|
331
|
+
|
332
|
+
it "correctly deletes at the top level" do
|
333
|
+
expect( node.rm("mysql") ).to eql(true)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
context "with array indexes" do
|
338
|
+
before do
|
339
|
+
node.role_default["mysql"]["server"][0]["port"] = 1234
|
340
|
+
node.normal["mysql"]["server"][0]["port"] = 2345
|
341
|
+
node.override["mysql"]["server"][0]["port"] = 3456
|
342
|
+
node.override["mysql"]["server"][1]["port"] = 3456
|
343
|
+
end
|
344
|
+
|
345
|
+
it "deletes the array element" do
|
346
|
+
expect( node.rm("mysql", "server", 0, "port") ).to eql(3456)
|
347
|
+
expect( node["mysql"]["server"][0]["port"] ).to be_nil
|
348
|
+
expect( node["mysql"]["server"][1]["port"] ).to eql(3456)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
context "with real arrays" do
|
353
|
+
before do
|
354
|
+
node.role_default["mysql"]["server"] = [ {
|
355
|
+
"port" => 1234,
|
356
|
+
} ]
|
357
|
+
node.normal["mysql"]["server"] = [ {
|
358
|
+
"port" => 2345,
|
359
|
+
} ]
|
360
|
+
node.override["mysql"]["server"] = [ {
|
361
|
+
"port" => 3456,
|
362
|
+
} ]
|
363
|
+
end
|
364
|
+
|
365
|
+
it "deletes the array element" do
|
366
|
+
expect( node.rm("mysql", "server", 0, "port") ).to eql(3456)
|
367
|
+
expect( node["mysql"]["server"][0]["port"] ).to be_nil
|
368
|
+
end
|
369
|
+
|
370
|
+
it "does not have a horrible error message when mistaking arrays for hashes" do
|
371
|
+
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?)")
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
describe "granular deleting attributes" do
|
377
|
+
context "when only defaults exist" do
|
378
|
+
before do
|
379
|
+
node.role_default["mysql"]["server"]["port"] = 1234
|
380
|
+
node.default["mysql"]["server"]["port"] = 2345
|
381
|
+
node.force_default["mysql"]["server"]["port"] = 3456
|
382
|
+
end
|
383
|
+
|
384
|
+
it "returns the deleted values" do
|
385
|
+
expect( node.rm_default("mysql", "server", "port") ).to eql(3456)
|
386
|
+
end
|
387
|
+
|
388
|
+
it "returns nil for the combined attribues" do
|
389
|
+
expect( node.rm_default("mysql", "server", "port") ).to eql(3456)
|
390
|
+
expect( node["mysql"]["server"]["port"] ).to eql(nil)
|
391
|
+
end
|
392
|
+
|
393
|
+
it "returns an empty hash for the default attrs" do
|
394
|
+
expect( node.rm_default("mysql", "server", "port") ).to eql(3456)
|
395
|
+
# this auto-vivifies, should it?
|
396
|
+
expect( node.default_attrs["mysql"]["server"]["port"] ).to eql({})
|
397
|
+
end
|
398
|
+
|
399
|
+
it "returns an empty hash after the last key is deleted" do
|
400
|
+
expect( node.rm_default("mysql", "server", "port") ).to eql(3456)
|
401
|
+
expect( node["mysql"]["server"] ).to eql({})
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
context "when trying to delete through a thing that isn't an array-like or hash-like object" do
|
406
|
+
before do
|
407
|
+
node.default["mysql"] = true
|
408
|
+
end
|
409
|
+
|
410
|
+
it "returns nil when you're two levels deeper" do
|
411
|
+
expect( node.rm_default("mysql", "server", "port") ).to eql(nil)
|
412
|
+
end
|
413
|
+
|
414
|
+
it "returns nil when you're one level deeper" do
|
415
|
+
expect( node.rm_default("mysql", "server") ).to eql(nil)
|
416
|
+
end
|
417
|
+
|
418
|
+
it "correctly deletes at the top level" do
|
419
|
+
expect( node.rm_default("mysql") ).to eql(true)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
context "when a higher precedence exists" do
|
424
|
+
before do
|
425
|
+
node.role_default["mysql"]["server"]["port"] = 1234
|
426
|
+
node.default["mysql"]["server"]["port"] = 2345
|
427
|
+
node.force_default["mysql"]["server"]["port"] = 3456
|
428
|
+
|
429
|
+
node.override["mysql"]["server"]["port"] = 9999
|
430
|
+
end
|
431
|
+
|
432
|
+
it "returns the deleted values" do
|
433
|
+
expect( node.rm_default("mysql", "server", "port") ).to eql(3456)
|
434
|
+
end
|
435
|
+
|
436
|
+
it "returns the higher precedence values after the delete" do
|
437
|
+
expect( node.rm_default("mysql", "server", "port") ).to eql(3456)
|
438
|
+
expect( node["mysql"]["server"]["port"] ).to eql(9999)
|
439
|
+
end
|
440
|
+
|
441
|
+
it "returns an empty has for the default attrs" do
|
442
|
+
expect( node.rm_default("mysql", "server", "port") ).to eql(3456)
|
443
|
+
# this auto-vivifies, should it?
|
444
|
+
expect( node.default_attrs["mysql"]["server"]["port"] ).to eql({})
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
context "when a lower precedence exists" do
|
449
|
+
before do
|
450
|
+
node.default["mysql"]["server"]["port"] = 2345
|
451
|
+
node.override["mysql"]["server"]["port"] = 9999
|
452
|
+
node.role_override["mysql"]["server"]["port"] = 9876
|
453
|
+
node.force_override["mysql"]["server"]["port"] = 6669
|
454
|
+
end
|
455
|
+
|
456
|
+
it "returns the deleted values" do
|
457
|
+
expect( node.rm_override("mysql", "server", "port") ).to eql(6669)
|
458
|
+
end
|
459
|
+
|
460
|
+
it "returns the lower precedence levels after the delete" do
|
461
|
+
expect( node.rm_override("mysql", "server", "port") ).to eql(6669)
|
462
|
+
expect( node["mysql"]["server"]["port"] ).to eql(2345)
|
463
|
+
end
|
464
|
+
|
465
|
+
it "returns an empty has for the override attrs" do
|
466
|
+
expect( node.rm_override("mysql", "server", "port") ).to eql(6669)
|
467
|
+
# this auto-vivifies, should it?
|
468
|
+
expect( node.override_attrs["mysql"]["server"]["port"] ).to eql({})
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
it "rm_default returns nil on deleting non-existent values" do
|
473
|
+
expect( node.rm_default("no", "such", "thing") ).to be_nil
|
474
|
+
end
|
475
|
+
|
476
|
+
it "rm_normal returns nil on deleting non-existent values" do
|
477
|
+
expect( node.rm_normal("no", "such", "thing") ).to be_nil
|
478
|
+
end
|
479
|
+
|
480
|
+
it "rm_override returns nil on deleting non-existent values" do
|
481
|
+
expect( node.rm_override("no", "such", "thing") ).to be_nil
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
describe "granular replacing attributes" do
|
486
|
+
it "removes everything at the level of the last key" do
|
487
|
+
node.default["mysql"]["server"]["port"] = 2345
|
488
|
+
|
489
|
+
node.default!["mysql"]["server"] = { "data_dir" => "/my_raid_volume/lib/mysql" }
|
490
|
+
|
491
|
+
expect( node["mysql"]["server"] ).to eql({ "data_dir" => "/my_raid_volume/lib/mysql" })
|
492
|
+
end
|
493
|
+
|
494
|
+
it "replaces a value at the cookbook sub-level of the atributes only" do
|
495
|
+
node.default["mysql"]["server"]["port"] = 2345
|
496
|
+
node.default["mysql"]["server"]["service_name"] = "fancypants-sql"
|
497
|
+
node.role_default["mysql"]["server"]["port"] = 1234
|
498
|
+
node.force_default["mysql"]["server"]["port"] = 3456
|
499
|
+
|
500
|
+
node.default!["mysql"]["server"] = { "data_dir" => "/my_raid_volume/lib/mysql" }
|
501
|
+
|
502
|
+
expect( node["mysql"]["server"]["port"] ).to eql(3456)
|
503
|
+
expect( node["mysql"]["server"]["service_name"] ).to be_nil
|
504
|
+
expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql")
|
505
|
+
expect( node["mysql"]["server"] ).to eql({ "port" => 3456, "data_dir" => "/my_raid_volume/lib/mysql" })
|
506
|
+
end
|
507
|
+
|
508
|
+
it "higher precedence values aren't removed" do
|
509
|
+
node.role_default["mysql"]["server"]["port"] = 1234
|
510
|
+
node.default["mysql"]["server"]["port"] = 2345
|
511
|
+
node.force_default["mysql"]["server"]["port"] = 3456
|
512
|
+
node.override["mysql"]["server"]["service_name"] = "fancypants-sql"
|
513
|
+
|
514
|
+
node.default!["mysql"]["server"] = { "data_dir" => "/my_raid_volume/lib/mysql" }
|
515
|
+
|
516
|
+
expect( node["mysql"]["server"]["port"] ).to eql(3456)
|
517
|
+
expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql")
|
518
|
+
expect( node["mysql"]["server"] ).to eql({ "service_name" => "fancypants-sql", "port" => 3456, "data_dir" => "/my_raid_volume/lib/mysql" })
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
describe "granular force replacing attributes" do
|
523
|
+
it "removes everything at the level of the last key" do
|
524
|
+
node.force_default["mysql"]["server"]["port"] = 2345
|
525
|
+
|
526
|
+
node.force_default!["mysql"]["server"] = {
|
527
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
528
|
+
}
|
529
|
+
|
530
|
+
expect( node["mysql"]["server"] ).to eql({
|
531
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
532
|
+
})
|
533
|
+
end
|
534
|
+
|
535
|
+
it "removes all values from the precedence level when setting" do
|
536
|
+
node.role_default["mysql"]["server"]["port"] = 1234
|
537
|
+
node.default["mysql"]["server"]["port"] = 2345
|
538
|
+
node.force_default["mysql"]["server"]["port"] = 3456
|
539
|
+
|
540
|
+
node.force_default!["mysql"]["server"] = {
|
541
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
542
|
+
}
|
543
|
+
|
544
|
+
expect( node["mysql"]["server"]["port"] ).to be_nil
|
545
|
+
expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql")
|
546
|
+
expect( node["mysql"]["server"] ).to eql({
|
547
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
548
|
+
})
|
549
|
+
end
|
550
|
+
|
551
|
+
it "higher precedence levels are not removed" do
|
552
|
+
node.role_default["mysql"]["server"]["port"] = 1234
|
553
|
+
node.default["mysql"]["server"]["port"] = 2345
|
554
|
+
node.force_default["mysql"]["server"]["port"] = 3456
|
555
|
+
node.override["mysql"]["server"]["service_name"] = "fancypants-sql"
|
556
|
+
|
557
|
+
node.force_default!["mysql"]["server"] = {
|
558
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
559
|
+
}
|
560
|
+
|
561
|
+
expect( node["mysql"]["server"]["port"] ).to be_nil
|
562
|
+
expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql")
|
563
|
+
expect( node["mysql"]["server"] ).to eql({
|
564
|
+
"service_name" => "fancypants-sql",
|
565
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
566
|
+
})
|
567
|
+
end
|
568
|
+
|
569
|
+
it "will autovivify" do
|
570
|
+
node.force_default!["mysql"]["server"] = {
|
571
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
572
|
+
}
|
573
|
+
expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql")
|
574
|
+
end
|
575
|
+
|
576
|
+
it "lower precedence levels aren't removed" do
|
577
|
+
node.role_override["mysql"]["server"]["port"] = 1234
|
578
|
+
node.override["mysql"]["server"]["port"] = 2345
|
579
|
+
node.force_override["mysql"]["server"]["port"] = 3456
|
580
|
+
node.default["mysql"]["server"]["service_name"] = "fancypants-sql"
|
581
|
+
|
582
|
+
node.force_override!["mysql"]["server"] = {
|
583
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
584
|
+
}
|
585
|
+
|
586
|
+
expect( node["mysql"]["server"]["port"] ).to be_nil
|
587
|
+
expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql")
|
588
|
+
expect( node["mysql"]["server"] ).to eql({
|
589
|
+
"service_name" => "fancypants-sql",
|
590
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
591
|
+
})
|
592
|
+
end
|
593
|
+
|
594
|
+
it "when overwriting a non-hash/array" do
|
595
|
+
node.override["mysql"] = false
|
596
|
+
node.force_override["mysql"] = true
|
597
|
+
node.force_override!["mysql"]["server"] = {
|
598
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
599
|
+
}
|
600
|
+
expect( node["mysql"]["server"]["data_dir"] ).to eql("/my_raid_volume/lib/mysql")
|
601
|
+
end
|
602
|
+
|
603
|
+
it "when overwriting an array with a hash" do
|
604
|
+
node.force_override["mysql"][0] = true
|
605
|
+
node.force_override!["mysql"]["server"] = {
|
606
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
607
|
+
}
|
608
|
+
expect( node["mysql"]["server"] ).to eql({
|
609
|
+
"data_dir" => "/my_raid_volume/lib/mysql",
|
610
|
+
})
|
611
|
+
end
|
302
612
|
end
|
303
613
|
|
304
614
|
it "should raise an ArgumentError if you ask for an attribute that doesn't exist via method_missing" do
|
@@ -536,7 +846,6 @@ describe Chef::Node do
|
|
536
846
|
@expansion.default_attrs.replace({:default => "from role", :d_role => "role only"})
|
537
847
|
@expansion.override_attrs.replace({:override => "from role", :o_role => "role only"})
|
538
848
|
|
539
|
-
|
540
849
|
@environment = Chef::Environment.new
|
541
850
|
@environment.default_attributes = {:default => "from env", :d_env => "env only" }
|
542
851
|
@environment.override_attributes = {:override => "from env", :o_env => "env only"}
|
@@ -753,7 +1062,6 @@ describe Chef::Node do
|
|
753
1062
|
node_for_json["default"]["env default"].should == "env default"
|
754
1063
|
end
|
755
1064
|
|
756
|
-
|
757
1065
|
it "should deserialize itself from json", :json => true do
|
758
1066
|
node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA))
|
759
1067
|
json = Chef::JSONCompat.to_json(node)
|