summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2007-09-12 15:32:25 -0500
committerLuke Kanies <luke@madstop.com>2007-09-12 15:32:25 -0500
commita6fe70054f4fb3efe4d558ffdd244917ca1c6f9c (patch)
tree6b8dbf7f3f2779254174b0829412a5365ad6ebed
parent1459c507ddccff2a2a6fbadd4c880c023b5e9893 (diff)
Another intermediate commit. The node and fact classes are now functional and are used instead of the network handlers, which have been removed. There are some failing tests as a result, but I want to get this code committed before I massage the rest of the system to make it work again.
-rw-r--r--lib/puppet/indirector.rb69
-rw-r--r--lib/puppet/indirector/facts/yaml.rb2
-rw-r--r--lib/puppet/indirector/indirection.rb74
-rw-r--r--lib/puppet/indirector/node/external.rb78
-rw-r--r--lib/puppet/indirector/node/ldap.rb6
-rw-r--r--lib/puppet/indirector/node/none.rb6
-rw-r--r--lib/puppet/network/handler/configuration.rb2
-rwxr-xr-xlib/puppet/network/handler/facts.rb68
-rwxr-xr-xlib/puppet/network/handler/fileserver.rb10
-rw-r--r--lib/puppet/network/handler/master.rb9
-rw-r--r--lib/puppet/node.rb17
-rwxr-xr-xlib/puppet/node/facts.rb22
-rw-r--r--spec/Rakefile6
-rw-r--r--spec/lib/spec/dsl/behaviour.rb6
-rw-r--r--spec/lib/spec/runner/behaviour_runner.rb2
-rw-r--r--spec/spec_helper.rb2
-rwxr-xr-xspec/unit/indirector/facts/yaml.rb2
-rwxr-xr-xspec/unit/indirector/indirection.rb57
-rwxr-xr-xspec/unit/indirector/indirector.rb34
-rwxr-xr-xspec/unit/indirector/node/external.rb119
-rwxr-xr-xspec/unit/indirector/node/ldap.rb243
-rwxr-xr-xspec/unit/indirector/node/none.rb32
-rwxr-xr-xspec/unit/node/facts.rb25
-rwxr-xr-xspec/unit/node/node.rb20
-rwxr-xr-xspec/unit/other/node.rb101
-rwxr-xr-xspec/unit/util/config.rb56
-rwxr-xr-xtest/language/snippets.rb7
-rwxr-xr-xtest/lib/puppettest.rb1
-rw-r--r--test/lib/puppettest/parsertesting.rb1
-rw-r--r--test/lib/puppettest/runnable_test.rb30
-rw-r--r--test/lib/puppettest/testcase.rb23
-rwxr-xr-xtest/network/handler/configuration.rb4
-rwxr-xr-xtest/network/handler/facts.rb112
-rwxr-xr-xtest/network/handler/master.rb5
34 files changed, 776 insertions, 475 deletions
diff --git a/lib/puppet/indirector.rb b/lib/puppet/indirector.rb
index b8690d7d5..704039abc 100644
--- a/lib/puppet/indirector.rb
+++ b/lib/puppet/indirector.rb
@@ -11,8 +11,20 @@ module Puppet::Indirector
class Terminus
require 'puppet/util/docs'
extend Puppet::Util::Docs
+
+ class << self
+ attr_accessor :name, :indirection
+ end
+ def name
+ self.class.name
+ end
+ def indirection
+ self.class.indirection
+ end
end
+ require 'puppet/indirector/indirection'
+
# This handles creating the terminus classes.
require 'puppet/util/classgen'
extend Puppet::Util::ClassGen
@@ -38,13 +50,15 @@ module Puppet::Indirector
# on the classes including the module. This allows a given indirection to
# be used in multiple classes.
def self.register_terminus(indirection, terminus, options = {}, &block)
- genclass(terminus,
+ klass = genclass(terminus,
:prefix => indirection.to_s.capitalize,
:hash => instance_hash(indirection),
:attributes => options,
:block => block,
:parent => options[:parent] || Terminus
)
+ klass.indirection = indirection
+ klass.name = terminus
end
# Retrieve a terminus class by indirection and name.
@@ -61,23 +75,14 @@ module Puppet::Indirector
# +:to+: What parameter to use as the name of the indirection terminus.
def indirects(indirection, options = {})
if defined?(@indirection)
- raise ArgumentError, "Already performing an indirection of %s; cannot redirect %s" % [@indirection[:name], indirection]
+ raise ArgumentError, "Already performing an indirection of %s; cannot redirect %s" % [@indirection.name, indirection]
end
- options[:name] = indirection
- @indirection = options
+ @indirection = Indirection.new(indirection, options)
- # Validate the parameter. This requires that indirecting
- # classes require 'puppet/defaults', because of ordering issues,
- # but it makes problems much easier to debug.
- if param_name = options[:to]
- begin
- name = Puppet[param_name]
- rescue
- raise ArgumentError, "Configuration parameter '%s' for indirection '%s' does not exist'" % [param_name, indirection]
- end
- end
# Set up autoloading of the appropriate termini.
Puppet::Indirector.register_indirection indirection
+
+ return @indirection
end
# Define methods for each of the HTTP methods. These just point to the
@@ -98,40 +103,16 @@ module Puppet::Indirector
private
-
- # Create a new terminus instance.
- def make_terminus(name)
- # Load our terminus class.
- unless klass = Puppet::Indirector.terminus(@indirection[:name], name)
- raise ArgumentError, "Could not find terminus %s for indirection %s" % [name, indirection]
- end
- return klass.new
- end
-
# Redirect a given HTTP method.
def redirect(method_name, *args)
begin
- terminus.send(method_name, *args)
- rescue NoMethodError
- raise ArgumentError, "Indirection category %s does not respond to REST method %s" % [indirection, method_name]
- end
- end
-
- # Return the singleton terminus for this indirection.
- def terminus(name = nil)
- @termini ||= {}
- # Get the name of the terminus.
- unless name
- unless param_name = @indirection[:to]
- raise ArgumentError, "You must specify an indirection terminus for indirection %s" % @indirection[:name]
+ @indirection.terminus.send(method_name, *args)
+ rescue NoMethodError => detail
+ if Puppet[:trace]
+ puts detail.backtrace
end
- name = Puppet[param_name]
- name = name.intern if name.is_a?(String)
- end
-
- unless @termini[name]
- @termini[name] = make_terminus(name)
+ raise ArgumentError, "The %s terminus of the %s indirection failed to respond to %s: %s" %
+ [@indirection.terminus.name, @indirection.name, method_name, detail]
end
- @termini[name]
end
end
diff --git a/lib/puppet/indirector/facts/yaml.rb b/lib/puppet/indirector/facts/yaml.rb
index 87860012f..f29ea8ebc 100644
--- a/lib/puppet/indirector/facts/yaml.rb
+++ b/lib/puppet/indirector/facts/yaml.rb
@@ -21,7 +21,7 @@ Puppet::Indirector.register_terminus :facts, :yaml do
end
# Store the facts to disk.
- def put(facts)
+ def post(facts)
File.open(path(facts.name), "w", 0600) do |f|
begin
f.print YAML::dump(facts.values)
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
new file mode 100644
index 000000000..7a4c4bd55
--- /dev/null
+++ b/lib/puppet/indirector/indirection.rb
@@ -0,0 +1,74 @@
+# An actual indirection.
+class Puppet::Indirector::Indirection
+ @@indirections = []
+
+ # Clear all cached termini from all indirections.
+ def self.clear_cache
+ @@indirections.each { |ind| ind.clear_cache }
+ end
+
+ attr_accessor :name, :termini
+ attr_reader :to
+
+ # Clear our cached list of termini.
+ # This is only used for testing.
+ def clear_cache
+ @termini.clear
+ end
+
+ # This is only used for testing.
+ def delete
+ @@indirections.delete(self) if @@indirections.include?(self)
+ end
+
+ def initialize(name, options = {})
+ @name = name
+ options.each do |name, value|
+ begin
+ send(name.to_s + "=", value)
+ rescue NoMethodError
+ raise ArgumentError, "%s is not a valid Indirection parameter" % name
+ end
+ end
+ @termini = {}
+ @@indirections << self
+ end
+
+ # Return the singleton terminus for this indirection.
+ def terminus(name = nil)
+ # Get the name of the terminus.
+ unless name
+ unless param_name = self.to
+ raise ArgumentError, "You must specify an indirection terminus for indirection %s" % self.name
+ end
+ name = Puppet[param_name]
+ name = name.intern if name.is_a?(String)
+ end
+
+ unless @termini[name]
+ @termini[name] = make_terminus(name)
+ end
+ @termini[name]
+ end
+
+ # Validate the parameter. This requires that indirecting
+ # classes require 'puppet/defaults', because of ordering issues,
+ # but it makes problems much easier to debug.
+ def to=(param_name)
+ unless Puppet.config.valid?(param_name)
+ raise ArgumentError, "Configuration parameter '%s' for indirection '%s' does not exist'" % [param_name, self.name]
+ end
+ @to = param_name
+ end
+
+ private
+
+ # Create a new terminus instance.
+ def make_terminus(name)
+ # Load our terminus class.
+ unless klass = Puppet::Indirector.terminus(self.name, name)
+ raise ArgumentError, "Could not find terminus %s for indirection %s" % [name, self.name]
+ end
+ return klass.new
+ end
+end
diff --git a/lib/puppet/indirector/node/external.rb b/lib/puppet/indirector/node/external.rb
index ed2a8893e..13cd265fb 100644
--- a/lib/puppet/indirector/node/external.rb
+++ b/lib/puppet/indirector/node/external.rb
@@ -1,18 +1,66 @@
+require 'puppet/node/facts'
+
Puppet::Indirector.register_terminus :node, :external do
desc "Call an external program to get node information."
include Puppet::Util
+
+ # Proxy the execution, so it's easier to test.
+ def execute(command)
+ Puppet::Util.execute(command)
+ end
+
# Look for external node definitions.
def get(name)
- return nil unless Puppet[:external_nodes] != "none"
+ unless Puppet[:external_nodes] != "none"
+ raise ArgumentError, "You must set the 'external_nodes' parameter to use the external node source"
+ end
+ unless Puppet[:external_nodes][0] == File::SEPARATOR[0]
+ raise ArgumentError, "You must set the 'external_nodes' parameter to a fully qualified command"
+ end
+
+ # Run the command.
+ unless output = query(name)
+ return nil
+ end
+
+ # Translate the output to ruby.
+ result = translate(name, output)
+
+ return create_node(name, result)
+ end
+
+ private
+
+ # Turn our outputted objects into a Puppet::Node instance.
+ def create_node(name, result)
+ node = Puppet::Node.new(name)
+ set = false
+ [:parameters, :classes].each do |param|
+ if value = result[param]
+ node.send(param.to_s + "=", value)
+ set = true
+ end
+ end
+
+ if set
+ node.fact_merge
+ return node
+ else
+ return nil
+ end
+ end
+
+ # Call the external command and see if it returns our output.
+ def query(name)
# This is a very cheap way to do this, since it will break on
# commands that have spaces in the arguments. But it's good
# enough for most cases.
external_node_command = Puppet[:external_nodes].split
external_node_command << name
begin
- output = Puppet::Util.execute(external_node_command)
+ output = execute(external_node_command)
rescue Puppet::ExecutionFailure => detail
if $?.exitstatus == 1
return nil
@@ -25,31 +73,17 @@ Puppet::Indirector.register_terminus :node, :external do
if output =~ /\A\s*\Z/ # all whitespace
Puppet.debug "Empty response for %s from external node source" % name
return nil
+ else
+ return output
end
+ end
+ # Translate the yaml string into Ruby objects.
+ def translate(name, output)
begin
- result = YAML.load(output).inject({}) { |hash, data| hash[symbolize(data[0])] = data[1]; hash }
+ YAML.load(output).inject({}) { |hash, data| hash[symbolize(data[0])] = data[1]; hash }
rescue => detail
raise Puppet::Error, "Could not load external node results for %s: %s" % [name, detail]
end
-
- node = Puppe::Node.new(name)
- set = false
- [:parameters, :classes].each do |param|
- if value = result[param]
- node.send(param.to_s + "=", value)
- set = true
- end
- end
-
- if facts = Puppet::Node.facts(name)
- node.fact_merge(facts)
- end
-
- if set
- return node
- else
- return nil
- end
end
end
diff --git a/lib/puppet/indirector/node/ldap.rb b/lib/puppet/indirector/node/ldap.rb
index 77be04126..fb60cad31 100644
--- a/lib/puppet/indirector/node/ldap.rb
+++ b/lib/puppet/indirector/node/ldap.rb
@@ -18,10 +18,8 @@ Puppet::Indirector.register_terminus :node, :ldap do
end
end
- node = Puppe::Node.new(name, :classes => classes, :source => "ldap", :parameters => parameters)
- if facts = Puppet::Node.facts(name)
- node.fact_merge(facts)
- end
+ node = Puppet::Node.new(name, :classes => classes, :source => "ldap", :parameters => parameters)
+ node.fact_merge
return node
end
diff --git a/lib/puppet/indirector/node/none.rb b/lib/puppet/indirector/node/none.rb
index 7143033d9..2b326968e 100644
--- a/lib/puppet/indirector/node/none.rb
+++ b/lib/puppet/indirector/node/none.rb
@@ -1,3 +1,5 @@
+require 'puppet/node/facts'
+
Puppet::Indirector.register_terminus :node, :none do
desc "Always return an empty node object. This is the node source you should
use when you don't have some other, functional source you want to use,
@@ -6,9 +8,7 @@ Puppet::Indirector.register_terminus :node, :none do
# Just return an empty node.
def get(name)
node = Puppet::Node.new(name)
- if facts = Puppet::Node.facts(name)
- node.fact_merge(facts)
- end
+ node.fact_merge
node
end
end
diff --git a/lib/puppet/network/handler/configuration.rb b/lib/puppet/network/handler/configuration.rb
index 372e80325..2df1b3ab4 100644
--- a/lib/puppet/network/handler/configuration.rb
+++ b/lib/puppet/network/handler/configuration.rb
@@ -79,7 +79,7 @@ class Puppet::Network::Handler
# Add any extra data necessary to the node.
def add_node_data(node)
# Merge in our server-side facts, so they can be used during compilation.
- node.fact_merge(@server_facts)
+ node.merge(@server_facts)
# Add any specified classes to the node's class list.
if classes = @options[:Classes]
diff --git a/lib/puppet/network/handler/facts.rb b/lib/puppet/network/handler/facts.rb
deleted file mode 100755
index 4767e8be4..000000000
--- a/lib/puppet/network/handler/facts.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-require 'yaml'
-require 'puppet/util/fact_store'
-
-class Puppet::Network::Handler
- # Receive logs from remote hosts.
- class Facts < Handler
- desc "An interface for storing and retrieving client facts. Currently only
- used internally by Puppet."
-
- @interface = XMLRPC::Service::Interface.new("facts") { |iface|
- iface.add_method("void set(string, string)")
- iface.add_method("string get(string)")
- iface.add_method("integer store_date(string)")
- }
-
- def initialize(hash = {})
- super
-
- backend = Puppet[:factstore]
-
- unless klass = Puppet::Util::FactStore.store(backend)
- raise Puppet::Error, "Could not find fact store %s" % backend
- end
-
- @backend = klass.new
- end
-
- # Get the facts from our back end.
- def get(node)
- if facts = @backend.get(node)
- return strip_internal(facts)
- else
- return nil
- end
- end
-
- # Set the facts in the backend.
- def set(node, facts)
- @backend.set(node, add_internal(facts))
- nil
- end
-
- # Retrieve a client's storage date.
- def store_date(node)
- if facts = get(node)
- facts[:_puppet_timestamp].to_i
- else
- nil
- end
- end
-
- private
-
- # Add internal data to the facts for storage.
- def add_internal(facts)
- facts = facts.dup
- facts[:_puppet_timestamp] = Time.now
- facts
- end
-
- # Strip out that internal data.
- def strip_internal(facts)
- facts = facts.dup
- facts.find_all { |name, value| name.to_s =~ /^_puppet_/ }.each { |name, value| facts.delete(name) }
- facts
- end
- end
-end
diff --git a/lib/puppet/network/handler/fileserver.rb b/lib/puppet/network/handler/fileserver.rb
index a429412d2..993e9d51a 100755
--- a/lib/puppet/network/handler/fileserver.rb
+++ b/lib/puppet/network/handler/fileserver.rb
@@ -243,7 +243,7 @@ class Puppet::Network::Handler
# the modules.
def modules_mount(module_name, client)
# Find our environment, if we have one.
- if node = node_handler.details(client || Facter.value("hostname"))
+ if node = Puppet::Node.get(client || Facter.value("hostname"))
env = node.environment
else
env = nil
@@ -258,14 +258,6 @@ class Puppet::Network::Handler
end
end
- # Create a node handler instance for looking up our nodes.
- def node_handler
- unless defined?(@node_handler)
- @node_handler = Puppet::Network::Handler.handler(:node).create
- end
- @node_handler
- end
-
# Read the configuration file.
def readconfig(check = true)
return if @noreadconfig
diff --git a/lib/puppet/network/handler/master.rb b/lib/puppet/network/handler/master.rb
index c8db277ba..9550dd550 100644
--- a/lib/puppet/network/handler/master.rb
+++ b/lib/puppet/network/handler/master.rb
@@ -74,7 +74,7 @@ class Puppet::Network::Handler
client, clientip = clientname(client, clientip, facts)
# Pass the facts to the fact handler
- fact_handler.set(client, facts)
+ Puppet::Node::Facts.post(Puppet::Node::Facts.new(client, facts))
# And get the configuration from the config handler
begin
@@ -134,13 +134,6 @@ class Puppet::Network::Handler
return facts
end
- def fact_handler
- unless defined? @fact_handler
- @fact_handler = Puppet::Network::Handler.handler(:facts).new :local => local?
- end
- @fact_handler
- end
-
# Translate our configuration appropriately for sending back to a client.
def translate(config)
if local?
diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb
index 9c5d2d397..7ad7bc3b3 100644
--- a/lib/puppet/node.rb
+++ b/lib/puppet/node.rb
@@ -1,8 +1,11 @@
+require 'puppet/indirector'
+
# A simplistic class for managing the node information itself.
class Puppet::Node
+ require 'puppet/node/facts'
+
# Set up indirection, so that nodes can be looked for in
# the node sources.
- require 'puppet/indirector'
extend Puppet::Indirector
# Use the node source as the indirection terminus.
@@ -66,9 +69,15 @@ class Puppet::Node
end
# Merge the node facts with parameters from the node source.
- # This is only called if the node source has 'fact_merge' set to true.
- def fact_merge(facts)
- facts.each do |name, value|
+ def fact_merge
+ if facts = Puppet::Node::Facts.get(name)
+ merge(facts.values)
+ end
+ end
+
+ # Merge any random parameters into our parameter list.
+ def merge(params)
+ params.each do |name, value|
@parameters[name] = value unless @parameters.include?(name)
end
end
diff --git a/lib/puppet/node/facts.rb b/lib/puppet/node/facts.rb
index eddf44def..e5774127b 100755
--- a/lib/puppet/node/facts.rb
+++ b/lib/puppet/node/facts.rb
@@ -1,9 +1,11 @@
+require 'puppet/node'
+require 'puppet/indirector'
+
# Manage a given node's facts. This either accepts facts and stores them, or
# returns facts for a given node.
class Puppet::Node::Facts
# Set up indirection, so that nodes can be looked for in
# the node sources.
- require 'puppet/indirector'
extend Puppet::Indirector
# Use the node source as the indirection terminus.
@@ -14,23 +16,21 @@ class Puppet::Node::Facts
def initialize(name, values = {})
@name = name
@values = values
+
+ add_internal
end
private
- # FIXME These methods are currently unused.
-
# Add internal data to the facts for storage.
- def add_internal(facts)
- facts = facts.dup
- facts[:_puppet_timestamp] = Time.now
- facts
+ def add_internal
+ self.values[:_timestamp] = Time.now
end
# Strip out that internal data.
- def strip_internal(facts)
- facts = facts.dup
- facts.find_all { |name, value| name.to_s =~ /^_puppet_/ }.each { |name, value| facts.delete(name) }
- facts
+ def strip_internal
+ newvals = values.dup
+ newvals.find_all { |name, value| name.to_s =~ /^_/ }.each { |name, value| newvals.delete(name) }
+ newvals
end
end
diff --git a/spec/Rakefile b/spec/Rakefile
index 40d107312..bb2a75de5 100644
--- a/spec/Rakefile
+++ b/spec/Rakefile
@@ -2,9 +2,15 @@ require File.join(File.dirname(__FILE__), "spec_helper.rb")
require 'rake'
require 'spec/rake/spectask'
+basedir = File.dirname(__FILE__)
+puppetlibdir = File.join(basedir, "../lib")
+puppettestlibdir = File.join(basedir, "../test/lib")
+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.libs = [puppetlibdir, puppettestlibdir, speclibdir]
end
task :default => [:unit]
diff --git a/spec/lib/spec/dsl/behaviour.rb b/spec/lib/spec/dsl/behaviour.rb
index 5158bb673..93a357f19 100644
--- a/spec/lib/spec/dsl/behaviour.rb
+++ b/spec/lib/spec/dsl/behaviour.rb
@@ -1,6 +1,10 @@
+require 'puppettest/runnable_test'
+
module Spec
module DSL
- class EvalModule < Module; end
+ class EvalModule < Module;
+ include PuppetTest::RunnableTest
+ end
class Behaviour
extend BehaviourCallbacks
diff --git a/spec/lib/spec/runner/behaviour_runner.rb b/spec/lib/spec/runner/behaviour_runner.rb
index 1ac891f3c..078490e92 100644
--- a/spec/lib/spec/runner/behaviour_runner.rb
+++ b/spec/lib/spec/runner/behaviour_runner.rb
@@ -55,6 +55,8 @@ module Spec
def run_behaviours
@behaviours.each do |behaviour|
+ # LAK:NOTE: this 'runnable' test is Puppet-specific.
+ next unless behaviour.runnable?
behaviour.run(@options.reporter, @options.dry_run, @options.reverse, @options.timeout)
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index a4171bb07..477842495 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -5,8 +5,8 @@ $:.unshift("#{dir}/lib").unshift("#{dir}/../lib")
$:.unshift("#{dir}/../test/lib")
require 'mocha'
-require 'spec'
require 'puppettest'
+require 'spec'
Spec::Runner.configure do |config|
config.mock_with :mocha
diff --git a/spec/unit/indirector/facts/yaml.rb b/spec/unit/indirector/facts/yaml.rb
index 45c079a69..176a47f04 100755
--- a/spec/unit/indirector/facts/yaml.rb
+++ b/spec/unit/indirector/facts/yaml.rb
@@ -23,7 +23,7 @@ describe Puppet::Indirector.terminus(:facts, :yaml), " when managing facts" do
it "should store facts in YAML in the yamlfactdir" do
values = {"one" => "two", "three" => "four"}
facts = Puppet::Node::Facts.new("node", values)
- @store.put(facts)
+ @store.post(facts)
# Make sure the file exists
path = File.join(Puppet[:yamlfactdir], facts.name) + ".yaml"
diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb
new file mode 100755
index 000000000..e9b10c8c7
--- /dev/null
+++ b/spec/unit/indirector/indirection.rb
@@ -0,0 +1,57 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/indirector'
+
+describe Puppet::Indirector::Indirection, " when initializing" do
+ it "should set the name" do
+ @indirection = Puppet::Indirector::Indirection.new(:myind)
+ @indirection.name.should == :myind
+ end
+
+ it "should set any passed options" do
+ @indirection = Puppet::Indirector::Indirection.new(:myind, :to => :node_source)
+ @indirection.to.should == :node_source
+ end
+
+ it "should only allow valid configuration parameters to be specified as :to targets" do
+ proc { Puppet::Indirector::Indirection.new(:myind, :to => :no_such_variable) }.should raise_error(ArgumentError)
+ end
+
+ after do
+ if defined? @indirection
+ @indirection.delete
+ end
+ end
+end
+
+describe Puppet::Indirector, " when managing termini" do
+ before do
+ @indirection = Puppet::Indirector::Indirection.new(:node, :to => :node_source)
+ end
+
+ it "should allow the clearance of cached termini" do
+ terminus1 = mock 'terminus1'
+ terminus2 = mock 'terminus2'
+ Puppet::Indirector.terminus(:node, Puppet[:node_source]).stubs(:new).returns(terminus1, terminus2, ArgumentError)
+ @indirection.terminus.should equal(terminus1)
+ @indirection.class.clear_cache
+ @indirection.terminus.should equal(terminus2)
+ end
+
+ # Make sure it caches the terminus.
+ it "should return the same terminus each time" do
+ @indirection = Puppet::Indirector::Indirection.new(:node, :to => :node_source)
+ @terminus = mock 'new'
+ Puppet::Indirector.terminus(:node, Puppet[:node_source]).expects(:new).returns(@terminus)
+
+ @indirection.terminus.should equal(@terminus)
+ @indirection.terminus.should equal(@terminus)
+ end
+
+ after do
+ @indirection.delete
+ Puppet::Indirector::Indirection.clear_cache
+ end
+end
diff --git a/spec/unit/indirector/indirector.rb b/spec/unit/indirector/indirector.rb
index c4221febb..312c60951 100755
--- a/spec/unit/indirector/indirector.rb
+++ b/spec/unit/indirector/indirector.rb
@@ -11,15 +11,10 @@ describe Puppet::Indirector, " when managing indirections" do
@indirector.send(:extend, Puppet::Indirector)
end
- # LAK:FIXME This seems like multiple tests, but I don't really know how to test one at a time.
- it "should accept specification of an indirection terminus via a configuration parameter" do
- @indirector.indirects :test, :to => :node_source
- Puppet[:node_source] = "test_source"
- klass = mock 'terminus_class'
- terminus = mock 'terminus'
- klass.expects(:new).returns terminus
- Puppet::Indirector.expects(:terminus).with(:test, :test_source).returns(klass)
- @indirector.send(:terminus).should equal(terminus)
+ it "should create an indirection" do
+ indirection = @indirector.indirects :test, :to => :node_source
+ indirection.name.should == :test
+ indirection.to.should == :node_source
end
it "should not allow more than one indirection in the same object" do
@@ -33,18 +28,15 @@ describe Puppet::Indirector, " when managing indirections" do
other.send(:extend, Puppet::Indirector)
proc { other.indirects :test }.should_not raise_error
end
-end
-
-describe Puppet::Indirector, " when managing termini" do
- before do
- @indirector = Object.new
- @indirector.send(:extend, Puppet::Indirector)
- end
it "should should autoload termini from disk" do
Puppet::Indirector.expects(:instance_load).with(:test, "puppet/indirector/test")
@indirector.indirects :test
end
+
+ after do
+ Puppet.config.clear
+ end
end
describe Puppet::Indirector, " when performing indirections" do
@@ -66,14 +58,4 @@ describe Puppet::Indirector, " when performing indirections" do
@terminus_class.expects(:new).returns(terminus)
@indirector.put("myargument")
end
-
- # Make sure it caches the terminus.
- it "should use the same terminus for all indirections" do
- terminus = mock 'terminus'
- terminus.expects(:put).with("myargument")
- terminus.expects(:get).with("other_argument")
- @terminus_class.expects(:new).returns(terminus)
- @indirector.put("myargument")
- @indirector.get("other_argument")
- end
end
diff --git a/spec/unit/indirector/node/external.rb b/spec/unit/indirector/node/external.rb
new file mode 100755
index 000000000..30b2f74c2
--- /dev/null
+++ b/spec/unit/indirector/node/external.rb
@@ -0,0 +1,119 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'yaml'
+require 'puppet/indirector'
+
+describe Puppet::Indirector.terminus(:node, :external), " when searching for nodes" do
+ require 'puppet/node'
+
+ before do
+ Puppet.config[:external_nodes] = "/yay/ness"
+ @searcher = Puppet::Indirector.terminus(:node, :external).new
+
+ # Set the searcher up so that we do not need to actually call the
+ # external script.
+ @searcher.meta_def(:execute) do |command|
+ name = command.last.chomp
+ result = {}
+
+ if name =~ /a/
+ result[:parameters] = {'one' => command.last + '1', 'two' => command.last + '2'}
+ end
+
+ if name =~ /p/
+ result['classes'] = [1,2,3].collect { |n| command.last + n.to_s }
+ end
+
+ return YAML.dump(result)
+ end
+ end
+
+ it "should throw an exception if the node_source is external but no external node command is set" do
+ Puppet[:external_nodes] = "none"
+ proc { @searcher.get("foo") }.should raise_error(ArgumentError)
+ end
+
+ it "should throw an exception if the external node source is not fully qualified" do
+ Puppet[:external_nodes] = "mycommand"
+ proc { @searcher.get("foo") }.should raise_error(ArgumentError)
+ end
+
+ it "should execute the command with the node name as the only argument" do
+ command = [Puppet[:external_nodes], "yay"]
+ @searcher.expects(:execute).with(command).returns("")
+ @searcher.get("yay")
+ end
+
+ it "should return a node object" do
+ @searcher.get("apple").should be_instance_of(Puppet::Node)
+ end
+
+ it "should set the node's name" do
+ @searcher.get("apple").name.should == "apple"
+ end
+
+ # If we use a name that has a 'p' but no 'a', then our test generator
+ # will return classes but no parameters.
+ it "should be able to configure a node's classes" do
+ node = @searcher.get("plum")
+ node.classes.should == %w{plum1 plum2 plum3}
+ node.parameters.should == {}
+ end
+
+ # If we use a name that has an 'a' but no 'p', then our test generator
+ # will return parameters but no classes.
+ it "should be able to configure a node's parameters" do
+ node = @searcher.get("guava")
+ node.classes.should == []
+ node.parameters.should == {"one" => "guava1", "two" => "guava2"}
+ end
+
+ it "should be able to configure a node's classes and parameters" do
+ node = @searcher.get("apple")
+ node.classes.should == %w{apple1 apple2 apple3}
+ node.parameters.should == {"one" => "apple1", "two" => "apple2"}
+ end
+
+ it "should merge node facts with returned parameters" do
+ facts = Puppet::Node::Facts.new("apple", "three" => "four")
+ Puppet::Node::Facts.expects(:get).with("apple").returns(facts)
+ node = @searcher.get("apple")
+ node.parameters["three"].should == "four"
+ end
+
+ it "should return nil when it cannot find the node" do
+ @searcher.get("honeydew").should be_nil
+ end
+
+ # Make sure a nodesearch with arguments works
+ def test_nodesearch_external_arguments
+ mapper = mk_node_mapper
+ Puppet[:external_nodes] = "#{mapper} -s something -p somethingelse"
+ searcher = mk_searcher(:external)
+ node = nil
+ assert_nothing_raised do
+ node = searcher.nodesearch("apple")
+ end
+ assert_instance_of(SimpleNode, node, "did not create node")
+ end
+
+ # A wrapper test, to make sure we're correctly calling the external search method.
+ def test_nodesearch_external_functional
+ mapper = mk_node_mapper
+ searcher = mk_searcher(:external)
+
+ Puppet[:external_nodes] = mapper
+
+ node = nil
+ assert_nothing_raised do
+ node = searcher.nodesearch("apple")
+ end
+ assert_instance_of(SimpleNode, node, "did not create node")
+ end
+
+ after do
+ Puppet.config.clear
+ end
+end
diff --git a/spec/unit/indirector/node/ldap.rb b/spec/unit/indirector/node/ldap.rb
new file mode 100755
index 000000000..c6eb45ffc
--- /dev/null
+++ b/spec/unit/indirector/node/ldap.rb
@@ -0,0 +1,243 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'yaml'
+require 'puppet/indirector'
+
+describe Puppet::Indirector.terminus(:node, :ldap), " when searching for nodes" do
+ require 'puppet/node'
+
+ def setup
+ Puppet.config[:external_nodes] = "/yay/ness"
+ @searcher = Puppet::Indirector.terminus(:node, :ldap).new
+ nodetable = {}
+ @nodetable = nodetable
+ # Override the ldapsearch definition, so we don't have to actually set it up.
+ @searcher.meta_def(:ldapsearch) do |name|
+ nodetable[name]
+ end
+ end
+
+ it "should return nil for hosts that cannot be found" do
+ @searcher.get("foo").should be_nil
+ end
+
+ it "should return Puppet::Node instances" do
+ @nodetable["foo"] = [nil, %w{}, {}]
+ @searcher.get("foo").should be_instance_of(Puppet::Node)
+ end
+
+ it "should set the node name" do
+ @nodetable["foo"] = [nil, %w{}, {}]
+ @searcher.get("foo").name.should == "foo"
+ end
+
+ it "should set the classes" do
+ @nodetable["foo"] = [nil, %w{one two}, {}]
+ @searcher.get("foo").classes.should == %w{one two}
+ end
+
+ it "should set the parameters" do
+ @nodetable["foo"] = [nil, %w{}, {"one" => "two"}]
+ @searcher.get("foo").parameters.should == {"one" => "two"}
+ end
+
+ it "should set classes and parameters from the parent node" do
+ @nodetable["foo"] = ["middle", %w{one two}, {"one" => "two"}]
+ @nodetable["middle"] = [nil, %w{three four}, {"three" => "four"}]
+ node = @searcher.get("foo")
+ node.classes.sort.should == %w{one two three four}.sort
+ node.parameters.should == {"one" => "two", "three" => "four"}
+ end
+
+ it "should prefer child parameters to parent parameters" do
+ @nodetable["foo"] = ["middle", %w{}, {"one" => "two"}]
+ @nodetable["middle"] = [nil, %w{}, {"one" => "four"}]
+ @searcher.get("foo").parameters["one"].should == "two"
+ end
+
+ it "should recurse indefinitely through parent relationships" do
+ @nodetable["foo"] = ["middle", %w{one two}, {"one" => "two"}]
+ @nodetable["middle"] = ["top", %w{three four}, {"three" => "four"}]
+ @nodetable["top"] = [nil, %w{five six}, {"five" => "six"}]
+ node = @searcher.get("foo")
+ node.parameters.should == {"one" => "two", "three" => "four", "five" => "six"}
+ node.classes.sort.should == %w{one two three four five six}.sort
+ end
+
+ # This can stay in the main test suite because it doesn't actually use ldapsearch,
+ # it just overrides the method so it behaves as though it were hitting ldap.
+ def test_ldap_nodesearch
+
+ # Make sure we get nothing for nonexistent hosts
+ node = nil
+ assert_nothing_raised do
+ node = searcher.nodesearch("nosuchhost")
+ end
+
+ assert_nil(node, "Got a node for a non-existent host")
+
+ # Now add a base node with some classes and parameters
+ nodetable["base"] = [nil, %w{one two}, {"base" => "true"}]
+
+ assert_nothing_raised do
+ node = searcher.nodesearch("base")
+ end
+
+ assert_instance_of(SimpleNode, node, "Did not get node from ldap nodesearch")
+ assert_equal("base", node.name, "node name was not set")
+
+ assert_equal(%w{one two}, node.classes, "node classes were not set")
+ assert_equal({"base" => "true"}, node.parameters, "node parameters were not set")
+
+ # Now use a different with this as the base
+ nodetable["middle"] = ["base", %w{three}, {"center" => "boo"}]
+ assert_nothing_raised do
+ node = searcher.nodesearch("middle")
+ end
+
+ assert_instance_of(SimpleNode, node, "Did not get node from ldap nodesearch")
+ assert_equal("middle", node.name, "node name was not set")
+
+ assert_equal(%w{one two three}.sort, node.classes.sort, "node classes were not set correctly with a parent node")
+ assert_equal({"base" => "true", "center" => "boo"}, node.parameters, "node parameters were not set correctly with a parent node")
+
+ # And one further, to make sure we fully recurse
+ nodetable["top"] = ["middle", %w{four five}, {"master" => "far"}]
+ assert_nothing_raised do
+ node = searcher.nodesearch("top")
+ end
+
+ assert_instance_of(SimpleNode, node, "Did not get node from ldap nodesearch")
+ assert_equal("top", node.name, "node name was not set")
+
+ assert_equal(%w{one two three four five}.sort, node.classes.sort, "node classes were not set correctly with the top node")
+ assert_equal({"base" => "true", "center" => "boo", "master" => "far"}, node.parameters, "node parameters were not set correctly with the top node")
+ end
+end
+
+describe Puppet::Indirector.terminus(:node, :ldap), " when interacting with ldap" do
+ confine "LDAP is not available" => Puppet.features.ldap?
+ confine "No LDAP test data for networks other than Luke's" => Facter.value(:domain) == "madstop.com"
+
+ def ldapconnect
+
+ @ldap = LDAP::Conn.new("ldap", 389)
+ @ldap.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 )
+ @ldap.simple_bind("", "")
+
+ return @ldap
+ end
+
+ def ldaphost(name)
+ node = Puppet::Node.new(name)
+ parent = nil
+ found = false
+ @ldap.search( "ou=hosts, dc=madstop, dc=com", 2,
+ "(&(objectclass=puppetclient)(cn=%s))" % name
+ ) do |entry|
+ node.classes = entry.vals("puppetclass") || []
+ node.parameters = entry.to_hash.inject({}) do |hash, ary|
+ if ary[1].length == 1
+ hash[ary[0]] = ary[1].shift
+ else
+ hash[ary[0]] = ary[1]
+ end
+ hash
+ end
+ parent = node.parameters["parentnode"]
+ found = true
+ end
+ raise "Could not find node %s" % name unless found
+
+ return node, parent
+ end
+
+ it "should have tests" do
+ raise ArgumentError
+ end
+
+ def test_ldapsearch
+ Puppet[:ldapbase] = "ou=hosts, dc=madstop, dc=com"
+ Puppet[:ldapnodes] = true
+
+ searcher = Object.new
+ searcher.extend(Node.node_source(:ldap))
+
+ ldapconnect()
+
+ # Make sure we get nil and nil back when we search for something missing
+ parent, classes, parameters = nil
+ assert_nothing_raised do
+ parent, classes, parameters = searcher.ldapsearch("nosuchhost")
+ end
+
+ assert_nil(parent, "Got a parent for a non-existent host")
+ assert_nil(classes, "Got classes for a non-existent host")
+
+ # Make sure we can find 'culain' in ldap
+ assert_nothing_raised do
+ parent, classes, parameters = searcher.ldapsearch("culain")
+ end
+
+ node, realparent = ldaphost("culain")
+ assert_equal(realparent, parent, "did not get correct parent node from ldap")
+ assert_equal(node.classes, classes, "did not get correct ldap classes from ldap")
+ assert_equal(node.parameters, parameters, "did not get correct ldap parameters from ldap")
+
+ # Now compare when we specify the attributes to get.
+ Puppet[:ldapattrs] = "cn"
+ assert_nothing_raised do
+ parent, classes, parameters = searcher.ldapsearch("culain")
+ end
+ assert_equal(realparent, parent, "did not get correct parent node from ldap")
+ assert_equal(node.classes, classes, "did not get correct ldap classes from ldap")
+
+ list = %w{cn puppetclass parentnode dn}
+ should = node.parameters.inject({}) { |h, a| h[a[0]] = a[1] if list.include?(a[0]); h }
+ assert_equal(should, parameters, "did not get correct ldap parameters from ldap")
+ end
+end
+
+describe Puppet::Indirector.terminus(:node, :ldap), " when connecting to ldap" do
+ confine "Not running on culain as root" => (Puppet::Util::SUIDManager.uid == 0 and Facter.value("hostname") == "culain")
+
+ it "should have tests" do
+ raise ArgumentError
+ end
+
+ def test_ldapreconnect
+ Puppet[:ldapbase] = "ou=hosts, dc=madstop, dc=com"
+ Puppet[:ldapnodes] = true
+
+ searcher = Object.new
+ searcher.extend(Node.node_source(:ldap))
+ hostname = "culain.madstop.com"
+
+ # look for our host
+ assert_nothing_raised {
+ parent, classes = searcher.nodesearch(hostname)
+ }
+
+ # Now restart ldap
+ system("/etc/init.d/slapd restart 2>/dev/null >/dev/null")
+ sleep(1)
+
+ # and look again
+ assert_nothing_raised {
+ parent, classes = searcher.nodesearch(hostname)
+ }
+
+ # Now stop ldap
+ system("/etc/init.d/slapd stop 2>/dev/null >/dev/null")
+ cleanup do
+ system("/etc/init.d/slapd start 2>/dev/null >/dev/null")
+ end
+
+ # And make sure we actually fail here
+ assert_raise(Puppet::Error) {
+ parent, classes = searcher.nodesearch(hostname)
+ }
+ end
+end
diff --git a/spec/unit/indirector/node/none.rb b/spec/unit/indirector/node/none.rb
new file mode 100755
index 000000000..d52d7ca83
--- /dev/null
+++ b/spec/unit/indirector/node/none.rb
@@ -0,0 +1,32 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'puppet/indirector'
+require 'puppet/node/facts'
+
+describe Puppet::Indirector.terminus(:node, :none), " when searching for nodes" do
+ before do
+ Puppet.config[:node_source] = "none"
+ @searcher = Puppet::Indirector.terminus(:node, :none).new
+ end
+
+ it "should create a node instance" do
+ @searcher.get("yay").should be_instance_of(Puppet::Node)
+ end
+
+ it "should create a new node with the correct name" do
+ @searcher.get("yay").name.should == "yay"
+ end
+
+ it "should merge the node's facts" do
+ facts = Puppet::Node::Facts.new("yay", "one" => "two", "three" => "four")
+ Puppet::Node::Facts.expects(:get).with("yay").returns(facts)
+ node = @searcher.get("yay")
+ node.parameters["one"].should == "two"
+ node.parameters["three"].should == "four"
+ end
+
+ after do
+ Puppet.config.clear
+ end
+end
diff --git a/spec/unit/node/facts.rb b/spec/unit/node/facts.rb
index c7fc65f38..c677c1d2e 100755
--- a/spec/unit/node/facts.rb
+++ b/spec/unit/node/facts.rb
@@ -6,11 +6,12 @@ require 'puppet/node/facts'
describe Puppet::Node::Facts, " when indirecting" do
before do
- Puppet[:fact_store] = "test_store"
- @terminus_class = mock 'terminus_class'
@terminus = mock 'terminus'
- @terminus_class.expects(:new).returns(@terminus)
- Puppet::Indirector.expects(:terminus).with(:facts, :test_store).returns(@terminus_class)
+ Puppet::Indirector.terminus(:facts, Puppet[:fact_store].intern).stubs(:new).returns(@terminus)
+
+ # We have to clear the cache so that the facts ask for our terminus stub,
+ # instead of anything that might be cached.
+ Puppet::Indirector::Indirection.clear_cache
end
it "should redirect to the specified fact store for retrieval" do
@@ -19,7 +20,19 @@ describe Puppet::Node::Facts, " when indirecting" do
end
it "should redirect to the specified fact store for storage" do
- @terminus.expects(:put).with(:my_facts)
- Puppet::Node::Facts.put(:my_facts)
+ @terminus.expects(:post).with(:my_facts)
+ Puppet::Node::Facts.post(:my_facts)
+ end
+
+ after do
+ mocha_verify
+ Puppet::Indirector::Indirection.clear_cache
+ end
+end
+
+describe Puppet::Node::Facts, " when storing and retrieving" do
+ it "should add metadata to the facts" do
+ facts = Puppet::Node::Facts.new("me", "one" => "two", "three" => "four")
+ facts.values[:_timestamp].should be_instance_of(Time)
end
end
diff --git a/spec/unit/node/node.rb b/spec/unit/node/node.rb
index a6cc1e301..9342dc5ce 100755
--- a/spec/unit/node/node.rb
+++ b/spec/unit/node/node.rb
@@ -85,32 +85,40 @@ end
describe Puppet::Node, " when merging facts" do
before do
@node = Puppet::Node.new("testnode")
+ Puppet::Node::Facts.stubs(:get).with(@node.name).returns(Puppet::Node::Facts.new(@node.name, "one" => "c", "two" => "b"))
end
it "should prefer parameters already set on the node over facts from the node" do
@node.parameters = {"one" => "a"}
- @node.fact_merge("one" => "c")
+ @node.fact_merge
@node.parameters["one"].should == "a"
end
it "should add passed parameters to the parameter list" do
@node.parameters = {"one" => "a"}
- @node.fact_merge("two" => "b")
+ @node.fact_merge
@node.parameters["two"].should == "b"
end
+
+ it "should accept arbitrary parameters to merge into its parameters" do
+ @node.parameters = {"one" => "a"}
+ @node.merge "two" => "three"
+ @node.parameters["two"].should == "three"
+ end
end
describe Puppet::Node, " when indirecting" do
before do
- Puppet[:node_source] = :test_source
- @terminus_class = mock 'terminus_class'
@terminus = mock 'terminus'
- @terminus_class.expects(:new).returns(@terminus)
- Puppet::Indirector.expects(:terminus).with(:node, :test_source).returns(@terminus_class)
+ Puppet::Indirector.terminus(:node, Puppet[:node_source]).stubs(:new).returns(@terminus)
end
it "should redirect to the specified node source" do
@terminus.expects(:get).with(:my_node)
Puppet::Node.get(:my_node)
end
+
+ after do
+ Puppet::Indirector::Indirection.clear_cache
+ end
end
diff --git a/spec/unit/other/node.rb b/spec/unit/other/node.rb
deleted file mode 100755
index 66d5ba9d7..000000000
--- a/spec/unit/other/node.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../spec_helper'
-
-describe Puppet::Node, " when initializing" do
- before do
- @node = Puppet::Node.new("testnode")
- end
-
- it "should set the node name" do
- @node.name.should == "testnode"
- end
-
- it "should default to an empty parameter hash" do
- @node.parameters.should == {}
- end
-
- it "should default to an empty class array" do
- @node.classes.should == []
- end
-
- it "should note its creation time" do
- @node.time.should be_instance_of(Time)
- end
-
- it "should accept parameters passed in during initialization" do
- params = {"a" => "b"}
- @node = Puppet::Node.new("testing", :parameters => params)
- @node.parameters.should == params
- end
-
- it "should accept classes passed in during initialization" do
- classes = %w{one two}
- @node = Puppet::Node.new("testing", :classes => classes)
- @node.classes.should == classes
- end
-
- it "should always return classes as an array" do
- @node = Puppet::Node.new("testing", :classes => "myclass")
- @node.classes.should == ["myclass"]
- end
-
- it "should accept the environment during initialization" do
- @node = Puppet::Node.new("testing", :environment => "myenv")
- @node.environment.should == "myenv"
- end
-
- it "should accept names passed in" do
- @node = Puppet::Node.new("testing", :names => ["myenv"])
- @node.names.should == ["myenv"]
- end
-end
-
-describe Puppet::Node, " when returning the environment" do
- before do
- @node = Puppet::Node.new("testnode")
- end
-
- it "should return the 'environment' fact if present and there is no explicit environment" do
- @node.parameters = {"environment" => "myenv"}
- @node.environment.should == "myenv"
- end
-
- it "should return the central environment if there is no environment fact nor explicit environment" do
- Puppet.config.expects(:[]).with(:environment).returns(:centralenv)
- @node.environment.should == :centralenv
- end
-
- it "should not use an explicit environment that is an empty string" do
- @node.environment == ""
- @node.environment.should be_nil
- end
-
- it "should not use an environment fact that is an empty string" do
- @node.parameters = {"environment" => ""}
- @node.environment.should be_nil
- end
-
- it "should not use an explicit environment that is an empty string" do
- Puppet.config.expects(:[]).with(:environment).returns(nil)
- @node.environment.should be_nil
- end
-end
-
-describe Puppet::Node, " when merging facts" do
- before do
- @node = Puppet::Node.new("testnode")
- end
-
- it "should prefer parameters already set on the node over facts from the node" do
- @node.parameters = {"one" => "a"}
- @node.fact_merge("one" => "c")
- @node.parameters["one"].should == "a"
- end
-
- it "should add passed parameters to the parameter list" do
- @node.parameters = {"one" => "a"}
- @node.fact_merge("two" => "b")
- @node.parameters["two"].should == "b"
- end
-end
diff --git a/spec/unit/util/config.rb b/spec/unit/util/config.rb
index 348a54893..28ccb04d7 100755
--- a/spec/unit/util/config.rb
+++ b/spec/unit/util/config.rb
@@ -387,22 +387,40 @@ describe Puppet::Util::Config, " when reparsing its configuration" do
end
end
-#describe Puppet::Util::Config, " when being used to manage the host machine" do
-# it "should provide a method that writes files with the correct modes"
-#
-# it "should provide a method that creates directories with the correct modes"
-#
-# it "should provide a method to declare what directories should exist"
-#
-# it "should provide a method to trigger enforcing of file modes on existing files and directories"
-#
-# it "should provide a method to convert the file mode enforcement into a Puppet manifest"
-#
-# it "should provide an option to create needed users and groups"
-#
-# it "should provide a method to print out the current configuration"
-#
-# it "should be able to provide all of its parameters in a format compatible with GetOpt::Long"
-#
-# it "should not attempt to manage files within /dev"
-#end
+describe Puppet::Util::Config, " when being used to manage the host machine" do
+ it "should provide a method that writes files with the correct modes" do
+ pending "Not converted from test/unit yet"
+ end
+
+ it "should provide a method that creates directories with the correct modes" do
+ pending "Not converted from test/unit yet"
+ end
+
+ it "should provide a method to declare what directories should exist" do
+ pending "Not converted from test/unit yet"
+ end
+
+ it "should provide a method to trigger enforcing of file modes on existing files and directories" do
+ pending "Not converted from test/unit yet"
+ end
+
+ it "should provide a method to convert the file mode enforcement into a Puppet manifest" do
+ pending "Not converted from test/unit yet"
+ end
+
+ it "should provide an option to create needed users and groups" do
+ pending "Not converted from test/unit yet"
+ end
+
+ it "should provide a method to print out the current configuration" do
+ pending "Not converted from test/unit yet"
+ end
+
+ it "should be able to provide all of its parameters in a format compatible with GetOpt::Long" do
+ pending "Not converted from test/unit yet"
+ end
+
+ it "should not attempt to manage files within /dev" do
+ pending "Not converted from test/unit yet"
+ end
+end
diff --git a/test/language/snippets.rb b/test/language/snippets.rb
index 2c74543e7..ff8a09881 100755
--- a/test/language/snippets.rb
+++ b/test/language/snippets.rb
@@ -472,13 +472,14 @@ class TestSnippets < Test::Unit::TestCase
:Manifest => snippet(file),
:Local => true
)
- server.send(:fact_handler).stubs(:set)
- server.send(:fact_handler).stubs(:get).returns(facts)
+ facts = Puppet::Node::Facts.new("testhost", facts)
+ Puppet::Node::Facts.stubs(:post)
+ Puppet::Node::Facts.stubs(:get).returns(facts)
client = Puppet::Network::Client.master.new(
:Master => server,
:Cache => false
)
- client.class.stubs(:facts).returns(facts)
+ client.class.stubs(:facts).returns(facts.values)
assert(client.local)
assert_nothing_raised {
diff --git a/test/lib/puppettest.rb b/test/lib/puppettest.rb
index 45c5b2ed9..06b85f147 100755
--- a/test/lib/puppettest.rb
+++ b/test/lib/puppettest.rb
@@ -264,6 +264,7 @@ module PuppetTest
Puppet::Type.allclear
Puppet::Util::Storage.clear
Puppet.clear
+ Puppet.config.clear
@memoryatend = Puppet::Util.memory
diff = @memoryatend - @memoryatstart
diff --git a/test/lib/puppettest/parsertesting.rb b/test/lib/puppettest/parsertesting.rb
index eef0cd8bc..c4bd7dc2b 100644
--- a/test/lib/puppettest/parsertesting.rb
+++ b/test/lib/puppettest/parsertesting.rb
@@ -42,7 +42,6 @@ module PuppetTest::ParserTesting
end
def mkcompile(parser = nil)
- require 'puppet/network/handler/node'
parser ||= mkparser
node = mknode
return Compile.new(node, parser)
diff --git a/test/lib/puppettest/runnable_test.rb b/test/lib/puppettest/runnable_test.rb
new file mode 100644
index 000000000..e4b0f9033
--- /dev/null
+++ b/test/lib/puppettest/runnable_test.rb
@@ -0,0 +1,30 @@
+# Manage whether a test is runnable.
+module PuppetTest
+ module RunnableTest
+ # Confine this test based on specified criteria. The keys of the
+ # hash should be the message to use if the test is not suitable,
+ # and the values should be either 'true' or 'false'; true values
+ # mean the test is suitable.
+ def confine(hash)
+ @confines ||= {}
+ hash.each do |message, result|
+ @confines[message] = result
+ end
+ end
+
+ # Evaluate all of our tests to see if any of them are false
+ # and thus whether this test is considered not runnable.
+ def runnable?
+ @messages ||= []
+ return false unless @messages.empty?
+ return true unless defined? @confines
+ @confines.find_all do |message, result|
+ ! result
+ end.each do |message, result|
+ @messages << message
+ end
+
+ return @messages.empty?
+ end
+ end
+end
diff --git a/test/lib/puppettest/testcase.rb b/test/lib/puppettest/testcase.rb
index cfedeee26..15c835854 100644
--- a/test/lib/puppettest/testcase.rb
+++ b/test/lib/puppettest/testcase.rb
@@ -4,28 +4,11 @@
# Copyright (c) 2007. All rights reserved.
require 'puppettest'
+require 'puppettest/runnable_test'
class PuppetTest::TestCase < Test::Unit::TestCase
include PuppetTest
- def self.confine(hash)
- @confines ||= {}
- hash.each do |message, result|
- @confines[message] = result
- end
- end
-
- def self.runnable?
- @messages ||= []
- return false unless @messages.empty?
- return true unless defined? @confines
- @confines.find_all do |message, result|
- ! result
- end.each do |message, result|
- @messages << message
- end
-
- return @messages.empty?
- end
+ extend PuppetTest::RunnableTest
def self.suite
# Always skip this parent class. It'd be nice if there were a
@@ -44,5 +27,3 @@ class PuppetTest::TestCase < Test::Unit::TestCase
end
end
end
-
-# $Id$
diff --git a/test/network/handler/configuration.rb b/test/network/handler/configuration.rb
index 0964a4c5e..29a393769 100755
--- a/test/network/handler/configuration.rb
+++ b/test/network/handler/configuration.rb
@@ -63,14 +63,14 @@ class TestHandlerConfiguration < Test::Unit::TestCase
fakenode = Object.new
# Set the server facts to something
config.instance_variable_set("@server_facts", :facts)
- fakenode.expects(:fact_merge).with(:facts)
+ fakenode.expects(:merge).with(:facts)
config.send(:add_node_data, fakenode)
# Now try it with classes.
config.instance_variable_set("@options", {:Classes => %w{a b}})
list = []
fakenode = Object.new
- fakenode.expects(:fact_merge).with(:facts)
+ fakenode.expects(:merge).with(:facts)
fakenode.expects(:classes).returns(list).times(2)
config.send(:add_node_data, fakenode)
assert_equal(%w{a b}, list, "Did not add classes to node")
diff --git a/test/network/handler/facts.rb b/test/network/handler/facts.rb
deleted file mode 100755
index 03327b8c4..000000000
--- a/test/network/handler/facts.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/usr/bin/env ruby
-
-$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
-
-require 'puppettest'
-require 'mocha'
-require 'puppet/network/handler/facts'
-
-class TestFactsHandler < Test::Unit::TestCase
- include PuppetTest::ServerTest
-
- def setup
- super
-
- @class = Puppet::Network::Handler.handler(:facts)
-
- @@client_facts = {}
-
- unless Puppet::Util::FactStore.store(:testing)
- Puppet::Util::FactStore.newstore(:testing) do
- def get(node)
- @@client_facts[node]
- end
-
- def set(node, facts)
- @@client_facts[node] = facts
- end
- end
- end
-
- Puppet[:factstore] = :testing
-
- @handler = @class.new
-
- @facts = {:a => :b, :c => :d}
- @name = "foo"
-
- @backend = @handler.instance_variable_get("@backend")
- end
-
- def teardown
- @@client_facts.clear
- end
-
- def test_strip_internal
- @facts[:_puppet_one] = "yay"
- @facts[:_puppet_two] = "boo"
- @facts[:_puppetthree] = "foo"
-
- newfacts = nil
- assert_nothing_raised("Could not call strip_internal") do
- newfacts = @handler.send(:strip_internal, @facts)
- end
-
- [:_puppet_one, :_puppet_two, :_puppetthree].each do |name|
- assert(@facts.include?(name), "%s was removed in strip_internal from original hash" % name)
- end
- [:_puppet_one, :_puppet_two].each do |name|
- assert(! newfacts.include?(name), "%s was not removed in strip_internal" % name)
- end
- assert_equal("foo", newfacts[:_puppetthree], "_puppetthree was removed in strip_internal")
- end
-
- def test_add_internal
- newfacts = nil
- assert_nothing_raised("Could not call strip_internal") do
- newfacts = @handler.send(:add_internal, @facts)
- end
-
- assert_instance_of(Time, newfacts[:_puppet_timestamp], "Did not set timestamp in add_internal")
- assert(! @facts.include?(:_puppet_timestamp), "Modified original hash in add_internal")
- end
-
- def test_set
- newfacts = @facts.dup
- newfacts[:_puppet_timestamp] = Time.now
- @handler.expects(:add_internal).with(@facts).returns(newfacts)
- @backend.expects(:set).with(@name, newfacts).returns(nil)
-
- assert_nothing_raised("Could not set facts") do
- assert_nil(@handler.set(@name, @facts), "handler.set did not return nil")
- end
- end
-
- def test_get
- prefacts = @facts.dup
- prefacts[:_puppet_timestamp] = Time.now
- @@client_facts[@name] = prefacts
- @handler.expects(:strip_internal).with(prefacts).returns(@facts)
- @backend.expects(:get).with(@name).returns(prefacts)
-
- assert_nothing_raised("Could not retrieve facts") do
- assert_equal(@facts, @handler.get(@name), "did not get correct answer from handler.get")
- end
-
- @handler = @class.new
- assert_nothing_raised("Failed to call 'get' with no stored facts") do
- @handler.get("nosuchname")
- end
- end
-
- def test_store_date
- time = Time.now
- @facts[:_puppet_timestamp] = time
-
- @handler.expects(:get).with(@name).returns(@facts)
-
- assert_equal(time.to_i, @handler.store_date(@name), "Did not retrieve timestamp correctly")
- end
-end
-
-# $Id$
diff --git a/test/network/handler/master.rb b/test/network/handler/master.rb
index a976726ef..9749c7bdf 100755
--- a/test/network/handler/master.rb
+++ b/test/network/handler/master.rb
@@ -8,6 +8,11 @@ require 'puppet/network/handler/master'
class TestMaster < Test::Unit::TestCase
include PuppetTest::ServerTest
+ def teardown
+ super
+ Puppet::Indirector::Indirection.clear_cache
+ end
+
def test_defaultmanifest
textfiles { |file|
Puppet[:manifest] = file