summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2015-01-14 10:51:32 -0800
committerLamont Granquist <lamont@scriptkiddie.org>2015-01-14 10:51:32 -0800
commitd724763623b9593f61e2df083e576d1ed8406aae (patch)
tree4e9c1d9b44085a86efc1b352c78eff406acecc2a
parent7b93aaea8ecb14bdc619d443bd81927a9faf5a1f (diff)
downloadchef-d724763623b9593f61e2df083e576d1ed8406aae.tar.gz
deep_merge_cache fixes for bugs in 12.0.0
In 12.0.0 we introduced a cache for the merged attributes for the top-level node attribute keys. This fixes this so that node['foo'] and node[:foo] are not cached separately. This also showed up in bugs as issues between node['foo'] access and node.foo access because node.foo is translated into node[:foo].
-rw-r--r--lib/chef/node/attribute.rb8
-rw-r--r--spec/unit/node_spec.rb31
2 files changed, 35 insertions, 4 deletions
diff --git a/lib/chef/node/attribute.rb b/lib/chef/node/attribute.rb
index 3c48f653eb..80f5ac4f8d 100644
--- a/lib/chef/node/attribute.rb
+++ b/lib/chef/node/attribute.rb
@@ -253,7 +253,7 @@ class Chef
if path.nil?
@deep_merge_cache = {}
else
- deep_merge_cache.delete(path)
+ deep_merge_cache.delete(path.to_s)
end
end
@@ -436,12 +436,12 @@ class Chef
end
def [](key)
- if deep_merge_cache.has_key?(key)
+ if deep_merge_cache.has_key?(key.to_s)
# return the cache of the deep merged values by top-level key
- deep_merge_cache[key]
+ deep_merge_cache[key.to_s]
else
# save all the work of computing node[key]
- deep_merge_cache[key] = merged_attributes(key)
+ deep_merge_cache[key.to_s] = merged_attributes(key)
end
end
diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb
index 0bc76db272..5939403ce6 100644
--- a/spec/unit/node_spec.rb
+++ b/spec/unit/node_spec.rb
@@ -611,6 +611,37 @@ describe Chef::Node do
end
end
+ # In Chef-12.0 there is a deep_merge cache on the top level attribute which had a bug
+ # where it cached node[:foo] separate from node['foo']. These tests exercise those edge conditions.
+ #
+ # https://github.com/opscode/chef/issues/2700
+ # https://github.com/opscode/chef/issues/2712
+ # https://github.com/opscode/chef/issues/2745
+ #
+ describe "deep merge attribute cache edge conditions" do
+ it "does not error with complicated attribute substitution" do
+ node.default['chef_attribute_hell']['attr1'] = "attribute1"
+ node.default['chef_attribute_hell']['attr2'] = "#{node.chef_attribute_hell.attr1}/attr2"
+ expect { node.default['chef_attribute_hell']['attr3'] = "#{node.chef_attribute_hell.attr2}/attr3" }.not_to raise_error
+ end
+
+ it "caches both strings and symbols correctly" do
+ node.force_default[:solr][:version] = '4.10.2'
+ node.force_default[:solr][:data_dir] = "/opt/solr-#{node['solr'][:version]}/example/solr"
+ node.force_default[:solr][:xms] = "512M"
+ expect(node[:solr][:xms]).to eql("512M")
+ expect(node['solr'][:xms]).to eql("512M")
+ end
+
+ it "method interpolation syntax also works" do
+ node.default['passenger']['version'] = '4.0.57'
+ node.default['passenger']['root_path'] = "passenger-#{node['passenger']['version']}"
+ node.default['passenger']['root_path_2'] = "passenger-#{node.passenger['version']}"
+ expect(node['passenger']['root_path_2']).to eql("passenger-4.0.57")
+ expect(node[:passenger]['root_path_2']).to eql("passenger-4.0.57")
+ end
+ end
+
it "should raise an ArgumentError if you ask for an attribute that doesn't exist via method_missing" do
expect { node.sunshine }.to raise_error(NoMethodError)
end