diff options
author | lamont-granquist <lamont@scriptkiddie.org> | 2014-04-22 15:00:31 -0700 |
---|---|---|
committer | lamont-granquist <lamont@scriptkiddie.org> | 2014-04-22 15:00:31 -0700 |
commit | b84c614bd534a48821e06e7f0bdb21eee203ba41 (patch) | |
tree | 5a157453fa573d5b18b97badbac7dfc5ed6570d8 | |
parent | 37a3f076d19d3f53e59e1a490f0b5a5d384bf460 (diff) | |
parent | ab350673594f9d47e37a5760eebfeb87967162a9 (diff) | |
download | chef-b84c614bd534a48821e06e7f0bdb21eee203ba41.tar.gz |
Merge pull request #1358 from johntdyer/master
CHEF-5116 - Catch HTTPServerException for 404 in remote_file retry
-rw-r--r-- | lib/chef/provider/remote_file/content.rb | 2 | ||||
-rw-r--r-- | spec/unit/provider/remote_file/content_spec.rb | 93 |
2 files changed, 59 insertions, 36 deletions
diff --git a/lib/chef/provider/remote_file/content.rb b/lib/chef/provider/remote_file/content.rb index 7f9e2332a8..3a8514e077 100644 --- a/lib/chef/provider/remote_file/content.rb +++ b/lib/chef/provider/remote_file/content.rb @@ -48,7 +48,7 @@ class Chef begin uri = URI.parse(source) raw_file = grab_file_from_uri(uri) - rescue SocketError, Errno::ECONNREFUSED, Errno::ENOENT, Errno::EACCES, Timeout::Error, Net::HTTPFatalError, Net::FTPError => e + rescue SocketError, Errno::ECONNREFUSED, Errno::ENOENT, Errno::EACCES, Timeout::Error, Net::HTTPServerException, Net::HTTPFatalError, Net::FTPError => e Chef::Log.warn("#{@new_resource} cannot be downloaded from #{source}: #{e.to_s}") if source = sources.shift Chef::Log.info("#{@new_resource} trying to download from another mirror") diff --git a/spec/unit/provider/remote_file/content_spec.rb b/spec/unit/provider/remote_file/content_spec.rb index 0f311dc0ec..4ee33aeefb 100644 --- a/spec/unit/provider/remote_file/content_spec.rb +++ b/spec/unit/provider/remote_file/content_spec.rb @@ -160,44 +160,68 @@ describe Chef::Provider::RemoteFile::Content do 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 = double("URI0") - @uri1 = double("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 = double("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 = double("Tempfile") - mtime = Time.now - http_fetcher_works = double("Chef::Provider::RemoteFile::HTTP", :fetch => @tempfile) - Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri1, new_resource, current_resource).and_return(http_fetcher_works) - end - - it "should return a valid tempfile" do - content.tempfile.should == @tempfile - end - - it "should not mutate the new_resource" do - content.tempfile - new_resource.source.length.should == 2 + # https://github.com/opscode/chef/pull/1358#issuecomment-40853299 + def create_exception(exception_class) + if [ Net::HTTPServerException, Net::HTTPFatalError ].include? exception_class + exception_class.new("message", {"something" => 1}) + else + exception_class.new 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) - end + let(:source) { [ "http://opscode.com/seattle.txt", "http://opscode.com/nyc.txt" ] } - it "should propagate the error back to the caller" do - lambda { content.tempfile }.should raise_error(Errno::ECONNREFUSED) + ### Test each exception we care about and make sure they all behave properly + [ + SocketError, + Errno::ECONNREFUSED, + Errno::ENOENT, + Errno::EACCES, + Timeout::Error, + Net::HTTPServerException, + Net::HTTPFatalError, + Net::FTPError + ].each do |exception| + describe "with an exception of #{exception}" do + before do + new_resource.stub(:checksum).and_return(nil) + current_resource.stub(:checksum).and_return(nil) + @uri0 = double("URI0") + @uri1 = double("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 = double("Chef::Provider::RemoteFile::HTTP") + @http_fetcher_throws_exception.should_receive(:fetch).at_least(:once).and_raise(create_exception(exception)) + Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri0, new_resource, current_resource).and_return(@http_fetcher_throws_exception) + end + + describe "the second url should succeed" do + before do + @tempfile = double("Tempfile") + mtime = Time.now + http_fetcher_works = double("Chef::Provider::RemoteFile::HTTP", :fetch => @tempfile) + Chef::Provider::RemoteFile::Fetcher.should_receive(:for_resource).with(@uri1, new_resource, current_resource).and_return(http_fetcher_works) + end + + it "should return a valid tempfile" do + content.tempfile.should == @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) + end + + it "should propagate the error back to the caller" do + lambda { content.tempfile }.should raise_error(exception) + end + end end end end @@ -227,4 +251,3 @@ describe Chef::Provider::RemoteFile::Content do end end - |