mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 01:18:58 +00:00
3273bbdab7
Conflicts: - doc/ref/configuration/master.rst - doc/ref/modules/all/index.rst - doc/topics/grains/index.rst - doc/topics/releases/2016.3.4.rst - doc/topics/spm/spm_formula.rst - doc/topics/tutorials/cron.rst - doc/topics/tutorials/index.rst - doc/topics/tutorials/stormpath.rst - salt/engines/slack.py - salt/log/handlers/fluent_mod.py - salt/modules/cyg.py - salt/modules/junos.py - salt/modules/namecheap_dns.py - salt/modules/namecheap_domains.py - salt/modules/namecheap_ns.py - salt/modules/namecheap_ssl.py - salt/modules/namecheap_users.py - salt/modules/reg.py - salt/modules/tomcat.py - salt/modules/vault.py - salt/modules/win_file.py - salt/modules/zpool.py - salt/output/highstate.py - salt/renderers/pass.py - salt/runners/cache.py - salt/states/boto_apigateway.py - salt/states/boto_iam.py - salt/states/boto_route53.py - salt/states/msteams.py - salt/states/reg.py - salt/states/win_iis.py - tests/integration/modules/test_cmdmod.py - tests/integration/states/test_user.py - tests/support/helpers.py - tests/unit/cloud/clouds/test_openstack.py - tests/unit/fileserver/test_gitfs.py - tests/unit/modules/test_junos.py - tests/unit/pillar/test_git.py - tests/unit/states/test_win_path.py - tests/unit/test_pillar.py - tests/unit/utils/test_format_call.py - tests/unit/utils/test_utils.py - tests/unit/utils/test_warnings.py
307 lines
15 KiB
Python
307 lines
15 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
:codeauthor: Pedro Algarvio (pedro@algarvio.me)
|
|
|
|
|
|
tests.unit.states.pip_test
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
'''
|
|
|
|
# Import python libs
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
# Import Salt Testing libs
|
|
from tests.support.mixins import LoaderModuleMockMixin, SaltReturnAssertsMixin
|
|
from tests.support.unit import skipIf, TestCase
|
|
from tests.support.mock import NO_MOCK, NO_MOCK_REASON, MagicMock, patch
|
|
|
|
# Import salt libs
|
|
import salt.states.pip_state as pip_state
|
|
import salt.utils.versions
|
|
|
|
# Import 3rd-party libs
|
|
try:
|
|
import pip
|
|
HAS_PIP = True
|
|
except ImportError:
|
|
HAS_PIP = False
|
|
|
|
|
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
@skipIf(not HAS_PIP,
|
|
'The \'pip\' library is not importable(installed system-wide)')
|
|
class PipStateTest(TestCase, SaltReturnAssertsMixin, LoaderModuleMockMixin):
|
|
|
|
def setup_loader_modules(self):
|
|
return {
|
|
pip_state: {
|
|
'__env__': 'base',
|
|
'__opts__': {'test': False},
|
|
'__salt__': {'cmd.which_bin': lambda _: 'pip'}
|
|
}
|
|
}
|
|
|
|
def test_install_requirements_parsing(self):
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'pep8': '1.3.3'})
|
|
pip_version = pip.__version__
|
|
mock_pip_version = MagicMock(return_value=pip_version)
|
|
with patch.dict(pip_state.__salt__, {'pip.version': mock_pip_version}):
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list}):
|
|
with patch.dict(pip_state.__opts__, {'test': True}):
|
|
if salt.utils.versions.compare(ver1=pip_version,
|
|
oper='<',
|
|
ver2='10.0'):
|
|
ret = pip_state.installed('pep8=1.3.2')
|
|
self.assertSaltFalseReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'Invalid version specification in package pep8=1.3.2. '
|
|
'\'=\' is not supported, use \'==\' instead.',
|
|
{'test': ret})
|
|
else:
|
|
self.assertRaises(
|
|
pip._internal.exceptions.InstallationError,
|
|
pip_state.installed, 'pep=1.3.2')
|
|
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'pep8': '1.3.3'})
|
|
pip_install = MagicMock(return_value={'retcode': 0})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list,
|
|
'pip.install': pip_install}):
|
|
with patch.dict(pip_state.__opts__, {'test': True}):
|
|
ret = pip_state.installed('pep8>=1.3.2')
|
|
self.assertSaltTrueReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'Python package pep8>=1.3.2 was already installed',
|
|
{'test': ret}
|
|
)
|
|
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'pep8': '1.3.3'})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list}):
|
|
with patch.dict(pip_state.__opts__, {'test': True}):
|
|
ret = pip_state.installed('pep8<1.3.2')
|
|
self.assertSaltNoneReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'Python package pep8<1.3.2 is set to be installed',
|
|
{'test': ret}
|
|
)
|
|
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'pep8': '1.3.2'})
|
|
pip_install = MagicMock(return_value={'retcode': 0})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list,
|
|
'pip.install': pip_install}):
|
|
with patch.dict(pip_state.__opts__, {'test': True}):
|
|
ret = pip_state.installed('pep8>1.3.1,<1.3.3')
|
|
self.assertSaltTrueReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'Python package pep8>1.3.1,<1.3.3 was already installed',
|
|
{'test': ret}
|
|
)
|
|
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'pep8': '1.3.1'})
|
|
pip_install = MagicMock(return_value={'retcode': 0})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list,
|
|
'pip.install': pip_install}):
|
|
with patch.dict(pip_state.__opts__, {'test': True}):
|
|
ret = pip_state.installed('pep8>1.3.1,<1.3.3')
|
|
self.assertSaltNoneReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'Python package pep8>1.3.1,<1.3.3 is set to be installed',
|
|
{'test': ret}
|
|
)
|
|
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'pep8': '1.3.1'})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list}):
|
|
with patch.dict(pip_state.__opts__, {'test': True}):
|
|
ret = pip_state.installed(
|
|
'git+https://github.com/saltstack/salt-testing.git#egg=SaltTesting>=0.5.1'
|
|
)
|
|
self.assertSaltNoneReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'Python package git+https://github.com/saltstack/'
|
|
'salt-testing.git#egg=SaltTesting>=0.5.1 is set to be '
|
|
'installed',
|
|
{'test': ret}
|
|
)
|
|
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'pep8': '1.3.1'})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list}):
|
|
with patch.dict(pip_state.__opts__, {'test': True}):
|
|
ret = pip_state.installed(
|
|
'git+https://github.com/saltstack/salt-testing.git#egg=SaltTesting'
|
|
)
|
|
self.assertSaltNoneReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'Python package git+https://github.com/saltstack/'
|
|
'salt-testing.git#egg=SaltTesting is set to be '
|
|
'installed',
|
|
{'test': ret}
|
|
)
|
|
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'pep8': '1.3.1'})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list}):
|
|
with patch.dict(pip_state.__opts__, {'test': True}):
|
|
ret = pip_state.installed(
|
|
'https://pypi.python.org/packages/source/S/SaltTesting/'
|
|
'SaltTesting-0.5.0.tar.gz'
|
|
'#md5=e6760af92b7165f8be53b5763e40bc24'
|
|
)
|
|
self.assertSaltNoneReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'Python package https://pypi.python.org/packages/source/'
|
|
'S/SaltTesting/SaltTesting-0.5.0.tar.gz'
|
|
'#md5=e6760af92b7165f8be53b5763e40bc24 is set to be '
|
|
'installed',
|
|
{'test': ret}
|
|
)
|
|
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'SaltTesting': '0.5.0'})
|
|
pip_install = MagicMock(return_value={
|
|
'retcode': 0,
|
|
'stderr': '',
|
|
'stdout': 'Downloading/unpacking https://pypi.python.org/packages'
|
|
'/source/S/SaltTesting/SaltTesting-0.5.0.tar.gz\n '
|
|
'Downloading SaltTesting-0.5.0.tar.gz\n Running '
|
|
'setup.py egg_info for package from '
|
|
'https://pypi.python.org/packages/source/S/SaltTesting/'
|
|
'SaltTesting-0.5.0.tar.gz\n \nCleaning up...'
|
|
})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list,
|
|
'pip.install': pip_install}):
|
|
ret = pip_state.installed(
|
|
'https://pypi.python.org/packages/source/S/SaltTesting/'
|
|
'SaltTesting-0.5.0.tar.gz'
|
|
'#md5=e6760af92b7165f8be53b5763e40bc24'
|
|
)
|
|
self.assertSaltTrueReturn({'test': ret})
|
|
self.assertInSaltComment('All packages were successfully installed',
|
|
{'test': ret}
|
|
)
|
|
self.assertInSaltReturn(
|
|
'Installed',
|
|
{'test': ret},
|
|
('changes', 'https://pypi.python.org/packages/source/S/'
|
|
'SaltTesting/SaltTesting-0.5.0.tar.gz'
|
|
'#md5=e6760af92b7165f8be53b5763e40bc24==???')
|
|
)
|
|
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'SaltTesting': '0.5.0'})
|
|
pip_install = MagicMock(return_value={
|
|
'retcode': 0,
|
|
'stderr': '',
|
|
'stdout': 'Cloned!'
|
|
})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list,
|
|
'pip.install': pip_install}):
|
|
with patch.dict(pip_state.__opts__, {'test': False}):
|
|
ret = pip_state.installed(
|
|
'git+https://github.com/saltstack/salt-testing.git#egg=SaltTesting'
|
|
)
|
|
self.assertSaltTrueReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'packages are already installed',
|
|
{'test': ret}
|
|
)
|
|
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'pep8': '1.3.1'})
|
|
pip_install = MagicMock(return_value={'retcode': 0})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list,
|
|
'pip.install': pip_install}):
|
|
with patch.dict(pip_state.__opts__, {'test': False}):
|
|
ret = pip_state.installed(
|
|
'arbitrary ID that should be ignored due to requirements specified',
|
|
requirements='/tmp/non-existing-requirements.txt'
|
|
)
|
|
self.assertSaltTrueReturn({'test': ret})
|
|
|
|
# Test VCS installations using git+git://
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'SaltTesting': '0.5.0'})
|
|
pip_install = MagicMock(return_value={
|
|
'retcode': 0,
|
|
'stderr': '',
|
|
'stdout': 'Cloned!'
|
|
})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list,
|
|
'pip.install': pip_install}):
|
|
with patch.dict(pip_state.__opts__, {'test': False}):
|
|
ret = pip_state.installed(
|
|
'git+git://github.com/saltstack/salt-testing.git#egg=SaltTesting'
|
|
)
|
|
self.assertSaltTrueReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'packages are already installed',
|
|
{'test': ret}
|
|
)
|
|
|
|
# Test VCS installations with version info like >= 0.1
|
|
with patch.object(pip, '__version__', MagicMock(side_effect=AttributeError(
|
|
'Faked missing __version__ attribute'))):
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={'SaltTesting': '0.5.0'})
|
|
pip_install = MagicMock(return_value={
|
|
'retcode': 0,
|
|
'stderr': '',
|
|
'stdout': 'Cloned!'
|
|
})
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list,
|
|
'pip.install': pip_install}):
|
|
with patch.dict(pip_state.__opts__, {'test': False}):
|
|
ret = pip_state.installed(
|
|
'git+https://github.com/saltstack/salt-testing.git#egg=SaltTesting>=0.5.0'
|
|
)
|
|
self.assertSaltTrueReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'packages are already installed',
|
|
{'test': ret}
|
|
)
|
|
|
|
def test_install_in_editable_mode(self):
|
|
'''
|
|
Check that `name` parameter containing bad characters is not parsed by
|
|
pip when package is being installed in editable mode.
|
|
For more information, see issue #21890.
|
|
'''
|
|
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
|
pip_list = MagicMock(return_value={})
|
|
pip_install = MagicMock(return_value={
|
|
'retcode': 0,
|
|
'stderr': '',
|
|
'stdout': 'Cloned!'
|
|
})
|
|
pip_version = MagicMock(return_value='10.0.1')
|
|
with patch.dict(pip_state.__salt__, {'cmd.run_all': mock,
|
|
'pip.list': pip_list,
|
|
'pip.install': pip_install,
|
|
'pip.version': pip_version}):
|
|
ret = pip_state.installed('state@name',
|
|
cwd='/path/to/project',
|
|
editable=['.'])
|
|
self.assertSaltTrueReturn({'test': ret})
|
|
self.assertInSaltComment(
|
|
'successfully installed',
|
|
{'test': ret}
|
|
)
|