Merge branch 'master' of git://michaelobrien.info/puppet into michael
This commit is contained in:
Коммит
32753e11d9
|
@ -1,4 +1,9 @@
|
|||
0.23.2 (misspiggy)
|
||||
The --use-nodes and --no-nodes options are now obsolete.
|
||||
Puppet automatically detects when nodes are defined, and if
|
||||
they are defined it will require that a node be found,
|
||||
else it will not look for a node nor will it fail if it
|
||||
fails to find one.
|
||||
|
||||
Fixed #832. Added the '--no-daemonize' option to puppetd and
|
||||
puppetmasterd. NOTE: The default behavior of 'verbose' and
|
||||
'debug' no longer cause puppetd and puppetmasterd to not
|
||||
|
@ -10,6 +15,7 @@
|
|||
|
||||
Added shortname support to config.rb and refactored addargs
|
||||
|
||||
0.23.2
|
||||
Fixed the problem in cron jobs where environment settings
|
||||
tended to multiple. (#749)
|
||||
|
||||
|
|
79
bin/puppet
79
bin/puppet
|
@ -80,14 +80,16 @@ Puppet.settings.addargs(options)
|
|||
|
||||
result = GetoptLong.new(*options)
|
||||
|
||||
debug = false
|
||||
verbose = false
|
||||
noop = false
|
||||
logfile = false
|
||||
loadclasses = false
|
||||
logset = false
|
||||
options = {
|
||||
:debug => false,
|
||||
:verbose => false,
|
||||
:noop => false,
|
||||
:logfile => false,
|
||||
:loadclasses => false,
|
||||
:logset => false,
|
||||
:code => nil
|
||||
}
|
||||
|
||||
code = nil
|
||||
|
||||
master = {
|
||||
:Local => true
|
||||
|
@ -107,19 +109,19 @@ begin
|
|||
exit
|
||||
end
|
||||
when "--use-nodes"
|
||||
master[:UseNodes] = true
|
||||
options[:UseNodes] = true
|
||||
when "--verbose"
|
||||
verbose = true
|
||||
options[:verbose] = true
|
||||
when "--debug"
|
||||
debug = true
|
||||
options[:debug] = true
|
||||
when "--execute"
|
||||
code = arg
|
||||
options[:code] = arg
|
||||
when "--loadclasses"
|
||||
loadclasses = true
|
||||
options[:loadclasses] = true
|
||||
when "--logdest"
|
||||
begin
|
||||
Puppet::Util::Log.newdestination(arg)
|
||||
logset = true
|
||||
options[:logset] = true
|
||||
rescue => detail
|
||||
$stderr.puts detail.to_s
|
||||
end
|
||||
|
@ -139,7 +141,7 @@ if Puppet[:noop]
|
|||
Puppet[:show_diff] = true
|
||||
end
|
||||
|
||||
unless logset
|
||||
unless options[:logset]
|
||||
Puppet::Util::Log.newdestination(:console)
|
||||
end
|
||||
|
||||
|
@ -148,9 +150,9 @@ server = nil
|
|||
|
||||
Puppet.settraps
|
||||
|
||||
if debug
|
||||
if options[:debug]
|
||||
Puppet::Util::Log.level = :debug
|
||||
elsif verbose
|
||||
elsif options[:verbose]
|
||||
Puppet::Util::Log.level = :info
|
||||
end
|
||||
|
||||
|
@ -162,18 +164,26 @@ end
|
|||
Puppet.genconfig
|
||||
Puppet.genmanifest
|
||||
|
||||
if code
|
||||
master[:Code] = code
|
||||
# Set our code or file to use.
|
||||
if options[:code] or ARGV.length == 0
|
||||
Puppet[:code] = options[:code] || STDIN.read
|
||||
else
|
||||
if ARGV.length > 0
|
||||
master[:Manifest] = ARGV.shift
|
||||
else
|
||||
master[:Code] = STDIN.read
|
||||
end
|
||||
Puppet[:manifest] = ARGV.shift
|
||||
end
|
||||
|
||||
# Collect our facts.
|
||||
Puppet::Node::Facts.terminus_class = :code
|
||||
facts = Puppet::Node::Facts.find("me")
|
||||
facts.name = facts.values["hostname"]
|
||||
|
||||
# Create our Node
|
||||
node = Puppet::Node.new(facts.name)
|
||||
|
||||
# Merge in the facts.
|
||||
node.merge(facts.values)
|
||||
|
||||
# Allow users to load the classes that puppetd creates.
|
||||
if loadclasses
|
||||
if options[:loadclasses]
|
||||
file = Puppet[:classfile]
|
||||
if FileTest.exists?(file)
|
||||
unless FileTest.readable?(file)
|
||||
|
@ -181,20 +191,21 @@ if loadclasses
|
|||
exit(63)
|
||||
end
|
||||
|
||||
master[:Classes] = File.read(file).split(/[\s\n]+/)
|
||||
node.classes = File.read(file).split(/[\s\n]+/)
|
||||
end
|
||||
end
|
||||
|
||||
# Compile and apply the configuration
|
||||
Puppet::Node::Configuration.terminus_class = :code
|
||||
|
||||
begin
|
||||
server = Puppet::Network::Handler.master.new(master)
|
||||
client = Puppet::Network::Client.master.new(
|
||||
:Master => server,
|
||||
:Cache => false
|
||||
)
|
||||
if Puppet[:parseonly]
|
||||
exit(0)
|
||||
end
|
||||
config = client.getconfig
|
||||
# Compile our configuration
|
||||
config = Puppet::Node::Configuration.find(node)
|
||||
|
||||
# Translate it to a RAL configuration
|
||||
config = config.to_ral
|
||||
|
||||
# And apply it
|
||||
config.apply
|
||||
rescue => detail
|
||||
if Puppet[:trace]
|
||||
|
|
|
@ -186,6 +186,9 @@ end
|
|||
Puppet.genconfig
|
||||
Puppet.genmanifest
|
||||
|
||||
# A temporary solution, to at least make the master work for now.
|
||||
Puppet::Node::Facts.terminus_class = :yaml
|
||||
|
||||
require 'etc'
|
||||
|
||||
handlers = {
|
||||
|
|
|
@ -150,14 +150,23 @@ unless setdest
|
|||
Puppet::Util::Log.newdestination(:syslog)
|
||||
end
|
||||
|
||||
master[:Manifest] = ARGV.shift
|
||||
Puppet[:manifest] = ARGV.shift
|
||||
|
||||
unless ENV.include?("CFALLCLASSES")
|
||||
$stderr.puts "Cfengine classes must be passed to the module"
|
||||
exit(15)
|
||||
end
|
||||
|
||||
master[:UseNodes] = false
|
||||
# Collect our facts.
|
||||
Puppet::Node::Facts.terminus_class = :code
|
||||
facts = Puppet::Node::Facts.find("me")
|
||||
facts.name = facts.values["hostname"]
|
||||
|
||||
# Create our Node
|
||||
node = Puppet::Node.new(facts.name)
|
||||
|
||||
# Merge in the facts.
|
||||
node.merge(facts.values)
|
||||
|
||||
classes = ENV["CFALLCLASSES"].split(":")
|
||||
|
||||
|
@ -166,32 +175,32 @@ if classes.empty?
|
|||
exit(16)
|
||||
end
|
||||
|
||||
master[:Classes] = classes
|
||||
node.classes = classes
|
||||
|
||||
begin
|
||||
server = Puppet::Network::Handler.master.new(master)
|
||||
# Compile our configuration
|
||||
config = Puppet::Node::Configuration.find(node)
|
||||
rescue => detail
|
||||
$stderr.puts detail
|
||||
if Puppet[:trace]
|
||||
puts detail.backtrace
|
||||
end
|
||||
if detail.is_a?(XMLRPC::FaultException)
|
||||
$stderr.puts detail.message
|
||||
else
|
||||
$stderr.puts detail
|
||||
end
|
||||
exit(1)
|
||||
end
|
||||
|
||||
begin
|
||||
client = Puppet::Network::Client.master.new(
|
||||
:Master => server,
|
||||
:Cache => false
|
||||
)
|
||||
rescue => detail
|
||||
$stderr.puts detail
|
||||
exit(1)
|
||||
end
|
||||
|
||||
|
||||
if parseonly
|
||||
exit(0)
|
||||
end
|
||||
|
||||
begin
|
||||
config = client.getconfig
|
||||
# Translate it to a RAL configuration
|
||||
config = config.to_ral
|
||||
|
||||
# And apply it
|
||||
config.apply
|
||||
rescue => detail
|
||||
Puppet.err detail
|
||||
|
|
|
@ -292,6 +292,9 @@ module Puppet
|
|||
"Where puppetmasterd looks for its manifests."],
|
||||
:manifest => ["$manifestdir/site.pp",
|
||||
"The entry-point manifest for puppetmasterd."],
|
||||
:code => ["", "Code to parse directly. This is essentially only used
|
||||
by ``puppet`, and should only be set if you're writing your own Puppet
|
||||
executable"],
|
||||
:masterlog => { :default => "$logdir/puppetmaster.log",
|
||||
:owner => "$user",
|
||||
:group => "$group",
|
||||
|
|
|
@ -251,12 +251,17 @@ module Puppet
|
|||
|
||||
def scope
|
||||
unless defined?(@scope)
|
||||
@interp = Puppet::Parser::Interpreter.new :Code => ""
|
||||
# Set the code to something innocuous; we just need the
|
||||
# scopes, not the interpreter. Hackish, but true.
|
||||
Puppet[:code] = " "
|
||||
@interp = Puppet::Parser::Interpreter.new
|
||||
require 'puppet/node'
|
||||
@node = Puppet::Node.new(Facter.value(:hostname))
|
||||
if env = Puppet[:environment] and env == ""
|
||||
env = nil
|
||||
end
|
||||
@node.parameters = Facter.to_hash
|
||||
@interp = Puppet::Parser::Interpreter.new :Code => ""
|
||||
@compile = Puppet::Parser::Compile.new(@node, @interp.send(:parser, Puppet[:environment]))
|
||||
@compile = Puppet::Parser::Compile.new(@node, @interp.send(:parser, env))
|
||||
@scope = @compile.topscope
|
||||
end
|
||||
@scope
|
||||
|
|
|
@ -15,7 +15,7 @@ module Puppet::Indirector
|
|||
# default, not the value -- if it's the value, then it gets
|
||||
# evaluated at parse time, which is before the user has had a chance
|
||||
# to override it.
|
||||
def indirects(indirection)
|
||||
def indirects(indirection, options = {})
|
||||
raise(ArgumentError, "Already handling indirection for %s; cannot also handle %s" % [@indirection.name, indirection]) if defined?(@indirection) and @indirection
|
||||
# populate this class with the various new methods
|
||||
extend ClassMethods
|
||||
|
@ -24,10 +24,29 @@ module Puppet::Indirector
|
|||
# instantiate the actual Terminus for that type and this name (:ldap, w/ args :node)
|
||||
# & hook the instantiated Terminus into this class (Node: @indirection = terminus)
|
||||
@indirection = Puppet::Indirector::Indirection.new(self, indirection)
|
||||
|
||||
unless options.empty?
|
||||
options.each do |param, value|
|
||||
case param
|
||||
when :terminus_class: @indirection.terminus_class = value
|
||||
else
|
||||
raise ArgumenError, "Invalid option '%s' to 'indirects'" % param
|
||||
end
|
||||
end
|
||||
end
|
||||
@indirection
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
attr_reader :indirection
|
||||
|
||||
def cache_class=(klass)
|
||||
indirection.cache_class = klass
|
||||
end
|
||||
|
||||
def terminus_class=(klass)
|
||||
indirection.terminus_class = klass
|
||||
end
|
||||
|
||||
def find(*args)
|
||||
indirection.find(*args)
|
||||
|
@ -43,6 +62,10 @@ module Puppet::Indirector
|
|||
end
|
||||
|
||||
module InstanceMethods
|
||||
# Make it easy for the model to set versions,
|
||||
# which are used for caching and such.
|
||||
attr_accessor :version
|
||||
|
||||
# these become instance methods
|
||||
def save(*args)
|
||||
self.class.indirection.save(self, *args)
|
||||
|
|
|
@ -15,24 +15,19 @@ class Puppet::Indirector::Code::Configuration < Puppet::Indirector::Code
|
|||
|
||||
# Compile a node's configuration.
|
||||
def find(key, client = nil, clientip = nil)
|
||||
# If we want to use the cert name as our key
|
||||
if Puppet[:node_name] == 'cert' and client
|
||||
key = client
|
||||
if key.is_a?(Puppet::Node)
|
||||
node = key
|
||||
else
|
||||
node = find_node(key)
|
||||
end
|
||||
|
||||
# Note that this is reasonable, because either their node source should actually
|
||||
# know about the node, or they should be using the ``none`` node source, which
|
||||
# will always return data.
|
||||
unless node = Puppet::Node.search(key)
|
||||
raise Puppet::Error, "Could not find node '%s'" % key
|
||||
if configuration = compile(node)
|
||||
return configuration.to_transportable
|
||||
else
|
||||
# This shouldn't actually happen; we should either return
|
||||
# a config or raise an exception.
|
||||
return nil
|
||||
end
|
||||
|
||||
# Add any external data to the node.
|
||||
add_node_data(node)
|
||||
|
||||
configuration = compile(node)
|
||||
|
||||
return configuration
|
||||
end
|
||||
|
||||
def initialize
|
||||
|
@ -47,6 +42,11 @@ class Puppet::Indirector::Code::Configuration < Puppet::Indirector::Code
|
|||
@interpreter
|
||||
end
|
||||
|
||||
# Is our compiler part of a network, or are we just local?
|
||||
def networked?
|
||||
$0 =~ /puppetmasterd/
|
||||
end
|
||||
|
||||
# Return the configuration version.
|
||||
def version(client = nil, clientip = nil)
|
||||
if client and node = Puppet::Node.search(client)
|
||||
|
@ -76,22 +76,14 @@ class Puppet::Indirector::Code::Configuration < Puppet::Indirector::Code
|
|||
end
|
||||
config = nil
|
||||
|
||||
# LAK:FIXME This should log at :none when our client is
|
||||
# local, since we don't want 'puppet' (vs. puppetmasterd) to
|
||||
# log compile times.
|
||||
benchmark(:notice, "Compiled configuration for %s" % node.name) do
|
||||
loglevel = networked? ? :notice : :none
|
||||
|
||||
benchmark(loglevel, "Compiled configuration for %s" % node.name) do
|
||||
begin
|
||||
config = interpreter.compile(node)
|
||||
rescue Puppet::Error => detail
|
||||
if Puppet[:trace]
|
||||
puts detail.backtrace
|
||||
end
|
||||
unless local?
|
||||
Puppet.err detail.to_s
|
||||
end
|
||||
raise XMLRPC::FaultException.new(
|
||||
1, detail.to_s
|
||||
)
|
||||
Puppet.err(detail.to_s) if networked?
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -100,21 +92,28 @@ class Puppet::Indirector::Code::Configuration < Puppet::Indirector::Code
|
|||
|
||||
# Create our interpreter object.
|
||||
def create_interpreter
|
||||
args = {}
|
||||
return Puppet::Parser::Interpreter.new
|
||||
end
|
||||
|
||||
# Allow specification of a code snippet or of a file
|
||||
if self.code
|
||||
args[:Code] = self.code
|
||||
end
|
||||
|
||||
# LAK:FIXME This needs to be handled somehow.
|
||||
#if options.include?(:UseNodes)
|
||||
# args[:UseNodes] = options[:UseNodes]
|
||||
#elsif @local
|
||||
# args[:UseNodes] = false
|
||||
# Turn our host name into a node object.
|
||||
def find_node(key)
|
||||
# If we want to use the cert name as our key
|
||||
# LAK:FIXME This needs to be figured out somehow, but it requires the routing.
|
||||
#if Puppet[:node_name] == 'cert' and client
|
||||
# key = client
|
||||
#end
|
||||
|
||||
return Puppet::Parser::Interpreter.new(args)
|
||||
# Note that this is reasonable, because either their node source should actually
|
||||
# know about the node, or they should be using the ``none`` node source, which
|
||||
# will always return data.
|
||||
unless node = Puppet::Node.search(key)
|
||||
raise Puppet::Error, "Could not find node '%s'" % key
|
||||
end
|
||||
|
||||
# Add any external data to the node.
|
||||
add_node_data(node)
|
||||
|
||||
node
|
||||
end
|
||||
|
||||
# Initialize our server fact hash; we add these to each client, and they
|
||||
|
@ -150,7 +149,7 @@ class Puppet::Indirector::Code::Configuration < Puppet::Indirector::Code
|
|||
# LAK:FIXME This method should probably be part of the protocol, but it
|
||||
# shouldn't be here.
|
||||
def translate(config)
|
||||
if local?
|
||||
unless networked?
|
||||
config
|
||||
else
|
||||
CGI.escape(config.to_yaml(:UseBlock => true))
|
||||
|
|
|
@ -90,12 +90,21 @@ class Puppet::Indirector::Indirection
|
|||
end
|
||||
end
|
||||
|
||||
def find(*args)
|
||||
terminus.find(*args)
|
||||
def find(key, *args)
|
||||
if cache? and cache.has_most_recent?(key, terminus.version(key))
|
||||
return cache.find(key, *args)
|
||||
end
|
||||
if result = terminus.find(key, *args)
|
||||
result.version ||= Time.now.utc
|
||||
if cache?
|
||||
Puppet.info "Caching %s %s" % [self.name, key]
|
||||
cache.save(result, *args)
|
||||
end
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
def destroy(*args)
|
||||
cache.destroy(*args) if cache?
|
||||
terminus.destroy(*args)
|
||||
end
|
||||
|
||||
|
@ -104,9 +113,12 @@ class Puppet::Indirector::Indirection
|
|||
end
|
||||
|
||||
# these become instance methods
|
||||
def save(*args)
|
||||
cache.save(*args) if cache?
|
||||
terminus.save(*args)
|
||||
def save(instance, *args)
|
||||
instance.version ||= Time.now.utc
|
||||
dest = cache? ? cache : terminus
|
||||
return if dest.has_most_recent?(instance.name, instance.version)
|
||||
cache.save(instance, *args) if cache?
|
||||
terminus.save(instance, *args)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -95,25 +95,52 @@ class Puppet::Indirector::Terminus
|
|||
end
|
||||
end
|
||||
|
||||
# Do we have an update for this object? This compares the provided version
|
||||
# to our version, and returns true if our version is at least as high
|
||||
# as the asked-about version.
|
||||
def has_most_recent?(key, vers)
|
||||
raise Puppet::DevError.new("Cannot check update status when no 'version' method is defined") unless respond_to?(:version)
|
||||
|
||||
if existing_version = version(key)
|
||||
#puts "%s fresh: %s (%s vs %s)" % [self.name, (existing_version.to_f >= vers.to_f).inspect, existing_version.to_f, vers.to_f]
|
||||
existing_version.to_f >= vers.to_f
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def indirection
|
||||
self.class.indirection
|
||||
end
|
||||
|
||||
def initialize
|
||||
if self.class.abstract_terminus?
|
||||
raise Puppet::DevError, "Cannot create instances of abstract terminus types"
|
||||
end
|
||||
end
|
||||
|
||||
def terminus_type
|
||||
self.class.terminus_type
|
||||
def model
|
||||
self.class.model
|
||||
end
|
||||
|
||||
def name
|
||||
self.class.name
|
||||
end
|
||||
|
||||
def model
|
||||
self.class.model
|
||||
def terminus_type
|
||||
self.class.terminus_type
|
||||
end
|
||||
|
||||
def indirection
|
||||
self.class.indirection
|
||||
# Provide a default method for retrieving an instance's version.
|
||||
# By default, just find the resource and get its version. Individual
|
||||
# terminus types can override this method to provide custom definitions of
|
||||
# 'versions'.
|
||||
def version(name)
|
||||
raise Puppet::DevError.new("Cannot retrieve an instance's version without a :find method") unless respond_to?(:find)
|
||||
if instance = find(name)
|
||||
instance.version
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,9 +14,9 @@ class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
|
|||
return nil unless FileTest.exist?(file)
|
||||
|
||||
begin
|
||||
return YAML.load(File.read(file))
|
||||
return from_yaml(File.read(file))
|
||||
rescue => detail
|
||||
raise Puppet::Error, "Could not read YAML data for %s(%s): %s" % [indirection.name, name, detail]
|
||||
raise Puppet::Error, "Could not read YAML data for %s %s: %s" % [indirection.name, name, detail]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -33,11 +33,23 @@ class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
|
|||
Dir.mkdir(basedir)
|
||||
end
|
||||
|
||||
File.open(file, "w", 0660) { |f| f.print YAML.dump(object) }
|
||||
begin
|
||||
File.open(file, "w", 0660) { |f| f.print to_yaml(object) }
|
||||
rescue TypeError => detail
|
||||
Puppet.err "Could not save %s %s: %s" % [self.name, object.name, detail]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def from_yaml(text)
|
||||
YAML.load(text)
|
||||
end
|
||||
|
||||
def to_yaml(object)
|
||||
YAML.dump(object)
|
||||
end
|
||||
|
||||
# Return the path to a given node's file.
|
||||
def path(name)
|
||||
File.join(Puppet[:yamldir], self.name.to_s, name.to_s + ".yaml")
|
||||
|
|
|
@ -2,4 +2,22 @@ require 'puppet/indirector/yaml'
|
|||
|
||||
class Puppet::Indirector::Yaml::Configuration < Puppet::Indirector::Yaml
|
||||
desc "Store configurations as flat files, serialized using YAML."
|
||||
|
||||
private
|
||||
|
||||
# Override these, because yaml doesn't want to convert our self-referential
|
||||
# objects. This is hackish, but eh.
|
||||
def from_yaml(text)
|
||||
if config = YAML.load(text)
|
||||
# We can't yaml-dump classes.
|
||||
#config.edgelist_class = Puppet::Relationship
|
||||
return config
|
||||
end
|
||||
end
|
||||
|
||||
def to_yaml(config)
|
||||
# We can't yaml-dump classes.
|
||||
#config.edgelist_class = nil
|
||||
YAML.dump(config)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -266,6 +266,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client
|
|||
self.getconfig
|
||||
end
|
||||
rescue => detail
|
||||
puts detail.backtrace if Puppet[:trace]
|
||||
Puppet.err "Could not retrieve configuration: %s" % detail
|
||||
end
|
||||
|
||||
|
@ -544,6 +545,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client
|
|||
end
|
||||
|
||||
rescue => detail
|
||||
puts detail.backtrace
|
||||
Puppet.err "Could not retrieve configuration: %s" % detail
|
||||
|
||||
unless Puppet[:usecacheonfailure]
|
||||
|
|
|
@ -13,7 +13,7 @@ class Puppet::Network::Handler
|
|||
|
||||
include Puppet::Util
|
||||
|
||||
attr_accessor :local
|
||||
attr_accessor :local, :classes
|
||||
|
||||
@interface = XMLRPC::Service::Interface.new("configuration") { |iface|
|
||||
iface.add_method("string configuration(string)")
|
||||
|
@ -43,17 +43,15 @@ class Puppet::Network::Handler
|
|||
end
|
||||
|
||||
def initialize(options = {})
|
||||
if options[:Local]
|
||||
@local = options[:Local]
|
||||
else
|
||||
@local = false
|
||||
options.each do |param, value|
|
||||
case param
|
||||
when :Classes: @classes = value
|
||||
when :Local: self.local = value
|
||||
else
|
||||
raise ArgumentError, "Configuration handler does not accept %s" % param
|
||||
end
|
||||
end
|
||||
|
||||
# Just store the options, rather than creating the interpreter
|
||||
# immediately. Mostly, this is so we can create the interpreter
|
||||
# on-demand, which is easier for testing.
|
||||
@options = options
|
||||
|
||||
set_server_facts
|
||||
end
|
||||
|
||||
|
@ -82,8 +80,8 @@ class Puppet::Network::Handler
|
|||
node.merge(@server_facts)
|
||||
|
||||
# Add any specified classes to the node's class list.
|
||||
if classes = @options[:Classes]
|
||||
classes.each do |klass|
|
||||
if @classes
|
||||
@classes.each do |klass|
|
||||
node.classes << klass
|
||||
end
|
||||
end
|
||||
|
@ -121,37 +119,14 @@ class Puppet::Network::Handler
|
|||
end
|
||||
|
||||
# Create our interpreter object.
|
||||
def create_interpreter(options)
|
||||
args = {}
|
||||
|
||||
# Allow specification of a code snippet or of a file
|
||||
if code = options[:Code]
|
||||
args[:Code] = code
|
||||
elsif options[:Manifest]
|
||||
args[:Manifest] = options[:Manifest]
|
||||
end
|
||||
|
||||
args[:Local] = local?
|
||||
|
||||
if options.include?(:UseNodes)
|
||||
args[:UseNodes] = options[:UseNodes]
|
||||
elsif @local
|
||||
args[:UseNodes] = false
|
||||
end
|
||||
|
||||
# This is only used by the cfengine module, or if --loadclasses was
|
||||
# specified in +puppet+.
|
||||
if options.include?(:Classes)
|
||||
args[:Classes] = options[:Classes]
|
||||
end
|
||||
|
||||
return Puppet::Parser::Interpreter.new(args)
|
||||
def create_interpreter
|
||||
return Puppet::Parser::Interpreter.new
|
||||
end
|
||||
|
||||
# Create/return our interpreter.
|
||||
def interpreter
|
||||
unless defined?(@interpreter) and @interpreter
|
||||
@interpreter = create_interpreter(@options)
|
||||
@interpreter = create_interpreter
|
||||
end
|
||||
@interpreter
|
||||
end
|
||||
|
|
|
@ -30,13 +30,6 @@ class Puppet::Network::Handler
|
|||
def initialize(hash = {})
|
||||
args = {}
|
||||
|
||||
# Allow specification of a code snippet or of a file
|
||||
if code = hash[:Code]
|
||||
args[:Code] = code
|
||||
elsif man = hash[:Manifest]
|
||||
args[:Manifest] = man
|
||||
end
|
||||
|
||||
if hash[:Local]
|
||||
@local = hash[:Local]
|
||||
else
|
||||
|
@ -53,12 +46,6 @@ class Puppet::Network::Handler
|
|||
|
||||
Puppet.debug("Creating interpreter")
|
||||
|
||||
if hash.include?(:UseNodes)
|
||||
args[:UseNodes] = hash[:UseNodes]
|
||||
elsif @local
|
||||
args[:UseNodes] = false
|
||||
end
|
||||
|
||||
# This is only used by the cfengine module, or if --loadclasses was
|
||||
# specified in +puppet+.
|
||||
if hash.include?(:Classes)
|
||||
|
@ -74,7 +61,7 @@ class Puppet::Network::Handler
|
|||
client, clientip = clientname(client, clientip, facts)
|
||||
|
||||
# Pass the facts to the fact handler
|
||||
Puppet::Node::Facts.new(client, facts).save
|
||||
Puppet::Node::Facts.new(client, facts).save unless local?
|
||||
|
||||
# And get the configuration from the config handler
|
||||
config = config_handler.configuration(client)
|
||||
|
|
|
@ -9,7 +9,7 @@ class Puppet::Node
|
|||
extend Puppet::Indirector
|
||||
|
||||
# Use the node source as the indirection terminus.
|
||||
indirects :node
|
||||
indirects :node, :terminus_class => :null
|
||||
|
||||
# Add the node-searching methods. This is what people will actually
|
||||
# interact with that will find the node with the list of names or
|
||||
|
|
|
@ -7,7 +7,7 @@ require 'puppet/external/gratr/digraph'
|
|||
# and the relationships between them.
|
||||
class Puppet::Node::Configuration < Puppet::PGraph
|
||||
extend Puppet::Indirector
|
||||
indirects :configuration
|
||||
indirects :configuration, :terminus_class => :code
|
||||
|
||||
# The host name this is a configuration for.
|
||||
attr_accessor :name
|
||||
|
@ -22,6 +22,10 @@ class Puppet::Node::Configuration < Puppet::PGraph
|
|||
# How we should extract the configuration for sending to the client.
|
||||
attr_reader :extraction_format
|
||||
|
||||
# We need the ability to set this externally, so we can yaml-dump the
|
||||
# configuration.
|
||||
attr_accessor :edgelist_class
|
||||
|
||||
# Whether this is a host configuration, which behaves very differently.
|
||||
# In particular, reports are sent, graphs are made, and state is
|
||||
# stored in the state database. If this is set incorrectly, then you often
|
||||
|
@ -355,6 +359,16 @@ class Puppet::Node::Configuration < Puppet::PGraph
|
|||
@tags.dup
|
||||
end
|
||||
|
||||
# Convert our configuration into a RAL configuration.
|
||||
def to_ral
|
||||
to_configuration :to_type
|
||||
end
|
||||
|
||||
# Turn our parser configuration into a transportable configuration.
|
||||
def to_transportable
|
||||
to_configuration :to_transobject
|
||||
end
|
||||
|
||||
# Produce the graph files if requested.
|
||||
def write_graph(name)
|
||||
# We only want to graph the main host configuration.
|
||||
|
@ -370,6 +384,14 @@ class Puppet::Node::Configuration < Puppet::PGraph
|
|||
}
|
||||
end
|
||||
|
||||
# LAK:NOTE We cannot yaml-dump the class in the edgelist_class, because classes cannot be
|
||||
# dumped by default, nor does yaml-dumping # the edge-labels work at this point (I don't
|
||||
# know why).
|
||||
# Neither of these matters right now, but I suppose it could at some point.
|
||||
def to_yaml_properties
|
||||
instance_variables.reject { |v| %w{@edgelist_class @edge_labels}.include?(v) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cleanup
|
||||
|
@ -379,4 +401,39 @@ class Puppet::Node::Configuration < Puppet::PGraph
|
|||
@relationship_graph = nil
|
||||
end
|
||||
end
|
||||
|
||||
# An abstracted method for converting one configuration into another type of configuration.
|
||||
# This pretty much just converts all of the resources from one class to another, using
|
||||
# a conversion method.
|
||||
def to_configuration(convert)
|
||||
result = self.class.new(self.name)
|
||||
|
||||
vertices.each do |resource|
|
||||
next if resource.respond_to?(:virtual?) and resource.virtual?
|
||||
|
||||
result.add_resource resource.send(convert)
|
||||
end
|
||||
|
||||
message = convert.to_s.gsub "_", " "
|
||||
edges.each do |edge|
|
||||
# Skip edges between virtual resources.
|
||||
next if edge.source.respond_to?(:virtual?) and edge.source.virtual?
|
||||
next if edge.target.respond_to?(:virtual?) and edge.target.virtual?
|
||||
|
||||
unless source = result.resource(edge.source.ref)
|
||||
raise Puppet::DevError, "Could not find vertex for %s when converting %s" % [edge.source.ref, message]
|
||||
end
|
||||
|
||||
unless target = result.resource(edge.target.ref)
|
||||
raise Puppet::DevError, "Could not find vertex for %s when converting %s" % [edge.target.ref, message]
|
||||
end
|
||||
|
||||
result.add_edge!(source, target, edge.label)
|
||||
end
|
||||
|
||||
result.add_class *self.classes
|
||||
result.tag(*self.tags)
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ class Puppet::Node::Facts
|
|||
extend Puppet::Indirector
|
||||
|
||||
# Use the node source as the indirection terminus.
|
||||
indirects :facts
|
||||
indirects :facts, :terminus_class => :code
|
||||
|
||||
attr_accessor :name, :values
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@ class Puppet::Parser::Compile
|
|||
include Puppet::Util::Errors
|
||||
attr_reader :topscope, :parser, :node, :facts, :collections, :configuration
|
||||
|
||||
attr_writer :ast_nodes
|
||||
|
||||
# Add a collection to the global list.
|
||||
def add_collection(coll)
|
||||
@collections << coll
|
||||
|
@ -25,7 +23,7 @@ class Puppet::Parser::Compile
|
|||
|
||||
# Do we use nodes found in the code, vs. the external node sources?
|
||||
def ast_nodes?
|
||||
defined?(@ast_nodes) and @ast_nodes
|
||||
parser.nodes.length > 0
|
||||
end
|
||||
|
||||
# Store the fact that we've evaluated a class, and store a reference to
|
||||
|
|
|
@ -14,7 +14,6 @@ class Puppet::Parser::Interpreter
|
|||
include Puppet::Util
|
||||
|
||||
attr_accessor :usenodes
|
||||
attr_accessor :code, :file
|
||||
|
||||
include Puppet::Util::Errors
|
||||
|
||||
|
@ -26,21 +25,11 @@ class Puppet::Parser::Interpreter
|
|||
# evaluate our whole tree
|
||||
def compile(node)
|
||||
raise Puppet::ParseError, "Could not parse configuration; cannot compile" unless env_parser = parser(node.environment)
|
||||
return Puppet::Parser::Compile.new(node, env_parser, :ast_nodes => usenodes?).compile
|
||||
return Puppet::Parser::Compile.new(node, env_parser).compile
|
||||
end
|
||||
|
||||
# create our interpreter
|
||||
def initialize(options = {})
|
||||
if @code = options[:Code]
|
||||
elsif @file = options[:Manifest]
|
||||
end
|
||||
|
||||
if options.include?(:UseNodes)
|
||||
@usenodes = options[:UseNodes]
|
||||
else
|
||||
@usenodes = true
|
||||
end
|
||||
|
||||
def initialize
|
||||
# The class won't always be defined during testing.
|
||||
if Puppet[:storeconfigs]
|
||||
if Puppet.features.rails?
|
||||
|
@ -53,21 +42,14 @@ class Puppet::Parser::Interpreter
|
|||
@parsers = {}
|
||||
end
|
||||
|
||||
# Should we parse ast nodes?
|
||||
def usenodes?
|
||||
defined?(@usenodes) and @usenodes
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Create a new parser object and pre-parse the configuration.
|
||||
def create_parser(environment)
|
||||
begin
|
||||
parser = Puppet::Parser::Parser.new(:environment => environment)
|
||||
if self.code
|
||||
parser.string = self.code
|
||||
elsif self.file
|
||||
parser.file = self.file
|
||||
if code = Puppet.settings.value(:code, environment) and code != ""
|
||||
parser.string = code
|
||||
else
|
||||
file = Puppet.settings.value(:manifest, environment)
|
||||
parser.file = file
|
||||
|
|
|
@ -366,10 +366,12 @@ class Puppet::Parser::Parser
|
|||
end
|
||||
|
||||
def on_error(token,value,stack)
|
||||
#on '%s' at '%s' in\n'%s'" % [token,value,stack]
|
||||
#error = "line %s: parse error after '%s'" %
|
||||
# [@lexer.line,@lexer.last]
|
||||
error = "Syntax error at '%s'" % [value]
|
||||
if token == 0 # denotes end of file
|
||||
value = 'end of file'
|
||||
else
|
||||
value = "'%s'" % value
|
||||
end
|
||||
error = "Syntax error at %s" % [value]
|
||||
|
||||
if brace = @lexer.expected
|
||||
error += "; expected '%s'" % brace
|
||||
|
|
|
@ -190,6 +190,10 @@ class Puppet::PGraph < GRATR::Digraph
|
|||
return result
|
||||
end
|
||||
|
||||
def to_yaml_properties
|
||||
instance_variables
|
||||
end
|
||||
|
||||
# A different way of walking a tree, and a much faster way than the
|
||||
# one that comes with GRATR.
|
||||
def tree_from_vertex2(start, direction = :out)
|
||||
|
|
|
@ -55,7 +55,7 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
|
|||
|
||||
# The common package name format.
|
||||
def package_name
|
||||
"%s/%s" % [@resource[:category], @resource[:name]]
|
||||
@resource[:category] ? "%s/%s" % [@resource[:category], @resource[:name]] : @resource[:name]
|
||||
end
|
||||
|
||||
def uninstall
|
||||
|
@ -71,7 +71,7 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
|
|||
result_fields = [:category, :name, :ensure, :version_available, :slot, :vendor, :description]
|
||||
|
||||
search_field = @resource[:category] ? "--category-name" : "--name"
|
||||
search_value = @resource[:category] ? package_name : @resource[:name]
|
||||
search_value = package_name
|
||||
search_format = "<category> <name> [<installedversionsshort>] [<best>] <homepage> <description>"
|
||||
|
||||
begin
|
||||
|
|
|
@ -17,7 +17,7 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
|
|||
|
||||
# If it's enabled, then it will print output showing removal of
|
||||
# links.
|
||||
if output =~ /etc\/rc[\dS].d|Nothing to do\./
|
||||
if output =~ /etc\/rc[\dS].d|not installed/
|
||||
return :true
|
||||
else
|
||||
return :false
|
||||
|
|
|
@ -8,7 +8,7 @@ module Puppet
|
|||
# YAML.
|
||||
class TransObject
|
||||
include Enumerable
|
||||
attr_accessor :type, :name, :file, :line, :collectable, :collected
|
||||
attr_accessor :type, :name, :file, :line, :configuration
|
||||
|
||||
attr_writer :tags
|
||||
|
||||
|
@ -25,7 +25,6 @@ module Puppet
|
|||
def initialize(name,type)
|
||||
@type = type
|
||||
@name = name
|
||||
@collectable = false
|
||||
@params = {}
|
||||
@tags = []
|
||||
end
|
||||
|
@ -34,10 +33,44 @@ module Puppet
|
|||
return [@type,@name].join('--')
|
||||
end
|
||||
|
||||
def ref
|
||||
unless defined? @ref
|
||||
if @type == :component
|
||||
@ref = @name
|
||||
else
|
||||
@ref = "%s[%s]" % [type_capitalized, name]
|
||||
end
|
||||
end
|
||||
@ref
|
||||
end
|
||||
|
||||
def tags
|
||||
return @tags
|
||||
end
|
||||
|
||||
# Convert a defined type into a component.
|
||||
def to_component
|
||||
tmpname = nil
|
||||
|
||||
# Nodes have the same name and type
|
||||
if self.name
|
||||
tmpname = "%s[%s]" % [type_capitalized, self.name]
|
||||
else
|
||||
tmpname = @type
|
||||
end
|
||||
trans = TransObject.new(tmpname, :component)
|
||||
if defined? @parameters
|
||||
@parameters.each { |param,value|
|
||||
Puppet.debug "Defining %s on %s of type %s" %
|
||||
[param,@name,@type]
|
||||
trans[param] = value
|
||||
}
|
||||
else
|
||||
#Puppet.debug "%s[%s] has no parameters" % [@type, @name]
|
||||
end
|
||||
Puppet::Type::Component.create(trans)
|
||||
end
|
||||
|
||||
def to_hash
|
||||
@params.dup
|
||||
end
|
||||
|
@ -57,18 +90,18 @@ module Puppet
|
|||
end
|
||||
|
||||
def to_yaml_properties
|
||||
instance_variables
|
||||
instance_variables.reject { |v| %w{@ref}.include?(v) }
|
||||
end
|
||||
|
||||
def to_ref
|
||||
unless defined? @ref
|
||||
unless defined? @res_ref
|
||||
if self.type and self.name
|
||||
@ref = "%s[%s]" % [self.type, self.name]
|
||||
@res_ref = "%s[%s]" % [type_capitalized, self.name]
|
||||
else
|
||||
@ref = nil
|
||||
@res_ref = nil
|
||||
end
|
||||
end
|
||||
@ref
|
||||
@res_ref
|
||||
end
|
||||
|
||||
def to_type
|
||||
|
@ -85,11 +118,16 @@ module Puppet
|
|||
end
|
||||
end
|
||||
else
|
||||
raise Puppet::Error.new("Could not find object type %s" % self.type)
|
||||
return to_component
|
||||
end
|
||||
|
||||
return retobj
|
||||
end
|
||||
|
||||
# Return the type fully capitalized correctly.
|
||||
def type_capitalized
|
||||
type.split("::").collect { |s| s.capitalize }.join("::")
|
||||
end
|
||||
end
|
||||
|
||||
# Just a linear container for objects. Behaves mostly like an array, except
|
||||
|
@ -107,20 +145,6 @@ module Puppet
|
|||
end
|
||||
}
|
||||
|
||||
# Remove all collectable objects from our tree, since the client
|
||||
# should not see them.
|
||||
def collectstrip!
|
||||
@children.dup.each do |child|
|
||||
if child.is_a? self.class
|
||||
child.collectstrip!
|
||||
else
|
||||
if child.collectable and ! child.collected
|
||||
@children.delete(child)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Recursively yield everything.
|
||||
def delve(&block)
|
||||
@children.each do |obj|
|
||||
|
|
|
@ -109,14 +109,6 @@ Puppet::Type.newtype(:component) do
|
|||
@children = []
|
||||
end
|
||||
|
||||
def parent=(parent)
|
||||
if self.parentof?(parent)
|
||||
devfail "%s[%s] is already the parent of %s[%s]" %
|
||||
[self.class.name, self.title, parent.class.name, parent.title]
|
||||
end
|
||||
@parent = parent
|
||||
end
|
||||
|
||||
# Add a hook for testing for recursion.
|
||||
def parentof?(child)
|
||||
if super(child)
|
||||
|
@ -133,7 +125,7 @@ Puppet::Type.newtype(:component) do
|
|||
def pathbuilder
|
||||
tmp = []
|
||||
myname = ""
|
||||
if self.title =~ /^class\[(.+)\]$/
|
||||
if self.title =~ /^class\[(.+)\]$/i
|
||||
# 'main' is the top class, so we want to see '//' instead of
|
||||
# its name.
|
||||
unless $1 == "main"
|
||||
|
|
|
@ -9,7 +9,7 @@ speclibdir = File.join(basedir, "lib")
|
|||
|
||||
desc "Run all spec unit tests"
|
||||
Spec::Rake::SpecTask.new('unit') do |t|
|
||||
t.spec_files = FileList['unit/**/*.rb']
|
||||
t.spec_files = FileList['unit/**/*.rb', 'integration/**/*.rb']
|
||||
t.libs = [puppetlibdir, puppettestlibdir, speclibdir]
|
||||
end
|
||||
|
||||
|
|
|
@ -9,8 +9,7 @@ require 'puppet/checksum'
|
|||
|
||||
describe Puppet::Checksum, " when using the file terminus" do
|
||||
before do
|
||||
Puppet[:checksum_terminus] = "file"
|
||||
|
||||
Puppet::Checksum.terminus_class = :file
|
||||
@content = "this is some content"
|
||||
@sum = Puppet::Checksum.new(@content)
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ require 'puppet/node'
|
|||
describe Puppet::Node, " when using the memory terminus" do
|
||||
before do
|
||||
@name = "me"
|
||||
Puppet::Node.terminus_class = :memory
|
||||
@node = Puppet::Node.new(@name)
|
||||
Puppet[:node_terminus] = "memory"
|
||||
end
|
||||
|
||||
it "should find no nodes by default" do
|
||||
|
|
|
@ -39,6 +39,11 @@ describe Puppet::Indirector::Code::Configuration do
|
|||
compiler.find('node1')
|
||||
compiler.find('node2')
|
||||
end
|
||||
|
||||
it "should provide a method for determining if the configuration is networked" do
|
||||
compiler = Puppet::Indirector::Code::Configuration.new
|
||||
compiler.should respond_to(:networked?)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Indirector::Code::Configuration, " when creating the interpreter" do
|
||||
|
@ -48,29 +53,16 @@ describe Puppet::Indirector::Code::Configuration, " when creating the interprete
|
|||
|
||||
it "should not create the interpreter until it is asked for the first time" do
|
||||
interp = mock 'interp'
|
||||
Puppet::Parser::Interpreter.expects(:new).with({}).returns(interp)
|
||||
Puppet::Parser::Interpreter.expects(:new).with().returns(interp)
|
||||
@compiler.interpreter.should equal(interp)
|
||||
end
|
||||
|
||||
it "should use the same interpreter for all compiles" do
|
||||
interp = mock 'interp'
|
||||
Puppet::Parser::Interpreter.expects(:new).with({}).returns(interp)
|
||||
Puppet::Parser::Interpreter.expects(:new).with().returns(interp)
|
||||
@compiler.interpreter.should equal(interp)
|
||||
@compiler.interpreter.should equal(interp)
|
||||
end
|
||||
|
||||
it "should provide a mechanism for setting the code to pass to the interpreter" do
|
||||
@compiler.should respond_to(:code=)
|
||||
end
|
||||
|
||||
it "should pass any specified code on to the interpreter when it is being initialized" do
|
||||
code = "some code"
|
||||
@compiler.code = code
|
||||
interp = mock 'interp'
|
||||
Puppet::Parser::Interpreter.expects(:new).with(:Code => code).returns(interp)
|
||||
@compiler.send(:interpreter).should equal(interp)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe Puppet::Indirector::Code::Configuration, " when finding nodes" do
|
||||
|
@ -132,10 +124,17 @@ describe Puppet::Indirector::Code::Configuration, " when creating configurations
|
|||
before do
|
||||
@compiler = Puppet::Indirector::Code::Configuration.new
|
||||
@name = "me"
|
||||
@node = stub 'node', :merge => nil, :name => @name, :environment => "yay"
|
||||
@node = Puppet::Node.new @name, :environment => "yay"
|
||||
@node.stubs(:merge)
|
||||
Puppet::Node.stubs(:search).with(@name).returns(@node)
|
||||
end
|
||||
|
||||
it "should directly use provided nodes" do
|
||||
Puppet::Node.expects(:search).never
|
||||
@compiler.interpreter.expects(:compile).with(@node)
|
||||
@compiler.find(@node)
|
||||
end
|
||||
|
||||
it "should pass the found node to the interpreter for compiling" do
|
||||
config = mock 'config'
|
||||
@compiler.interpreter.expects(:compile).with(@node)
|
||||
|
@ -144,11 +143,14 @@ describe Puppet::Indirector::Code::Configuration, " when creating configurations
|
|||
|
||||
it "should return the results of compiling as the configuration" do
|
||||
config = mock 'config'
|
||||
@compiler.interpreter.expects(:compile).with(@node).returns(:configuration)
|
||||
result = mock 'result', :to_transportable => :configuration
|
||||
|
||||
@compiler.interpreter.expects(:compile).with(@node).returns(result)
|
||||
@compiler.find(@name).should == :configuration
|
||||
end
|
||||
|
||||
it "should benchmark the compile process" do
|
||||
@compiler.stubs(:networked?).returns(true)
|
||||
@compiler.expects(:benchmark).with do |level, message|
|
||||
level == :notice and message =~ /^Compiled configuration/
|
||||
end
|
||||
|
|
|
@ -7,28 +7,62 @@ require 'puppet/indirector'
|
|||
describe Puppet::Indirector::Indirection do
|
||||
before do
|
||||
@indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
|
||||
@terminus = mock 'terminus'
|
||||
@terminus = stub 'terminus', :has_most_recent? => false
|
||||
@indirection.stubs(:terminus).returns(@terminus)
|
||||
@instance = stub 'instance', :version => nil, :version= => nil, :name => "whatever"
|
||||
@name = :mything
|
||||
end
|
||||
|
||||
it "should not attempt to set a timestamp if the terminus cannot find the instance" do
|
||||
@terminus.expects(:find).with(@name).returns(nil)
|
||||
proc { @indirection.find(@name) }.should_not raise_error
|
||||
end
|
||||
|
||||
it "should handle lookups of a model instance by letting the appropriate terminus perform the lookup" do
|
||||
@terminus.expects(:find).with(:mything).returns(:whev)
|
||||
@indirection.find(:mything).should == :whev
|
||||
@terminus.expects(:find).with(@name).returns(@instance)
|
||||
@indirection.find(@name).should == @instance
|
||||
end
|
||||
|
||||
it "should handle removing model instances from a terminus letting the appropriate terminus remove the instance" do
|
||||
@terminus.expects(:destroy).with(:mything).returns(:whev)
|
||||
@indirection.destroy(:mything).should == :whev
|
||||
@terminus.expects(:destroy).with(@name).returns(@instance)
|
||||
@indirection.destroy(@name).should == @instance
|
||||
end
|
||||
|
||||
it "should handle searching for model instances by letting the appropriate terminus find the matching instances" do
|
||||
@terminus.expects(:search).with(:mything).returns(:whev)
|
||||
@indirection.search(:mything).should == :whev
|
||||
@terminus.expects(:search).with(@name).returns(@instance)
|
||||
@indirection.search(@name).should == @instance
|
||||
end
|
||||
|
||||
it "should handle storing a model instance by letting the appropriate terminus store the instance" do
|
||||
@terminus.expects(:save).with(:mything).returns(:whev)
|
||||
@indirection.save(:mything).should == :whev
|
||||
@terminus.expects(:save).with(@instance).returns(@instance)
|
||||
@indirection.save(@instance).should == @instance
|
||||
end
|
||||
|
||||
it "should add versions to found instances that do not already have them" do
|
||||
@terminus.expects(:find).with(@name).returns(@instance)
|
||||
time = mock 'time'
|
||||
time.expects(:utc).returns(:mystamp)
|
||||
Time.expects(:now).returns(time)
|
||||
@instance.expects(:version=).with(:mystamp)
|
||||
@indirection.find(@name)
|
||||
end
|
||||
|
||||
it "should add versions to saved instances that do not already have them" do
|
||||
time = mock 'time'
|
||||
time.expects(:utc).returns(:mystamp)
|
||||
Time.expects(:now).returns(time)
|
||||
@instance.expects(:version=).with(:mystamp)
|
||||
@terminus.stubs(:save)
|
||||
@indirection.save(@instance)
|
||||
end
|
||||
|
||||
# We've already tested this, basically, but...
|
||||
it "should use the current time in UTC for versions" do
|
||||
@instance.expects(:version=).with do |time|
|
||||
time.utc?
|
||||
end
|
||||
@terminus.stubs(:save)
|
||||
@indirection.save(@instance)
|
||||
end
|
||||
|
||||
after do
|
||||
|
@ -189,33 +223,14 @@ describe Puppet::Indirector::Indirection, " when deciding whether to cache" do
|
|||
proc { @indirection.cache_class = :foo }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "should not use a cache if there no cache setting" do
|
||||
@indirection.expects(:cache).never
|
||||
@terminus.stubs(:save)
|
||||
@indirection.save(:whev)
|
||||
end
|
||||
|
||||
it "should use a cache if a cache was configured" do
|
||||
cache = mock 'cache'
|
||||
cache.expects(:save).with(:whev)
|
||||
|
||||
cache_class = mock 'cache class'
|
||||
cache_class.expects(:new).returns(cache)
|
||||
Puppet::Indirector::Terminus.stubs(:terminus_class).with(:mycache, :test).returns(cache_class)
|
||||
|
||||
@indirection.cache_class = :mycache
|
||||
@terminus.stubs(:save)
|
||||
@indirection.save(:whev)
|
||||
end
|
||||
|
||||
after do
|
||||
@indirection.delete
|
||||
Puppet::Indirector::Indirection.clear_cache
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Indirector::Indirection, " when using a cache" do
|
||||
before do
|
||||
module IndirectionCaching
|
||||
def setup
|
||||
Puppet.settings.stubs(:value).with("test_terminus").returns("test_terminus")
|
||||
@terminus_class = mock 'terminus_class'
|
||||
@terminus = mock 'terminus'
|
||||
|
@ -228,13 +243,14 @@ describe Puppet::Indirector::Indirection, " when using a cache" do
|
|||
@indirection.terminus_class = :test_terminus
|
||||
end
|
||||
|
||||
it "should copy all writing indirection calls to the cache terminus" do
|
||||
@cache_class.expects(:new).returns(@cache)
|
||||
@indirection.cache_class = :cache_terminus
|
||||
@cache.expects(:save).with(:whev)
|
||||
@terminus.stubs(:save)
|
||||
@indirection.save(:whev)
|
||||
def teardown
|
||||
@indirection.delete
|
||||
Puppet::Indirector::Indirection.clear_cache
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Indirector::Indirection, " when managing the cache terminus" do
|
||||
include IndirectionCaching
|
||||
|
||||
it "should not create a cache terminus at initialization" do
|
||||
# This is weird, because all of the code is in the setup. If we got
|
||||
|
@ -257,9 +273,77 @@ describe Puppet::Indirector::Indirection, " when using a cache" do
|
|||
@indirection.clear_cache
|
||||
@indirection.cache.should equal(cache2)
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
@indirection.delete
|
||||
Puppet::Indirector::Indirection.clear_cache
|
||||
describe Puppet::Indirector::Indirection, " when saving and using a cache" do
|
||||
include IndirectionCaching
|
||||
|
||||
before do
|
||||
@indirection.cache_class = :cache_terminus
|
||||
@cache_class.expects(:new).returns(@cache)
|
||||
@name = "testing"
|
||||
@instance = stub 'instance', :version => 5, :name => @name
|
||||
end
|
||||
|
||||
it "should not update the cache or terminus if the new object is not different" do
|
||||
@cache.expects(:has_most_recent?).with(@name, 5).returns(true)
|
||||
@indirection.save(@instance)
|
||||
end
|
||||
|
||||
it "should update the original and the cache if the cached object is different" do
|
||||
@cache.expects(:has_most_recent?).with(@name, 5).returns(false)
|
||||
@terminus.expects(:save).with(@instance)
|
||||
@cache.expects(:save).with(@instance)
|
||||
@indirection.save(@instance)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Indirector::Indirection, " when finding and using a cache" do
|
||||
include IndirectionCaching
|
||||
|
||||
before do
|
||||
@indirection.cache_class = :cache_terminus
|
||||
@cache_class.expects(:new).returns(@cache)
|
||||
end
|
||||
|
||||
it "should return the cached object if the cache is up to date" do
|
||||
cached = mock 'cached object'
|
||||
|
||||
name = "myobject"
|
||||
|
||||
@terminus.expects(:version).with(name).returns(1)
|
||||
@cache.expects(:has_most_recent?).with(name, 1).returns(true)
|
||||
|
||||
@cache.expects(:find).with(name).returns(cached)
|
||||
|
||||
@indirection.find(name).should equal(cached)
|
||||
end
|
||||
|
||||
it "should return the original object if the cache is not up to date" do
|
||||
real = stub 'real object', :version => 1
|
||||
|
||||
name = "myobject"
|
||||
|
||||
@cache.stubs(:save)
|
||||
@cache.expects(:has_most_recent?).with(name, 1).returns(false)
|
||||
@terminus.expects(:version).with(name).returns(1)
|
||||
|
||||
@terminus.expects(:find).with(name).returns(real)
|
||||
|
||||
@indirection.find(name).should equal(real)
|
||||
end
|
||||
|
||||
it "should cache any newly returned objects" do
|
||||
real = stub 'real object', :version => 1
|
||||
|
||||
name = "myobject"
|
||||
|
||||
@terminus.expects(:version).with(name).returns(1)
|
||||
@cache.expects(:has_most_recent?).with(name, 1).returns(false)
|
||||
|
||||
@terminus.expects(:find).with(name).returns(real)
|
||||
@cache.expects(:save).with(real)
|
||||
|
||||
@indirection.find(name).should equal(real)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,43 +44,68 @@ describe Puppet::Indirector, "when registering an indirection" do
|
|||
@thingie.indirection.should equal(@indirection)
|
||||
end
|
||||
|
||||
it "should allow specification of a default terminus" do
|
||||
klass = mock 'terminus class'
|
||||
Puppet::Indirector::Terminus.stubs(:terminus_class).with(:foo, :first).returns(klass)
|
||||
@indirection = @thingie.indirects :first, :terminus_class => :foo
|
||||
@indirection.terminus_class.should == :foo
|
||||
end
|
||||
|
||||
after do
|
||||
@indirection.delete if @indirection
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Indirector, " when redirecting a model" do
|
||||
before do
|
||||
@thingie = Class.new do
|
||||
extend Puppet::Indirector
|
||||
before do
|
||||
@thingie = Class.new do
|
||||
extend Puppet::Indirector
|
||||
end
|
||||
@indirection = @thingie.send(:indirects, :test)
|
||||
end
|
||||
@mock_terminus = mock('Terminus')
|
||||
@indirection = @thingie.send(:indirects, :test)
|
||||
@thingie.expects(:indirection).returns(@mock_terminus)
|
||||
end
|
||||
|
||||
it "should give the model the ability to lookup a model instance by letting the indirection perform the lookup" do
|
||||
@mock_terminus.expects(:find)
|
||||
@thingie.find
|
||||
end
|
||||
|
||||
it "should give the model the ability to remove model instances from a terminus by letting the indirection remove the instance" do
|
||||
@mock_terminus.expects(:destroy)
|
||||
@thingie.destroy
|
||||
end
|
||||
|
||||
it "should give the model the ability to search for model instances by letting the indirection find the matching instances" do
|
||||
@mock_terminus.expects(:search)
|
||||
@thingie.search
|
||||
end
|
||||
|
||||
it "should give the model the ability to store a model instance by letting the indirection store the instance" do
|
||||
thing = @thingie.new
|
||||
@mock_terminus.expects(:save).with(thing)
|
||||
thing.save
|
||||
end
|
||||
it "should give the model the ability set a version" do
|
||||
thing = @thingie.new
|
||||
thing.should respond_to(:version=)
|
||||
end
|
||||
|
||||
after do
|
||||
@indirection.delete
|
||||
end
|
||||
it "should give the model the ability retrieve a version" do
|
||||
thing = @thingie.new
|
||||
thing.should respond_to(:version)
|
||||
end
|
||||
|
||||
it "should give the model the ability to lookup a model instance by letting the indirection perform the lookup" do
|
||||
@indirection.expects(:find)
|
||||
@thingie.find
|
||||
end
|
||||
|
||||
it "should give the model the ability to remove model instances from a terminus by letting the indirection remove the instance" do
|
||||
@indirection.expects(:destroy)
|
||||
@thingie.destroy
|
||||
end
|
||||
|
||||
it "should give the model the ability to search for model instances by letting the indirection find the matching instances" do
|
||||
@indirection.expects(:search)
|
||||
@thingie.search
|
||||
end
|
||||
|
||||
it "should give the model the ability to store a model instance by letting the indirection store the instance" do
|
||||
thing = @thingie.new
|
||||
@indirection.expects(:save).with(thing)
|
||||
thing.save
|
||||
end
|
||||
|
||||
it "should give the model the ability to set the indirection terminus class" do
|
||||
@indirection.expects(:terminus_class=).with(:myterm)
|
||||
@thingie.terminus_class = :myterm
|
||||
end
|
||||
|
||||
it "should give the model the ability to set the indirection cache class" do
|
||||
@indirection.expects(:cache_class=).with(:mycache)
|
||||
@thingie.cache_class = :mycache
|
||||
end
|
||||
|
||||
after do
|
||||
@indirection.delete
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require File.dirname(__FILE__) + '/../../spec_helper'
|
||||
require 'puppet/defaults'
|
||||
require 'puppet/indirector'
|
||||
|
@ -200,8 +202,8 @@ describe Puppet::Indirector::Terminus, " when creating terminus classes" do
|
|||
end
|
||||
end
|
||||
|
||||
describe Puppet::Indirector::Terminus, " when a terminus instance" do
|
||||
before do
|
||||
module TerminusInstanceTesting
|
||||
def setup
|
||||
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
|
||||
@indirection = stub 'indirection', :name => :myyaml, :register_terminus_type => nil
|
||||
Puppet::Indirector::Indirection.stubs(:instance).with(:my_stuff).returns(@indirection)
|
||||
|
@ -218,6 +220,10 @@ describe Puppet::Indirector::Terminus, " when a terminus instance" do
|
|||
@terminus_class.name = :test
|
||||
@terminus = @terminus_class.new
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Indirector::Terminus, " when a terminus instance" do
|
||||
include TerminusInstanceTesting
|
||||
|
||||
it "should return the class's name as its name" do
|
||||
@terminus.name.should == :test
|
||||
|
@ -236,3 +242,58 @@ describe Puppet::Indirector::Terminus, " when a terminus instance" do
|
|||
@terminus.model.should == :yay
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Indirector::Terminus, " when managing indirected instances" do
|
||||
include TerminusInstanceTesting
|
||||
|
||||
it "should support comparing an instance's version with the terminus's version using just the instance's key" do
|
||||
@terminus.should respond_to(:has_most_recent?)
|
||||
end
|
||||
|
||||
it "should fail if the :version method has not been overridden and no :find method is available" do
|
||||
proc { @terminus.version('yay') }.should raise_error(Puppet::DevError)
|
||||
end
|
||||
|
||||
it "should use a found instance's version by default" do
|
||||
name = 'instance'
|
||||
instance = stub name, :version => 2
|
||||
@terminus.expects(:find).with(name).returns(instance)
|
||||
@terminus.version(name).should == 2
|
||||
end
|
||||
|
||||
it "should return nil as the version if no instance can be found" do
|
||||
name = 'instance'
|
||||
@terminus.expects(:find).with(name).returns(nil)
|
||||
@terminus.version(name).should be_nil
|
||||
end
|
||||
|
||||
it "should consider an instance fresh if its version is more recent than the version provided" do
|
||||
name = "yay"
|
||||
@terminus.expects(:version).with(name).returns(5)
|
||||
@terminus.has_most_recent?(name, 4).should be_true
|
||||
end
|
||||
|
||||
it "should consider an instance fresh if its version is equal to the version provided" do
|
||||
name = "yay"
|
||||
@terminus.expects(:version).with(name).returns(5)
|
||||
@terminus.has_most_recent?(name, 5).should be_true
|
||||
end
|
||||
|
||||
it "should consider an instance not fresh if the provided version is more recent than its version" do
|
||||
name = "yay"
|
||||
@terminus.expects(:version).with(name).returns(4)
|
||||
@terminus.has_most_recent?(name, 5).should be_false
|
||||
end
|
||||
|
||||
# Times annoyingly can't be compared directly to numbers, and our
|
||||
# default version is 0.
|
||||
it "should convert versions to floats when checking for freshness" do
|
||||
existing = mock 'existing version'
|
||||
new = mock 'new version'
|
||||
existing.expects(:to_f).returns(1.0)
|
||||
new.expects(:to_f).returns(1.0)
|
||||
name = "yay"
|
||||
@terminus.expects(:version).with(name).returns(existing)
|
||||
@terminus.has_most_recent?(name, new)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -151,6 +151,153 @@ describe Puppet::Node::Configuration, " when extracting transobjects" do
|
|||
end
|
||||
end
|
||||
|
||||
describe Puppet::Node::Configuration, " when converting to a transobject configuration" do
|
||||
class TestResource
|
||||
attr_accessor :name, :virtual, :builtin
|
||||
def initialize(name, options = {})
|
||||
@name = name
|
||||
options.each { |p,v| send(p.to_s + "=", v) }
|
||||
end
|
||||
|
||||
def ref
|
||||
if builtin?
|
||||
"File[%s]" % name
|
||||
else
|
||||
"Class[%s]" % name
|
||||
end
|
||||
end
|
||||
|
||||
def virtual?
|
||||
virtual
|
||||
end
|
||||
|
||||
def builtin?
|
||||
builtin
|
||||
end
|
||||
|
||||
def to_transobject
|
||||
Puppet::TransObject.new(name, builtin? ? "file" : "class")
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
@original = Puppet::Node::Configuration.new("mynode")
|
||||
@original.tag(*%w{one two three})
|
||||
@original.add_class *%w{four five six}
|
||||
|
||||
@top = TestResource.new 'top'
|
||||
@topobject = TestResource.new 'topobject', :builtin => true
|
||||
@virtual = TestResource.new 'virtual', :virtual => true
|
||||
@virtualobject = TestResource.new 'virtualobject', :builtin => true, :virtual => true
|
||||
@middle = TestResource.new 'middle'
|
||||
@middleobject = TestResource.new 'middleobject', :builtin => true
|
||||
@bottom = TestResource.new 'bottom'
|
||||
@bottomobject = TestResource.new 'bottomobject', :builtin => true
|
||||
|
||||
@resources = [@top, @topobject, @middle, @middleobject, @bottom, @bottomobject]
|
||||
|
||||
@original.add_edge!(@top, @topobject)
|
||||
@original.add_edge!(@top, @virtual)
|
||||
@original.add_edge!(@virtual, @virtualobject)
|
||||
@original.add_edge!(@top, @middle)
|
||||
@original.add_edge!(@middle, @middleobject)
|
||||
@original.add_edge!(@middle, @bottom)
|
||||
@original.add_edge!(@bottom, @bottomobject)
|
||||
|
||||
@config = @original.to_transportable
|
||||
end
|
||||
|
||||
it "should add all resources as TransObjects" do
|
||||
@resources.each { |resource| @config.resource(resource.ref).should be_instance_of(Puppet::TransObject) }
|
||||
end
|
||||
|
||||
it "should not extract defined virtual resources" do
|
||||
@config.vertices.find { |v| v.name == "virtual" }.should be_nil
|
||||
end
|
||||
|
||||
it "should not extract builtin virtual resources" do
|
||||
@config.vertices.find { |v| v.name == "virtualobject" }.should be_nil
|
||||
end
|
||||
|
||||
it "should copy the tag list to the new configuration" do
|
||||
@config.tags.sort.should == @original.tags.sort
|
||||
end
|
||||
|
||||
it "should copy the class list to the new configuration" do
|
||||
@config.classes.should == @original.classes
|
||||
end
|
||||
|
||||
it "should duplicate the original edges" do
|
||||
@original.edges.each do |edge|
|
||||
next if edge.source.virtual? or edge.target.virtual?
|
||||
source = @config.resource(edge.source.ref)
|
||||
target = @config.resource(edge.target.ref)
|
||||
|
||||
source.should_not be_nil
|
||||
target.should_not be_nil
|
||||
@config.edge?(source, target).should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "should set itself as the configuration for each converted resource" do
|
||||
@config.vertices.each { |v| v.configuration.object_id.should equal(@config.object_id) }
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Node::Configuration, " when converting to a RAL configuration" do
|
||||
before do
|
||||
@original = Puppet::Node::Configuration.new("mynode")
|
||||
@original.tag(*%w{one two three})
|
||||
@original.add_class *%w{four five six}
|
||||
|
||||
@top = Puppet::TransObject.new 'Class[top]', "component"
|
||||
@topobject = Puppet::TransObject.new '/topobject', "file"
|
||||
@middle = Puppet::TransObject.new 'Class[middle]', "component"
|
||||
@middleobject = Puppet::TransObject.new '/middleobject', "file"
|
||||
@bottom = Puppet::TransObject.new 'Class[bottom]', "component"
|
||||
@bottomobject = Puppet::TransObject.new '/bottomobject', "file"
|
||||
|
||||
@resources = [@top, @topobject, @middle, @middleobject, @bottom, @bottomobject]
|
||||
|
||||
@original.add_resource(*@resources)
|
||||
|
||||
@original.add_edge!(@top, @topobject)
|
||||
@original.add_edge!(@top, @middle)
|
||||
@original.add_edge!(@middle, @middleobject)
|
||||
@original.add_edge!(@middle, @bottom)
|
||||
@original.add_edge!(@bottom, @bottomobject)
|
||||
|
||||
@config = @original.to_ral
|
||||
end
|
||||
|
||||
it "should add all resources as RAL instances" do
|
||||
@resources.each { |resource| @config.resource(resource.ref).should be_instance_of(Puppet::Type) }
|
||||
end
|
||||
|
||||
it "should copy the tag list to the new configuration" do
|
||||
@config.tags.sort.should == @original.tags.sort
|
||||
end
|
||||
|
||||
it "should copy the class list to the new configuration" do
|
||||
@config.classes.should == @original.classes
|
||||
end
|
||||
|
||||
it "should duplicate the original edges" do
|
||||
@original.edges.each do |edge|
|
||||
@config.edge?(@config.resource(edge.source.ref), @config.resource(edge.target.ref)).should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "should set itself as the configuration for each converted resource" do
|
||||
@config.vertices.each { |v| v.configuration.object_id.should equal(@config.object_id) }
|
||||
end
|
||||
|
||||
after do
|
||||
# Remove all resource instances.
|
||||
@config.clear(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Node::Configuration, " when functioning as a resource container" do
|
||||
before do
|
||||
@config = Puppet::Node::Configuration.new("host")
|
||||
|
@ -490,3 +637,60 @@ describe Puppet::Node::Configuration, " when writing dot files" do
|
|||
Puppet.settings.clear
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Node::Configuration, " when indirecting" do
|
||||
before do
|
||||
@indirection = mock 'indirection'
|
||||
|
||||
Puppet::Indirector::Indirection.clear_cache
|
||||
end
|
||||
|
||||
it "should redirect to the indirection for retrieval" do
|
||||
Puppet::Node::Configuration.stubs(:indirection).returns(@indirection)
|
||||
@indirection.expects(:find).with(:myconfig)
|
||||
Puppet::Node::Configuration.find(:myconfig)
|
||||
end
|
||||
|
||||
it "should default to the code terminus" do
|
||||
Puppet::Node::Configuration.indirection.terminus_class.should == :code
|
||||
end
|
||||
|
||||
after do
|
||||
mocha_verify
|
||||
Puppet::Indirector::Indirection.clear_cache
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Node::Configuration, " when converting to yaml" do
|
||||
before do
|
||||
@configuration = Puppet::Node::Configuration.new("me")
|
||||
@configuration.add_edge!("one", "two")
|
||||
end
|
||||
|
||||
it "should be able to be dumped to yaml" do
|
||||
YAML.dump(@configuration).should be_instance_of(String)
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Node::Configuration, " when converting from yaml" do
|
||||
before do
|
||||
@configuration = Puppet::Node::Configuration.new("me")
|
||||
@configuration.add_edge!("one", "two")
|
||||
|
||||
text = YAML.dump(@configuration)
|
||||
@newconfig = YAML.load(text)
|
||||
end
|
||||
|
||||
it "should get converted back to a configuration" do
|
||||
@newconfig.should be_instance_of(Puppet::Node::Configuration)
|
||||
end
|
||||
|
||||
it "should have all vertices" do
|
||||
@newconfig.vertex?("one").should be_true
|
||||
@newconfig.vertex?("two").should be_true
|
||||
end
|
||||
|
||||
it "should have all edges" do
|
||||
@newconfig.edge?("one", "two").should be_true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,25 +6,30 @@ require 'puppet/node/facts'
|
|||
|
||||
describe Puppet::Node::Facts, " when indirecting" do
|
||||
before do
|
||||
@terminus = mock 'terminus'
|
||||
Puppet::Node::Facts.stubs(:indirection).returns(@terminus)
|
||||
@indirection = mock 'indirection'
|
||||
|
||||
# We have to clear the cache so that the facts ask for our terminus stub,
|
||||
# We have to clear the cache so that the facts ask for our indirection stub,
|
||||
# instead of anything that might be cached.
|
||||
Puppet::Indirector::Indirection.clear_cache
|
||||
@facts = Puppet::Node::Facts.new("me", "one" => "two")
|
||||
end
|
||||
|
||||
it "should redirect to the specified fact store for retrieval" do
|
||||
@terminus.expects(:find).with(:my_facts)
|
||||
Puppet::Node::Facts.stubs(:indirection).returns(@indirection)
|
||||
@indirection.expects(:find).with(:my_facts)
|
||||
Puppet::Node::Facts.find(:my_facts)
|
||||
end
|
||||
|
||||
it "should redirect to the specified fact store for storage" do
|
||||
@terminus.expects(:save).with(@facts)
|
||||
Puppet::Node::Facts.stubs(:indirection).returns(@indirection)
|
||||
@indirection.expects(:save).with(@facts)
|
||||
@facts.save
|
||||
end
|
||||
|
||||
it "should default to the code terminus" do
|
||||
Puppet::Node::Facts.indirection.terminus_class.should == :code
|
||||
end
|
||||
|
||||
after do
|
||||
mocha_verify
|
||||
Puppet::Indirector::Indirection.clear_cache
|
||||
|
|
|
@ -112,14 +112,15 @@ describe Puppet::Node, " when merging facts" do
|
|||
end
|
||||
|
||||
describe Puppet::Node, " when indirecting" do
|
||||
before do
|
||||
@terminus = mock 'terminus'
|
||||
Puppet::Node.stubs(:indirection).returns(@terminus)
|
||||
it "should redirect to the indirection" do
|
||||
@indirection = mock 'indirection'
|
||||
Puppet::Node.stubs(:indirection).returns(@indirection)
|
||||
@indirection.expects(:find).with(:my_node.to_s)
|
||||
Puppet::Node.find(:my_node.to_s)
|
||||
end
|
||||
|
||||
it "should redirect to the specified node source" do
|
||||
@terminus.expects(:find).with(:my_node.to_s)
|
||||
Puppet::Node.find(:my_node.to_s)
|
||||
it "should default to the 'null' node terminus" do
|
||||
Puppet::Node.indirection.terminus_class.should == :null
|
||||
end
|
||||
|
||||
after do
|
||||
|
|
|
@ -49,4 +49,14 @@ describe Puppet::Parser::Compile, " when compiling" do
|
|||
@compile.resources.find { |r| r.to_s == "Class[two]" }.should be_nil
|
||||
@compile.resources.find { |r| r.to_s == "Class[four]" }.should be_nil
|
||||
end
|
||||
|
||||
it "should enable ast_nodes if the parser has any nodes" do
|
||||
@parser.expects(:nodes).returns(:one => :yay)
|
||||
@compile.ast_nodes?.should be_true
|
||||
end
|
||||
|
||||
it "should disable ast_nodes if the parser has no nodes" do
|
||||
@parser.expects(:nodes).returns({})
|
||||
@compile.ast_nodes?.should be_false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,65 +2,25 @@
|
|||
|
||||
require File.dirname(__FILE__) + '/../../spec_helper'
|
||||
|
||||
describe Puppet::Parser::Interpreter, " when initializing" do
|
||||
it "should default to neither code nor file" do
|
||||
interp = Puppet::Parser::Interpreter.new
|
||||
interp.code.should be_nil
|
||||
interp.file.should be_nil
|
||||
end
|
||||
|
||||
it "should set the code to parse" do
|
||||
interp = Puppet::Parser::Interpreter.new :Code => :code
|
||||
interp.code.should equal(:code)
|
||||
end
|
||||
|
||||
it "should set the file to parse" do
|
||||
interp = Puppet::Parser::Interpreter.new :Manifest => :file
|
||||
interp.file.should equal(:file)
|
||||
end
|
||||
|
||||
it "should set code and ignore manifest when both are present" do
|
||||
interp = Puppet::Parser::Interpreter.new :Code => :code, :Manifest => :file
|
||||
interp.code.should equal(:code)
|
||||
interp.file.should be_nil
|
||||
end
|
||||
|
||||
it "should default to usenodes" do
|
||||
interp = Puppet::Parser::Interpreter.new
|
||||
interp.usenodes?.should be_true
|
||||
end
|
||||
|
||||
it "should allow disabling of usenodes" do
|
||||
interp = Puppet::Parser::Interpreter.new :UseNodes => false
|
||||
interp.usenodes?.should be_false
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Parser::Interpreter, " when creating parser instances" do
|
||||
before do
|
||||
@interp = Puppet::Parser::Interpreter.new
|
||||
@parser = mock('parser')
|
||||
end
|
||||
|
||||
it "should create a parser with code passed in at initialization time" do
|
||||
@interp.code = :some_code
|
||||
@parser.expects(:string=).with(:some_code)
|
||||
it "should create a parser with code if there is code defined in the :code setting" do
|
||||
Puppet.settings.stubs(:value).with(:code, :myenv).returns("mycode")
|
||||
@parser.expects(:string=).with("mycode")
|
||||
@parser.expects(:parse)
|
||||
Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
|
||||
@interp.send(:create_parser, :myenv).object_id.should equal(@parser.object_id)
|
||||
end
|
||||
|
||||
it "should create a parser with a file passed in at initialization time" do
|
||||
@interp.file = :a_file
|
||||
@parser.expects(:file=).with(:a_file)
|
||||
it "should create a parser with the main manifest when the code setting is an empty string" do
|
||||
Puppet.settings.stubs(:value).with(:code, :myenv).returns("")
|
||||
Puppet.settings.stubs(:value).with(:manifest, :myenv).returns("/my/file")
|
||||
@parser.expects(:parse)
|
||||
Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
|
||||
@interp.send(:create_parser, :myenv).should equal(@parser)
|
||||
end
|
||||
|
||||
it "should create a parser with the main manifest when passed neither code nor file" do
|
||||
@parser.expects(:parse)
|
||||
@parser.expects(:file=).with(Puppet[:manifest])
|
||||
@parser.expects(:file=).with("/my/file")
|
||||
Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
|
||||
@interp.send(:create_parser, :myenv).should equal(@parser)
|
||||
end
|
||||
|
@ -159,22 +119,13 @@ describe Puppet::Parser::Interpreter, " when compiling configurations" do
|
|||
@parser = mock 'parser'
|
||||
end
|
||||
|
||||
it "should create a compile with the node, parser, and whether to use ast nodes when ast nodes is true" do
|
||||
it "should create a compile with the node and parser" do
|
||||
@compile.expects(:compile).returns(:config)
|
||||
@interp.expects(:parser).with(:myenv).returns(@parser)
|
||||
@interp.expects(:usenodes?).returns(true)
|
||||
Puppet::Parser::Compile.expects(:new).with(@node, @parser, :ast_nodes => true).returns(@compile)
|
||||
Puppet::Parser::Compile.expects(:new).with(@node, @parser).returns(@compile)
|
||||
@interp.compile(@node)
|
||||
end
|
||||
|
||||
it "should create a compile with the node, parser, and whether to use ast nodes when ast nodes is false" do
|
||||
@compile.expects(:compile).returns(:config)
|
||||
@interp.expects(:parser).with(:myenv).returns(@parser)
|
||||
@interp.expects(:usenodes?).returns(false)
|
||||
Puppet::Parser::Compile.expects(:new).with(@node, @parser, :ast_nodes => false).returns(@compile)
|
||||
@interp.compile(@node).should equal(:config)
|
||||
end
|
||||
|
||||
it "should fail intelligently when no parser can be found" do
|
||||
@interp.expects(:parser).with(:myenv).returns(nil)
|
||||
proc { @interp.compile(@node) }.should raise_error(Puppet::ParseError)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# $Id$
|
||||
|
||||
define component {
|
||||
define mytype {
|
||||
file { "/tmp/classtest": ensure => file, mode => 755 }
|
||||
}
|
||||
|
||||
class testing {
|
||||
component { "componentname": }
|
||||
mytype { "componentname": }
|
||||
}
|
||||
|
||||
include testing
|
||||
|
|
|
@ -23,7 +23,7 @@ class TestCompile < Test::Unit::TestCase
|
|||
|
||||
def mkparser
|
||||
# This should mock an interpreter
|
||||
@parser = stub 'parser', :version => "1.0"
|
||||
@parser = stub 'parser', :version => "1.0", :nodes => {}
|
||||
end
|
||||
|
||||
def mkcompile(options = {})
|
||||
|
@ -38,7 +38,7 @@ class TestCompile < Test::Unit::TestCase
|
|||
def test_initialize
|
||||
compile = nil
|
||||
node = stub 'node', :name => "foo"
|
||||
parser = stub 'parser', :version => "1.0"
|
||||
parser = stub 'parser', :version => "1.0", :nodes => {}
|
||||
assert_nothing_raised("Could not init compile with all required options") do
|
||||
compile = Compile.new(node, parser)
|
||||
end
|
||||
|
@ -51,7 +51,7 @@ class TestCompile < Test::Unit::TestCase
|
|||
|
||||
# Now try it with some options
|
||||
assert_nothing_raised("Could not init compile with extra options") do
|
||||
compile = Compile.new(node, parser, :ast_nodes => false)
|
||||
compile = Compile.new(node, parser)
|
||||
end
|
||||
|
||||
assert_equal(false, compile.ast_nodes?, "Did not set ast_nodes? correctly")
|
||||
|
@ -188,7 +188,7 @@ class TestCompile < Test::Unit::TestCase
|
|||
# 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 :ast_nodes => false
|
||||
compile = mkcompile
|
||||
name = compile.node.name
|
||||
compile.expects(:ast_nodes?).returns(false)
|
||||
compile.parser.expects(:nodes).never
|
||||
|
@ -201,7 +201,7 @@ class TestCompile < Test::Unit::TestCase
|
|||
|
||||
# Now try it with them enabled, but no node found.
|
||||
nodes = mock 'node_hash'
|
||||
compile = mkcompile :ast_nodes => true
|
||||
compile = mkcompile
|
||||
name = compile.node.name
|
||||
compile.expects(:ast_nodes?).returns(true)
|
||||
compile.parser.stubs(:nodes).returns(nodes)
|
||||
|
@ -221,7 +221,7 @@ class TestCompile < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
# Finally, make sure it works dandily when we have a node
|
||||
compile = mkcompile :ast_nodes => true
|
||||
compile = mkcompile
|
||||
compile.expects(:ast_nodes?).returns(true)
|
||||
|
||||
node = stub 'node', :classname => "c"
|
||||
|
@ -240,7 +240,7 @@ class TestCompile < Test::Unit::TestCase
|
|||
"Did not create node resource")
|
||||
|
||||
# Lastly, check when we actually find the default.
|
||||
compile = mkcompile :ast_nodes => true
|
||||
compile = mkcompile
|
||||
compile.expects(:ast_nodes?).returns(true)
|
||||
|
||||
node = stub 'node', :classname => "default"
|
||||
|
|
|
@ -202,16 +202,10 @@ class TestLangFunctions < Test::Unit::TestCase
|
|||
f.puts "original text"
|
||||
end
|
||||
|
||||
manifest = tempfile()
|
||||
file = tempfile()
|
||||
File.open(manifest, "w") do |f|
|
||||
f.puts %{file { "#{file}": content => template("#{template}") }}
|
||||
end
|
||||
|
||||
interp = Puppet::Parser::Interpreter.new(
|
||||
:Manifest => manifest,
|
||||
:UseNodes => false
|
||||
)
|
||||
Puppet[:code] = %{file { "#{file}": content => template("#{template}") }}
|
||||
interp = Puppet::Parser::Interpreter.new
|
||||
node = mknode
|
||||
node.stubs(:environment).returns("yay")
|
||||
|
||||
|
|
|
@ -618,7 +618,8 @@ file { "/tmp/yayness":
|
|||
f.puts "file { '#{file}': ensure => present }"
|
||||
end
|
||||
|
||||
interp = mkinterp :Manifest => top, :UseNodes => false
|
||||
Puppet[:manifest] = top
|
||||
interp = Puppet::Parser::Interpreter.new
|
||||
|
||||
code = nil
|
||||
assert_nothing_raised do
|
||||
|
|
|
@ -399,24 +399,17 @@ class TestScope < Test::Unit::TestCase
|
|||
Puppet::Rails.init
|
||||
sleep 1
|
||||
children = []
|
||||
file = tempfile()
|
||||
File.open(file, "w") { |f|
|
||||
f.puts "
|
||||
Puppet[:code] = "
|
||||
class yay {
|
||||
@@host { myhost: ip => \"192.168.0.2\" }
|
||||
}
|
||||
include yay
|
||||
@@host { puppet: ip => \"192.168.0.3\" }
|
||||
Host <<||>>"
|
||||
}
|
||||
|
||||
interp = nil
|
||||
assert_nothing_raised {
|
||||
interp = Puppet::Parser::Interpreter.new(
|
||||
:Manifest => file,
|
||||
:UseNodes => false,
|
||||
:ForkSave => false
|
||||
)
|
||||
interp = Puppet::Parser::Interpreter.new
|
||||
}
|
||||
|
||||
config = nil
|
||||
|
|
|
@ -202,7 +202,7 @@ class TestSnippets < Test::Unit::TestCase
|
|||
|
||||
assert_nothing_raised {
|
||||
assert_equal(
|
||||
"//testing/component[componentname]/File[/tmp/classtest]",
|
||||
"//testing/Mytype[componentname]/File[/tmp/classtest]",
|
||||
file.path)
|
||||
}
|
||||
end
|
||||
|
@ -449,45 +449,24 @@ class TestSnippets < Test::Unit::TestCase
|
|||
#eval("alias %s %s" % [testname, mname])
|
||||
testname = ("test_" + mname).intern
|
||||
self.send(:define_method, testname) {
|
||||
Puppet[:manifest] = snippet(file)
|
||||
facts = {
|
||||
"hostname" => "testhost",
|
||||
"domain" => "domain.com",
|
||||
"ipaddress" => "127.0.0.1",
|
||||
"fqdn" => "testhost.domain.com"
|
||||
}
|
||||
Facter.stubs(:each)
|
||||
facts.each do |name, value|
|
||||
Facter.stubs(:value).with(name).returns(value)
|
||||
end
|
||||
# first parse the file
|
||||
server = Puppet::Network::Handler.master.new(
|
||||
:Manifest => snippet(file),
|
||||
:Local => true
|
||||
)
|
||||
facts = Puppet::Node::Facts.new("testhost", facts)
|
||||
Puppet::Node::Facts.stubs(:save)
|
||||
Puppet::Node::Facts.stubs(:find).returns(facts)
|
||||
client = Puppet::Network::Client.master.new(
|
||||
:Master => server,
|
||||
:Cache => false
|
||||
)
|
||||
client.class.stubs(:facts).returns(facts.values)
|
||||
|
||||
assert(client.local)
|
||||
assert_nothing_raised {
|
||||
client.getconfig()
|
||||
node = Puppet::Node.new("testhost")
|
||||
node.merge(facts)
|
||||
|
||||
config = nil
|
||||
assert_nothing_raised("Could not compile configuration") {
|
||||
config = Puppet::Node::Configuration.find(node)
|
||||
}
|
||||
|
||||
client = Puppet::Network::Client.master.new(
|
||||
:Master => server,
|
||||
:Cache => false
|
||||
)
|
||||
|
||||
assert(client.local)
|
||||
# Now do it again
|
||||
Puppet::Type.allclear
|
||||
assert_nothing_raised {
|
||||
client.getconfig()
|
||||
assert_nothing_raised("Could not convert configuration") {
|
||||
config = config.to_ral
|
||||
}
|
||||
|
||||
Puppet::Type.eachtype { |type|
|
||||
|
@ -500,12 +479,10 @@ class TestSnippets < Test::Unit::TestCase
|
|||
assert(obj.name)
|
||||
}
|
||||
}
|
||||
@configuration = client.configuration
|
||||
@configuration = config
|
||||
assert_nothing_raised {
|
||||
self.send(mname)
|
||||
}
|
||||
|
||||
client.clear
|
||||
}
|
||||
mname = mname.intern
|
||||
end
|
||||
|
|
|
@ -47,37 +47,17 @@ class TestTransportable < Test::Unit::TestCase
|
|||
assert(newobj.type, "Bucket has no type")
|
||||
end
|
||||
|
||||
# Verify that we correctly strip out collectable objects, since they should
|
||||
# not be sent to the client.
|
||||
def test_collectstrip
|
||||
top = mk_transtree do |object, depth, width|
|
||||
if width % 2 == 1
|
||||
object.collectable = true
|
||||
end
|
||||
end
|
||||
|
||||
assert(top.flatten.find_all { |o| o.collectable }.length > 0,
|
||||
"Could not find any collectable objects")
|
||||
|
||||
# Now strip out the collectable objects
|
||||
top.collectstrip!
|
||||
|
||||
# And make sure they're actually gone
|
||||
assert_equal(0, top.flatten.find_all { |o| o.collectable }.length,
|
||||
"Still found collectable objects")
|
||||
end
|
||||
|
||||
# Make sure our 'delve' command is working
|
||||
def test_delve
|
||||
top = mk_transtree do |object, depth, width|
|
||||
if width % 2 == 1
|
||||
object.collectable = true
|
||||
object.file = :funtest
|
||||
end
|
||||
end
|
||||
|
||||
objects = []
|
||||
buckets = []
|
||||
collectable = []
|
||||
found = []
|
||||
|
||||
count = 0
|
||||
assert_nothing_raised {
|
||||
|
@ -87,8 +67,8 @@ class TestTransportable < Test::Unit::TestCase
|
|||
buckets << object
|
||||
else
|
||||
objects << object
|
||||
if object.collectable
|
||||
collectable << object
|
||||
if object.file == :funtest
|
||||
found << object
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -98,9 +78,9 @@ class TestTransportable < Test::Unit::TestCase
|
|||
assert(objects.include?(obj), "Missing obj %s[%s]" % [obj.type, obj.name])
|
||||
end
|
||||
|
||||
assert_equal(collectable.length,
|
||||
top.flatten.find_all { |o| o.collectable }.length,
|
||||
"Found incorrect number of collectable objects")
|
||||
assert_equal(found.length,
|
||||
top.flatten.find_all { |o| o.file == :funtest }.length,
|
||||
"Found incorrect number of objects")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -54,10 +54,8 @@ module PuppetTest::ParserTesting
|
|||
Puppet::Node.new(name)
|
||||
end
|
||||
|
||||
def mkinterp(args = {})
|
||||
args[:Code] ||= "" unless args.include?(:Manifest)
|
||||
args[:Local] ||= true
|
||||
Puppet::Parser::Interpreter.new(args)
|
||||
def mkinterp
|
||||
Puppet::Parser::Interpreter.new
|
||||
end
|
||||
|
||||
def mkparser
|
||||
|
@ -301,11 +299,10 @@ module PuppetTest::ParserTesting
|
|||
# This assumes no nodes
|
||||
def assert_creates(manifest, *files)
|
||||
interp = nil
|
||||
oldmanifest = Puppet[:manifest]
|
||||
Puppet[:manifest] = manifest
|
||||
assert_nothing_raised {
|
||||
interp = Puppet::Parser::Interpreter.new(
|
||||
:Manifest => manifest,
|
||||
:UseNodes => false
|
||||
)
|
||||
interp = Puppet::Parser::Interpreter.new
|
||||
}
|
||||
|
||||
trans = nil
|
||||
|
@ -323,6 +320,8 @@ module PuppetTest::ParserTesting
|
|||
files.each do |file|
|
||||
assert(FileTest.exists?(file), "Did not create %s" % file)
|
||||
end
|
||||
ensure
|
||||
Puppet[:manifest] = oldmanifest
|
||||
end
|
||||
|
||||
def mk_transobject(file = "/etc/passwd")
|
||||
|
|
|
@ -141,17 +141,13 @@ class TestClient < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_classfile
|
||||
manifest = tempfile()
|
||||
Puppet[:code] = "class yaytest {}\n class bootest {}\n include yaytest, bootest"
|
||||
|
||||
File.open(manifest, "w") do |file|
|
||||
file.puts "class yaytest {}\n class bootest {}\n include yaytest, bootest"
|
||||
end
|
||||
Puppet::Node::Facts.indirection.stubs(:save)
|
||||
|
||||
master = client = nil
|
||||
assert_nothing_raised() {
|
||||
master = Puppet::Network::Handler.master.new(
|
||||
:Manifest => manifest,
|
||||
:UseNodes => false,
|
||||
:Local => false
|
||||
)
|
||||
}
|
||||
|
|
|
@ -48,8 +48,10 @@ class TestMasterClient < Test::Unit::TestCase
|
|||
def mkmaster(options = {})
|
||||
options[:UseNodes] = false
|
||||
options[:Local] = true
|
||||
unless options[:Code]
|
||||
options[:Manifest] ||= mktestmanifest
|
||||
if code = options[:Code]
|
||||
Puppet[:code] = code
|
||||
else
|
||||
Puppet[:manifest] = options[:Manifest] || mktestmanifest
|
||||
end
|
||||
# create our master
|
||||
# this is the default server setup
|
||||
|
@ -395,6 +397,8 @@ end
|
|||
manifest = tempfile()
|
||||
File.open(manifest, "w") { |f| f.puts "file { '#{file}': content => yay }" }
|
||||
|
||||
Puppet::Node::Facts.indirection.stubs(:save)
|
||||
|
||||
driver = mkmaster(:Manifest => manifest)
|
||||
driver.local = false
|
||||
master = mkclient(driver)
|
||||
|
@ -404,7 +408,7 @@ end
|
|||
|
||||
assert(! master.fresh?(master.class.facts),
|
||||
"Considered fresh with no compile at all")
|
||||
|
||||
|
||||
assert_nothing_raised { master.run }
|
||||
assert(master.fresh?(master.class.facts),
|
||||
"not considered fresh after compile")
|
||||
|
@ -479,7 +483,9 @@ end
|
|||
master.local = false
|
||||
driver = master.send(:instance_variable_get, "@driver")
|
||||
driver.local = false
|
||||
Puppet::Node::Facts.indirection.stubs(:save)
|
||||
# Retrieve the configuration
|
||||
|
||||
master.getconfig
|
||||
|
||||
# Now the config is up to date, so get rid of the @objects var and
|
||||
|
@ -507,6 +513,8 @@ end
|
|||
driver = master.send(:instance_variable_get, "@driver")
|
||||
driver.local = false
|
||||
|
||||
Puppet::Node::Facts.indirection.stubs(:save)
|
||||
|
||||
assert_nothing_raised("Could not compile config") do
|
||||
master.getconfig
|
||||
end
|
||||
|
|
|
@ -25,9 +25,7 @@ class TestHandlerConfiguration < Test::Unit::TestCase
|
|||
config = Config.new
|
||||
|
||||
# First test the defaults
|
||||
args = {}
|
||||
config.instance_variable_set("@options", args)
|
||||
config.expects(:create_interpreter).with(args).returns(:interp)
|
||||
config.expects(:create_interpreter).returns(:interp)
|
||||
assert_equal(:interp, config.send(:interpreter), "Did not return the interpreter")
|
||||
|
||||
# Now run it again and make sure we get the same thing
|
||||
|
@ -39,20 +37,8 @@ class TestHandlerConfiguration < Test::Unit::TestCase
|
|||
args = {}
|
||||
|
||||
# Try it first with defaults.
|
||||
Puppet::Parser::Interpreter.expects(:new).with(:Local => config.local?).returns(:interp)
|
||||
assert_equal(:interp, config.send(:create_interpreter, args), "Did not return the interpreter")
|
||||
|
||||
# Now reset it and make sure a specified manifest passes through
|
||||
file = tempfile
|
||||
args[:Manifest] = file
|
||||
Puppet::Parser::Interpreter.expects(:new).with(:Local => config.local?, :Manifest => file).returns(:interp)
|
||||
assert_equal(:interp, config.send(:create_interpreter, args), "Did not return the interpreter")
|
||||
|
||||
# And make sure the code does, too
|
||||
args.delete(:Manifest)
|
||||
args[:Code] = "yay"
|
||||
Puppet::Parser::Interpreter.expects(:new).with(:Local => config.local?, :Code => "yay").returns(:interp)
|
||||
assert_equal(:interp, config.send(:create_interpreter, args), "Did not return the interpreter")
|
||||
Puppet::Parser::Interpreter.expects(:new).returns(:interp)
|
||||
assert_equal(:interp, config.send(:create_interpreter), "Did not return the interpreter")
|
||||
end
|
||||
|
||||
# Make sure node objects get appropriate data added to them.
|
||||
|
@ -67,7 +53,7 @@ class TestHandlerConfiguration < Test::Unit::TestCase
|
|||
config.send(:add_node_data, fakenode)
|
||||
|
||||
# Now try it with classes.
|
||||
config.instance_variable_set("@options", {:Classes => %w{a b}})
|
||||
config.classes = %w{a b}
|
||||
list = []
|
||||
fakenode = Object.new
|
||||
fakenode.expects(:merge).with(:facts)
|
||||
|
@ -126,8 +112,9 @@ class TestHandlerConfiguration < Test::Unit::TestCase
|
|||
|
||||
# Now a non-local
|
||||
config = Config.new(:Local => false)
|
||||
obj = Object.new
|
||||
yamld = Object.new
|
||||
assert(! config.local?, "Config wrongly thinks it's local")
|
||||
obj = mock 'dumpee'
|
||||
yamld = mock 'yaml'
|
||||
obj.expects(:to_yaml).with(:UseBlock => true).returns(yamld)
|
||||
CGI.expects(:escape).with(yamld).returns(:translated)
|
||||
assert_equal(:translated, config.send(:translate, obj), "Did not return translated config")
|
||||
|
|
|
@ -56,11 +56,10 @@ class TestMaster < Test::Unit::TestCase
|
|||
@@tmpfiles << file2
|
||||
|
||||
client = master = nil
|
||||
Puppet[:manifest] = manifest
|
||||
assert_nothing_raised() {
|
||||
# this is the default server setup
|
||||
master = Puppet::Network::Handler.master.new(
|
||||
:Manifest => manifest,
|
||||
:UseNodes => false,
|
||||
:Local => true
|
||||
)
|
||||
}
|
||||
|
|
|
@ -7,15 +7,14 @@ require 'puppettest'
|
|||
class TestHandlerRunner < Test::Unit::TestCase
|
||||
include PuppetTest
|
||||
|
||||
def mkclient(file)
|
||||
def mkclient(code)
|
||||
master = nil
|
||||
client = nil
|
||||
Puppet[:code] = code
|
||||
# create our master
|
||||
assert_nothing_raised() {
|
||||
# this is the default server setup
|
||||
master = Puppet::Network::Handler.master.new(
|
||||
:Manifest => file,
|
||||
:UseNodes => false,
|
||||
:Local => true
|
||||
)
|
||||
}
|
||||
|
@ -38,8 +37,7 @@ class TestHandlerRunner < Test::Unit::TestCase
|
|||
created = tempfile()
|
||||
# We specify the schedule here, because I was having problems with
|
||||
# using default schedules.
|
||||
File.open(file, "w") do |f|
|
||||
f.puts %{
|
||||
code = %{
|
||||
class yayness {
|
||||
schedule { "yayness": period => weekly }
|
||||
file { "#{created}": ensure => file, schedule => yayness }
|
||||
|
@ -47,9 +45,8 @@ class TestHandlerRunner < Test::Unit::TestCase
|
|||
|
||||
include yayness
|
||||
}
|
||||
end
|
||||
|
||||
client = mkclient(file)
|
||||
client = mkclient(code)
|
||||
|
||||
runner = nil
|
||||
assert_nothing_raised {
|
||||
|
|
|
@ -25,7 +25,6 @@ class ConfigurationRailsTests < PuppetTest::TestCase
|
|||
def test_finish_before_store
|
||||
railsinit
|
||||
compile = mkcompile
|
||||
compile.ast_nodes = true
|
||||
parser = compile.parser
|
||||
|
||||
node = parser.newnode [compile.node.name], :code => AST::ASTArray.new(:children => [
|
||||
|
@ -52,19 +51,9 @@ class ConfigurationRailsTests < PuppetTest::TestCase
|
|||
Puppet[:storeconfigs] = true
|
||||
}
|
||||
|
||||
file = tempfile()
|
||||
File.open(file, "w") { |f|
|
||||
f.puts "file { \"/etc\": owner => root }"
|
||||
}
|
||||
Puppet[:code] = "file { \"/etc\": owner => root }"
|
||||
|
||||
interp = nil
|
||||
assert_nothing_raised {
|
||||
interp = Puppet::Parser::Interpreter.new(
|
||||
:Manifest => file,
|
||||
:UseNodes => false,
|
||||
:ForkSave => false
|
||||
)
|
||||
}
|
||||
interp = Puppet::Parser::Interpreter.new
|
||||
|
||||
facts = {}
|
||||
Facter.each { |fact, val| facts[fact] = val }
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# Created by David Schmitt on 2007-09-13
|
||||
# Copyright (c) 2007. All rights reserved.
|
||||
|
||||
$:.unshift("../../../lib") if __FILE__ =~ /\.rb$/
|
||||
|
||||
require 'puppettest'
|
||||
|
||||
class TestDebianServiceProvider < Test::Unit::TestCase
|
||||
include PuppetTest
|
||||
include Puppet::Util
|
||||
|
||||
def prepare_provider(servicename, output)
|
||||
service = Puppet::Type.type(:service).create(
|
||||
:name => servicename, :provider => :debian
|
||||
)
|
||||
|
||||
provider = service.provider
|
||||
assert(provider, "did not get debian provider")
|
||||
|
||||
metaclass = class << provider
|
||||
self
|
||||
end
|
||||
|
||||
metaclass.instance_eval do
|
||||
define_method :update do |*args|
|
||||
return output
|
||||
end
|
||||
end
|
||||
|
||||
provider
|
||||
end
|
||||
|
||||
def assert_enabled( servicename, output)
|
||||
provider = prepare_provider( servicename, output )
|
||||
assert_equal(:true, provider.enabled?,
|
||||
"Service provider=debian thinks service is disabled, when it isn't")
|
||||
end
|
||||
|
||||
def assert_disabled( servicename, output )
|
||||
provider = prepare_provider( servicename, output )
|
||||
assert_equal(:false, provider.enabled?,
|
||||
"Service provider=debian thinks service is enabled, when it isn't")
|
||||
end
|
||||
|
||||
# Testing #822
|
||||
def test_file_rc
|
||||
# These messages are from file-rc's
|
||||
# update-rc.d -n -f $service remove
|
||||
assert_enabled("test1", "/etc/runlevel.tmp not installed as /etc/runlevel.conf\n")
|
||||
assert_disabled("test2", "Nothing to do.\n")
|
||||
end
|
||||
|
||||
def test_sysv_rc
|
||||
# These messages are from file-rc's
|
||||
# update-rc.d -n -f $service remove
|
||||
assert_enabled("test3", """ Removing any system startup links for /etc/init.d/test3 ...
|
||||
/etc/rc0.d/K11test3
|
||||
/etc/rc1.d/K11test3
|
||||
/etc/rc2.d/S89test3
|
||||
/etc/rc3.d/S89test3
|
||||
/etc/rc4.d/S89test3
|
||||
/etc/rc5.d/S89test3
|
||||
/etc/rc6.d/K11test3
|
||||
""")
|
||||
assert_disabled("test4", " Removing any system startup links for /etc/init.d/test4 ...\n")
|
||||
end
|
||||
end
|
||||
|
||||
# $Id$
|
Загрузка…
Ссылка в новой задаче