summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2015-12-07 18:16:37 -0800
committerLamont Granquist <lamont@scriptkiddie.org>2015-12-07 18:16:37 -0800
commit812008eadb9a3b72ec2142db4a401cfe0b668f18 (patch)
tree897babda8bd6874db9a9b9fc294e1e1c30d569ba
parent5085b5e365f6fb1052b658c107f6f1a322a12fbb (diff)
downloadchef-lcg/dpkg-s-return-codes.tar.gz
restore handling of dpkg -s returns codes (w/tests)lcg/dpkg-s-return-codes
Previously dpkg -s would allow a 0 or 1 exit status and it wasn't entirely clear why this was so either from the code or the tests. This restores throwing an exception if we are outside of the [0,1] range, and then adds tests for both behaviors: - on old ubuntu/debian we get an exit(0) and output on stdout if the file is not installed - on newer ubuntu/debian we get an exit(1) and output on stderr if the file is not installed Added tests for both those cases, and the case where dpkg -s does some other kind of exitcode barf and we should raise.
-rw-r--r--lib/chef/provider/package/dpkg.rb2
-rw-r--r--spec/unit/provider/package/dpkg_spec.rb41
2 files changed, 39 insertions, 4 deletions
diff --git a/lib/chef/provider/package/dpkg.rb b/lib/chef/provider/package/dpkg.rb
index 35c55e366c..0da675e883 100644
--- a/lib/chef/provider/package/dpkg.rb
+++ b/lib/chef/provider/package/dpkg.rb
@@ -109,7 +109,7 @@ class Chef
def read_current_version_of_package(package_name)
Chef::Log.debug("#{new_resource} checking install state of #{package_name}")
- status = shell_out_with_timeout("dpkg -s #{package_name}")
+ status = shell_out_with_timeout!("dpkg -s #{package_name}", returns: [0, 1])
package_installed = false
status.stdout.each_line do |line|
case line
diff --git a/spec/unit/provider/package/dpkg_spec.rb b/spec/unit/provider/package/dpkg_spec.rb
index 15b2903a0e..5b77e7788b 100644
--- a/spec/unit/provider/package/dpkg_spec.rb
+++ b/spec/unit/provider/package/dpkg_spec.rb
@@ -52,7 +52,7 @@ Conflicts: wget-ssl
before(:each) do
allow(provider).to receive(:shell_out!).with("dpkg-deb -W #{source}", timeout: 900).and_return(dpkg_deb_status)
- allow(provider).to receive(:shell_out).with("dpkg -s #{package}", timeout: 900).and_return(double(stdout: "", exitstatus: -1))
+ allow(provider).to receive(:shell_out!).with("dpkg -s #{package}", timeout: 900, returns: [0,1]).and_return(double(stdout: "", exitstatus: 1))
allow(::File).to receive(:exist?).with(source).and_return(true)
end
@@ -169,12 +169,47 @@ Conflicts: wget-ssl
end
it "should return the current version installed if found by dpkg" do
- allow(provider).to receive(:shell_out).with("dpkg -s #{package}", timeout: 900).and_return(dpkg_s_status)
+ allow(provider).to receive(:shell_out!).with("dpkg -s #{package}", timeout: 900, returns: [0,1]).and_return(dpkg_s_status)
provider.load_current_resource
expect(provider.current_resource.version).to eq(["1.11.4-1ubuntu1"])
end
- it "should raise an exception if dpkg fails to run" do
+ it "on new debian/ubuntu we get an exit(1) and no stdout from dpkg -s for uninstalled" do
+ dpkg_s_status = double(
+ exitstatus: 1, stdout: "", stderr: <<-EOF
+dpkg-query: package '#{package}' is not installed and no information is available
+Use dpkg --info (= dpkg-deb --info) to examine archive files,
+and dpkg --contents (= dpkg-deb --contents) to list their contents.
+ EOF
+ )
+ expect(provider).to receive(:shell_out!).with("dpkg -s #{package}", returns: [0, 1], timeout: 900).and_return(dpkg_s_status)
+ provider.load_current_resource
+ expect(provider.current_resource.version).to eq([nil])
+ end
+
+ it "on old debian/ubuntu we get an exit(0) and we get info on stdout from dpkg -s for uninstalled" do
+ dpkg_s_status = double(
+ exitstatus: 0, stderr: "", stdout: <<-EOF
+Package: #{package}
+Status: unknown ok not-installed
+Priority: extra
+Section: ruby
+ EOF
+ )
+ expect(provider).to receive(:shell_out!).with("dpkg -s #{package}", returns: [0, 1], timeout: 900).and_return(dpkg_s_status)
+ provider.load_current_resource
+ expect(provider.current_resource.version).to eq([nil])
+ end
+
+ it "and we should raise if we get any other exit codes from dpkg -s" do
+ dpkg_s_status = double(
+ exitstatus: 3, stderr: "i am very, very angry with you. i'm very, very cross. go to your room.", stdout: ""
+ )
+ expect(provider).to receive(:shell_out!).with("dpkg -s #{package}", returns: [0, 1], timeout: 900).and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ expect { provider.load_current_resource }.to raise_error(Mixlib::ShellOut::ShellCommandFailed)
+ end
+
+ it "should raise an exception if dpkg-deb -W fails to run" do
status = double(:stdout => "", :exitstatus => -1)
expect(provider).to receive(:shell_out_with_timeout!).with("dpkg-deb -W /tmp/wget_1.11.4-1ubuntu1_amd64.deb").and_raise(Mixlib::ShellOut::ShellCommandFailed)
expect { provider.load_current_resource }.to raise_error(Mixlib::ShellOut::ShellCommandFailed)