summaryrefslogtreecommitdiffstats
path: root/spec/unit/indirector
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit/indirector')
-rwxr-xr-xspec/unit/indirector/catalog/compiler.rb24
-rwxr-xr-xspec/unit/indirector/catalog/yaml.rb12
-rwxr-xr-xspec/unit/indirector/certificate/ca.rb28
-rwxr-xr-xspec/unit/indirector/certificate/file.rb28
-rwxr-xr-xspec/unit/indirector/certificate/rest.rb15
-rwxr-xr-xspec/unit/indirector/certificate_request/ca.rb19
-rwxr-xr-xspec/unit/indirector/certificate_request/file.rb19
-rwxr-xr-xspec/unit/indirector/certificate_request/rest.rb15
-rwxr-xr-xspec/unit/indirector/certificate_revocation_list/ca.rb21
-rwxr-xr-xspec/unit/indirector/certificate_revocation_list/file.rb20
-rwxr-xr-xspec/unit/indirector/certificate_revocation_list/rest.rb15
-rwxr-xr-xspec/unit/indirector/direct_file_server.rb11
-rwxr-xr-xspec/unit/indirector/file.rb7
-rwxr-xr-xspec/unit/indirector/file_metadata/file.rb10
-rwxr-xr-xspec/unit/indirector/file_metadata/modules.rb4
-rwxr-xr-xspec/unit/indirector/file_server.rb57
-rwxr-xr-xspec/unit/indirector/indirection.rb42
-rwxr-xr-xspec/unit/indirector/key/ca.rb34
-rwxr-xr-xspec/unit/indirector/key/file.rb104
-rwxr-xr-xspec/unit/indirector/module_files.rb69
-rw-r--r--spec/unit/indirector/report/rest.rb11
-rwxr-xr-xspec/unit/indirector/request.rb63
-rwxr-xr-xspec/unit/indirector/rest.rb669
-rwxr-xr-xspec/unit/indirector/ssl_file.rb280
-rwxr-xr-xspec/unit/indirector/ssl_rsa/file.rb116
25 files changed, 1125 insertions, 568 deletions
diff --git a/spec/unit/indirector/catalog/compiler.rb b/spec/unit/indirector/catalog/compiler.rb
index 8cd3c72f4..29b76d8e5 100755
--- a/spec/unit/indirector/catalog/compiler.rb
+++ b/spec/unit/indirector/catalog/compiler.rb
@@ -7,7 +7,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/catalog/compiler'
-describe Puppet::Node::Catalog::Compiler do
+describe Puppet::Resource::Catalog::Compiler do
before do
Puppet.expects(:version).returns(1)
Facter.expects(:value).with('fqdn').returns("my.server.com")
@@ -15,11 +15,11 @@ describe Puppet::Node::Catalog::Compiler do
end
it "should gather data about itself" do
- Puppet::Node::Catalog::Compiler.new
+ Puppet::Resource::Catalog::Compiler.new
end
it "should cache the server metadata and reuse it" do
- compiler = Puppet::Node::Catalog::Compiler.new
+ compiler = Puppet::Resource::Catalog::Compiler.new
node1 = stub 'node1', :merge => nil
node2 = stub 'node2', :merge => nil
compiler.stubs(:compile)
@@ -31,16 +31,16 @@ describe Puppet::Node::Catalog::Compiler do
end
it "should provide a method for determining if the catalog is networked" do
- compiler = Puppet::Node::Catalog::Compiler.new
+ compiler = Puppet::Resource::Catalog::Compiler.new
compiler.should respond_to(:networked?)
end
end
-describe Puppet::Node::Catalog::Compiler, " when creating the interpreter" do
+describe Puppet::Resource::Catalog::Compiler, " when creating the interpreter" do
before do
# This gets pretty annoying on a plane where we have no IP address
Facter.stubs(:value).returns("whatever")
- @compiler = Puppet::Node::Catalog::Compiler.new
+ @compiler = Puppet::Resource::Catalog::Compiler.new
end
it "should not create the interpreter until it is asked for the first time" do
@@ -57,10 +57,10 @@ describe Puppet::Node::Catalog::Compiler, " when creating the interpreter" do
end
end
-describe Puppet::Node::Catalog::Compiler, " when finding nodes" do
+describe Puppet::Resource::Catalog::Compiler, " when finding nodes" do
before do
Facter.stubs(:value).returns("whatever")
- @compiler = Puppet::Node::Catalog::Compiler.new
+ @compiler = Puppet::Resource::Catalog::Compiler.new
@name = "me"
@node = mock 'node'
@request = stub 'request', :key => @name, :options => {}
@@ -74,12 +74,12 @@ describe Puppet::Node::Catalog::Compiler, " when finding nodes" do
end
end
-describe Puppet::Node::Catalog::Compiler, " after finding nodes" do
+describe Puppet::Resource::Catalog::Compiler, " after finding nodes" do
before do
Puppet.expects(:version).returns(1)
Facter.expects(:value).with('fqdn').returns("my.server.com")
Facter.expects(:value).with('ipaddress').returns("my.ip.address")
- @compiler = Puppet::Node::Catalog::Compiler.new
+ @compiler = Puppet::Resource::Catalog::Compiler.new
@name = "me"
@node = mock 'node'
@request = stub 'request', :key => @name, :options => {}
@@ -103,13 +103,13 @@ describe Puppet::Node::Catalog::Compiler, " after finding nodes" do
end
end
-describe Puppet::Node::Catalog::Compiler, " when creating catalogs" do
+describe Puppet::Resource::Catalog::Compiler, " when creating catalogs" do
before do
Facter.stubs(:value).returns("whatever")
env = stub 'environment', :name => "yay"
Puppet::Node::Environment.stubs(:new).returns(env)
- @compiler = Puppet::Node::Catalog::Compiler.new
+ @compiler = Puppet::Resource::Catalog::Compiler.new
@name = "me"
@node = Puppet::Node.new @name
@node.stubs(:merge)
diff --git a/spec/unit/indirector/catalog/yaml.rb b/spec/unit/indirector/catalog/yaml.rb
index 717fb816c..5f233c91c 100755
--- a/spec/unit/indirector/catalog/yaml.rb
+++ b/spec/unit/indirector/catalog/yaml.rb
@@ -2,24 +2,24 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
-require 'puppet/node/catalog'
+require 'puppet/resource/catalog'
require 'puppet/indirector/catalog/yaml'
-describe Puppet::Node::Catalog::Yaml do
+describe Puppet::Resource::Catalog::Yaml do
it "should be a subclass of the Yaml terminus" do
- Puppet::Node::Catalog::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
+ Puppet::Resource::Catalog::Yaml.superclass.should equal(Puppet::Indirector::Yaml)
end
it "should have documentation" do
- Puppet::Node::Catalog::Yaml.doc.should_not be_nil
+ Puppet::Resource::Catalog::Yaml.doc.should_not be_nil
end
it "should be registered with the catalog store indirection" do
indirection = Puppet::Indirector::Indirection.instance(:catalog)
- Puppet::Node::Catalog::Yaml.indirection.should equal(indirection)
+ Puppet::Resource::Catalog::Yaml.indirection.should equal(indirection)
end
it "should have its name set to :yaml" do
- Puppet::Node::Catalog::Yaml.name.should == :yaml
+ Puppet::Resource::Catalog::Yaml.name.should == :yaml
end
end
diff --git a/spec/unit/indirector/certificate/ca.rb b/spec/unit/indirector/certificate/ca.rb
new file mode 100755
index 000000000..0158a8d90
--- /dev/null
+++ b/spec/unit/indirector/certificate/ca.rb
@@ -0,0 +1,28 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-7.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/certificate/ca'
+
+describe Puppet::SSL::Certificate::Ca do
+ it "should have documentation" do
+ Puppet::SSL::Certificate::Ca.doc.should be_instance_of(String)
+ end
+
+ it "should use the :signeddir as the collection directory" do
+ Puppet.settings.expects(:value).with(:signeddir).returns "/cert/dir"
+ Puppet::SSL::Certificate::Ca.collection_directory.should == "/cert/dir"
+ end
+
+ it "should store the ca certificate at the :cacert location" do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert"
+ file = Puppet::SSL::Certificate::Ca.new
+ file.stubs(:ca?).returns true
+ file.path("whatever").should == "/ca/cert"
+ end
+end
diff --git a/spec/unit/indirector/certificate/file.rb b/spec/unit/indirector/certificate/file.rb
new file mode 100755
index 000000000..6fb00f1ca
--- /dev/null
+++ b/spec/unit/indirector/certificate/file.rb
@@ -0,0 +1,28 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-7.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/certificate/file'
+
+describe Puppet::SSL::Certificate::File do
+ it "should have documentation" do
+ Puppet::SSL::Certificate::File.doc.should be_instance_of(String)
+ end
+
+ it "should use the :certdir as the collection directory" do
+ Puppet.settings.expects(:value).with(:certdir).returns "/cert/dir"
+ Puppet::SSL::Certificate::File.collection_directory.should == "/cert/dir"
+ end
+
+ it "should store the ca certificate at the :localcacert location" do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:localcacert).returns "/ca/cert"
+ file = Puppet::SSL::Certificate::File.new
+ file.stubs(:ca?).returns true
+ file.path("whatever").should == "/ca/cert"
+ end
+end
diff --git a/spec/unit/indirector/certificate/rest.rb b/spec/unit/indirector/certificate/rest.rb
new file mode 100755
index 000000000..62b1ef543
--- /dev/null
+++ b/spec/unit/indirector/certificate/rest.rb
@@ -0,0 +1,15 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/certificate/rest'
+
+describe Puppet::SSL::Certificate::Rest do
+ before do
+ @searcher = Puppet::SSL::Certificate::Rest.new
+ end
+
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::SSL::Certificate::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
+end
diff --git a/spec/unit/indirector/certificate_request/ca.rb b/spec/unit/indirector/certificate_request/ca.rb
new file mode 100755
index 000000000..b35d8b474
--- /dev/null
+++ b/spec/unit/indirector/certificate_request/ca.rb
@@ -0,0 +1,19 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-7.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/certificate_request/ca'
+
+describe Puppet::SSL::CertificateRequest::Ca do
+ it "should have documentation" do
+ Puppet::SSL::CertificateRequest::Ca.doc.should be_instance_of(String)
+ end
+
+ it "should use the :csrdir as the collection directory" do
+ Puppet.settings.expects(:value).with(:csrdir).returns "/request/dir"
+ Puppet::SSL::CertificateRequest::Ca.collection_directory.should == "/request/dir"
+ end
+end
diff --git a/spec/unit/indirector/certificate_request/file.rb b/spec/unit/indirector/certificate_request/file.rb
new file mode 100755
index 000000000..e1f442e2a
--- /dev/null
+++ b/spec/unit/indirector/certificate_request/file.rb
@@ -0,0 +1,19 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-7.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/certificate_request/file'
+
+describe Puppet::SSL::CertificateRequest::File do
+ it "should have documentation" do
+ Puppet::SSL::CertificateRequest::File.doc.should be_instance_of(String)
+ end
+
+ it "should use the :requestdir as the collection directory" do
+ Puppet.settings.expects(:value).with(:requestdir).returns "/request/dir"
+ Puppet::SSL::CertificateRequest::File.collection_directory.should == "/request/dir"
+ end
+end
diff --git a/spec/unit/indirector/certificate_request/rest.rb b/spec/unit/indirector/certificate_request/rest.rb
new file mode 100755
index 000000000..cbd525f17
--- /dev/null
+++ b/spec/unit/indirector/certificate_request/rest.rb
@@ -0,0 +1,15 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/certificate_request/rest'
+
+describe Puppet::SSL::CertificateRequest::Rest do
+ before do
+ @searcher = Puppet::SSL::CertificateRequest::Rest.new
+ end
+
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::SSL::CertificateRequest::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
+end
diff --git a/spec/unit/indirector/certificate_revocation_list/ca.rb b/spec/unit/indirector/certificate_revocation_list/ca.rb
new file mode 100755
index 000000000..f6da86861
--- /dev/null
+++ b/spec/unit/indirector/certificate_revocation_list/ca.rb
@@ -0,0 +1,21 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-7.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/certificate_revocation_list/ca'
+
+describe Puppet::SSL::CertificateRevocationList::Ca do
+ it "should have documentation" do
+ Puppet::SSL::CertificateRevocationList::Ca.doc.should be_instance_of(String)
+ end
+
+ it "should use the :cacrl setting as the crl location" do
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).with(:cacrl).returns "/request/dir"
+ Puppet::SSL::CertificateRevocationList::Ca.new.path("whatever").should == "/request/dir"
+ end
+end
diff --git a/spec/unit/indirector/certificate_revocation_list/file.rb b/spec/unit/indirector/certificate_revocation_list/file.rb
new file mode 100755
index 000000000..5db4f8c06
--- /dev/null
+++ b/spec/unit/indirector/certificate_revocation_list/file.rb
@@ -0,0 +1,20 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-7.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/certificate_revocation_list/file'
+
+describe Puppet::SSL::CertificateRevocationList::File do
+ it "should have documentation" do
+ Puppet::SSL::CertificateRevocationList::File.doc.should be_instance_of(String)
+ end
+
+ it "should always store the file to :hostcrl location" do
+ Puppet.settings.expects(:value).with(:hostcrl).returns "/host/crl"
+ Puppet.settings.stubs(:use)
+ Puppet::SSL::CertificateRevocationList::File.file_location.should == "/host/crl"
+ end
+end
diff --git a/spec/unit/indirector/certificate_revocation_list/rest.rb b/spec/unit/indirector/certificate_revocation_list/rest.rb
new file mode 100755
index 000000000..f6f493c37
--- /dev/null
+++ b/spec/unit/indirector/certificate_revocation_list/rest.rb
@@ -0,0 +1,15 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/certificate_revocation_list/rest'
+
+describe Puppet::SSL::CertificateRevocationList::Rest do
+ before do
+ @searcher = Puppet::SSL::CertificateRevocationList::Rest.new
+ end
+
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::SSL::CertificateRevocationList::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
+end
diff --git a/spec/unit/indirector/direct_file_server.rb b/spec/unit/indirector/direct_file_server.rb
index 0753f1bbe..e32fe6678 100755
--- a/spec/unit/indirector/direct_file_server.rb
+++ b/spec/unit/indirector/direct_file_server.rb
@@ -24,7 +24,7 @@ describe Puppet::Indirector::DirectFileServer do
@uri = "file:///my/local"
- @request = stub 'request', :key => @uri, :options => {}
+ @request = Puppet::Indirector::Request.new(:mytype, :find, @uri)
end
describe Puppet::Indirector::DirectFileServer, "when finding a single file" do
@@ -45,17 +45,12 @@ describe Puppet::Indirector::DirectFileServer do
before do
@data = mock 'content'
- @data.stubs(:collect_attributes)
+ @data.stubs(:collect)
FileTest.expects(:exists?).with("/my/local").returns true
end
- 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(@request)
- end
-
it "should pass the full path to the instance" do
- @model.expects(:new).with { |key, options| options[:path] == "/my/local" }.returns(@data)
+ @model.expects(:new).with { |key, options| key == "/my/local" }.returns(@data)
@server.find(@request)
end
diff --git a/spec/unit/indirector/file.rb b/spec/unit/indirector/file.rb
index 67ead4cdb..d64ed9f57 100755
--- a/spec/unit/indirector/file.rb
+++ b/spec/unit/indirector/file.rb
@@ -140,6 +140,13 @@ describe Puppet::Indirector::File do
proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)
end
+ it "should log that is removing the file" do
+ File.expects(:exist?).returns(true)
+ File.expects(:unlink)
+ Puppet.expects(:notice)
+ @searcher.destroy(@request)
+ end
+
it "should use the path() method to calculate the path if it exists" do
@searcher.meta_def(:path) do |thing|
thing.to_s.upcase
diff --git a/spec/unit/indirector/file_metadata/file.rb b/spec/unit/indirector/file_metadata/file.rb
index 9474620c7..a096d469d 100755
--- a/spec/unit/indirector/file_metadata/file.rb
+++ b/spec/unit/indirector/file_metadata/file.rb
@@ -21,14 +21,14 @@ describe Puppet::Indirector::FileMetadata::File do
@metadata = Puppet::Indirector::FileMetadata::File.new
@uri = "file:///my/local"
@data = mock 'metadata'
- @data.stubs(:collect_attributes)
+ @data.stubs(:collect)
FileTest.expects(:exists?).with("/my/local").returns true
- @request = stub 'request', :key => @uri, :options => {}
+ @request = Puppet::Indirector::Request.new(:file_metadata, :find, @uri)
end
it "should collect its attributes when a file is found" do
- @data.expects(:collect_attributes)
+ @data.expects(:collect)
Puppet::FileServing::Metadata.expects(:new).returns(@data)
@metadata.find(@request).should == @data
@@ -40,12 +40,12 @@ describe Puppet::Indirector::FileMetadata::File do
@metadata = Puppet::Indirector::FileMetadata::File.new
@uri = "file:///my/local"
- @request = stub 'request', :key => @uri, :options => {}
+ @request = Puppet::Indirector::Request.new(:file_metadata, :find, @uri)
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.expects(:path2instances).returns( [mock("one", :collect => nil), mock("two", :collect => nil)] )
@metadata.search(@request)
end
end
diff --git a/spec/unit/indirector/file_metadata/modules.rb b/spec/unit/indirector/file_metadata/modules.rb
index 3905a49ad..7e5113df5 100755
--- a/spec/unit/indirector/file_metadata/modules.rb
+++ b/spec/unit/indirector/file_metadata/modules.rb
@@ -24,7 +24,7 @@ describe Puppet::Indirector::FileMetadata::Modules, " when finding metadata" do
@module = Puppet::Module.new("mymod", "/path/to")
@finder.stubs(:find_module).returns(@module)
- @request = Puppet::Indirector::Request.new(:metadata, :find, "puppetmounts://hostname/modules/mymod/my/file")
+ @request = Puppet::Indirector::Request.new(:metadata, :find, "puppet://hostname/modules/mymod/my/file")
end
it "should return nil if the file is not found" do
@@ -36,7 +36,7 @@ describe Puppet::Indirector::FileMetadata::Modules, " when finding metadata" do
FileTest.expects(:exists?).with("/path/to/files/my/file").returns true
instance = mock 'metadta'
Puppet::FileServing::Metadata.expects(:new).returns instance
- instance.expects :collect_attributes
+ instance.expects :collect
@finder.find(@request)
end
end
diff --git a/spec/unit/indirector/file_server.rb b/spec/unit/indirector/file_server.rb
index ba951737a..e17deecf9 100755
--- a/spec/unit/indirector/file_server.rb
+++ b/spec/unit/indirector/file_server.rb
@@ -24,7 +24,7 @@ describe Puppet::Indirector::FileServer do
@file_server = @file_server_class.new
- @uri = "puppetmounts://host/my/local/file"
+ @uri = "puppet://host/my/local/file"
@configuration = mock 'configuration'
Puppet::FileServing::Configuration.stubs(:create).returns(@configuration)
@@ -34,46 +34,42 @@ describe Puppet::Indirector::FileServer do
describe Puppet::Indirector::FileServer, " when finding files" do
it "should use the path portion of the URI as the file name" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @configuration.expects(:file_path).with("my/local/file", :node => nil)
@file_server.find(@request)
end
it "should use the FileServing configuration to convert the file name to a fully qualified path" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @configuration.expects(:file_path).with("my/local/file", :node => nil)
@file_server.find(@request)
end
it "should pass the node name to the FileServing configuration if one is provided" do
- @configuration.expects(:file_path).with("/my/local/file", :node => "testing")
+ @configuration.expects(:file_path).with("my/local/file", :node => "testing")
@request.node = "testing"
@file_server.find(@request)
end
it "should return nil if no fully qualified path is found" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns(nil)
+ @configuration.expects(:file_path).with("my/local/file", :node => nil).returns(nil)
@file_server.find(@request).should be_nil
end
it "should return an instance of the model created with the full path if a file is found" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/some/file")
- @model.expects(:new).returns(:myinstance)
- @file_server.find(@request).should == :myinstance
+ @configuration.expects(:file_path).with("my/local/file", :node => nil).returns("/some/file")
+ instance = stub("instance", :collect => nil)
+ @model.expects(:new).returns instance
+ @file_server.find(@request).should equal(instance)
end
end
describe Puppet::Indirector::FileServer, " when returning instances" do
before :each do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/some/file")
- @instance = mock 'instance'
- end
-
- it "should create the instance with the key used to find the instance" do
- @model.expects(:new).with { |key, *options| key == @uri }
- @file_server.find(@request)
+ @configuration.expects(:file_path).with("my/local/file", :node => nil).returns("/some/file")
+ @instance = stub 'instance', :collect => nil
end
it "should create the instance with the path at which the instance was found" do
- @model.expects(:new).with { |key, options| options[:path] == "/some/file" }
+ @model.expects(:new).with { |key, options| key == "/some/file" }.returns @instance
@file_server.find(@request)
end
@@ -88,6 +84,12 @@ describe Puppet::Indirector::FileServer do
@model.expects(:new).returns(@instance)
@file_server.find(@request)
end
+
+ it "should collect each instance's attributes before returning" do
+ @instance.expects(:collect)
+ @model.expects(:new).returns @instance
+ @file_server.find(@request)
+ end
end
describe Puppet::Indirector::FileServer, " when checking authorization" do
@@ -108,7 +110,6 @@ describe Puppet::Indirector::FileServer do
describe "and finding file information" do
before do
- @request.key = "puppetmounts://host/my/file"
@request.method = :find
end
@@ -118,7 +119,7 @@ describe Puppet::Indirector::FileServer do
end
it "should pass the file path from the URI to the file server configuration" do
- @configuration.expects(:authorized?).with { |uri, *args| uri == "/my/file" }
+ @configuration.expects(:authorized?).with { |uri, *args| uri == "my/local/file" }
@file_server.authorized?(@request)
end
@@ -149,36 +150,42 @@ describe Puppet::Indirector::FileServer do
describe Puppet::Indirector::FileServer, " when searching for files" do
it "should use the path portion of the URI as the file name" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @configuration.expects(:file_path).with("my/local/file", :node => nil)
@file_server.search(@request)
end
it "should use the FileServing configuration to convert the file name to a fully qualified path" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @configuration.expects(:file_path).with("my/local/file", :node => nil)
@file_server.search(@request)
end
it "should pass the node name to the FileServing configuration if one is provided" do
- @configuration.expects(:file_path).with("/my/local/file", :node => "testing")
+ @configuration.expects(:file_path).with("my/local/file", :node => "testing")
@request.node = "testing"
@file_server.search(@request)
end
it "should return nil if no fully qualified path is found" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns(nil)
+ @configuration.expects(:file_path).with("my/local/file", :node => nil).returns(nil)
@file_server.search(@request).should be_nil
end
it "should use :path2instances from the terminus_helper to return instances if a module is found and the file exists" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/my/file")
+ @configuration.expects(:file_path).with("my/local/file", :node => nil).returns("my/file")
@file_server.expects(:path2instances)
@file_server.search(@request)
end
it "should pass the request on to :path2instances" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/my/file")
- @file_server.expects(:path2instances).with(@request, "/my/file")
+ @configuration.expects(:file_path).with("my/local/file", :node => nil).returns("my/file")
+ @file_server.expects(:path2instances).with(@request, "my/file").returns []
@file_server.search(@request)
end
+
+ it "should return the result of :path2instances" do
+ @configuration.expects(:file_path).with("my/local/file", :node => nil).returns("my/file")
+ @file_server.expects(:path2instances).with(@request, "my/file").returns :footest
+ @file_server.search(@request).should == :footest
+ end
end
end
diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb
index 5d4539e95..564b2d871 100755
--- a/spec/unit/indirector/indirection.rb
+++ b/spec/unit/indirector/indirection.rb
@@ -34,6 +34,22 @@ describe "Indirection Delegator", :shared => true do
@indirection.send(@method, "me")
end
+ it "should fail if the :select_terminus hook does not return a terminus name" 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 nil
+
+ lambda { @indirection.send(@method, "me") }.should raise_error(ArgumentError)
+ end
+
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
@@ -87,6 +103,9 @@ describe "Delegation Authorizer", :shared => true do
end
describe Puppet::Indirector::Indirection do
+ after do
+ Puppet::Util::Cacher.expire
+ end
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
@@ -494,7 +513,7 @@ describe Puppet::Indirector::Indirection do
after :each do
@indirection.delete
- Puppet::Indirector::Indirection.clear_cache
+ Puppet::Util::Cacher.expire
end
end
@@ -615,15 +634,6 @@ describe Puppet::Indirector::Indirection do
@indirection.terminus(:foo).should equal(@terminus)
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
-
# 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)
@@ -638,7 +648,6 @@ describe Puppet::Indirector::Indirection do
after do
@indirection.delete
- Puppet::Indirector::Indirection.clear_cache
end
end
@@ -675,7 +684,6 @@ describe Puppet::Indirector::Indirection do
after do
@indirection.delete
- Puppet::Indirector::Indirection.clear_cache
end
end
@@ -706,15 +714,6 @@ describe Puppet::Indirector::Indirection do
@indirection.cache.should equal(@cache)
@indirection.cache.should equal(@cache)
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)
- end
end
describe "and saving" do
@@ -725,7 +724,6 @@ describe Puppet::Indirector::Indirection do
after :each do
@indirection.delete
- Puppet::Indirector::Indirection.clear_cache
end
end
end
diff --git a/spec/unit/indirector/key/ca.rb b/spec/unit/indirector/key/ca.rb
new file mode 100755
index 000000000..579617f71
--- /dev/null
+++ b/spec/unit/indirector/key/ca.rb
@@ -0,0 +1,34 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-7.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/key/ca'
+
+describe Puppet::SSL::Key::Ca do
+ it "should have documentation" do
+ Puppet::SSL::Key::Ca.doc.should be_instance_of(String)
+ end
+
+ it "should store the ca key at the :cakey location" do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:cakey).returns "/ca/key"
+ file = Puppet::SSL::Key::Ca.new
+ file.stubs(:ca?).returns true
+ file.path("whatever").should == "/ca/key"
+ end
+
+ describe "when choosing the path for the public key" do
+ it "should fail if the key is not for the CA" do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:cakey).returns "/ca/key"
+ file = Puppet::SSL::Key::Ca.new
+ file.stubs(:ca?).returns false
+ lambda { file.path("whatever") }.should raise_error(ArgumentError)
+ end
+ end
+end
diff --git a/spec/unit/indirector/key/file.rb b/spec/unit/indirector/key/file.rb
new file mode 100755
index 000000000..8a1cb04bd
--- /dev/null
+++ b/spec/unit/indirector/key/file.rb
@@ -0,0 +1,104 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-7.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/key/file'
+
+describe Puppet::SSL::Key::File do
+ it "should have documentation" do
+ Puppet::SSL::Key::File.doc.should be_instance_of(String)
+ end
+
+ it "should use the :privatekeydir as the collection directory" do
+ Puppet.settings.expects(:value).with(:privatekeydir).returns "/key/dir"
+ Puppet::SSL::Key::File.collection_directory.should == "/key/dir"
+ end
+
+ it "should store the ca key at the :cakey location" do
+ Puppet.settings.stubs(:use)
+ Puppet.settings.stubs(:value).returns "whatever"
+ Puppet.settings.stubs(:value).with(:cakey).returns "/ca/key"
+ file = Puppet::SSL::Key::File.new
+ file.stubs(:ca?).returns true
+ file.path("whatever").should == "/ca/key"
+ end
+
+ describe "when choosing the path for the public key" do
+ it "should use the :capub setting location if the key is for the certificate authority" do
+ Puppet.settings.stubs(:value).returns "/fake/dir"
+ Puppet.settings.stubs(:value).with(:capub).returns "/ca/pubkey"
+ Puppet.settings.stubs(:use)
+
+ @searcher = Puppet::SSL::Key::File.new
+ @searcher.stubs(:ca?).returns true
+ @searcher.public_key_path("whatever").should == "/ca/pubkey"
+ end
+
+ it "should use the host name plus '.pem' in :publickeydir for normal hosts" do
+ Puppet.settings.stubs(:value).with(:privatekeydir).returns "/private/key/dir"
+ Puppet.settings.stubs(:value).with(:publickeydir).returns "/public/key/dir"
+ Puppet.settings.stubs(:use)
+
+ @searcher = Puppet::SSL::Key::File.new
+ @searcher.stubs(:ca?).returns false
+ @searcher.public_key_path("whatever").should == "/public/key/dir/whatever.pem"
+ end
+ end
+
+ describe "when managing private keys" do
+ before do
+ @searcher = Puppet::SSL::Key::File.new
+
+ @private_key_path = File.join("/fake/key/path")
+ @public_key_path = File.join("/other/fake/key/path")
+
+ @searcher.stubs(:public_key_path).returns @public_key_path
+ @searcher.stubs(:path).returns @private_key_path
+
+ FileTest.stubs(:directory?).returns true
+ FileTest.stubs(:writable?).returns true
+
+ @public_key = stub 'public_key'
+ @real_key = stub 'sslkey', :public_key => @public_key
+
+ @key = stub 'key', :name => "myname", :content => @real_key
+
+ @request = stub 'request', :key => "myname", :instance => @key
+ end
+
+ it "should save the public key when saving the private key" do
+ File.stubs(:open).with(@private_key_path, "w")
+
+ fh = mock 'filehandle'
+
+ File.expects(:open).with(@public_key_path, "w").yields fh
+ @public_key.expects(:to_pem).returns "my pem"
+
+ fh.expects(:print).with "my pem"
+
+ @searcher.save(@request)
+ end
+
+ it "should destroy the public key when destroying the private key" do
+ File.stubs(:unlink).with(@private_key_path)
+ FileTest.stubs(:exist?).with(@private_key_path).returns true
+ FileTest.expects(:exist?).with(@public_key_path).returns true
+ File.expects(:unlink).with(@public_key_path)
+
+ @searcher.destroy(@request)
+ end
+
+ it "should not fail if the public key does not exist when deleting the private key" do
+ File.stubs(:unlink).with(@private_key_path)
+
+ FileTest.stubs(:exist?).with(@private_key_path).returns true
+ FileTest.expects(:exist?).with(@public_key_path).returns false
+ File.expects(:unlink).with(@public_key_path).never
+
+ @searcher.destroy(@request)
+ end
+ end
+end
diff --git a/spec/unit/indirector/module_files.rb b/spec/unit/indirector/module_files.rb
index 32dedd4f1..f5f9527df 100755
--- a/spec/unit/indirector/module_files.rb
+++ b/spec/unit/indirector/module_files.rb
@@ -25,49 +25,47 @@ describe Puppet::Indirector::ModuleFiles do
@module_files = @module_files_class.new
- @uri = "puppetmounts://host/modules/my/local/file"
@module = Puppet::Module.new("mymod", "/module/path")
- @request = stub 'request', :key => @uri, :options => {}, :node => nil, :ip => nil, :method => :find
+ @request = Puppet::Indirector::Request.new(:mytype, :find, "puppet://host/modules/mymod/local/file")
end
describe Puppet::Indirector::ModuleFiles, " when finding files" do
+ before do
+ Puppet::Module.stubs(:find).returns @module
+ end
- it "should strip off the leading '/modules' mount name" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ it "should strip off the leading 'modules/' mount name" do
+ Puppet::Module.expects(:find).with { |key, env| key == 'mymod' }.returns @module
@module_files.find(@request)
end
- it "should not strip off leading terms that start with '/modules' but are longer words" do
- @request.stubs(:key).returns "puppetmounts://host/modulestart/my/local/file"
- Puppet::Module.expects(:find).with('modulestart', "myenv").returns nil
+ it "should not strip off leading terms that start with 'modules' but are longer words" do
+ @request.stubs(:key).returns "modulestart/mymod/local/file"
+ Puppet::Module.expects(:find).with { |key, env| key == 'modulestart'}.returns nil
@module_files.find(@request)
end
it "should search for a module whose name is the first term in the remaining file path" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
@module_files.find(@request)
end
it "should search for a file relative to the module's files directory" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
FileTest.expects(:exists?).with("/module/path/files/local/file")
@module_files.find(@request)
end
it "should return nil if the module does not exist" do
- Puppet::Module.expects(:find).with('my', "myenv").returns nil
+ Puppet::Module.expects(:find).returns nil
@module_files.find(@request).should be_nil
end
it "should return nil if the module exists but the file does not" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
FileTest.expects(:exists?).with("/module/path/files/local/file").returns(false)
@module_files.find(@request).should be_nil
end
it "should return an instance of the model if a module is found and the file exists" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
@model.expects(:new).returns(:myinstance)
@module_files.find(@request).should == :myinstance
@@ -76,7 +74,7 @@ describe Puppet::Indirector::ModuleFiles do
it "should use the node's environment to look up the module if the node name is provided" do
node = stub "node", :environment => "testing"
Puppet::Node.expects(:find).with("mynode").returns(node)
- Puppet::Module.expects(:find).with('my', "testing")
+ Puppet::Module.expects(:find).with('mymod', "testing")
@request.stubs(:node).returns "mynode"
@module_files.find(@request)
@@ -85,7 +83,7 @@ describe Puppet::Indirector::ModuleFiles do
it "should use the default environment setting to look up the module if the node name is not provided" do
env = stub "environment", :name => "testing"
Puppet::Node::Environment.stubs(:new).returns(env)
- Puppet::Module.expects(:find).with('my', "testing")
+ Puppet::Module.expects(:find).with('mymod', "testing")
@module_files.find(@request)
end
end
@@ -93,18 +91,13 @@ describe Puppet::Indirector::ModuleFiles do
describe Puppet::Indirector::ModuleFiles, " when returning instances" do
before do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ Puppet::Module.expects(:find).with('mymod', "myenv").returns @module
FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
@instance = mock 'instance'
end
- it "should create the instance with the key used to find the instance" do
- @model.expects(:new).with { |key, *options| key == @uri }
- @module_files.find(@request)
- end
-
it "should create the instance with the path at which the instance was found" do
- @model.expects(:new).with { |key, options| options[:path] == "/module/path/files/local/file" }
+ @model.expects(:new).with { |key, options| key == "/module/path/files/local/file" }
@module_files.find(@request)
end
@@ -149,19 +142,19 @@ describe Puppet::Indirector::ModuleFiles do
end
it "should use the path directly from the URI if it already includes /modules" do
- @request.expects(:key).returns "puppetmounts://host/modules/my/file"
- @configuration.expects(:authorized?).with { |uri, *args| uri == "/modules/my/file" }
+ @request.expects(:key).returns "modules/my/file"
+ @configuration.expects(:authorized?).with { |uri, *args| uri == "modules/my/file" }
@module_files.authorized?(@request)
end
- it "should add /modules to the file path if it's not included in the URI" do
- @request.expects(:key).returns "puppetmounts://host/my/file"
- @configuration.expects(:authorized?).with { |uri, *args| uri == "/modules/my/file" }
+ it "should add modules/ to the file path if it's not included in the URI" do
+ @request.expects(:key).returns "my/file"
+ @configuration.expects(:authorized?).with { |uri, *args| uri == "modules/my/file" }
@module_files.authorized?(@request)
end
it "should pass the node name to the file server configuration" do
- @request.expects(:key).returns "puppetmounts://host/my/file"
+ @request.expects(:key).returns "my/file"
@configuration.expects(:authorized?).with { |key, options| options[:node] == "mynode" }
@request.stubs(:node).returns "mynode"
@module_files.authorized?(@request)
@@ -186,41 +179,41 @@ describe Puppet::Indirector::ModuleFiles do
describe Puppet::Indirector::ModuleFiles, " when searching for files" do
- it "should strip off the leading '/modules' mount name" do
+ it "should strip off the leading 'modules/' mount name" do
Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ Puppet::Module.expects(:find).with { |key, env| key == 'mymod'}.returns @module
@module_files.search(@request)
end
it "should not strip off leading terms that start with '/modules' but are longer words" do
Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
Puppet::Module.expects(:find).with('modulestart', "myenv").returns nil
- @request.stubs(:key).returns "puppetmounts://host/modulestart/my/local/file"
+ @request.stubs(:key).returns "modulestart/my/local/file"
@module_files.search @request
end
it "should search for a module whose name is the first term in the remaining file path" do
Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ Puppet::Module.expects(:find).with('mymod', "myenv").returns @module
@module_files.search(@request)
end
it "should search for a file relative to the module's files directory" do
Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ Puppet::Module.expects(:find).with('mymod', "myenv").returns @module
FileTest.expects(:exists?).with("/module/path/files/local/file")
@module_files.search(@request)
end
it "should return nil if the module does not exist" do
Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns nil
+ Puppet::Module.expects(:find).with('mymod', "myenv").returns nil
@module_files.search(@request).should be_nil
end
it "should return nil if the module exists but the file does not" do
Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ Puppet::Module.expects(:find).with('mymod', "myenv").returns @module
FileTest.expects(:exists?).with("/module/path/files/local/file").returns(false)
@module_files.search(@request).should be_nil
end
@@ -228,7 +221,7 @@ describe Puppet::Indirector::ModuleFiles do
it "should use the node's environment to look up the module if the node name is provided" do
node = stub "node", :environment => "testing"
Puppet::Node.expects(:find).with("mynode").returns(node)
- Puppet::Module.expects(:find).with('my', "testing")
+ Puppet::Module.expects(:find).with('mymod', "testing")
@request.stubs(:node).returns "mynode"
@module_files.search(@request)
end
@@ -236,13 +229,13 @@ describe Puppet::Indirector::ModuleFiles do
it "should use the default environment setting to look up the module if the node name is not provided and the environment is not set to ''" do
env = stub 'env', :name => "testing"
Puppet::Node::Environment.stubs(:new).returns(env)
- Puppet::Module.expects(:find).with('my', "testing")
+ Puppet::Module.expects(:find).with('mymod', "testing")
@module_files.search(@request)
end
it "should use :path2instances from the terminus_helper to return instances if a module is found and the file exists" do
Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ Puppet::Module.expects(:find).with('mymod', "myenv").returns @module
FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
@module_files.expects(:path2instances).with(@request, "/module/path/files/local/file")
@module_files.search(@request)
@@ -250,7 +243,7 @@ describe Puppet::Indirector::ModuleFiles do
it "should pass the request directly to :path2instances" do
Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ Puppet::Module.expects(:find).with('mymod', "myenv").returns @module
FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
@module_files.expects(:path2instances).with(@request, "/module/path/files/local/file")
@module_files.search(@request)
diff --git a/spec/unit/indirector/report/rest.rb b/spec/unit/indirector/report/rest.rb
new file mode 100644
index 000000000..a51ebca2a
--- /dev/null
+++ b/spec/unit/indirector/report/rest.rb
@@ -0,0 +1,11 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/report/rest'
+
+describe Puppet::Transaction::Report::Rest do
+ it "should be a sublcass of Puppet::Indirector::REST" do
+ Puppet::Transaction::Report::Rest.superclass.should equal(Puppet::Indirector::REST)
+ end
+end
diff --git a/spec/unit/indirector/request.rb b/spec/unit/indirector/request.rb
index f7702f821..18f625946 100755
--- a/spec/unit/indirector/request.rb
+++ b/spec/unit/indirector/request.rb
@@ -75,6 +75,57 @@ describe Puppet::Indirector::Request do
it "should keep its options as a hash even if another option is specified" do
Puppet::Indirector::Request.new(:ind, :method, :key, :foo => "bar").options.should be_instance_of(Hash)
end
+
+ describe "and the request key is a URI" do
+ describe "and the URI is a 'file' URI" do
+ before do
+ @request = Puppet::Indirector::Request.new(:ind, :method, "file:///my/file")
+ end
+
+ it "should set the request key to the full file path" do @request.key.should == "/my/file" end
+
+ it "should not set the protocol" do
+ @request.protocol.should be_nil
+ end
+
+ it "should not set the port" do
+ @request.port.should be_nil
+ end
+
+ it "should not set the server" do
+ @request.server.should be_nil
+ end
+ end
+
+ it "should set the protocol to the URI scheme" do
+ Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff").protocol.should == "http"
+ end
+
+ it "should set the server if a server is provided" do
+ Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff").server.should == "host"
+ end
+
+ it "should set the server and port if both are provided" do
+ Puppet::Indirector::Request.new(:ind, :method, "http://host:543/stuff").port.should == 543
+ end
+
+ it "should default to the masterport if the URI scheme is 'puppet'" do
+ Puppet.settings.expects(:value).with(:masterport).returns "321"
+ Puppet::Indirector::Request.new(:ind, :method, "puppet://host/stuff").port.should == 321
+ end
+
+ it "should use the provided port if the URI scheme is not 'puppet'" do
+ Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff").port.should == 80
+ end
+
+ it "should set the request key to the unqualified path from the URI" do
+ Puppet::Indirector::Request.new(:ind, :method, "http:///stuff").key.should == "stuff"
+ end
+
+ it "should set the :uri attribute to the full URI" do
+ Puppet::Indirector::Request.new(:ind, :method, "http:///stuff").uri.should == "http:///stuff"
+ end
+ end
end
it "should look use the Indirection class to return the appropriate indirection" do
@@ -84,4 +135,16 @@ describe Puppet::Indirector::Request do
request.indirection.should equal(ind)
end
+
+ it "should have a method for determining if the request is plural or singular" do
+ Puppet::Indirector::Request.new(:myind, :method, :key).should respond_to(:plural?)
+ end
+
+ it "should be considered plural if the method is 'search'" do
+ Puppet::Indirector::Request.new(:myind, :search, :key).should be_plural
+ end
+
+ it "should not be considered plural if the method is not 'search'" do
+ Puppet::Indirector::Request.new(:myind, :find, :key).should_not be_plural
+ end
end
diff --git a/spec/unit/indirector/rest.rb b/spec/unit/indirector/rest.rb
index 1a1064491..e7afbb5b2 100755
--- a/spec/unit/indirector/rest.rb
+++ b/spec/unit/indirector/rest.rb
@@ -3,10 +3,32 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/rest'
+describe "a REST http call", :shared => true do
+ it "should accept a path" do
+ lambda { @search.send(@method, *@arguments) }.should_not raise_error(ArgumentError)
+ end
+
+ it "should require a path" do
+ lambda { @searcher.send(@method) }.should raise_error(ArgumentError)
+ end
+
+ it "should return the results of deserializing the response to the request" do
+ conn = mock 'connection'
+ conn.stubs(:put).returns @response
+ conn.stubs(:delete).returns @response
+ conn.stubs(:get).returns @response
+ Puppet::Network::HttpPool.stubs(:http_instance).returns conn
+
+ @searcher.expects(:deserialize).with(@response).returns "myobject"
+
+ @searcher.send(@method, *@arguments).should == 'myobject'
+ end
+end
+
describe Puppet::Indirector::REST do
before do
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = stub('model')
+ @model = stub('model', :supported_formats => %w{}, :convert_from => nil)
@instance = stub('model instance')
@indirection = stub('indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model)
Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
@@ -17,356 +39,335 @@ describe Puppet::Indirector::REST do
end
end
+ @response = stub('mock response', :body => 'result', :code => "200")
+ @response.stubs(:[]).with('content-type').returns "text/plain"
+
@searcher = @rest_class.new
end
-
- describe "when locating the REST connection" do
- before do
- Puppet.settings.stubs(:value).returns("whatever")
- end
- it "should return the :server setting as the host" do
+ it "should have a method for specifying what setting a subclass should use to retrieve its server" do
+ @rest_class.should respond_to(:use_server_setting)
+ end
+
+ it "should use any specified setting to pick the server" do
+ @rest_class.expects(:server_setting).returns :servset
+ Puppet.settings.expects(:value).with(:servset).returns "myserver"
+ @rest_class.server.should == "myserver"
+ end
+
+ it "should default to :server for the server setting" do
+ @rest_class.expects(:server_setting).returns nil
Puppet.settings.expects(:value).with(:server).returns "myserver"
- @searcher.rest_connection_details[:host].should == "myserver"
- end
-
- it "should return the :masterport (as an Integer) as the port" do
- Puppet.settings.expects(:value).with(:masterport).returns "1234"
- @searcher.rest_connection_details[:port].should == 1234
- end
+ @rest_class.server.should == "myserver"
+ end
+
+ it "should have a method for specifying what setting a subclass should use to retrieve its port" do
+ @rest_class.should respond_to(:use_port_setting)
end
-
- describe "when doing a network fetch" do
- before :each do
- Net::HTTP.stubs(:start).returns('result')
- @details = { :host => '127.0.0.1', :port => 34343 }
- @searcher.stubs(:rest_connection_details).returns(@details)
- end
-
- it "should accept a path" do
- lambda { @search.network_fetch('foo') }.should_not raise_error(ArgumentError)
- end
-
- it "should require a path" do
- lambda { @searcher.network_fetch }.should raise_error(ArgumentError)
- end
-
- it "should look up connection details" do
- @searcher.expects(:rest_connection_details).returns(@details)
- @searcher.network_fetch('foo')
- end
-
- it "should use the GET http method" do
- @mock_result = stub('mock result', :body => 'result')
- @mock_connection = mock('mock http connection', :get => @mock_result)
- @searcher.stubs(:network).yields(@mock_connection)
- @searcher.network_fetch('foo')
- end
-
- it "should use the appropriate remote server" do
- Net::HTTP.expects(:start).with {|host, port| host == @details[:host] }
- @searcher.network_fetch('foo')
- end
-
- it "should use the appropriate remote port" do
- Net::HTTP.expects(:start).with {|host, port| port == @details[:port] }
- @searcher.network_fetch('foo')
- end
-
- it "should use the provided path" do
- @mock_result = stub('mock result', :body => 'result')
- @mock_connection = stub('mock http connection')
- @mock_connection.expects(:get).with('/foo').returns(@mock_result)
- @searcher.stubs(:network).yields(@mock_connection)
- @searcher.network_fetch('foo')
- end
-
- it "should return the results of the GET request" do
- @searcher.network_fetch('foo').should == 'result'
- end
+
+ it "should use any specified setting to pick the port" do
+ @rest_class.expects(:port_setting).returns :servset
+ Puppet.settings.expects(:value).with(:servset).returns "321"
+ @rest_class.port.should == 321
+ end
+
+ it "should default to :port for the port setting" do
+ @rest_class.expects(:port_setting).returns nil
+ Puppet.settings.expects(:value).with(:masterport).returns "543"
+ @rest_class.port.should == 543
end
- describe "when doing a network delete" do
- before :each do
- Net::HTTP.stubs(:start).returns('result')
- @details = { :host => '127.0.0.1', :port => 34343 }
- @searcher.stubs(:rest_connection_details).returns(@details)
- end
-
- it "should accept a path" do
- lambda { @search.network_delete('foo') }.should_not raise_error(ArgumentError)
- end
-
- it "should require a path" do
- lambda { @searcher.network_delete }.should raise_error(ArgumentError)
- end
-
- it "should look up connection details" do
- @searcher.expects(:rest_connection_details).returns(@details)
- @searcher.network_delete('foo')
- end
-
- it "should use the DELETE http method" do
- @mock_result = stub('mock result', :body => 'result')
- @mock_connection = mock('mock http connection', :delete => @mock_result)
- @searcher.stubs(:network).yields(@mock_connection)
- @searcher.network_delete('foo')
- end
-
- it "should use the appropriate remote server" do
- Net::HTTP.expects(:start).with {|host, port| host == @details[:host] }
- @searcher.network_delete('foo')
- end
-
- it "should use the appropriate remote port" do
- Net::HTTP.expects(:start).with {|host, port| port == @details[:port] }
- @searcher.network_delete('foo')
- end
-
- it "should use the provided path" do
- @mock_result = stub('mock result', :body => 'result')
- @mock_connection = stub('mock http connection')
- @mock_connection.expects(:delete).with('/foo').returns(@mock_result)
- @searcher.stubs(:network).yields(@mock_connection)
- @searcher.network_delete('foo')
- end
-
- it "should return the results of the DELETE request" do
- @searcher.network_delete('foo').should == 'result'
- end
+ describe "when deserializing responses" do
+ it "should return nil if the response code is 404" do
+ response = mock 'response'
+ response.expects(:code).returns "404"
+
+ @searcher.deserialize(response).should be_nil
+ end
+
+ it "should fail if the response code is not in the 200s" do
+ @model.expects(:convert_from).never
+
+ response = mock 'response'
+ response.stubs(:code).returns "300"
+ response.stubs(:message).returns "There was a problem"
+
+ lambda { @searcher.deserialize(response) }.should raise_error(Net::HTTPError)
+ end
+
+ it "should return the results of converting from the format specified by the content-type header if the response code is in the 200s" do
+ @model.expects(:convert_from).with("myformat", "mydata").returns "myobject"
+
+ response = mock 'response'
+ response.stubs(:[]).with("content-type").returns "myformat"
+ response.stubs(:body).returns "mydata"
+ response.stubs(:code).returns "200"
+
+ @searcher.deserialize(response).should == "myobject"
+ end
+
+ it "should convert and return multiple instances if the return code is in the 200s and 'multiple' is specified" do
+ @model.expects(:convert_from_multiple).with("myformat", "mydata").returns "myobjects"
+
+ response = mock 'response'
+ response.stubs(:[]).with("content-type").returns "myformat"
+ response.stubs(:body).returns "mydata"
+ response.stubs(:code).returns "200"
+
+ @searcher.deserialize(response, true).should == "myobjects"
+ end
end
-
- describe "when doing a network put" do
- before :each do
- Net::HTTP.stubs(:start).returns('result')
- @details = { :host => '127.0.0.1', :port => 34343 }
- @data = { :foo => 'bar' }
- @searcher.stubs(:rest_connection_details).returns(@details)
- end
-
- it "should accept a path and data" do
- lambda { @search.network_put('foo', @data) }.should_not raise_error(ArgumentError)
- end
-
- it "should require a path and data" do
- lambda { @searcher.network_put('foo') }.should raise_error(ArgumentError)
- end
-
- it "should look up connection details" do
- @searcher.expects(:rest_connection_details).returns(@details)
- @searcher.network_put('foo', @data)
- end
-
- it "should use the appropriate remote server" do
- Net::HTTP.expects(:start).with {|host, port| host == @details[:host] }
- @searcher.network_put('foo', @data)
- end
-
- it "should use the appropriate remote port" do
- Net::HTTP.expects(:start).with {|host, port| port == @details[:port] }
- @searcher.network_put('foo', @data)
- end
-
- it "should use the PUT http method" do
- @mock_result = stub('mock result', :body => 'result')
- @mock_connection = mock('mock http connection', :put => @mock_result)
- @searcher.stubs(:network).yields(@mock_connection)
- @searcher.network_put('foo', @data)
- end
-
- it "should use the provided path" do
- @mock_result = stub('mock result', :body => 'result')
- @mock_connection = stub('mock http connection')
- @mock_connection.expects(:put).with {|path, data| path == '/foo' }.returns(@mock_result)
- @searcher.stubs(:network).yields(@mock_connection)
- @searcher.network_put('foo', @data)
- end
-
- it "should use the provided data" do
- @mock_result = stub('mock result', :body => 'result')
- @mock_connection = stub('mock http connection')
- @mock_connection.expects(:put).with {|path, data| data == @data }.returns(@mock_result)
- @searcher.stubs(:network).yields(@mock_connection)
- @searcher.network_put('foo', @data)
- end
-
- it "should return the results of the PUT request" do
- @searcher.network_put('foo', @data).should == 'result'
- end
+
+ describe "when creating an HTTP client" do
+ before do
+ Puppet.settings.stubs(:value).returns("rest_testing")
+ end
+
+ it "should use the class's server and port if the indirection request provides neither" do
+ @request = stub 'request', :key => "foo", :server => nil, :port => nil
+ @searcher.class.expects(:port).returns 321
+ @searcher.class.expects(:server).returns "myserver"
+ Puppet::Network::HttpPool.expects(:http_instance).with("myserver", 321).returns "myconn"
+ @searcher.network(@request).should == "myconn"
+ end
+
+ it "should use the server from the indirection request if one is present" do
+ @request = stub 'request', :key => "foo", :server => "myserver", :port => nil
+ @searcher.class.stubs(:port).returns 321
+ Puppet::Network::HttpPool.expects(:http_instance).with("myserver", 321).returns "myconn"
+ @searcher.network(@request).should == "myconn"
+ end
+
+ it "should use the port from the indirection request if one is present" do
+ @request = stub 'request', :key => "foo", :server => nil, :port => 321
+ @searcher.class.stubs(:server).returns "myserver"
+ Puppet::Network::HttpPool.expects(:http_instance).with("myserver", 321).returns "myconn"
+ @searcher.network(@request).should == "myconn"
+ end
end
describe "when doing a find" do
- before :each do
- @result = { :foo => 'bar'}.to_yaml
- @searcher.stubs(:network_fetch).returns(@result) # neuter the network connection
- @model.stubs(:from_yaml).returns(@instance)
-
- @request = stub 'request', :key => 'foo'
- end
-
- it "should look up the model instance over the network" do
- @searcher.expects(:network_fetch).returns(@result)
- @searcher.find(@request)
- end
-
- it "should look up the model instance using the named indirection" do
- @searcher.expects(:network_fetch).with {|path| path =~ %r{^#{@indirection.name.to_s}/} }.returns(@result)
- @searcher.find(@request)
- end
-
- it "should look up the model instance using the provided key" do
- @searcher.expects(:network_fetch).with {|path| path =~ %r{/foo$} }.returns(@result)
- @searcher.find(@request)
- end
-
- it "should deserialize result data to a Model instance" do
- @model.expects(:from_yaml)
- @searcher.find(@request)
- end
-
- it "should return the deserialized Model instance" do
- @searcher.find(@request).should == @instance
- end
-
- it "should return nil when deserialized model instance is nil" do
- @model.stubs(:from_yaml).returns(nil)
- @searcher.find(@request).should be_nil
- end
-
- it "should generate an error when result data deserializes improperly" do
- @model.stubs(:from_yaml).raises(ArgumentError)
- lambda { @searcher.find(@request) }.should raise_error(ArgumentError)
- end
-
- it "should generate an error when result data specifies an error" do
- @searcher.stubs(:network_fetch).returns(RuntimeError.new("bogus").to_yaml)
- lambda { @searcher.find(@request) }.should raise_error(RuntimeError)
- end
+ before :each do
+ @connection = stub('mock http connection', :get => @response)
+ @searcher.stubs(:network).returns(@connection) # neuter the network connection
+
+ @request = stub 'request', :key => 'foo', :options => {}
+ end
+
+ it "should call the GET http method on a network connection" do
+ @searcher.expects(:network).returns @connection
+ @connection.expects(:get).returns @response
+ @searcher.find(@request)
+ end
+
+ it "should deserialize and return the http response" do
+ @connection.expects(:get).returns @response
+ @searcher.expects(:deserialize).with(@response).returns "myobject"
+
+ @searcher.find(@request).should == 'myobject'
+ end
+
+ it "should use the indirection name and request key to create the path" do
+ should_path = "/%s/%s" % [@indirection.name.to_s, "foo"]
+ @connection.expects(:get).with { |path, args| path == should_path }.returns(@response)
+ @searcher.find(@request)
+ end
+
+ it "should include all options in the query string" do
+ @request.stubs(:options).returns(:one => "two", :three => "four")
+ should_path = "/%s/%s" % [@indirection.name.to_s, "foo"]
+ @connection.expects(:get).with { |path, args| path =~ /\?one=two&three=four$/ or path =~ /\?three=four&one=two$/ }.returns(@response)
+ @searcher.find(@request)
+ end
+
+ it "should provide an Accept header containing the list of supported formats joined with commas" do
+ @connection.expects(:get).with { |path, args| args["Accept"] == "supported, formats" }.returns(@response)
+
+ @searcher.model.expects(:supported_formats).returns %w{supported formats}
+ @searcher.find(@request)
+ end
+
+ it "should deserialize and return the network response" do
+ @searcher.expects(:deserialize).with(@response).returns @instance
+ @searcher.find(@request).should equal(@instance)
+ end
+
+ it "should generate an error when result data deserializes fails" do
+ @searcher.expects(:deserialize).raises(ArgumentError)
+ lambda { @searcher.find(@request) }.should raise_error(ArgumentError)
+ end
end
describe "when doing a search" do
- before :each do
- @result = [1, 2].to_yaml
- @searcher.stubs(:network_fetch).returns(@result)
- @model.stubs(:from_yaml).returns(@instance)
-
- @request = stub 'request', :key => 'foo'
- end
-
- it "should look up the model data over the network" do
- @searcher.expects(:network_fetch).returns(@result)
- @searcher.search(@request)
- end
-
- it "should look up the model instance using the named indirection" do
- @searcher.expects(:network_fetch).with {|path| path =~ %r{^#{@indirection.name.to_s}s/} }.returns(@result)
- @searcher.search(@request)
- end
-
- it "should look up the model instance using the provided key" do
- @searcher.expects(:network_fetch).with {|path| path =~ %r{/foo$} }.returns(@result)
- @searcher.search(@request)
- end
-
- it "should deserialize result data into a list of Model instances" do
- @model.expects(:from_yaml).at_least(2)
- @searcher.search(@request)
- end
-
- it "should generate an error when result data deserializes improperly" do
- @model.stubs(:from_yaml).raises(ArgumentError)
- lambda { @searcher.search(@request) }.should raise_error(ArgumentError)
- end
-
- it "should generate an error when result data specifies an error" do
- @searcher.stubs(:network_fetch).returns(RuntimeError.new("bogus").to_yaml)
- lambda { @searcher.search(@request) }.should raise_error(RuntimeError)
- end
- end
-
+ before :each do
+ @connection = stub('mock http connection', :get => @response)
+ @searcher.stubs(:network).returns(@connection) # neuter the network connection
+
+ @model.stubs(:convert_from_multiple)
+
+ @request = stub 'request', :key => 'foo', :options => {}
+ end
+
+ it "should call the GET http method on a network connection" do
+ @searcher.expects(:network).returns @connection
+ @connection.expects(:get).returns @response
+ @searcher.search(@request)
+ end
+
+ it "should deserialize as multiple instances and return the http response" do
+ @connection.expects(:get).returns @response
+ @searcher.expects(:deserialize).with(@response, true).returns "myobject"
+
+ @searcher.search(@request).should == 'myobject'
+ end
+
+ it "should use the plural indirection name as the path if there is no request key" do
+ should_path = "/%ss" % [@indirection.name.to_s]
+ @request.stubs(:key).returns nil
+ @connection.expects(:get).with { |path, args| path == should_path }.returns(@response)
+ @searcher.search(@request)
+ end
+
+ it "should use the plural indirection name and request key to create the path if the request key is set" do
+ should_path = "/%ss/%s" % [@indirection.name.to_s, "foo"]
+ @connection.expects(:get).with { |path, args| path == should_path }.returns(@response)
+ @searcher.search(@request)
+ end
+
+ it "should include all options in the query string" do
+ @request.stubs(:options).returns(:one => "two", :three => "four")
+
+ should_path = "/%s/%s" % [@indirection.name.to_s, "foo"]
+ @connection.expects(:get).with { |path, args| path =~ /\?one=two&three=four$/ or path =~ /\?three=four&one=two$/ }.returns(@response)
+ @searcher.search(@request)
+ end
+
+ it "should provide an Accept header containing the list of supported formats joined with commas" do
+ @connection.expects(:get).with { |path, args| args["Accept"] == "supported, formats" }.returns(@response)
+
+ @searcher.model.expects(:supported_formats).returns %w{supported formats}
+ @searcher.search(@request)
+ end
+
+ it "should return an empty array if serialization returns nil" do
+ @model.stubs(:convert_from_multiple).returns nil
+
+ @searcher.search(@request).should == []
+ end
+
+ it "should generate an error when result data deserializes fails" do
+ @searcher.expects(:deserialize).raises(ArgumentError)
+ lambda { @searcher.search(@request) }.should raise_error(ArgumentError)
+ end
+ end
+
describe "when doing a destroy" do
- before :each do
- @result = true.to_yaml
- @searcher.stubs(:network_delete).returns(@result) # neuter the network connection
- @model.stubs(:from_yaml).returns(@instance)
-
- @request = stub 'request', :key => 'foo'
- end
-
- it "should look up the model instance over the network" do
- @searcher.expects(:network_delete).returns(@result)
- @searcher.destroy(@request)
- end
-
- it "should look up the model instance using the named indirection" do
- @searcher.expects(:network_delete).with {|path| path =~ %r{^#{@indirection.name.to_s}/} }.returns(@result)
- @searcher.destroy(@request)
- end
-
- it "should look up the model instance using the provided key" do
- @searcher.expects(:network_delete).with {|path| path =~ %r{/foo$} }.returns(@result)
- @searcher.destroy(@request)
- end
-
- it "should deserialize result data" do
- YAML.expects(:load).with(@result)
- @searcher.destroy(@request)
- end
-
- it "should return deserialized result data" do
- @searcher.destroy(@request).should == true
- end
-
- it "should generate an error when result data specifies an error" do
- @searcher.stubs(:network_delete).returns(RuntimeError.new("bogus").to_yaml)
- lambda { @searcher.destroy(@request) }.should raise_error(RuntimeError)
- end
+ before :each do
+ @connection = stub('mock http connection', :delete => @response)
+ @searcher.stubs(:network).returns(@connection) # neuter the network connection
+
+ @request = stub 'request', :key => 'foo', :options => {}
+ end
+
+ it "should call the DELETE http method on a network connection" do
+ @searcher.expects(:network).returns @connection
+ @connection.expects(:delete).returns @response
+ @searcher.destroy(@request)
+ end
+
+ it "should fail if any options are provided, since DELETE apparently does not support query options" do
+ @request.stubs(:options).returns(:one => "two", :three => "four")
+
+ lambda { @searcher.destroy(@request) }.should raise_error(ArgumentError)
+ end
+
+ it "should deserialize and return the http response" do
+ @connection.expects(:delete).returns @response
+ @searcher.expects(:deserialize).with(@response).returns "myobject"
+
+ @searcher.destroy(@request).should == 'myobject'
+ end
+
+ it "should use the indirection name and request key to create the path" do
+ should_path = "/%s/%s" % [@indirection.name.to_s, "foo"]
+ @connection.expects(:delete).with { |path, args| path == should_path }.returns(@response)
+ @searcher.destroy(@request)
+ end
+
+ it "should provide an Accept header containing the list of supported formats joined with commas" do
+ @connection.expects(:delete).with { |path, args| args["Accept"] == "supported, formats" }.returns(@response)
+
+ @searcher.model.expects(:supported_formats).returns %w{supported formats}
+ @searcher.destroy(@request)
+ end
+
+ it "should deserialize and return the network response" do
+ @searcher.expects(:deserialize).with(@response).returns @instance
+ @searcher.destroy(@request).should equal(@instance)
+ end
+
+ it "should generate an error when result data deserializes fails" do
+ @searcher.expects(:deserialize).raises(ArgumentError)
+ lambda { @searcher.destroy(@request) }.should raise_error(ArgumentError)
+ end
end
describe "when doing a save" do
- before :each do
- @result = { :foo => 'bar'}.to_yaml
- @searcher.stubs(:network_put).returns(@result) # neuter the network connection
- @model.stubs(:from_yaml).returns(@instance)
-
- @request = stub 'request', :instance => @instance
- end
-
- it "should save the model instance over the network" do
- @searcher.expects(:network_put).returns(@result)
- @searcher.save(@request)
- end
-
- it "should save the model instance using the named indirection" do
- @searcher.expects(:network_put).with do |path, data|
- path =~ %r{^#{@indirection.name.to_s}/} and
- data == @instance.to_yaml
- end.returns(@result)
- @searcher.save(@request)
- end
-
- it "should deserialize result data to a Model instance" do
- @model.expects(:from_yaml)
- @searcher.save(@request)
- end
-
- it "should return the resulting deserialized Model instance" do
- @searcher.save(@request).should == @instance
- end
-
- it "should return nil when deserialized model instance is nil" do
- @model.stubs(:from_yaml).returns(nil)
- @searcher.save(@request).should be_nil
- end
-
- it "should generate an error when result data deserializes improperly" do
- @model.stubs(:from_yaml).raises(ArgumentError)
- lambda { @searcher.save(@request) }.should raise_error(ArgumentError)
- end
-
- it "should generate an error when result data specifies an error" do
- @searcher.stubs(:network_put).returns(RuntimeError.new("bogus").to_yaml)
- lambda { @searcher.save(@request) }.should raise_error(RuntimeError)
- end
+ before :each do
+ @connection = stub('mock http connection', :put => @response)
+ @searcher.stubs(:network).returns(@connection) # neuter the network connection
+
+ @instance = stub 'instance', :render => "mydata"
+ @request = stub 'request', :instance => @instance, :options => {}
+ end
+
+ it "should call the PUT http method on a network connection" do
+ @searcher.expects(:network).returns @connection
+ @connection.expects(:put).returns @response
+ @searcher.save(@request)
+ end
+
+ it "should fail if any options are provided, since DELETE apparently does not support query options" do
+ @request.stubs(:options).returns(:one => "two", :three => "four")
+
+ lambda { @searcher.save(@request) }.should raise_error(ArgumentError)
+ end
+
+ it "should use the indirection name as the path for the request" do
+ @connection.expects(:put).with { |path, data, args| path == "/#{@indirection.name.to_s}/" }.returns @response
+
+ @searcher.save(@request)
+ end
+
+ it "should serialize the instance using the default format and pass the result as the body of the request" do
+ @instance.expects(:render).returns "serial_instance"
+ @connection.expects(:put).with { |path, data, args| data == "serial_instance" }.returns @response
+
+ @searcher.save(@request)
+ end
+
+ it "should deserialize and return the http response" do
+ @connection.expects(:put).returns @response
+ @searcher.expects(:deserialize).with(@response).returns "myobject"
+
+ @searcher.save(@request).should == 'myobject'
+ end
+
+ it "should provide an Accept header containing the list of supported formats joined with commas" do
+ @connection.expects(:put).with { |path, data, args| args["Accept"] == "supported, formats" }.returns(@response)
+
+ @searcher.model.expects(:supported_formats).returns %w{supported formats}
+ @searcher.save(@request)
+ end
+
+ it "should deserialize and return the network response" do
+ @searcher.expects(:deserialize).with(@response).returns @instance
+ @searcher.save(@request).should equal(@instance)
+ end
+
+ it "should generate an error when result data deserializes fails" do
+ @searcher.expects(:deserialize).raises(ArgumentError)
+ lambda { @searcher.save(@request) }.should raise_error(ArgumentError)
+ end
end
end
diff --git a/spec/unit/indirector/ssl_file.rb b/spec/unit/indirector/ssl_file.rb
new file mode 100755
index 000000000..89f682f38
--- /dev/null
+++ b/spec/unit/indirector/ssl_file.rb
@@ -0,0 +1,280 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-10.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/indirector/ssl_file'
+
+describe Puppet::Indirector::SslFile do
+ before do
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :testing, :model => @model
+ Puppet::Indirector::Indirection.expects(:instance).with(:testing).returns(@indirection)
+ @file_class = Class.new(Puppet::Indirector::SslFile) do
+ def self.to_s
+ "Testing::Mytype"
+ end
+ end
+
+ @setting = :mydir
+ @file_class.store_in @setting
+ @path = "/my/directory"
+ Puppet.settings.stubs(:value).returns "stubbed_setting"
+ Puppet.settings.stubs(:value).with(@setting).returns(@path)
+ Puppet.settings.stubs(:value).with(:trace).returns(false)
+ end
+
+ it "should use :main and :ssl upon initialization" do
+ Puppet.settings.expects(:use).with(:main, :ssl)
+ @file_class.new
+ end
+
+ it "should return a nil collection directory if no directory setting has been provided" do
+ @file_class.store_in nil
+ @file_class.collection_directory.should be_nil
+ end
+
+ it "should return a nil file location if no location has been provided" do
+ @file_class.store_at nil
+ @file_class.file_location.should be_nil
+ end
+
+ it "should fail if no store directory or file location has been set" do
+ @file_class.store_in nil
+ @file_class.store_at nil
+ lambda { @file_class.new }.should raise_error(Puppet::DevError)
+ end
+
+ describe "when managing ssl files" do
+ before do
+ Puppet.settings.stubs(:use)
+ @searcher = @file_class.new
+
+ @cert = stub 'certificate', :name => "myname"
+ @certpath = File.join(@path, "myname" + ".pem")
+
+ @request = stub 'request', :key => @cert.name, :instance => @cert
+ end
+
+ it "should consider the file a ca file if the name is equal to what the SSL::Host class says is the CA name" do
+ Puppet::SSL::Host.expects(:ca_name).returns "amaca"
+ @searcher.should be_ca("amaca")
+ end
+
+ describe "when choosing the location for certificates" do
+ it "should set them at the ca setting's path if a ca setting is available and the name resolves to the CA name" do
+ @file_class.store_in nil
+ @file_class.store_at :mysetting
+ @file_class.store_ca_at :casetting
+
+ Puppet.settings.stubs(:value).with(:casetting).returns "/ca/file"
+
+ @searcher.expects(:ca?).with(@cert.name).returns true
+ @searcher.path(@cert.name).should == "/ca/file"
+ end
+
+ it "should set them at the file location if a file setting is available" do
+ @file_class.store_in nil
+ @file_class.store_at :mysetting
+
+ Puppet.settings.stubs(:value).with(:mysetting).returns "/some/file"
+
+ @searcher.path(@cert.name).should == "/some/file"
+ end
+
+ it "should set them in the setting directory, with the certificate name plus '.pem', if a directory setting is available" do
+ @searcher.path(@cert.name).should == @certpath
+ end
+ end
+
+ describe "when finding certificates on disk" do
+ describe "and no certificate is present" do
+ before do
+ # Stub things so the case management bits work.
+ FileTest.stubs(:exist?).with(File.dirname(@certpath)).returns false
+ FileTest.expects(:exist?).with(@certpath).returns false
+ end
+
+ it "should return nil" do
+ @searcher.find(@request).should be_nil
+ end
+ end
+
+ describe "and a certificate is present" do
+ before do
+ FileTest.expects(:exist?).with(@certpath).returns true
+ end
+
+ it "should return an instance of the model, which it should use to read the certificate" do
+ cert = mock 'cert'
+ model = mock 'model'
+ @file_class.stubs(:model).returns model
+
+ model.expects(:new).with("myname").returns cert
+ cert.expects(:read).with(@certpath)
+ @searcher.find(@request).should equal(cert)
+ end
+ end
+
+ describe "and a certificate is present but has uppercase letters" do
+ before do
+ @request = stub 'request', :key => "myhost"
+ end
+
+ # This is kind of more an integration test; it's for #1382, until
+ # the support for upper-case certs can be removed around mid-2009.
+ it "should rename the existing file to the lower-case path" do
+ @path = @searcher.path("myhost")
+ FileTest.expects(:exist?).with(@path).returns(false)
+ dir, file = File.split(@path)
+ FileTest.expects(:exist?).with(dir).returns true
+ Dir.expects(:entries).with(dir).returns [".", "..", "something.pem", file.upcase]
+
+ File.expects(:rename).with(File.join(dir, file.upcase), @path)
+
+ cert = mock 'cert'
+ model = mock 'model'
+ @searcher.stubs(:model).returns model
+ @searcher.model.expects(:new).with("myhost").returns cert
+ cert.expects(:read).with(@path)
+
+ @searcher.find(@request)
+ end
+ end
+ end
+
+ describe "when saving certificates to disk" do
+ before do
+ FileTest.stubs(:directory?).returns true
+ FileTest.stubs(:writable?).returns true
+ end
+
+ it "should fail if the directory is absent" do
+ FileTest.expects(:directory?).with(File.dirname(@certpath)).returns false
+ lambda { @searcher.save(@request) }.should raise_error(Puppet::Error)
+ end
+
+ it "should fail if the directory is not writeable" do
+ FileTest.stubs(:directory?).returns true
+ FileTest.expects(:writable?).with(File.dirname(@certpath)).returns false
+ lambda { @searcher.save(@request) }.should raise_error(Puppet::Error)
+ end
+
+ it "should save to the path the output of converting the certificate to a string" do
+ fh = mock 'filehandle'
+ fh.expects(:print).with("mycert")
+
+ @searcher.stubs(:write).yields fh
+ @cert.expects(:to_s).returns "mycert"
+
+ @searcher.save(@request)
+ end
+
+ describe "and a directory setting is set" do
+ it "should open the file in write mode" do
+ @searcher.class.store_in @setting
+ fh = mock 'filehandle'
+ fh.stubs :print
+ File.expects(:open).with(@certpath, "w").yields(fh)
+
+ @searcher.save(@request)
+ end
+ end
+
+ describe "and a file location is set" do
+ it "should use the filehandle provided by the Settings" do
+ @searcher.class.store_at @setting
+
+ fh = mock 'filehandle'
+ fh.stubs :print
+ Puppet.settings.expects(:write).with(@setting).yields fh
+ @searcher.save(@request)
+ end
+ end
+
+ describe "and the name is the CA name and a ca setting is set" do
+ it "should use the filehandle provided by the Settings" do
+ @searcher.class.store_at @setting
+ @searcher.class.store_ca_at :castuff
+
+ fh = mock 'filehandle'
+ fh.stubs :print
+ Puppet.settings.expects(:write).with(:castuff).yields fh
+ @searcher.stubs(:ca?).returns true
+ @searcher.save(@request)
+ end
+ end
+ end
+
+ describe "when destroying certificates" do
+ describe "that do not exist" do
+ before do
+ FileTest.expects(:exist?).with(@certpath).returns false
+ end
+
+ it "should return false" do
+ @searcher.destroy(@request).should be_false
+ end
+ end
+
+ describe "that exist" do
+ before do
+ FileTest.expects(:exist?).with(@certpath).returns true
+ end
+
+ it "should unlink the certificate file" do
+ File.expects(:unlink).with(@certpath)
+ @searcher.destroy(@request)
+ end
+
+ it "should log that is removing the file" do
+ File.stubs(:exist?).returns true
+ File.stubs(:unlink)
+ Puppet.expects(:notice)
+ @searcher.destroy(@request)
+ end
+ end
+ end
+
+ describe "when searching for certificates" do
+ before do
+ @model = mock 'model'
+ @file_class.stubs(:model).returns @model
+ end
+ it "should return a certificate instance for all files that exist" do
+ Dir.expects(:entries).with(@path).returns %w{one.pem two.pem}
+
+ one = stub 'one', :read => nil
+ two = stub 'two', :read => nil
+
+ @model.expects(:new).with("one").returns one
+ @model.expects(:new).with("two").returns two
+
+ @searcher.search(@request).should == [one, two]
+ end
+
+ it "should read each certificate in using the model's :read method" do
+ Dir.expects(:entries).with(@path).returns %w{one.pem}
+
+ one = stub 'one'
+ one.expects(:read).with(File.join(@path, "one.pem"))
+
+ @model.expects(:new).with("one").returns one
+
+ @searcher.search(@request)
+ end
+
+ it "should skip any files that do not match /\.pem$/" do
+ Dir.expects(:entries).with(@path).returns %w{. .. one.pem}
+
+ one = stub 'one', :read => nil
+
+ @model.expects(:new).with("one").returns one
+
+ @searcher.search(@request)
+ end
+ end
+ end
+end
diff --git a/spec/unit/indirector/ssl_rsa/file.rb b/spec/unit/indirector/ssl_rsa/file.rb
deleted file mode 100755
index 76e5e3a94..000000000
--- a/spec/unit/indirector/ssl_rsa/file.rb
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env ruby
-#
-# Created by Luke Kanies on 2007-9-22.
-# Copyright (c) 2007. All rights reserved.
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-require 'puppet/sslcertificates/monkey_patch'
-require 'puppet/indirector/ssl_rsa/file'
-
-
-describe Puppet::Indirector::SslRsa::File do
-
- it "should be a subclass of the File terminus class" do
- Puppet::Indirector::SslRsa::File.superclass.should equal(Puppet::Indirector::File)
- end
-
- it "should have documentation" do
- Puppet::Indirector::SslRsa::File.doc.should be_instance_of(String)
- end
-end
-
-describe Puppet::Indirector::SslRsa::File, " when choosing a path for a ca key" do
- before do
- @file = Puppet::Indirector::SslRsa::File.new
- @name = :ca
- end
-
- it "should use the cadir" do
- Puppet.settings.stubs(:value).with(:cadir).returns("/dir")
- @file.path(@name).should =~ /^\/dir/
- end
-
- it "should use 'ca_key.pem' as the file name" do
- @file.path(@name).should =~ /ca_key\.pem$/
- end
-end
-
-describe Puppet::Indirector::SslRsa::File, " when choosing a path for a non-ca key" do
- before do
- @file = Puppet::Indirector::SslRsa::File.new
- @name = :publickey
- end
-
- it "should use the publickeydir" do
- Puppet.settings.stubs(:value).with(:publickeydir).returns("/dir")
- @file.path(@name).should =~ /^\/dir/
- end
-
- it "should use the key name with the pem file extension" do
- @file.path(@name).should =~ /#{@name}\.pem$/
- end
-end
-
-describe Puppet::Indirector::SslRsa::File, " when saving" do
- before do
- @file = Puppet::Indirector::SslRsa::File.new
-
- Puppet.settings.stubs(:value).with(:publickeydir).returns("/dir")
- @key = stub "key", :name => "foo"
- end
-
- it "should store the rsa key to disk in pem format" do
- @key.expects(:to_pem).returns(:data)
- @path = "/dir/foo.pem"
- filehandle = mock "filehandle"
- File.expects(:open).with(@path, "w").yields(filehandle)
- filehandle.expects(:print).with(:data)
- @file.save(@key)
- end
-end
-
-describe Puppet::Indirector::SslRsa::File, " when finding a key by name" do
- before do
- @file = Puppet::Indirector::SslRsa::File.new
-
- Puppet.settings.stubs(:value).with(:publickeydir).returns("/dir")
- @name = "foo"
- end
-
- it "should return the key as a key object on success" do
- @path = "/dir/foo.pem"
- FileTest.stubs(:exists?).with(@path).returns(true)
- File.stubs(:read).with(@path).returns(:data)
- OpenSSL::PKey::RSA.expects(:new).with(:data).returns(:mykey)
- @file.find(@name).should == :mykey
- end
-
- it "should return 'nil' on failure" do
- @path = "/dir/foo.pem"
- FileTest.stubs(:exists?).with(@path).returns(false)
- @file.find(@name).should == nil
- end
-end
-
-describe Puppet::Indirector::SslRsa::File, " when removing a key" do
- before do
- @file = Puppet::Indirector::SslRsa::File.new
-
- Puppet.settings.stubs(:value).with(:publickeydir).returns("/dir")
- @name = "foo"
- end
-
- it "should remove the key from disk and return true" do
- @path = "/dir/foo.pem"
- FileTest.stubs(:exists?).with(@path).returns(true)
- File.stubs(:unlink).with(@path).returns(true)
- @file.destroy(@name).should == true
- end
-
- it "should return an exception on failure" do
- @path = "/dir/foo.pem"
- FileTest.stubs(:exists?).with(@path).returns(false)
- @file.destroy(@name).should == nil
- end
-end