diff options
author | Lamont Granquist <lamont@opscode.com> | 2013-04-01 16:52:57 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@opscode.com> | 2013-04-01 16:52:57 -0700 |
commit | 1f460cae553c16254f77b21bab83e8020dc89ca3 (patch) | |
tree | 307c02bbf5b2a037775dd73a3590974ed383bd49 /spec/unit/provider/remote_file | |
parent | 4c1924d9adbbd334fb1d45f79aace3df68774b3e (diff) | |
download | chef-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.rb | 248 |
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 + |