diff options
Diffstat (limited to 'spec/unit/indirector')
-rwxr-xr-x | spec/unit/indirector/certificate/ca.rb | 28 | ||||
-rwxr-xr-x | spec/unit/indirector/certificate/file.rb | 28 | ||||
-rwxr-xr-x | spec/unit/indirector/certificate/rest.rb | 15 | ||||
-rwxr-xr-x | spec/unit/indirector/certificate_request/ca.rb | 19 | ||||
-rwxr-xr-x | spec/unit/indirector/certificate_request/file.rb | 19 | ||||
-rwxr-xr-x | spec/unit/indirector/certificate_request/rest.rb | 15 | ||||
-rwxr-xr-x | spec/unit/indirector/certificate_revocation_list/ca.rb | 21 | ||||
-rwxr-xr-x | spec/unit/indirector/certificate_revocation_list/file.rb | 20 | ||||
-rwxr-xr-x | spec/unit/indirector/certificate_revocation_list/rest.rb | 15 | ||||
-rwxr-xr-x | spec/unit/indirector/indirection.rb | 26 | ||||
-rwxr-xr-x | spec/unit/indirector/key/ca.rb | 34 | ||||
-rwxr-xr-x | spec/unit/indirector/key/file.rb | 104 | ||||
-rwxr-xr-x | spec/unit/indirector/rest.rb | 623 | ||||
-rwxr-xr-x | spec/unit/indirector/ssl_file.rb | 272 | ||||
-rwxr-xr-x | spec/unit/indirector/ssl_rsa/file.rb | 116 |
15 files changed, 885 insertions, 470 deletions
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/indirection.rb b/spec/unit/indirector/indirection.rb index 5d4539e95..e52be31e1 100755 --- a/spec/unit/indirector/indirection.rb +++ b/spec/unit/indirector/indirection.rb @@ -87,6 +87,9 @@ describe "Delegation Authorizer", :shared => true do end describe Puppet::Indirector::Indirection do + after do + Puppet::Util::Cacher.invalidate + 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 +497,7 @@ describe Puppet::Indirector::Indirection do after :each do @indirection.delete - Puppet::Indirector::Indirection.clear_cache + Puppet::Util::Cacher.invalidate end end @@ -615,15 +618,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 +632,6 @@ describe Puppet::Indirector::Indirection do after do @indirection.delete - Puppet::Indirector::Indirection.clear_cache end end @@ -675,7 +668,6 @@ describe Puppet::Indirector::Indirection do after do @indirection.delete - Puppet::Indirector::Indirection.clear_cache end end @@ -706,15 +698,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 +708,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/rest.rb b/spec/unit/indirector/rest.rb index 1a1064491..1f802b603 100755 --- a/spec/unit/indirector/rest.rb +++ b/spec/unit/indirector/rest.rb @@ -3,6 +3,39 @@ 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 use the Http Pool with the remote server and port looked up from the REST terminus" do + @searcher.expects(:rest_connection_details).returns(@details) + + conn = mock 'connection' + result = stub 'result', :body => "body" + conn.stubs(:put).returns result + conn.stubs(:delete).returns result + conn.stubs(:get).returns result + Puppet::Network::HttpPool.expects(:http_instance).with(@details[:host], @details[:port]).returns conn + @searcher.send(@method, *@arguments) + end + + it "should return the results of the request" do + conn = mock 'connection' + result = stub 'result', :body => "result" + conn.stubs(:put).returns result + conn.stubs(:delete).returns result + conn.stubs(:get).returns result + Puppet::Network::HttpPool.stubs(:http_instance).returns conn + + @searcher.send(@method, *@arguments).should == 'result' + end +end + describe Puppet::Indirector::REST do before do Puppet::Indirector::Terminus.stubs(:register_terminus_class) @@ -19,354 +52,280 @@ describe Puppet::Indirector::REST do @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 - 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 + + describe "when configuring the REST http call" do + before do + Puppet.settings.stubs(:value).returns("rest_testing") + end + + it "should return the :server setting as the host" do + 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 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 + before :each do + Net::HTTP.stubs(:start).returns('result') + @details = { :host => '127.0.0.1', :port => 34343 } + @searcher.stubs(:rest_connection_details).returns(@details) + + @method = :network_fetch + @arguments = "foo" + end + + it_should_behave_like "a REST http call" + + 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).returns(@mock_connection) + @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).returns(@mock_connection) + @searcher.network_fetch('foo') + end 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 + before :each do + Net::HTTP.stubs(:start).returns('result') + @details = { :host => '127.0.0.1', :port => 34343 } + @searcher.stubs(:rest_connection_details).returns(@details) + + @method = :network_delete + @arguments = "foo" + end + + it_should_behave_like "a REST http call" + + 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).returns(@mock_connection) + @searcher.network_delete('foo') + 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 + 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) + + @method = :network_put + @arguments = ["foo", @data] + end + + it_should_behave_like "a REST http call" + + 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).returns(@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).returns(@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).returns(@mock_connection) + @searcher.network_put('foo', @data) + 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 + @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 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 + @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 plural of 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 + 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 + @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 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 + @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 end end diff --git a/spec/unit/indirector/ssl_file.rb b/spec/unit/indirector/ssl_file.rb new file mode 100755 index 000000000..756101a00 --- /dev/null +++ b/spec/unit/indirector/ssl_file.rb @@ -0,0 +1,272 @@ +#!/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 + @indirection = stub 'indirection', :name => :testing + 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 + 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 |