#!/usr/bin/env ruby
$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'etc'
class TestPackageProvider < Test::Unit::TestCase
include PuppetTest
# Load the testpackages hash.
def self.load_test_packages
require 'yaml'
file = File.join(PuppetTest.datadir(), "providers", "package", "testpackages.yaml")
unless FileTest.exists?(file)
raise "Could not find file %s" % file
end
array = YAML::load(File.read(file)).collect { |hash|
# Stupid ruby 1.8.1. YAML is sometimes broken such that
# symbols end up being strings with the : in them.
hash.each do |name, value|
if name.is_a?(String) and name =~ /^:/
hash.delete(name)
name = name.sub(/^:/, '').intern
hash[name] = value
end
if value.is_a?(String) and value =~ /^:/
hash[name] = value.sub(/^:/, '').intern
end
end
}
return array
end
def self.suitable_test_packages
list = load_test_packages
providers = {}
Puppet::Type.type(:package).suitableprovider.each do |provider|
providers[provider.name] = provider
end
facts = {}
Facter.to_hash.each do |fact, value|
facts[fact.downcase.intern] = value.downcase.intern
end
list.find_all { |hash| # First find the matching providers
hash.include?(:provider) and providers.include?(hash[:provider])
}.reject { |hash| # Then find matching fact sets
facts.detect do |fact, value|
# We're detecting unmatched facts, but we also want to
# delete the facts so they don't show up later.
if fval = hash[fact]
hash.delete(fact)
fval = [fval] unless fval.is_a?(Array)
fval = fval.collect { |v| v.downcase.intern }
! fval.include?(value)
end
end
}
end
def assert_absent(provider, msg = "package not absent")
result = nil
assert_nothing_raised("Could not query provider") do
result = provider.query
end
if result.nil?
assert_nil(result)
elsif result.is_a?(Hash)
assert_equal(:absent, result[:ensure], msg)
else
raise "dunno how to handle %s" % result.inspect
end
end
def assert_not_absent(provider, msg = "package not installed")
result = nil
assert_nothing_raised("Could not query provider") do
result = provider.query
end
assert((result == :listed or result.is_a?(Hash)),
"query did not return hash or :listed")
if result == :listed
assert(provider.model.is(:ensure) != :absent, msg)
else
assert(result[:ensure] != :absent, msg)
end
end
# Run a package through all of its paces. FIXME This should use the
# provider, not the package, duh.
def run_package_installation_test(hash)
# Turn the hash into a package
if files = hash[:files]
hash.delete(:files)
if files.is_a?(Array)
hash[:source] = files.shift
else
hash[:source] = files
files = []
end
else
files = []
end
if versions = hash[:versions]
hash.delete(:versions)
else
versions = []
end
# Start out by just making sure it's installed
if versions.empty?
hash[:ensure] = :present
else
hash[:ensure] = versions.shift
end
if hash[:source]
unless FileTest.exists?(hash[:source])
$stderr.puts "Create a package at %s for testing" % hash[:source]
return
end
end
if cleancmd = hash[:cleanup]
hash.delete(:cleanup)
end
pkg = nil
assert_nothing_raised(
"Could not turn %s into a package" % hash.inspect
) do
pkg = Puppet::Type.newpackage(hash)
end
# Make any necessary modifications.
modpkg(pkg)
provider = pkg.provider
assert(provider, "Could not retrieve provider")
assert_absent(provider)
if Process.uid != 0
$stderr.puts "Run as root for full package tests"
return
end
cleanup do
if pkg.provider.respond_to?(:uninstall)
pkg[:ensure] = :absent
assert_apply(pkg)
else
if cleancmd
system(cleancmd)
end
end
end
assert_nothing_raised("Could not install package") do
provider.install
end
assert_not_absent(provider, "package did not install")
# If there are any remaining files, then test upgrading from there
unless files.empty?
pkg[:source] = files.shift
current = provider.query
assert_nothing_raised("Could not upgrade") do
provider.update
end
new = provider.query
assert(current != new, "package was not upgraded: %s did not change" %
current.inspect)
end
unless versions.empty?
pkg[:ensure] = versions.shift
current = provider.query
assert_nothing_raised("Could not upgrade") do
provider.update
end
new = provider.query
assert(current != new, "package was not upgraded: %s did not change" %
current.inspect)
end
# Now remove the package
if provider.respond_to?(:uninstall)
assert_nothing_raised do
provider.uninstall
end
assert_absent(provider)
end
end
# Now create a separate test method for each package
suitable_test_packages.each do |hash|
mname = ["test", hash[:name].to_s, hash[:provider].to_s].join("_").intern
if method_defined?(mname)
warn "Already a test method defined for %s" % mname
else
define_method(mname) do
run_package_installation_test(hash)
end
end
end
def modpkg(pkg)
case pkg[:provider]
when :sun:
pkg[:adminfile] = "/usr/local/pkg/admin_file"
end
end
# Make sure providers throw an error when you tell them to install a
# non-existent package.
def test_no_such_package
Puppet::Type.type(:package).suitableprovider.each do |provider|
assert_raise(ArgumentError, Puppet::Error, Puppet::ExecutionFailure,
"Successfully installed nonexistent package with %s" % provider.name) {
pkg = Puppet::Type.newpackage :name => "nosuch%s" % provider.name.to_s,
:provider => provider.name
provider = pkg.provider
provider.install
}
end
end
# Make sure all of the suitable providers on our platform can successfully
# list.
def test_listing
Puppet::Type.type(:package).suitableprovider.each do |provider|
result = nil
assert_nothing_raised("Could not list %s packages" % provider.name) do
result = provider.list
end
result.each do |pkg|
assert_instance_of(Puppet::Type.type(:package), pkg,
"%s returned non-package" % provider.name)
assert_equal(provider.name, pkg.provider.class.name,
"%s did not set provider correctly" % provider.name)
end
end
end
end
# $Id: package.rb 2170 2007-02-07 17:21:52Z luke $
syntax highlighted by Code2HTML, v. 0.9.1