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.

Reply via email to