summaryrefslogtreecommitdiff
path: root/spec/unit/provider/package/freebsd_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit/provider/package/freebsd_spec.rb')
-rw-r--r--spec/unit/provider/package/freebsd_spec.rb259
1 files changed, 259 insertions, 0 deletions
diff --git a/spec/unit/provider/package/freebsd_spec.rb b/spec/unit/provider/package/freebsd_spec.rb
new file mode 100644
index 0000000000..270c85d934
--- /dev/null
+++ b/spec/unit/provider/package/freebsd_spec.rb
@@ -0,0 +1,259 @@
+#
+# Authors:: Bryan McLellan (btm@loftninjas.org)
+# Matthew Landauer (matthew@openaustralia.org)
+# Copyright:: Copyright (c) 2009 Bryan McLellan, Matthew Landauer
+# 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::Freebsd, "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("zsh")
+ @current_resource = Chef::Resource::Package.new("zsh")
+
+ @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider.current_resource = @current_resource
+ ::File.stub!(:exist?).with('/usr/ports/Makefile').and_return(false)
+ end
+
+ describe "when determining the current package state" do
+ before do
+ @provider.stub!(:ports_candidate_version).and_return("4.3.6")
+ end
+
+ it "should create a current resource with the name of the new_resource" do
+ current_resource = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context).current_resource
+ current_resource.name.should == "zsh"
+ end
+
+ it "should return a version if the package is installed" do
+ @provider.should_receive(:current_installed_version).and_return("4.3.6_7")
+ @provider.load_current_resource
+ @current_resource.version.should == "4.3.6_7"
+ end
+
+ it "should return nil if the package is not installed" do
+ @provider.should_receive(:current_installed_version).and_return(nil)
+ @provider.load_current_resource
+ @current_resource.version.should be_nil
+ end
+
+ it "should return a candidate version if it exists" do
+ @provider.should_receive(:current_installed_version).and_return(nil)
+ @provider.load_current_resource
+ @provider.candidate_version.should eql("4.3.6")
+ end
+ end
+
+ describe "when querying for package state and attributes" do
+ before do
+ #@new_resource = Chef::Resource::Package.new("zsh")
+
+ #@provider = Chef::Provider::Package::Freebsd.new(@node, @new_resource)
+
+ #@status = mock("Status", :exitstatus => 0)
+ #@stdin = mock("STDIN", :null_object => true)
+ #@stdout = mock("STDOUT", :null_object => true)
+ #@stderr = mock("STDERR", :null_object => true)
+ #@pid = mock("PID", :null_object => true)
+ end
+
+ it "should return the version number when it is installed" do
+ pkg_info = OpenStruct.new(:stdout => "zsh-4.3.6_7")
+ @provider.should_receive(:shell_out!).with('pkg_info -E "zsh*"', :env => nil, :returns => [0,1]).and_return(pkg_info)
+ #@provider.should_receive(:popen4).with('pkg_info -E "zsh*"').and_yield(@pid, @stdin, ["zsh-4.3.6_7"], @stderr).and_return(@status)
+ @provider.stub!(:package_name).and_return("zsh")
+ @provider.current_installed_version.should == "4.3.6_7"
+ end
+
+ it "does not set the current version number when the package is not installed" do
+ pkg_info = OpenStruct.new(:stdout => "")
+ @provider.should_receive(:shell_out!).with('pkg_info -E "zsh*"', :env => nil, :returns => [0,1]).and_return(pkg_info)
+ @provider.stub!(:package_name).and_return("zsh")
+ @provider.current_installed_version.should be_nil
+ end
+
+ it "should return the port path for a valid port name" do
+ whereis = OpenStruct.new(:stdout => "zsh: /usr/ports/shells/zsh")
+ @provider.should_receive(:shell_out!).with("whereis -s zsh", :env => nil).and_return(whereis)
+ #@provider.should_receive(:popen4).with("whereis -s zsh").and_yield(@pid, @stdin, ["zsh: /usr/ports/shells/zsh"], @stderr).and_return(@status)
+ @provider.stub!(:port_name).and_return("zsh")
+ @provider.port_path.should == "/usr/ports/shells/zsh"
+ end
+
+ # Not happy with the form of these tests as they are far too closely tied to the implementation and so very fragile.
+ it "should return the ports candidate version when given a valid port path" do
+ @provider.stub!(:port_path).and_return("/usr/ports/shells/zsh")
+ make_v = OpenStruct.new(:stdout => "4.3.6\n")
+ @provider.should_receive(:shell_out!).with("make -V PORTVERSION", {:cwd=>"/usr/ports/shells/zsh", :returns=>[0, 1], :env=>nil}).and_return(make_v)
+ @provider.ports_candidate_version.should == "4.3.6"
+ end
+
+ it "should figure out the package name when we have ports" do
+ ::File.stub!(:exist?).with('/usr/ports/Makefile').and_return(true)
+ @provider.stub!(:port_path).and_return("/usr/ports/shells/zsh")
+ make_v = OpenStruct.new(:stdout => "zsh-4.3.6_7\n")
+ @provider.should_receive(:shell_out!).with("make -V PKGNAME", {:cwd=>"/usr/ports/shells/zsh", :env=>nil, :returns=>[0, 1]}).and_return(make_v)
+ #@provider.should_receive(:ports_makefile_variable_value).with("PKGNAME").and_return("zsh-4.3.6_7")
+ @provider.package_name.should == "zsh"
+ end
+ end
+
+ describe Chef::Provider::Package::Freebsd, "install_package" do
+ before(:each) do
+ @cmd_result = OpenStruct.new(:status => true)
+
+ @provider.current_resource = @current_resource
+ @provider.stub!(:package_name).and_return("zsh")
+ @provider.stub!(:latest_link_name).and_return("zsh")
+ @provider.stub!(:port_path).and_return("/usr/ports/shells/zsh")
+ end
+
+ it "should run pkg_add -r with the package name" do
+ @provider.should_receive(:shell_out!).with("pkg_add -r zsh", :env => nil).and_return(@cmd_result)
+ @provider.install_package("zsh", "4.3.6_7")
+ end
+
+ it "should run make install when installing from ports" do
+ @new_resource.stub!(:source).and_return("ports")
+ @provider.should_not_receive(:shell_out!).with("make -DBATCH -f /usr/ports/shells/zsh/Makefile install", :timeout => 1200, :env=>nil)
+ @provider.should_receive(:shell_out!).with("make -DBATCH install", :timeout => 1200, :env=>nil, :cwd => @provider.port_path).and_return(@cmd_result)
+ @provider.install_package("zsh", "4.3.6_7")
+ end
+ end
+
+ describe Chef::Provider::Package::Freebsd, "port path" do
+ before do
+ #@node = Chef::Node.new
+ @new_resource = Chef::Resource::Package.new("zsh")
+ @new_resource.cookbook_name = "adventureclub"
+ @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ end
+
+ it "should figure out the port path from the package_name using whereis" do
+ whereis = OpenStruct.new(:stdout => "zsh: /usr/ports/shells/zsh")
+ @provider.should_receive(:shell_out!).with("whereis -s zsh", :env=>nil).and_return(whereis)
+ @provider.port_path.should == "/usr/ports/shells/zsh"
+ end
+
+ it "should use the package_name as the port path when it starts with /" do
+ new_resource = Chef::Resource::Package.new("/usr/ports/www/wordpress")
+ provider = Chef::Provider::Package::Freebsd.new(new_resource, @run_context)
+ provider.should_not_receive(:popen4)
+ provider.port_path.should == "/usr/ports/www/wordpress"
+ end
+
+ it "should use the package_name as a relative path from /usr/ports when it contains / but doesn't start with it" do
+ # @new_resource = mock( "Chef::Resource::Package",
+ # :package_name => "www/wordpress",
+ # :cookbook_name => "xenoparadox")
+ new_resource = Chef::Resource::Package.new("www/wordpress")
+ provider = Chef::Provider::Package::Freebsd.new(new_resource, @run_context)
+ provider.should_not_receive(:popen4)
+ provider.port_path.should == "/usr/ports/www/wordpress"
+ end
+ end
+
+ describe Chef::Provider::Package::Freebsd, "ruby-iconv (package with a dash in the name)" do
+ before(:each) do
+ @new_resource = Chef::Resource::Package.new("ruby-iconv")
+ @current_resource = Chef::Resource::Package.new("ruby-iconv")
+ @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider.current_resource = @current_resource
+ @provider.stub!(:port_path).and_return("/usr/ports/converters/ruby-iconv")
+ @provider.stub!(:package_name).and_return("ruby18-iconv")
+ @provider.stub!(:latest_link_name).and_return("ruby18-iconv")
+
+ @install_result = OpenStruct.new(:status => true)
+ end
+
+ it "should run pkg_add -r with the package name" do
+ @provider.should_receive(:shell_out!).with("pkg_add -r ruby18-iconv", :env => nil).and_return(@install_result)
+ @provider.install_package("ruby-iconv", "1.0")
+ end
+
+ it "should run make install when installing from ports" do
+ @new_resource.stub!(:source).and_return("ports")
+ @provider.should_receive(:shell_out!).with("make -DBATCH install", :timeout => 1200, :env=>nil, :cwd => @provider.port_path).and_return(@install_result)
+ @provider.install_package("ruby-iconv", "1.0")
+ end
+ end
+
+ describe Chef::Provider::Package::Freebsd, "remove_package" do
+ before(:each) do
+ @pkg_delete = OpenStruct.new(:status => true)
+ @new_resource.version "4.3.6_7"
+ @current_resource.version "4.3.6_7"
+ @provider.current_resource = @current_resource
+ @provider.stub!(:package_name).and_return("zsh")
+ end
+
+ it "should run pkg_delete with the package name and version" do
+ @provider.should_receive(:shell_out!).with("pkg_delete zsh-4.3.6_7", :env => nil).and_return(@pkg_delete)
+ @provider.remove_package("zsh", "4.3.6_7")
+ end
+ end
+
+ # A couple of examples to show up the difficulty of determining the command to install the binary package given the port:
+ # PORT DIRECTORY INSTALLED PACKAGE NAME COMMAND TO INSTALL PACKAGE
+ # /usr/ports/lang/perl5.8 perl-5.8.8_1 pkg_add -r perl
+ # /usr/ports/databases/mysql50-server mysql-server-5.0.45_1 pkg_add -r mysql50-server
+ #
+ # So, in one case it appears the command to install the package can be derived from the name of the port directory and in the
+ # other case it appears the command can be derived from the package name. Very confusing!
+ # Well, luckily, after much poking around, I discovered that the two can be disambiguated through the use of the LATEST_LINK
+ # variable which is set by the ports Makefile
+ #
+ # PORT DIRECTORY LATEST_LINK INSTALLED PACKAGE NAME COMMAND TO INSTALL PACKAGE
+ # /usr/ports/lang/perl5.8 perl perl-5.8.8_1 pkg_add -r perl
+ # /usr/ports/databases/mysql50-server mysql50-server mysql-server-5.0.45_1 pkg_add -r mysql50-server
+ #
+ # The variable LATEST_LINK is named that way because the directory that "pkg_add -r" downloads from is called "Latest" and
+ # contains the "latest" versions of package as symbolic links to the files in the "All" directory.
+
+ describe Chef::Provider::Package::Freebsd, "install_package latest link fixes" do
+ it "should install the perl binary package with the correct name" do
+ @new_resource = Chef::Resource::Package.new("perl5.8")
+ @current_resource = Chef::Resource::Package.new("perl5.8")
+ @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider.current_resource = @current_resource
+ @provider.stub!(:package_name).and_return("perl")
+ @provider.stub!(:latest_link_name).and_return("perl")
+
+ cmd = OpenStruct.new(:status => true)
+ @provider.should_receive(:shell_out!).with("pkg_add -r perl", :env => nil).and_return(cmd)
+ @provider.install_package("perl5.8", "5.8.8_1")
+ end
+
+ it "should install the mysql50-server binary package with the correct name" do
+
+ @new_resource = Chef::Resource::Package.new("mysql50-server")
+ @current_resource = Chef::Resource::Package.new("mysql50-server")
+ @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider.current_resource = @current_resource
+ @provider.stub!(:package_name).and_return("mysql-server")
+ @provider.stub!(:latest_link_name).and_return("mysql50-server")
+
+ cmd = OpenStruct.new(:status => true)
+ @provider.should_receive(:shell_out!).with("pkg_add -r mysql50-server", :env=>nil).and_return(cmd)
+ @provider.install_package("mysql50-server", "5.0.45_1")
+ end
+ end
+end