summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG5
-rw-r--r--lib/puppet/parser/compiler.rb1
-rw-r--r--lib/puppet/parser/resource.rb37
-rwxr-xr-xspec/unit/parser/resource.rb161
-rwxr-xr-xtest/language/resource.rb159
5 files changed, 178 insertions, 185 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 539db731b..ec16dfa4d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+ Always duplicating resource defaults in the parser, so that
+ stacked metaparameter values do not result in all resources
+ that receive a given default also getting those stacked
+ values.
+
0.24.2
Fixing #1062 by moving the yamldir setting to its own yaml
section. This should keep the yamldir from being created
diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb
index 70cd6e11a..8fba41121 100644
--- a/lib/puppet/parser/compiler.rb
+++ b/lib/puppet/parser/compiler.rb
@@ -366,7 +366,6 @@ class Puppet::Parser::Compiler
# Make sure all of our resources and such have done any last work
# necessary.
def finish
- #@catalog.resources.each do |name|
@catalog.vertices.each do |resource|
# Add in any resource overrides.
if overrides = resource_overrides(resource)
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index b001e165b..4b48ff6cf 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -233,6 +233,20 @@ class Puppet::Parser::Resource
@ref.to_s
end
+ # Define a parameter in our resource.
+ def set_parameter(param, value = nil)
+ if value
+ param = Puppet::Parser::Resource::Param.new(
+ :name => param, :value => value, :source => self.source
+ )
+ elsif ! param.is_a?(Puppet::Parser::Resource::Param)
+ raise ArgumentError, "Must pass a parameter or all necessary values"
+ end
+
+ # And store it in our parameter hash.
+ @params[param.name] = param
+ end
+
def to_hash
@params.inject({}) do |hash, ary|
param = ary[1]
@@ -331,7 +345,7 @@ class Puppet::Parser::Resource
unless @params.include?(name)
self.debug "Adding default for %s" % name
- @params[name] = param
+ @params[name] = param.dup
end
end
end
@@ -370,11 +384,8 @@ class Puppet::Parser::Resource
# The parameter is already set. Fail if they're not allowed to override it.
unless param.source.child_of?(current.source)
- if Puppet[:trace]
- puts caller
- end
- msg = "Parameter '%s' is already set on %s" %
- [param.name, self.to_s]
+ puts caller if Puppet[:trace]
+ msg = "Parameter '%s' is already set on %s" % [param.name, self.to_s]
if current.source.to_s != ""
msg += " by %s" % current.source
end
@@ -426,20 +437,6 @@ class Puppet::Parser::Resource
end
end
- # Define a parameter in our resource.
- def set_parameter(param, value = nil)
- if value
- param = Puppet::Parser::Resource::Param.new(
- :name => param, :value => value, :source => self.source
- )
- elsif ! param.is_a?(Puppet::Parser::Resource::Param)
- raise ArgumentError, "Must pass a parameter or all necessary values"
- end
-
- # And store it in our parameter hash.
- @params[param.name] = param
- end
-
# Make sure the resource's parameters are all valid for the type.
def validate
@params.each do |name, param|
diff --git a/spec/unit/parser/resource.rb b/spec/unit/parser/resource.rb
index 9ce7b391b..1948a3c07 100755
--- a/spec/unit/parser/resource.rb
+++ b/spec/unit/parser/resource.rb
@@ -14,6 +14,36 @@ describe Puppet::Parser::Resource do
@scope = @compiler.topscope
end
+ def mkresource(args = {})
+ args[:source] ||= "source"
+ args[:scope] ||= stub('scope', :source => mock('source'))
+
+ {:type => "resource", :title => "testing", :source => "source", :scope => "scope"}.each do |param, value|
+ args[param] ||= value
+ end
+
+ params = args[:params] || {:one => "yay", :three => "rah"}
+ if args[:params] == :none
+ args.delete(:params)
+ else
+ args[:params] = paramify(args[:source], params)
+ end
+
+ Puppet::Parser::Resource.new(args)
+ end
+
+ def param(name, value, source)
+ Puppet::Parser::Resource::Param.new(:name => name, :value => value, :source => source)
+ end
+
+ def paramify(source, hash)
+ hash.collect do |name, value|
+ Puppet::Parser::Resource::Param.new(
+ :name => name, :value => value, :source => source
+ )
+ end
+ end
+
it "should be isomorphic if it is builtin and models an isomorphic type" do
Puppet::Type.type(:file).expects(:isomorphic?).returns(true)
@resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
@@ -29,6 +59,30 @@ describe Puppet::Parser::Resource do
@resource = Puppet::Parser::Resource.new(:type => "whatever", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
end
+ it "should have a array-indexing method for retrieving parameter values" do
+ @resource = mkresource
+ @resource[:one].should == "yay"
+ end
+
+ describe "when initializing" do
+ before do
+ @arguments = {:type => "resource", :title => "testing", :scope => stub('scope', :source => mock('source'))}
+ end
+
+ [:type, :title, :scope].each do |name|
+ it "should fail unless #{name.to_s} is specified" do
+ try = @arguments.dup
+ try.delete(name)
+ lambda { Puppet::Parser::Resource.new(try) }.should raise_error(ArgumentError)
+ end
+ end
+
+ it "should set the reference correctly" do
+ res = Puppet::Parser::Resource.new(@arguments)
+ res.ref.should == "Resource[testing]"
+ end
+ end
+
describe "when evaluating" do
before do
@type = Puppet::Parser::Resource
@@ -60,11 +114,10 @@ describe Puppet::Parser::Resource do
describe "when finishing" do
before do
- @definition = @parser.newdefine "mydefine"
@class = @parser.newclass "myclass"
@nodedef = @parser.newnode("mynode")[0]
- @resource = Puppet::Parser::Resource.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
+ @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source)
end
it "should do nothing if it has already been finished" do
@@ -73,6 +126,32 @@ describe Puppet::Parser::Resource do
@resource.finish
end
+ it "should add all defaults available from the scope" do
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => param(:owner, "default", @resource.source))
+ @resource.finish
+
+ @resource[:owner].should == "default"
+ end
+
+ it "should not replace existing parameters with defaults" do
+ @resource.set_parameter :owner, "oldvalue"
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => :replaced)
+ @resource.finish
+
+ @resource[:owner].should == "oldvalue"
+ end
+
+ it "should add a copy of each default, rather than the actual default parameter instance" do
+ newparam = param(:owner, "default", @resource.source)
+ other = newparam.dup
+ other.value = "other"
+ newparam.expects(:dup).returns(other)
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => newparam)
+ @resource.finish
+
+ @resource[:owner].should == "other"
+ end
+
it "should copy metaparams from its scope" do
@scope.setvar("noop", "true")
@@ -82,7 +161,7 @@ describe Puppet::Parser::Resource do
end
it "should not copy metaparams that it already has" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("noop", "false") }
+ @resource.set_parameter("noop", "false")
@scope.setvar("noop", "true")
@resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
@@ -91,7 +170,7 @@ describe Puppet::Parser::Resource do
end
it "should stack relationship metaparams from its container if it already has them" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("require", "resource") }
+ @resource.set_parameter("require", "resource")
@scope.setvar("require", "container")
@resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
@@ -100,7 +179,7 @@ describe Puppet::Parser::Resource do
end
it "should flatten the array resulting from stacking relationship metaparams" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("require", ["resource1", "resource2"]) }
+ @resource.set_parameter("require", ["resource1", "resource2"])
@scope.setvar("require", %w{container1 container2})
@resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
@@ -167,4 +246,76 @@ describe Puppet::Parser::Resource do
lambda { @resource.tag("good_tag") }.should_not raise_error(Puppet::ParseError)
end
end
+
+ describe "when merging overrides" do
+ before do
+ @source = "source1"
+ @resource = mkresource :source => @source
+ @override = mkresource :source => @source
+ end
+
+ it "should fail when the override was not created by a parent class" do
+ @override.source = "source2"
+ @override.source.expects(:child_of?).with("source1").returns(false)
+ assert_raise(Puppet::ParseError, "Allowed unrelated resources to override") do
+ @resource.merge(@override)
+ end
+ end
+
+ it "should succeed when the override was created in the current scope" do
+ @resource.source = "source3"
+ @override.source = @resource.source
+ @override.source.expects(:child_of?).with("source3").never
+ params = {:a => :b, :c => :d}
+ @override.expects(:params).returns(params)
+ @resource.expects(:override_parameter).with(:b)
+ @resource.expects(:override_parameter).with(:d)
+ @resource.merge(@override)
+ end
+
+ it "should succeed when a parent class created the override" do
+ @resource.source = "source3"
+ @override.source = "source4"
+ @override.source.expects(:child_of?).with("source3").returns(true)
+ params = {:a => :b, :c => :d}
+ @override.expects(:params).returns(params)
+ @resource.expects(:override_parameter).with(:b)
+ @resource.expects(:override_parameter).with(:d)
+ @resource.merge(@override)
+ end
+
+ it "should add new parameters when the parameter is not set" do
+ @source.stubs(:child_of?).returns true
+ @override.set_parameter(:testing, "value")
+ @resource.merge(@override)
+
+ @resource[:testing].should == "value"
+ end
+
+ it "should replace existing parameter values" do
+ @source.stubs(:child_of?).returns true
+ @resource.set_parameter(:testing, "old")
+ @override.set_parameter(:testing, "value")
+
+ @resource.merge(@override)
+
+ @resource[:testing].should == "value"
+ end
+
+ it "should add values to the parameter when the override was created with the '+>' syntax" do
+ @source.stubs(:child_of?).returns true
+ param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "testing", :source => @resource.source)
+ param.add = true
+
+ @override.set_parameter(param)
+
+ @resource.set_parameter(:testing, "other")
+
+ @resource.merge(@override)
+
+ @resource[:testing].should == %w{other testing}
+ end
+
+
+ end
end
diff --git a/test/language/resource.rb b/test/language/resource.rb
index 608e7c995..b3eaf0390 100755
--- a/test/language/resource.rb
+++ b/test/language/resource.rb
@@ -23,95 +23,6 @@ class TestResource < PuppetTest::TestCase
mocha_verify
end
- def test_initialize
- args = {:type => "resource", :title => "testing",
- :scope => mkscope}
- # Check our arg requirements
- args.each do |name, value|
- try = args.dup
- try.delete(name)
- assert_raise(ArgumentError, "Did not fail when %s was missing" % name) do
- Parser::Resource.new(try)
- end
- end
-
- res = nil
- assert_nothing_raised do
- res = Parser::Resource.new(args)
- end
-
- ref = res.instance_variable_get("@ref")
- assert_equal("Resource", ref.type, "did not set resource type")
- assert_equal("testing", ref.title, "did not set resource title")
- end
-
- def test_merge
- res = mkresource
- other = mkresource
-
- # First try the case where the resource is not allowed to override
- res.source = "source1"
- other.source = "source2"
- other.source.expects(:child_of?).with("source1").returns(false)
- assert_raise(Puppet::ParseError, "Allowed unrelated resources to override") do
- res.merge(other)
- end
-
- # Next try it when the sources are equal.
- res.source = "source3"
- other.source = res.source
- other.source.expects(:child_of?).with("source3").never
- params = {:a => :b, :c => :d}
- other.expects(:params).returns(params)
- res.expects(:override_parameter).with(:b)
- res.expects(:override_parameter).with(:d)
- res.merge(other)
-
- # And then parentage is involved
- other = mkresource
- res.source = "source3"
- other.source = "source4"
- other.source.expects(:child_of?).with("source3").returns(true)
- params = {:a => :b, :c => :d}
- other.expects(:params).returns(params)
- res.expects(:override_parameter).with(:b)
- res.expects(:override_parameter).with(:d)
- res.merge(other)
- end
-
- # the [] method
- def test_array_accessors
- res = mkresource
- params = res.instance_variable_get("@params")
- assert_nil(res[:missing], "Found a missing parameter somehow")
- params[:something] = stub(:value => "yay")
- assert_equal("yay", res[:something], "Did not correctly call value on the parameter")
-
- res.expects(:title).returns(:mytitle)
- assert_equal(:mytitle, res[:title], "Did not call title when asked for it as a param")
- end
-
- # Make sure any defaults stored in the scope get added to our resource.
- def test_add_defaults
- res = mkresource
- params = res.instance_variable_get("@params")
- params[:a] = :b
- res.scope.expects(:lookupdefaults).with(res.type).returns(:a => :replaced, :c => :d)
- res.expects(:debug)
-
- res.send(:add_defaults)
- assert_equal(:d, params[:c], "Did not set default")
- assert_equal(:b, params[:a], "Replaced parameter with default")
- end
-
- def test_finish
- res = mkresource
- res.expects(:add_defaults)
- res.expects(:add_metaparams)
- res.expects(:validate)
- res.finish
- end
-
# Make sure we paramcheck our params
def test_validate
res = mkresource
@@ -123,43 +34,6 @@ class TestResource < PuppetTest::TestCase
res.send(:validate)
end
- def test_override_parameter
- res = mkresource
- params = res.instance_variable_get("@params")
-
- # There are three cases, with the second having two options:
-
- # No existing parameter.
- param = stub(:name => "myparam")
- res.send(:override_parameter, param)
- assert_equal(param, params["myparam"], "Override was not added to param list")
-
- # An existing parameter that we can override.
- source = stub(:child_of? => true)
- # Start out without addition
- params["param2"] = stub(:source => :whatever)
- param = stub(:name => "param2", :source => source, :add => false)
- res.send(:override_parameter, param)
- assert_equal(param, params["param2"], "Override was not added to param list")
-
- # Try with addition.
- params["param2"] = stub(:value => :a, :source => :whatever)
- param = stub(:name => "param2", :source => source, :add => true, :value => :b)
- param.expects(:value=).with([:a, :b])
- res.send(:override_parameter, param)
- assert_equal(param, params["param2"], "Override was not added to param list")
-
- # And finally, make sure we throw an exception when the sources aren't related
- source = stub(:child_of? => false)
- params["param2"] = stub(:source => :whatever, :file => :f, :line => :l)
- old = params["param2"]
- param = stub(:name => "param2", :source => source, :file => :f, :line => :l)
- assert_raise(Puppet::ParseError, "Did not fail when params conflicted") do
- res.send(:override_parameter, param)
- end
- assert_equal(old, params["param2"], "Param was replaced irrespective of conflict")
- end
-
def test_set_parameter
res = mkresource
params = res.instance_variable_get("@params")
@@ -420,37 +294,4 @@ class TestResource < PuppetTest::TestCase
assert(newres.exported?, "Exported defined resource generated non-exported resources")
assert(newres.virtual?, "Exported defined resource generated non-virtual resources")
end
-
- # Make sure tags behave appropriately.
- def test_tags
- scope_resource = stub 'scope_resource', :tags => %w{srone srtwo}
- scope = stub 'scope', :resource => scope_resource
- resource = Puppet::Parser::Resource.new(:type => "file", :title => "yay", :scope => scope, :source => mock('source'))
-
- # Make sure we get the type and title
- %w{yay file}.each do |tag|
- assert(resource.tags.include?(tag), "Did not tag resource with %s" % tag)
- end
-
- # make sure we can only set legal tags
- ["an invalid tag", "-anotherinvalid", "bad*tag"].each do |tag|
- assert_raise(Puppet::ParseError, "Tag #{tag} was considered valid") do
- resource.tag tag
- end
- end
-
- # make sure good tags make it through.
- tags = %w{good-tag yaytag GoodTag another_tag a ab A}
- tags.each do |tag|
- assert_nothing_raised("Tag #{tag} was considered invalid") do
- resource.tag tag
- end
- end
-
- # make sure we get each of them.
- ptags = resource.tags
- tags.each do |tag|
- assert(ptags.include?(tag.downcase), "missing #{tag}")
- end
- end
end