(#13542) New and updated unit tests for the PMT tarball install
This patch adds new and updates the original unit tests for the PMT install/upgrade code which now uses the ebeded minitar to work with the module packages instead of calling external tar commands and has gained the capability to install modules from tarballs.
This commit is contained in:
Родитель
137246fe1e
Коммит
0b75658447
|
@ -304,10 +304,16 @@ module Puppet::ModuleTool::Shared
|
|||
release[:has_local_changes] = mod.has_metadata? && mod.has_local_changes?
|
||||
end
|
||||
|
||||
def resolve_constraints(dependencies, selected = {})
|
||||
#
|
||||
# Select releases satisfying the constraints specified by the dependencies
|
||||
# parameter while making sure they are not in conflict with previously
|
||||
# selected realeases specified by the selected parameter.
|
||||
#
|
||||
def get_candidates(dependencies, selected)
|
||||
candidates = []
|
||||
preferred = []
|
||||
dependencies.each { |module_name, constraints|
|
||||
|
||||
dependencies.each do |module_name, constraints|
|
||||
range = constraints.map { |constraint| constraint[:range] }.inject(&:&)
|
||||
|
||||
if selected.include?(module_name)
|
||||
|
@ -378,51 +384,26 @@ module Puppet::ModuleTool::Shared
|
|||
end
|
||||
|
||||
candidates << releases
|
||||
}
|
||||
|
||||
# we are done if there are no dependencies left to be resolved
|
||||
return [] if candidates.empty?
|
||||
|
||||
resolution_exception = nil
|
||||
# try all possible combinations of candidates in unifromly increasing sequence
|
||||
mostly_uniformly_increasing_sequence(candidates.map(&:length), preferred) do |offsets|
|
||||
# the current set of candidates (possible resolutions) to try
|
||||
candidate_set = []
|
||||
|
||||
# dependencies to resolve in the next recursion
|
||||
# (constraints imposed by the candidates in the candidate set)
|
||||
subdependencies = Hash.new { |h,k| h[k] = [] }
|
||||
|
||||
# map of parents used to link resolutions of dependencies to the candidates
|
||||
# in the current candidate set to build the install/upgrade tree which
|
||||
# is printed by the install/upgrade command
|
||||
parentmap = {}
|
||||
|
||||
# select the next set of candidates/resolutions
|
||||
# and gather their dependencies
|
||||
candidates.each_index do |index|
|
||||
release = candidates[index][offsets[index]]
|
||||
|
||||
release[:dependencies].each do |dependency|
|
||||
name = dependency[:target]
|
||||
parentmap[name] = index unless parentmap.include?(name)
|
||||
subdependencies[name] << dependency
|
||||
end
|
||||
|
||||
selected[release[:module_name]] = release
|
||||
candidate_set << release
|
||||
[candidates, preferred]
|
||||
end
|
||||
|
||||
begin
|
||||
subresolutions = @ignore_dependencies ? [] : resolve_constraints(subdependencies, selected)
|
||||
#
|
||||
# Perform the following post-resolution checks when applicable:
|
||||
# - check that the resolution satisfies contraints imposed by already installed module releases
|
||||
# - check that the resolution is not a downgrade of an already installed module release
|
||||
# - check that the reoslution is not replacing an already installead module release with local modifications
|
||||
# Throw an appropriate exception in case any of the checks fails.
|
||||
#
|
||||
def check_resolution(release, selected)
|
||||
# skip the tests if --force was specified or the resolution
|
||||
# is an already installed module release
|
||||
return if @force || release[:module]
|
||||
|
||||
resolutions = candidate_set.map do |release|
|
||||
# perfrom post-resolution checks on modules installed from Forge (or a tarball)
|
||||
# (skip the checks if --force was specified)
|
||||
unless @force || release[:module] # skip already installed modules
|
||||
module_name = release[:module_name]
|
||||
|
||||
# verify that constraints imposed by already installed modules
|
||||
# verify that constraints imposed by already installed module releases
|
||||
# are not violated
|
||||
constraints = @conditions[module_name].select { |constraint|
|
||||
# ignore constraints from modules which are being upgraded
|
||||
|
@ -461,6 +442,58 @@ module Puppet::ModuleTool::Shared
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Resolve constraints described by the dependencies parameter.
|
||||
# First select all releases which satisfy the constraints, these
|
||||
# are candidates for the resolution. Then select one particular
|
||||
# release of each module from the candidates, collect all
|
||||
# dependencies of these selected releases and try to resolve
|
||||
# those recursively. If the resolution fails, try to select
|
||||
# different releases from the candidates and try again.
|
||||
#
|
||||
def resolve_constraints(dependencies, selected = {})
|
||||
candidates, preferred = get_candidates(dependencies, selected)
|
||||
|
||||
# we are done if there are no dependencies left to be resolved
|
||||
return [] if candidates.empty?
|
||||
|
||||
resolution_exception = nil
|
||||
# try all possible combinations of candidates in unifromly increasing sequence
|
||||
mostly_uniformly_increasing_sequence(candidates.map(&:length), preferred) do |offsets|
|
||||
# the current set of candidates (possible resolutions) to try
|
||||
candidate_set = []
|
||||
|
||||
# dependencies to resolve in the next recursion
|
||||
# (constraints imposed by the candidates in the candidate set)
|
||||
subdependencies = Hash.new { |h,k| h[k] = [] }
|
||||
|
||||
# map of parents used to link resolutions of dependencies to the candidates
|
||||
# in the current candidate set to build the install/upgrade tree which
|
||||
# is printed by the install/upgrade command
|
||||
parentmap = {}
|
||||
|
||||
# select the next set of candidates/resolutions
|
||||
# and gather their dependencies
|
||||
candidates.each_index do |index|
|
||||
release = candidates[index][offsets[index]]
|
||||
|
||||
release[:dependencies].each do |dependency|
|
||||
name = dependency[:target]
|
||||
parentmap[name] = index unless parentmap.include?(name)
|
||||
subdependencies[name] << dependency
|
||||
end
|
||||
|
||||
selected[release[:module_name]] = release
|
||||
candidate_set << release
|
||||
end
|
||||
|
||||
begin
|
||||
subresolutions = @ignore_dependencies ? [] : resolve_constraints(subdependencies, selected)
|
||||
|
||||
resolutions = candidate_set.map do |release|
|
||||
# perform post resolution checks
|
||||
check_resolution(release, selected)
|
||||
|
||||
# the rosultion consists of the release satisfying the constriants
|
||||
# and the list of resolutions satisfying its dependencies (to be
|
||||
# filled in just below)
|
||||
|
@ -472,7 +505,7 @@ module Puppet::ModuleTool::Shared
|
|||
resolution
|
||||
end
|
||||
|
||||
# link the subresolutions with the resolutions to from the install/upgrade tree
|
||||
# link the subresolutions with the resolutions to form the install/upgrade tree
|
||||
subresolutions.each do |subresolution|
|
||||
resolutions[parentmap[subresolution[:release][:module_name]]][:dependencies] << subresolution
|
||||
end
|
||||
|
@ -500,7 +533,7 @@ module Puppet::ModuleTool::Shared
|
|||
# fall through to try the next candidate set
|
||||
end
|
||||
|
||||
# the currently selected candidate set is could not be resolved
|
||||
# the currently selected candidate set could not be resolved
|
||||
# we need to unselected the respective releaes and try the next set
|
||||
candidate_set.each do |release|
|
||||
selected.delete(release[:module_name])
|
||||
|
@ -619,7 +652,7 @@ module Puppet::ModuleTool::Shared
|
|||
# Long term we should just get rid of this caching behavior and cleanup downloaded modules after they install
|
||||
# but for now this is a quick fix to disable caching
|
||||
Puppet::Forge::Cache.clean
|
||||
download_tarballs(@graph, @options[:target_dir])
|
||||
download_tarballs(@graph, options[:target_dir])
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -181,15 +181,11 @@ describe "puppet module install" do
|
|||
|
||||
def expects_installer_run_with(name, options)
|
||||
installer = mock("Installer")
|
||||
install_dir = mock("InstallDir")
|
||||
forge = mock("Forge")
|
||||
|
||||
Puppet::Forge.expects(:new).with("PMT", subject.version).returns(forge)
|
||||
Puppet::ModuleTool::InstallDirectory.expects(:new).
|
||||
with(Pathname.new(expected_options[:target_dir])).
|
||||
returns(install_dir)
|
||||
Puppet::ModuleTool::Applications::Installer.expects(:new).
|
||||
with("puppetlabs-apache", forge, install_dir, expected_options).
|
||||
with("puppetlabs-apache", forge, expected_options).
|
||||
returns(installer)
|
||||
installer.expects(:run)
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
let(:forge) do
|
||||
forge = mock("Puppet::Forge")
|
||||
|
||||
forge.stubs(:remote_dependency_info).returns(remote_dependency_info)
|
||||
forge.stubs(:multiple_remote_dependency_info).returns(remote_dependency_info)
|
||||
forge.stubs(:uri).returns('forge-dev.puppetlabs.com')
|
||||
remote_dependency_info.each_key do |mod|
|
||||
remote_dependency_info[mod].each do |release|
|
||||
|
@ -37,6 +37,7 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
let(:install_dir) do
|
||||
install_dir = mock("Puppet::ModuleTool::InstallDirectory")
|
||||
install_dir.stubs(:prepare)
|
||||
Puppet::ModuleTool::InstallDirectory.stubs(:new).returns(install_dir)
|
||||
install_dir
|
||||
end
|
||||
|
||||
|
@ -78,26 +79,18 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
}
|
||||
end
|
||||
|
||||
describe "the behavior of .is_module_package?" do
|
||||
it "should return true when file is a module package" do
|
||||
pending("porting to Windows", :if => Puppet.features.microsoft_windows?) do
|
||||
installer = installer_class.new("foo", forge, install_dir, options)
|
||||
installer.send(:is_module_package?, stdlib_pkg).should be_true
|
||||
end
|
||||
end
|
||||
def installer_run(*args)
|
||||
installer = installer_class.new(*args)
|
||||
installer.instance_exec(fake_env) { |environment|
|
||||
@environment = environment
|
||||
}
|
||||
|
||||
it "should return false when file is not a module package" do
|
||||
pending("porting to Windows", :if => Puppet.features.microsoft_windows?) do
|
||||
installer = installer_class.new("foo", forge, install_dir, options)
|
||||
installer.send(:is_module_package?, "pmtacceptance-apollo-0.0.2.tar").
|
||||
should be_false
|
||||
end
|
||||
end
|
||||
installer.run
|
||||
end
|
||||
|
||||
context "when the source is a repository" do
|
||||
it "should require a valid name" do
|
||||
lambda { installer_class.run('puppet', install_dir, params) }.should
|
||||
lambda { installer_class.run('puppet', params) }.should
|
||||
raise_error(ArgumentError, "Could not install module with invalid name: puppet")
|
||||
end
|
||||
|
||||
|
@ -106,18 +99,14 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
Puppet::ModuleTool::Applications::Unpacker.expects(:new).
|
||||
with('/fake_cache/pmtacceptance-stdlib-1.0.0.tar.gz', options).
|
||||
returns(unpacker)
|
||||
results = installer_class.run('pmtacceptance-stdlib', forge, install_dir, options)
|
||||
results[:installed_modules].length == 1
|
||||
results = installer_run('pmtacceptance-stdlib', forge, options)
|
||||
results[:installed_modules].length.should == 1
|
||||
results[:installed_modules][0][:module].should == "pmtacceptance-stdlib"
|
||||
results[:installed_modules][0][:version][:vstring].should == "1.0.0"
|
||||
end
|
||||
end
|
||||
|
||||
context "should check the target directory" do
|
||||
let(:installer) do
|
||||
installer_class.new('pmtacceptance-stdlib', forge, install_dir, options)
|
||||
end
|
||||
|
||||
def expect_normal_unpacker
|
||||
Puppet::ModuleTool::Applications::Unpacker.expects(:new).
|
||||
with('/fake_cache/pmtacceptance-stdlib-1.0.0.tar.gz', options).
|
||||
|
@ -132,10 +121,8 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
pending("porting to Windows", :if => Puppet.features.microsoft_windows?) do
|
||||
expect_normal_unpacker
|
||||
install_dir.expects(:prepare).with("pmtacceptance-stdlib", "latest")
|
||||
|
||||
results = installer.run
|
||||
|
||||
results[:installed_modules].length.should eq 1
|
||||
results = installer_run('pmtacceptance-stdlib', forge, options)
|
||||
results[:installed_modules].length.should == 1
|
||||
results[:installed_modules][0][:module].should == "pmtacceptance-stdlib"
|
||||
results[:installed_modules][0][:version][:vstring].should == "1.0.0"
|
||||
end
|
||||
|
@ -145,9 +132,7 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
pending("porting to Windows", :if => Puppet.features.microsoft_windows?) do
|
||||
install_dir.expects(:prepare).with("pmtacceptance-stdlib", "latest").
|
||||
raises(Puppet::ModuleTool::Errors::PermissionDeniedCreateInstallDirectoryError.new("original", :module => "pmtacceptance-stdlib"))
|
||||
|
||||
results = installer.run
|
||||
|
||||
results = installer_run('pmtacceptance-stdlib', forge, options)
|
||||
results[:result].should == :failure
|
||||
results[:error][:oneline].should =~ /Permission is denied/
|
||||
end
|
||||
|
@ -167,7 +152,7 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
with('/fake_cache/pmtacceptance-java-1.7.1.tar.gz', options).
|
||||
returns(unpacker)
|
||||
|
||||
results = installer_class.run('pmtacceptance-apollo', forge, install_dir, options)
|
||||
results = installer_run('pmtacceptance-apollo', forge, options)
|
||||
installed_dependencies = results[:installed_modules][0][:dependencies]
|
||||
|
||||
dependencies = installed_dependencies.inject({}) do |result, dep|
|
||||
|
@ -187,7 +172,7 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
Puppet::ModuleTool::Applications::Unpacker.expects(:new).
|
||||
with('/fake_cache/pmtacceptance-apollo-0.0.2.tar.gz', options).
|
||||
returns(unpacker)
|
||||
results = installer_class.run('pmtacceptance-apollo', forge, install_dir, options)
|
||||
results = installer_run('pmtacceptance-apollo', forge, options)
|
||||
results[:installed_modules][0][:module].should == "pmtacceptance-apollo"
|
||||
end
|
||||
end
|
||||
|
@ -198,7 +183,7 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
Puppet::ModuleTool::Applications::Unpacker.expects(:new).
|
||||
with('/fake_cache/pmtacceptance-apollo-0.0.2.tar.gz', options).
|
||||
returns(unpacker)
|
||||
results = installer_class.run('pmtacceptance-apollo', forge, install_dir, options)
|
||||
results = installer_run('pmtacceptance-apollo', forge, options)
|
||||
dependencies = results[:installed_modules][0][:dependencies]
|
||||
dependencies.should == []
|
||||
end
|
||||
|
@ -210,7 +195,7 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
Puppet::ModuleTool::Applications::Unpacker.expects(:new).
|
||||
with('/fake_cache/pmtacceptance-apollo-0.0.2.tar.gz', options).
|
||||
returns(unpacker)
|
||||
results = installer_class.run('pmtacceptance-apollo', forge, install_dir, options)
|
||||
results = installer_run('pmtacceptance-apollo', forge, options)
|
||||
dependencies = results[:installed_modules][0][:dependencies]
|
||||
dependencies.should == []
|
||||
end
|
||||
|
@ -219,49 +204,21 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => Puppet.features
|
|||
it "should set an error if dependencies can't be resolved" do
|
||||
pending("porting to Windows", :if => Puppet.features.microsoft_windows?) do
|
||||
options = { :version => '0.0.1', :target_dir => modpath1 }
|
||||
oneline = "'pmtacceptance-apollo' (v0.0.1) requested; Invalid dependency cycle"
|
||||
oneline = "Could not install 'pmtacceptance-apollo' (v0.0.1); module 'pmtacceptance-stdlib' cannot satisfy dependencies"
|
||||
multiline = <<-MSG.strip
|
||||
Could not install module 'pmtacceptance-apollo' (v0.0.1)
|
||||
No version of 'pmtacceptance-stdlib' will satisfy dependencies
|
||||
You specified 'pmtacceptance-apollo' (v0.0.1),
|
||||
which depends on 'pmtacceptance-java' (v1.7.1),
|
||||
which depends on 'pmtacceptance-stdlib' (v1.0.0)
|
||||
Use `puppet module install --force` to install this module anyway
|
||||
'pmtacceptance-apollo' (v0.0.1) requires 'pmtacceptance-stdlib' (v0.0.1)
|
||||
'pmtacceptance-java' (v1.7.1) requires 'pmtacceptance-stdlib' (v1.0.0)
|
||||
Use `puppet module install --ignore-dependencies` to install only this module
|
||||
MSG
|
||||
|
||||
results = installer_class.run('pmtacceptance-apollo', forge, install_dir, options)
|
||||
results = installer_class.run('pmtacceptance-apollo', forge, options)
|
||||
results[:result].should == :failure
|
||||
results[:error][:oneline].should == oneline
|
||||
results[:error][:multiline].should == multiline
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are modules installed" do
|
||||
it "should use local version when already exists and satisfies constraints"
|
||||
it "should reinstall the local version if force is used"
|
||||
it "should upgrade local version when necessary to satisfy constraints"
|
||||
it "should error when a local version can't be upgraded to satisfy constraints"
|
||||
end
|
||||
|
||||
context "when a local module needs upgrading to satisfy constraints but has changes" do
|
||||
it "should error"
|
||||
it "should warn and continue if force is used"
|
||||
end
|
||||
|
||||
it "should error when a local version of a dependency has no version metadata"
|
||||
it "should error when a local version of a dependency has a non-semver version"
|
||||
it "should error when a local version of a dependency has a different forge name"
|
||||
it "should error when a local version of a dependency has no metadata"
|
||||
end
|
||||
|
||||
context "when the source is a filesystem" do
|
||||
before do
|
||||
@sourcedir = tmpdir('sourcedir')
|
||||
end
|
||||
|
||||
it "should error if it can't parse the name"
|
||||
|
||||
it "should try to get_release_package_from_filesystem if it has a valid name"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,38 +30,21 @@ describe Puppet::ModuleTool::Applications::Unpacker do
|
|||
end
|
||||
|
||||
before :each do
|
||||
# Mock redhat for most test cases
|
||||
Facter.stubs(:value).with("osfamily").returns("Redhat")
|
||||
build_dir.stubs(:mkpath => nil, :rmtree => nil, :children => [])
|
||||
unpacker.stubs(:build_dir).at_least_once.returns(build_dir)
|
||||
FileUtils.stubs(:mv)
|
||||
end
|
||||
|
||||
context "on linux" do
|
||||
it "should attempt to untar file to temporary location using system tar" do
|
||||
it "should attempt to open the file with Zlib::GzipReader and process the yielded stream with Puppet::Util::Archive::Tar::Minitar::Reader" do
|
||||
pending("porting to Windows", :if => Puppet.features.microsoft_windows?) do
|
||||
Puppet::Util::Execution.expects(:execute).with("tar xzf #{filename} -C #{build_dir}").returns(true)
|
||||
tar = mock('Puppet::Util::Archive::Tar::Minitar::Reader')
|
||||
tar.expects(:each)
|
||||
gzip = mock('Zlib::GzipReader')
|
||||
Puppet::Util::Archive::Tar::Minitar::Reader.expects(:open).with(gzip).yields(tar)
|
||||
Zlib::GzipReader.expects(:open).with(Pathname.new(filename)).yields(gzip)
|
||||
unpacker.run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "on solaris" do
|
||||
before :each do
|
||||
Facter.expects(:value).with("osfamily").returns("Solaris")
|
||||
end
|
||||
|
||||
it "should attempt to untar file to temporary location using gnu tar" do
|
||||
Puppet::Util.stubs(:which).with('gtar').returns('/usr/sfw/bin/gtar')
|
||||
Puppet::Util::Execution.expects(:execute).with("gtar xzf #{filename} -C #{build_dir}").returns(true)
|
||||
unpacker.run
|
||||
end
|
||||
|
||||
it "should throw exception if gtar is not in the path exists" do
|
||||
Puppet::Util.stubs(:which).with('gtar').returns(nil)
|
||||
expect { unpacker.run }.to raise_error RuntimeError, "Cannot find the command 'gtar'. Make sure GNU tar is installed, and is in your PATH."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -6,29 +6,140 @@ require 'semver'
|
|||
describe Puppet::ModuleTool::Applications::Upgrader do
|
||||
include PuppetSpec::Files
|
||||
|
||||
it "should update the requested module"
|
||||
it "should not update dependencies"
|
||||
it "should fail when updating a dependency to an unsupported version"
|
||||
it "should fail when updating a module that is not installed"
|
||||
it "should warn when the latest version is already installed"
|
||||
it "should warn when the best version is already installed"
|
||||
let(:unpacker) { stub(:run) }
|
||||
let(:upgrader_class) { Puppet::ModuleTool::Applications::Upgrader }
|
||||
let(:modpath) { File.join(tmpdir('upgrader'), 'modpath') }
|
||||
let(:fake_env) { Puppet::Node::Environment.new('fake_env') }
|
||||
let(:options) { { :target_dir => modpath } }
|
||||
|
||||
context "when using the '--version' option" do
|
||||
it "should update an installed module to the requested version"
|
||||
let(:forge) {
|
||||
forge = mock("Puppet::Forge")
|
||||
|
||||
forge.stubs(:multiple_remote_dependency_info).returns(remote_dependency_info)
|
||||
forge.stubs(:uri).returns('forge-dev.puppetlabs.com')
|
||||
remote_dependency_info.each_key do |mod|
|
||||
remote_dependency_info[mod].each do |release|
|
||||
forge.stubs(:retrieve).with(release['file']).returns("/fake_cache#{release['file']}")
|
||||
end
|
||||
end
|
||||
|
||||
context "when using the '--force' flag" do
|
||||
it "should ignore missing dependencies"
|
||||
it "should ignore version constraints"
|
||||
it "should not update a module that is not installed"
|
||||
forge
|
||||
}
|
||||
|
||||
let(:remote_dependency_info) {
|
||||
{
|
||||
"pmtacceptance/stdlib" => [
|
||||
{ "dependencies" => [],
|
||||
"version" => "0.0.1",
|
||||
"file" => "/pmtacceptance-stdlib-0.0.1.tar.gz" },
|
||||
{ "dependencies" => [],
|
||||
"version" => "0.0.2",
|
||||
"file" => "/pmtacceptance-stdlib-0.0.2.tar.gz" },
|
||||
{ "dependencies" => [],
|
||||
"version" => "1.0.0",
|
||||
"file" => "/pmtacceptance-stdlib-1.0.0.tar.gz" }
|
||||
],
|
||||
"pmtacceptance/java" => [
|
||||
{ "dependencies" => [["pmtacceptance/stdlib", ">= 0.0.1"]],
|
||||
"version" => "1.7.0",
|
||||
"file" => "/pmtacceptance-java-1.7.0.tar.gz" },
|
||||
{ "dependencies" => [["pmtacceptance/stdlib", "1.0.0"]],
|
||||
"version" => "1.7.1",
|
||||
"file" => "/pmtacceptance-java-1.7.1.tar.gz" }
|
||||
],
|
||||
"pmtacceptance/apollo" => [
|
||||
{ "dependencies" => [
|
||||
["pmtacceptance/java", "1.7.1"],
|
||||
["pmtacceptance/stdlib", "0.0.1"]
|
||||
],
|
||||
"version" => "0.0.1",
|
||||
"file" => "/pmtacceptance-apollo-0.0.1.tar.gz" },
|
||||
{ "dependencies" => [
|
||||
["pmtacceptance/java", ">= 1.7.0"],
|
||||
["pmtacceptance/stdlib", ">= 1.0.0"]
|
||||
],
|
||||
"version" => "0.0.2",
|
||||
"file" => "/pmtacceptance-apollo-0.0.2.tar.gz" }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
before do
|
||||
FileUtils.mkdir_p(modpath)
|
||||
fake_env.modulepath = [modpath]
|
||||
Puppet.settings[:modulepath] = modpath
|
||||
end
|
||||
|
||||
context "when using the '--env' option" do
|
||||
it "should use the correct environment"
|
||||
def upgrader_run(*args)
|
||||
upgrader = upgrader_class.new(*args)
|
||||
upgrader.instance_exec(fake_env) { |environment|
|
||||
@environment = environment
|
||||
}
|
||||
|
||||
upgrader.run
|
||||
end
|
||||
|
||||
context "when there are missing dependencies" do
|
||||
it "should fail to upgrade the original module"
|
||||
it "should raise an error"
|
||||
it "should update the requested module" do
|
||||
local_module = mock('Puppet::Module')
|
||||
local_module.stubs(:forge_name).returns('pmtacceptance/stdlib')
|
||||
local_module.stubs(:name).returns('stdlib')
|
||||
local_module.stubs(:version).returns('0.5.0')
|
||||
local_module.stubs(:has_metadata?).returns(true)
|
||||
local_module.stubs(:has_local_changes?).returns(false)
|
||||
local_module.stubs(:modulepath).returns(modpath)
|
||||
local_module.stubs(:dependencies).returns([])
|
||||
|
||||
fake_env.stubs(:modules_by_path).returns({
|
||||
modpath => [ local_module ]
|
||||
})
|
||||
|
||||
Puppet::ModuleTool::Applications::Unpacker.expects(:new).
|
||||
with('/fake_cache/pmtacceptance-stdlib-1.0.0.tar.gz', options).
|
||||
returns(unpacker)
|
||||
|
||||
results = upgrader_run('pmtacceptance-stdlib', forge, options)
|
||||
results[:affected_modules].length.should == 1
|
||||
results[:affected_modules][0][:module].should == 'pmtacceptance-stdlib'
|
||||
results[:affected_modules][0][:version][:vstring].should == '1.0.0'
|
||||
end
|
||||
|
||||
it 'should fail when updating a module that is not installed' do
|
||||
fake_env.stubs(:modules_by_path).returns({})
|
||||
|
||||
results = upgrader_run('pmtacceptance-stdlib', forge, options)
|
||||
|
||||
results[:result].should == :failure
|
||||
results[:error][:oneline].should == "Could not upgrade 'pmtacceptance-stdlib'; module is not installed"
|
||||
end
|
||||
|
||||
it 'should warn when the latest version is already installed' do
|
||||
local_module = mock('Puppet::Module')
|
||||
local_module.stubs(:forge_name).returns('pmtacceptance/stdlib')
|
||||
local_module.stubs(:name).returns('stdlib')
|
||||
local_module.stubs(:version).returns('1.0.0')
|
||||
local_module.stubs(:has_metadata?).returns(true)
|
||||
local_module.stubs(:has_local_changes?).returns(false)
|
||||
local_module.stubs(:modulepath).returns(modpath)
|
||||
local_module.stubs(:dependencies).returns([])
|
||||
|
||||
fake_env.stubs(:modules_by_path).returns({
|
||||
modpath => [ local_module ]
|
||||
})
|
||||
|
||||
results = upgrader_run('pmtacceptance-stdlib', forge, options)
|
||||
|
||||
results[:result].should == :noop
|
||||
results[:error][:oneline].should == "Could not upgrade 'pmtacceptance-stdlib'; a better release is already installed"
|
||||
end
|
||||
|
||||
it 'should not update a module that is not installed even when --force is specified' do
|
||||
options[:force] = true
|
||||
|
||||
fake_env.stubs(:modules_by_path).returns({})
|
||||
|
||||
results = upgrader_run('pmtacceptance-stdlib', forge, options)
|
||||
|
||||
results[:result].should == :failure
|
||||
results[:error][:oneline].should == "Could not upgrade 'pmtacceptance-stdlib'; module is not installed"
|
||||
end
|
||||
end
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче