summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2007-11-12 11:00:54 -0600
committerLuke Kanies <luke@madstop.com>2007-11-12 11:00:54 -0600
commitdd7caa76e160ed51c8b0e123c18f7526b575bfec (patch)
treeb1014b34503396cfa7efd56d5ec78860a8d29b51
parent47a26054fea97641aebb3906ca7416a982f4c0d5 (diff)
downloadpuppet-dd7caa76e160ed51c8b0e123c18f7526b575bfec.tar.gz
puppet-dd7caa76e160ed51c8b0e123c18f7526b575bfec.tar.xz
puppet-dd7caa76e160ed51c8b0e123c18f7526b575bfec.zip
Moving some compile tests to the spec/ directory, and
switching the node scope to no longer be lazy evaluation, just like I switched 'main'. When I made all of these classes and nodes lazy evaluated, I should have decoupled my real goal (using resources to evaluate them) from the idea of lazy-evaluating them, and this basically does that. I also changed the scope heirarchy slightly so that scopes will tend to be below the node scope, altho this was already generally the case.
-rw-r--r--CHANGELOG5
-rw-r--r--lib/puppet/parser/compile.rb19
-rwxr-xr-xspec/unit/parser/compile.rb100
-rwxr-xr-xtest/language/compile.rb73
4 files changed, 119 insertions, 78 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 5a7103403..bbe621742 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+ The node scope is now above all other scopes besides
+ the 'main' scope, which should help make its variables
+ visible to other classes, assuming those classes were
+ not included in the node's parent.
+
Replaced GRATR::Digraph with Puppet::SimpleGraph as
the base class for Puppet's graphing. Functionality
should be equivalent but with dramatically better
diff --git a/lib/puppet/parser/compile.rb b/lib/puppet/parser/compile.rb
index 3083f4849..45d60a58c 100644
--- a/lib/puppet/parser/compile.rb
+++ b/lib/puppet/parser/compile.rb
@@ -14,7 +14,7 @@ require 'puppet/util/errors'
class Puppet::Parser::Compile
include Puppet::Util
include Puppet::Util::Errors
- attr_reader :topscope, :parser, :node, :facts, :collections, :configuration
+ attr_reader :parser, :node, :facts, :collections, :configuration, :node_scope
# Add a collection to the global list.
def add_collection(coll)
@@ -229,6 +229,12 @@ class Puppet::Parser::Compile
@configuration.add_edge!(scope.resource, resource)
end
+ # The top scope is usually the top-level scope, but if we're using AST nodes,
+ # then it is instead the node's scope.
+ def topscope
+ node_scope || @topscope
+ end
+
private
# If ast nodes are enabled, then see if we can find and evaluate one.
@@ -241,10 +247,7 @@ class Puppet::Parser::Compile
break if astnode = @parser.nodes[name.to_s.downcase]
end
- unless astnode
- astnode = @parser.nodes["default"]
- end
- unless astnode
+ unless (astnode ||= @parser.nodes["default"])
raise Puppet::ParseError, "Could not find default node or by name with '%s'" % node.names.join(", ")
end
@@ -253,6 +256,12 @@ class Puppet::Parser::Compile
resource = Puppet::Parser::Resource.new(:type => "node", :title => astnode.classname, :scope => topscope, :source => topscope.source)
store_resource(topscope, resource)
@configuration.tag(astnode.classname)
+
+ resource.evaluate
+
+ # Now set the node scope appropriately, so that :topscope can
+ # behave differently.
+ @node_scope = class_scope(astnode)
end
# Evaluate our collections and return true if anything returned an object.
diff --git a/spec/unit/parser/compile.rb b/spec/unit/parser/compile.rb
index 93c440417..5f239636b 100755
--- a/spec/unit/parser/compile.rb
+++ b/spec/unit/parser/compile.rb
@@ -141,3 +141,103 @@ describe Puppet::Parser::Compile, " when evaluating found classes" do
@compile.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
end
end
+
+describe Puppet::Parser::Compile, " when evaluating AST nodes with no AST nodes present" do
+ before do
+ @node = stub 'node', :name => "foo"
+ @parser = stub 'parser', :version => "1.0", :nodes => {}
+ @compile = Puppet::Parser::Compile.new(@node, @parser)
+ end
+
+ it "should do nothing" do
+ @compile.expects(:ast_nodes?).returns(false)
+ @compile.parser.expects(:nodes).never
+ Puppet::Parser::Resource.expects(:new).never
+
+ @compile.send(:evaluate_ast_node)
+ end
+end
+
+describe Puppet::Parser::Compile, " when evaluating AST nodes with AST nodes present" do
+ before do
+ @node = stub 'node', :name => "foo"
+ @parser = stub 'parser', :version => "1.0", :nodes => {}
+ @compile = Puppet::Parser::Compile.new(@node, @parser)
+
+ @nodes = mock 'node_hash'
+ @compile.stubs(:ast_nodes?).returns(true)
+ @compile.parser.stubs(:nodes).returns(@nodes)
+
+ # Set some names for our test
+ @node.stubs(:names).returns(%w{a b c})
+ @nodes.stubs(:[]).with("a").returns(nil)
+ @nodes.stubs(:[]).with("b").returns(nil)
+ @nodes.stubs(:[]).with("c").returns(nil)
+
+ # It should check this last, of course.
+ @nodes.stubs(:[]).with("default").returns(nil)
+ end
+
+ it "should fail if the named node cannot be found" do
+ proc { @compile.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should create a resource for the first node class matching the node name" do
+ node_class = stub 'node', :classname => "c"
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
+ Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "c" and args[:type] == "node" }.returns(node_resource)
+
+ @compile.send(:evaluate_ast_node)
+ end
+
+ it "should match the default node if no matching node can be found" do
+ node_class = stub 'node', :classname => "default"
+ @nodes.stubs(:[]).with("default").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil
+ Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "default" and args[:type] == "node" }.returns(node_resource)
+
+ @compile.send(:evaluate_ast_node)
+ end
+
+ it "should tag the configuration with the found node name" do
+ node_class = stub 'node', :classname => "c"
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
+ Puppet::Parser::Resource.stubs(:new).returns(node_resource)
+
+ @compile.configuration.expects(:tag).with("c")
+ @compile.send(:evaluate_ast_node)
+ end
+
+ it "should evaluate the node resource immediately rather than using lazy evaluation" do
+ node_class = stub 'node', :classname => "c"
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[c]"
+ Puppet::Parser::Resource.stubs(:new).returns(node_resource)
+
+ node_resource.expects(:evaluate)
+
+ @compile.send(:evaluate_ast_node)
+ end
+
+ it "should set the node's scope as the top scope" do
+ node_class = stub 'node', :classname => "c"
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[c]"
+ Puppet::Parser::Resource.stubs(:new).returns(node_resource)
+
+ # The #evaluate method normally does this.
+ @compile.class_set(node_class.classname, :my_node_scope)
+ node_resource.stubs(:evaluate)
+
+ @compile.send(:evaluate_ast_node)
+
+ @compile.topscope.should == :my_node_scope
+ end
+end
diff --git a/test/language/compile.rb b/test/language/compile.rb
index f5d9cb7d9..50b16a24d 100755
--- a/test/language/compile.rb
+++ b/test/language/compile.rb
@@ -188,79 +188,6 @@ class TestCompile < Test::Unit::TestCase
end
end
- # Make sure we either don't look for nodes, or that we find and evaluate the right object.
- def test_evaluate_ast_node
- # First try it with ast_nodes disabled
- compile = mkcompile
- name = compile.node.name
- compile.expects(:ast_nodes?).returns(false)
- compile.parser.expects(:nodes).never
-
- assert_nothing_raised("Could not call evaluate_ast_node when ast nodes are disabled") do
- compile.send(:evaluate_ast_node)
- end
-
- assert_nil(compile.resources.find { |r| r.to_s == "Node[#{name}]" }, "Created node object when ast_nodes was false")
-
- # Now try it with them enabled, but no node found.
- nodes = mock 'node_hash'
- compile = mkcompile
- name = compile.node.name
- compile.expects(:ast_nodes?).returns(true)
- compile.parser.stubs(:nodes).returns(nodes)
-
- # Set some names for our test
- @node.names = %w{a b c}
- nodes.expects(:[]).with("a").returns(nil)
- nodes.expects(:[]).with("b").returns(nil)
- nodes.expects(:[]).with("c").returns(nil)
-
- # It should check this last, of course.
- nodes.expects(:[]).with("default").returns(nil)
-
- # And make sure the lack of a node throws an exception
- assert_raise(Puppet::ParseError, "Did not fail when we couldn't find an ast node") do
- compile.send(:evaluate_ast_node)
- end
-
- # Finally, make sure it works dandily when we have a node
- compile = mkcompile
- compile.expects(:ast_nodes?).returns(true)
-
- node = stub 'node', :classname => "c"
- nodes = {"c" => node}
- compile.parser.stubs(:nodes).returns(nodes)
-
- # Set some names for our test
- @node.names = %w{a b c}
-
- # And make sure we throw no exceptions.
- assert_nothing_raised("Failed when a node was found") do
- compile.send(:evaluate_ast_node)
- end
-
- assert_instance_of(Puppet::Parser::Resource, compile.resources.find { |r| r.to_s == "Node[c]" },
- "Did not create node resource")
-
- # Lastly, check when we actually find the default.
- compile = mkcompile
- compile.expects(:ast_nodes?).returns(true)
-
- node = stub 'node', :classname => "default"
- nodes = {"default" => node}
- compile.parser.stubs(:nodes).returns(nodes)
-
- # Set some names for our test
- @node.names = %w{a b c}
-
- # And make sure the lack of a node throws an exception
- assert_nothing_raised("Failed when a node was found") do
- compile.send(:evaluate_ast_node)
- end
- assert_instance_of(Puppet::Parser::Resource, compile.resources.find { |r| r.to_s == "Node[default]" },
- "Did not create default node resource")
- end
-
def test_evaluate_node_classes
compile = mkcompile
@node.classes = %w{one two three four}