#!/usr/bin/env ruby
$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppet'
require 'puppet/rails'
require 'puppet/parser/interpreter'
require 'puppet/parser/parser'
require 'puppet/network/client'
require 'puppettest'
require 'puppettest/resourcetesting'
require 'puppettest/parsertesting'
require 'puppettest/railstesting'
class TestAST < Test::Unit::TestCase
include PuppetTest::RailsTesting
include PuppetTest::ParserTesting
include PuppetTest::ResourceTesting
if defined? ActiveRecord
# Verify that our collection stuff works.
def test_collection
collectable = []
non = []
# First put some objects into the database.
bucket = mk_transtree do |object, depth, width|
# and mark some of them collectable
if width % 2 == 1
object.collectable = true
collectable << object
else
non << object
end
end
# Now collect our facts
facts = {}
Facter.each do |fact, value| facts[fact] = value end
assert_nothing_raised {
Puppet::Rails.init
}
# Now try storing our crap
assert_nothing_raised {
host = Puppet::Rails::Host.store(
:objects => bucket,
:facts => facts,
:host => facts["hostname"]
)
}
# Now create an ast tree that collects that. They should all be files.
coll = nil
assert_nothing_raised {
coll = AST::Collection.new(
:type => nameobj("file")
)
}
top = nil
assert_nothing_raised("Could not create top object") {
top = AST::ASTArray.new(
:children => [coll]
)
}
objects = nil
assert_nothing_raised("Could not evaluate") {
scope = mkscope
objects = scope.evaluate(:ast => top).flatten
}
assert(objects.length > 0, "Did not receive any collected objects")
end
else
$stderr.puts "No ActiveRecord -- skipping collection tests"
end
def test_if
astif = nil
astelse = nil
fakeelse = FakeAST.new(:else)
faketest = FakeAST.new(true)
fakeif = FakeAST.new(:if)
assert_nothing_raised {
astelse = AST::Else.new(:statements => fakeelse)
}
assert_nothing_raised {
astif = AST::IfStatement.new(
:test => faketest,
:statements => fakeif,
:else => astelse
)
}
# We initialized it to true, so we should get that first
ret = nil
assert_nothing_raised {
ret = astif.evaluate(:scope => "yay")
}
assert_equal(:if, ret)
# Now set it to false and check that
faketest.evaluate = false
assert_nothing_raised {
ret = astif.evaluate(:scope => "yay")
}
assert_equal(:else, ret)
end
# Make sure our override object behaves "correctly"
def test_override
interp, scope, source = mkclassframing
ref = nil
assert_nothing_raised do
ref = resourceoverride("resource", "yaytest", "one" => "yay", "two" => "boo")
end
ret = nil
assert_nothing_raised do
ret = ref.evaluate :scope => scope
end
assert_instance_of(Puppet::Parser::Resource, ret)
assert(ret.override?, "Resource was not an override resource")
assert(scope.overridetable[ret.ref].include?(ret),
"Was not stored in the override table")
end
# make sure our resourcedefaults ast object works correctly.
def test_resourcedefaults
interp, scope, source = mkclassframing
# Now make some defaults for files
args = {:source => "/yay/ness", :group => "yayness"}
assert_nothing_raised do
obj = defaultobj "file", args
obj.evaluate :scope => scope
end
hash = nil
assert_nothing_raised do
hash = scope.lookupdefaults("file")
end
hash.each do |name, value|
assert_instance_of(Symbol, name) # params always convert
assert_instance_of(Puppet::Parser::Resource::Param, value)
end
args.each do |name, value|
assert(hash[name], "Did not get default %s" % name)
assert_equal(value, hash[name].value)
end
end
def test_node
interp = mkinterp
scope = mkscope(:interp => interp)
# Define a base node
basenode = interp.newnode "basenode", :code => AST::ASTArray.new(:children => [
resourcedef("file", "/tmp/base", "owner" => "root")
])
# Now define a subnode
nodes = interp.newnode ["mynode", "othernode"],
:code => AST::ASTArray.new(:children => [
resourcedef("file", "/tmp/mynode", "owner" => "root"),
resourcedef("file", "/tmp/basenode", "owner" => "daemon")
])
assert_instance_of(Array, nodes)
# Make sure we can find them all.
%w{mynode othernode}.each do |node|
assert(interp.nodesearch_code(node), "Could not find %s" % node)
end
mynode = interp.nodesearch_code("mynode")
# Now try evaluating the node
assert_nothing_raised do
mynode.evaluate :scope => scope
end
# Make sure that we can find each of the files
myfile = scope.findresource "File[/tmp/mynode]"
assert(myfile, "Could not find file from node")
assert_equal("root", myfile[:owner])
basefile = scope.findresource "File[/tmp/basenode]"
assert(basefile, "Could not find file from base node")
assert_equal("daemon", basefile[:owner])
# Now make sure we can evaluate nodes with parents
child = interp.newnode(%w{child}, :parent => "basenode").shift
newscope = mkscope :interp => interp
assert_nothing_raised do
child.evaluate :scope => newscope
end
assert(newscope.findresource("File[/tmp/base]"),
"Could not find base resource")
end
def test_collection
interp = mkinterp
scope = mkscope(:interp => interp)
coll = nil
assert_nothing_raised do
coll = AST::Collection.new(:type => "file", :form => :virtual)
end
assert_instance_of(AST::Collection, coll)
ret = nil
assert_nothing_raised do
ret = coll.evaluate :scope => scope
end
assert_instance_of(Puppet::Parser::Collector, ret)
# Now make sure we get it back from the scope
assert_equal([ret], scope.collections)
end
def test_virtual_collexp
@interp, @scope, @source = mkclassframing
# make a resource
resource = mkresource(:type => "file", :title => "/tmp/testing",
:params => {:owner => "root", :group => "bin", :mode => "644"})
run_collection_queries(:virtual) do |string, result, query|
code = nil
assert_nothing_raised do
str, code = query.evaluate :scope => @scope
end
assert_instance_of(Proc, code)
assert_nothing_raised do
assert_equal(result, code.call(resource),
"'#{string}' failed")
end
end
end
if defined? ActiveRecord::Base
def test_exported_collexp
railsinit
Puppet[:storeconfigs] = true
@interp, @scope, @source = mkclassframing
# make a rails resource
railsresource "file", "/tmp/testing", :owner => "root", :group => "bin",
:mode => "644"
run_collection_queries(:exported) do |string, result, query|
code = nil
str = nil
# We don't support anything but the title in rails right now
retval = nil
bad = false
# Figure out if the search is for anything rails will ignore
string.scan(/(\w+) [!=]= \w+/) do |s|
unless s[0] == "title"
bad = true
break
end
end
# And if it is, make sure we throw an error.
if bad
assert_raise(Puppet::ParseError, "Evaluated '#{string}'") do
str, code = query.evaluate :scope => @scope
end
next
else
assert_nothing_raised("Could not evaluate '#{string}'") do
str, code = query.evaluate :scope => @scope
end
end
assert_nothing_raised("Could not find resource") do
retval = Puppet::Rails::Resource.find(:all,
:include => :param_values,
:conditions => str)
end
if result
assert_equal(1, retval.length, "Did not find resource with '#{string}'")
res = retval.shift
assert_equal("file", res.restype)
assert_equal("/tmp/testing", res.title)
else
assert_equal(0, retval.length, "found a resource with '#{string}'")
end
end
end
end
def run_collection_queries(form)
{true => [%{title == "/tmp/testing"}, %{(title == "/tmp/testing")},
%{title == "/tmp/testing" and group == bin}, %{title == bin or group == bin},
%{title == "/tmp/testing" or title == bin}, %{title == "/tmp/testing"},
%{(title == "/tmp/testing" or title == bin) and group == bin}],
false => [%{title == bin}, %{title == bin or (title == bin and group == bin)},
%{title != "/tmp/testing"}, %{title != "/tmp/testing" and group != bin}]
}.each do |res, ary|
ary.each do |str|
if form == :virtual
code = "File <| #{str} |>"
else
code = "File <<| #{str} |>>"
end
parser = mkparser
query = nil
assert_nothing_raised("Could not parse '#{str}'") do
query = parser.parse(code)[0].query
end
yield str, res, query
end
end
end
end
# $Id: ast.rb 2296 2007-03-18 22:48:57Z luke $
syntax highlighted by Code2HTML, v. 0.9.1