# # Author:: Caleb Tennis (<caleb.tennis@gmail.com>) # Copyright:: Copyright (c) 2008 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::Package::Portage, "load_current_resource" do before(:each) do @node = Chef::Node.new @events = Chef::EventDispatch::Dispatcher.new @run_context = Chef::RunContext.new(@node, {}, @events) @new_resource = Chef::Resource::Package.new("dev-util/git") @new_resource_without_category = Chef::Resource::Package.new("git") @current_resource = Chef::Resource::Package.new("dev-util/git") @provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context) Chef::Resource::Package.stub(:new).and_return(@current_resource) end describe "when determining the current state of the package" do it "should create a current resource with the name of new_resource" do ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0"]) Chef::Resource::Package.should_receive(:new).and_return(@current_resource) @provider.load_current_resource end it "should set the current resource package name to the new resource package name" do ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0"]) @current_resource.should_receive(:package_name).with(@new_resource.package_name) @provider.load_current_resource end it "should return a current resource with the correct version if the package is found" do ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-foobar-0.9", "/var/db/pkg/dev-util/git-1.0.0"]) @provider.load_current_resource @provider.current_resource.version.should == "1.0.0" end it "should return a current resource with the correct version if the package is found with revision" do ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0-r1"]) @provider.load_current_resource @provider.current_resource.version.should == "1.0.0-r1" end it "should return a current resource with a nil version if the package is not found" do ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/notgit-1.0.0"]) @provider.load_current_resource @provider.current_resource.version.should be_nil end it "should return a package name match from /var/db/pkg/* if a category isn't specified and a match is found" do ::Dir.stub(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-foobar-0.9", "/var/db/pkg/dev-util/git-1.0.0"]) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) @provider.load_current_resource @provider.current_resource.version.should == "1.0.0" end it "should return a current resource with a nil version if a category isn't specified and a name match from /var/db/pkg/* is not found" do ::Dir.stub(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/notgit-1.0.0"]) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) @provider.load_current_resource @provider.current_resource.version.should be_nil end it "should throw an exception if a category isn't specified and multiple packages are found" do ::Dir.stub(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/funny-words/git-1.0.0"]) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Package) end it "should return a current resource with a nil version if a category is specified and multiple packages are found" do ::Dir.stub(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/funny-words/git-1.0.0"]) @provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context) @provider.load_current_resource @provider.current_resource.version.should be_nil end it "should return a current resource with a nil version if a category is not specified and multiple packages from the same category are found" do ::Dir.stub(:[]).with("/var/db/pkg/*/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0", "/var/db/pkg/dev-util/git-1.0.1"]) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) @provider.load_current_resource @provider.current_resource.version.should be_nil end end describe "once the state of the package is known" do describe Chef::Provider::Package::Portage, "candidate_version" do it "should return the candidate_version variable if already set" do @provider.candidate_version = "1.0.0" @provider.should_not_receive(:popen4) @provider.candidate_version end it "should throw an exception if the exitstatus is not 0" do @status = double("Status", :exitstatus => 1) @provider.stub(:popen4).and_return(@status) lambda { @provider.candidate_version }.should raise_error(Chef::Exceptions::Package) end it "should find the candidate_version if a category is specifed and there are no duplicates" do output = <<EOF Searching... [ Results for search key : git ] [ Applications found : 14 ] * app-misc/digitemp [ Masked ] Latest version available: 3.5.0 Latest version installed: [ Not Installed ] Size of files: 261 kB Homepage: http://www.digitemp.com/ http://www.ibutton.com/ Description: Temperature logging and reporting using Dallas Semiconductor's iButtons and 1-Wire protocol License: GPL-2 * dev-util/git Latest version available: 1.6.0.6 Latest version installed: ignore Size of files: 2,725 kB Homepage: http://git.or.cz/ Description: GIT - the stupid content tracker, the revision control system heavily used by the Linux kernel team License: GPL-2 * dev-util/gitosis [ Masked ] Latest version available: 0.2_p20080825 Latest version installed: [ Not Installed ] Size of files: 31 kB Homepage: http://eagain.net/gitweb/?p=gitosis.git;a=summary Description: gitosis -- software for hosting git repositories License: GPL-2 EOF @status = double("Status", :exitstatus => 0) @provider.should_receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status) @provider.candidate_version.should == "1.6.0.6" end it "should find the candidate_version if a category is not specifed and there are no duplicates" do output = <<EOF Searching... [ Results for search key : git ] [ Applications found : 14 ] * app-misc/digitemp [ Masked ] Latest version available: 3.5.0 Latest version installed: [ Not Installed ] Size of files: 261 kB Homepage: http://www.digitemp.com/ http://www.ibutton.com/ Description: Temperature logging and reporting using Dallas Semiconductor's iButtons and 1-Wire protocol License: GPL-2 * dev-util/git Latest version available: 1.6.0.6 Latest version installed: ignore Size of files: 2,725 kB Homepage: http://git.or.cz/ Description: GIT - the stupid content tracker, the revision control system heavily used by the Linux kernel team License: GPL-2 * dev-util/gitosis [ Masked ] Latest version available: 0.2_p20080825 Latest version installed: [ Not Installed ] Size of files: 31 kB Homepage: http://eagain.net/gitweb/?p=gitosis.git;a=summary Description: gitosis -- software for hosting git repositories License: GPL-2 EOF @status = double("Status", :exitstatus => 0) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) @provider.should_receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status) @provider.candidate_version.should == "1.6.0.6" end it "should throw an exception if a category is not specified and there are duplicates" do output = <<EOF Searching... [ Results for search key : git ] [ Applications found : 14 ] * app-misc/digitemp [ Masked ] Latest version available: 3.5.0 Latest version installed: [ Not Installed ] Size of files: 261 kB Homepage: http://www.digitemp.com/ http://www.ibutton.com/ Description: Temperature logging and reporting using Dallas Semiconductor's iButtons and 1-Wire protocol License: GPL-2 * app-misc/git Latest version available: 4.3.20 Latest version installed: [ Not Installed ] Size of files: 416 kB Homepage: http://www.gnu.org/software/git/ Description: GNU Interactive Tools - increase speed and efficiency of most daily task License: GPL-2 * dev-util/git Latest version available: 1.6.0.6 Latest version installed: ignore Size of files: 2,725 kB Homepage: http://git.or.cz/ Description: GIT - the stupid content tracker, the revision control system heavily used by the Linux kernel team License: GPL-2 * dev-util/gitosis [ Masked ] Latest version available: 0.2_p20080825 Latest version installed: [ Not Installed ] Size of files: 31 kB Homepage: http://eagain.net/gitweb/?p=gitosis.git;a=summary Description: gitosis -- software for hosting git repositories License: GPL-2 EOF @status = double("Status", :exitstatus => 0) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) @provider.should_receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status) lambda { @provider.candidate_version }.should raise_error(Chef::Exceptions::Package) end it "should find the candidate_version if a category is specifed and there are category duplicates" do output = <<EOF Searching... [ Results for search key : git ] [ Applications found : 14 ] * app-misc/digitemp [ Masked ] Latest version available: 3.5.0 Latest version installed: [ Not Installed ] Size of files: 261 kB Homepage: http://www.digitemp.com/ http://www.ibutton.com/ Description: Temperature logging and reporting using Dallas Semiconductor's iButtons and 1-Wire protocol License: GPL-2 * app-misc/git Latest version available: 4.3.20 Latest version installed: [ Not Installed ] Size of files: 416 kB Homepage: http://www.gnu.org/software/git/ Description: GNU Interactive Tools - increase speed and efficiency of most daily task License: GPL-2 * dev-util/git Latest version available: 1.6.0.6 Latest version installed: ignore Size of files: 2,725 kB Homepage: http://git.or.cz/ Description: GIT - the stupid content tracker, the revision control system heavily used by the Linux kernel team License: GPL-2 * dev-util/gitosis [ Masked ] Latest version available: 0.2_p20080825 Latest version installed: [ Not Installed ] Size of files: 31 kB Homepage: http://eagain.net/gitweb/?p=gitosis.git;a=summary Description: gitosis -- software for hosting git repositories License: GPL-2 EOF @status = double("Status", :exitstatus => 0) @provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context) @provider.should_receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status) @provider.candidate_version.should == "1.6.0.6" end end describe Chef::Provider::Package::Portage, "install_package" do it "should install a normally versioned package using portage" do @provider.should_receive(:run_command_with_systems_locale).with({ :command => "emerge -g --color n --nospinner --quiet =dev-util/git-1.0.0" }) @provider.install_package("dev-util/git", "1.0.0") end it "should install a tilde versioned package using portage" do @provider.should_receive(:run_command_with_systems_locale).with({ :command => "emerge -g --color n --nospinner --quiet ~dev-util/git-1.0.0" }) @provider.install_package("dev-util/git", "~1.0.0") end it "should add options to the emerge command when specified" do @provider.should_receive(:run_command_with_systems_locale).with({ :command => "emerge -g --color n --nospinner --quiet --oneshot =dev-util/git-1.0.0" }) @new_resource.stub(:options).and_return("--oneshot") @provider.install_package("dev-util/git", "1.0.0") end end describe Chef::Provider::Package::Portage, "remove_package" do it "should un-emerge the package with no version specified" do @provider.should_receive(:run_command_with_systems_locale).with({ :command => "emerge --unmerge --color n --nospinner --quiet dev-util/git" }) @provider.remove_package("dev-util/git", nil) end it "should un-emerge the package with a version specified" do @provider.should_receive(:run_command_with_systems_locale).with({ :command => "emerge --unmerge --color n --nospinner --quiet =dev-util/git-1.0.0" }) @provider.remove_package("dev-util/git", "1.0.0") end end end end