Resources mark themselves as evaluated to prevent being evaluated again. Unfortunately, they were not marking themselves until after they had finished being completely evaluated. Thus, there was nothing actually stopping recursive evaluations. This patch just makes resources mark themselves as evaluated when they start evaluating, and adds tests.
The original setting of evaluated was done in an ensure block, so this doesn't change the behavior of a resource which fails to evaluate. The only places evaluated? is checked aren't affected by this change, as they wouldn't want to evaluate it when it's already being evaluated anyway. Signed-off-by: Nick Lewis <[email protected]> --- lib/puppet/parser/resource.rb | 3 +- spec/unit/parser/functions/include_spec.rb | 50 ++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 spec/unit/parser/functions/include_spec.rb diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb index c956a11..3c45192 100644 --- a/lib/puppet/parser/resource.rb +++ b/lib/puppet/parser/resource.rb @@ -64,6 +64,7 @@ class Puppet::Parser::Resource < Puppet::Resource # Retrieve the associated definition and evaluate it. def evaluate + @evaluated = true if klass = resource_type and ! builtin_type? finish return klass.evaluate_code(self) @@ -72,8 +73,6 @@ class Puppet::Parser::Resource < Puppet::Resource else self.fail "Cannot find definition #{type}" end - ensure - @evaluated = true end # Mark this resource as both exported and virtual, diff --git a/spec/unit/parser/functions/include_spec.rb b/spec/unit/parser/functions/include_spec.rb new file mode 100644 index 0000000..4954ac6 --- /dev/null +++ b/spec/unit/parser/functions/include_spec.rb @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe "the 'include' function" do + + before :each do + Puppet::Node::Environment.stubs(:current).returns(nil) + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo")) + @scope = Puppet::Parser::Scope.new(:compiler => @compiler) + end + + it "should exist" do + Puppet::Parser::Functions.function("include").should == "function_include" + end + + it "should include a single class" do + inc = "foo" + @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| klasses == [inc]}.returns([inc]) + @scope.function_include("foo") + end + + it "should include multiple classes" do + inc = ["foo","bar"] + @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| klasses == inc}.returns(inc) + @scope.function_include(["foo","bar"]) + end + + it "should not lazily evaluate the included class" do + @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| lazy == false}.returns("foo") + @scope.function_include("foo") + end + + it "should allow a parent to include its child" do + @parent_type = Puppet::Resource::Type.new(:hostclass, "parent") + @parent_resource = Puppet::Parser::Resource.new(:hostclass, "parent", :scope => @scope) + @subscope = @parent_type.subscope(@scope,@parent_resource) + @scope.environment.known_resource_types.stubs(:find_hostclass).with{|nses,name| name.downcase == "parent"}.returns(@parent_type) + + @type = Puppet::Resource::Type.new(:hostclass, "foo") + @type.stubs(:parent_scope).returns(@subscope) + @type.parent = "parent" + @resource = Puppet::Parser::Resource.new(:hostclass, "foo", :scope => @subscope) + @resource.stubs(:resource_type).returns(@type) + @scope.environment.known_resource_types.stubs(:find_hostclass).with{|nses,name| name.downcase == "foo"}.returns(@parent_type) + Puppet::Resource.stubs(:new).returns(@resource) + Puppet::Parser::Resource.stubs(:new).returns(@resource) + lambda { @subscope.function_include("foo") }.should_not raise_error + end +end -- 1.7.2 -- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.
