Commit 44afcf28 authored by Léo-Paul Géneau's avatar Léo-Paul Géneau 👾

Feature: adds deployment mode

- adds deployment mode in recipe options
- checks errors message in tests
parent 9d09fb7f
Pipeline #15988 passed with stage
in 0 seconds
......@@ -44,6 +44,10 @@ version
ruby-executable
A path to a Ruby executable. Gems will be installed using this executable.
deployment
If set to ``true``, the version of each gem dependency must be provided in
``gems`` option. Default value is ``false``.
gem-options
Extra options, that will be passed to gem executable. Example::
......
......@@ -13,6 +13,7 @@ import zc.buildout
import six.moves.urllib as urllib
from distutils.util import strtobool
from slapos.recipe.downloadunpacked import Recipe as Download
strip = lambda x:x.strip() # noqa
......@@ -32,16 +33,23 @@ class Recipe(object):
self.name,
)
if 'gems' not in options:
self.log.error("Missing 'gems' option.")
raise zc.buildout.UserError('Configuration error')
self.gems = options.get('gems')
if self.gems:
self.gems = self.gems.split()
else:
raise zc.buildout.UserError(
"Configuration error, 'gems' option is missing")
self.gems = options['gems'].split()
self.version = options.get('version')
self.url = options.get('url')
# Allow to define specific ruby executable. If not, take just 'ruby'
self.ruby_executable = options.get('ruby-executable', 'ruby')
deployment = options.get('deployment', 'false')
self.deployment = bool(strtobool(deployment))
self.gem_regex = re.compile(r'\s+([\w\-_.]+) \((<|~>|>=) '
r'((\d+\.)*\d+)(, (>=) ((\d+\.)*\d+))?\)')
def run(self, cmd, environ=None):
"""Run the given ``cmd`` in a child process."""
env = os.environ.copy()
......@@ -49,26 +57,70 @@ class Recipe(object):
env.update(environ)
try:
subprocess.check_output(cmd, env=env)
cmd_result = subprocess.check_output(cmd, env=env).decode()
except OSError as e:
self.log.error('Command failed: %s: %s' % (e, cmd))
raise zc.buildout.UserError('System error')
raise zc.buildout.UserError(
'System error, command failed: %s: %s' % (e, cmd))
except subprocess.CalledProcessError as e:
self.log.error(e.output)
if e.returncode < 0:
self.log.error('Command received signal %s: %s' % (
-e.returncode, e.cmd
))
raise zc.buildout.UserError('System error')
raise zc.buildout.UserError(
'System error, command received signal %s: %s'
% (-e.returncode, e.cmd)
)
elif e.returncode > 0:
self.log.error('Command failed with exit code %s: %s' % (
e.returncode, e.cmd
))
raise zc.buildout.UserError('System error')
raise zc.buildout.UserError(
'System error, command failed with exit code %s: %s'
% (e.returncode, e.cmd)
)
return cmd_result
def update(self):
pass
def _check_dependency_constraint(self, cons_dict, dep_dict, gemname):
if not cons_dict['symbol']:
return
dep_version_list = list(map(int, dep_dict['version'].split('.')))
cons_version_list = list(map(int, cons_dict['version'].split('.')))
if cons_dict['symbol'] == '~>':
self._check_dependency_constraint(
{ 'symbol': '>=', 'version': cons_dict['version'],},
dep_dict, gemname
)
if len(cons_version_list) > 1:
cons_version_list = cons_version_list[:-1]
cons_version_list[-1] += 1
self._check_dependency_constraint(
{
'symbol': '<',
'version': '.'.join(map(str, cons_version_list)),
},
dep_dict, gemname
)
return
elif cons_dict['symbol'] == '<':
if dep_version_list < cons_version_list:
return
elif cons_dict['symbol'] == '>=':
if dep_version_list >= cons_version_list:
return
else:
raise ValueError(
'Unhandled symbol in constraint %s for dependecy %s of gem %s'
% (' '.join(cons_dict.values()), dep_dict['gemname'], gemname)
)
raise zc.buildout.UserError(
'Configuration error, version %s for gem %s '
'does not satisfy dependency constraint %s of gem %s'
% (dep_dict['version'], dep_dict['gemname'],
' '.join(cons_dict.values()), gemname)
)
def _join_paths(self, *paths):
return ':'.join(filter(None, paths))
......@@ -79,8 +131,10 @@ class Recipe(object):
map(strip, line.split('=', 1)) for line in env
]])
except ValueError: # Unpacking impossible
self.log.error("Every environment line should contain a '=' sign")
raise zc.buildout.UserError('Configuration error')
raise zc.buildout.UserError(
'Configuration error, '
'every environment line should contain a "=" sign'
)
return env
def _get_env(self):
......@@ -107,6 +161,13 @@ class Recipe(object):
env.update({k: (v % env) for k, v in env_override})
return env
def _get_gem_dict(self, gem_str):
parsed_gem = gem_str.split('==', 1)
gem_dict = {'gemname': parsed_gem[0].strip()}
if len(parsed_gem) > 1:
gem_dict['version'] = parsed_gem[1].strip()
return gem_dict
def _get_latest_rubygems(self):
if self.url:
version = self.version
......@@ -130,8 +191,8 @@ class Recipe(object):
version = r.group(1)
return (url, version)
else:
self.log.error("Can't find latest rubygems version.")
raise zc.buildout.UserError('Configuration error')
raise zc.buildout.UserError(
'Can\'t find latest rubygems version.')
def _install_rubygems(self):
url, version = self._get_latest_rubygems()
......@@ -153,10 +214,10 @@ class Recipe(object):
if e.errno == errno.EEXIST:
pass
else:
self.log.error((
"IO error while creating '%s' directory."
) % self.options['location'])
raise zc.buildout.UserError('Configuration error')
raise zc.buildout.UserError(
'IO error while creating %s directory.'
% self.options['location']
)
os.chdir(srcdir)
......@@ -167,7 +228,7 @@ class Recipe(object):
self.ruby_executable,
'setup.rb',
'all',
'--prefix=%s' % self.options['location'],
'--prefix=' + self.options['location'],
'--no-rdoc',
'--no-ri',
]
......@@ -198,21 +259,21 @@ class Recipe(object):
return executable
def _install_gem(self, gemname, gem_executable, bindir):
def _install_gem(self, gem_dict, gem_executable, bindir):
cmd = [
self.ruby_executable,
gem_executable,
'install',
'--no-document',
'--bindir=%s' % bindir,
'--bindir=' + bindir,
]
if '==' in gemname:
gemname, version = map(strip, gemname.split('==', 1))
cmd.append(gemname)
cmd.append('--version=%s' % version)
else:
cmd.append(gemname)
if self.deployment:
cmd.append('--ignore-dependencies')
cmd.append(gem_dict['gemname'])
if 'version' in gem_dict:
cmd.append('--version=' + gem_dict['version'])
extra = self.options.get('gem-options', '')
extra = filter(None, map(strip, extra.splitlines()))
......@@ -229,6 +290,31 @@ class Recipe(object):
if gem_executable:
return gem_executable[0]
def get_dependency_list(self, gem_dict, gem_executable):
cmd = [
self.ruby_executable,
gem_executable,
'dependency',
'-rv',
gem_dict['version'],
'/^' + gem_dict['gemname'].replace('.',r'\.') + '$/',
]
cmd_result = self.run(cmd, self._get_env())
return [{
'gemname': match[0],
'constraint_list': [
{
'symbol': match[1],
'version': match[2],
},
{
'symbol': match[5],
'version': match[6],
},
],
} for match in self.gem_regex.findall(cmd_result)]
def install(self):
parts = [self.options['location']]
......@@ -239,9 +325,32 @@ class Recipe(object):
self._install_rubygems()
gem_executable = self.get_gem_executable(bindir)
for gemname in self.gems:
self.log.info('installing ruby gem "%s"' % gemname)
self._install_gem(gemname, gem_executable, bindir)
gem_dict_list = list(map(self._get_gem_dict, self.gems))
for gem_dict in gem_dict_list:
if self.deployment:
if 'version' not in gem_dict:
raise zc.buildout.UserError(
'Configuration error, '
'version for gem %s is missing' % gem_dict['gemname']
)
for dep_dict in self.get_dependency_list(gem_dict,
gem_executable):
match = [gem_d for gem_d in gem_dict_list
if dep_dict['gemname'] == gem_d['gemname']]
if not match:
raise zc.buildout.UserError(
'Configuration error, '
'version for dependency %s is missing'
% dep_dict['gemname']
)
for constraint in dep_dict['constraint_list']:
self._check_dependency_constraint(
constraint, match[0], gem_dict['gemname'])
self.log.info('installing ruby gem "%s"', gem_dict['gemname'])
self._install_gem(gem_dict, gem_executable, bindir)
for executable in os.listdir(bindir):
installed_path = self._install_executable(
......
......@@ -22,6 +22,191 @@ def touch(path):
with path.open('w') as f:
f.write('')
gem_dependencies = {
'cucumber-core': {
'3.0.0': [
{
'gemname': 'backports',
'constraint_list': [
{
'symbol': '>=',
'version': '3.8.0',
},
{
'symbol': '',
'version': '',
},
]
},
{
'gemname': 'cucumber-tag_expressions',
'constraint_list': [
{
'symbol': '>=',
'version': '1.0.1',
},
{
'symbol': '',
'version': '',
},
]
},
{
'gemname': 'gherkin',
'constraint_list': [
{
'symbol': '>=',
'version': '4.1.3',
},
{
'symbol': '',
'version': '',
},
]
},
],
'7.1.0': [
{
'gemname': 'cucumber-gherkin',
'constraint_list': [
{
'symbol': '~>',
'version': '14.0',
},
{
'symbol': '>=',
'version': '14.0.1',
},
]
},
{
'gemname': 'cucumber-messages',
'constraint_list': [
{
'symbol': '>=',
'version': '12.2.0',
},
{
'symbol': '~>',
'version': '12.2',
},
]
},
{
'gemname': 'cucumber-tag_expressions',
'constraint_list': [
{
'symbol': '~>',
'version': '2.0',
},
{
'symbol': '>=',
'version': '2.0.4',
},
]
},
],
},
'cucumber-gherkin': {
'9.1.0': [
{
'gemname': 'cucumber-messages',
'constraint_list': [
{
'symbol': '~>',
'version': '9.0',
},
{
'symbol': '>=',
'version': '9.0.3',
},
]
},
],
'14.1.0': [
{
'gemname': 'cucumber-messages',
'constraint_list': [
{
'symbol': '~>',
'version': '12.3',
},
{
'symbol': '>=',
'version': '12.3.2',
},
]
},
],
},
'gherkin': {
'8.0.0': [
{
'gemname': 'cucumber-messages',
'constraint_list': [
{
'symbol': '~>',
'version': '6.0',
},
{
'symbol': '>=',
'version': '6.0.1',
},
]
},
],
},
'hoe': {
'3.4.0': [
{
'gemname': 'rake',
'constraint_list': [
{
'symbol': '<',
'version': '11.0',
},
{
'symbol': '>=',
'version': '0.8',
},
]
},
],
},
'rash': {
'0.1.0': [
{
'gemname': 'hashie',
'constraint_list': [
{
'symbol': '>=',
'version': '0.3.1',
},
{
'symbol': '',
'version': '',
},
]
},
],
'0.3.0': [
{
'gemname': 'hashie',
'constraint_list': [
{
'symbol': '~>',
'version': '1.0.0',
},
{
'symbol': '',
'version': '',
},
]
},
],
},
}
class fixture(object):
def __init__(self, options=None, version='2.0.0'):
......@@ -54,7 +239,7 @@ class fixture(object):
def set_up(self):
name = 'rubygems'
version = self.options.get('return', {}).get('version', self.version)
self.patch((
('check_output', 'rubygems.subprocess.check_output'),
('urlopen', 'rubygems.urllib.request.urlopen'),
......@@ -66,8 +251,8 @@ class fixture(object):
self.makedirs((
'bin',
'ruby-%s' % version,
'rubygems-%s' % version,
'ruby-' + version,
'rubygems-' + version,
'rubygems/bin',
))
......@@ -87,11 +272,24 @@ class fixture(object):
class RubyGemsTests(unittest.TestCase):
@fixture({'recipe': {'gems': 'sass'}})
def test_success(self, path, patches, buildout, name, options):
recipe = rubygems.Recipe(buildout, name, options)
recipe.install()
def check_output_test(self, check_output_mock, expected_arg_list_list):
self.assertEqual(check_output_mock.call_count,
len(expected_arg_list_list))
for command_nb, expected_arg_list in enumerate(
expected_arg_list_list):
# half of the mock calls come from the use of 'decode' method
self.assertEqual(
check_output_mock.mock_calls[2*command_nb][1][0],
expected_arg_list
)
self.assertEqual(
str(check_output_mock.mock_calls[2*command_nb+1]),
'call().decode()'
)
def install_with_default_rubygems_test(self, path, patches,
expected_install_arg_list_list):
# One urlopen call to get latest version
self.assertEqual(patches['urlopen'].call_count, 1)
......@@ -107,26 +305,33 @@ class RubyGemsTests(unittest.TestCase):
'destination': str(path / 'rubygems-2.0.0'),
})
# Two check_output calls to install rubygems and specified gem
self.assertEqual(patches['check_output'].call_count, 2)
args = patches['check_output'].mock_calls[0][1]
self.assertEqual(args[0], [
expected_install_arg_list_list.insert(0, [
'ruby', 'setup.rb', 'all', '--prefix=%s/rubygems' % path,
'--no-rdoc', '--no-ri',
])
self.check_output_test(
patches['check_output'], expected_install_arg_list_list)
args = patches['check_output'].mock_calls[1][1]
self.assertEqual(args[0], [
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'sass', '--'
])
@fixture({'recipe': {'gems': 'sass'}})
def test_success(self, path, patches, buildout, name, options):
recipe = rubygems.Recipe(buildout, name, options)
recipe.install()
expected_install_arg_list_list = [
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'sass', '--',
],
]
self.install_with_default_rubygems_test(
path, patches, expected_install_arg_list_list)
@fixture({'recipe': {}})
def test_missing_gems(self, path, patches, buildout, name, options):
self.assertRaises(
self.assertRaisesRegexp(
zc.buildout.UserError,
"Configuration error, 'gems' option is missing",
rubygems.Recipe, buildout, name, options
)
......@@ -134,21 +339,33 @@ class RubyGemsTests(unittest.TestCase):
def test_oserror(self, path, patches, buildout, name, options):
patches['check_output'].side_effect = OSError
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaises(zc.buildout.UserError, recipe.install)
self.assertRaisesRegexp(
zc.buildout.UserError,
'System error, command failed: .*',
recipe.install
)
@fixture({'recipe': {'gems': 'sass'}})
def test_signal_received(self, path, patches, buildout, name, options):
exception = subprocess.CalledProcessError(-1, '')
patches['check_output'].side_effect = exception
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaises(zc.buildout.UserError, recipe.install)
self.assertRaisesRegexp(
zc.buildout.UserError,
'System error, command received signal 1: .*',
recipe.install
)
@fixture({'recipe': {'gems': 'sass'}})
def test_non_zero_exitcode(self, path, patches, buildout, name, options):
exception = subprocess.CalledProcessError(1, '')
patches['check_output'].side_effect = exception
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaises(zc.buildout.UserError, recipe.install)
self.assertRaisesRegexp(
zc.buildout.UserError,
'System error, command failed with exit code 1: .*',
recipe.install
)
@fixture({'recipe': {'gems': 'sass'}})
def test_update(self, path, patches, buildout, name, options):
......@@ -158,7 +375,12 @@ class RubyGemsTests(unittest.TestCase):
@fixture({'recipe': {'gems': 'sass', 'environment': 'invalid'}})
def test_invalid_environment(self, path, patches, buildout, name, options):
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaises(zc.buildout.UserError, recipe.install)
self.assertRaisesRegexp(
zc.buildout.UserError,
'Configuration error, '
'every environment line should contain a "=" sign',
recipe.install
)
@fixture({'recipe': {
'gems': 'sass',
......@@ -177,14 +399,21 @@ class RubyGemsTests(unittest.TestCase):
def test_no_version(self, path, patches, buildout, name, options):
patches['urlopen'].return_value = BytesIO(b'')
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaises(zc.buildout.UserError, recipe.install)
self.assertRaisesRegexp(zc.buildout.UserError,
'Can\'t find latest rubygems version.',
recipe.install
)
@fixture({'recipe': {'gems': 'sass'}})
@mock.patch('rubygems.os.mkdir')
def test_mkdir_error(self, path, patches, buildout, name, options, mkdir):
mkdir.side_effect = OSError(errno.EIO)
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaises(zc.buildout.UserError, recipe.install)
self.assertRaisesRegexp(
zc.buildout.UserError,
'IO error while creating %s/rubygems directory.' % path,
recipe.install
)
@fixture({'recipe': {'gems': 'sass'}})
def test_executables(self, path, patches, buildout, name, options):
......@@ -204,3 +433,337 @@ class RubyGemsTests(unittest.TestCase):
if matched:
self.assertEqual(matched.group(), '--version=1.0')
break
@fixture({'recipe': {'gems': 'sass', 'deployment': 'true'}})
def test_deployment_not_pinned_version_error(
self, path, patches, buildout, name, options):
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaisesRegexp(
zc.buildout.UserError,
'Configuration error, version for gem sass is missing',
recipe.install
)
@fixture({'recipe': {'gems': 'rash==0.1.0', 'deployment': 'true'}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_not_pinned_dependency_error(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [gem_dependencies['rash']['0.1.0']]
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaisesRegexp(
zc.buildout.UserError,
'Configuration error, version for dependency hashie is missing',
recipe.install
)
@fixture({'recipe': {
'gems': 'rash==0.1.0 hashie==0.3.0',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_rash010_version_dependency_error(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [gem_dependencies['rash']['0.1.0']]
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaisesRegexp(
zc.buildout.UserError,
'Configuration error, version 0.3.0 for gem hashie '
'does not satisfy dependency constraint >= 0.3.1 of gem rash',
recipe.install
)
@fixture({'recipe': {
'gems': 'rash==0.1.0 hashie==0.3.1',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_rash010_pinned_dependency(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [gem_dependencies['rash']['0.1.0'],
[],]
recipe = rubygems.Recipe(buildout, name, options)
recipe.install()
expected_install_arg_list_list = [
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'rash', '--version=0.1.0', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'hashie', '--version=0.3.1', '--',
],
]
self.install_with_default_rubygems_test(
path, patches, expected_install_arg_list_list)
@fixture({'recipe': {
'gems': 'rash==0.3.0 hashie==1.1.0',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_rash030_version_dependency_error(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [gem_dependencies['rash']['0.3.0']]
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaisesRegexp(
zc.buildout.UserError,
'Configuration error, version 1.1.0 for gem hashie '
'does not satisfy dependency constraint < 1.1 of gem rash',
recipe.install
)
@fixture({'recipe': {
'gems': 'rash==0.3.0 hashie==1.0.0',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_rash030_pinned_dependency(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [gem_dependencies['rash']['0.3.0'],
[],]
recipe = rubygems.Recipe(buildout, name, options)
recipe.install()
expected_install_arg_list_list = [
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'rash', '--version=0.3.0', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'hashie', '--version=1.0.0', '--',
],
]
self.install_with_default_rubygems_test(
path, patches, expected_install_arg_list_list)
@fixture({'recipe': {
'gems': 'cucumber-gherkin==9.1.0 cucumber-messages==9.0.2',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_cucumber_gherkin_version_dependency_error(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [
gem_dependencies['cucumber-gherkin']['9.1.0']]
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaisesRegexp(
zc.buildout.UserError,
'Configuration error, version 9.0.2 for gem cucumber-messages '
'does not satisfy dependency constraint >= 9.0.3 '
'of gem cucumber-gherkin',
recipe.install
)
@fixture({'recipe': {
'gems': 'cucumber-gherkin==9.1.0 cucumber-messages==9.0.3',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_cucumber_gherkin_pinned_dependency(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [
gem_dependencies['cucumber-gherkin']['9.1.0'], []]
recipe = rubygems.Recipe(buildout, name, options)
recipe.install()
expected_install_arg_list_list = [
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'cucumber-gherkin',
'--version=9.1.0', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'cucumber-messages',
'--version=9.0.3', '--',
],
]
self.install_with_default_rubygems_test(
path, patches, expected_install_arg_list_list)
@fixture({'recipe': {
'gems': 'hoe==3.4.0 rake==11.0.0',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_hoe_version_dependency_error(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [gem_dependencies['hoe']['3.4.0']]
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaisesRegexp(
zc.buildout.UserError,
'Configuration error, version 11.0.0 for gem rake '
'does not satisfy dependency constraint < 11.0 of gem hoe',
recipe.install
)
@fixture({'recipe': {
'gems': 'hoe==3.4.0 rake==10.0.1',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_hoe_pinned_dependency(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [
gem_dependencies['hoe']['3.4.0'], []]
recipe = rubygems.Recipe(buildout, name, options)
recipe.install()
expected_install_arg_list_list = [
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'hoe', '--version=3.4.0', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'rake', '--version=10.0.1', '--',
],
]
self.install_with_default_rubygems_test(
path, patches, expected_install_arg_list_list)
@fixture({'recipe': {
'gems': 'cucumber-core==3.0.0 backports==3.8.0 '
'cucumber-tag_expressions==1.0.1 gherkin==8.0.0',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_cucumber_core300_version_dependency_error(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [
gem_dependencies['cucumber-core']['3.0.0'], [], [],
gem_dependencies['gherkin']['8.0.0'],
]
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaisesRegexp(
zc.buildout.UserError,
'Configuration error, version for dependency '
'cucumber-messages is missing',
recipe.install
)
@fixture({'recipe': {
'gems': 'cucumber-core==3.0.0 backports==3.8.0 '
'cucumber-tag_expressions==1.0.1 gherkin==8.0.0 '
'cucumber-messages==6.0.1',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_cucumber_core300_pinnned_dependency(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [
gem_dependencies['cucumber-core']['3.0.0'], [], [],
gem_dependencies['gherkin']['8.0.0'], [],
]
recipe = rubygems.Recipe(buildout, name, options)
recipe.install()
expected_install_arg_list_list = [
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'cucumber-core',
'--version=3.0.0', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'backports',
'--version=3.8.0', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'cucumber-tag_expressions',
'--version=1.0.1', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'gherkin',
'--version=8.0.0', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'cucumber-messages',
'--version=6.0.1', '--',
],
]
self.install_with_default_rubygems_test(
path, patches, expected_install_arg_list_list)
@fixture({'recipe': {
'gems': 'cucumber-core==7.1.0 cucumber-messages==12.2.0 '
'cucumber-gherkin==14.1.0 cucumber-tag_expressions==2.0.4',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_cucumber_core710_version_dependency_error(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [
gem_dependencies['cucumber-core']['7.1.0'], [],
gem_dependencies['cucumber-gherkin']['14.1.0'], [],
]
recipe = rubygems.Recipe(buildout, name, options)
self.assertRaisesRegexp(
zc.buildout.UserError,
'Configuration error, version 12.2.0 for gem cucumber-messages '
'does not satisfy dependency constraint >= 12.3 '
'of gem cucumber-gherkin',
recipe.install
)
@fixture({'recipe': {
'gems': 'cucumber-core==7.1.0 cucumber-messages==12.3.2 '
'cucumber-gherkin==14.1.0 cucumber-tag_expressions==2.0.4',
'deployment': 'true'
}})
@mock.patch('rubygems.Recipe.get_dependency_list')
def test_deployment_cucumber_core710_pinned_dependency(
self, path, patches, buildout, name, options, get_dependency_list):
get_dependency_list.side_effect = [
gem_dependencies['cucumber-core']['7.1.0'], [],
gem_dependencies['cucumber-gherkin']['14.1.0'], [],
]
recipe = rubygems.Recipe(buildout, name, options)
recipe.install()
expected_install_arg_list_list = [
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'cucumber-core',
'--version=7.1.0', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'cucumber-messages',
'--version=12.3.2', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'cucumber-gherkin',
'--version=14.1.0', '--',
],
[
'ruby', None, 'install', '--no-document',
'--bindir=%s/rubygems/bin' % path,
'--ignore-dependencies', 'cucumber-tag_expressions',
'--version=2.0.4', '--',
],
]
self.install_with_default_rubygems_test(
path, patches, expected_install_arg_list_list)
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment