summaryrefslogtreecommitdiff
path: root/spec/unit/provider/package/yum_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit/provider/package/yum_spec.rb')
-rw-r--r--spec/unit/provider/package/yum_spec.rb1795
1 files changed, 1795 insertions, 0 deletions
diff --git a/spec/unit/provider/package/yum_spec.rb b/spec/unit/provider/package/yum_spec.rb
new file mode 100644
index 0000000000..0002ec39f3
--- /dev/null
+++ b/spec/unit/provider/package/yum_spec.rb
@@ -0,0 +1,1795 @@
+#
+# Author:: Adam Jacob (<adam@opscode.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::Yum 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('cups')
+ @status = mock("Status", :exitstatus => 0)
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.18.el5_2.3",
+ :package_available? => true,
+ :version_available? => true,
+ :allow_multi_install => [ "kernel" ],
+ :package_repository => "base"
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @stderr = StringIO.new
+ @pid = mock("PID")
+ end
+
+ describe "when loading the current system state" do
+ it "should create a current resource with the name of the new_resource" do
+ @provider.load_current_resource
+ @provider.current_resource.name.should == "cups"
+ end
+
+ it "should set the current resources package name to the new resources package name" do
+ @provider.load_current_resource
+ @provider.current_resource.package_name.should == "cups"
+ end
+
+ it "should set the installed version to nil on the current resource if no installed package" do
+ @yum_cache.stub!(:installed_version).and_return(nil)
+ @provider.load_current_resource
+ @provider.current_resource.version.should be_nil
+ end
+
+ it "should set the installed version if yum has one" do
+ @provider.load_current_resource
+ @provider.current_resource.version.should == "1.2.4-11.18.el5"
+ end
+
+ it "should set the candidate version if yum info has one" do
+ @provider.load_current_resource
+ @provider.candidate_version.should eql("1.2.4-11.18.el5_2.3")
+ end
+
+ it "should return the current resouce" do
+ @provider.load_current_resource.should eql(@provider.current_resource)
+ end
+
+ describe "when arch in package_name" do
+ it "should set the arch if no existing package_name is found and new_package_name+new_arch is available" do
+ @new_resource = Chef::Resource::YumPackage.new('testing.noarch')
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache'
+ )
+ @yum_cache.stub!(:installed_version) do |package_name, arch|
+ # nothing installed for package_name/new_package_name
+ nil
+ end
+ @yum_cache.stub!(:candidate_version) do |package_name, arch|
+ if package_name == "testing.noarch" || package_name == "testing.more.noarch"
+ nil
+ # candidate for new_package_name
+ elsif package_name == "testing" || package_name == "testing.more"
+ "1.1"
+ end
+ end
+ @yum_cache.stub!(:package_available?).and_return(true)
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @provider.new_resource.package_name.should == "testing"
+ @provider.new_resource.arch.should == "noarch"
+ @provider.arch.should == "noarch"
+
+ @new_resource = Chef::Resource::YumPackage.new('testing.more.noarch')
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @provider.new_resource.package_name.should == "testing.more"
+ @provider.new_resource.arch.should == "noarch"
+ @provider.arch.should == "noarch"
+ end
+
+ it "should not set the arch when an existing package_name is found" do
+ @new_resource = Chef::Resource::YumPackage.new('testing.beta3')
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache'
+ )
+ @yum_cache.stub!(:installed_version) do |package_name, arch|
+ # installed for package_name
+ if package_name == "testing.beta3" || package_name == "testing.beta3.more"
+ "1.1"
+ elsif package_name == "testing" || package_name == "testing.beta3"
+ nil
+ end
+ end
+ @yum_cache.stub!(:candidate_version) do |package_name, arch|
+ # no candidate for package_name/new_package_name
+ nil
+ end
+ @yum_cache.stub!(:package_available?).and_return(true)
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ # annoying side effect of the fun stub'ing above
+ @provider.load_current_resource
+ @provider.new_resource.package_name.should == "testing.beta3"
+ @provider.new_resource.arch.should == nil
+ @provider.arch.should == nil
+
+ @new_resource = Chef::Resource::YumPackage.new('testing.beta3.more')
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @provider.new_resource.package_name.should == "testing.beta3.more"
+ @provider.new_resource.arch.should == nil
+ @provider.arch.should == nil
+ end
+
+ it "should not set the arch when no existing package_name or new_package_name+new_arch is found" do
+ @new_resource = Chef::Resource::YumPackage.new('testing.beta3')
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache'
+ )
+ @yum_cache.stub!(:installed_version) do |package_name, arch|
+ # nothing installed for package_name/new_package_name
+ nil
+ end
+ @yum_cache.stub!(:candidate_version) do |package_name, arch|
+ # no candidate for package_name/new_package_name
+ nil
+ end
+ @yum_cache.stub!(:package_available?).and_return(true)
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @provider.new_resource.package_name.should == "testing.beta3"
+ @provider.new_resource.arch.should == nil
+ @provider.arch.should == nil
+
+ @new_resource = Chef::Resource::YumPackage.new('testing.beta3.more')
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @provider.new_resource.package_name.should == "testing.beta3.more"
+ @provider.new_resource.arch.should == nil
+ @provider.arch.should == nil
+ end
+
+ it "should ensure it doesn't clobber an existing arch if passed" do
+ @new_resource = Chef::Resource::YumPackage.new('testing.i386')
+ @new_resource.arch("x86_64")
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache'
+ )
+ @yum_cache.stub!(:installed_version) do |package_name, arch|
+ # nothing installed for package_name/new_package_name
+ nil
+ end
+ @yum_cache.stub!(:candidate_version) do |package_name, arch|
+ if package_name == "testing.noarch"
+ nil
+ # candidate for new_package_name
+ elsif package_name == "testing"
+ "1.1"
+ end
+ end.and_return("something")
+ @yum_cache.stub!(:package_available?).and_return(true)
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @provider.new_resource.package_name.should == "testing.i386"
+ @provider.new_resource.arch.should == "x86_64"
+ end
+ end
+
+ it "should flush the cache if :before is true" do
+ @new_resource.stub!(:flush_cache).and_return({:after => false, :before => true})
+ @yum_cache.should_receive(:reload).once
+ @provider.load_current_resource
+ end
+
+ it "should flush the cache if :before is false" do
+ @new_resource.stub!(:flush_cache).and_return({:after => false, :before => false})
+ @yum_cache.should_not_receive(:reload)
+ @provider.load_current_resource
+ end
+
+ it "should search provides if package name can't be found then set package_name to match" do
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.18.el5",
+ :package_available? => false,
+ :version_available? => true
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ pkg = Chef::Provider::Package::Yum::RPMPackage.new("test-package", "1.2.4-11.18.el5", "x86_64", [])
+ @yum_cache.should_receive(:packages_from_require).and_return([pkg])
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @new_resource.package_name.should == "test-package"
+ end
+
+ it "should search provides if package name can't be found, warn about multiple matches, but use the first one" do
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.18.el5",
+ :package_available? => false,
+ :version_available? => true
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ pkg_x = Chef::Provider::Package::Yum::RPMPackage.new("test-package-x", "1.2.4-11.18.el5", "x86_64", [])
+ pkg_y = Chef::Provider::Package::Yum::RPMPackage.new("test-package-y", "1.2.6-11.3.el5", "i386", [])
+ @yum_cache.should_receive(:packages_from_require).and_return([pkg_x, pkg_y])
+ Chef::Log.should_receive(:warn).exactly(1).times.with(%r{matched multiple Provides})
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @new_resource.package_name.should == "test-package-x"
+ end
+
+ it "should search provides if no package is available - if no match in installed provides then load the complete set" do
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.18.el5",
+ :package_available? => false,
+ :version_available? => true
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @yum_cache.should_receive(:packages_from_require).twice.and_return([])
+ @yum_cache.should_receive(:reload_provides)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ end
+
+ it "should search provides if no package is available and not load the complete set if action is :remove or :purge" do
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.18.el5",
+ :package_available? => false,
+ :version_available? => true
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @yum_cache.should_receive(:packages_from_require).once.and_return([])
+ @yum_cache.should_not_receive(:reload_provides)
+ @new_resource.action(:remove)
+ @provider.load_current_resource
+ @yum_cache.should_receive(:packages_from_require).once.and_return([])
+ @yum_cache.should_not_receive(:reload_provides)
+ @new_resource.action(:purge)
+ @provider.load_current_resource
+ end
+
+ it "should search provides if no package is available - if no match in provides leave the name intact" do
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_provides => true,
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.18.el5",
+ :package_available? => false,
+ :version_available? => true
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @yum_cache.should_receive(:packages_from_require).twice.and_return([])
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @new_resource.package_name.should == "cups"
+ end
+ end
+
+ describe "when installing a package" do
+ it "should run yum install with the package name and version" do
+ @provider.load_current_resource
+ Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y install emacs-1.0"
+ )
+ @provider.install_package("emacs", "1.0")
+ end
+
+ it "should run yum localinstall if given a path to an rpm" do
+ @new_resource.stub!(:source).and_return("/tmp/emacs-21.4-20.el5.i386.rpm")
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y localinstall /tmp/emacs-21.4-20.el5.i386.rpm"
+ )
+ @provider.install_package("emacs", "21.4-20.el5")
+ end
+
+ it "should run yum localinstall if given a path to an rpm as the package" do
+ @new_resource = Chef::Resource::Package.new("/tmp/emacs-21.4-20.el5.i386.rpm")
+ ::File.stub!(:exists?).and_return(true)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @new_resource.source.should == "/tmp/emacs-21.4-20.el5.i386.rpm"
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y localinstall /tmp/emacs-21.4-20.el5.i386.rpm"
+ )
+ @provider.install_package("/tmp/emacs-21.4-20.el5.i386.rpm", "21.4-20.el5")
+ end
+
+ it "should run yum install with the package name, version and arch" do
+ @provider.load_current_resource
+ @new_resource.stub!(:arch).and_return("i386")
+ Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y install emacs-21.4-20.el5.i386"
+ )
+ @provider.install_package("emacs", "21.4-20.el5")
+ end
+
+ it "installs the package with the options given in the resource" do
+ @provider.load_current_resource
+ @provider.candidate_version = '11'
+ @new_resource.stub!(:options).and_return("--disablerepo epmd")
+ Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y --disablerepo epmd install cups-11"
+ )
+ @provider.install_package(@new_resource.name, @provider.candidate_version)
+ end
+
+ it "should raise an exception if the package is not available" do
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_from_cache => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.18.el5_2.3",
+ :package_available? => true,
+ :version_available? => nil
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ lambda { @provider.install_package("lolcats", "0.99") }.should raise_error(Chef::Exceptions::Package, %r{Version .* not found})
+ end
+
+ it "should raise an exception if candidate version is older than the installed version and allow_downgrade is false" do
+ @new_resource.stub!(:allow_downgrade).and_return(false)
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.15.el5",
+ :package_available? => true,
+ :version_available? => true,
+ :allow_multi_install => [ "kernel" ]
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ lambda { @provider.install_package("cups", "1.2.4-11.15.el5") }.should raise_error(Chef::Exceptions::Package, %r{is newer than candidate package})
+ end
+
+ it "should not raise an exception if candidate version is older than the installed version and the package is list in yum's installonlypkg option" do
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.15.el5",
+ :package_available? => true,
+ :version_available? => true,
+ :allow_multi_install => [ "cups" ],
+ :package_repository => "base"
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y install cups-1.2.4-11.15.el5"
+ )
+ @provider.install_package("cups", "1.2.4-11.15.el5")
+ end
+
+ it "should run yum downgrade if candidate version is older than the installed version and allow_downgrade is true" do
+ @new_resource.stub!(:allow_downgrade).and_return(true)
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.15.el5",
+ :package_available? => true,
+ :version_available? => true,
+ :allow_multi_install => [],
+ :package_repository => "base"
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y downgrade cups-1.2.4-11.15.el5"
+ )
+ @provider.install_package("cups", "1.2.4-11.15.el5")
+ end
+
+ it "should run yum install then flush the cache if :after is true" do
+ @new_resource.stub!(:flush_cache).and_return({:after => true, :before => false})
+ @provider.load_current_resource
+ Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y install emacs-1.0"
+ )
+ @yum_cache.should_receive(:reload).once
+ @provider.install_package("emacs", "1.0")
+ end
+
+ it "should run yum install then not flush the cache if :after is false" do
+ @new_resource.stub!(:flush_cache).and_return({:after => false, :before => false})
+ @provider.load_current_resource
+ Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y install emacs-1.0"
+ )
+ @yum_cache.should_not_receive(:reload)
+ @provider.install_package("emacs", "1.0")
+ end
+ end
+
+ describe "when upgrading a package" do
+ it "should run yum install if the package is installed and a version is given" do
+ @provider.load_current_resource
+ @provider.candidate_version = '11'
+ Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y install cups-11"
+ )
+ @provider.upgrade_package(@new_resource.name, @provider.candidate_version)
+ end
+
+ it "should run yum install if the package is not installed" do
+ @provider.load_current_resource
+ @current_resource = Chef::Resource::Package.new('cups')
+ @provider.candidate_version = '11'
+ Chef::Provider::Package::Yum::RPMUtils.stub!(:rpmvercmp).and_return(-1)
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y install cups-11"
+ )
+ @provider.upgrade_package(@new_resource.name, @provider.candidate_version)
+ end
+
+ it "should raise an exception if candidate version is older than the installed version" do
+ @yum_cache = mock(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.2.4-11.18.el5",
+ :candidate_version => "1.2.4-11.15.el5",
+ :package_available? => true,
+ :version_available? => true,
+ :allow_multi_install => [ "kernel" ]
+ )
+ Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ lambda { @provider.upgrade_package("cups", "1.2.4-11.15.el5") }.should raise_error(Chef::Exceptions::Package, %r{is newer than candidate package})
+ end
+
+ # Test our little workaround, some crossover into Chef::Provider::Package territory
+ it "should call action_upgrade in the parent if the current resource version is nil" do
+ @yum_cache.stub!(:installed_version).and_return(nil)
+ @provider.load_current_resource
+ @current_resource = Chef::Resource::Package.new('cups')
+ @provider.candidate_version = '11'
+ @provider.should_receive(:upgrade_package).with(
+ "cups",
+ "11"
+ )
+ @provider.action_upgrade
+ @provider.converge
+ end
+
+ it "should call action_upgrade in the parent if the candidate version is nil" do
+ @provider.load_current_resource
+ @current_resource = Chef::Resource::Package.new('cups')
+ @provider.candidate_version = nil
+ @provider.should_not_receive(:upgrade_package)
+ @provider.action_upgrade
+ @provider.converge
+ end
+
+ it "should call action_upgrade in the parent if the candidate is newer" do
+ @provider.load_current_resource
+ @current_resource = Chef::Resource::Package.new('cups')
+ @provider.candidate_version = '11'
+ @provider.should_receive(:upgrade_package).with(
+ "cups",
+ "11"
+ )
+ @provider.action_upgrade
+ @provider.converge
+ end
+
+ it "should not call action_upgrade in the parent if the candidate is older" do
+ @yum_cache.stub!(:installed_version).and_return("12")
+ @provider.load_current_resource
+ @current_resource = Chef::Resource::Package.new('cups')
+ @provider.candidate_version = '11'
+ @provider.should_not_receive(:upgrade_package)
+ @provider.action_upgrade
+ @provider.converge
+ end
+ end
+
+ describe "when removing a package" do
+ it "should run yum remove with the package name" do
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y remove emacs-1.0"
+ )
+ @provider.remove_package("emacs", "1.0")
+ end
+
+ it "should run yum remove with the package name and arch" do
+ @new_resource.stub!(:arch).and_return("x86_64")
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y remove emacs-1.0.x86_64"
+ )
+ @provider.remove_package("emacs", "1.0")
+ end
+ end
+
+ describe "when purging a package" do
+ it "should run yum remove with the package name" do
+ @provider.should_receive(:yum_command).with(
+ "yum -d0 -e0 -y remove emacs-1.0"
+ )
+ @provider.purge_package("emacs", "1.0")
+ end
+ end
+
+ describe "when running yum" do
+ it "should run yum once if it exits with a return code of 0" do
+ @status = mock("Status", :exitstatus => 0)
+ @provider.stub!(:output_of_command).and_return([@status, "", ""])
+ @provider.should_receive(:output_of_command).once.with(
+ "yum -d0 -e0 -y install emacs-1.0",
+ {}
+ )
+ @provider.yum_command("yum -d0 -e0 -y install emacs-1.0")
+ end
+
+ it "should run yum once if it exits with a return code > 0 and no scriptlet failures" do
+ @status = mock("Status", :exitstatus => 2)
+ @provider.stub!(:output_of_command).and_return([@status, "failure failure", "problem problem"])
+ @provider.should_receive(:output_of_command).once.with(
+ "yum -d0 -e0 -y install emacs-1.0",
+ {}
+ )
+ lambda { @provider.yum_command("yum -d0 -e0 -y install emacs-1.0") }.should raise_error(Chef::Exceptions::Exec)
+ end
+
+ it "should run yum once if it exits with a return code of 1 and %pre scriptlet failures" do
+ @status = mock("Status", :exitstatus => 1)
+ @provider.stub!(:output_of_command).and_return([@status, "error: %pre(demo-1-1.el5.centos.x86_64) scriptlet failed, exit status 2", ""])
+ @provider.should_receive(:output_of_command).once.with(
+ "yum -d0 -e0 -y install emacs-1.0",
+ {}
+ )
+ # will still raise an exception, can't stub out the subsequent call
+ lambda { @provider.yum_command("yum -d0 -e0 -y install emacs-1.0") }.should raise_error(Chef::Exceptions::Exec)
+ end
+
+ it "should run yum twice if it exits with a return code of 1 and %post scriptlet failures" do
+ @status = mock("Status", :exitstatus => 1)
+ @provider.stub!(:output_of_command).and_return([@status, "error: %post(demo-1-1.el5.centos.x86_64) scriptlet failed, exit status 2", ""])
+ @provider.should_receive(:output_of_command).twice.with(
+ "yum -d0 -e0 -y install emacs-1.0",
+ {}
+ )
+ # will still raise an exception, can't stub out the subsequent call
+ lambda { @provider.yum_command("yum -d0 -e0 -y install emacs-1.0") }.should raise_error(Chef::Exceptions::Exec)
+ end
+ end
+end
+
+describe Chef::Provider::Package::Yum::RPMUtils do
+ describe "version_parse" do
+ before do
+ @rpmutils = Chef::Provider::Package::Yum::RPMUtils
+ end
+
+ it "parses known good epoch strings" do
+ [
+ [ "0:3.3", [ 0, "3.3", nil ] ],
+ [ "9:1.7.3", [ 9, "1.7.3", nil ] ],
+ [ "15:20020927", [ 15, "20020927", nil ] ]
+ ].each do |x, y|
+ @rpmutils.version_parse(x).should == y
+ end
+ end
+
+ it "parses strange epoch strings" do
+ [
+ [ ":3.3", [ 0, "3.3", nil ] ],
+ [ "-1:1.7.3", [ nil, nil, "1:1.7.3" ] ],
+ [ "-:20020927", [ nil, nil, ":20020927" ] ]
+ ].each do |x, y|
+ @rpmutils.version_parse(x).should == y
+ end
+ end
+
+ it "parses known good version strings" do
+ [
+ [ "3.3", [ nil, "3.3", nil ] ],
+ [ "1.7.3", [ nil, "1.7.3", nil ] ],
+ [ "20020927", [ nil, "20020927", nil ] ]
+ ].each do |x, y|
+ @rpmutils.version_parse(x).should == y
+ end
+ end
+
+ it "parses strange version strings" do
+ [
+ [ "3..3", [ nil, "3..3", nil ] ],
+ [ "0001.7.3", [ nil, "0001.7.3", nil ] ],
+ [ "20020927,3", [ nil, "20020927,3", nil ] ]
+ ].each do |x, y|
+ @rpmutils.version_parse(x).should == y
+ end
+ end
+
+ it "parses known good version release strings" do
+ [
+ [ "3.3-0.pre3.1.60.el5_5.1", [ nil, "3.3", "0.pre3.1.60.el5_5.1" ] ],
+ [ "1.7.3-1jpp.2.el5", [ nil, "1.7.3", "1jpp.2.el5" ] ],
+ [ "20020927-46.el5", [ nil, "20020927", "46.el5" ] ]
+ ].each do |x, y|
+ @rpmutils.version_parse(x).should == y
+ end
+ end
+
+ it "parses strange version release strings" do
+ [
+ [ "3.3-", [ nil, "3.3", nil ] ],
+ [ "-1jpp.2.el5", [ nil, nil, "1jpp.2.el5" ] ],
+ [ "-0020020927-46.el5", [ nil, "-0020020927", "46.el5" ] ]
+ ].each do |x, y|
+ @rpmutils.version_parse(x).should == y
+ end
+ end
+ end
+
+ describe "rpmvercmp" do
+ before do
+ @rpmutils = Chef::Provider::Package::Yum::RPMUtils
+ end
+
+ it "should validate version compare logic for standard examples" do
+ [
+ # numeric
+ [ "0.0.2", "0.0.1", 1 ],
+ [ "0.2.0", "0.1.0", 1 ],
+ [ "2.0.0", "1.0.0", 1 ],
+ [ "0.0.1", "0.0.1", 0 ],
+ [ "0.0.1", "0.0.2", -1 ],
+ [ "0.1.0", "0.2.0", -1 ],
+ [ "1.0.0", "2.0.0", -1 ],
+ # alpha
+ [ "bb", "aa", 1 ],
+ [ "ab", "aa", 1 ],
+ [ "aa", "aa", 0 ],
+ [ "aa", "bb", -1 ],
+ [ "aa", "ab", -1 ],
+ [ "BB", "AA", 1 ],
+ [ "AA", "AA", 0 ],
+ [ "AA", "BB", -1 ],
+ [ "aa", "AA", 1 ],
+ [ "AA", "aa", -1 ],
+ # alphanumeric
+ [ "0.0.1b", "0.0.1a", 1 ],
+ [ "0.1b.0", "0.1a.0", 1 ],
+ [ "1b.0.0", "1a.0.0", 1 ],
+ [ "0.0.1a", "0.0.1a", 0 ],
+ [ "0.0.1a", "0.0.1b", -1 ],
+ [ "0.1a.0", "0.1b.0", -1 ],
+ [ "1a.0.0", "1b.0.0", -1 ],
+ # alphanumeric against alphanumeric
+ [ "0.0.1", "0.0.a", 1 ],
+ [ "0.1.0", "0.a.0", 1 ],
+ [ "1.0.0", "a.0.0", 1 ],
+ [ "0.0.a", "0.0.a", 0 ],
+ [ "0.0.a", "0.0.1", -1 ],
+ [ "0.a.0", "0.1.0", -1 ],
+ [ "a.0.0", "1.0.0", -1 ],
+ # alphanumeric against numeric
+ [ "0.0.2", "0.0.1a", 1 ],
+ [ "0.0.2a", "0.0.1", 1 ],
+ [ "0.0.1", "0.0.2a", -1 ],
+ [ "0.0.1a", "0.0.2", -1 ],
+ # length
+ [ "0.0.1aa", "0.0.1a", 1 ],
+ [ "0.0.1aa", "0.0.1aa", 0 ],
+ [ "0.0.1a", "0.0.1aa", -1 ],
+ ].each do |x, y, result|
+ @rpmutils.rpmvercmp(x,y).should == result
+ end
+ end
+
+ it "should validate version compare logic for strange examples" do
+ [
+ [ "2,0,0", "1.0.0", 1 ],
+ [ "0.0.1", "0,0.1", 0 ],
+ [ "1.0.0", "2,0,0", -1 ],
+ [ "002.0.0", "001.0.0", 1 ],
+ [ "001..0.1", "001..0.0", 1 ],
+ [ "-001..1", "-001..0", 1 ],
+ [ "1.0.1", nil, 1 ],
+ [ nil, nil, 0 ],
+ [ nil, "1.0.1", -1 ],
+ [ "1.0.1", "", 1 ],
+ [ "", "", 0 ],
+ [ "", "1.0.1", -1 ]
+ ].each do |x, y, result|
+ @rpmutils.rpmvercmp(x,y).should == result
+ end
+ end
+
+ it "tests isalnum good input" do
+ [ 'a', 'z', 'A', 'Z', '0', '9' ].each do |t|
+ @rpmutils.isalnum(t).should == true
+ end
+ end
+
+ it "tests isalnum bad input" do
+ [ '-', '.', '!', '^', ':', '_' ].each do |t|
+ @rpmutils.isalnum(t).should == false
+ end
+ end
+
+ it "tests isalpha good input" do
+ [ 'a', 'z', 'A', 'Z', ].each do |t|
+ @rpmutils.isalpha(t).should == true
+ end
+ end
+
+ it "tests isalpha bad input" do
+ [ '0', '9', '-', '.', '!', '^', ':', '_' ].each do |t|
+ @rpmutils.isalpha(t).should == false
+ end
+ end
+
+ it "tests isdigit good input" do
+ [ '0', '9', ].each do |t|
+ @rpmutils.isdigit(t).should == true
+ end
+ end
+
+ it "tests isdigit bad input" do
+ [ 'A', 'z', '-', '.', '!', '^', ':', '_' ].each do |t|
+ @rpmutils.isdigit(t).should == false
+ end
+ end
+ end
+
+end
+
+describe Chef::Provider::Package::Yum::RPMVersion do
+ describe "new - with parsing" do
+ before do
+ @rpmv = Chef::Provider::Package::Yum::RPMVersion.new("1:1.6.5-9.36.el5")
+ end
+
+ it "should expose evr (name-version-release) available" do
+ @rpmv.e.should == 1
+ @rpmv.v.should == "1.6.5"
+ @rpmv.r.should == "9.36.el5"
+
+ @rpmv.evr.should == "1:1.6.5-9.36.el5"
+ end
+
+ it "should output a version-release string" do
+ @rpmv.to_s.should == "1.6.5-9.36.el5"
+ end
+ end
+
+ describe "new - no parsing" do
+ before do
+ @rpmv = Chef::Provider::Package::Yum::RPMVersion.new("1", "1.6.5", "9.36.el5")
+ end
+
+ it "should expose evr (name-version-release) available" do
+ @rpmv.e.should == 1
+ @rpmv.v.should == "1.6.5"
+ @rpmv.r.should == "9.36.el5"
+
+ @rpmv.evr.should == "1:1.6.5-9.36.el5"
+ end
+
+ it "should output a version-release string" do
+ @rpmv.to_s.should == "1.6.5-9.36.el5"
+ end
+ end
+
+ it "should raise an error unless passed 1 or 3 args" do
+ lambda {
+ Chef::Provider::Package::Yum::RPMVersion.new()
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMVersion.new("1:1.6.5-9.36.el5")
+ }.should_not raise_error
+ lambda {
+ Chef::Provider::Package::Yum::RPMVersion.new("1:1.6.5-9.36.el5", "extra")
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMVersion.new("1", "1.6.5", "9.36.el5")
+ }.should_not raise_error
+ lambda {
+ Chef::Provider::Package::Yum::RPMVersion.new("1", "1.6.5", "9.36.el5", "extra")
+ }.should raise_error(ArgumentError)
+ end
+
+ # thanks version_class_spec.rb!
+ describe "compare" do
+ it "should sort based on complete epoch-version-release data" do
+ [
+ # smaller, larger
+ [ "0:1.6.5-9.36.el5",
+ "1:1.6.5-9.36.el5" ],
+ [ "0:2.3-15.el5",
+ "0:3.3-15.el5" ],
+ [ "0:alpha9.8-27.2",
+ "0:beta9.8-27.2" ],
+ [ "0:0.09-14jpp.3",
+ "0:0.09-15jpp.3" ],
+ [ "0:0.9.0-0.6.20110211.el5",
+ "0:0.9.0-0.6.20120211.el5" ],
+ [ "0:1.9.1-4.el5",
+ "0:1.9.1-5.el5" ],
+ [ "0:1.4.10-7.20090624svn.el5",
+ "0:1.4.10-7.20090625svn.el5" ],
+ [ "0:2.3.4-2.el5",
+ "0:2.3.4-2.el6" ]
+ ].each do |smaller, larger|
+ sm = Chef::Provider::Package::Yum::RPMVersion.new(smaller)
+ lg = Chef::Provider::Package::Yum::RPMVersion.new(larger)
+ sm.should be < lg
+ lg.should be > sm
+ sm.should_not == lg
+ end
+ end
+
+ it "should sort based on partial epoch-version-release data" do
+ [
+ # smaller, larger
+ [ ":1.6.5-9.36.el5",
+ "1:1.6.5-9.36.el5" ],
+ [ "2.3-15.el5",
+ "3.3-15.el5" ],
+ [ "alpha9.8",
+ "beta9.8" ],
+ [ "14jpp",
+ "15jpp" ],
+ [ "0.9.0-0.6",
+ "0.9.0-0.7" ],
+ [ "0:1.9",
+ "3:1.9" ],
+ [ "2.3-2.el5",
+ "2.3-2.el6" ]
+ ].each do |smaller, larger|
+ sm = Chef::Provider::Package::Yum::RPMVersion.new(smaller)
+ lg = Chef::Provider::Package::Yum::RPMVersion.new(larger)
+ sm.should be < lg
+ lg.should be > sm
+ sm.should_not == lg
+ end
+ end
+
+ it "should verify equality of complete epoch-version-release data" do
+ [
+ [ "0:1.6.5-9.36.el5",
+ "0:1.6.5-9.36.el5" ],
+ [ "0:2.3-15.el5",
+ "0:2.3-15.el5" ],
+ [ "0:alpha9.8-27.2",
+ "0:alpha9.8-27.2" ]
+ ].each do |smaller, larger|
+ sm = Chef::Provider::Package::Yum::RPMVersion.new(smaller)
+ lg = Chef::Provider::Package::Yum::RPMVersion.new(larger)
+ sm.should be == lg
+ end
+ end
+
+ it "should verify equality of partial epoch-version-release data" do
+ [
+ [ ":1.6.5-9.36.el5",
+ "0:1.6.5-9.36.el5" ],
+ [ "2.3-15.el5",
+ "2.3-15.el5" ],
+ [ "alpha9.8-3",
+ "alpha9.8-3" ]
+ ].each do |smaller, larger|
+ sm = Chef::Provider::Package::Yum::RPMVersion.new(smaller)
+ lg = Chef::Provider::Package::Yum::RPMVersion.new(larger)
+ sm.should be == lg
+ end
+ end
+ end
+
+ describe "partial compare" do
+ it "should compare based on partial epoch-version-release data" do
+ [
+ # smaller, larger
+ [ "0:1.1.1-1",
+ "1:" ],
+ [ "0:1.1.1-1",
+ "0:1.1.2" ],
+ [ "0:1.1.1-1",
+ "0:1.1.2-1" ],
+ [ "0:",
+ "1:1.1.1-1" ],
+ [ "0:1.1.1",
+ "0:1.1.2-1" ],
+ [ "0:1.1.1-1",
+ "0:1.1.2-1" ],
+ ].each do |smaller, larger|
+ sm = Chef::Provider::Package::Yum::RPMVersion.new(smaller)
+ lg = Chef::Provider::Package::Yum::RPMVersion.new(larger)
+ sm.partial_compare(lg).should be == -1
+ lg.partial_compare(sm).should be == 1
+ sm.partial_compare(lg).should_not be == 0
+ end
+ end
+
+ it "should verify equality based on partial epoch-version-release data" do
+ [
+ [ "0:",
+ "0:1.1.1-1" ],
+ [ "0:1.1.1",
+ "0:1.1.1-1" ],
+ [ "0:1.1.1-1",
+ "0:1.1.1-1" ],
+ ].each do |smaller, larger|
+ sm = Chef::Provider::Package::Yum::RPMVersion.new(smaller)
+ lg = Chef::Provider::Package::Yum::RPMVersion.new(larger)
+ sm.partial_compare(lg).should be == 0
+ end
+ end
+ end
+
+end
+
+describe Chef::Provider::Package::Yum::RPMPackage do
+ describe "new - with parsing" do
+ before do
+ @rpm = Chef::Provider::Package::Yum::RPMPackage.new("testing", "1:1.6.5-9.36.el5", "x86_64", [])
+ end
+
+ it "should expose nevra (name-epoch-version-release-arch) available" do
+ @rpm.name.should == "testing"
+ @rpm.version.e.should == 1
+ @rpm.version.v.should == "1.6.5"
+ @rpm.version.r.should == "9.36.el5"
+ @rpm.arch.should == "x86_64"
+
+ @rpm.nevra.should == "testing-1:1.6.5-9.36.el5.x86_64"
+ @rpm.to_s.should == @rpm.nevra
+ end
+
+ it "should always have at least one provide, itself" do
+ @rpm.provides.size.should == 1
+ @rpm.provides[0].name == "testing"
+ @rpm.provides[0].version.evr == "1:1.6.5-9.36.el5"
+ @rpm.provides[0].flag == :==
+ end
+ end
+
+ describe "new - no parsing" do
+ before do
+ @rpm = Chef::Provider::Package::Yum::RPMPackage.new("testing", "1", "1.6.5", "9.36.el5", "x86_64", [])
+ end
+
+ it "should expose nevra (name-epoch-version-release-arch) available" do
+ @rpm.name.should == "testing"
+ @rpm.version.e.should == 1
+ @rpm.version.v.should == "1.6.5"
+ @rpm.version.r.should == "9.36.el5"
+ @rpm.arch.should == "x86_64"
+
+ @rpm.nevra.should == "testing-1:1.6.5-9.36.el5.x86_64"
+ @rpm.to_s.should == @rpm.nevra
+ end
+
+ it "should always have at least one provide, itself" do
+ @rpm.provides.size.should == 1
+ @rpm.provides[0].name == "testing"
+ @rpm.provides[0].version.evr == "1:1.6.5-9.36.el5"
+ @rpm.provides[0].flag == :==
+ end
+ end
+
+ it "should raise an error unless passed 4 or 6 args" do
+ lambda {
+ Chef::Provider::Package::Yum::RPMPackage.new()
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMPackage.new("testing")
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMPackage.new("testing", "1:1.6.5-9.36.el5")
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMPackage.new("testing", "1:1.6.5-9.36.el5", "x86_64")
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMPackage.new("testing", "1:1.6.5-9.36.el5", "x86_64", [])
+ }.should_not raise_error
+ lambda {
+ Chef::Provider::Package::Yum::RPMPackage.new("testing", "1", "1.6.5", "9.36.el5", "x86_64")
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMPackage.new("testing", "1", "1.6.5", "9.36.el5", "x86_64", [])
+ }.should_not raise_error
+ lambda {
+ Chef::Provider::Package::Yum::RPMPackage.new("testing", "1", "1.6.5", "9.36.el5", "x86_64", [], "extra")
+ }.should raise_error(ArgumentError)
+ end
+
+ describe "<=>" do
+ it "should sort alphabetically based on package name" do
+ [
+ [ "a-test",
+ "b-test" ],
+ [ "B-test",
+ "a-test" ],
+ [ "A-test",
+ "B-test" ],
+ [ "Aa-test",
+ "aA-test" ],
+ [ "1test",
+ "2test" ],
+ ].each do |smaller, larger|
+ sm = Chef::Provider::Package::Yum::RPMPackage.new(smaller, "0:0.0.1-1", "x86_64", [])
+ lg = Chef::Provider::Package::Yum::RPMPackage.new(larger, "0:0.0.1-1", "x86_64", [])
+ sm.should be < lg
+ lg.should be > sm
+ sm.should_not == lg
+ end
+ end
+
+ it "should sort alphabetically based on package arch" do
+ [
+ [ "i386",
+ "x86_64" ],
+ [ "i386",
+ "noarch" ],
+ [ "noarch",
+ "x86_64" ],
+ ].each do |smaller, larger|
+ sm = Chef::Provider::Package::Yum::RPMPackage.new("test-package", "0:0.0.1-1", smaller, [])
+ lg = Chef::Provider::Package::Yum::RPMPackage.new("test-package", "0:0.0.1-1", larger, [])
+ sm.should be < lg
+ lg.should be > sm
+ sm.should_not == lg
+ end
+ end
+ end
+
+end
+
+describe Chef::Provider::Package::Yum::RPMDbPackage do
+ before(:each) do
+ # name, version, arch, installed, available, repoid
+ @rpm_x = Chef::Provider::Package::Yum::RPMDbPackage.new("test-package-b", "0:1.6.5-9.36.el5", "noarch", [], false, true, "base")
+ @rpm_y = Chef::Provider::Package::Yum::RPMDbPackage.new("test-package-b", "0:1.6.5-9.36.el5", "noarch", [], true, true, "extras")
+ @rpm_z = Chef::Provider::Package::Yum::RPMDbPackage.new("test-package-b", "0:1.6.5-9.36.el5", "noarch", [], true, false, "other")
+ end
+
+ describe "initialize" do
+ it "should return a Chef::Provider::Package::Yum::RPMDbPackage object" do
+ @rpm_x.should be_kind_of(Chef::Provider::Package::Yum::RPMDbPackage)
+ end
+ end
+
+ describe "available" do
+ it "should return true" do
+ @rpm_x.available.should be == true
+ @rpm_y.available.should be == true
+ @rpm_z.available.should be == false
+ end
+ end
+
+ describe "installed" do
+ it "should return true" do
+ @rpm_x.installed.should be == false
+ @rpm_y.installed.should be == true
+ @rpm_z.installed.should be == true
+ end
+ end
+
+ describe "repoid" do
+ it "should return the source repository repoid" do
+ @rpm_x.repoid.should be == "base"
+ @rpm_y.repoid.should be == "extras"
+ @rpm_z.repoid.should be == "other"
+ end
+ end
+end
+
+describe Chef::Provider::Package::Yum::RPMDependency do
+ describe "new - with parsing" do
+ before do
+ @rpmdep = Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :==)
+ end
+
+ it "should expose name, version, flag available" do
+ @rpmdep.name.should == "testing"
+ @rpmdep.version.e.should == 1
+ @rpmdep.version.v.should == "1.6.5"
+ @rpmdep.version.r.should == "9.36.el5"
+ @rpmdep.flag.should == :==
+ end
+ end
+
+ describe "new - no parsing" do
+ before do
+ @rpmdep = Chef::Provider::Package::Yum::RPMDependency.new("testing", "1", "1.6.5", "9.36.el5", :==)
+ end
+
+ it "should expose name, version, flag available" do
+ @rpmdep.name.should == "testing"
+ @rpmdep.version.e.should == 1
+ @rpmdep.version.v.should == "1.6.5"
+ @rpmdep.version.r.should == "9.36.el5"
+ @rpmdep.flag.should == :==
+ end
+ end
+
+ it "should raise an error unless passed 3 or 5 args" do
+ lambda {
+ Chef::Provider::Package::Yum::RPMDependency.new()
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMDependency.new("testing")
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5")
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :==)
+ }.should_not raise_error
+ lambda {
+ Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :==, "extra")
+ }.should raise_error(ArgumentError)
+ lambda {
+ Chef::Provider::Package::Yum::RPMDependency.new("testing", "1", "1.6.5", "9.36.el5", :==)
+ }.should_not raise_error
+ lambda {
+ Chef::Provider::Package::Yum::RPMDependency.new("testing", "1", "1.6.5", "9.36.el5", :==, "extra")
+ }.should raise_error(ArgumentError)
+ end
+
+ describe "parse" do
+ it "should parse a name, flag, version string into a valid RPMDependency object" do
+ @rpmdep = Chef::Provider::Package::Yum::RPMDependency.parse("testing >= 1:1.6.5-9.36.el5")
+
+ @rpmdep.name.should == "testing"
+ @rpmdep.version.e.should == 1
+ @rpmdep.version.v.should == "1.6.5"
+ @rpmdep.version.r.should == "9.36.el5"
+ @rpmdep.flag.should == :>=
+ end
+
+ it "should parse a name into a valid RPMDependency object" do
+ @rpmdep = Chef::Provider::Package::Yum::RPMDependency.parse("testing")
+
+ @rpmdep.name.should == "testing"
+ @rpmdep.version.e.should == nil
+ @rpmdep.version.v.should == nil
+ @rpmdep.version.r.should == nil
+ @rpmdep.flag.should == :==
+ end
+
+ it "should parse an invalid string into the name of a RPMDependency object" do
+ @rpmdep = Chef::Provider::Package::Yum::RPMDependency.parse("testing blah >")
+
+ @rpmdep.name.should == "testing blah >"
+ @rpmdep.version.e.should == nil
+ @rpmdep.version.v.should == nil
+ @rpmdep.version.r.should == nil
+ @rpmdep.flag.should == :==
+ end
+
+ it "should parse various valid flags" do
+ [
+ [ ">", :> ],
+ [ ">=", :>= ],
+ [ "=", :== ],
+ [ "==", :== ],
+ [ "<=", :<= ],
+ [ "<", :< ]
+ ].each do |before, after|
+ @rpmdep = Chef::Provider::Package::Yum::RPMDependency.parse("testing #{before} 1:1.1-1")
+ @rpmdep.flag.should == after
+ end
+ end
+
+ it "should parse various invalid flags and treat them as names" do
+ [
+ [ "<>", :== ],
+ [ "!=", :== ],
+ [ ">>", :== ],
+ [ "<<", :== ],
+ [ "!", :== ],
+ [ "~", :== ]
+ ].each do |before, after|
+ @rpmdep = Chef::Provider::Package::Yum::RPMDependency.parse("testing #{before} 1:1.1-1")
+ @rpmdep.name.should == "testing #{before} 1:1.1-1"
+ @rpmdep.flag.should == after
+ end
+ end
+ end
+
+ describe "satisfy?" do
+ it "should raise an error unless a RPMDependency is passed" do
+ @rpmprovide = Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :==)
+ @rpmrequire = Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :>=)
+ lambda {
+ @rpmprovide.satisfy?("hi")
+ }.should raise_error(ArgumentError)
+ lambda {
+ @rpmprovide.satisfy?(@rpmrequire)
+ }.should_not raise_error
+ end
+
+ it "should validate dependency satisfaction logic for standard examples" do
+ [
+ # names
+ [ "test", "test", true ],
+ [ "test", "foo", false ],
+ # full: epoch:version-relese
+ [ "testing = 1:1.1-1", "testing > 1:1.1-0", true ],
+ [ "testing = 1:1.1-1", "testing >= 1:1.1-0", true ],
+ [ "testing = 1:1.1-1", "testing >= 1:1.1-1", true ],
+ [ "testing = 1:1.1-1", "testing = 1:1.1-1", true ],
+ [ "testing = 1:1.1-1", "testing == 1:1.1-1", true ],
+ [ "testing = 1:1.1-1", "testing <= 1:1.1-1", true ],
+ [ "testing = 1:1.1-1", "testing <= 1:1.1-0", false ],
+ [ "testing = 1:1.1-1", "testing < 1:1.1-0", false ],
+ # partial: epoch:version
+ [ "testing = 1:1.1", "testing > 1:1.0", true ],
+ [ "testing = 1:1.1", "testing >= 1:1.0", true ],
+ [ "testing = 1:1.1", "testing >= 1:1.1", true ],
+ [ "testing = 1:1.1", "testing = 1:1.1", true ],
+ [ "testing = 1:1.1", "testing == 1:1.1", true ],
+ [ "testing = 1:1.1", "testing <= 1:1.1", true ],
+ [ "testing = 1:1.1", "testing <= 1:1.0", false ],
+ [ "testing = 1:1.1", "testing < 1:1.0", false ],
+ # partial: epoch
+ [ "testing = 1:", "testing > 0:", true ],
+ [ "testing = 1:", "testing >= 0:", true ],
+ [ "testing = 1:", "testing >= 1:", true ],
+ [ "testing = 1:", "testing = 1:", true ],
+ [ "testing = 1:", "testing == 1:", true ],
+ [ "testing = 1:", "testing <= 1:", true ],
+ [ "testing = 1:", "testing <= 0:", false ],
+ [ "testing = 1:", "testing < 0:", false ],
+ # mix and match!
+ [ "testing = 1:1.1-1", "testing == 1:1.1", true ],
+ [ "testing = 1:1.1-1", "testing == 1:", true ],
+ ].each do |prov, req, result|
+ @rpmprovide = Chef::Provider::Package::Yum::RPMDependency.parse(prov)
+ @rpmrequire = Chef::Provider::Package::Yum::RPMDependency.parse(req)
+
+ @rpmprovide.satisfy?(@rpmrequire).should == result
+ @rpmrequire.satisfy?(@rpmprovide).should == result
+ end
+ end
+ end
+
+end
+
+# thanks resource_collection_spec.rb!
+describe Chef::Provider::Package::Yum::RPMDb do
+ before(:each) do
+ @rpmdb = Chef::Provider::Package::Yum::RPMDb.new
+ # name, version, arch, installed, available
+ deps_v = [
+ Chef::Provider::Package::Yum::RPMDependency.parse("libz.so.1()(64bit)"),
+ Chef::Provider::Package::Yum::RPMDependency.parse("test-package-a = 0:1.6.5-9.36.el5")
+ ]
+ deps_z = [
+ Chef::Provider::Package::Yum::RPMDependency.parse("libz.so.1()(64bit)"),
+ Chef::Provider::Package::Yum::RPMDependency.parse("config(test) = 0:1.6.5-9.36.el5"),
+ Chef::Provider::Package::Yum::RPMDependency.parse("test-package-c = 0:1.6.5-9.36.el5")
+ ]
+ @rpm_v = Chef::Provider::Package::Yum::RPMDbPackage.new("test-package-a", "0:1.6.5-9.36.el5", "i386", deps_v, true, false, "base")
+ @rpm_w = Chef::Provider::Package::Yum::RPMDbPackage.new("test-package-b", "0:1.6.5-9.36.el5", "i386", [], true, true, "extras")
+ @rpm_x = Chef::Provider::Package::Yum::RPMDbPackage.new("test-package-b", "0:1.6.5-9.36.el5", "x86_64", [], false, true, "extras")
+ @rpm_y = Chef::Provider::Package::Yum::RPMDbPackage.new("test-package-b", "1:1.6.5-9.36.el5", "x86_64", [], true, true, "extras")
+ @rpm_z = Chef::Provider::Package::Yum::RPMDbPackage.new("test-package-c", "0:1.6.5-9.36.el5", "noarch", deps_z, true, true, "base")
+ @rpm_z_mirror = Chef::Provider::Package::Yum::RPMDbPackage.new("test-package-c", "0:1.6.5-9.36.el5", "noarch", deps_z, true, true, "base")
+ end
+
+ describe "initialize" do
+ it "should return a Chef::Provider::Package::Yum::RPMDb object" do
+ @rpmdb.should be_kind_of(Chef::Provider::Package::Yum::RPMDb)
+ end
+ end
+
+ describe "push" do
+ it "should accept an RPMDbPackage object through pushing" do
+ lambda { @rpmdb.push(@rpm_w) }.should_not raise_error
+ end
+
+ it "should accept multiple RPMDbPackage object through pushing" do
+ lambda { @rpmdb.push(@rpm_w, @rpm_x, @rpm_y, @rpm_z) }.should_not raise_error
+ end
+
+ it "should only accept an RPMDbPackage object" do
+ lambda { @rpmdb.push("string") }.should raise_error
+ end
+
+ it "should add the package to the package db" do
+ @rpmdb.push(@rpm_w)
+ @rpmdb["test-package-b"].should_not be == nil
+ end
+
+ it "should add conditionally add the package to the available list" do
+ @rpmdb.available_size.should be == 0
+ @rpmdb.push(@rpm_v, @rpm_w)
+ @rpmdb.available_size.should be == 1
+ end
+
+ it "should add conditionally add the package to the installed list" do
+ @rpmdb.installed_size.should be == 0
+ @rpmdb.push(@rpm_w, @rpm_x)
+ @rpmdb.installed_size.should be == 1
+ end
+
+ it "should have a total of 2 packages in the RPMDb" do
+ @rpmdb.size.should be == 0
+ @rpmdb.push(@rpm_w, @rpm_x, @rpm_y, @rpm_z)
+ @rpmdb.size.should be == 2
+ end
+
+ it "should keep the Array unique when a duplicate is pushed" do
+ @rpmdb.push(@rpm_z, @rpm_z_mirror)
+ @rpmdb["test-package-c"].size.should be == 1
+ end
+
+ it "should register the package provides in the provides index" do
+ @rpmdb.push(@rpm_v, @rpm_w, @rpm_z)
+ @rpmdb.lookup_provides("test-package-a")[0].should be == @rpm_v
+ @rpmdb.lookup_provides("config(test)")[0].should be == @rpm_z
+ @rpmdb.lookup_provides("libz.so.1()(64bit)")[0].should be == @rpm_v
+ @rpmdb.lookup_provides("libz.so.1()(64bit)")[1].should be == @rpm_z
+ end
+ end
+
+ describe "<<" do
+ it "should accept an RPMPackage object through the << operator" do
+ lambda { @rpmdb << @rpm_w }.should_not raise_error
+ end
+ end
+
+ describe "lookup" do
+ it "should return an Array of RPMPackage objects by index" do
+ @rpmdb << @rpm_w
+ @rpmdb.lookup("test-package-b").should be_kind_of(Array)
+ end
+ end
+
+ describe "[]" do
+ it "should return an Array of RPMPackage objects though the [index] operator" do
+ @rpmdb << @rpm_w
+ @rpmdb["test-package-b"].should be_kind_of(Array)
+ end
+
+ it "should return an Array of 3 RPMPackage objects" do
+ @rpmdb.push(@rpm_w, @rpm_x, @rpm_y, @rpm_z)
+ @rpmdb["test-package-b"].size.should be == 3
+ end
+
+ it "should return an Array of RPMPackage objects sorted from newest to oldest" do
+ @rpmdb.push(@rpm_w, @rpm_x, @rpm_y, @rpm_z)
+ @rpmdb["test-package-b"][0].should be == @rpm_y
+ @rpmdb["test-package-b"][1].should be == @rpm_x
+ @rpmdb["test-package-b"][2].should be == @rpm_w
+ end
+ end
+
+ describe "lookup_provides" do
+ it "should return an Array of RPMPackage objects by index" do
+ @rpmdb << @rpm_z
+ x = @rpmdb.lookup_provides("config(test)")
+ x.should be_kind_of(Array)
+ x[0].should be == @rpm_z
+ end
+ end
+
+ describe "clear" do
+ it "should clear the RPMDb" do
+ @rpmdb.should_receive(:clear_available).once
+ @rpmdb.should_receive(:clear_installed).once
+ @rpmdb.push(@rpm_w, @rpm_x, @rpm_y, @rpm_z)
+ @rpmdb.size.should_not be == 0
+ @rpmdb.lookup_provides("config(test)").should be_kind_of(Array)
+ @rpmdb.clear
+ @rpmdb.lookup_provides("config(test)").should be == nil
+ @rpmdb.size.should be == 0
+ end
+ end
+
+ describe "clear_available" do
+ it "should clear the available list" do
+ @rpmdb.push(@rpm_w, @rpm_x, @rpm_y, @rpm_z)
+ @rpmdb.available_size.should_not be == 0
+ @rpmdb.clear_available
+ @rpmdb.available_size.should be == 0
+ end
+ end
+
+ describe "available?" do
+ it "should return true if a package is available" do
+ @rpmdb.available?(@rpm_w).should be == false
+ @rpmdb.push(@rpm_v, @rpm_w)
+ @rpmdb.available?(@rpm_v).should be == false
+ @rpmdb.available?(@rpm_w).should be == true
+ end
+ end
+
+ describe "clear_installed" do
+ it "should clear the installed list" do
+ @rpmdb.push(@rpm_w, @rpm_x, @rpm_y, @rpm_z)
+ @rpmdb.installed_size.should_not be == 0
+ @rpmdb.clear_installed
+ @rpmdb.installed_size.should be == 0
+ end
+ end
+
+ describe "installed?" do
+ it "should return true if a package is installed" do
+ @rpmdb.installed?(@rpm_w).should be == false
+ @rpmdb.push(@rpm_w, @rpm_x)
+ @rpmdb.installed?(@rpm_w).should be == true
+ @rpmdb.installed?(@rpm_x).should be == false
+ end
+ end
+
+ describe "whatprovides" do
+ it "should raise an error unless a RPMDependency is passed" do
+ @rpmprovide = Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :==)
+ @rpmrequire = Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :>=)
+ lambda {
+ @rpmdb.whatprovides("hi")
+ }.should raise_error(ArgumentError)
+ lambda {
+ @rpmdb.whatprovides(@rpmrequire)
+ }.should_not raise_error
+ end
+
+ it "should return an Array of packages statisfying a RPMDependency" do
+ @rpmdb.push(@rpm_v, @rpm_w, @rpm_z)
+
+ @rpmrequire = Chef::Provider::Package::Yum::RPMDependency.parse("test-package-a >= 1.6.5")
+ x = @rpmdb.whatprovides(@rpmrequire)
+ x.should be_kind_of(Array)
+ x[0].should be == @rpm_v
+
+ @rpmrequire = Chef::Provider::Package::Yum::RPMDependency.parse("libz.so.1()(64bit)")
+ x = @rpmdb.whatprovides(@rpmrequire)
+ x.should be_kind_of(Array)
+ x[0].should be == @rpm_v
+ x[1].should be == @rpm_z
+ end
+ end
+
+end
+
+describe Chef::Provider::Package::Yum::YumCache do
+ # allow for the reset of a Singleton
+ # thanks to Ian White (http://blog.ardes.com/2006/12/11/testing-singletons-with-ruby)
+ class << Chef::Provider::Package::Yum::YumCache
+ def reset_instance
+ Singleton.send :__init__, self
+ self
+ end
+ end
+
+ before(:each) do
+ yum_dump_good_output = <<EOF
+[option installonlypkgs] kernel kernel-bigmem kernel-enterprise
+erlang-mochiweb 0 1.4.1 5.el5 x86_64 ['erlang-mochiweb = 1.4.1-5.el5', 'mochiweb = 1.4.1-5.el5'] i installed
+zip 0 2.31 2.el5 x86_64 ['zip = 2.31-2.el5'] r base
+zisofs-tools 0 1.0.6 3.2.2 x86_64 [] a extras
+zlib 0 1.2.3 3 x86_64 ['zlib = 1.2.3-3', 'libz.so.1()(64bit)'] r base
+zlib 0 1.2.3 3 i386 ['zlib = 1.2.3-3', 'libz.so.1'] r base
+zlib-devel 0 1.2.3 3 i386 [] a extras
+zlib-devel 0 1.2.3 3 x86_64 ['zlib-devel = 1.2.3-3'] r base
+znc 0 0.098 1.el5 x86_64 [] a base
+znc-devel 0 0.098 1.el5 i386 [] a extras
+znc-devel 0 0.098 1.el5 x86_64 [] a base
+znc-extra 0 0.098 1.el5 x86_64 [] a base
+znc-modtcl 0 0.098 1.el5 x86_64 [] a base
+znc-test.beta1 0 0.098 1.el5 x86_64 [] a extras
+znc-test.test.beta1 0 0.098 1.el5 x86_64 [] a base
+EOF
+
+ yum_dump_bad_output_separators = <<EOF
+zip 0 2.31 2.el5 x86_64 ['zip = 2.31-2.el5'] r base
+zlib 0 1.2.3 3 x86_64 ['zlib = 1.2.3-3', 'libz.so.1()(64bit)'] i base bad
+zlib-devel 0 1.2.3 3 i386 [] a extras
+bad zlib-devel 0 1.2.3 3 x86_64 ['zlib-devel = 1.2.3-3'] i installed
+znc-modtcl 0 0.098 1.el5 x86_64 [] a base bad
+EOF
+
+ yum_dump_bad_output_type = <<EOF
+zip 0 2.31 2.el5 x86_64 ['zip = 2.31-2.el5'] r base
+zlib 0 1.2.3 3 x86_64 ['zlib = 1.2.3-3', 'libz.so.1()(64bit)'] c base
+zlib-devel 0 1.2.3 3 i386 [] a extras
+zlib-devel 0 1.2.3 3 x86_64 ['zlib-devel = 1.2.3-3'] bad installed
+znc-modtcl 0 0.098 1.el5 x86_64 [] a base
+EOF
+
+ yum_dump_error = <<EOF
+yum-dump Config Error: File contains no section headers.
+file: file://///etc/yum.repos.d/CentOS-Base.repo, line: 12
+'qeqwewe\n'
+EOF
+
+ @status = mock("Status", :exitstatus => 0)
+ @status_bad = mock("Status", :exitstatus => 1)
+ @stdin = mock("STDIN", :nil_object => true)
+ @stdout = mock("STDOUT", :nil_object => true)
+ @stdout_good = yum_dump_good_output.split("\n")
+ @stdout_bad_type = yum_dump_bad_output_type.split("\n")
+ @stdout_bad_separators = yum_dump_bad_output_separators.split("\n")
+ @stderr = mock("STDERR", :nil_object => true)
+ @stderr.stub!(:readlines).and_return(yum_dump_error.split("\n"))
+ @pid = mock("PID", :nil_object => true)
+
+ # new singleton each time
+ Chef::Provider::Package::Yum::YumCache.reset_instance
+ @yc = Chef::Provider::Package::Yum::YumCache.instance
+ # load valid data
+ @yc.stub!(:popen4).and_yield(@pid, @stdin, @stdout_good, @stderr).and_return(@status)
+ end
+
+ describe "initialize" do
+ it "should return a Chef::Provider::Package::Yum::YumCache object" do
+ @yc.should be_kind_of(Chef::Provider::Package::Yum::YumCache)
+ end
+
+ it "should register reload for start of Chef::Client runs" do
+ Chef::Provider::Package::Yum::YumCache.reset_instance
+ Chef::Client.should_receive(:when_run_starts) do |&b|
+ b.should_not be_nil
+ end
+ @yc = Chef::Provider::Package::Yum::YumCache.instance
+ end
+ end
+
+ describe "refresh" do
+ it "should implicitly call yum-dump.py only once by default after being instantiated" do
+ @yc.should_receive(:popen4).once
+ @yc.installed_version("zlib")
+ @yc.reset
+ @yc.installed_version("zlib")
+ end
+
+ it "should run yum-dump.py using the system python when next_refresh is for :all" do
+ @yc.reload
+ @yc.should_receive(:popen4).with(%r{^/usr/bin/python .*/yum-dump.py --options --installed-provides$}, :waitlast=>true)
+ @yc.refresh
+ end
+
+ it "should run yum-dump.py with the installed flag when next_refresh is for :installed" do
+ @yc.reload_installed
+ @yc.should_receive(:popen4).with(%r{^/usr/bin/python .*/yum-dump.py --installed$}, :waitlast=>true)
+ @yc.refresh
+ end
+
+ it "should run yum-dump.py with the all-provides flag when next_refresh is for :provides" do
+ @yc.reload_provides
+ @yc.should_receive(:popen4).with(%r{^/usr/bin/python .*/yum-dump.py --options --all-provides$}, :waitlast=>true)
+ @yc.refresh
+ end
+
+ it "should warn about invalid data with too many separators" do
+ @yc.stub!(:popen4).and_yield(@pid, @stdin, @stdout_bad_separators, @stderr).and_return(@status)
+ Chef::Log.should_receive(:warn).exactly(3).times.with(%r{Problem parsing})
+ @yc.refresh
+ end
+
+ it "should warn about invalid data with an incorrect type" do
+ @yc.stub!(:popen4).and_yield(@pid, @stdin, @stdout_bad_type, @stderr).and_return(@status)
+ Chef::Log.should_receive(:warn).exactly(2).times.with(%r{Problem parsing})
+ @yc.refresh
+ end
+
+ it "should warn about no output from yum-dump.py" do
+ @yc.stub!(:popen4).and_yield(@pid, @stdin, [], @stderr).and_return(@status)
+ Chef::Log.should_receive(:warn).exactly(1).times.with(%r{no output from yum-dump.py})
+ @yc.refresh
+ end
+
+ it "should raise exception yum-dump.py exits with a non zero status" do
+ @yc.stub!(:popen4).and_yield(@pid, @stdin, [], @stderr).and_return(@status_bad)
+ lambda { @yc.refresh}.should raise_error(Chef::Exceptions::Package, %r{CentOS-Base.repo, line: 12})
+ end
+
+ it "should parse type 'i' into an installed state for a package" do
+ @yc.available_version("erlang-mochiweb").should be == nil
+ @yc.installed_version("erlang-mochiweb").should_not be == nil
+ end
+
+ it "should parse type 'a' into an available state for a package" do
+ @yc.available_version("znc").should_not be == nil
+ @yc.installed_version("znc").should be == nil
+ end
+
+ it "should parse type 'r' into an installed and available states for a package" do
+ @yc.available_version("zip").should_not be == nil
+ @yc.installed_version("zip").should_not be == nil
+ end
+
+ it "should parse installonlypkgs from yum-dump.py options output" do
+ @yc.allow_multi_install.should be == %w{kernel kernel-bigmem kernel-enterprise}
+ end
+ end
+
+ describe "installed_version" do
+ it "should take one or two arguments" do
+ lambda { @yc.installed_version("zip") }.should_not raise_error(ArgumentError)
+ lambda { @yc.installed_version("zip", "i386") }.should_not raise_error(ArgumentError)
+ lambda { @yc.installed_version("zip", "i386", "extra") }.should raise_error(ArgumentError)
+ end
+
+ it "should return version-release for matching package regardless of arch" do
+ @yc.installed_version("zip", "x86_64").should be == "2.31-2.el5"
+ @yc.installed_version("zip", nil).should be == "2.31-2.el5"
+ end
+
+ it "should return version-release for matching package and arch" do
+ @yc.installed_version("zip", "x86_64").should be == "2.31-2.el5"
+ @yc.installed_version("zisofs-tools", "i386").should be == nil
+ end
+
+ it "should return nil for an unmatched package" do
+ @yc.installed_version(nil, nil).should be == nil
+ @yc.installed_version("test1", nil).should be == nil
+ @yc.installed_version("test2", "x86_64").should be == nil
+ end
+ end
+
+ describe "available_version" do
+ it "should take one or two arguments" do
+ lambda { @yc.available_version("zisofs-tools") }.should_not raise_error(ArgumentError)
+ lambda { @yc.available_version("zisofs-tools", "i386") }.should_not raise_error(ArgumentError)
+ lambda { @yc.available_version("zisofs-tools", "i386", "extra") }.should raise_error(ArgumentError)
+ end
+
+ it "should return version-release for matching package regardless of arch" do
+ @yc.available_version("zip", "x86_64").should be == "2.31-2.el5"
+ @yc.available_version("zip", nil).should be == "2.31-2.el5"
+ end
+
+ it "should return version-release for matching package and arch" do
+ @yc.available_version("zip", "x86_64").should be == "2.31-2.el5"
+ @yc.available_version("zisofs-tools", "i386").should be == nil
+ end
+
+ it "should return nil for an unmatched package" do
+ @yc.available_version(nil, nil).should be == nil
+ @yc.available_version("test1", nil).should be == nil
+ @yc.available_version("test2", "x86_64").should be == nil
+ end
+ end
+
+ describe "version_available?" do
+ it "should take two or three arguments" do
+ lambda { @yc.version_available?("zisofs-tools") }.should raise_error(ArgumentError)
+ lambda { @yc.version_available?("zisofs-tools", "1.0.6-3.2.2") }.should_not raise_error(ArgumentError)
+ lambda { @yc.version_available?("zisofs-tools", "1.0.6-3.2.2", "x86_64") }.should_not raise_error(ArgumentError)
+ end
+
+ it "should return true if our package-version-arch is available" do
+ @yc.version_available?("zisofs-tools", "1.0.6-3.2.2", "x86_64").should be == true
+ end
+
+ it "should return true if our package-version, no arch, is available" do
+ @yc.version_available?("zisofs-tools", "1.0.6-3.2.2", nil).should be == true
+ @yc.version_available?("zisofs-tools", "1.0.6-3.2.2").should be == true
+ end
+
+ it "should return false if our package-version-arch isn't available" do
+ @yc.version_available?("zisofs-tools", "1.0.6-3.2.2", "pretend").should be == false
+ @yc.version_available?("zisofs-tools", "pretend", "x86_64").should be == false
+ @yc.version_available?("pretend", "1.0.6-3.2.2", "x86_64").should be == false
+ end
+
+ it "should return false if our package-version, no arch, isn't available" do
+ @yc.version_available?("zisofs-tools", "pretend", nil).should be == false
+ @yc.version_available?("zisofs-tools", "pretend").should be == false
+ @yc.version_available?("pretend", "1.0.6-3.2.2").should be == false
+ end
+ end
+
+ describe "package_repository" do
+ it "should take two or three arguments" do
+ lambda { @yc.package_repository("zisofs-tools") }.should raise_error(ArgumentError)
+ lambda { @yc.package_repository("zisofs-tools", "1.0.6-3.2.2") }.should_not raise_error(ArgumentError)
+ lambda { @yc.package_repository("zisofs-tools", "1.0.6-3.2.2", "x86_64") }.should_not raise_error(ArgumentError)
+ end
+
+ it "should return repoid for package-version-arch" do
+ @yc.package_repository("zlib-devel", "1.2.3-3", "i386").should be == "extras"
+ @yc.package_repository("zlib-devel", "1.2.3-3", "x86_64").should be == "base"
+ end
+
+ it "should return repoid for package-version, no arch" do
+ @yc.package_repository("zisofs-tools", "1.0.6-3.2.2", nil).should be == "extras"
+ @yc.package_repository("zisofs-tools", "1.0.6-3.2.2").should be == "extras"
+ end
+
+ it "should return nil when no match for package-version-arch" do
+ @yc.package_repository("zisofs-tools", "1.0.6-3.2.2", "pretend").should be == nil
+ @yc.package_repository("zisofs-tools", "pretend", "x86_64").should be == nil
+ @yc.package_repository("pretend", "1.0.6-3.2.2", "x86_64").should be == nil
+ end
+
+ it "should return nil when no match for package-version, no arch" do
+ @yc.package_repository("zisofs-tools", "pretend", nil).should be == nil
+ @yc.package_repository("zisofs-tools", "pretend").should be == nil
+ @yc.package_repository("pretend", "1.0.6-3.2.2").should be == nil
+ end
+ end
+
+ describe "reset" do
+ it "should empty the installed and available packages RPMDb" do
+ @yc.available_version("zip", "x86_64").should be == "2.31-2.el5"
+ @yc.installed_version("zip", "x86_64").should be == "2.31-2.el5"
+ @yc.reset
+ @yc.available_version("zip", "x86_64").should be == nil
+ @yc.installed_version("zip", "x86_64").should be == nil
+ end
+ end
+
+ describe "package_available?" do
+ it "should return true a package name is available" do
+ @yc.package_available?("zisofs-tools").should be == true
+ @yc.package_available?("moo").should be == false
+ @yc.package_available?(nil).should be == false
+ end
+
+ it "should return true a package name + arch is available" do
+ @yc.package_available?("zlib-devel.i386").should be == true
+ @yc.package_available?("zisofs-tools.x86_64").should be == true
+ @yc.package_available?("znc-test.beta1.x86_64").should be == true
+ @yc.package_available?("znc-test.beta1").should be == true
+ @yc.package_available?("znc-test.test.beta1").should be == true
+ @yc.package_available?("moo.i386").should be == false
+ @yc.package_available?("zisofs-tools.beta").should be == false
+ @yc.package_available?("znc-test.test").should be == false
+ end
+ end
+
+end