summaryrefslogtreecommitdiff
path: root/spec/unit/provider/remote_file
diff options
context:
space:
mode:
authorLamont Granquist <lamont@opscode.com>2013-04-01 16:52:57 -0700
committerLamont Granquist <lamont@opscode.com>2013-04-01 16:52:57 -0700
commit1f460cae553c16254f77b21bab83e8020dc89ca3 (patch)
tree307c02bbf5b2a037775dd73a3590974ed383bd49 /spec/unit/provider/remote_file
parent4c1924d9adbbd334fb1d45f79aace3df68774b3e (diff)
downloadchef-1f460cae553c16254f77b21bab83e8020dc89ca3.tar.gz
refactoring into remote_file content spec
Diffstat (limited to 'spec/unit/provider/remote_file')
-rw-r--r--spec/unit/provider/remote_file/content_spec.rb248
1 files changed, 248 insertions, 0 deletions
diff --git a/spec/unit/provider/remote_file/content_spec.rb b/spec/unit/provider/remote_file/content_spec.rb
new file mode 100644
index 0000000000..ac8252510b
--- /dev/null
+++ b/spec/unit/provider/remote_file/content_spec.rb
@@ -0,0 +1,248 @@
+#
+# Author:: Lamont Granquist (<lamont@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+
+describe Chef::Provider::RemoteFile::Content do
+
+ #
+ # mock setup
+ #
+
+ let(:current_resource) do
+ mock("Chef::Provider::RemoteFile::Resource (current)", :source => nil)
+ end
+
+ let(:source) { [ "http://opscode.com/seattle.txt" ] }
+
+ let(:new_resource) do
+ mock("Chef::Provider::RemoteFile::Resource (new)", :source => source, :etag => nil, :last_modified => nil)
+ end
+
+ let(:run_context) { mock("Chef::RunContext") }
+
+ #
+ # subject
+ #
+ let(:content) do
+ Chef::Provider::RemoteFile::Content.new(new_resource, current_resource, run_context)
+ end
+
+ describe "when the checksum of the current_resource matches the checksum set on the resource" do
+ before do
+ new_resource.stub!(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
+ current_resource.stub!(:checksum).and_return("0fd012fdc96e96f8f7cf2046522a54aed0ce470224513e45da6bc1a17a4924aa")
+ end
+
+ it "should return nil for the tempfile" do
+ content.tempfile.should be_nil
+ end
+ end
+
+ describe "when the checksum of the current_resource does not match the checksum set on the resource" do
+ before do
+ # FIXME: test one or the other nil, test both not nil and not equal, abuse the regexp a little
+ new_resource.stub!(:checksum).and_return(nil)
+ current_resource.stub!(:checksum).and_return(nil)
+ @uri = mock("URI")
+ @sanitized_uri = mock("URI")
+ URI.should_receive(:parse).with(new_resource.source[0]).and_return(@uri)
+ Chef::Provider::RemoteFile::Util.should_receive(:uri_for_cache).with(@uri).and_return(@sanitized_uri)
+ end
+
+ describe "when the fetcher returns nil for the tempfile" do
+ before do
+ @result = mock("Chef::Provider::RemoteFile::Result", :raw_file => nil, :etag => nil, :mtime => nil)
+ http_fetcher = mock("Chef::Provider::RemoteFile::HTTP", :fetch => @result)
+ Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri, new_resource, current_resource).and_return(http_fetcher)
+ end
+
+ it "should return nil for the tempfile" do
+ content.tempfile.should be_nil
+ end
+
+ it "should return the raw_file_source when the accessor is called after getting the tempfile" do
+ content.tempfile
+ content.raw_file_source.should == @sanitized_uri
+ end
+
+ it "should not set the etags on the new resource" do
+ new_resource.should_not_receive(:etag).with(@result.etag)
+ content.tempfile
+ end
+
+ it "should not set the mtime on the new resource" do
+ new_resource.should_not_receive(:mtime).with(@result.mtime)
+ content.tempfile
+ end
+ end
+
+ describe "when the fetcher returns a result with a valid tempfile" do
+ before do
+ @tempfile = mock("Tempfile")
+ mtime = Time.now
+ @result = mock("Chef::Provider::RemoteFile::Result", :raw_file => @tempfile, :etag => "etag", :mtime => mtime)
+ http_fetcher = mock("Chef::Provider::RemoteFile::HTTP", :fetch => @result)
+ Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri, new_resource, current_resource).and_return(http_fetcher)
+ end
+
+ it "should return the tempfile object to the caller" do
+ content.tempfile.should == @tempfile
+ end
+
+ it "should return the raw_file_source when the accessor is called after getting the tempfile" do
+ content.tempfile
+ content.raw_file_source.should == @sanitized_uri
+ end
+
+ it "should set the etags on the new resource" do
+ new_resource.should_receive(:etag).with(@result.etag)
+ content.tempfile
+ end
+
+ it "should set the mtime on the new resource" do
+ new_resource.should_receive(:last_modified).with(@result.mtime)
+ content.tempfile
+ end
+ end
+ end
+
+ describe "when the fetcher throws an exception" do
+ before do
+ new_resource.stub!(:checksum).and_return(nil)
+ current_resource.stub!(:checksum).and_return(nil)
+ @uri = mock("URI")
+ URI.should_receive(:parse).with(new_resource.source[0]).and_return(@uri)
+ http_fetcher = mock("Chef::Provider::RemoteFile::HTTP")
+ http_fetcher.should_receive(:fetch).and_raise(Errno::ECONNREFUSED)
+ Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri, new_resource, current_resource).and_return(http_fetcher)
+ Chef::Provider::RemoteFile::Util.should_not_receive(:uri_for_cache)
+ end
+
+ it "should propagate the error back to the caller" do
+ lambda { content.tempfile }.should raise_error(Errno::ECONNREFUSED)
+ end
+ end
+
+ describe "when there is an array of sources and the first fails" do
+
+ let(:source) { [ "http://opscode.com/seattle.txt", "http://opscode.com/nyc.txt" ] }
+ before do
+ new_resource.stub!(:checksum).and_return(nil)
+ current_resource.stub!(:checksum).and_return(nil)
+ @uri0 = mock("URI0")
+ @uri1 = mock("URI1")
+ URI.should_receive(:parse).with(new_resource.source[0]).and_return(@uri0)
+ URI.should_receive(:parse).with(new_resource.source[1]).and_return(@uri1)
+ @http_fetcher_throws_exception = mock("Chef::Provider::RemoteFile::HTTP")
+ @http_fetcher_throws_exception.should_receive(:fetch).at_least(:once).and_raise(Errno::ECONNREFUSED)
+ Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri0, new_resource, current_resource).and_return(@http_fetcher_throws_exception)
+ end
+
+ describe "when the second url succeeds" do
+ before do
+ @tempfile = mock("Tempfile")
+ mtime = Time.now
+ @result = mock("Chef::Provider::RemoteFile::Result", :raw_file => @tempfile, :etag => "etag", :mtime => mtime)
+ http_fetcher_works = mock("Chef::Provider::RemoteFile::HTTP", :fetch => @result)
+ Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri1, new_resource, current_resource).and_return(http_fetcher_works)
+ @sanitized_uri = mock("URI")
+ Chef::Provider::RemoteFile::Util.should_receive(:uri_for_cache).with(@uri1).and_return(@sanitized_uri)
+ end
+
+ it "should return a valid tempfile" do
+ content.tempfile.should == @tempfile
+ end
+
+ it "should return the raw_file_source when the accessor is called after getting the tempfile" do
+ content.tempfile
+ content.raw_file_source.should == @sanitized_uri
+ end
+
+ it "should set the etags on the new resource" do
+ new_resource.should_receive(:etag).with(@result.etag)
+ content.tempfile
+ end
+
+ it "should set the mtime on the new resource" do
+ new_resource.should_receive(:last_modified).with(@result.mtime)
+ content.tempfile
+ end
+
+ it "should not mutate the new_resource" do
+ content.tempfile
+ new_resource.source.length.should == 2
+ end
+ end
+
+ describe "when both urls fail" do
+ before do
+ Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri1, new_resource, current_resource).and_return(@http_fetcher_throws_exception)
+ Chef::Provider::RemoteFile::Util.should_not_receive(:uri_for_cache)
+ end
+
+ it "should propagate the error back to the caller" do
+ lambda { content.tempfile }.should raise_error(Errno::ECONNREFUSED)
+ end
+ end
+ end
+
+ describe "when there is an array of sources and the first succeeds" do
+ let(:source) { [ "http://opscode.com/seattle.txt", "http://opscode.com/nyc.txt" ] }
+ before do
+ new_resource.stub!(:checksum).and_return(nil)
+ current_resource.stub!(:checksum).and_return(nil)
+ @uri0 = mock("URI0")
+ URI.should_receive(:parse).with(new_resource.source[0]).and_return(@uri0)
+ URI.should_not_receive(:parse).with(new_resource.source[1])
+ @tempfile = mock("Tempfile")
+ mtime = Time.now
+ @result = mock("Chef::Provider::RemoteFile::Result", :raw_file => @tempfile, :etag => "etag", :mtime => mtime)
+ http_fetcher_works = mock("Chef::Provider::RemoteFile::HTTP", :fetch => @result)
+ Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri0, new_resource, current_resource).and_return(http_fetcher_works)
+ @sanitized_uri = mock("URI")
+ Chef::Provider::RemoteFile::Util.should_receive(:uri_for_cache).with(@uri0).and_return(@sanitized_uri)
+ end
+
+ it "should return a valid tempfile" do
+ content.tempfile.should == @tempfile
+ end
+
+ it "should return the raw_file_source when the accessor is called after getting the tempfile" do
+ content.tempfile
+ content.raw_file_source.should == @sanitized_uri
+ end
+
+ it "should set the etags on the new resource" do
+ new_resource.should_receive(:etag).with(@result.etag)
+ content.tempfile
+ end
+
+ it "should set the mtime on the new resource" do
+ new_resource.should_receive(:last_modified).with(@result.mtime)
+ content.tempfile
+ end
+
+ it "should not mutate the new_resource" do
+ content.tempfile
+ new_resource.source.length.should == 2
+ end
+ end
+
+end
+