summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/puppet/indirector.rb49
-rw-r--r--lib/puppet/indirector/checksum/file.rb4
-rw-r--r--lib/puppet/indirector/direct_file_server.rb14
-rw-r--r--lib/puppet/indirector/file.rb28
-rw-r--r--lib/puppet/indirector/file_metadata/file.rb4
-rw-r--r--lib/puppet/indirector/indirection.rb50
-rw-r--r--lib/puppet/indirector/memory.rb14
-rw-r--r--lib/puppet/indirector/plain.rb4
-rw-r--r--lib/puppet/indirector/request.rb2
-rw-r--r--lib/puppet/indirector/yaml.rb28
-rw-r--r--lib/puppet/transaction/report.rb4
-rwxr-xr-xspec/integration/indirector/direct_file_server.rb10
-rwxr-xr-xspec/integration/node/catalog.rb34
-rw-r--r--spec/shared_behaviours/file_serving.rb12
-rw-r--r--spec/shared_behaviours/memory_terminus.rb32
-rwxr-xr-xspec/unit/indirector.rb98
-rwxr-xr-xspec/unit/indirector/catalog/compiler.rb4
-rwxr-xr-xspec/unit/indirector/checksum/file.rb17
-rwxr-xr-xspec/unit/indirector/direct_file_server.rb24
-rwxr-xr-xspec/unit/indirector/file.rb50
-rwxr-xr-xspec/unit/indirector/file_metadata/file.rb50
-rwxr-xr-xspec/unit/indirector/indirection.rb215
-rwxr-xr-xspec/unit/indirector/memory.rb30
-rwxr-xr-xspec/unit/indirector/node/memory.rb5
-rwxr-xr-xspec/unit/indirector/plain.rb6
-rwxr-xr-xspec/unit/indirector/request.rb18
-rwxr-xr-xspec/unit/indirector/yaml.rb34
-rwxr-xr-xspec/unit/node.rb4
-rwxr-xr-xspec/unit/node/catalog.rb4
-rwxr-xr-xspec/unit/node/facts.rb6
-rwxr-xr-xspec/unit/transaction/report.rb14
31 files changed, 473 insertions, 395 deletions
diff --git a/lib/puppet/indirector.rb b/lib/puppet/indirector.rb
index c30c097b2..a8a7a84d1 100644
--- a/lib/puppet/indirector.rb
+++ b/lib/puppet/indirector.rb
@@ -9,6 +9,7 @@ module Puppet::Indirector
require 'puppet/indirector/indirection'
require 'puppet/indirector/terminus'
+ require 'puppet/indirector/envelope'
# Declare that the including class indirects its methods to
# this terminus. The terminus name must be the name of a Puppet
@@ -20,6 +21,7 @@ module Puppet::Indirector
# populate this class with the various new methods
extend ClassMethods
include InstanceMethods
+ include Puppet::Indirector::Envelope
# instantiate the actual Terminus for that type and this name (:ldap, w/ args :node)
# & hook the instantiated Terminus into this class (Node: @indirection = terminus)
@@ -28,41 +30,32 @@ module Puppet::Indirector
end
module ClassMethods
- attr_reader :indirection
+ attr_reader :indirection
- def cache_class=(klass)
- indirection.cache_class = klass
- end
+ def cache_class=(klass)
+ indirection.cache_class = klass
+ end
- def terminus_class=(klass)
- indirection.terminus_class = klass
- end
+ def terminus_class=(klass)
+ indirection.terminus_class = klass
+ end
- def find(*args)
- indirection.find(*args)
- end
+ def find(*args)
+ indirection.find Puppet::Indirector::Request.new(indirection.name, :find, *args)
+ end
- def destroy(*args)
- indirection.destroy(*args)
- end
+ def destroy(*args)
+ indirection.destroy Puppet::Indirector::Request.new(indirection.name, :destroy, *args)
+ end
- def search(*args)
- indirection.search(*args)
- end
-
- def version(*args)
- indirection.version(*args)
- end
+ def search(*args)
+ indirection.search Puppet::Indirector::Request.new(indirection.name, :search, *args)
+ end
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)
- end
+ def save(*args)
+ self.class.indirection.save Puppet::Indirector::Request.new(self.class.indirection.name, :save, self, *args)
+ end
end
end
diff --git a/lib/puppet/indirector/checksum/file.rb b/lib/puppet/indirector/checksum/file.rb
index 3b196a1f8..5489b40e8 100644
--- a/lib/puppet/indirector/checksum/file.rb
+++ b/lib/puppet/indirector/checksum/file.rb
@@ -18,8 +18,8 @@ class Puppet::Checksum::File < Puppet::Indirector::File
path.join(File::SEPARATOR)
end
- def save(file)
- path = File.dirname(path(file.name))
+ def save(request)
+ path = File.dirname(path(request.key))
# Make the directories if necessary.
unless FileTest.directory?(path)
diff --git a/lib/puppet/indirector/direct_file_server.rb b/lib/puppet/indirector/direct_file_server.rb
index 31cc9aa16..1711356f9 100644
--- a/lib/puppet/indirector/direct_file_server.rb
+++ b/lib/puppet/indirector/direct_file_server.rb
@@ -11,17 +11,17 @@ class Puppet::Indirector::DirectFileServer < Puppet::Indirector::Terminus
include Puppet::Util::URIHelper
include Puppet::FileServing::TerminusHelper
- def find(key, options = {})
- uri = key2uri(key)
+ def find(request)
+ uri = key2uri(request.key)
return nil unless FileTest.exists?(uri.path)
- instance = model.new(key, :path => uri.path)
- instance.links = options[:links] if options[:links]
+ instance = model.new(request.key, :path => uri.path)
+ instance.links = request.options[:links] if request.options[:links]
return instance
end
- def search(key, options = {})
- uri = key2uri(key)
+ def search(request)
+ uri = key2uri(request.key)
return nil unless FileTest.exists?(uri.path)
- path2instances(key, uri.path, options)
+ path2instances(request.key, uri.path, request.options)
end
end
diff --git a/lib/puppet/indirector/file.rb b/lib/puppet/indirector/file.rb
index 8c984154b..e5382155f 100644
--- a/lib/puppet/indirector/file.rb
+++ b/lib/puppet/indirector/file.rb
@@ -3,27 +3,27 @@ require 'puppet/indirector/terminus'
# An empty terminus type, meant to just return empty objects.
class Puppet::Indirector::File < Puppet::Indirector::Terminus
# Remove files on disk.
- def destroy(name)
+ def destroy(request)
if respond_to?(:path)
- path = path(name)
+ path = path(request.key)
else
- path = name
+ path = request.key
end
- raise Puppet::Error.new("File %s does not exist; cannot destroy" % [name]) unless File.exist?(path)
+ raise Puppet::Error.new("File %s does not exist; cannot destroy" % [request.key]) unless File.exist?(path)
begin
File.unlink(path)
rescue => detail
- raise Puppet::Error, "Could not remove %s: %s" % [name, detail]
+ raise Puppet::Error, "Could not remove %s: %s" % [request.key, detail]
end
end
# Return a model instance for a given file on disk.
- def find(name)
+ def find(request)
if respond_to?(:path)
- path = path(name)
+ path = path(request.key)
else
- path = name
+ path = request.key
end
return nil unless File.exist?(path)
@@ -38,20 +38,20 @@ class Puppet::Indirector::File < Puppet::Indirector::Terminus
end
# Save a new file to disk.
- def save(file)
+ def save(request)
if respond_to?(:path)
- path = path(file.name)
+ path = path(request.key)
else
- path = file.path
+ path = request.key
end
dir = File.dirname(path)
- raise Puppet::Error.new("Cannot save %s; parent directory %s does not exist" % [file, dir]) unless File.directory?(dir)
+ raise Puppet::Error.new("Cannot save %s; parent directory %s does not exist" % [request.key, dir]) unless File.directory?(dir)
begin
- File.open(path, "w") { |f| f.print file.content }
+ File.open(path, "w") { |f| f.print request.instance.content }
rescue => detail
- raise Puppet::Error, "Could not write %s: %s" % [file, detail]
+ raise Puppet::Error, "Could not write %s: %s" % [request.key, detail]
end
end
end
diff --git a/lib/puppet/indirector/file_metadata/file.rb b/lib/puppet/indirector/file_metadata/file.rb
index b36846bbe..c46015c38 100644
--- a/lib/puppet/indirector/file_metadata/file.rb
+++ b/lib/puppet/indirector/file_metadata/file.rb
@@ -9,14 +9,14 @@ require 'puppet/indirector/direct_file_server'
class Puppet::Indirector::FileMetadata::File < Puppet::Indirector::DirectFileServer
desc "Retrieve file metadata directly from the local filesystem."
- def find(key, options = {})
+ def find(request)
return unless data = super
data.collect_attributes
return data
end
- def search(key, options = {})
+ def search(request)
return unless result = super
result.each { |instance| instance.collect_attributes }
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index 1b6613035..56cd687af 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -126,6 +126,11 @@ class Puppet::Indirector::Indirection
end
end
+ # Set up our request object.
+ def request(key, method, arguments = nil)
+ Puppet::Indirector::Request.new(self.name, key, method, arguments)
+ end
+
# Return the singleton terminus for this indirection.
def terminus(terminus_name = nil)
# Get the name of the terminus.
@@ -167,28 +172,27 @@ class Puppet::Indirector::Indirection
end
end
- def find(key, *args)
- request = request(key, :find, *args)
+ def find(request)
terminus = prepare(request)
# See if our instance is in the cache and up to date.
- if cache? and cached = cache.find(key, *args)
+ if cache? and cached = cache.find(request)
if cached.expired?
- Puppet.info "Cached %s %s expired at %s; not using" % [self.name, key, cached.expiration]
+ Puppet.info "Cached %s %s expired at %s; not using" % [self.name, request.key, cached.expiration]
else
- Puppet.debug "Using cached %s %s" % [self.name, key]
+ Puppet.debug "Using cached %s %s" % [self.name, request.key]
return cached
end
end
# Otherwise, return the result from the terminus, caching if appropriate.
- if result = terminus.find(key, *args)
- # Include the envelope module, so we can set the expiration.
- result.extend(Puppet::Indirector::Envelope)
+ if result = terminus.find(request)
result.expiration ||= self.expiration
if cache?
- Puppet.info "Caching %s %s" % [self.name, key]
- cache.save(result, *args)
+ Puppet.info "Caching %s %s" % [self.name, request.key]
+ cached_request = request.clone
+ cached_request.instance = result
+ cache.save(cached_request)
end
return result
@@ -198,38 +202,35 @@ class Puppet::Indirector::Indirection
end
# Remove something via the terminus.
- def destroy(key, *args)
- request = request(key, :destroy, *args)
+ def destroy(request)
terminus = prepare(request)
- terminus.destroy(key, *args)
+ terminus.destroy(request)
- if cache? and cached = cache.find(key, *args)
- cache.destroy(key, *args)
+ if cache? and cached = cache.find(request)
+ cache.destroy(request)
end
nil
end
# Search for more than one instance. Should always return an array.
- def search(key, *args)
- request = request(key, :search, *args)
+ def search(request)
terminus = prepare(request)
- result = terminus.search(key, *args)
+ result = terminus.search(request)
result
end
# Save the instance in the appropriate terminus. This method is
# normally an instance method on the indirected class.
- def save(instance, *args)
- request = request(instance.name, :save, *args)
+ def save(request)
terminus = prepare(request)
# If caching is enabled, save our document there
- cache.save(instance, *args) if cache?
- terminus.save(instance, *args)
+ cache.save(request) if cache?
+ terminus.save(request)
end
private
@@ -268,9 +269,4 @@ class Puppet::Indirector::Indirection
end
return klass.new
end
-
- # Set up our request object.
- def request(key, method, arguments = nil)
- Puppet::Indirector::Request.new(self.name, key, method, arguments)
- end
end
diff --git a/lib/puppet/indirector/memory.rb b/lib/puppet/indirector/memory.rb
index b97e6ffb6..19acc14e2 100644
--- a/lib/puppet/indirector/memory.rb
+++ b/lib/puppet/indirector/memory.rb
@@ -6,16 +6,16 @@ class Puppet::Indirector::Memory < Puppet::Indirector::Terminus
@instances = {}
end
- def destroy(name)
- raise ArgumentError.new("Could not find %s to destroy" % name) unless @instances.include?(name)
- @instances.delete(name)
+ def destroy(request)
+ raise ArgumentError.new("Could not find %s to destroy" % request.key) unless @instances.include?(request.key)
+ @instances.delete(request.key)
end
- def find(name)
- @instances[name]
+ def find(request)
+ @instances[request.key]
end
- def save(instance)
- @instances[instance.name] = instance
+ def save(request)
+ @instances[request.key] = request.instance
end
end
diff --git a/lib/puppet/indirector/plain.rb b/lib/puppet/indirector/plain.rb
index 8bdf8469c..2caa0946d 100644
--- a/lib/puppet/indirector/plain.rb
+++ b/lib/puppet/indirector/plain.rb
@@ -3,7 +3,7 @@ require 'puppet/indirector/terminus'
# An empty terminus type, meant to just return empty objects.
class Puppet::Indirector::Plain < Puppet::Indirector::Terminus
# Just return nothing.
- def find(name)
- indirection.model.new(name)
+ def find(request)
+ indirection.model.new(request.key)
end
end
diff --git a/lib/puppet/indirector/request.rb b/lib/puppet/indirector/request.rb
index 708862b28..68b7ee160 100644
--- a/lib/puppet/indirector/request.rb
+++ b/lib/puppet/indirector/request.rb
@@ -5,7 +5,7 @@ require 'puppet/indirector'
class Puppet::Indirector::Request
attr_accessor :indirection_name, :key, :method, :options, :instance
- def initialize(indirection_name, key, method, options = {})
+ def initialize(indirection_name, method, key, options = {})
@indirection_name, @method, @options = indirection_name, method, (options || {})
if key.is_a?(String) or key.is_a?(Symbol)
diff --git a/lib/puppet/indirector/yaml.rb b/lib/puppet/indirector/yaml.rb
index 4dd29159e..23bca02b8 100644
--- a/lib/puppet/indirector/yaml.rb
+++ b/lib/puppet/indirector/yaml.rb
@@ -3,23 +3,22 @@ require 'puppet/indirector/terminus'
# The base class for YAML indirection termini.
class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
# Read a given name's file in and convert it from YAML.
- def find(name)
- raise ArgumentError.new("You must specify the name of the object to retrieve") unless name
- file = path(name)
+ def find(request)
+ file = path(request.key)
return nil unless FileTest.exist?(file)
begin
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, request.key, detail]
end
end
# Convert our object to YAML and store it to the disk.
- def save(object)
- raise ArgumentError.new("You can only save objects that respond to :name") unless object.respond_to?(:name)
+ def save(request)
+ raise ArgumentError.new("You can only save objects that respond to :name") unless request.instance.respond_to?(:name)
- file = path(object.name)
+ file = path(request.key)
basedir = File.dirname(file)
@@ -29,15 +28,15 @@ class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
end
begin
- File.open(file, "w", 0660) { |f| f.print to_yaml(object) }
+ File.open(file, "w", 0660) { |f| f.print to_yaml(request.instance) }
rescue TypeError => detail
- Puppet.err "Could not save %s %s: %s" % [self.name, object.name, detail]
+ Puppet.err "Could not save %s %s: %s" % [self.name, request.key, detail]
end
end
- def version(name)
- return nil unless FileTest.exist?(path(name))
- return File.stat(path(name)).mtime
+ # Return the path to a given node's file.
+ def path(name)
+ File.join(Puppet[:yamldir], self.class.indirection_name.to_s, name.to_s + ".yaml")
end
private
@@ -49,9 +48,4 @@ class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
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.class.indirection_name.to_s, name.to_s + ".yaml")
- end
end
diff --git a/lib/puppet/transaction/report.rb b/lib/puppet/transaction/report.rb
index 56f8a602a..bd62ebbe6 100644
--- a/lib/puppet/transaction/report.rb
+++ b/lib/puppet/transaction/report.rb
@@ -34,6 +34,10 @@ class Puppet::Transaction::Report
end
end
+ def name
+ host
+ end
+
# Create a new metric.
def newmetric(name, hash)
metric = Puppet::Util::Metric.new(name)
diff --git a/spec/integration/indirector/direct_file_server.rb b/spec/integration/indirector/direct_file_server.rb
index 383486986..40b753a6c 100755
--- a/spec/integration/indirector/direct_file_server.rb
+++ b/spec/integration/indirector/direct_file_server.rb
@@ -19,7 +19,7 @@ describe Puppet::Indirector::DirectFileServer, " when interacting with the files
it "should return an instance of the model" do
FileTest.expects(:exists?).with(@filepath).returns(true)
- @terminus.find("file://host#{@filepath}").should be_instance_of(Puppet::FileServing::Content)
+ @terminus.find(@terminus.indirection.request(:find, "file://host#{@filepath}")).should be_instance_of(Puppet::FileServing::Content)
end
it "should return an instance capable of returning its content" do
@@ -27,7 +27,7 @@ describe Puppet::Indirector::DirectFileServer, " when interacting with the files
File.stubs(:lstat).with(@filepath).returns(stub("stat", :ftype => "file"))
File.expects(:read).with(@filepath).returns("my content")
- instance = @terminus.find("file://host#{@filepath}")
+ instance = @terminus.find(@terminus.indirection.request(:find, "file://host#{@filepath}"))
instance.content.should == "my content"
end
@@ -50,10 +50,12 @@ describe Puppet::Indirector::DirectFileServer, " when interacting with FileServi
end
Dir.expects(:entries).with(@filepath).returns @subfiles
+
+ @request = @terminus.indirection.request(:search, "file:///my/file", :recurse => true)
end
it "should return an instance for every file in the fileset" do
- result = @terminus.search("file:///my/file", :recurse => true)
+ result = @terminus.search(@request)
result.should be_instance_of(Array)
result.length.should == 3
result.each { |r| r.should be_instance_of(Puppet::FileServing::Content) }
@@ -65,7 +67,7 @@ describe Puppet::Indirector::DirectFileServer, " when interacting with FileServi
File.expects(:read).with(File.join(@filepath, name)).returns("#{name} content")
end
- @terminus.search("file:///my/file", :recurse => true).each do |instance|
+ @terminus.search(@request).each do |instance|
case instance.key
when /one/: instance.content.should == "one content"
when /two/: instance.content.should == "two content"
diff --git a/spec/integration/node/catalog.rb b/spec/integration/node/catalog.rb
new file mode 100755
index 000000000..d0ddfd8aa
--- /dev/null
+++ b/spec/integration/node/catalog.rb
@@ -0,0 +1,34 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-10-18.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe Puppet::Node::Catalog do
+ describe "when using the indirector" do
+ after { Puppet::Node::Catalog.indirection.clear_cache }
+
+ it "should be able to delegate to the :yaml terminus" do
+ Puppet::Node::Catalog.indirection.stubs(:terminus_class).returns :yaml
+
+ # Load now, before we stub the exists? method.
+ Puppet::Node::Catalog.indirection.terminus(:yaml)
+
+ file = File.join(Puppet[:yamldir], "catalog", "me.yaml")
+ FileTest.expects(:exist?).with(file).returns false
+ Puppet::Node::Catalog.find("me").should be_nil
+ end
+
+ it "should be able to delegate to the :compiler terminus" do
+ Puppet::Node::Catalog.indirection.stubs(:terminus_class).returns :compiler
+
+ # Load now, before we stub the exists? method.
+ compiler = Puppet::Node::Catalog.indirection.terminus(:compiler)
+
+ compiler.expects(:compile).with("me").returns nil
+
+ Puppet::Node::Catalog.find("me").should be_nil
+ end
+ end
+end
diff --git a/spec/shared_behaviours/file_serving.rb b/spec/shared_behaviours/file_serving.rb
index b5ab6b0fd..82f207243 100644
--- a/spec/shared_behaviours/file_serving.rb
+++ b/spec/shared_behaviours/file_serving.rb
@@ -6,7 +6,7 @@
describe "Puppet::FileServing::Files", :shared => true do
it "should use the rest terminus when the 'puppet' URI scheme is used and a host name is present" do
uri = "puppet://myhost/mymod/my/file"
- @indirection.terminus(:rest).expects(:find).with(uri)
+ @indirection.terminus(:rest).expects(:find)
@test_class.find(uri)
end
@@ -14,7 +14,7 @@ describe "Puppet::FileServing::Files", :shared => true do
uri = "puppet:///mymod/my/file"
Puppet.settings.stubs(:value).with(:name).returns("puppetd")
Puppet.settings.stubs(:value).with(:modulepath).returns("")
- @indirection.terminus(:rest).expects(:find).with(uri)
+ @indirection.terminus(:rest).expects(:find)
@test_class.find(uri)
end
@@ -27,27 +27,27 @@ describe "Puppet::FileServing::Files", :shared => true do
Puppet.settings.stubs(:value).with(:libdir).returns("")
Puppet.settings.stubs(:value).with(:fileserverconfig).returns("/whatever")
Puppet.settings.stubs(:value).with(:environment).returns("")
- @indirection.terminus(:file_server).expects(:find).with(uri)
+ @indirection.terminus(:file_server).expects(:find)
@indirection.terminus(:file_server).stubs(:authorized?).returns(true)
@test_class.find(uri)
end
it "should use the file_server terminus when the 'puppetmounts' URI scheme is used" do
uri = "puppetmounts:///mymod/my/file"
- @indirection.terminus(:file_server).expects(:find).with(uri)
+ @indirection.terminus(:file_server).expects(:find)
@indirection.terminus(:file_server).stubs(:authorized?).returns(true)
@test_class.find(uri)
end
it "should use the file terminus when the 'file' URI scheme is used" do
uri = "file:///mymod/my/file"
- @indirection.terminus(:file).expects(:find).with(uri)
+ @indirection.terminus(:file).expects(:find)
@test_class.find(uri)
end
it "should use the file terminus when a fully qualified path is provided" do
uri = "/mymod/my/file"
- @indirection.terminus(:file).expects(:find).with(uri)
+ @indirection.terminus(:file).expects(:find)
@test_class.find(uri)
end
end
diff --git a/spec/shared_behaviours/memory_terminus.rb b/spec/shared_behaviours/memory_terminus.rb
new file mode 100644
index 000000000..a00dc9f74
--- /dev/null
+++ b/spec/shared_behaviours/memory_terminus.rb
@@ -0,0 +1,32 @@
+#
+# Created by Luke Kanies on 2008-4-8.
+# Copyright (c) 2008. All rights reserved.
+
+describe "A Memory Terminus", :shared => true do
+ it "should find no instances by default" do
+ @searcher.find(@request).should be_nil
+ end
+
+ it "should be able to find instances that were previously saved" do
+ @searcher.save(@request)
+ @searcher.find(@request).should equal(@instance)
+ end
+
+ it "should replace existing saved instances when a new instance with the same name is saved" do
+ @searcher.save(@request)
+ two = stub 'second', :name => @name
+ trequest = stub 'request', :key => @name, :instance => two
+ @searcher.save(trequest)
+ @searcher.find(@request).should equal(two)
+ end
+
+ it "should be able to remove previously saved instances" do
+ @searcher.save(@request)
+ @searcher.destroy(@request)
+ @searcher.find(@request).should be_nil
+ end
+
+ it "should fail when asked to destroy an instance that does not exist" do
+ proc { @searcher.destroy(@request) }.should raise_error(ArgumentError)
+ end
+end
diff --git a/spec/unit/indirector.rb b/spec/unit/indirector.rb
index 1a5867c51..892e70c1f 100755
--- a/spec/unit/indirector.rb
+++ b/spec/unit/indirector.rb
@@ -21,6 +21,10 @@ describe Puppet::Indirector, "when registering an indirection" do
before do
@thingie = Class.new do
extend Puppet::Indirector
+ attr_reader :name
+ def initialize(name)
+ @name = name
+ end
end
end
@@ -55,48 +59,92 @@ describe Puppet::Indirector, "when registering an indirection" do
end
end
-describe Puppet::Indirector, " when redirecting a model" do
+describe "Delegated Indirection Method", :shared => true do
+ it "should create an indirection request with the indirection name, the method being delegated, and all of the arguments to the method call" do
+ Puppet::Indirector::Request.expects(:new).with(@indirection.name, @method, "me", :one => :two)
+ @indirection.stubs(@method)
+ @thingie.send(@method, "me", :one => :two)
+ end
+
+ it "should delegate to the indirection" do
+ @indirection.expects(@method)
+ @thingie.send(@method, "me")
+ end
+
+ it "should pass the indirection's request instance to the indirection's method" do
+ request = mock 'request'
+ Puppet::Indirector::Request.expects(:new).returns request
+ @indirection.expects(@method).with(request)
+ @thingie.send(@method, "me")
+ end
+
+ it "should return the results of the delegation as its result" do
+ request = mock 'request'
+ @indirection.expects(@method).returns "yay"
+ @thingie.send(@method, "me").should == "yay"
+ end
+end
+
+describe Puppet::Indirector, "when redirecting a model" do
before do
@thingie = Class.new do
extend Puppet::Indirector
+ attr_reader :name
+ def initialize(name)
+ @name = name
+ end
end
@indirection = @thingie.send(:indirects, :test)
end
- it "should give the model the ability set a version" do
- thing = @thingie.new
- thing.should respond_to(:version=)
+ it "should include the Envelope module in the model" do
+ @thingie.ancestors.should be_include(Puppet::Indirector::Envelope)
end
- it "should give the model the ability retrieve a version" do
- thing = @thingie.new
- thing.should respond_to(:version)
+ describe "when finding instances via the model" do
+ before { @method = :find }
+ it_should_behave_like "Delegated Indirection Method"
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
+ describe "when destroying instances via the model" do
+ before { @method = :destroy }
+ it_should_behave_like "Delegated Indirection Method"
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
+ describe "when searching for instances via the model" do
+ before { @method = :search }
+ it_should_behave_like "Delegated Indirection Method"
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
+ # This is an instance method, so it behaves a bit differently.
+ describe "when saving instances via the model" do
+ before do
+ @instance = @thingie.new("me")
+ 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 pass the method name, the instance, plus all passed arguments to the indirection's request method" do
+ Puppet::Indirector::Request.expects(:new).with(@indirection.name, :save, @instance, :one => :two)
+ @indirection.stubs(:save)
+ @instance.save(:one => :two)
+ end
- it "should give the model the ability to look up an instance's version by letting the indirection perform the lookup" do
- @indirection.expects(:version).with(:thing)
- @thingie.version(:thing)
+ it "should delegate to the indirection" do
+ @indirection.expects(:save)
+ @instance.save
+ end
+
+ it "should pass the indirection's request instance to the indirection's method" do
+ request = mock 'request'
+ Puppet::Indirector::Request.expects(:new).returns request
+ @indirection.expects(:save).with(request)
+ @instance.save
+ end
+
+ it "should return the results of the delegation as its result" do
+ request = mock 'request'
+ @indirection.expects(:save).returns "yay"
+ @instance.save.should == "yay"
+ end
end
it "should give the model the ability to set the indirection terminus class" do
diff --git a/spec/unit/indirector/catalog/compiler.rb b/spec/unit/indirector/catalog/compiler.rb
index a4a0acd58..5a26302d1 100755
--- a/spec/unit/indirector/catalog/compiler.rb
+++ b/spec/unit/indirector/catalog/compiler.rb
@@ -75,7 +75,9 @@ describe Puppet::Node::Catalog::Compiler, " when finding nodes" do
it "should fail if it cannot find the node" do
@node.stubs :merge
Puppet::Node.expects(:find_by_any_name).with(@name).returns(nil)
- proc { @compiler.find(@name) }.should raise_error(Puppet::Error)
+ request = stub 'request', :key => @name
+ @compiler.find(request)
+ proc { @compiler.find(request) }.should raise_error(Puppet::Error)
end
end
diff --git a/spec/unit/indirector/checksum/file.rb b/spec/unit/indirector/checksum/file.rb
index 64425904f..857d7b050 100755
--- a/spec/unit/indirector/checksum/file.rb
+++ b/spec/unit/indirector/checksum/file.rb
@@ -38,6 +38,8 @@ describe Puppet::Checksum::File do
Puppet.stubs(:[]).with(:bucketdir).returns(@dir)
@path = @store.path(@value)
+
+ @request = stub 'request', :key => @value
end
@@ -76,7 +78,7 @@ describe Puppet::Checksum::File do
# The smallest test that will use the calculated path
it "should look for the calculated path" do
File.expects(:exist?).with(@path).returns(false)
- @store.find(@value)
+ @store.find(@request)
end
it "should return an instance of Puppet::Checksum created with the content if the file exists" do
@@ -87,18 +89,18 @@ describe Puppet::Checksum::File do
File.expects(:exist?).with(@path).returns(true)
File.expects(:read).with(@path).returns(content)
- @store.find(@value).should equal(sum)
+ @store.find(@request).should equal(sum)
end
it "should return nil if no file is found" do
File.expects(:exist?).with(@path).returns(false)
- @store.find(@value).should be_nil
+ @store.find(@request).should be_nil
end
it "should fail intelligently if a found file cannot be read" do
File.expects(:exist?).with(@path).returns(true)
File.expects(:read).with(@path).raises(RuntimeError)
- proc { @store.find(@value) }.should raise_error(Puppet::Error)
+ proc { @store.find(@request) }.should raise_error(Puppet::Error)
end
end
@@ -112,7 +114,7 @@ describe Puppet::Checksum::File do
File.expects(:open).with(@path, "w")
file = stub 'file', :name => @value
- @store.save(file)
+ @store.save(@request)
end
it "should make any directories necessary for storage" do
@@ -122,8 +124,7 @@ describe Puppet::Checksum::File do
File.expects(:directory?).with(File.dirname(@path)).returns(true)
File.expects(:open).with(@path, "w")
- file = stub 'file', :name => @value
- @store.save(file)
+ @store.save(@request)
end
end
@@ -132,7 +133,7 @@ describe Puppet::Checksum::File do
File.expects(:exist?).with(@path).returns(true)
File.expects(:unlink).with(@path)
- @store.destroy(@value)
+ @store.destroy(@request)
end
end
end
diff --git a/spec/unit/indirector/direct_file_server.rb b/spec/unit/indirector/direct_file_server.rb
index a89b938e7..a8583716a 100755
--- a/spec/unit/indirector/direct_file_server.rb
+++ b/spec/unit/indirector/direct_file_server.rb
@@ -23,19 +23,21 @@ describe Puppet::Indirector::DirectFileServer do
@server = @direct_file_class.new
@uri = "file:///my/local"
+
+ @request = stub 'request', :key => @uri, :options => {}
end
describe Puppet::Indirector::DirectFileServer, "when finding a single file" do
it "should return nil if the file does not exist" do
FileTest.expects(:exists?).with("/my/local").returns false
- @server.find(@uri).should be_nil
+ @server.find(@request).should be_nil
end
it "should return a Content instance created with the full path to the file if the file exists" do
FileTest.expects(:exists?).with("/my/local").returns true
@model.expects(:new).returns(:mycontent)
- @server.find(@uri).should == :mycontent
+ @server.find(@request).should == :mycontent
end
end
@@ -49,18 +51,20 @@ describe Puppet::Indirector::DirectFileServer do
it "should create the Content instance with the original key as the key" do
@model.expects(:new).with { |key, options| key == @uri }.returns(@data)
- @server.find(@uri)
+ @server.find(@request)
end
it "should pass the full path to the instance" do
@model.expects(:new).with { |key, options| options[:path] == "/my/local" }.returns(@data)
- @server.find(@uri)
+ @server.find(@request)
end
it "should pass the :links setting on to the created Content instance if the file exists and there is a value for :links" do
@model.expects(:new).returns(@data)
@data.expects(:links=).with(:manage)
- @server.find(@uri, :links => :manage)
+
+ @request.stubs(:options).returns(:links => :manage)
+ @server.find(@request)
end
end
@@ -68,25 +72,27 @@ describe Puppet::Indirector::DirectFileServer do
it "should return nil if the file does not exist" do
FileTest.expects(:exists?).with("/my/local").returns false
- @server.find(@uri).should be_nil
+ @server.find(@request).should be_nil
end
it "should pass the original key to :path2instances" do
FileTest.expects(:exists?).with("/my/local").returns true
@server.expects(:path2instances).with { |uri, path, options| uri == @uri }
- @server.search(@uri)
+ @server.search(@request)
end
it "should use :path2instances from the terminus_helper to return instances if the file exists" do
FileTest.expects(:exists?).with("/my/local").returns true
@server.expects(:path2instances)
- @server.search(@uri)
+ @server.search(@request)
end
it "should pass any options on to :path2instances" do
FileTest.expects(:exists?).with("/my/local").returns true
@server.expects(:path2instances).with { |uri, path, options| options == {:testing => :one, :other => :two}}
- @server.search(@uri, :testing => :one, :other => :two)
+
+ @request.stubs(:options).returns(:testing => :one, :other => :two)
+ @server.search(@request)
end
end
end
diff --git a/spec/unit/indirector/file.rb b/spec/unit/indirector/file.rb
index fa10743ef..67ead4cdb 100755
--- a/spec/unit/indirector/file.rb
+++ b/spec/unit/indirector/file.rb
@@ -21,6 +21,8 @@ describe Puppet::Indirector::File do
@path = "/my/file"
@dir = "/my"
+
+ @request = stub 'request', :key => @path
end
describe Puppet::Indirector::File, " when finding files" do
@@ -37,7 +39,7 @@ describe Puppet::Indirector::File do
File.expects(:exist?).with(@path).returns(true)
File.expects(:read).with(@path).returns(content)
- @searcher.find(@path)
+ @searcher.find(@request)
end
it "should create the model instance with the content as the only argument to initialization" do
@@ -48,18 +50,18 @@ describe Puppet::Indirector::File do
File.expects(:exist?).with(@path).returns(true)
File.expects(:read).with(@path).returns(content)
- @searcher.find(@path).should equal(file)
+ @searcher.find(@request).should equal(file)
end
it "should return nil if no file is found" do
File.expects(:exist?).with(@path).returns(false)
- @searcher.find(@path).should be_nil
+ @searcher.find(@request).should be_nil
end
it "should fail intelligently if a found file cannot be read" do
File.expects(:exist?).with(@path).returns(true)
File.expects(:read).with(@path).raises(RuntimeError)
- proc { @searcher.find(@path) }.should raise_error(Puppet::Error)
+ proc { @searcher.find(@request) }.should raise_error(Puppet::Error)
end
it "should use the path() method to calculate the path if it exists" do
@@ -68,42 +70,39 @@ describe Puppet::Indirector::File do
end
File.expects(:exist?).with(@path.upcase).returns(false)
- @searcher.find(@path)
+ @searcher.find(@request)
end
end
describe Puppet::Indirector::File, " when saving files" do
+ before do
+ @content = "my content"
+ @file = stub 'file', :content => @content, :path => @path, :name => @path
+ @request.stubs(:instance).returns @file
+ end
it "should provide a method to save file contents at a specified path" do
filehandle = mock 'file'
- content = "my content"
File.expects(:directory?).with(@dir).returns(true)
File.expects(:open).with(@path, "w").yields(filehandle)
- filehandle.expects(:print).with(content)
-
- file = stub 'file', :content => content, :path => @path, :name => @path
+ filehandle.expects(:print).with(@content)
- @searcher.save(file)
+ @searcher.save(@request)
end
it "should fail intelligently if the file's parent directory does not exist" do
File.expects(:directory?).with(@dir).returns(false)
- file = stub 'file', :path => @path, :name => @path
-
- proc { @searcher.save(file) }.should raise_error(Puppet::Error)
+ proc { @searcher.save(@request) }.should raise_error(Puppet::Error)
end
it "should fail intelligently if a file cannot be written" do
filehandle = mock 'file'
- content = "my content"
File.expects(:directory?).with(@dir).returns(true)
File.expects(:open).with(@path, "w").yields(filehandle)
- filehandle.expects(:print).with(content).raises(ArgumentError)
-
- file = stub 'file', :content => content, :path => @path, :name => @path
+ filehandle.expects(:print).with(@content).raises(ArgumentError)
- proc { @searcher.save(file) }.should raise_error(Puppet::Error)
+ proc { @searcher.save(@request) }.should raise_error(Puppet::Error)
end
it "should use the path() method to calculate the path if it exists" do
@@ -111,10 +110,11 @@ describe Puppet::Indirector::File do
name.upcase
end
- file = stub 'file', :name => "/yay"
+ # Reset the key to something without a parent dir, so no checks are necessary
+ @request.stubs(:key).returns "/my"
- File.expects(:open).with("/YAY", "w")
- @searcher.save(file)
+ File.expects(:open).with("/MY", "w")
+ @searcher.save(@request)
end
end
@@ -124,20 +124,20 @@ describe Puppet::Indirector::File do
File.expects(:exist?).with(@path).returns(true)
File.expects(:unlink).with(@path)
- @searcher.destroy(@path)
+ @searcher.destroy(@request)
end
it "should throw an exception if the file is not found" do
File.expects(:exist?).with(@path).returns(false)
- proc { @searcher.destroy(@path) }.should raise_error(Puppet::Error)
+ proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)
end
it "should fail intelligently if the file cannot be removed" do
File.expects(:exist?).with(@path).returns(true)
File.expects(:unlink).with(@path).raises(ArgumentError)
- proc { @searcher.destroy(@path) }.should raise_error(Puppet::Error)
+ proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)
end
it "should use the path() method to calculate the path if it exists" do
@@ -148,7 +148,7 @@ describe Puppet::Indirector::File do
File.expects(:exist?).with("/MY/FILE").returns(true)
File.expects(:unlink).with("/MY/FILE")
- @searcher.destroy(@path)
+ @searcher.destroy(@request)
end
end
end
diff --git a/spec/unit/indirector/file_metadata/file.rb b/spec/unit/indirector/file_metadata/file.rb
index 0a37a6895..9474620c7 100755
--- a/spec/unit/indirector/file_metadata/file.rb
+++ b/spec/unit/indirector/file_metadata/file.rb
@@ -15,34 +15,38 @@ describe Puppet::Indirector::FileMetadata::File do
it "should be a subclass of the DirectFileServer terminus" do
Puppet::Indirector::FileMetadata::File.superclass.should equal(Puppet::Indirector::DirectFileServer)
end
-end
-describe Puppet::Indirector::FileMetadata::File, "when creating the instance for a single found file" do
- before do
- @metadata = Puppet::Indirector::FileMetadata::File.new
- @uri = "file:///my/local"
- @data = mock 'metadata'
- @data.stubs(:collect_attributes)
- FileTest.expects(:exists?).with("/my/local").returns true
- end
+ describe "when creating the instance for a single found file" do
+ before do
+ @metadata = Puppet::Indirector::FileMetadata::File.new
+ @uri = "file:///my/local"
+ @data = mock 'metadata'
+ @data.stubs(:collect_attributes)
+ FileTest.expects(:exists?).with("/my/local").returns true
- it "should collect its attributes when a file is found" do
- @data.expects(:collect_attributes)
+ @request = stub 'request', :key => @uri, :options => {}
+ end
- Puppet::FileServing::Metadata.expects(:new).returns(@data)
- @metadata.find(@uri).should == @data
- end
-end
+ it "should collect its attributes when a file is found" do
+ @data.expects(:collect_attributes)
-describe Puppet::Indirector::FileMetadata::File, "when searching for multiple files" do
- before do
- @metadata = Puppet::Indirector::FileMetadata::File.new
- @uri = "file:///my/local"
+ Puppet::FileServing::Metadata.expects(:new).returns(@data)
+ @metadata.find(@request).should == @data
+ end
end
- it "should collect the attributes of the instances returned" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @metadata.expects(:path2instances).returns( [mock("one", :collect_attributes => nil), mock("two", :collect_attributes => nil)] )
- @metadata.search(@uri)
+ describe "when searching for multiple files" do
+ before do
+ @metadata = Puppet::Indirector::FileMetadata::File.new
+ @uri = "file:///my/local"
+
+ @request = stub 'request', :key => @uri, :options => {}
+ end
+
+ it "should collect the attributes of the instances returned" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @metadata.expects(:path2instances).returns( [mock("one", :collect_attributes => nil), mock("two", :collect_attributes => nil)] )
+ @metadata.search(@request)
+ end
end
end
diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb
index 8768076c6..f33444bbf 100755
--- a/spec/unit/indirector/indirection.rb
+++ b/spec/unit/indirector/indirection.rb
@@ -55,6 +55,8 @@ describe Puppet::Indirector::Indirection do
@instance = stub 'instance', :expiration => nil, :expiration= => nil, :name => "whatever"
@name = :mything
+
+ @request = stub 'instance', :key => "/my/key", :instance => @instance, :options => {}
end
it "should allow setting the ttl" do
@@ -73,57 +75,67 @@ describe Puppet::Indirector::Indirection do
Time.stubs(:now).returns now
@indirection.expiration.should == (Time.now + 100)
end
-
- describe "and looking for a model instance" do
- it "should create a request with the indirection name, the sought-after name, the :find method, and any passed arguments" do
- request = mock 'request'
- Puppet::Indirector::Request.expects(:new).with(@indirection.name, @name, :find, {:one => :two}).returns request
- @indirection.stubs(:check_authorization)
- @terminus.stubs(:find)
+ it "should have a method for creating an indirection request instance" do
+ @indirection.should respond_to(:request)
+ end
- @indirection.find(@name, :one => :two)
+ describe "creates a request" do
+ it "should create it with its name as the request's indirection name" do
+ Puppet::Indirector::Request.expects(:new).with { |name, *other| @indirection.name == name }
+ @indirection.request(:funtest, "yayness")
end
- it "should let the :select_terminus method choose the terminus if the method is defined" do
+ it "should require a method and key" do
+ Puppet::Indirector::Request.expects(:new).with { |name, method, key, *other| method == :funtest and key == "yayness" }
+ @indirection.request(:funtest, "yayness")
+ end
+
+ it "should support optional arguments" do
+ Puppet::Indirector::Request.expects(:new).with { |name, method, key, other| other == {:one => :two} }
+ @indirection.request(:funtest, "yayness", :one => :two)
+ end
+
+ it "should default to the arguments being nil" do
+ Puppet::Indirector::Request.expects(:new).with { |name, method, key, args| args.nil? }
+ @indirection.request(:funtest, "yayness")
+ end
+
+ it "should return the request" do
request = mock 'request'
Puppet::Indirector::Request.expects(:new).returns request
-
+ @indirection.request(:funtest, "yayness").should equal(request)
+ end
+ end
+
+ describe "and looking for a model instance" do
+ it "should let the :select_terminus method choose the terminus if the method is defined" do
# Define the method, so our respond_to? hook matches.
class << @indirection
def select_terminus(request)
end
end
- @indirection.expects(:select_terminus).with(request).returns :test_terminus
+ @indirection.expects(:select_terminus).with(@request).returns :test_terminus
@indirection.stubs(:check_authorization)
@terminus.expects(:find)
- @indirection.find(@name)
+ @indirection.find(@request)
end
it "should let the appropriate terminus perform the lookup" do
- @terminus.expects(:find).with(@name).returns(@instance)
- @indirection.find(@name).should == @instance
+ @terminus.expects(:find).with(@request).returns(@instance)
+ @indirection.find(@request).should == @instance
end
it "should return nil if nothing is returned by the terminus" do
- @terminus.expects(:find).with(@name).returns(nil)
- @indirection.find(@name).should be_nil
- end
-
- it "should extend any found instance with the Envelope module" do
- @terminus.stubs(:find).returns(@instance)
-
- @instance.expects(:extend).with(Puppet::Indirector::Envelope)
- @indirection.find(@name)
+ @terminus.expects(:find).with(@request).returns(nil)
+ @indirection.find(@request).should be_nil
end
it "should set the expiration date on any instances without one set" do
- # Otherwise, our stub method doesn't get used, so the tests fail.
- @instance.stubs(:extend)
@terminus.stubs(:find).returns(@instance)
@indirection.expects(:expiration).returns :yay
@@ -131,12 +143,10 @@ describe Puppet::Indirector::Indirection do
@instance.expects(:expiration).returns(nil)
@instance.expects(:expiration=).with(:yay)
- @indirection.find(@name)
+ @indirection.find(@request)
end
it "should not override an already-set expiration date on returned instances" do
- # Otherwise, our stub method doesn't get used, so the tests fail.
- @instance.stubs(:extend)
@terminus.stubs(:find).returns(@instance)
@indirection.expects(:expiration).never
@@ -144,7 +154,7 @@ describe Puppet::Indirector::Indirection do
@instance.expects(:expiration).returns(:yay)
@instance.expects(:expiration=).never
- @indirection.find(@name)
+ @indirection.find(@request)
end
describe "when caching is enabled" do
@@ -157,23 +167,23 @@ describe Puppet::Indirector::Indirection do
it "should first look in the cache for an instance" do
@terminus.expects(:find).never
- @cache.expects(:find).with(@name).returns @instance
+ @cache.expects(:find).with(@request).returns @instance
- @indirection.find(@name)
+ @indirection.find(@request)
end
it "should return the cached object if it is not expired" do
@instance.stubs(:expired?).returns false
@cache.stubs(:find).returns @instance
- @indirection.find(@name).should equal(@instance)
+ @indirection.find(@request).should equal(@instance)
end
it "should send a debug log if it is using the cached object" do
Puppet.expects(:debug)
@cache.stubs(:find).returns @instance
- @indirection.find(@name)
+ @indirection.find(@request)
end
it "should not return the cached object if it is expired" do
@@ -181,7 +191,7 @@ describe Puppet::Indirector::Indirection do
@cache.stubs(:find).returns @instance
@terminus.stubs(:find).returns nil
- @indirection.find(@name).should be_nil
+ @indirection.find(@request).should be_nil
end
it "should send an info log if it is using the cached object" do
@@ -190,63 +200,67 @@ describe Puppet::Indirector::Indirection do
@cache.stubs(:find).returns @instance
@terminus.stubs(:find).returns nil
- @indirection.find(@name)
+ @indirection.find(@request)
end
it "should cache any objects not retrieved from the cache" do
- @cache.expects(:find).with(@name).returns nil
+ @cache.expects(:find).with(@request).returns nil
- @terminus.expects(:find).with(@name).returns(@instance)
- @cache.expects(:save).with(@instance)
+ @terminus.expects(:find).with(@request).returns(@instance)
+ @cache.expects(:save)
- @indirection.find(@name)
+ @request.expects(:clone).returns(stub('newreq', :instance= => nil))
+
+ @indirection.find(@request)
+ end
+
+ it "should cache a clone of the request with the instance set to the cached object" do
+ @cache.expects(:find).with(@request).returns nil
+
+ newreq = mock 'request'
+ @request.expects(:clone).returns newreq
+ newreq.expects(:instance=).with(@instance)
+
+ @terminus.expects(:find).with(@request).returns(@instance)
+ @cache.expects(:save).with(newreq)
+
+ @indirection.find(@request)
end
it "should send an info log that the object is being cached" do
@cache.stubs(:find).returns nil
+ @request.expects(:clone).returns(stub('newreq', :instance= => nil))
+
@terminus.stubs(:find).returns(@instance)
@cache.stubs(:save)
Puppet.expects(:info)
- @indirection.find(@name)
+ @indirection.find(@request)
end
end
end
describe "and storing a model instance" do
- it "should create a request with the indirection name, the instance's name, the :save method, and any passed arguments" do
- request = mock 'request'
- Puppet::Indirector::Request.expects(:new).with(@indirection.name, @instance.name, :save, {:one => :two}).returns request
-
- @indirection.stubs(:check_authorization)
- @terminus.stubs(:save)
-
- @indirection.save(@instance, :one => :two)
- end
-
it "should let the :select_terminus method choose the terminus if the method is defined" do
- request = mock 'request'
- Puppet::Indirector::Request.expects(:new).returns request
-
# Define the method, so our respond_to? hook matches.
class << @indirection
- def select_terminus(request)
+ def select_terminus(req)
end
end
- @indirection.expects(:select_terminus).with(request).returns :test_terminus
+ @indirection.expects(:select_terminus).with(@request).returns :test_terminus
@indirection.stubs(:check_authorization)
@terminus.expects(:save)
- @indirection.save(@instance)
+ @indirection.save(@request)
end
it "should let the appropriate terminus store the instance" do
- @terminus.expects(:save).with(@instance).returns(@instance)
- @indirection.save(@instance).should == @instance
+ @terminus.expects(:save).with(@request).returns(@instance)
+ @indirection.save(@request).should == @instance
end
describe "when caching is enabled" do
@@ -258,50 +272,37 @@ describe Puppet::Indirector::Indirection do
end
it "should save the object to the cache" do
- @cache.expects(:save).with(@instance)
+ @cache.expects(:save).with(@request)
@terminus.stubs(:save)
- @indirection.save(@instance)
+ @indirection.save(@request)
end
end
end
describe "and removing a model instance" do
- it "should create a request with the indirection name, the name of the instance being destroyed, the :destroy method, and any passed arguments" do
- request = mock 'request'
- Puppet::Indirector::Request.expects(:new).with(@indirection.name, "me", :destroy, {:one => :two}).returns request
-
- @indirection.stubs(:check_authorization)
- @terminus.stubs(:destroy)
-
- @indirection.destroy("me", :one => :two)
- end
-
it "should let the :select_terminus method choose the terminus if the method is defined" do
- request = mock 'request'
- Puppet::Indirector::Request.expects(:new).returns request
-
# Define the method, so our respond_to? hook matches.
class << @indirection
def select_terminus(request)
end
end
- @indirection.expects(:select_terminus).with(request).returns :test_terminus
+ @indirection.expects(:select_terminus).with(@request).returns :test_terminus
@indirection.stubs(:check_authorization)
@terminus.expects(:destroy)
- @indirection.destroy(@name)
+ @indirection.destroy(@request)
end
it "should delegate the instance removal to the appropriate terminus" do
- @terminus.expects(:destroy).with(@name)
- @indirection.destroy(@name)
+ @terminus.expects(:destroy).with(@request)
+ @indirection.destroy(@request)
end
it "should return nil" do
@terminus.stubs(:destroy)
- @indirection.destroy(@name).should be_nil
+ @indirection.destroy(@request).should be_nil
end
describe "when caching is enabled" do
@@ -314,47 +315,34 @@ describe Puppet::Indirector::Indirection do
it "should destroy any found object in the cache" do
cached = mock 'cache'
- @cache.expects(:find).with(@name).returns cached
- @cache.expects(:destroy).with(@name)
+ @cache.expects(:find).with(@request).returns cached
+ @cache.expects(:destroy).with(@request)
@terminus.stubs(:destroy)
- @indirection.destroy(@name)
+ @indirection.destroy(@request)
end
end
end
describe "and searching for multiple model instances" do
- it "should create a request with the indirection name, the search key, the :search method, and any passed arguments" do
- request = mock 'request'
- Puppet::Indirector::Request.expects(:new).with(@indirection.name, "me", :search, {:one => :two}).returns request
-
- @indirection.stubs(:check_authorization)
- @terminus.stubs(:search)
-
- @indirection.search("me", :one => :two)
- end
-
it "should let the :select_terminus method choose the terminus if the method is defined" do
- request = mock 'request'
- Puppet::Indirector::Request.expects(:new).returns request
-
# Define the method, so our respond_to? hook matches.
class << @indirection
- def select_terminus(request)
+ def select_terminus(req)
end
end
- @indirection.expects(:select_terminus).with(request).returns :test_terminus
+ @indirection.expects(:select_terminus).with(@request).returns :test_terminus
@indirection.stubs(:check_authorization)
@terminus.expects(:search)
- @indirection.search("me")
+ @indirection.search(@request)
end
it "should let the appropriate terminus find the matching instances" do
- @terminus.expects(:search).with(@name).returns(@instance)
- @indirection.search(@name).should == @instance
+ @terminus.expects(:search).with(@request).returns(@instance)
+ @indirection.search(@request).should == @instance
end
end
@@ -365,69 +353,72 @@ describe Puppet::Indirector::Indirection do
def authorized?
end
end
+
+ @request = stub 'instance', :key => "/my/key", :instance => @instance, :options => {:node => "mynode"}
end
it "should not check authorization if a node name is not provided" do
@terminus.expects(:authorized?).never
@terminus.stubs(:find)
- @indirection.find("/my/key")
+
+ # The quotes are necessary here, else it looks like a block.
+ @request.stubs(:options).returns({})
+ @indirection.find(@request)
end
it "should pass the request to the terminus's authorization method" do
- request = stub 'request', :options => {:node => "yayhost"}
- Puppet::Indirector::Request.expects(:new).returns(request)
- @terminus.expects(:authorized?).with(request).returns(true)
+ @terminus.expects(:authorized?).with(@request).returns(true)
@terminus.stubs(:find)
- @indirection.find("/my/key", :node => "mynode")
+ @indirection.find(@request)
end
it "should fail while finding instances if authorization returns false" do
@terminus.expects(:authorized?).returns(false)
@terminus.stubs(:find)
- proc { @indirection.find("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ proc { @indirection.find(@request) }.should raise_error(ArgumentError)
end
it "should continue finding instances if authorization returns true" do
@terminus.expects(:authorized?).returns(true)
@terminus.stubs(:find)
- @indirection.find("/my/key", :node => "mynode")
+ @indirection.find(@request)
end
it "should fail while saving instances if authorization returns false" do
@terminus.expects(:authorized?).returns(false)
@terminus.stubs(:save)
- proc { @indirection.save(@instance, :node => "mynode") }.should raise_error(ArgumentError)
+ proc { @indirection.save(@request) }.should raise_error(ArgumentError)
end
it "should continue saving instances if authorization returns true" do
@terminus.expects(:authorized?).returns(true)
@terminus.stubs(:save)
- @indirection.save(@instance, :node => "mynode")
+ @indirection.save(@request)
end
it "should fail while destroying instances if authorization returns false" do
@terminus.expects(:authorized?).returns(false)
@terminus.stubs(:destroy)
- proc { @indirection.destroy("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ proc { @indirection.destroy(@request) }.should raise_error(ArgumentError)
end
it "should continue destroying instances if authorization returns true" do
@terminus.expects(:authorized?).returns(true)
@terminus.stubs(:destroy)
- @indirection.destroy(@instance, :node => "mynode")
+ @indirection.destroy(@request)
end
it "should fail while searching for instances if authorization returns false" do
@terminus.expects(:authorized?).returns(false)
@terminus.stubs(:search)
- proc { @indirection.search("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ proc { @indirection.search(@request) }.should raise_error(ArgumentError)
end
it "should continue searching for instances if authorization returns true" do
@terminus.expects(:authorized?).returns(true)
@terminus.stubs(:search)
- @indirection.search("/my/key", :node => "mynode")
+ @indirection.search(@request)
end
end
diff --git a/spec/unit/indirector/memory.rb b/spec/unit/indirector/memory.rb
index 2e9a7f8f3..3b754a1eb 100755
--- a/spec/unit/indirector/memory.rb
+++ b/spec/unit/indirector/memory.rb
@@ -3,33 +3,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/memory'
-describe "A Memory Terminus", :shared => true do
- it "should find no instances by default" do
- @searcher.find(@name).should be_nil
- end
-
- it "should be able to find instances that were previously saved" do
- @searcher.save(@instance)
- @searcher.find(@name).should equal(@instance)
- end
-
- it "should replace existing saved instances when a new instance with the same name is saved" do
- @searcher.save(@instance)
- two = stub 'second', :name => @name
- @searcher.save(two)
- @searcher.find(@name).should equal(two)
- end
-
- it "should be able to remove previously saved instances" do
- @searcher.save(@instance)
- @searcher.destroy(@instance.name)
- @searcher.find(@name).should be_nil
- end
-
- it "should fail when asked to destroy an instance that does not exist" do
- proc { @searcher.destroy(@instance) }.should raise_error(ArgumentError)
- end
-end
+require 'shared_behaviours/memory_terminus'
describe Puppet::Indirector::Memory do
it_should_behave_like "A Memory Terminus"
@@ -49,5 +23,7 @@ describe Puppet::Indirector::Memory do
@searcher = @memory_class.new
@name = "me"
@instance = stub 'instance', :name => @name
+
+ @request = stub 'request', :key => @name, :instance => @instance
end
end
diff --git a/spec/unit/indirector/node/memory.rb b/spec/unit/indirector/node/memory.rb
index a924c6209..71e01d4f3 100755
--- a/spec/unit/indirector/node/memory.rb
+++ b/spec/unit/indirector/node/memory.rb
@@ -4,14 +4,15 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/memory'
-# All of our behaviour is described here, so we always have to include it.
-require File.dirname(__FILE__) + '/../memory'
+require 'shared_behaviours/memory_terminus'
describe Puppet::Node::Memory do
before do
@name = "me"
@searcher = Puppet::Node::Memory.new
@instance = stub 'instance', :name => @name
+
+ @request = stub 'request', :key => @name, :instance => @instance
end
it_should_behave_like "A Memory Terminus"
diff --git a/spec/unit/indirector/plain.rb b/spec/unit/indirector/plain.rb
index 1277739af..aca2816f2 100755
--- a/spec/unit/indirector/plain.rb
+++ b/spec/unit/indirector/plain.rb
@@ -17,11 +17,13 @@ describe Puppet::Indirector::Plain do
end
@searcher = @plain_class.new
+
+ @request = stub 'request', :key => "yay"
end
it "should return return an instance of the indirected model" do
object = mock 'object'
- @model.expects(:new).with("yay").returns object
- @searcher.find("yay").should equal(object)
+ @model.expects(:new).with(@request.key).returns object
+ @searcher.find(@request).should equal(object)
end
end
diff --git a/spec/unit/indirector/request.rb b/spec/unit/indirector/request.rb
index fd57c5297..cdb40b181 100755
--- a/spec/unit/indirector/request.rb
+++ b/spec/unit/indirector/request.rb
@@ -10,45 +10,45 @@ describe Puppet::Indirector::Request do
end
it "should use provided value as the key if it is a string" do
- Puppet::Indirector::Request.new(:ind, "mykey", :method).key.should == "mykey"
+ Puppet::Indirector::Request.new(:ind, :method, "mykey").key.should == "mykey"
end
it "should use provided value as the key if it is a symbol" do
- Puppet::Indirector::Request.new(:ind, :mykey, :method).key.should == :mykey
+ Puppet::Indirector::Request.new(:ind, :method, :mykey).key.should == :mykey
end
it "should use the name of the provided instance as its key if an instance is provided as the key instead of a string" do
instance = mock 'instance', :name => "mykey"
- request = Puppet::Indirector::Request.new(:ind, instance, :method)
+ request = Puppet::Indirector::Request.new(:ind, :method, instance)
request.key.should == "mykey"
request.instance.should equal(instance)
end
it "should support options specified as a hash" do
- lambda { Puppet::Indirector::Request.new(:ind, :key, :method, :one => :two) }.should_not raise_error(ArgumentError)
+ lambda { Puppet::Indirector::Request.new(:ind, :method, :key, :one => :two) }.should_not raise_error(ArgumentError)
end
it "should support nil options" do
- lambda { Puppet::Indirector::Request.new(:ind, :key, :method, nil) }.should_not raise_error(ArgumentError)
+ lambda { Puppet::Indirector::Request.new(:ind, :method, :key, nil) }.should_not raise_error(ArgumentError)
end
it "should support unspecified options" do
- lambda { Puppet::Indirector::Request.new(:ind, :key, :method) }.should_not raise_error(ArgumentError)
+ lambda { Puppet::Indirector::Request.new(:ind, :method, :key) }.should_not raise_error(ArgumentError)
end
it "should fail if options are specified as anything other than nil or a hash" do
- lambda { Puppet::Indirector::Request.new(:ind, :key, :method, [:one, :two]) }.should raise_error(ArgumentError)
+ lambda { Puppet::Indirector::Request.new(:ind, :method, :key, [:one, :two]) }.should raise_error(ArgumentError)
end
it "should use an empty options hash if nil was provided" do
- Puppet::Indirector::Request.new(:ind, :key, :method, nil).options.should == {}
+ Puppet::Indirector::Request.new(:ind, :method, :key, nil).options.should == {}
end
end
it "should look use the Indirection class to return the appropriate indirection" do
ind = mock 'indirection'
Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns ind
- request = Puppet::Indirector::Request.new(:myind, :key, :method)
+ request = Puppet::Indirector::Request.new(:myind, :method, :key)
request.indirection.should equal(ind)
end
diff --git a/spec/unit/indirector/yaml.rb b/spec/unit/indirector/yaml.rb
index 339529ab0..53d12f426 100755
--- a/spec/unit/indirector/yaml.rb
+++ b/spec/unit/indirector/yaml.rb
@@ -21,37 +21,28 @@ describe Puppet::Indirector::Yaml, " when choosing file location" do
@dir = "/what/ever"
Puppet.settings.stubs(:value).with(:yamldir).returns(@dir)
- end
-
- it "should use the mtime of the written file as the version" do
- stat = mock 'stat'
- FileTest.stubs(:exist?).returns true
- File.expects(:stat).returns stat
- time = Time.now
- stat.expects(:mtime).returns time
- @store.version(:me).should equal(time)
+ @request = stub 'request', :key => :me, :instance => @subject
end
describe Puppet::Indirector::Yaml, " when choosing file location" do
-
it "should store all files in a single file root set in the Puppet defaults" do
- @store.send(:path, :me).should =~ %r{^#{@dir}}
+ @store.path(:me).should =~ %r{^#{@dir}}
end
it "should use the terminus name for choosing the subdirectory" do
- @store.send(:path, :me).should =~ %r{^#{@dir}/my_yaml}
+ @store.path(:me).should =~ %r{^#{@dir}/my_yaml}
end
it "should use the object's name to determine the file name" do
- @store.send(:path, :me).should =~ %r{me.yaml$}
+ @store.path(:me).should =~ %r{me.yaml$}
end
end
describe Puppet::Indirector::Yaml, " when storing objects as YAML" do
-
it "should only store objects that respond to :name" do
- proc { @store.save(Object.new) }.should raise_error(ArgumentError)
+ @request.stubs(:instance).returns Object.new
+ proc { @store.save(@request) }.should raise_error(ArgumentError)
end
it "should convert Ruby objects to YAML and write them to disk" do
@@ -62,7 +53,7 @@ describe Puppet::Indirector::Yaml, " when choosing file location" do
File.expects(:open).with(path, "w", 0660).yields(file)
file.expects(:print).with(yaml)
- @store.save(@subject)
+ @store.save(@request)
end
it "should create the indirection subdirectory if it does not exist" do
@@ -75,16 +66,11 @@ describe Puppet::Indirector::Yaml, " when choosing file location" do
File.expects(:open).with(path, "w", 0660).yields(file)
file.expects(:print).with(yaml)
- @store.save(@subject)
+ @store.save(@request)
end
end
describe Puppet::Indirector::Yaml, " when retrieving YAML" do
-
- it "should require the name of the object to retrieve" do
- proc { @store.find(nil) }.should raise_error(ArgumentError)
- end
-
it "should read YAML in from disk and convert it to Ruby objects" do
path = @store.send(:path, @subject.name)
@@ -92,7 +78,7 @@ describe Puppet::Indirector::Yaml, " when choosing file location" do
FileTest.expects(:exist?).with(path).returns(true)
File.expects(:read).with(path).returns(yaml)
- @store.find(@subject.name).instance_variable_get("@name").should == :me
+ @store.find(@request).instance_variable_get("@name").should == :me
end
it "should fail coherently when the stored YAML is invalid" do
@@ -104,7 +90,7 @@ describe Puppet::Indirector::Yaml, " when choosing file location" do
FileTest.expects(:exist?).with(path).returns(true)
File.expects(:read).with(path).returns(yaml)
- proc { @store.find(@subject.name) }.should raise_error(Puppet::Error)
+ proc { @store.find(@request) }.should raise_error(Puppet::Error)
end
end
end
diff --git a/spec/unit/node.rb b/spec/unit/node.rb
index e62bd5d07..421fcd635 100755
--- a/spec/unit/node.rb
+++ b/spec/unit/node.rb
@@ -117,9 +117,9 @@ end
describe Puppet::Node, " when indirecting" do
it "should redirect to the indirection" do
- @indirection = mock 'indirection'
+ @indirection = stub 'indirection', :name => :node
Puppet::Node.stubs(:indirection).returns(@indirection)
- @indirection.expects(:find).with(:my_node.to_s)
+ @indirection.expects(:find)
Puppet::Node.find(:my_node.to_s)
end
diff --git a/spec/unit/node/catalog.rb b/spec/unit/node/catalog.rb
index 360dd87f2..cd27b925b 100755
--- a/spec/unit/node/catalog.rb
+++ b/spec/unit/node/catalog.rb
@@ -777,14 +777,14 @@ end
describe Puppet::Node::Catalog, " when indirecting" do
before do
- @indirection = mock 'indirection'
+ @indirection = stub 'indirection', :name => :catalog
Puppet::Indirector::Indirection.clear_cache
end
it "should redirect to the indirection for retrieval" do
Puppet::Node::Catalog.stubs(:indirection).returns(@indirection)
- @indirection.expects(:find).with(:myconfig)
+ @indirection.expects(:find)
Puppet::Node::Catalog.find(:myconfig)
end
diff --git a/spec/unit/node/facts.rb b/spec/unit/node/facts.rb
index 743a7082e..1bfccd32e 100755
--- a/spec/unit/node/facts.rb
+++ b/spec/unit/node/facts.rb
@@ -6,7 +6,7 @@ require 'puppet/node/facts'
describe Puppet::Node::Facts, " when indirecting" do
before do
- @indirection = mock 'indirection'
+ @indirection = stub 'indirection', :request => mock('request'), :name => :facts
# We have to clear the cache so that the facts ask for our indirection stub,
# instead of anything that might be cached.
@@ -16,13 +16,13 @@ describe Puppet::Node::Facts, " when indirecting" do
it "should redirect to the specified fact store for retrieval" do
Puppet::Node::Facts.stubs(:indirection).returns(@indirection)
- @indirection.expects(:find).with(:my_facts)
+ @indirection.expects(:find)
Puppet::Node::Facts.find(:my_facts)
end
it "should redirect to the specified fact store for storage" do
Puppet::Node::Facts.stubs(:indirection).returns(@indirection)
- @indirection.expects(:save).with(@facts)
+ @indirection.expects(:save)
@facts.save
end
diff --git a/spec/unit/transaction/report.rb b/spec/unit/transaction/report.rb
index 8fc3f0794..644f8d709 100755
--- a/spec/unit/transaction/report.rb
+++ b/spec/unit/transaction/report.rb
@@ -9,18 +9,18 @@ require 'puppet/transaction/report'
describe Puppet::Transaction::Report, " when being indirect" do
it "should redirect :find to the indirection" do
- @indirection = mock 'indirection'
+ @indirection = stub 'indirection', :name => :report
Puppet::Transaction::Report.stubs(:indirection).returns(@indirection)
- @indirection.expects(:find).with(:report)
+ @indirection.expects(:find)
Puppet::Transaction::Report.find(:report)
end
it "should redirect :save to the indirection" do
Facter.stubs(:value).returns("eh")
- @indirection = mock 'indirection'
+ @indirection = stub 'indirection', :name => :report
Puppet::Transaction::Report.stubs(:indirection).returns(@indirection)
report = Puppet::Transaction::Report.new
- @indirection.expects(:save).with(report)
+ @indirection.expects(:save)
report.save
end
@@ -28,6 +28,12 @@ describe Puppet::Transaction::Report, " when being indirect" do
Puppet::Transaction::Report.indirection.terminus_class.should == :processor
end
+ it "should delegate its name attribute to its host method" do
+ report = Puppet::Transaction::Report.new
+ report.expects(:host).returns "me"
+ report.name.should == "me"
+ end
+
after do
Puppet::Indirector::Indirection.clear_cache
end