Fixed #1030 - class and definition evaluation has been significantly
refactored, fixing this problem and making the whole interplay between the classes, definitions, and nodes, and the Compile class much cleaner.
This commit is contained in:
Родитель
3b740ff7a6
Коммит
6a4cf6c978
11
CHANGELOG
11
CHANGELOG
|
@ -1,6 +1,11 @@
|
|||
Exec resources must now have unique names. This is easily accomplished
|
||||
by just specifying a unique name with whatever (unique or otherwise)
|
||||
command you need.
|
||||
Fixed #1030 - class and definition evaluation has been significantly
|
||||
refactored, fixing this problem and making the whole interplay
|
||||
between the classes, definitions, and nodes, and the Compile class much
|
||||
cleaner.
|
||||
|
||||
Exec resources must now have unique names. This is easily accomplished by
|
||||
just specifying a unique name with whatever (unique or otherwise) command
|
||||
you need.
|
||||
|
||||
Fixed #989 -- missing CRL files are correctly ignored, and the
|
||||
value should be set to 'false' to explicitly not look for these
|
||||
|
|
|
@ -395,6 +395,11 @@ class Puppet::Node::Catalog < Puppet::PGraph
|
|||
nil
|
||||
end
|
||||
|
||||
# Does our tag list include this tag?
|
||||
def tagged?(tag)
|
||||
@tags.include?(tag)
|
||||
end
|
||||
|
||||
# Return the list of tags.
|
||||
def tags
|
||||
@tags.dup
|
||||
|
|
|
@ -24,7 +24,12 @@ class Puppet::Parser::AST::Definition < Puppet::Parser::AST::Branch
|
|||
|
||||
# Create a resource that knows how to evaluate our actual code.
|
||||
def evaluate(scope)
|
||||
resource = Puppet::Parser::Resource.new(:type => "class", :title => klass.classname, :scope => scope, :source => scope.source)
|
||||
# Do nothing if the resource already exists; this provides the singleton nature classes need.
|
||||
return if scope.catalog.resource(:class, self.classname)
|
||||
|
||||
resource = Puppet::Parser::Resource.new(:type => "class", :title => self.classname, :scope => scope, :source => scope.source)
|
||||
|
||||
scope.catalog.tag(*resource.tags)
|
||||
|
||||
scope.compile.store_resource(scope, resource)
|
||||
|
||||
|
@ -91,23 +96,21 @@ class Puppet::Parser::AST::Definition < Puppet::Parser::AST::Branch
|
|||
|
||||
# Hunt down our class object.
|
||||
def parentobj
|
||||
if @parentclass
|
||||
# Cache our result, since it should never change.
|
||||
unless defined?(@parentobj)
|
||||
unless tmp = find_parentclass
|
||||
parsefail "Could not find %s %s" % [self.class.name, @parentclass]
|
||||
end
|
||||
return nil unless @parentclass
|
||||
|
||||
if tmp == self
|
||||
parsefail "Parent classes must have dissimilar names"
|
||||
end
|
||||
|
||||
@parentobj = tmp
|
||||
# Cache our result, since it should never change.
|
||||
unless defined?(@parentobj)
|
||||
unless tmp = find_parentclass
|
||||
parsefail "Could not find %s parent %s" % [self.class.name, @parentclass]
|
||||
end
|
||||
@parentobj
|
||||
else
|
||||
nil
|
||||
|
||||
if tmp == self
|
||||
parsefail "Parent classes must have dissimilar names"
|
||||
end
|
||||
|
||||
@parentobj = tmp
|
||||
end
|
||||
@parentobj
|
||||
end
|
||||
|
||||
# Create a new subscope in which to evaluate our code.
|
||||
|
|
|
@ -18,6 +18,15 @@ class Puppet::Parser::AST::HostClass < Puppet::Parser::AST::Definition
|
|||
end
|
||||
end
|
||||
|
||||
# Make sure our parent class has been evaluated, if we have one.
|
||||
def evaluate(scope)
|
||||
if parentclass and ! scope.catalog.resource(:class, parentclass)
|
||||
resource = parentobj.evaluate(scope)
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
# Evaluate the code associated with this class.
|
||||
def evaluate_code(resource)
|
||||
scope = resource.scope
|
||||
|
@ -58,11 +67,6 @@ class Puppet::Parser::AST::HostClass < Puppet::Parser::AST::Definition
|
|||
end
|
||||
end
|
||||
|
||||
def initialize(options)
|
||||
@parentclass = nil
|
||||
super
|
||||
end
|
||||
|
||||
def parent_scope(scope, klass)
|
||||
if s = scope.compile.class_scope(klass)
|
||||
return s
|
||||
|
|
|
@ -115,16 +115,11 @@ class Puppet::Parser::Compile
|
|||
if klass = scope.findclass(name)
|
||||
found << name and next if class_scope(klass)
|
||||
|
||||
# Create a resource to model this class, and then add it to the list
|
||||
# of resources.
|
||||
resource = Puppet::Parser::Resource.new(:type => "class", :title => klass.classname, :scope => scope, :source => scope.source)
|
||||
|
||||
store_resource(scope, resource)
|
||||
resource = klass.evaluate(scope)
|
||||
|
||||
# If they've disabled lazy evaluation (which the :include function does),
|
||||
# then evaluate our resource immediately.
|
||||
resource.evaluate unless lazy_evaluate
|
||||
@catalog.tag(klass.classname)
|
||||
found << name
|
||||
else
|
||||
Puppet.info "Could not find class %s for %s" % [name, node.name]
|
||||
|
@ -412,9 +407,6 @@ class Puppet::Parser::Compile
|
|||
# but they each refer back to the scope that created them.
|
||||
@collections = []
|
||||
|
||||
# A list of tags we've generated; most class names.
|
||||
@tags = []
|
||||
|
||||
# A graph for maintaining scope relationships.
|
||||
@scope_graph = Puppet::SimpleGraph.new
|
||||
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require File.dirname(__FILE__) + '/../../../spec_helper'
|
||||
|
||||
module HostClassTesting
|
||||
def setup
|
||||
@node = Puppet::Node.new "testnode"
|
||||
@parser = Puppet::Parser::Parser.new :environment => "development"
|
||||
@scope_resource = stub 'scope_resource', :builtin? => true
|
||||
@compile = Puppet::Parser::Compile.new(@node, @parser)
|
||||
|
||||
@scope = @compile.topscope
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::AST::HostClass, "when evaluating" do
|
||||
include HostClassTesting
|
||||
|
||||
before do
|
||||
@top = @parser.newclass "top"
|
||||
@middle = @parser.newclass "middle", :parent => "top"
|
||||
end
|
||||
|
||||
it "should create a resource that references itself" do
|
||||
@top.evaluate(@scope)
|
||||
|
||||
@compile.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
|
||||
end
|
||||
|
||||
it "should evaluate the parent class if one exists" do
|
||||
@middle.evaluate(@scope)
|
||||
|
||||
@compile.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
|
||||
end
|
||||
|
||||
it "should fail to evaluate if a parent class is defined but cannot be found" do
|
||||
othertop = @parser.newclass "something", :parent => "yay"
|
||||
lambda { othertop.evaluate(@scope) }.should raise_error(Puppet::ParseError)
|
||||
end
|
||||
|
||||
it "should not create a new resource if one already exists" do
|
||||
@compile.catalog.expects(:resource).with(:class, "top").returns("something")
|
||||
@compile.catalog.expects(:add_resource).never
|
||||
@top.evaluate(@scope)
|
||||
end
|
||||
|
||||
it "should not create a new parent resource if one already exists and it has a parent class" do
|
||||
@top.evaluate(@scope)
|
||||
|
||||
top_resource = @compile.catalog.resource(:class, "top")
|
||||
|
||||
@middle.evaluate(@scope)
|
||||
|
||||
@compile.catalog.resource(:class, "top").should equal(top_resource)
|
||||
end
|
||||
|
||||
# #795 - tag before evaluation.
|
||||
it "should tag the catalog with the resource tags when it is evaluated" do
|
||||
@middle.evaluate(@scope)
|
||||
|
||||
@compile.catalog.should be_tagged("middle")
|
||||
end
|
||||
|
||||
it "should tag the catalog with the parent class tags when it is evaluated" do
|
||||
@middle.evaluate(@scope)
|
||||
|
||||
@compile.catalog.should be_tagged("top")
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::AST::HostClass, "when evaluating code" do
|
||||
include HostClassTesting
|
||||
|
||||
before do
|
||||
@top_resource = stub "top_resource"
|
||||
@top = @parser.newclass "top", :code => @top_resource
|
||||
|
||||
@middle_resource = stub "middle_resource"
|
||||
@middle = @parser.newclass "top::middle", :parent => "top", :code => @middle_resource
|
||||
end
|
||||
|
||||
it "should set its namespace to its fully qualified name" do
|
||||
@middle.namespace.should == "top::middle"
|
||||
end
|
||||
|
||||
it "should evaluate the code referred to by the class" do
|
||||
@top_resource.expects(:safeevaluate)
|
||||
|
||||
resource = @top.evaluate(@scope)
|
||||
|
||||
@top.evaluate_code(resource)
|
||||
end
|
||||
|
||||
it "should evaluate the parent class's code if it has a parent" do
|
||||
@top_resource.expects(:safeevaluate)
|
||||
@middle_resource.expects(:safeevaluate)
|
||||
|
||||
resource = @middle.evaluate(@scope)
|
||||
|
||||
@middle.evaluate_code(resource)
|
||||
end
|
||||
|
||||
it "should not evaluate the parent class's code if the parent has already been evaluated" do
|
||||
@top_resource.stubs(:safeevaluate)
|
||||
resource = @top.evaluate(@scope)
|
||||
@top.evaluate_code(resource)
|
||||
|
||||
@top_resource.expects(:safeevaluate).never
|
||||
@middle_resource.stubs(:safeevaluate)
|
||||
resource = @middle.evaluate(@scope)
|
||||
@middle.evaluate_code(resource)
|
||||
end
|
||||
|
||||
it "should use the parent class's scope as its parent scope" do
|
||||
@top_resource.stubs(:safeevaluate)
|
||||
@middle_resource.stubs(:safeevaluate)
|
||||
resource = @middle.evaluate(@scope)
|
||||
@middle.evaluate_code(resource)
|
||||
|
||||
@compile.class_scope(@middle).parent.should equal(@compile.class_scope(@top))
|
||||
end
|
||||
|
||||
it "should add the parent class's namespace to its namespace search path" do
|
||||
@top_resource.stubs(:safeevaluate)
|
||||
@middle_resource.stubs(:safeevaluate)
|
||||
resource = @middle.evaluate(@scope)
|
||||
@middle.evaluate_code(resource)
|
||||
|
||||
@compile.class_scope(@middle).namespaces.should be_include(@top.namespace)
|
||||
end
|
||||
end
|
|
@ -13,6 +13,78 @@ module CompileTesting
|
|||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile do
|
||||
include CompileTesting
|
||||
|
||||
it "should be able to store references to class scopes" do
|
||||
lambda { @compile.class_set "myname", "myscope" }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should be able to retrieve class scopes by name" do
|
||||
@compile.class_set "myname", "myscope"
|
||||
@compile.class_scope("myname").should == "myscope"
|
||||
end
|
||||
|
||||
it "should be able to retrieve class scopes by object" do
|
||||
klass = mock 'ast_class'
|
||||
klass.expects(:classname).returns("myname")
|
||||
@compile.class_set "myname", "myscope"
|
||||
@compile.class_scope(klass).should == "myscope"
|
||||
end
|
||||
|
||||
it "should be able to return a class list containing all set classes" do
|
||||
@compile.class_set "", "empty"
|
||||
@compile.class_set "one", "yep"
|
||||
@compile.class_set "two", "nope"
|
||||
|
||||
@compile.classlist.sort.should == %w{one two}.sort
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile, " when initializing" do
|
||||
include CompileTesting
|
||||
|
||||
it "should set its node attribute" do
|
||||
@compile.node.should equal(@node)
|
||||
end
|
||||
|
||||
it "should set its parser attribute" do
|
||||
@compile.parser.should equal(@parser)
|
||||
end
|
||||
|
||||
it "should detect when ast nodes are absent" do
|
||||
@compile.ast_nodes?.should be_false
|
||||
end
|
||||
|
||||
it "should detect when ast nodes are present" do
|
||||
@parser.nodes["testing"] = "yay"
|
||||
@compile.ast_nodes?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile, "when managing scopes" do
|
||||
include CompileTesting
|
||||
|
||||
it "should create a top scope" do
|
||||
@compile.topscope.should be_instance_of(Puppet::Parser::Scope)
|
||||
end
|
||||
|
||||
it "should be able to create new scopes" do
|
||||
@compile.newscope(@compile.topscope).should be_instance_of(Puppet::Parser::Scope)
|
||||
end
|
||||
|
||||
it "should correctly set the level of newly created scopes" do
|
||||
@compile.newscope(@compile.topscope, :level => 5).level.should == 5
|
||||
end
|
||||
|
||||
it "should set the parent scope of the new scope to be the passed-in parent" do
|
||||
scope = mock 'scope'
|
||||
newscope = @compile.newscope(scope)
|
||||
|
||||
@compile.parent(newscope).should equal(scope)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile, " when compiling" do
|
||||
include CompileTesting
|
||||
|
||||
|
@ -174,21 +246,6 @@ describe Puppet::Parser::Compile, " when compiling" do
|
|||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile, " when evaluating classes" do
|
||||
include CompileTesting
|
||||
|
||||
it "should fail if there's no source listed for the scope" do
|
||||
scope = stub 'scope', :source => nil
|
||||
proc { @compile.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError)
|
||||
end
|
||||
|
||||
it "should tag the catalog with the name of each not-found class" do
|
||||
@compile.catalog.expects(:tag).with("notfound")
|
||||
@scope.expects(:findclass).with("notfound").returns(nil)
|
||||
@compile.evaluate_classes(%w{notfound}, @scope)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile, " when evaluating collections" do
|
||||
include CompileTesting
|
||||
|
||||
|
@ -235,6 +292,20 @@ describe Puppet::Parser::Compile, " when evaluating collections" do
|
|||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile, "when told to evaluate missing classes" do
|
||||
include CompileTesting
|
||||
|
||||
it "should fail if there's no source listed for the scope" do
|
||||
scope = stub 'scope', :source => nil
|
||||
proc { @compile.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError)
|
||||
end
|
||||
|
||||
it "should tag the catalog with the name of each not-found class" do
|
||||
@compile.catalog.expects(:tag).with("notfound")
|
||||
@scope.expects(:findclass).with("notfound").returns(nil)
|
||||
@compile.evaluate_classes(%w{notfound}, @scope)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile, " when evaluating found classes" do
|
||||
include CompileTesting
|
||||
|
@ -243,53 +314,33 @@ describe Puppet::Parser::Compile, " when evaluating found classes" do
|
|||
@class = stub 'class', :classname => "my::class"
|
||||
@scope.stubs(:findclass).with("myclass").returns(@class)
|
||||
|
||||
@resource = stub 'resource', :ref => 'Class[myclass]'
|
||||
@resource = stub 'resource', :ref => "Class[myclass]"
|
||||
end
|
||||
|
||||
it "should create a resource for each found class" do
|
||||
it "should evaluate each class" do
|
||||
@compile.catalog.stubs(:tag)
|
||||
|
||||
@compile.stubs :store_resource
|
||||
@class.expects(:evaluate).with(@scope)
|
||||
|
||||
Puppet::Parser::Resource.expects(:new).with(:scope => @scope, :source => @scope.source, :title => "my::class", :type => "class").returns(@resource)
|
||||
@compile.evaluate_classes(%w{myclass}, @scope)
|
||||
end
|
||||
|
||||
it "should store each created resource in the compile" do
|
||||
@compile.catalog.stubs(:tag)
|
||||
|
||||
@compile.expects(:store_resource).with(@scope, @resource)
|
||||
|
||||
Puppet::Parser::Resource.stubs(:new).returns(@resource)
|
||||
@compile.evaluate_classes(%w{myclass}, @scope)
|
||||
end
|
||||
|
||||
it "should tag the catalog with the fully-qualified name of each found class" do
|
||||
@compile.catalog.expects(:tag).with("my::class")
|
||||
|
||||
@compile.stubs(:store_resource)
|
||||
|
||||
Puppet::Parser::Resource.stubs(:new).returns(@resource)
|
||||
@compile.evaluate_classes(%w{myclass}, @scope)
|
||||
end
|
||||
|
||||
it "should not evaluate the resources created for found classes unless asked" do
|
||||
@compile.catalog.stubs(:tag)
|
||||
|
||||
@compile.stubs(:store_resource)
|
||||
@resource.expects(:evaluate).never
|
||||
|
||||
Puppet::Parser::Resource.stubs(:new).returns(@resource)
|
||||
@class.expects(:evaluate).returns(@resource)
|
||||
|
||||
@compile.evaluate_classes(%w{myclass}, @scope)
|
||||
end
|
||||
|
||||
it "should immediately evaluate the resources created for found classes when asked" do
|
||||
@compile.catalog.stubs(:tag)
|
||||
|
||||
@compile.stubs(:store_resource)
|
||||
@resource.expects(:evaluate)
|
||||
@class.expects(:evaluate).returns(@resource)
|
||||
|
||||
Puppet::Parser::Resource.stubs(:new).returns(@resource)
|
||||
@compile.evaluate_classes(%w{myclass}, @scope, false)
|
||||
end
|
||||
|
||||
|
@ -313,6 +364,7 @@ describe Puppet::Parser::Compile, " when evaluating found classes" do
|
|||
@scope.stubs(:findclass).with("notfound").returns(nil)
|
||||
|
||||
Puppet::Parser::Resource.stubs(:new).returns(@resource)
|
||||
@class.stubs :evaluate
|
||||
@compile.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
|
||||
end
|
||||
end
|
||||
|
@ -411,78 +463,6 @@ describe Puppet::Parser::Compile, " when evaluating AST nodes with AST nodes pre
|
|||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile, " when initializing" do
|
||||
include CompileTesting
|
||||
|
||||
it "should set its node attribute" do
|
||||
@compile.node.should equal(@node)
|
||||
end
|
||||
|
||||
it "should set its parser attribute" do
|
||||
@compile.parser.should equal(@parser)
|
||||
end
|
||||
|
||||
it "should detect when ast nodes are absent" do
|
||||
@compile.ast_nodes?.should be_false
|
||||
end
|
||||
|
||||
it "should detect when ast nodes are present" do
|
||||
@parser.nodes["testing"] = "yay"
|
||||
@compile.ast_nodes?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile do
|
||||
include CompileTesting
|
||||
|
||||
it "should be able to store references to class scopes" do
|
||||
lambda { @compile.class_set "myname", "myscope" }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should be able to retrieve class scopes by name" do
|
||||
@compile.class_set "myname", "myscope"
|
||||
@compile.class_scope("myname").should == "myscope"
|
||||
end
|
||||
|
||||
it "should be able to retrieve class scopes by object" do
|
||||
klass = mock 'ast_class'
|
||||
klass.expects(:classname).returns("myname")
|
||||
@compile.class_set "myname", "myscope"
|
||||
@compile.class_scope(klass).should == "myscope"
|
||||
end
|
||||
|
||||
it "should be able to return a class list containing all set classes" do
|
||||
@compile.class_set "", "empty"
|
||||
@compile.class_set "one", "yep"
|
||||
@compile.class_set "two", "nope"
|
||||
|
||||
@compile.classlist.sort.should == %w{one two}.sort
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile, "when managing scopes" do
|
||||
include CompileTesting
|
||||
|
||||
it "should create a top scope" do
|
||||
@compile.topscope.should be_instance_of(Puppet::Parser::Scope)
|
||||
end
|
||||
|
||||
it "should be able to create new scopes" do
|
||||
@compile.newscope(@compile.topscope).should be_instance_of(Puppet::Parser::Scope)
|
||||
end
|
||||
|
||||
it "should correctly set the level of newly created scopes" do
|
||||
@compile.newscope(@compile.topscope, :level => 5).level.should == 5
|
||||
end
|
||||
|
||||
it "should set the parent scope of the new scope to be the passed-in parent" do
|
||||
scope = mock 'scope'
|
||||
newscope = @compile.newscope(scope)
|
||||
|
||||
@compile.parent(newscope).should equal(scope)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Compile, "when storing compiled resources" do
|
||||
include CompileTesting
|
||||
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# Created by Luke A. Kanies on 2006-02-20.
|
||||
# Copyright (c) 2006. All rights reserved.
|
||||
|
||||
require File.dirname(__FILE__) + '/../../lib/puppettest'
|
||||
|
||||
require 'puppettest'
|
||||
require 'puppettest/parsertesting'
|
||||
require 'puppettest/resourcetesting'
|
||||
require 'mocha'
|
||||
|
||||
class TestASTHostClass < Test::Unit::TestCase
|
||||
include PuppetTest
|
||||
include PuppetTest::ParserTesting
|
||||
include PuppetTest::ResourceTesting
|
||||
AST = Puppet::Parser::AST
|
||||
|
||||
def test_hostclass
|
||||
scope = mkscope
|
||||
parser = scope.compile.parser
|
||||
|
||||
# Create the class we're testing, first with no parent
|
||||
klass = parser.newclass "first",
|
||||
:code => AST::ASTArray.new(
|
||||
:children => [resourcedef("file", "/tmp",
|
||||
"owner" => "nobody", "mode" => "755")]
|
||||
)
|
||||
|
||||
resource = Puppet::Parser::Resource.new(:type => "class", :title => "first", :scope => scope)
|
||||
assert_nothing_raised do
|
||||
klass.evaluate_code(resource)
|
||||
end
|
||||
|
||||
# Then try it again
|
||||
assert_nothing_raised do
|
||||
klass.evaluate_code(resource)
|
||||
end
|
||||
|
||||
assert(scope.compile.class_scope(klass), "Class was not considered evaluated")
|
||||
|
||||
tmp = scope.findresource("File[/tmp]")
|
||||
assert(tmp, "Could not find file /tmp")
|
||||
assert_equal("nobody", tmp[:owner])
|
||||
assert_equal("755", tmp[:mode])
|
||||
|
||||
# Now create a couple more classes.
|
||||
newbase = parser.newclass "newbase",
|
||||
:code => AST::ASTArray.new(
|
||||
:children => [resourcedef("file", "/tmp/other",
|
||||
"owner" => "nobody", "mode" => "644")]
|
||||
)
|
||||
|
||||
newsub = parser.newclass "newsub",
|
||||
:parent => "newbase",
|
||||
:code => AST::ASTArray.new(
|
||||
:children => [resourcedef("file", "/tmp/yay",
|
||||
"owner" => "nobody", "mode" => "755"),
|
||||
resourceoverride("file", "/tmp/other",
|
||||
"owner" => "daemon")
|
||||
]
|
||||
)
|
||||
|
||||
# Override a different variable in the top scope.
|
||||
moresub = parser.newclass "moresub",
|
||||
:parent => "newbase",
|
||||
:code => AST::ASTArray.new(
|
||||
:children => [resourceoverride("file", "/tmp/other",
|
||||
"mode" => "755")]
|
||||
)
|
||||
|
||||
assert_nothing_raised do
|
||||
newsub.evaluate_code(resource)
|
||||
end
|
||||
|
||||
assert_nothing_raised do
|
||||
moresub.evaluate_code(resource)
|
||||
end
|
||||
|
||||
assert(scope.compile.class_scope(newbase), "Did not eval newbase")
|
||||
assert(scope.compile.class_scope(newsub), "Did not eval newsub")
|
||||
|
||||
yay = scope.findresource("File[/tmp/yay]")
|
||||
assert(yay, "Did not find file /tmp/yay")
|
||||
assert_equal("nobody", yay[:owner])
|
||||
assert_equal("755", yay[:mode])
|
||||
|
||||
other = scope.findresource("File[/tmp/other]")
|
||||
assert(other, "Did not find file /tmp/other")
|
||||
assert_equal("daemon", other[:owner])
|
||||
assert_equal("755", other[:mode])
|
||||
end
|
||||
|
||||
# Make sure that classes set their namespaces to themselves. This
|
||||
# way they start looking for definitions in their own namespace.
|
||||
def test_hostclass_namespace
|
||||
scope = mkscope
|
||||
parser = scope.compile.parser
|
||||
|
||||
# Create a new class
|
||||
klass = nil
|
||||
assert_nothing_raised do
|
||||
klass = parser.newclass "funtest"
|
||||
end
|
||||
|
||||
# Now define a definition in that namespace
|
||||
|
||||
define = nil
|
||||
assert_nothing_raised do
|
||||
define = parser.newdefine "funtest::mydefine"
|
||||
end
|
||||
|
||||
assert_equal("funtest", klass.namespace,
|
||||
"component namespace was not set in the class")
|
||||
|
||||
assert_equal("funtest", define.namespace,
|
||||
"component namespace was not set in the definition")
|
||||
|
||||
newscope = klass.subscope(scope, mock("resource"))
|
||||
|
||||
assert_equal(["funtest"], newscope.namespaces,
|
||||
"Scope did not inherit namespace")
|
||||
|
||||
# Now make sure we can find the define
|
||||
assert(newscope.finddefine("mydefine"),
|
||||
"Could not find definition in my enclosing class")
|
||||
end
|
||||
|
||||
# Make sure that our scope is a subscope of the parentclass's scope.
|
||||
# At the same time, make sure definitions in the parent class can be
|
||||
# found within the subclass (#517).
|
||||
def test_parent_scope_from_parentclass
|
||||
scope = mkscope
|
||||
parser = scope.compile.parser
|
||||
|
||||
source = parser.newclass ""
|
||||
parser.newclass("base")
|
||||
fun = parser.newdefine("base::fun")
|
||||
parser.newclass("middle", :parent => "base")
|
||||
parser.newclass("sub", :parent => "middle")
|
||||
scope = mkscope :parser => parser
|
||||
|
||||
ret = nil
|
||||
assert_nothing_raised do
|
||||
ret = scope.compile.evaluate_classes(["sub"], scope)
|
||||
end
|
||||
scope.compile.send(:evaluate_generators)
|
||||
|
||||
subscope = scope.compile.class_scope(scope.findclass("sub"))
|
||||
assert(subscope, "could not find sub scope")
|
||||
mscope = scope.compile.class_scope(scope.findclass("middle"))
|
||||
assert(mscope, "could not find middle scope")
|
||||
pscope = scope.compile.class_scope(scope.findclass("base"))
|
||||
assert(pscope, "could not find parent scope")
|
||||
|
||||
assert(pscope == mscope.parent, "parent scope of middle was not set correctly")
|
||||
assert(mscope == subscope.parent, "parent scope of sub was not set correctly")
|
||||
|
||||
result = mscope.finddefine("fun")
|
||||
assert(result, "could not find parent-defined definition from middle")
|
||||
assert(fun == result, "found incorrect parent-defined definition from middle")
|
||||
|
||||
result = subscope.finddefine("fun")
|
||||
assert(result, "could not find parent-defined definition from sub")
|
||||
assert(fun == result, "found incorrect parent-defined definition from sub")
|
||||
end
|
||||
|
||||
# #795 - make sure the subclass's tags get set before we
|
||||
# evaluate the parent class, so we can be sure that the parent
|
||||
# class can switch based on the sub classes.
|
||||
def test_tags_set_before_parent_is_evaluated
|
||||
scope = mkscope
|
||||
parser = scope.compile.parser
|
||||
base = parser.newclass "base"
|
||||
sub = parser.newclass "sub", :parent => "base"
|
||||
|
||||
base.expects(:evaluate_code).with do |*args|
|
||||
assert(scope.catalog.tags.include?("sub"), "Did not tag with sub class name before evaluating base class")
|
||||
base.evaluate_code(*args)
|
||||
true
|
||||
end
|
||||
sub.evaluate_code scope.resource
|
||||
end
|
||||
end
|
Загрузка…
Ссылка в новой задаче