# # Author:: Adam Jacob () # Copyright:: Copyright 2008-2016, Chef Software 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" require "ostruct" describe Chef::Provider::Package::Apt do # XXX: sorry this is ugly and was done quickly to get 12.0.2 out, this file needs a rewrite to use # let blocks and shared examples [ Chef::Resource::Package, Chef::Resource::AptPackage ].each do |resource_klass| describe "when the new_resource is a #{resource_klass}" do before(:each) do @node = Chef::Node.new @events = Chef::EventDispatch::Dispatcher.new @run_context = Chef::RunContext.new(@node, {}, @events) @new_resource = resource_klass.new("irssi", @run_context) @status = double("Status", :exitstatus => 0) @provider = Chef::Provider::Package::Apt.new(@new_resource, @run_context) @stdin = StringIO.new @stdout =<<-PKG_STATUS irssi: Installed: (none) Candidate: 0.8.14-1ubuntu4 Version table: 0.8.14-1ubuntu4 0 500 http://us.archive.ubuntu.com/ubuntu/ lucid/main Packages PKG_STATUS @stderr = "" @shell_out = OpenStruct.new(:stdout => @stdout,:stdin => @stdin,:stderr => @stderr,:status => @status,:exitstatus => 0) @timeout = 900 end describe "when loading current resource" do it "should create a current resource with the name of the new_resource" do expect(@provider).to receive(:shell_out!).with( "apt-cache policy #{@new_resource.package_name}", :timeout => @timeout, ).and_return(@shell_out) @provider.load_current_resource current_resource = @provider.current_resource expect(current_resource).to be_a(Chef::Resource::Package) expect(current_resource.name).to eq("irssi") expect(current_resource.package_name).to eq("irssi") expect(current_resource.version).to be_nil end it "should set the installed version if package has one" do @stdout.replace(<<-INSTALLED) sudo: Installed: 1.7.2p1-1ubuntu5.3 Candidate: 1.7.2p1-1ubuntu5.3 Version table: *** 1.7.2p1-1ubuntu5.3 0 500 http://us.archive.ubuntu.com/ubuntu/ lucid-updates/main Packages 500 http://security.ubuntu.com/ubuntu/ lucid-security/main Packages 100 /var/lib/dpkg/status 1.7.2p1-1ubuntu5 0 500 http://us.archive.ubuntu.com/ubuntu/ lucid/main Packages INSTALLED expect(@provider).to receive(:shell_out!).and_return(@shell_out) @provider.load_current_resource expect(@provider.current_resource.version).to eq("1.7.2p1-1ubuntu5.3") expect(@provider.candidate_version).to eql("1.7.2p1-1ubuntu5.3") end # libmysqlclient-dev is a real package in newer versions of debian + ubuntu # list of virtual packages: http://www.debian.org/doc/packaging-manuals/virtual-package-names-list.txt it "should not install the virtual package there is a single provider package and it is installed" do @new_resource.package_name("libmysqlclient15-dev") virtual_package_out=<<-VPKG_STDOUT libmysqlclient15-dev: Installed: (none) Candidate: (none) Version table: VPKG_STDOUT virtual_package = double(:stdout => virtual_package_out,:exitstatus => 0) expect(@provider).to receive(:shell_out!).with( "apt-cache policy libmysqlclient15-dev", :timeout => @timeout, ).and_return(virtual_package) showpkg_out =<<-SHOWPKG_STDOUT Package: libmysqlclient15-dev Versions: Reverse Depends: libmysqlclient-dev,libmysqlclient15-dev libmysqlclient-dev,libmysqlclient15-dev libmysqlclient-dev,libmysqlclient15-dev libmysqlclient-dev,libmysqlclient15-dev libmysqlclient-dev,libmysqlclient15-dev libmysqlclient-dev,libmysqlclient15-dev Dependencies: Provides: Reverse Provides: libmysqlclient-dev 5.1.41-3ubuntu12.7 libmysqlclient-dev 5.1.41-3ubuntu12.10 libmysqlclient-dev 5.1.41-3ubuntu12 SHOWPKG_STDOUT showpkg = double(:stdout => showpkg_out,:exitstatus => 0) expect(@provider).to receive(:shell_out!).with( "apt-cache showpkg libmysqlclient15-dev", :timeout => @timeout, ).and_return(showpkg) real_package_out=<<-RPKG_STDOUT libmysqlclient-dev: Installed: 5.1.41-3ubuntu12.10 Candidate: 5.1.41-3ubuntu12.10 Version table: *** 5.1.41-3ubuntu12.10 0 500 http://us.archive.ubuntu.com/ubuntu/ lucid-updates/main Packages 100 /var/lib/dpkg/status 5.1.41-3ubuntu12.7 0 500 http://security.ubuntu.com/ubuntu/ lucid-security/main Packages 5.1.41-3ubuntu12 0 500 http://us.archive.ubuntu.com/ubuntu/ lucid/main Packages RPKG_STDOUT real_package = double(:stdout => real_package_out,:exitstatus => 0) expect(@provider).to receive(:shell_out!).with( "apt-cache policy libmysqlclient-dev", :timeout => @timeout, ).and_return(real_package) @provider.load_current_resource end it "should raise an exception if you specify a virtual package with multiple provider packages" do @new_resource.package_name("mp3-decoder") virtual_package_out=<<-VPKG_STDOUT mp3-decoder: Installed: (none) Candidate: (none) Version table: VPKG_STDOUT virtual_package = double(:stdout => virtual_package_out,:exitstatus => 0) expect(@provider).to receive(:shell_out!).with( "apt-cache policy mp3-decoder", :timeout => @timeout, ).and_return(virtual_package) showpkg_out=<<-SHOWPKG_STDOUT Package: mp3-decoder Versions: Reverse Depends: nautilus,mp3-decoder vux,mp3-decoder plait,mp3-decoder ecasound,mp3-decoder nautilus,mp3-decoder Dependencies: Provides: Reverse Provides: vlc-nox 1.0.6-1ubuntu1.8 vlc 1.0.6-1ubuntu1.8 vlc-nox 1.0.6-1ubuntu1 vlc 1.0.6-1ubuntu1 opencubicplayer 1:0.1.17-2 mpg321 0.2.10.6 mpg123 1.12.1-0ubuntu1 SHOWPKG_STDOUT showpkg = double(:stdout => showpkg_out,:exitstatus => 0) expect(@provider).to receive(:shell_out!).with( "apt-cache showpkg mp3-decoder", :timeout => @timeout, ).and_return(showpkg) expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Package) end it "should run apt-cache policy with the default_release option, if there is one on the resource" do @new_resource = Chef::Resource::AptPackage.new("irssi", @run_context) @provider = Chef::Provider::Package::Apt.new(@new_resource, @run_context) allow(@new_resource).to receive(:default_release).and_return("lenny-backports") allow(@new_resource).to receive(:provider).and_return(nil) expect(@provider).to receive(:shell_out!).with( "apt-cache -o APT::Default-Release=lenny-backports policy irssi", :timeout => @timeout, ).and_return(@shell_out) @provider.load_current_resource end it "raises an exception if a source is specified (CHEF-5113)" do @new_resource.source "pluto" expect(@provider).to receive(:shell_out!).with( "apt-cache policy #{@new_resource.package_name}", :timeout => @timeout, ).and_return(@shell_out) @provider.load_current_resource @provider.define_resource_requirements expect(@provider).to receive(:shell_out!).with("apt-cache policy irssi", {:timeout=>900}).and_return(@shell_out) expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package) end end context "after loading the current resource" do before do @current_resource = resource_klass.new("irssi", @run_context) @provider.current_resource = @current_resource end describe "install_package" do it "should run apt-get install with the package name and version" do expect(@provider).to receive(:shell_out!). with( "apt-get -q -y install irssi=0.8.12-7", :env => { "DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil}, :timeout => @timeout, ) @provider.install_package("irssi", "0.8.12-7") end it "should run apt-get install with the package name and version and options if specified" do expect(@provider).to receive(:shell_out!).with( "apt-get -q -y --force-yes install irssi=0.8.12-7", :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil }, :timeout => @timeout, ) @new_resource.options("--force-yes") @provider.install_package("irssi", "0.8.12-7") end it "should run apt-get install with the package name and version and default_release if there is one and provider is explicitly defined" do @new_resource = nil @new_resource = Chef::Resource::AptPackage.new("irssi", @run_context) @new_resource.default_release("lenny-backports") @new_resource.provider = nil @provider.new_resource = @new_resource expect(@provider).to receive(:shell_out!).with( "apt-get -q -y -o APT::Default-Release=lenny-backports install irssi=0.8.12-7", :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil }, :timeout => @timeout, ) @provider.install_package("irssi", "0.8.12-7") end end describe resource_klass, "upgrade_package" do it "should run install_package with the name and version" do expect(@provider).to receive(:install_package).with("irssi", "0.8.12-7") @provider.upgrade_package("irssi", "0.8.12-7") end end describe resource_klass, "remove_package" do it "should run apt-get remove with the package name" do expect(@provider).to receive(:shell_out!).with( "apt-get -q -y remove irssi", :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil}, :timeout => @timeout, ) @provider.remove_package("irssi", "0.8.12-7") end it "should run apt-get remove with the package name and options if specified" do expect(@provider).to receive(:shell_out!).with( "apt-get -q -y --force-yes remove irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil }, :timeout => @timeout, ) @new_resource.options("--force-yes") @provider.remove_package("irssi", "0.8.12-7") end end describe "when purging a package" do it "should run apt-get purge with the package name" do expect(@provider).to receive(:shell_out!).with( "apt-get -q -y purge irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil }, :timeout => @timeout, ) @provider.purge_package("irssi", "0.8.12-7") end it "should run apt-get purge with the package name and options if specified" do expect(@provider).to receive(:shell_out!).with( "apt-get -q -y --force-yes purge irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil }, :timeout => @timeout, ) @new_resource.options("--force-yes") @provider.purge_package("irssi", "0.8.12-7") end end describe "when preseeding a package" do before(:each) do allow(@provider).to receive(:get_preseed_file).and_return("/tmp/irssi-0.8.12-7.seed") end it "should get the full path to the preseed response file" do file = "/tmp/irssi-0.8.12-7.seed" expect(@provider).to receive(:shell_out!).with( "debconf-set-selections /tmp/irssi-0.8.12-7.seed", :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil}, :timeout => @timeout, ) @provider.preseed_package(file) end it "should run debconf-set-selections on the preseed file if it has changed" do expect(@provider).to receive(:shell_out!).with( "debconf-set-selections /tmp/irssi-0.8.12-7.seed", :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil}, :timeout => @timeout, ) file = @provider.get_preseed_file("irssi", "0.8.12-7") @provider.preseed_package(file) end it "should not run debconf-set-selections if the preseed file has not changed" do allow(@provider).to receive(:check_all_packages_state) @current_resource.version "0.8.11" @new_resource.response_file "/tmp/file" allow(@provider).to receive(:get_preseed_file).and_return(false) expect(@provider).not_to receive(:shell_out!) @provider.run_action(:reconfig) end end describe "when reconfiguring a package" do it "should run dpkg-reconfigure package" do expect(@provider).to receive(:shell_out!).with( "dpkg-reconfigure irssi", :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil }, :timeout => @timeout, ) @provider.reconfig_package("irssi", "0.8.12-7") end end describe "when installing a virtual package" do it "should install the package without specifying a version" do @provider.is_virtual_package["libmysqlclient-dev"] = true expect(@provider).to receive(:shell_out!).with( "apt-get -q -y install libmysqlclient-dev", :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil }, :timeout => @timeout, ) @provider.install_package("libmysqlclient-dev", "not_a_real_version") end end describe "when installing multiple packages" do it "can install a virtual package followed by a non-virtual package" do # https://github.com/chef/chef/issues/2914 @provider.is_virtual_package["libmysqlclient-dev"] = true @provider.is_virtual_package["irssi"] = false expect(@provider).to receive(:shell_out!).with( "apt-get -q -y install libmysqlclient-dev irssi=0.8.12-7", :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil }, :timeout => @timeout, ) @provider.install_package(["libmysqlclient-dev", "irssi"], ["not_a_real_version", "0.8.12-7"]) end end end end end end