summaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rwxr-xr-xspec/integration/checksum.rb2
-rwxr-xr-xspec/integration/indirector/direct_file_server.rb10
-rwxr-xr-xspec/integration/node.rb104
-rwxr-xr-xspec/integration/node/catalog.rb38
-rwxr-xr-xspec/integration/node/facts.rb45
-rwxr-xr-xspec/integration/transaction/report.rb26
-rw-r--r--spec/shared_behaviours/file_serving.rb12
-rw-r--r--spec/shared_behaviours/memory_terminus.rb32
-rwxr-xr-xspec/unit/file_serving/configuration.rb2
-rwxr-xr-xspec/unit/file_serving/configuration/parser.rb2
-rwxr-xr-xspec/unit/file_serving/indirection_hooks.rb204
-rwxr-xr-xspec/unit/indirector.rb85
-rwxr-xr-xspec/unit/indirector/catalog/compiler.rb87
-rwxr-xr-xspec/unit/indirector/checksum/file.rb21
-rwxr-xr-xspec/unit/indirector/direct_file_server.rb26
-rwxr-xr-xspec/unit/indirector/envelope.rb47
-rwxr-xr-xspec/unit/indirector/exec.rb18
-rwxr-xr-xspec/unit/indirector/facts/facter.rb10
-rwxr-xr-xspec/unit/indirector/file.rb64
-rwxr-xr-xspec/unit/indirector/file_metadata/file.rb50
-rwxr-xr-xspec/unit/indirector/file_server.rb2
-rwxr-xr-xspec/unit/indirector/indirection.rb1005
-rwxr-xr-xspec/unit/indirector/ldap.rb18
-rwxr-xr-xspec/unit/indirector/memory.rb30
-rwxr-xr-xspec/unit/indirector/node/exec.rb20
-rwxr-xr-xspec/unit/indirector/node/ldap.rb43
-rwxr-xr-xspec/unit/indirector/node/memory.rb5
-rwxr-xr-xspec/unit/indirector/node/plain.rb9
-rwxr-xr-xspec/unit/indirector/plain.rb6
-rwxr-xr-xspec/unit/indirector/report/processor.rb16
-rwxr-xr-xspec/unit/indirector/request.rb55
-rwxr-xr-xspec/unit/indirector/terminus.rb54
-rwxr-xr-xspec/unit/indirector/yaml.rb34
-rwxr-xr-xspec/unit/module.rb (renamed from spec/unit/other/modules.rb)11
-rwxr-xr-xspec/unit/network/client/master.rb25
-rwxr-xr-xspec/unit/node.rb4
-rwxr-xr-xspec/unit/node/catalog.rb4
-rwxr-xr-xspec/unit/node/facts.rb6
-rwxr-xr-xspec/unit/parser/ast/node.rb2
-rwxr-xr-xspec/unit/parser/resource.rb7
-rwxr-xr-xspec/unit/ral/type/nagios.rb70
-rwxr-xr-xspec/unit/transaction/report.rb14
-rwxr-xr-xspec/unit/util/loadedfile.rb65
43 files changed, 1409 insertions, 981 deletions
diff --git a/spec/integration/checksum.rb b/spec/integration/checksum.rb
index cb187c656..c94f3e47e 100755
--- a/spec/integration/checksum.rb
+++ b/spec/integration/checksum.rb
@@ -38,7 +38,7 @@ describe Puppet::Checksum, " when using the file terminus" do
File.stubs(:exist?).returns(true)
File.expects(:unlink).with(@file)
- Puppet::Checksum.destroy(@sum)
+ Puppet::Checksum.destroy(@sum.name)
end
after do
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.rb b/spec/integration/node.rb
index 631d4403e..b0375e743 100755
--- a/spec/integration/node.rb
+++ b/spec/integration/node.rb
@@ -7,38 +7,86 @@ require File.dirname(__FILE__) + '/../spec_helper'
require 'puppet/node'
-describe Puppet::Node, " when using the memory terminus" do
- before do
- @name = "me"
- @old_terminus = Puppet::Node.indirection.terminus_class
- @terminus = Puppet::Node.indirection.terminus(:memory)
- Puppet::Node.indirection.stubs(:terminus).returns @terminus
- @node = Puppet::Node.new(@name)
- end
+describe Puppet::Node do
+ describe "when delegating indirection calls" do
+ before do
+ @name = "me"
+ @node = Puppet::Node.new(@name)
+ end
- it "should find no nodes by default" do
- Puppet::Node.find(@name).should be_nil
- end
+ it "should be able to use the exec terminus" do
+ Puppet::Node.indirection.stubs(:terminus_class).returns :exec
- it "should be able to find nodes that were previously saved" do
- @node.save
- Puppet::Node.find(@name).should equal(@node)
- end
+ # Load now so we can stub
+ terminus = Puppet::Node.indirection.terminus(:exec)
- it "should replace existing saved nodes when a new node with the same name is saved" do
- @node.save
- two = Puppet::Node.new(@name)
- two.save
- Puppet::Node.find(@name).should equal(two)
- end
+ terminus.expects(:query).with(@name).returns "myresults"
+ terminus.expects(:translate).with(@name, "myresults").returns "translated_results"
+ terminus.expects(:create_node).with(@name, "translated_results").returns @node
- it "should be able to remove previously saved nodes" do
- @node.save
- Puppet::Node.destroy(@node)
- Puppet::Node.find(@name).should be_nil
- end
+ Puppet::Node.find(@name).should equal(@node)
+ end
+
+ it "should be able to use the yaml terminus" do
+ Puppet::Node.indirection.stubs(:terminus_class).returns :yaml
+
+ # Load now, before we stub the exists? method.
+ Puppet::Node.indirection.terminus(:yaml)
+
+ file = File.join(Puppet[:yamldir], "node", "me.yaml")
+ FileTest.expects(:exist?).with(file).returns false
+ Puppet::Node.find(@name).should be_nil
+ end
+
+ it "should have an ldap terminus" do
+ Puppet::Node.indirection.terminus(:ldap).should_not be_nil
+ end
+
+ it "should be able to use the plain terminus" do
+ Puppet::Node.indirection.stubs(:terminus_class).returns :plain
+
+ # Load now, before we stub the exists? method.
+ Puppet::Node.indirection.terminus(:plain)
+
+ Puppet::Node.expects(:new).with(@name).returns @node
+
+ Puppet::Node.find(@name).should equal(@node)
+ end
+
+ describe "and using the memory terminus" do
+ before do
+ @name = "me"
+ @old_terminus = Puppet::Node.indirection.terminus_class
+ @terminus = Puppet::Node.indirection.terminus(:memory)
+ Puppet::Node.indirection.stubs(:terminus).returns @terminus
+ @node = Puppet::Node.new(@name)
+ end
+
+ it "should find no nodes by default" do
+ Puppet::Node.find(@name).should be_nil
+ end
+
+ it "should be able to find nodes that were previously saved" do
+ @node.save
+ Puppet::Node.find(@name).should equal(@node)
+ end
+
+ it "should replace existing saved nodes when a new node with the same name is saved" do
+ @node.save
+ two = Puppet::Node.new(@name)
+ two.save
+ Puppet::Node.find(@name).should equal(two)
+ end
+
+ it "should be able to remove previously saved nodes" do
+ @node.save
+ Puppet::Node.destroy(@node.name)
+ Puppet::Node.find(@name).should be_nil
+ end
- it "should fail when asked to destroy a node that does not exist" do
- proc { Puppet::Node.destroy(@node) }.should raise_error(ArgumentError)
+ it "should fail when asked to destroy a node that does not exist" do
+ proc { Puppet::Node.destroy(@node) }.should raise_error(ArgumentError)
+ end
+ end
end
end
diff --git a/spec/integration/node/catalog.rb b/spec/integration/node/catalog.rb
new file mode 100755
index 000000000..ca14c2ea8
--- /dev/null
+++ b/spec/integration/node/catalog.rb
@@ -0,0 +1,38 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-4-8.
+# Copyright (c) 2008. 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)
+
+ node = mock 'node'
+ node.stub_everything
+
+ Puppet::Node.expects(:find).returns(node)
+ compiler.expects(:compile).with(node).returns nil
+
+ Puppet::Node::Catalog.find("me").should be_nil
+ end
+ end
+end
diff --git a/spec/integration/node/facts.rb b/spec/integration/node/facts.rb
new file mode 100755
index 000000000..c2f876578
--- /dev/null
+++ b/spec/integration/node/facts.rb
@@ -0,0 +1,45 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-4-8.
+# Copyright (c) 2008. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe Puppet::Node::Facts do
+ describe "when using the indirector" do
+ after { Puppet::Node::Facts.indirection.clear_cache }
+
+ it "should expire any cached node instances when it is saved" do
+ Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml
+ terminus = Puppet::Node::Facts.indirection.terminus(:yaml)
+
+ terminus.expects(:save)
+ Puppet::Node.expects(:expire).with("me")
+
+ facts = Puppet::Node::Facts.new("me")
+ facts.save
+ end
+
+ it "should be able to delegate to the :yaml terminus" do
+ Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml
+
+ # Load now, before we stub the exists? method.
+ Puppet::Node::Facts.indirection.terminus(:yaml)
+
+ file = File.join(Puppet[:yamldir], "facts", "me.yaml")
+ FileTest.expects(:exist?).with(file).returns false
+
+ Puppet::Node::Facts.find("me").should be_nil
+ end
+
+ it "should be able to delegate to the :facter terminus" do
+ Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :facter
+
+ Facter.expects(:to_hash).returns "facter_hash"
+ facts = Puppet::Node::Facts.new("me")
+ Puppet::Node::Facts.expects(:new).with("me", "facter_hash").returns facts
+
+ Puppet::Node::Facts.find("me").should equal(facts)
+ end
+ end
+end
diff --git a/spec/integration/transaction/report.rb b/spec/integration/transaction/report.rb
new file mode 100755
index 000000000..48e59f203
--- /dev/null
+++ b/spec/integration/transaction/report.rb
@@ -0,0 +1,26 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-4-8.
+# Copyright (c) 2008. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe Puppet::Transaction::Report do
+ describe "when using the indirector" do
+ after { Puppet::Transaction::Report.indirection.clear_cache }
+
+ it "should be able to delegate to the :processor terminus" do
+ Puppet::Transaction::Report.indirection.stubs(:terminus_class).returns :processor
+
+ terminus = Puppet::Transaction::Report.indirection.terminus(:processor)
+
+ Facter.stubs(:value).returns "host.domain.com"
+
+ report = Puppet::Transaction::Report.new
+
+ terminus.expects(:process).with(report)
+
+ report.save
+ 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/file_serving/configuration.rb b/spec/unit/file_serving/configuration.rb
index eecaefe5f..a0710e20d 100755
--- a/spec/unit/file_serving/configuration.rb
+++ b/spec/unit/file_serving/configuration.rb
@@ -221,4 +221,4 @@ describe Puppet::FileServing::Configuration do
@config.authorized?("/one/my/file").should be_false
end
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/file_serving/configuration/parser.rb b/spec/unit/file_serving/configuration/parser.rb
index df2f629d5..93d30ca1c 100755
--- a/spec/unit/file_serving/configuration/parser.rb
+++ b/spec/unit/file_serving/configuration/parser.rb
@@ -132,4 +132,4 @@ describe Puppet::FileServing::Configuration::Parser do
@parser.parse
end
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/file_serving/indirection_hooks.rb b/spec/unit/file_serving/indirection_hooks.rb
index 34614b7b8..160e3ff0a 100755
--- a/spec/unit/file_serving/indirection_hooks.rb
+++ b/spec/unit/file_serving/indirection_hooks.rb
@@ -7,104 +7,118 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/indirection_hooks'
-describe Puppet::FileServing::IndirectionHooks, " when being used to select termini" do
+describe Puppet::FileServing::IndirectionHooks do
before do
@object = Object.new
@object.extend(Puppet::FileServing::IndirectionHooks)
- end
-
- it "should escape the key before parsing" do
- uri = stub 'uri', :scheme => "puppet", :host => "blah", :path => "/something"
- URI.expects(:escape).with("mykey").returns("http://myhost/blah")
- URI.expects(:parse).with("http://myhost/blah").returns(uri)
- @object.select_terminus("mykey")
- end
-
- it "should use the URI class to parse the key" do
- uri = stub 'uri', :scheme => "puppet", :host => "blah", :path => "/something"
- URI.expects(:parse).with("http://myhost/blah").returns(uri)
- @object.select_terminus("http://myhost/blah")
- end
-
- it "should choose :rest when the protocol is 'puppet'" do
- @object.select_terminus("puppet://host/module/file").should == :rest
- end
-
- it "should choose :file_server when the protocol is 'puppetmounts' and the mount name is not 'modules'" do
- modules = mock 'modules'
- @object.stubs(:terminus).with(:modules).returns(modules)
- modules.stubs(:find_module).returns(nil)
-
- @object.select_terminus("puppetmounts://host/notmodules/file").should == :file_server
- end
-
- it "should choose :file_server when no server name is provided, the process name is 'puppet', and the mount name is not 'modules'" do
- modules = mock 'modules'
- @object.stubs(:terminus).with(:modules).returns(modules)
- modules.stubs(:find_module).returns(nil)
-
- Puppet.settings.expects(:value).with(:name).returns("puppet")
- @object.select_terminus("puppet:///notmodules/file").should == :file_server
- end
-
- it "should choose :modules if it would normally choose :file_server but the mount name is 'modules'" do
- @object.select_terminus("puppetmounts://host/modules/mymod/file").should == :modules
- end
-
- it "should choose :modules it would normally choose :file_server but a module exists with the mount name" do
- modules = mock 'modules'
-
- @object.expects(:terminus).with(:modules).returns(modules)
- modules.expects(:find_module).with("mymod", nil).returns(:thing)
-
- @object.select_terminus("puppetmounts://host/mymod/file").should == :modules
- end
-
- it "should choose :rest when no server name is provided and the process name is not 'puppet'" do
- Puppet.settings.expects(:value).with(:name).returns("puppetd")
- @object.select_terminus("puppet:///module/file").should == :rest
- end
-
- it "should choose :file when the protocol is 'file'" do
- @object.select_terminus("file://host/module/file").should == :file
- end
-
- it "should choose :file when the URI is a normal path name" do
- @object.select_terminus("/module/file").should == :file
- end
-
- # This is so that we only choose modules over mounts, not file
- it "should choose :file when the protocol is 'file' and the fully qualified path starts with '/modules'" do
- @object.select_terminus("file://host/modules/file").should == :file
- end
-
- it "should fail when a protocol other than :puppet, :file, or :puppetmounts is used" do
- proc { @object.select_terminus("http:///module/file") }.should raise_error(ArgumentError)
- end
-end
-
-describe Puppet::FileServing::IndirectionHooks, " when looking for a module whose name matches the mount name" do
- before do
- @object = Object.new
- @object.extend(Puppet::FileServing::IndirectionHooks)
-
- @modules = mock 'modules'
- @object.stubs(:terminus).with(:modules).returns(@modules)
- end
-
- it "should use the modules terminus to look up the module" do
- @modules.expects(:find_module).with("mymod", nil)
- @object.select_terminus("puppetmounts://host/mymod/my/file")
- end
-
- it "should pass the node name to the modules terminus" do
- @modules.expects(:find_module).with("mymod", nil)
- @object.select_terminus("puppetmounts://host/mymod/my/file")
- end
- it "should log a deprecation warning if a module is found" do
- @modules.expects(:find_module).with("mymod", nil).returns(:something)
- Puppet.expects(:warning)
- @object.select_terminus("puppetmounts://host/mymod/my/file")
+ @request = stub 'request', :key => "http://myhost/blah", :options => {:node => "whatever"}
+ end
+
+ describe "when being used to select termini" do
+ it "should escape the key before parsing" do
+ uri = stub 'uri', :scheme => "puppet", :host => "blah", :path => "/something"
+ URI.expects(:escape).with("http://myhost/blah").returns("escaped_blah")
+ URI.expects(:parse).with("escaped_blah").returns(uri)
+ @object.select_terminus(@request)
+ end
+
+ it "should use the URI class to parse the key" do
+ uri = stub 'uri', :scheme => "puppet", :host => "blah", :path => "/something"
+ URI.expects(:parse).with("http://myhost/blah").returns(uri)
+ @object.select_terminus @request
+ end
+
+ it "should choose :rest when the protocol is 'puppet'" do
+ @request.stubs(:key).returns "puppet://host/module/file"
+ @object.select_terminus(@request).should == :rest
+ end
+
+ it "should choose :file_server when the protocol is 'puppetmounts' and the mount name is not 'modules'" do
+ modules = mock 'modules'
+ @object.stubs(:terminus).with(:modules).returns(modules)
+ modules.stubs(:find_module).returns(nil)
+
+ @request.stubs(:key).returns "puppetmounts://host/notmodules/file"
+
+ @object.select_terminus(@request).should == :file_server
+ end
+
+ it "should choose :file_server when no server name is provided, the process name is 'puppet', and the mount name is not 'modules'" do
+ modules = mock 'modules'
+ @object.stubs(:terminus).with(:modules).returns(modules)
+ modules.stubs(:find_module).returns(nil)
+
+ Puppet.settings.expects(:value).with(:name).returns("puppet")
+ @request.stubs(:key).returns "puppet:///notmodules/file"
+ @object.select_terminus(@request).should == :file_server
+ end
+
+ it "should choose :modules if it would normally choose :file_server but the mount name is 'modules'" do
+ @request.stubs(:key).returns "puppetmounts://host/modules/mymod/file"
+ @object.select_terminus(@request).should == :modules
+ end
+
+ it "should choose :modules if it would normally choose :file_server but a module exists with the mount name" do
+ modules = mock 'modules'
+
+ @object.expects(:terminus).with(:modules).returns(modules)
+ modules.expects(:find_module).with("mymod", @request.options[:node]).returns(:thing)
+
+ @request.stubs(:key).returns "puppetmounts://host/mymod/file"
+ @object.select_terminus(@request).should == :modules
+ end
+
+ it "should choose :rest when no server name is provided and the process name is not 'puppet'" do
+ Puppet.settings.expects(:value).with(:name).returns("puppetd")
+ @request.stubs(:key).returns "puppet:///module/file"
+ @object.select_terminus(@request).should == :rest
+ end
+
+ it "should choose :file when the protocol is 'file'" do
+ @request.stubs(:key).returns "file://host/module/file"
+ @object.select_terminus(@request).should == :file
+ end
+
+ it "should choose :file when the URI is a normal path name" do
+ @request.stubs(:key).returns "/module/file"
+ @object.select_terminus(@request).should == :file
+ end
+
+ # This is so that we only choose modules over mounts, not file
+ it "should choose :file when the protocol is 'file' and the fully qualified path starts with '/modules'" do
+ @request.stubs(:key).returns "/module/file"
+ @object.select_terminus(@request).should == :file
+ end
+
+ it "should fail when a protocol other than :puppet, :file, or :puppetmounts is used" do
+ @request.stubs(:key).returns "http:///module/file"
+ proc { @object.select_terminus(@request) }.should raise_error(ArgumentError)
+ end
+ end
+
+ describe "when looking for a module whose name matches the mount name" do
+ before do
+ @modules = mock 'modules'
+ @object.stubs(:terminus).with(:modules).returns(@modules)
+
+ @request.stubs(:key).returns "puppetmounts://host/mymod/file"
+ end
+
+ it "should use the modules terminus to look up the module" do
+ @modules.expects(:find_module).with("mymod", @request.options[:node])
+ @object.select_terminus @request
+ end
+
+ it "should pass the node name to the modules terminus" do
+ @modules.expects(:find_module).with("mymod", @request.options[:node])
+ @object.select_terminus @request
+ end
+
+ it "should log a deprecation warning if a module is found" do
+ @modules.expects(:find_module).with("mymod", @request.options[:node]).returns(:something)
+ Puppet.expects(:warning)
+ @object.select_terminus @request
+ end
end
end
diff --git a/spec/unit/indirector.rb b/spec/unit/indirector.rb
index 1a5867c51..1efa7b2e5 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,81 @@ 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 delegate to the indirection" do
+ @indirection.expects(@method)
+ @thingie.send(@method, "me")
+ end
+
+ it "should pass all of the passed arguments directly to the indirection instance" do
+ @indirection.expects(@method).with("me", :one => :two)
+ @thingie.send(@method, "me", :one => :two)
+ 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
+ describe "when expiring instances via the model" do
+ before { @method = :expire }
+ it_should_behave_like "Delegated Indirection Method"
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
+ # 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 delegate to the indirection" do
+ @indirection.expects(:save)
+ @instance.save
+ 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 pass the instance and all arguments to the indirection's :save method" do
+ @indirection.expects(:save).with(@instance, :one => :two)
+ @instance.save :one => :two
+ 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..083a9ced5 100755
--- a/spec/unit/indirector/catalog/compiler.rb
+++ b/spec/unit/indirector/catalog/compiler.rb
@@ -26,8 +26,8 @@ describe Puppet::Node::Catalog::Compiler do
Puppet::Node.stubs(:find_by_any_name).with('node1').returns(node1)
Puppet::Node.stubs(:find_by_any_name).with('node2').returns(node2)
- compiler.find('node1')
- compiler.find('node2')
+ compiler.find(stub('request', :key => 'node1', :options => {}))
+ compiler.find(stub('node2request', :key => 'node2', :options => {}))
end
it "should provide a method for determining if the catalog is networked" do
@@ -63,19 +63,14 @@ describe Puppet::Node::Catalog::Compiler, " when finding nodes" do
@compiler = Puppet::Node::Catalog::Compiler.new
@name = "me"
@node = mock 'node'
+ @request = stub 'request', :key => @name, :options => {}
@compiler.stubs(:compile)
end
it "should look node information up via the Node class with the provided key" do
@node.stubs :merge
Puppet::Node.expects(:find_by_any_name).with(@name).returns(@node)
- @compiler.find(@name)
- end
-
- 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)
+ @compiler.find(@request)
end
end
@@ -88,23 +83,24 @@ describe Puppet::Node::Catalog::Compiler, " after finding nodes" do
@compiler = Puppet::Node::Catalog::Compiler.new
@name = "me"
@node = mock 'node'
+ @request = stub 'request', :key => @name, :options => {}
@compiler.stubs(:compile)
Puppet::Node.stubs(:find_by_any_name).with(@name).returns(@node)
end
it "should add the server's Puppet version to the node's parameters as 'serverversion'" do
@node.expects(:merge).with { |args| args["serverversion"] == "1" }
- @compiler.find(@name)
+ @compiler.find(@request)
end
it "should add the server's fqdn to the node's parameters as 'servername'" do
@node.expects(:merge).with { |args| args["servername"] == "my.server.com" }
- @compiler.find(@name)
+ @compiler.find(@request)
end
it "should add the server's IP address to the node's parameters as 'serverip'" do
@node.expects(:merge).with { |args| args["serverip"] == "my.ip.address" }
- @compiler.find(@name)
+ @compiler.find(@request)
end
# LAK:TODO This is going to be difficult, because this whole process is so
@@ -125,27 +121,34 @@ describe Puppet::Node::Catalog::Compiler, " when creating catalogs" do
@name = "me"
@node = Puppet::Node.new @name
@node.stubs(:merge)
+ @request = stub 'request', :key => @name, :options => {}
Puppet::Node.stubs(:find_by_any_name).with(@name).returns(@node)
end
it "should directly use provided nodes" do
Puppet::Node.expects(:find_by_any_name).never
@compiler.interpreter.expects(:compile).with(@node)
- @compiler.find(@node)
+ @request.stubs(:options).returns(:node => @node)
+ @compiler.find(@request)
+ end
+
+ it "should fail if no node is passed and none can be found" do
+ Puppet::Node.stubs(:find_by_any_name).with(@name).returns(nil)
+ proc { @compiler.find(@request) }.should raise_error(ArgumentError)
end
it "should pass the found node to the interpreter for compiling" do
config = mock 'config'
@compiler.interpreter.expects(:compile).with(@node)
- @compiler.find(@name)
+ @compiler.find(@request)
end
it "should return the results of compiling as the catalog" do
config = mock 'config'
- result = mock 'result', :to_transportable => :catalog
+ result = mock 'result'
@compiler.interpreter.expects(:compile).with(@node).returns(result)
- @compiler.find(@name).should == :catalog
+ @compiler.find(@request).should equal(result)
end
it "should benchmark the compile process" do
@@ -154,56 +157,6 @@ describe Puppet::Node::Catalog::Compiler, " when creating catalogs" do
level == :notice and message =~ /^Compiled catalog/
end
@compiler.interpreter.stubs(:compile).with(@node)
- @compiler.find(@name)
- end
-end
-
-describe Puppet::Node::Catalog::Compiler, " when determining a client's available catalog version" do
- before do
- Puppet::Node::Facts.stubs(:find).returns(nil)
- Facter.stubs(:value).returns("whatever")
- @catalog = Puppet::Node::Catalog::Compiler.new
- @name = "johnny"
- end
-
- it "should provide a mechanism for providing the version of a given client's catalog" do
- @catalog.should respond_to(:version)
- end
-
- it "should use the client's Facts version as the available catalog version if it is the most recent" do
- Puppet::Node::Facts.stubs(:version).with(@name).returns(5)
- Puppet::Node.expects(:version).with(@name).returns(3)
- @catalog.interpreter.stubs(:catalog_version).returns(4)
-
- @catalog.version(@name).should == 5
- end
-
- it "should use the client's Node version as the available catalog version if it is the most recent" do
- Puppet::Node::Facts.stubs(:version).with(@name).returns(3)
- Puppet::Node.expects(:version).with(@name).returns(5)
- @catalog.interpreter.stubs(:catalog_version).returns(4)
-
- @catalog.version(@name).should == 5
- end
-
- it "should use the last parse date as the available catalog version if it is the most recent" do
- Puppet::Node::Facts.stubs(:version).with(@name).returns(3)
- Puppet::Node.expects(:version).with(@name).returns(4)
- @catalog.interpreter.stubs(:catalog_version).returns(5)
-
- @catalog.version(@name).should == 5
- end
-
- it "should return a version of 0 if no information on the node can be found" do
- Puppet::Node.stubs(:find_by_any_name).returns(nil)
- @catalog.version(@name).should == 0
- end
-
- it "should indicate when an update is available even if an input has clock skew" do
- pending "Unclear how to implement this"
- end
-
- it "should not indicate an available update when apparent updates are a result of clock skew" do
- pending "Unclear how to implement this"
+ @compiler.find(@request)
end
end
diff --git a/spec/unit/indirector/checksum/file.rb b/spec/unit/indirector/checksum/file.rb
index 4f8ee98b2..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,19 +124,16 @@ 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
describe Puppet::Checksum::File, " when deleting files" do
-
it "should remove the file at the calculated path" do
File.expects(:exist?).with(@path).returns(true)
File.expects(:unlink).with(@path)
- file = stub 'file', :name => @value
- @store.destroy(file)
+ @store.destroy(@request)
end
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/indirector/direct_file_server.rb b/spec/unit/indirector/direct_file_server.rb
index 9f3652536..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 \ No newline at end of file
+end
diff --git a/spec/unit/indirector/envelope.rb b/spec/unit/indirector/envelope.rb
new file mode 100755
index 000000000..17c62023a
--- /dev/null
+++ b/spec/unit/indirector/envelope.rb
@@ -0,0 +1,47 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/indirector/envelope'
+
+describe Puppet::Indirector::Envelope do
+ before do
+ @instance = Object.new
+ @instance.extend(Puppet::Indirector::Envelope)
+ end
+
+ it "should have an expiration accessor" do
+ @instance.expiration = "testing"
+ @instance.expiration.should == "testing"
+ end
+
+ it "should have an expiration setter" do
+ @instance.should respond_to(:expiration=)
+ end
+
+ it "should have a means of testing whether it is expired" do
+ @instance.should respond_to(:expired?)
+ end
+
+ describe "when testing if it is expired" do
+ it "should return false if there is no expiration set" do
+ @instance.should_not be_expired
+ end
+
+ it "should return true if the current date is after the expiration date" do
+ @instance.expiration = Time.now - 10
+ @instance.should be_expired
+ end
+
+ it "should return false if the current date is prior to the expiration date" do
+ @instance.expiration = Time.now + 10
+ @instance.should_not be_expired
+ end
+
+ it "should return false if the current date is equal to the expiration date" do
+ now = Time.now
+ Time.stubs(:now).returns(now)
+ @instance.expiration = now
+ @instance.should_not be_expired
+ end
+ end
+end
diff --git a/spec/unit/indirector/exec.rb b/spec/unit/indirector/exec.rb
index 3baf06629..e474de8b9 100755
--- a/spec/unit/indirector/exec.rb
+++ b/spec/unit/indirector/exec.rb
@@ -18,31 +18,33 @@ describe Puppet::Indirector::Exec do
@searcher = @exec_class.new
@searcher.command = ["/echo"]
+
+ @request = stub 'request', :key => "foo"
end
it "should throw an exception if the command is not an array" do
@searcher.command = "/usr/bin/echo"
- proc { @searcher.find("foo") }.should raise_error(Puppet::DevError)
+ proc { @searcher.find(@request) }.should raise_error(Puppet::DevError)
end
it "should throw an exception if the command is not fully qualified" do
@searcher.command = ["mycommand"]
- proc { @searcher.find("foo") }.should raise_error(ArgumentError)
+ proc { @searcher.find(@request) }.should raise_error(ArgumentError)
end
it "should execute the command with the object name as the only argument" do
- @searcher.expects(:execute).with(%w{/echo yay})
- @searcher.find("yay")
+ @searcher.expects(:execute).with(%w{/echo foo})
+ @searcher.find(@request)
end
it "should return the output of the script" do
- @searcher.expects(:execute).with(%w{/echo yay}).returns("whatever")
- @searcher.find("yay").should == "whatever"
+ @searcher.expects(:execute).with(%w{/echo foo}).returns("whatever")
+ @searcher.find(@request).should == "whatever"
end
it "should return nil when the command produces no output" do
- @searcher.expects(:execute).with(%w{/echo yay}).returns(nil)
- @searcher.find("yay").should be_nil
+ @searcher.expects(:execute).with(%w{/echo foo}).returns(nil)
+ @searcher.find(@request).should be_nil
end
it "should be able to execute commands with multiple arguments"
diff --git a/spec/unit/indirector/facts/facter.rb b/spec/unit/indirector/facts/facter.rb
index 0974a60ec..225eb153b 100755
--- a/spec/unit/indirector/facts/facter.rb
+++ b/spec/unit/indirector/facts/facter.rb
@@ -36,22 +36,22 @@ describe Puppet::Node::Facts::Facter do
@facter = Puppet::Node::Facts::Facter.new
Facter.stubs(:to_hash).returns({})
@name = "me"
- @facts = @facter.find(@name)
+ @request = stub 'request', :key => @name
end
describe Puppet::Node::Facts::Facter, " when finding facts" do
it "should return a Facts instance" do
- @facts.should be_instance_of(Puppet::Node::Facts)
+ @facter.find(@request).should be_instance_of(Puppet::Node::Facts)
end
it "should return a Facts instance with the provided key as the name" do
- @facts.name.should == @name
+ @facter.find(@request).name.should == @name
end
it "should return the Facter facts as the values in the Facts instance" do
Facter.expects(:to_hash).returns("one" => "two")
- facts = @facter.find(@name)
+ facts = @facter.find(@request)
facts.values["one"].should == "two"
end
end
@@ -73,4 +73,4 @@ describe Puppet::Node::Facts::Facter do
describe Puppet::Node::Facts::Facter, " when loading facts from the factpath" do
it "should load every fact in each factpath directory"
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/indirector/file.rb b/spec/unit/indirector/file.rb
index 37740f0d0..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)
+ filehandle.expects(:print).with(@content)
- file = stub 'file', :content => content, :path => @path, :name => @path
-
- @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,48 +110,45 @@ 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
describe Puppet::Indirector::File, " when removing files" do
it "should provide a method to remove files at a specified path" do
- file = stub 'file', :path => @path, :name => @path
File.expects(:exist?).with(@path).returns(true)
File.expects(:unlink).with(@path)
- @searcher.destroy(file)
+ @searcher.destroy(@request)
end
it "should throw an exception if the file is not found" do
- file = stub 'file', :path => @path, :name => @path
File.expects(:exist?).with(@path).returns(false)
- proc { @searcher.destroy(file) }.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 = stub 'file', :path => @path, :name => @path
File.expects(:exist?).with(@path).returns(true)
File.expects(:unlink).with(@path).raises(ArgumentError)
- proc { @searcher.destroy(file) }.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
- @searcher.meta_def(:path) do |name|
- name.upcase
+ @searcher.meta_def(:path) do |thing|
+ thing.to_s.upcase
end
- file = stub 'file', :name => "/yay"
- File.expects(:exist?).with("/YAY").returns(true)
- File.expects(:unlink).with("/YAY")
+ File.expects(:exist?).with("/MY/FILE").returns(true)
+ File.expects(:unlink).with("/MY/FILE")
- @searcher.destroy(file)
+ @searcher.destroy(@request)
end
end
-end \ No newline at end of file
+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/file_server.rb b/spec/unit/indirector/file_server.rb
index 974b95e0e..79be8cc29 100755
--- a/spec/unit/indirector/file_server.rb
+++ b/spec/unit/indirector/file_server.rb
@@ -165,4 +165,4 @@ describe Puppet::Indirector::FileServer do
@file_server.search(@uri, :testing => :one, :other => :two)
end
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb
index fe456b61e..e8ab9633b 100755
--- a/spec/unit/indirector/indirection.rb
+++ b/spec/unit/indirector/indirection.rb
@@ -2,579 +2,730 @@
require File.dirname(__FILE__) + '/../../spec_helper'
-require 'puppet/indirector'
+require 'puppet/indirector/indirection'
+describe "Indirection Delegator", :shared => true do
+ it "should create a request object with the appropriate method name and all of the passed arguments" do
+ request = stub 'request', :options => {}
+ @indirection.expects(:request).with(@method, "mystuff", :one => :two).returns request
-describe Puppet::Indirector::Indirection, " when initializing" do
- # (LAK) I've no idea how to test this, really.
- it "should store a reference to itself before it consumes its options" do
- proc { @indirection = Puppet::Indirector::Indirection.new(Object.new, :testingness, :not_valid_option) }.should raise_error
- Puppet::Indirector::Indirection.instance(:testingness).should be_instance_of(Puppet::Indirector::Indirection)
- Puppet::Indirector::Indirection.instance(:testingness).delete
+ @terminus.stubs(@method)
+
+ @indirection.send(@method, "mystuff", :one => :two)
end
- it "should keep a reference to the indirecting model" do
- model = mock 'model'
- @indirection = Puppet::Indirector::Indirection.new(model, :myind)
- @indirection.model.should equal(model)
+ it "should let the :select_terminus method choose the terminus using the created request if the :select_terminus method is available" do
+ # Define the method, so our respond_to? hook matches.
+ class << @indirection
+ def select_terminus(request)
+ end
+ end
+
+ request = stub 'request', :key => "me", :options => {}
+
+ @indirection.stubs(:request).returns request
+
+ @indirection.expects(:select_terminus).with(request).returns :test_terminus
+
+ @indirection.stubs(:check_authorization)
+ @terminus.expects(@method)
+
+ @indirection.send(@method, "me")
end
- it "should set the name" do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :myind)
- @indirection.name.should == :myind
+ it "should choose the terminus returned by the :terminus_class method if no :select_terminus method is available" do
+ @indirection.expects(:terminus_class).returns :test_terminus
+
+ @terminus.expects(@method)
+
+ @indirection.send(@method, "me")
end
- it "should require indirections to have unique names" do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- proc { Puppet::Indirector::Indirection.new(:test) }.should raise_error(ArgumentError)
+ it "should let the appropriate terminus perform the lookup" do
+ @terminus.expects(@method).with { |r| r.is_a?(Puppet::Indirector::Request) }
+ @indirection.send(@method, "me")
end
+end
- it "should extend itself with any specified module" do
- mod = Module.new
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test, :extend => mod)
- @indirection.metaclass.included_modules.should include(mod)
+describe "Delegation Authorizer", :shared => true do
+ before do
+ # So the :respond_to? turns out correctly.
+ class << @terminus
+ def authorized?
+ end
+ end
end
- after do
- @indirection.delete if defined? @indirection
+ it "should not check authorization if a node name is not provided" do
+ @terminus.expects(:authorized?).never
+ @terminus.stubs(@method)
+
+ # The quotes are necessary here, else it looks like a block.
+ @request.stubs(:options).returns({})
+ @indirection.send(@method, "/my/key")
end
-end
-describe Puppet::Indirector::Indirection do
- before :each do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = stub 'terminus', :has_most_recent? => false
- @indirection.stubs(:terminus).returns(@terminus)
- @indirection.stubs(:terminus_class).returns(:whatever)
- @instance = stub 'instance', :version => nil, :version= => nil, :name => "whatever"
- @name = :mything
+ it "should pass the request to the terminus's authorization method" do
+ @terminus.expects(:authorized?).with { |r| r.is_a?(Puppet::Indirector::Request) }.returns(true)
+ @terminus.stubs(@method)
+
+ @indirection.send(@method, "/my/key", :node => "mynode")
end
-
- describe Puppet::Indirector::Indirection, " when looking for a model instance" do
- it "should let the appropriate terminus perform the lookup" do
- @terminus.expects(:find).with(@name).returns(@instance)
- @indirection.find(@name).should == @instance
- end
+ it "should fail if authorization returns false" do
+ @terminus.expects(:authorized?).returns(false)
+ @terminus.stubs(@method)
+ proc { @indirection.send(@method, "/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ end
+
+ it "should continue if authorization returns true" do
+ @terminus.expects(:authorized?).returns(true)
+ @terminus.stubs(@method)
+ @indirection.send(@method, "/my/key", :node => "mynode")
+ end
+end
- it "should not attempt to set a timestamp if the terminus cannot find the instance" do
- @terminus.expects(:find).with(@name).returns(nil)
- proc { @indirection.find(@name) }.should_not raise_error
+describe Puppet::Indirector::Indirection do
+ describe "when initializing" do
+ # (LAK) I've no idea how to test this, really.
+ it "should store a reference to itself before it consumes its options" do
+ proc { @indirection = Puppet::Indirector::Indirection.new(Object.new, :testingness, :not_valid_option) }.should raise_error
+ Puppet::Indirector::Indirection.instance(:testingness).should be_instance_of(Puppet::Indirector::Indirection)
+ Puppet::Indirector::Indirection.instance(:testingness).delete
end
- it "should pass the instance to the :post_find hook if there is one" do
- class << @terminus
- def post_find
- end
- end
- @terminus.expects(:post_find).with(@instance)
- @terminus.expects(:find).with(@name).returns(@instance)
- @indirection.find(@name)
+ it "should keep a reference to the indirecting model" do
+ model = mock 'model'
+ @indirection = Puppet::Indirector::Indirection.new(model, :myind)
+ @indirection.model.should equal(model)
end
- end
-
- describe Puppet::Indirector::Indirection, " when removing a model instance" do
- it "should let the appropriate terminus remove the instance" do
- @terminus.expects(:destroy).with(@name).returns(@instance)
- @indirection.destroy(@name).should == @instance
+ it "should set the name" do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :myind)
+ @indirection.name.should == :myind
end
- end
- describe Puppet::Indirector::Indirection, " when searching for multiple model instances" do
+ it "should require indirections to have unique names" do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ proc { Puppet::Indirector::Indirection.new(:test) }.should raise_error(ArgumentError)
+ end
- it "should let the appropriate terminus find the matching instances" do
- @terminus.expects(:search).with(@name).returns(@instance)
- @indirection.search(@name).should == @instance
+ it "should extend itself with any specified module" do
+ mod = Module.new
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test, :extend => mod)
+ @indirection.metaclass.included_modules.should include(mod)
end
- it "should pass the instances to the :post_search hook if there is one" do
- class << @terminus
- def post_search
- end
- end
- @terminus.expects(:post_search).with(@instance)
- @terminus.expects(:search).with(@name).returns(@instance)
- @indirection.search(@name)
+ after do
+ @indirection.delete if defined? @indirection
end
end
- describe Puppet::Indirector::Indirection, " when storing a model instance" do
+ describe "when an instance" do
+ before :each do
+ @terminus_class = mock 'terminus_class'
+ @terminus = mock 'terminus'
+ @terminus_class.stubs(:new).returns(@terminus)
+ @cache = mock 'cache'
+ @cache_class = mock 'cache_class'
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :cache_terminus).returns(@cache_class)
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :test_terminus).returns(@terminus_class)
+
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @indirection.terminus_class = :test_terminus
+
+ @instance = stub 'instance', :expiration => nil, :expiration= => nil, :name => "whatever"
+ @name = :mything
- it "should let the appropriate terminus store the instance" do
- @terminus.expects(:save).with(@instance).returns(@instance)
- @indirection.save(@instance).should == @instance
+ #@request = stub 'instance', :key => "/my/key", :instance => @instance, :options => {}
+ @request = mock 'instance'
+ end
+
+ it "should allow setting the ttl" do
+ @indirection.ttl = 300
+ @indirection.ttl.should == 300
end
- end
-
- describe Puppet::Indirector::Indirection, " when handling instance versions" do
- it "should let the appropriate terminus perform the lookup" do
- @terminus.expects(:version).with(@name).returns(5)
- @indirection.version(@name).should == 5
+ it "should default to the :runinterval setting, converted to an integer, for its ttl" do
+ Puppet.settings.expects(:value).returns "1800"
+ @indirection.ttl.should == 1800
end
- it "should add versions to found instances that do not already have them" do
- @terminus.expects(:find).with(@name).returns(@instance)
- time = mock 'time'
- time.expects(:utc).returns(:mystamp)
- Time.expects(:now).returns(time)
- @instance.expects(:version=).with(:mystamp)
- @indirection.find(@name)
+ it "should calculate the current expiration by adding the TTL to the current time" do
+ @indirection.stubs(:ttl).returns(100)
+ now = Time.now
+ Time.stubs(:now).returns now
+ @indirection.expiration.should == (Time.now + 100)
end
- it "should add versions to saved instances that do not already have them" do
- time = mock 'time'
- time.expects(:utc).returns(:mystamp)
- Time.expects(:now).returns(time)
- @instance.expects(:version=).with(:mystamp)
- @terminus.stubs(:save)
- @indirection.save(@instance)
+ it "should have a method for creating an indirection request instance" do
+ @indirection.should respond_to(:request)
end
- # We've already tested this, basically, but...
- it "should use the current time in UTC for versions" do
- @instance.expects(:version=).with do |time|
- time.utc?
+ 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 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
- @terminus.stubs(:save)
- @indirection.save(@instance)
end
- end
+
+ describe "and looking for a model instance" do
+ before { @method = :find }
+ it_should_behave_like "Indirection Delegator"
+ it_should_behave_like "Delegation Authorizer"
- describe Puppet::Indirector::Indirection, " when an authorization hook is present" do
+ it "should return the results of the delegation" do
+ @terminus.expects(:find).returns(@instance)
+ @indirection.find("me").should equal(@instance)
+ end
- before do
- # So the :respond_to? turns out right.
- class << @terminus
- def authorized?
+ it "should set the expiration date on any instances without one set" do
+ @terminus.stubs(:find).returns(@instance)
+
+ @indirection.expects(:expiration).returns :yay
+
+ @instance.expects(:expiration).returns(nil)
+ @instance.expects(:expiration=).with(:yay)
+
+ @indirection.find("/my/key")
+ end
+
+ it "should not override an already-set expiration date on returned instances" do
+ @terminus.stubs(:find).returns(@instance)
+
+ @indirection.expects(:expiration).never
+
+ @instance.expects(:expiration).returns(:yay)
+ @instance.expects(:expiration=).never
+
+ @indirection.find("/my/key")
+ end
+
+ describe "when caching is enabled" do
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.expects(:new).returns(@cache)
+
+ @instance.stubs(:expired?).returns false
+ end
+
+ it "should first look in the cache for an instance" do
+ @terminus.stubs(:find).never
+ @cache.expects(:find).returns @instance
+
+ @indirection.find("/my/key")
+ end
+
+ it "should use a request to look in the cache for cached objects" do
+ @cache.expects(:find).with { |r| r.method == :find and r.key == "/my/key" }.returns @instance
+
+ @cache.stubs(:save)
+
+ @indirection.find("/my/key")
+ 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("/my/key").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("/my/key")
+ end
+
+ it "should not return the cached object if it is expired" do
+ @instance.stubs(:expired?).returns true
+
+ @cache.stubs(:find).returns @instance
+ @terminus.stubs(:find).returns nil
+ @indirection.find("/my/key").should be_nil
+ end
+
+ it "should send an info log if it is using the cached object" do
+ Puppet.expects(:info)
+ @instance.stubs(:expired?).returns true
+
+ @cache.stubs(:find).returns @instance
+ @terminus.stubs(:find).returns nil
+ @indirection.find("/my/key")
+ end
+
+ it "should cache any objects not retrieved from the cache" do
+ @cache.expects(:find).returns nil
+
+ @terminus.expects(:find).returns(@instance)
+ @cache.expects(:save)
+
+ @indirection.find("/my/key")
+ end
+
+ it "should use a request to look in the cache for cached objects" do
+ @cache.expects(:find).with { |r| r.method == :find and r.key == "/my/key" }.returns nil
+
+ @terminus.stubs(:find).returns(@instance)
+ @cache.stubs(:save)
+
+ @indirection.find("/my/key")
+ end
+
+ it "should cache the instance using a request with the instance set to the cached object" do
+ @cache.stubs(:find).returns nil
+
+ @terminus.stubs(:find).returns(@instance)
+
+ @cache.expects(:save).with { |r| r.method == :save and r.instance == @instance }
+
+ @indirection.find("/my/key")
+ end
+
+ it "should send an info log that the object is being cached" do
+ @cache.stubs(:find).returns nil
+
+ @terminus.stubs(:find).returns(@instance)
+ @cache.stubs(:save)
+
+ Puppet.expects(:info)
+
+ @indirection.find("/my/key")
end
end
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")
- end
+ describe "and storing a model instance" do
+ before { @method = :save }
- it "should fail while finding instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:find, "/my/key", :node => "mynode").returns(false)
- @terminus.stubs(:find)
- proc { @indirection.find("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
- end
+ it_should_behave_like "Indirection Delegator"
+ it_should_behave_like "Delegation Authorizer"
- it "should continue finding instances if authorization returns true" do
- @terminus.expects(:authorized?).with(:find, "/my/key", :node => "mynode").returns(true)
- @terminus.stubs(:find)
- @indirection.find("/my/key", :node => "mynode")
- end
+ it "should return nil" do
+ @terminus.stubs(:save)
+ @indirection.save(@instance).should be_nil
+ end
- it "should fail while saving instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:save, :myinstance, :node => "mynode").returns(false)
- @terminus.stubs(:save)
- proc { @indirection.save(:myinstance, :node => "mynode") }.should raise_error(ArgumentError)
- end
+ describe "when caching is enabled" do
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.expects(:new).returns(@cache)
- it "should continue saving instances if authorization returns true" do
- instance = stub 'instance', :version => 1.0, :name => "eh"
- @terminus.expects(:authorized?).with(:save, instance, :node => "mynode").returns(true)
- @terminus.stubs(:save)
- @indirection.save(instance, :node => "mynode")
- end
+ @instance.stubs(:expired?).returns false
+ end
- it "should fail while destroying instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:destroy, "/my/key", :node => "mynode").returns(false)
- @terminus.stubs(:destroy)
- proc { @indirection.destroy("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
- end
+ it "should use a request to save the object to the cache" do
+ request = stub 'request', :instance => @instance, :options => {}
- it "should continue destroying instances if authorization returns true" do
- instance = stub 'instance', :version => 1.0, :name => "eh"
- @terminus.expects(:authorized?).with(:destroy, instance, :node => "mynode").returns(true)
- @terminus.stubs(:destroy)
- @indirection.destroy(instance, :node => "mynode")
- end
+ @indirection.expects(:request).returns request
- it "should fail while searching for instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:search, "/my/key", :node => "mynode").returns(false)
- @terminus.stubs(:search)
- proc { @indirection.search("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ @cache.expects(:save).with(request)
+ @terminus.stubs(:save)
+ @indirection.save(@instance)
+ end
+ end
end
+
+ describe "and removing a model instance" do
+ before { @method = :destroy }
- it "should continue searching for instances if authorization returns true" do
- @terminus.expects(:authorized?).with(:search, "/my/key", :node => "mynode").returns(true)
- @terminus.stubs(:search)
- @indirection.search("/my/key", :node => "mynode")
- end
- end
+ it_should_behave_like "Indirection Delegator"
+ it_should_behave_like "Delegation Authorizer"
- after :each do
- @indirection.delete
- Puppet::Indirector::Indirection.clear_cache
- end
-end
+ it "should return nil" do
+ @terminus.stubs(:destroy)
+ @indirection.destroy("/my/key").should be_nil
+ end
+ describe "when caching is enabled" do
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.expects(:new).returns(@cache)
-describe Puppet::Indirector::Indirection, " when managing indirection instances" do
- it "should allow an indirection to be retrieved by name" do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- Puppet::Indirector::Indirection.instance(:test).should equal(@indirection)
- end
-
- it "should return nil when the named indirection has not been created" do
- Puppet::Indirector::Indirection.instance(:test).should be_nil
- end
+ @instance.stubs(:expired?).returns false
+ end
- it "should allow an indirection's model to be retrieved by name" do
- mock_model = mock('model')
- @indirection = Puppet::Indirector::Indirection.new(mock_model, :test)
- Puppet::Indirector::Indirection.model(:test).should equal(mock_model)
- end
-
- it "should return nil when no model matches the requested name" do
- Puppet::Indirector::Indirection.model(:test).should be_nil
- end
+ it "should use a request instance to search in and remove objects from the cache" do
+ destroy = stub 'destroy_request', :key => "/my/key", :options => {}
+ find = stub 'destroy_request', :key => "/my/key", :options => {}
- after do
- @indirection.delete if defined? @indirection
- end
-end
-
-describe Puppet::Indirector::Indirection, " when choosing the terminus class" do
- before do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = mock 'terminus'
- @terminus_class = stub 'terminus class', :new => @terminus
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :default).returns(@terminus_class)
- end
+ @indirection.expects(:request).with(:destroy, "/my/key").returns destroy
+ @indirection.expects(:request).with(:find, "/my/key").returns find
- it "should choose the default terminus class if one is specified and no specific terminus class is provided" do
- @indirection.terminus_class = :default
- @indirection.terminus_class.should equal(:default)
- end
+ cached = mock 'cache'
- it "should use the provided Puppet setting if told to do so" do
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :my_terminus).returns(mock("terminus_class2"))
- Puppet.settings.expects(:value).with(:my_setting).returns("my_terminus")
- @indirection.terminus_setting = :my_setting
- @indirection.terminus_class.should equal(:my_terminus)
- end
+ @cache.expects(:find).with(find).returns cached
+ @cache.expects(:destroy).with(destroy)
- it "should fail if the provided terminus class is not valid" do
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :nosuchclass).returns(nil)
- proc { @indirection.terminus_class = :nosuchclass }.should raise_error(ArgumentError)
- end
-
- it "should fail if no terminus class is picked" do
- proc { @indirection.terminus_class }.should raise_error(Puppet::DevError)
- end
+ @terminus.stubs(:destroy)
- after do
- @indirection.delete if defined? @indirection
- end
-end
+ @indirection.destroy("/my/key")
+ end
+ end
+ end
-describe Puppet::Indirector::Indirection, " when specifying the terminus class to use" do
- before do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = mock 'terminus'
- @terminus_class = stub 'terminus class', :new => @terminus
- end
+ describe "and searching for multiple model instances" do
+ before { @method = :search }
- it "should allow specification of a terminus type" do
- @indirection.should respond_to(:terminus_class=)
- end
+ it_should_behave_like "Indirection Delegator"
+ it_should_behave_like "Delegation Authorizer"
- it "should fail to redirect if no terminus type has been specified" do
- proc { @indirection.find("blah") }.should raise_error(Puppet::DevError)
- end
+ it "should set the expiration date on any instances without one set" do
+ @terminus.stubs(:search).returns([@instance])
- it "should fail when the terminus class name is an empty string" do
- proc { @indirection.terminus_class = "" }.should raise_error(ArgumentError)
- end
+ @indirection.expects(:expiration).returns :yay
- it "should fail when the terminus class name is nil" do
- proc { @indirection.terminus_class = nil }.should raise_error(ArgumentError)
- end
+ @instance.expects(:expiration).returns(nil)
+ @instance.expects(:expiration=).with(:yay)
- it "should fail when the specified terminus class cannot be found" do
- Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(nil)
- proc { @indirection.terminus_class = :foo }.should raise_error(ArgumentError)
- end
+ @indirection.search("/my/key")
+ end
- it "should select the specified terminus class if a terminus class name is provided" do
- Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(@terminus_class)
- @indirection.terminus(:foo).should equal(@terminus)
- end
+ it "should not override an already-set expiration date on returned instances" do
+ @terminus.stubs(:search).returns([@instance])
- it "should use the configured terminus class if no terminus name is specified" do
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
- @indirection.terminus_class = :foo
- @indirection.terminus().should equal(@terminus)
- end
+ @indirection.expects(:expiration).never
- after do
- @indirection.delete if defined? @indirection
- end
-end
+ @instance.expects(:expiration).returns(:yay)
+ @instance.expects(:expiration=).never
-describe Puppet::Indirector::Indirection, " when a select_terminus hook is available" do
- before do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @indirection.search("/my/key")
+ end
- # And provide a select_terminus hook
- @indirection.meta_def(:select_terminus) do |uri|
- :other
+ it "should return the results of searching in the terminus" do
+ @terminus.expects(:search).returns([@instance])
+ @indirection.search("/my/key").should == [@instance]
+ end
end
- @terminus = mock 'terminus'
- @terminus_class = stub 'terminus class', :new => @terminus
+ describe "and expiring a model instance" do
+ describe "when caching is not enabled" do
+ it "should do nothing" do
+ @cache_class.expects(:new).never
- @other_terminus = mock 'other_terminus'
- @other_terminus_class = stub 'other_terminus_class', :new => @other_terminus
+ @indirection.expire("/my/key")
+ end
+ end
- @cache_terminus = mock 'cache_terminus'
- @cache_terminus_class = stub 'cache_terminus_class', :new => @cache_terminus
+ describe "when caching is enabled" do
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.expects(:new).returns(@cache)
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :other).returns(@other_terminus_class)
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :cache).returns(@cache_terminus_class)
+ @instance.stubs(:expired?).returns false
- # Set it to a default type.
- @indirection.terminus_class = :foo
+ @cached = stub 'cached', :expiration= => nil, :name => "/my/key"
+ end
- @uri = "full://url/path"
- @result = stub 'result', :version => 1.0
- end
+ it "should use a request to find within the cache" do
+ @cache.expects(:find).with { |r| r.is_a?(Puppet::Indirector::Request) and r.method == :find }
+ @indirection.expire("/my/key")
+ end
- it "should use the terminus name provided by passing the key to the :select_terminus hook when finding instances" do
- # Set up the expectation
- @other_terminus.expects(:find).with(@uri).returns(@result)
+ it "should do nothing if no such instance is cached" do
+ @cache.expects(:find).returns nil
- @indirection.find(@uri)
- end
+ @indirection.expire("/my/key")
+ end
- it "should use the terminus name provided by passing the key to the :select_terminus hook when testing if a cached instance is up to date" do
- @indirection.cache_class = :cache
+ it "should log that it is expiring any found instance" do
+ @cache.expects(:find).returns @cached
+ @cache.stubs(:save)
- @other_terminus.expects(:version).with(@uri).returns(2.0)
+ Puppet.expects(:info)
- @cache_terminus.expects(:has_most_recent?).with(@uri, 2.0).returns(true)
- @cache_terminus.expects(:find).returns(:whatever)
+ @indirection.expire("/my/key")
+ end
- @indirection.find(@uri).should == :whatever
- end
+ it "should set the cached instance's expiration to a time in the past" do
+ @cache.expects(:find).returns @cached
+ @cache.stubs(:save)
- it "should pass all arguments to the :select_terminus hook" do
- @indirection.expects(:select_terminus).with(@uri, :node => "johnny").returns(:other)
- @other_terminus.stubs(:find)
+ @cached.expects(:expiration=).with { |t| t < Time.now }
- @indirection.find(@uri, :node => "johnny")
- end
+ @indirection.expire("/my/key")
+ end
- it "should pass the original key to the terminus rather than a modified key" do
- # This is the same test as before
- @other_terminus.expects(:find).with(@uri).returns(@result)
- @indirection.find(@uri)
- end
+ it "should save the now expired instance back into the cache" do
+ @cache.expects(:find).returns @cached
- after do
- @indirection.delete if defined? @indirection
- end
-end
+ @cached.expects(:expiration=).with { |t| t < Time.now }
-describe Puppet::Indirector::Indirection, " when managing terminus instances" do
- before do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = mock 'terminus'
- @terminus_class = mock 'terminus class'
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
- end
+ @cache.expects(:save)
- it "should create an instance of the chosen terminus class" do
- @terminus_class.stubs(:new).returns(@terminus)
- @indirection.terminus(:foo).should equal(@terminus)
- end
+ @indirection.expire("/my/key")
+ end
- it "should allow the clearance of cached terminus instances" do
- terminus1 = mock 'terminus1'
- terminus2 = mock 'terminus2'
- @terminus_class.stubs(:new).returns(terminus1, terminus2, ArgumentError)
- @indirection.terminus(:foo).should equal(terminus1)
- @indirection.class.clear_cache
- @indirection.terminus(:foo).should equal(terminus2)
- end
+ it "should use a request to save the expired resource to the cache" do
+ @cache.expects(:find).returns @cached
- # Make sure it caches the terminus.
- it "should return the same terminus instance each time for a given name" do
- @terminus_class.stubs(:new).returns(@terminus)
- @indirection.terminus(:foo).should equal(@terminus)
- @indirection.terminus(:foo).should equal(@terminus)
- end
+ @cached.expects(:expiration=).with { |t| t < Time.now }
- it "should not create a terminus instance until one is actually needed" do
- Puppet::Indirector.expects(:terminus).never
- indirection = Puppet::Indirector::Indirection.new(mock('model'), :lazytest)
- end
+ @cache.expects(:save).with { |r| r.is_a?(Puppet::Indirector::Request) and r.instance == @cached and r.method == :save }.returns(@cached)
- after do
- @indirection.delete
- Puppet::Indirector::Indirection.clear_cache
- end
-end
+ @indirection.expire("/my/key")
+ end
+ end
+ end
-describe Puppet::Indirector::Indirection, " when deciding whether to cache" do
- before do
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = mock 'terminus'
- @terminus_class = mock 'terminus class'
- @terminus_class.stubs(:new).returns(@terminus)
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
- @indirection.terminus_class = :foo
+ after :each do
+ @indirection.delete
+ Puppet::Indirector::Indirection.clear_cache
+ end
end
- it "should provide a method for setting the cache terminus class" do
- @indirection.should respond_to(:cache_class=)
- end
- it "should fail to cache if no cache type has been specified" do
- proc { @indirection.cache }.should raise_error(Puppet::DevError)
- end
+ describe "when managing indirection instances" do
+ it "should allow an indirection to be retrieved by name" do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ Puppet::Indirector::Indirection.instance(:test).should equal(@indirection)
+ end
+
+ it "should return nil when the named indirection has not been created" do
+ Puppet::Indirector::Indirection.instance(:test).should be_nil
+ end
- it "should fail to set the cache class when the cache class name is an empty string" do
- proc { @indirection.cache_class = "" }.should raise_error(ArgumentError)
- end
+ it "should allow an indirection's model to be retrieved by name" do
+ mock_model = mock('model')
+ @indirection = Puppet::Indirector::Indirection.new(mock_model, :test)
+ Puppet::Indirector::Indirection.model(:test).should equal(mock_model)
+ end
+
+ it "should return nil when no model matches the requested name" do
+ Puppet::Indirector::Indirection.model(:test).should be_nil
+ end
- it "should fail to set the cache class when the cache class name is nil" do
- proc { @indirection.cache_class = nil }.should raise_error(ArgumentError)
+ after do
+ @indirection.delete if defined? @indirection
+ end
end
- it "should fail to set the cache class when the specified cache class cannot be found" do
- Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(nil)
- proc { @indirection.cache_class = :foo }.should raise_error(ArgumentError)
- end
+ describe "when routing to the correct the terminus class" do
+ before do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = mock 'terminus'
+ @terminus_class = stub 'terminus class', :new => @terminus
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :default).returns(@terminus_class)
+ end
- after do
- @indirection.delete
- Puppet::Indirector::Indirection.clear_cache
- end
-end
+ it "should fail if no terminus class can be picked" do
+ proc { @indirection.terminus_class }.should raise_error(Puppet::DevError)
+ end
-describe Puppet::Indirector::Indirection do
- before :each do
- Puppet.settings.stubs(:value).with("test_terminus").returns("test_terminus")
- @terminus_class = mock 'terminus_class'
- @terminus = mock 'terminus'
- @terminus_class.stubs(:new).returns(@terminus)
- @cache = mock 'cache'
- @cache_class = mock 'cache_class'
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :cache_terminus).returns(@cache_class)
- Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :test_terminus).returns(@terminus_class)
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @indirection.terminus_class = :test_terminus
+ it "should choose the default terminus class if one is specified" do
+ @indirection.terminus_class = :default
+ @indirection.terminus_class.should equal(:default)
+ end
+
+ it "should use the provided Puppet setting if told to do so" do
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :my_terminus).returns(mock("terminus_class2"))
+ Puppet.settings.expects(:value).with(:my_setting).returns("my_terminus")
+ @indirection.terminus_setting = :my_setting
+ @indirection.terminus_class.should equal(:my_terminus)
+ end
+
+ it "should fail if the provided terminus class is not valid" do
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :nosuchclass).returns(nil)
+ proc { @indirection.terminus_class = :nosuchclass }.should raise_error(ArgumentError)
+ end
+
+ after do
+ @indirection.delete if defined? @indirection
+ end
end
- describe Puppet::Indirector::Indirection, " when managing the cache terminus" do
+ describe "when specifying the terminus class to use" do
+ before do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = mock 'terminus'
+ @terminus_class = stub 'terminus class', :new => @terminus
+ end
+
+ it "should allow specification of a terminus type" do
+ @indirection.should respond_to(:terminus_class=)
+ end
- it "should not create a cache terminus at initialization" do
- # This is weird, because all of the code is in the setup. If we got
- # new() called on the cache class, we'd get an exception here.
+ it "should fail to redirect if no terminus type has been specified" do
+ proc { @indirection.find("blah") }.should raise_error(Puppet::DevError)
end
- it "should reuse the cache terminus" do
- @cache_class.expects(:new).returns(@cache)
- Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus")
- @indirection.cache_class = :cache_terminus
- @indirection.cache.should equal(@cache)
- @indirection.cache.should equal(@cache)
+ it "should fail when the terminus class name is an empty string" do
+ proc { @indirection.terminus_class = "" }.should raise_error(ArgumentError)
end
- it "should remove the cache terminus when all other terminus instances are cleared" do
- cache2 = mock 'cache2'
- @cache_class.stubs(:new).returns(@cache, cache2)
- @indirection.cache_class = :cache_terminus
- @indirection.cache.should equal(@cache)
- @indirection.clear_cache
- @indirection.cache.should equal(cache2)
+ it "should fail when the terminus class name is nil" do
+ proc { @indirection.terminus_class = nil }.should raise_error(ArgumentError)
end
- end
- describe Puppet::Indirector::Indirection, " when saving and using a cache" do
+ it "should fail when the specified terminus class cannot be found" do
+ Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(nil)
+ proc { @indirection.terminus_class = :foo }.should raise_error(ArgumentError)
+ end
- before do
- @indirection.cache_class = :cache_terminus
- @cache_class.expects(:new).returns(@cache)
- @name = "testing"
- @instance = stub 'instance', :version => 5, :name => @name
+ it "should select the specified terminus class if a terminus class name is provided" do
+ Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(@terminus_class)
+ @indirection.terminus(:foo).should equal(@terminus)
end
- it "should not update the cache or terminus if the new object is not different" do
- @cache.expects(:has_most_recent?).with(@name, 5).returns(true)
- @indirection.save(@instance)
+ it "should use the configured terminus class if no terminus name is specified" do
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
+ @indirection.terminus_class = :foo
+ @indirection.terminus().should equal(@terminus)
end
- it "should update the original and the cache if the cached object is different" do
- @cache.expects(:has_most_recent?).with(@name, 5).returns(false)
- @terminus.expects(:save).with(@instance)
- @cache.expects(:save).with(@instance)
- @indirection.save(@instance)
+ after do
+ @indirection.delete if defined? @indirection
end
end
-
- describe Puppet::Indirector::Indirection, " when finding and using a cache" do
+ describe "when managing terminus instances" do
before do
- @indirection.cache_class = :cache_terminus
- @cache_class.expects(:new).returns(@cache)
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = mock 'terminus'
+ @terminus_class = mock 'terminus class'
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
+ end
+
+ it "should create an instance of the chosen terminus class" do
+ @terminus_class.stubs(:new).returns(@terminus)
+ @indirection.terminus(:foo).should equal(@terminus)
end
- it "should return the cached object if the cache is up to date" do
- cached = mock 'cached object'
+ it "should allow the clearance of cached terminus instances" do
+ terminus1 = mock 'terminus1'
+ terminus2 = mock 'terminus2'
+ @terminus_class.stubs(:new).returns(terminus1, terminus2, ArgumentError)
+ @indirection.terminus(:foo).should equal(terminus1)
+ @indirection.class.clear_cache
+ @indirection.terminus(:foo).should equal(terminus2)
+ end
- name = "myobject"
+ # Make sure it caches the terminus.
+ it "should return the same terminus instance each time for a given name" do
+ @terminus_class.stubs(:new).returns(@terminus)
+ @indirection.terminus(:foo).should equal(@terminus)
+ @indirection.terminus(:foo).should equal(@terminus)
+ end
- @terminus.expects(:version).with(name).returns(1)
- @cache.expects(:has_most_recent?).with(name, 1).returns(true)
+ it "should not create a terminus instance until one is actually needed" do
+ Puppet::Indirector.expects(:terminus).never
+ indirection = Puppet::Indirector::Indirection.new(mock('model'), :lazytest)
+ end
- @cache.expects(:find).with(name).returns(cached)
+ after do
+ @indirection.delete
+ Puppet::Indirector::Indirection.clear_cache
+ end
+ end
+
+ describe "when deciding whether to cache" do
+ before do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = mock 'terminus'
+ @terminus_class = mock 'terminus class'
+ @terminus_class.stubs(:new).returns(@terminus)
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
+ @indirection.terminus_class = :foo
+ end
- @indirection.find(name).should equal(cached)
+ it "should provide a method for setting the cache terminus class" do
+ @indirection.should respond_to(:cache_class=)
end
- it "should return the original object if the cache is not up to date" do
- real = stub 'real object', :version => 1
+ it "should fail to cache if no cache type has been specified" do
+ proc { @indirection.cache }.should raise_error(Puppet::DevError)
+ end
- name = "myobject"
+ it "should fail to set the cache class when the cache class name is an empty string" do
+ proc { @indirection.cache_class = "" }.should raise_error(ArgumentError)
+ end
- @cache.stubs(:save)
- @cache.expects(:has_most_recent?).with(name, 1).returns(false)
- @terminus.expects(:version).with(name).returns(1)
+ it "should fail to set the cache class when the cache class name is nil" do
+ proc { @indirection.cache_class = nil }.should raise_error(ArgumentError)
+ end
- @terminus.expects(:find).with(name).returns(real)
+ it "should fail to set the cache class when the specified cache class cannot be found" do
+ Puppet::Indirector::Terminus.expects(:terminus_class).with(:test, :foo).returns(nil)
+ proc { @indirection.cache_class = :foo }.should raise_error(ArgumentError)
+ end
- @indirection.find(name).should equal(real)
+ after do
+ @indirection.delete
+ Puppet::Indirector::Indirection.clear_cache
end
+ end
- it "should cache any newly returned objects" do
- real = stub 'real object', :version => 1
+ describe "when using a cache" do
+ before :each do
+ Puppet.settings.stubs(:value).with("test_terminus").returns("test_terminus")
+ @terminus_class = mock 'terminus_class'
+ @terminus = mock 'terminus'
+ @terminus_class.stubs(:new).returns(@terminus)
+ @cache = mock 'cache'
+ @cache_class = mock 'cache_class'
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :cache_terminus).returns(@cache_class)
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :test_terminus).returns(@terminus_class)
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @indirection.terminus_class = :test_terminus
+ end
- name = "myobject"
+ describe "and managing the cache terminus" do
+ it "should not create a cache terminus at initialization" do
+ # This is weird, because all of the code is in the setup. If we got
+ # new() called on the cache class, we'd get an exception here.
+ end
- @terminus.expects(:version).with(name).returns(1)
- @cache.expects(:has_most_recent?).with(name, 1).returns(false)
+ it "should reuse the cache terminus" do
+ @cache_class.expects(:new).returns(@cache)
+ Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus")
+ @indirection.cache_class = :cache_terminus
+ @indirection.cache.should equal(@cache)
+ @indirection.cache.should equal(@cache)
+ end
- @terminus.expects(:find).with(name).returns(real)
- @cache.expects(:save).with(real)
+ it "should remove the cache terminus when all other terminus instances are cleared" do
+ cache2 = mock 'cache2'
+ @cache_class.stubs(:new).returns(@cache, cache2)
+ @indirection.cache_class = :cache_terminus
+ @indirection.cache.should equal(@cache)
+ @indirection.clear_cache
+ @indirection.cache.should equal(cache2)
+ end
+ end
- @indirection.find(name).should equal(real)
+ describe "and saving" do
+ end
+
+ describe "and finding" do
+ end
+
+ after :each do
+ @indirection.delete
+ Puppet::Indirector::Indirection.clear_cache
end
- end
-
- after :each do
- @indirection.delete
- Puppet::Indirector::Indirection.clear_cache
end
end
diff --git a/spec/unit/indirector/ldap.rb b/spec/unit/indirector/ldap.rb
index 6712ccb4f..2599bcecf 100755
--- a/spec/unit/indirector/ldap.rb
+++ b/spec/unit/indirector/ldap.rb
@@ -24,11 +24,13 @@ describe Puppet::Indirector::Ldap, " when searching ldap" do
@searcher.stubs(:search_filter).returns(:filter)
@searcher.stubs(:search_base).returns(:base)
@searcher.stubs(:process)
+
+ @request = stub 'request', :key => "yay"
end
it "should call the ldapsearch method with the name being searched for" do
@searcher.expects(:ldapsearch).with("yay")
- @searcher.find "yay"
+ @searcher.find @request
end
it "should fail if no block is passed to the ldapsearch method" do
@@ -41,7 +43,7 @@ describe Puppet::Indirector::Ldap, " when searching ldap" do
args[0].should == "mybase"
true
end
- @searcher.find "yay"
+ @searcher.find @request
end
it "should default to the value of the :search_base setting as the result of the ldapbase method" do
@@ -56,7 +58,7 @@ describe Puppet::Indirector::Ldap, " when searching ldap" do
args[3].should == :myattrs
true
end
- @searcher.find "yay"
+ @searcher.find @request
end
it "should use the results of the :search_filter method as the search filter" do
@@ -65,7 +67,7 @@ describe Puppet::Indirector::Ldap, " when searching ldap" do
args[2].should == "yay's filter"
true
end
- @searcher.find "yay"
+ @searcher.find @request
end
it "should use depth 2 when searching" do
@@ -73,13 +75,13 @@ describe Puppet::Indirector::Ldap, " when searching ldap" do
args[1].should == 2
true
end
- @searcher.find "yay"
+ @searcher.find @request
end
it "should call process() on the first found entry" do
@connection.expects(:search).yields("myresult")
@searcher.expects(:process).with("yay", "myresult")
- @searcher.find "yay"
+ @searcher.find @request
end
it "should reconnect and retry the search if there is a failure" do
@@ -94,7 +96,7 @@ describe Puppet::Indirector::Ldap, " when searching ldap" do
end.yields("myresult")
@searcher.expects(:process).with("yay", "myresult")
- @searcher.find "yay"
+ @searcher.find @request
end
it "should not reconnect on failure more than once" do
@@ -103,7 +105,7 @@ describe Puppet::Indirector::Ldap, " when searching ldap" do
count += 1
raise ArgumentError, "yay"
end
- proc { @searcher.find("whatever") }.should raise_error(Puppet::Error)
+ proc { @searcher.find(@request) }.should raise_error(Puppet::Error)
count.should == 2
end
diff --git a/spec/unit/indirector/memory.rb b/spec/unit/indirector/memory.rb
index c0fca6bd9..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)
- @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/exec.rb b/spec/unit/indirector/node/exec.rb
index b67e0fe97..09f13ab90 100755
--- a/spec/unit/indirector/node/exec.rb
+++ b/spec/unit/indirector/node/exec.rb
@@ -11,12 +11,6 @@ describe Puppet::Node::Exec do
@searcher = Puppet::Node::Exec.new
end
- it "should use the version of the facts as its version" do
- version = mock 'version'
- Puppet::Node::Facts.expects(:version).with("me").returns version
- @searcher.version("me").should equal(version)
- end
-
describe "when constructing the command to run" do
it "should use the external_node script as the command" do
Puppet.expects(:[]).with(:external_nodes).returns("/bin/echo")
@@ -25,7 +19,7 @@ describe Puppet::Node::Exec do
it "should throw an exception if no external node command is set" do
Puppet.expects(:[]).with(:external_nodes).returns("none")
- proc { @searcher.find("foo") }.should raise_error(ArgumentError)
+ proc { @searcher.find(stub('request', :key => "foo")) }.should raise_error(ArgumentError)
end
end
@@ -40,34 +34,36 @@ describe Puppet::Node::Exec do
@searcher.meta_def(:execute) do |command|
return YAML.dump(result)
end
+
+ @request = stub 'request', :key => @name
end
it "should translate the YAML into a Node instance" do
# Use an empty hash
- @searcher.find(@name).should equal(@node)
+ @searcher.find(@request).should equal(@node)
end
it "should set the resulting parameters as the node parameters" do
@result[:parameters] = {"a" => "b", "c" => "d"}
@node.expects(:parameters=).with "a" => "b", "c" => "d"
- @searcher.find(@name)
+ @searcher.find(@request)
end
it "should set the resulting classes as the node classes" do
@result[:classes] = %w{one two}
@node.expects(:classes=).with %w{one two}
- @searcher.find(@name)
+ @searcher.find(@request)
end
it "should merge the node's facts with its parameters" do
@node.expects(:fact_merge)
- @searcher.find(@name)
+ @searcher.find(@request)
end
it "should set the node's environment if one is provided" do
@result[:environment] = "yay"
@node.expects(:environment=).with "yay"
- @searcher.find(@name)
+ @searcher.find(@request)
end
end
end
diff --git a/spec/unit/indirector/node/ldap.rb b/spec/unit/indirector/node/ldap.rb
index 34456703d..a40698662 100755
--- a/spec/unit/indirector/node/ldap.rb
+++ b/spec/unit/indirector/node/ldap.rb
@@ -5,13 +5,6 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/ldap'
describe Puppet::Node::Ldap do
- it "should use the version of the facts as its version" do
- @searcher = Puppet::Node::Ldap.new
- version = mock 'version'
- Puppet::Node::Facts.expects(:version).with("me").returns version
- @searcher.version("me").should equal(version)
- end
-
describe "when searching for nodes" do
before :each do
@searcher = Puppet::Node::Ldap.new
@@ -31,16 +24,18 @@ describe Puppet::Node::Ldap do
@node.stubs(:fact_merge)
@name = "mynode"
Puppet::Node.stubs(:new).with(@name).returns(@node)
+
+ @request = stub 'request', :key => @name
end
it "should return nil if no results are found in ldap" do
@connection.stubs(:search)
- @searcher.find("mynode").should be_nil
+ @searcher.find(@request).should be_nil
end
it "should return a node object if results are found in ldap" do
@entry.stubs(:to_hash).returns({})
- @searcher.find("mynode").should equal(@node)
+ @searcher.find(@request).should equal(@node)
end
it "should deduplicate class values" do
@@ -49,7 +44,7 @@ describe Puppet::Node::Ldap do
@entry.stubs(:vals).with("one").returns(%w{a b})
@entry.stubs(:vals).with("two").returns(%w{b c})
@node.expects(:classes=).with(%w{a b c})
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should add any values stored in the class_attributes attributes to the node classes" do
@@ -58,38 +53,38 @@ describe Puppet::Node::Ldap do
@entry.stubs(:vals).with("one").returns(%w{a b})
@entry.stubs(:vals).with("two").returns(%w{c d})
@node.expects(:classes=).with(%w{a b c d})
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should add all entry attributes as node parameters" do
@entry.stubs(:to_hash).returns("one" => ["two"], "three" => ["four"])
@node.expects(:parameters=).with("one" => "two", "three" => "four")
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should set the node's environment to the environment of the results" do
@entry.stubs(:to_hash).returns("environment" => ["test"])
@node.stubs(:parameters=)
@node.expects(:environment=).with("test")
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should retain false parameter values" do
@entry.stubs(:to_hash).returns("one" => [false])
@node.expects(:parameters=).with("one" => false)
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should turn single-value parameter value arrays into single non-arrays" do
@entry.stubs(:to_hash).returns("one" => ["a"])
@node.expects(:parameters=).with("one" => "a")
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should keep multi-valued parametes as arrays" do
@entry.stubs(:to_hash).returns("one" => ["a", "b"])
@node.expects(:parameters=).with("one" => ["a", "b"])
- @searcher.find("mynode")
+ @searcher.find(@request)
end
describe "and a parent node is specified" do
@@ -113,7 +108,7 @@ describe Puppet::Node::Ldap do
@entry.stubs(:to_hash).returns({})
@entry.stubs(:vals).with(:parent).returns(%w{parent})
- proc { @searcher.find("mynode") }.should raise_error(Puppet::Error)
+ proc { @searcher.find(@request) }.should raise_error(Puppet::Error)
end
it "should add any parent classes to the node's classes" do
@@ -127,7 +122,7 @@ describe Puppet::Node::Ldap do
@searcher.stubs(:class_attributes).returns(%w{classes})
@node.expects(:classes=).with(%w{a b c d})
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should add any parent parameters to the node's parameters" do
@@ -138,7 +133,7 @@ describe Puppet::Node::Ldap do
@parent.stubs(:vals).with(:parent).returns(nil)
@node.expects(:parameters=).with("one" => "two", "three" => "four")
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should prefer node parameters over parent parameters" do
@@ -149,7 +144,7 @@ describe Puppet::Node::Ldap do
@parent.stubs(:vals).with(:parent).returns(nil)
@node.expects(:parameters=).with("one" => "two")
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should use the parent's environment if the node has none" do
@@ -161,7 +156,7 @@ describe Puppet::Node::Ldap do
@node.stubs(:parameters=)
@node.expects(:environment=).with("parent")
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should prefer the node's environment to the parent's" do
@@ -173,7 +168,7 @@ describe Puppet::Node::Ldap do
@node.stubs(:parameters=)
@node.expects(:environment=).with("child")
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should recursively look up parent information" do
@@ -188,7 +183,7 @@ describe Puppet::Node::Ldap do
@parent_parent.stubs(:vals).with(:parent).returns(nil)
@node.expects(:parameters=).with("one" => "two", "three" => "four", "five" => "six")
- @searcher.find("mynode")
+ @searcher.find(@request)
end
it "should not allow loops in parent declarations" do
@@ -197,7 +192,7 @@ describe Puppet::Node::Ldap do
@parent.stubs(:to_hash).returns("three" => "four")
@parent.stubs(:vals).with(:parent).returns([@name])
- proc { @searcher.find("mynode") }.should raise_error(ArgumentError)
+ proc { @searcher.find(@request) }.should raise_error(ArgumentError)
end
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/node/plain.rb b/spec/unit/indirector/node/plain.rb
index 943af52b4..a595998a1 100755
--- a/spec/unit/indirector/node/plain.rb
+++ b/spec/unit/indirector/node/plain.rb
@@ -13,12 +13,7 @@ describe Puppet::Node::Plain do
node = mock 'node'
Puppet::Node.expects(:new).with("mynode").returns(node)
node.expects(:fact_merge)
- @searcher.find("mynode")
- end
-
- it "should use the version of the facts as its version" do
- version = mock 'version'
- Puppet::Node::Facts.expects(:version).with("me").returns version
- @searcher.version("me").should equal(version)
+ request = stub 'request', :key => "mynode"
+ @searcher.find(request)
end
end
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/report/processor.rb b/spec/unit/indirector/report/processor.rb
index 587f512ee..bcb400bda 100755
--- a/spec/unit/indirector/report/processor.rb
+++ b/spec/unit/indirector/report/processor.rb
@@ -13,7 +13,6 @@ describe Puppet::Transaction::Report::Processor do
end
end
-
describe Puppet::Transaction::Report::Processor, " when saving a report" do
before do
Puppet.settings.stubs(:use)
@@ -24,7 +23,9 @@ describe Puppet::Transaction::Report::Processor, " when saving a report" do
Puppet::Reports.expects(:report).never
Puppet.settings.expects(:value).with(:reports).returns("none")
- @reporter.save(:whatever)
+ request = stub 'request', :instance => mock("report")
+
+ @reporter.save(request)
end
it "should process the report with each configured report type" do
@@ -44,6 +45,9 @@ describe Puppet::Transaction::Report::Processor, " when processing a report" do
@dup_report.stubs(:process)
@report = mock 'report'
@report.expects(:dup).returns(@dup_report)
+
+ @request = stub 'request', :instance => @report
+
Puppet::Reports.expects(:report).with("one").returns(@report_type)
@dup_report.expects(:extend).with(@report_type)
@@ -53,21 +57,21 @@ describe Puppet::Transaction::Report::Processor, " when processing a report" do
# make sense to split it out, which means I just do the same test
# three times so the spec looks right.
it "should process a duplicate of the report, not the original" do
- @reporter.save(@report)
+ @reporter.save(@request)
end
it "should extend the report with the report type's module" do
- @reporter.save(@report)
+ @reporter.save(@request)
end
it "should call the report type's :process method" do
@dup_report.expects(:process)
- @reporter.save(@report)
+ @reporter.save(@request)
end
it "should not raise exceptions" do
Puppet.settings.stubs(:value).with(:trace).returns(false)
@dup_report.expects(:process).raises(ArgumentError)
- proc { @reporter.save(@report) }.should_not raise_error
+ proc { @reporter.save(@request) }.should_not raise_error
end
end
diff --git a/spec/unit/indirector/request.rb b/spec/unit/indirector/request.rb
new file mode 100755
index 000000000..cdb40b181
--- /dev/null
+++ b/spec/unit/indirector/request.rb
@@ -0,0 +1,55 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/indirector/request'
+
+describe Puppet::Indirector::Request do
+ describe "when initializing" do
+ it "should require an indirection name, a key, and a method" do
+ lambda { Puppet::Indirector::Request.new }.should raise_error(ArgumentError)
+ end
+
+ it "should use provided value as the key if it is a string" do
+ 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, :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, :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, :method, :key, :one => :two) }.should_not raise_error(ArgumentError)
+ end
+
+ it "should support nil options" do
+ 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, :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, :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, :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, :method, :key)
+
+ request.indirection.should equal(ind)
+ end
+end
diff --git a/spec/unit/indirector/terminus.rb b/spec/unit/indirector/terminus.rb
index 86813e4e5..3fcbf9d0c 100755
--- a/spec/unit/indirector/terminus.rb
+++ b/spec/unit/indirector/terminus.rb
@@ -106,60 +106,6 @@ describe Puppet::Indirector::Terminus do
@terminus.model.should == :yay
end
end
-
- describe Puppet::Indirector::Terminus, " when managing indirected instances" do
-
- it "should support comparing an instance's version with the terminus's version using just the instance's key" do
- @terminus.should respond_to(:has_most_recent?)
- end
-
- it "should fail if the :version method has not been overridden and no :find method is available" do
- proc { @terminus.version('yay') }.should raise_error(Puppet::DevError)
- end
-
- it "should use a found instance's version by default" do
- name = 'instance'
- instance = stub name, :version => 2
- @terminus.expects(:find).with(name).returns(instance)
- @terminus.version(name).should == 2
- end
-
- it "should return nil as the version if no instance can be found" do
- name = 'instance'
- @terminus.expects(:find).with(name).returns(nil)
- @terminus.version(name).should be_nil
- end
-
- it "should consider an instance fresh if its version is more recent than the version provided" do
- name = "yay"
- @terminus.expects(:version).with(name).returns(5)
- @terminus.has_most_recent?(name, 4).should be_true
- end
-
- it "should consider an instance fresh if its version is equal to the version provided" do
- name = "yay"
- @terminus.expects(:version).with(name).returns(5)
- @terminus.has_most_recent?(name, 5).should be_true
- end
-
- it "should consider an instance not fresh if the provided version is more recent than its version" do
- name = "yay"
- @terminus.expects(:version).with(name).returns(4)
- @terminus.has_most_recent?(name, 5).should be_false
- end
-
- # Times annoyingly can't be compared directly to numbers, and our
- # default version is 0.
- it "should convert versions to floats when checking for freshness" do
- existing = mock 'existing version'
- new = mock 'new version'
- existing.expects(:to_f).returns(1.0)
- new.expects(:to_f).returns(1.0)
- name = "yay"
- @terminus.expects(:version).with(name).returns(existing)
- @terminus.has_most_recent?(name, new)
- end
- end
end
# LAK: This could reasonably be in the Indirection instances, too. It doesn't make
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/other/modules.rb b/spec/unit/module.rb
index 26ca3907d..06b2d016d 100755
--- a/spec/unit/other/modules.rb
+++ b/spec/unit/module.rb
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
-require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/../spec_helper'
describe Puppet::Module, " when building its search path" do
include PuppetTest
@@ -171,6 +171,15 @@ describe Puppet::Module, " when searching for manifests in a found module" do
Puppet::Module.find_manifests("mymod/yay/*.pp").should == %w{/one /two}
end
+ it "should not return directories" do
+ Puppet.settings.expects(:value).with(:modulepath, nil).returns("/my/modules")
+ File.stubs(:directory?).returns(true)
+ Dir.expects(:glob).with("/my/modules/mymod/manifests/yay/*.pp").returns(%w{/one /two})
+ FileTest.expects(:directory?).with("/one").returns false
+ FileTest.expects(:directory?).with("/two").returns true
+ Puppet::Module.find_manifests("mymod/yay/*.pp").should == %w{/one}
+ end
+
it "should default to the 'init.pp' file in the manifests directory" do
Puppet.settings.expects(:value).with(:modulepath, nil).returns("/my/modules")
File.stubs(:directory?).returns(true)
diff --git a/spec/unit/network/client/master.rb b/spec/unit/network/client/master.rb
index 7bf755d88..c0ad7562f 100755
--- a/spec/unit/network/client/master.rb
+++ b/spec/unit/network/client/master.rb
@@ -36,30 +36,6 @@ describe Puppet::Network::Client::Master, " when retrieving the catalog" do
proc { @client.getconfig }.should raise_error(Puppet::Network::ClientError)
end
- it "should use the cached catalog if it is up to date" do
- file = "/path/to/cachefile"
- @client.stubs(:cachefile).returns(file)
- FileTest.expects(:exist?).with(file).returns(true)
- @client.expects(:fresh?).with(@facts).returns true
- @client.class.stubs(:facts).returns(@facts)
- @client.expects(:use_cached_config).returns(true)
- Puppet.stubs(:info)
-
- @client.getconfig
- end
-
- it "should log that the catalog does not need a recompile" do
- file = "/path/to/cachefile"
- @client.stubs(:cachefile).returns(file)
- FileTest.stubs(:exist?).with(file).returns(true)
- @client.stubs(:fresh?).with(@facts).returns true
- @client.stubs(:use_cached_config).returns(true)
- @client.class.stubs(:facts).returns(@facts)
- Puppet.expects(:info).with { |m| m.include?("up to date") }
-
- @client.getconfig
- end
-
it "should retrieve plugins if :pluginsync is enabled" do
file = "/path/to/cachefile"
@client.stubs(:cachefile).returns(file)
@@ -69,7 +45,6 @@ describe Puppet::Network::Client::Master, " when retrieving the catalog" do
@client.expects(:getplugins)
@client.stubs(:get_actual_config).returns(nil)
FileTest.stubs(:exist?).with(file).returns(true)
- @client.stubs(:fresh?).with(@facts).returns true
@client.stubs(:use_cached_config).returns(true)
@client.class.stubs(:facts).returns(@facts)
@client.getconfig
diff --git a/spec/unit/node.rb b/spec/unit/node.rb
index bb99378d9..348e160cf 100755
--- a/spec/unit/node.rb
+++ b/spec/unit/node.rb
@@ -133,9 +133,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 d607b3540..8d7692442 100755
--- a/spec/unit/node/catalog.rb
+++ b/spec/unit/node/catalog.rb
@@ -794,14 +794,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/parser/ast/node.rb b/spec/unit/parser/ast/node.rb
index 757934415..aaba4c2e8 100755
--- a/spec/unit/parser/ast/node.rb
+++ b/spec/unit/parser/ast/node.rb
@@ -122,4 +122,4 @@ describe Puppet::Parser::AST::Node do
@compiler.class_scope(@middle).namespaces.should be_include(@top.namespace)
end
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/parser/resource.rb b/spec/unit/parser/resource.rb
index 776e9c742..6b2021916 100755
--- a/spec/unit/parser/resource.rb
+++ b/spec/unit/parser/resource.rb
@@ -64,6 +64,13 @@ describe Puppet::Parser::Resource do
@resource[:one].should == "yay"
end
+ it "should have a method for converting to a ral resource" do
+ trans = mock 'trans', :to_type => "yay"
+ @resource = mkresource
+ @resource.expects(:to_trans).returns trans
+ @resource.to_type.should == "yay"
+ end
+
describe "when initializing" do
before do
@arguments = {:type => "resource", :title => "testing", :scope => stub('scope', :source => mock('source'))}
diff --git a/spec/unit/ral/type/nagios.rb b/spec/unit/ral/type/nagios.rb
index 8aca7d401..35f00b0e5 100755
--- a/spec/unit/ral/type/nagios.rb
+++ b/spec/unit/ral/type/nagios.rb
@@ -4,51 +4,59 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/external/nagios'
-Nagios::Base.eachtype do |name, nagios_type|
- puppet_type = Puppet::Type.type("nagios_" + name.to_s)
+describe "Nagios resource types" do
+ Nagios::Base.eachtype do |name, nagios_type|
+ puppet_type = Puppet::Type.type("nagios_" + name.to_s)
- describe puppet_type do
- it "should be defined as a Puppet resource type" do
+ it "should have a valid type for #{name}" do
puppet_type.should_not be_nil
end
- it "should have documentation" do
- puppet_type.instance_variable_get("@doc").should_not == ""
- end
+ next unless puppet_type
- it "should have %s as its namevar" % nagios_type.namevar do
- puppet_type.namevar.should == nagios_type.namevar
- end
+ describe puppet_type do
+ it "should be defined as a Puppet resource type" do
+ puppet_type.should_not be_nil
+ end
- it "should have documentation for its %s parameter" % nagios_type.namevar do
- puppet_type.attrclass(nagios_type.namevar).instance_variable_get("@doc").should_not be_nil
- end
+ it "should have documentation" do
+ puppet_type.instance_variable_get("@doc").should_not == ""
+ end
- it "should have an ensure property" do
- puppet_type.should be_validproperty(:ensure)
- end
+ it "should have %s as its namevar" % nagios_type.namevar do
+ puppet_type.namevar.should == nagios_type.namevar
+ end
- it "should have a target property" do
- puppet_type.should be_validproperty(:target)
- end
+ it "should have documentation for its %s parameter" % nagios_type.namevar do
+ puppet_type.attrclass(nagios_type.namevar).instance_variable_get("@doc").should_not be_nil
+ end
- it "should have documentation for its target property" do
- puppet_type.attrclass(:target).instance_variable_get("@doc").should_not be_nil
- end
+ it "should have an ensure property" do
+ puppet_type.should be_validproperty(:ensure)
+ end
- nagios_type.parameters.reject { |param| param == nagios_type.namevar or param.to_s =~ /^[0-9]/ }.each do |param|
- it "should have a %s property" % param do
- puppet_type.should be_validproperty(param)
+ it "should have a target property" do
+ puppet_type.should be_validproperty(:target)
end
- it "should have documentation for its %s property" % param do
- puppet_type.attrclass(param).instance_variable_get("@doc").should_not be_nil
+ it "should have documentation for its target property" do
+ puppet_type.attrclass(:target).instance_variable_get("@doc").should_not be_nil
+ end
+
+ nagios_type.parameters.reject { |param| param == nagios_type.namevar or param.to_s =~ /^[0-9]/ }.each do |param|
+ it "should have a %s property" % param do
+ puppet_type.should be_validproperty(param)
+ end
+
+ it "should have documentation for its %s property" % param do
+ puppet_type.attrclass(param).instance_variable_get("@doc").should_not be_nil
+ end
end
- end
- nagios_type.parameters.find_all { |param| param.to_s =~ /^[0-9]/ }.each do |param|
- it "should have not have a %s property" % param do
- puppet_type.should_not be_validproperty(:param)
+ nagios_type.parameters.find_all { |param| param.to_s =~ /^[0-9]/ }.each do |param|
+ it "should have not have a %s property" % param do
+ puppet_type.should_not be_validproperty(:param)
+ end
end
end
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
diff --git a/spec/unit/util/loadedfile.rb b/spec/unit/util/loadedfile.rb
new file mode 100755
index 000000000..083120e20
--- /dev/null
+++ b/spec/unit/util/loadedfile.rb
@@ -0,0 +1,65 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'tempfile'
+require 'puppet/util/loadedfile'
+
+describe Puppet::Util::LoadedFile do
+ before(:each) do
+ @f = Tempfile.new('loadedfile_test')
+ @f.puts "yayness"
+ @f.flush
+
+ @loaded = Puppet::Util::LoadedFile.new(@f.path)
+
+ fake_ctime = Time.now - (2 * Puppet[:filetimeout])
+ @stat = stub('stat', :ctime => fake_ctime)
+ @fake_now = Time.now + (2 * Puppet[:filetimeout])
+ end
+
+ it "should recognize when the file has not changed" do
+ # Use fake "now" so that we can be sure changed? actually checks, without sleeping
+ # for Puppet[:filetimeout] seconds.
+ Time.stubs(:now).returns(@fake_now)
+ @loaded.changed?.should == false
+ end
+
+ it "should recognize when the file has changed" do
+ # Fake File.stat so we don't have to depend on the filesystem granularity. Doing a flush()
+ # just didn't do the job.
+ File.stubs(:stat).returns(@stat)
+ # Use fake "now" so that we can be sure changed? actually checks, without sleeping
+ # for Puppet[:filetimeout] seconds.
+ Time.stubs(:now).returns(@fake_now)
+ @loaded.changed?.should be_an_instance_of(Time)
+ end
+
+ it "should not catch a change until the timeout has elapsed" do
+ # Fake File.stat so we don't have to depend on the filesystem granularity. Doing a flush()
+ # just didn't do the job.
+ File.stubs(:stat).returns(@stat)
+ @loaded.changed?.should be(false)
+ # Use fake "now" so that we can be sure changed? actually checks, without sleeping
+ # for Puppet[:filetimeout] seconds.
+ Time.stubs(:now).returns(@fake_now)
+ @loaded.changed?.should_not be(false)
+ end
+
+ it "should consider a file changed when that file is missing" do
+ @f.close!
+ # Use fake "now" so that we can be sure changed? actually checks, without sleeping
+ # for Puppet[:filetimeout] seconds.
+ Time.stubs(:now).returns(@fake_now)
+ @loaded.changed?.should_not be(false)
+ end
+
+ it "should disable checking if Puppet[:filetimeout] is negative" do
+ Puppet[:filetimeout] = -1
+ @loaded.changed?.should_not be(false)
+ end
+
+ after(:each) do
+ @f.close
+ end
+end