Paul,

We really appreciate your work on adding testing for this provider; 
unfortunately, we are unable to run the tests you wrote on our development 
machines, as they directly call the pacman command, which is not available on 
our computers (currently, 15/19 of the tests fail with the message "Command 
pacman is missing" or some variant thereof). You will need to stub these calls 
rather than calling the actual pacman command. You may want to check out the 
specs for other package providers such as pip or apt to see how they stub out 
calls to the actual executable to prevent it from being run. If you need more 
information or guidance on how to proceed, please feel free to e-mail the list, 
or check out our Wiki documentation on writing tests:

https://projects.puppetlabs.com/projects/puppet/wiki/Development_Writing_Tests

-- 
Max Martin
On Wednesday, May 11, 2011 at 6:35 PM, Paul Boyd wrote: 
> From: Paul Boyd <boyd.pa...@gmail.com>
> 
> Adds support for use Archlinux's pacman package manager in Puppet.
> 
> Originally written by Miah Johnson, with bug fixes from Thomas Hatch and
> myself.
> 
> Signed-off-by: Paul Boyd <pb...@dev3l.net>
> ---
> Local-branch: feature/master/1853
>  lib/puppet/provider/package/pacman.rb | 94 ++++++++++++
>  spec/unit/provider/package/pacman_spec.rb | 237 +++++++++++++++++++++++++++++
>  2 files changed, 331 insertions(+), 0 deletions(-)
>  create mode 100644 lib/puppet/provider/package/pacman.rb
>  create mode 100644 spec/unit/provider/package/pacman_spec.rb
> 
> diff --git a/lib/puppet/provider/package/pacman.rb 
> b/lib/puppet/provider/package/pacman.rb
> new file mode 100644
> index 0000000..6eb7dbe
> --- /dev/null
> +++ b/lib/puppet/provider/package/pacman.rb
> @@ -0,0 +1,94 @@
> +require 'puppet/provider/package'
> +
> +Puppet::Type.type(:package).provide :pacman, :parent => 
> Puppet::Provider::Package do
> + desc "Support for the Package Manager Utility (pacman) used in Archlinux."
> +
> + commands :pacman => "/usr/bin/pacman"
> + defaultfor :operatingsystem => :archlinux
> + confine :operatingsystem => :archlinux
> + has_feature :upgradeable
> +
> + # Install a package using 'pacman'.
> + # Installs quietly, without confirmation or progressbar, updates package
> + # list from servers defined in pacman.conf.
> + def install
> + pacman "--noconfirm", "--noprogressbar", "-Sy", @resource[:name]
> +
> + unless self.query
> + raise Puppet::ExecutionFailure.new("Could not find package %s" % self.name)
> + end
> + end
> +
> + def self.listcmd
> + [command(:pacman), " -Q"]
> + end
> +
> + # Fetch the list of packages currently installed on the system.
> + def self.instances
> + packages = []
> + begin
> + execpipe(listcmd()) do |process|
> + # pacman -Q output is 'packagename version-rel'
> + regex = %r{^(\S+)\s(\S+)}
> + fields = [:name, :ensure]
> + hash = {}
> +
> + process.each { |line|
> + if match = regex.match(line)
> + fields.zip(match.captures) { |field,value|
> + hash[field] = value
> + }
> +
> + name = hash[:name]
> + hash[:provider] = self.name
> +
> + packages << new(hash)
> + hash = {}
> + else
> + warning("Failed to match line %s" % line)
> + end
> + }
> + end
> + rescue Puppet::ExecutionFailure
> + return nil
> + end
> + packages
> + end
> +
> + # Because Archlinux is a rolling release based distro, installing a package
> + # should always result in the newest release.
> + def update
> + # Install in pacman can be used for update, too
> + self.install
> + end
> +
> + def latest
> + pacman "-Sy"
> + output = pacman "-Sp", "--print-format", "%v", @resource[:name]
> + output.chomp
> + end
> +
> + # Querys the pacman master list for information about the package.
> + def query
> + begin
> + output = pacman("-Qi", @resource[:name])
> +
> + if output =~ /Version.*:\s(.+)/
> + return { :ensure => $1 }
> + end
> + rescue Puppet::ExecutionFailure
> + return {
> + :ensure => :purged,
> + :status => 'missing',
> + :name => @resource[:name],
> + :error => 'ok',
> + }
> + end
> + nil
> + end
> +
> + # Removes a package from the system.
> + def uninstall
> + pacman "--noconfirm", "--noprogressbar", "-R", @resource[:name]
> + end
> +end
> diff --git a/spec/unit/provider/package/pacman_spec.rb 
> b/spec/unit/provider/package/pacman_spec.rb
> new file mode 100644
> index 0000000..499ccca
> --- /dev/null
> +++ b/spec/unit/provider/package/pacman_spec.rb
> @@ -0,0 +1,237 @@
> +#!/usr/bin/env ruby
> +
> +Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? 
> require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
> +
> +provider = Puppet::Type.type(:package).provider(:pacman)
> +
> +describe provider do
> + before do
> + @resource = stub 'resource'
> + @resource.stubs(:[]).returns("package")
> + @resource.stubs(:name).returns("name")
> + @provider = provider.new(@resource)
> + end
> +
> + describe "when installing" do
> + before do
> + @provider.stubs(:query).returns({
> + :ensure => '1.0'
> + })
> + end
> +
> + it "should call pacman" do
> + provider.
> + expects(:execute).
> + at_least_once.
> + with { |args|
> + args[0] == "/usr/bin/pacman"
> + }.
> + returns ""
> +
> + @provider.install
> + end
> +
> + it "should be quiet" do
> + provider.
> + expects(:execute).
> + with { |args|
> + args[1,2] == ["--noconfirm", "--noprogressbar"]
> + }.
> + returns("")
> +
> + @provider.install
> + end
> +
> + it "should install the right package" do
> + provider.
> + expects(:execute).
> + with { |args|
> + args[3,4] == ["-Sy", @resource[0]]
> + }.
> + returns("")
> +
> + @provider.install
> + end
> +
> + it "should raise an ExecutionFailure if the installation failed" do
> + provider.stubs(:execute).returns("")
> + @provider.expects(:query).returns(nil)
> +
> + lambda { @provider.install }.should 
> raise_exception(Puppet::ExecutionFailure)
> + end
> + end
> +
> + describe "when updating" do
> + it "should call install" do
> + @provider.expects(:install).returns("install return value")
> + @provider.update.should == "install return value"
> + end
> + end
> +
> + describe "when uninstalling" do
> + it "should call pacman" do
> + provider.
> + expects(:execute).
> + with { |args|
> + args[0] == "/usr/bin/pacman"
> + }.
> + returns ""
> +
> + @provider.uninstall
> + end
> +
> + it "should be quiet" do
> + provider.
> + expects(:execute).
> + with { |args|
> + args[1,2] == ["--noconfirm", "--noprogressbar"]
> + }.
> + returns("")
> +
> + @provider.uninstall
> + end
> +
> + it "should remove the right package" do
> + provider.
> + expects(:execute).
> + with { |args|
> + args[3,4] == ["-R", @resource[0]]
> + }.
> + returns("")
> +
> + @provider.uninstall
> + end
> + end
> +
> + describe "when querying" do
> + it "should query pacman" do
> + provider.
> + expects(:execute).
> + with(["/usr/bin/pacman", "-Qi", @resource[0]])
> + @provider.query
> + end
> +
> + it "should return the version" do
> + query_output = <<EOF
> +Name : package
> +Version : 1.01.3-2
> +URL : http://www.archlinux.org/pacman/
> +Licenses : GPL
> +Groups : base
> +Provides : None
> +Depends On : bash libarchive>=2.7.1 libfetch>=2.25 pacman-mirrorlist
> +Optional Deps : fakeroot: for makepkg usage as normal user
> + curl: for rankmirrors usage
> +Required By : None
> +Conflicts With : None
> +Replaces : None
> +Installed Size : 2352.00 K
> +Packager : Dan McGee <d...@archlinux.org>
> +Architecture : i686
> +Build Date : Sat 22 Jan 2011 03:56:41 PM EST
> +Install Date : Thu 27 Jan 2011 06:45:49 AM EST
> +Install Reason : Explicitly installed
> +Install Script : Yes
> +Description : A library-based package manager with dependency support
> +EOF
> +
> + provider.expects(:execute).returns(query_output)
> + @provider.query.should == {:ensure => "1.01.3-2"}
> + end
> +
> + it "should return a nil if the package isn't found" do
> + provider.expects(:execute).returns("")
> + @provider.query.should be_nil
> + end
> +
> + it "should return a hash indicating that the package is missing on error" do
> + provider.expects(:execute).raises(Puppet::ExecutionFailure.new("ERROR!"))
> + @provider.query.should == {
> + :ensure => :purged,
> + :status => 'missing',
> + :name => @resource[0],
> + :error => 'ok',
> + }
> + end
> + end
> +
> + describe "when fetching a package list" do
> + it "should query pacman" do
> + provider.expects(:execpipe).with(["/usr/bin/pacman", ' -Q'])
> + provider.instances
> + end
> +
> + it "should return installed packages with their versions" do
> + provider.expects(:execpipe).yields("package1 1.23-4\npackage2 2.00\n")
> + packages = provider.instances
> +
> + packages.length.should == 2
> +
> + packages[0].properties.should == {
> + :provider => :pacman,
> + :ensure => '1.23-4',
> + :name => 'package1'
> + }
> +
> + packages[1].properties.should == {
> + :provider => :pacman,
> + :ensure => '2.00',
> + :name => 'package2'
> + }
> + end
> +
> + it "should return nil on error" do
> + provider.expects(:execpipe).raises(Puppet::ExecutionFailure.new("ERROR!"))
> + provider.instances.should be_nil
> + end
> +
> + it "should warn on invalid input" do
> + provider.expects(:execpipe).yields("blah")
> + provider.expects(:warning).with("Failed to match line blah")
> + provider.instances.should == []
> + end
> + end
> +
> + describe "when determining the latest version" do
> + it "should refresh package list" do
> + refreshed = states('refreshed').starts_as('unrefreshed')
> + provider.
> + expects(:execute).
> + when(refreshed.is('unrefreshed')).
> + with(['/usr/bin/pacman', '-Sy']).
> + then(refreshed.is('refreshed'))
> +
> + provider.
> + stubs(:execute).
> + when(refreshed.is('refreshed')).
> + returns("")
> +
> + @provider.latest
> + end
> +
> + it "should get query pacman for the latest version" do
> + refreshed = states('refreshed').starts_as('unrefreshed')
> + provider.
> + stubs(:execute).
> + when(refreshed.is('unrefreshed')).
> + then(refreshed.is('refreshed'))
> +
> + provider.
> + expects(:execute).
> + when(refreshed.is('refreshed')).
> + with(['/usr/bin/pacman', '-Sp', '--print-format', '%v', @resource[0]]).
> + returns("")
> +
> + @provider.latest
> + end
> +
> + it "should return the version number from pacman" do
> + provider.
> + expects(:execute).
> + at_least_once().
> + returns("1.00.2-3\n")
> +
> + @provider.latest.should == "1.00.2-3"
> + end
> + end
> +end
> -- 
> 1.7.4.1
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Puppet Developers" group.
> To post to this group, send email to puppet-dev@googlegroups.com.
> To unsubscribe from this group, send email to 
> puppet-dev+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/puppet-dev?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to puppet-dev@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-dev+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to