Fix integration.modules.test_pip

Pass password as kwarg for runas on Windows
Fix issues with pip 10 in unit.states.test_pip
This commit is contained in:
twangboy 2018-05-01 15:33:29 -06:00
parent 22ac81df63
commit 7c46d9d0d4
No known key found for this signature in database
GPG key ID: 93FF3BDEB278C9EB
8 changed files with 131 additions and 145 deletions

View file

@ -307,6 +307,13 @@ def _process_requirements(requirements, cmd, cwd, saltenv, user):
treq = tempfile.mkdtemp()
__salt__['file.chown'](treq, user, None)
# In Windows, just being owner of a file isn't enough. You also
# need permissions
if salt.utils.is_windows():
__utils__['win_dacl.set_permissions'](
obj_name=treq,
principal=user,
permissions='read_execute')
current_directory = None
@ -885,6 +892,9 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
cmd_kwargs = dict(saltenv=saltenv, use_vt=use_vt, runas=user)
if kwargs:
cmd_kwargs.update(kwargs)
if env_vars:
cmd_kwargs.setdefault('env', {}).update(_format_env_vars(env_vars))
@ -1037,7 +1047,8 @@ def freeze(bin_env=None,
user=None,
cwd=None,
use_vt=False,
env_vars=None):
env_vars=None,
**kwargs):
'''
Return a list of installed packages either globally or in the specified
virtualenv
@ -1086,6 +1097,8 @@ def freeze(bin_env=None,
cmd.append('--all')
cmd_kwargs = dict(runas=user, cwd=cwd, use_vt=use_vt, python_shell=False)
if kwargs:
cmd_kwargs.update(**kwargs)
if bin_env and os.path.isdir(bin_env):
cmd_kwargs['env'] = {'VIRTUAL_ENV': bin_env}
if env_vars:
@ -1102,7 +1115,8 @@ def list_(prefix=None,
bin_env=None,
user=None,
cwd=None,
env_vars=None):
env_vars=None,
**kwargs):
'''
Filter list of installed apps from ``freeze`` and check to see if
``prefix`` exists in the list of packages installed.
@ -1131,7 +1145,11 @@ def list_(prefix=None,
if prefix is None or 'pip'.startswith(prefix):
packages['pip'] = version(bin_env)
for line in freeze(bin_env=bin_env, user=user, cwd=cwd, env_vars=env_vars):
for line in freeze(bin_env=bin_env,
user=user,
cwd=cwd,
env_vars=env_vars,
**kwargs):
if line.startswith('-f') or line.startswith('#'):
# ignore -f line as it contains --find-links directory
# ignore comment lines

View file

@ -103,6 +103,11 @@ def create(path,
user : None
Set ownership for the virtualenv
.. note::
On Windows you must also pass a ``password`` parameter. Additionally,
the user must have permissions to the location where the virtual
environment is being created
runas : None
Set ownership for the virtualenv
@ -162,7 +167,7 @@ def create(path,
# Unable to import?? Let's parse the version from the console
version_cmd = [venv_bin, '--version']
ret = __salt__['cmd.run_all'](
version_cmd, runas=user, python_shell=False
version_cmd, runas=user, python_shell=False, **kwargs
)
if ret['retcode'] > 0 or not ret['stdout'].strip():
raise CommandExecutionError(

View file

@ -184,9 +184,9 @@ def _check_pkg_version_format(pkg):
return ret
def _check_if_installed(prefix, state_pkg_name, version_spec,
ignore_installed, force_reinstall,
upgrade, user, cwd, bin_env, env_vars):
def _check_if_installed(prefix, state_pkg_name, version_spec, ignore_installed,
force_reinstall, upgrade, user, cwd, bin_env, env_vars,
**kwargs):
# result: None means the command failed to run
# result: True means the package is installed
# result: False means the package is not installed
@ -195,7 +195,7 @@ def _check_if_installed(prefix, state_pkg_name, version_spec,
# Check if the requested package is already installed.
pip_list = __salt__['pip.list'](prefix, bin_env=bin_env,
user=user, cwd=cwd,
env_vars=env_vars)
env_vars=env_vars, **kwargs)
prefix_realname = _find_key(prefix, pip_list)
# If the package was already installed, check
@ -723,7 +723,8 @@ def installed(name,
version_spec = version_spec
out = _check_if_installed(prefix, state_pkg_name, version_spec,
ignore_installed, force_reinstall,
upgrade, user, cwd, bin_env, env_vars)
upgrade, user, cwd, bin_env, env_vars,
**kwargs)
# If _check_if_installed result is None, something went wrong with
# the command running. This way we keep stateful output.
if out['result'] is None:
@ -814,7 +815,8 @@ def installed(name,
env_vars=env_vars,
use_vt=use_vt,
trusted_host=trusted_host,
no_cache_dir=no_cache_dir
no_cache_dir=no_cache_dir,
**kwargs
)
if pip_install_call and pip_install_call.get('retcode', 1) == 0:
@ -870,7 +872,8 @@ def installed(name,
if prefix:
pipsearch = __salt__['pip.list'](prefix, bin_env,
user=user, cwd=cwd,
env_vars=env_vars)
env_vars=env_vars,
**kwargs)
# If we didn't find the package in the system after
# installing it report it

View file

@ -207,6 +207,7 @@ def managed(name,
prompt=prompt,
user=user,
use_vt=use_vt,
**kwargs
)
except CommandNotFoundError as err:
ret['result'] = False
@ -316,7 +317,8 @@ def managed(name,
use_vt=use_vt,
env_vars=env_vars,
no_cache_dir=pip_no_cache_dir,
cache_dir=pip_cache_dir
cache_dir=pip_cache_dir,
**kwargs
)
ret['result'] &= pip_ret['retcode'] == 0
if pip_ret['retcode'] > 0:

View file

@ -34,6 +34,7 @@ from tests.support.helpers import (
# Import salt libs
from tests.support.case import ModuleCase
import salt.utils
import salt.utils.win_dacl
import salt.utils.win_functions
from salt.modules.virtualenv_mod import KNOWN_BINARY_NAMES
from salt.exceptions import CommandExecutionError
@ -268,162 +269,103 @@ class PipStateTest(ModuleCase, SaltReturnAssertsMixin):
@destructiveTest
@skip_if_not_root
@skipIf(salt.utils.is_windows(), "password required on Windows")
@with_system_user('issue-6912', on_existing='delete', delete=True)
@with_system_user('issue-6912', on_existing='delete', delete=True,
password='PassWord1!')
def test_issue_6912_wrong_owner(self, username):
venv_dir = os.path.join(
RUNTIME_VARS.TMP, '6912-wrong-owner'
)
# ----- Using runas ------------------------------------------------->
venv_create = self.run_function(
'virtualenv.create', [venv_dir], user=username
)
if venv_create['retcode'] > 0:
self.skipTest(
'Failed to create testcase virtual environment: {0}'.format(
venv_create
)
)
# Setup virtual environment directory to be used throughout the test
venv_dir = os.path.join(RUNTIME_VARS.TMP, '6912-wrong-owner')
# Using the package name.
# The virtual environment needs to be in a location that is accessible
# by both the user running the test and the runas user
if salt.utils.is_windows():
venv_dir = os.path.normpath(
os.path.join(os.environ['SystemDrive'], '\\', 'ProgramData',
'Temp', '6912-wrong-owner'))
# Create the virtual environment
venv_create = self.run_function(
'virtualenv.create', [venv_dir], user=username,
password='PassWord1!')
if venv_create['retcode'] > 0:
self.skipTest('Failed to create testcase virtual environment: {0}'
''.format(venv_create))
# pip install passing the package name in `name`
try:
ret = self.run_state(
'pip.installed', name='pep8', user=username, bin_env=venv_dir
)
'pip.installed', name='pep8', user=username, bin_env=venv_dir,
password='PassWord1!')
self.assertSaltTrueReturn(ret)
if HAS_PWD:
uid = pwd.getpwnam(username).pw_uid
else:
if salt.utils.is_windows():
uid = salt.utils.win_functions.get_sid_from_name(
salt.utils.win_functions.get_current_user()
)
for globmatch in (os.path.join(venv_dir, '**', 'pep8*'),
os.path.join(venv_dir, '*', '**', 'pep8*'),
os.path.join(venv_dir, '*', '*', '**', 'pep8*')):
for path in glob.glob(globmatch):
self.assertequal(uid, os.stat(path).st_uid)
if HAS_PWD:
self.assertEqual(uid, os.stat(path).st_uid)
elif salt.utils.is_windows():
self.assertEqual(
salt.utils.win_dacl.get_owner(path), username)
finally:
if os.path.isdir(venv_dir):
shutil.rmtree(venv_dir, ignore_errors=True)
# using a requirements file
@destructiveTest
@skip_if_not_root
@with_system_user('issue-6912', on_existing='delete', delete=True,
password='PassWord1!')
def test_issue_6912_wrong_owner_requirements_file(self, username):
# Setup virtual environment directory to be used throughout the test
venv_dir = os.path.join(RUNTIME_VARS.TMP, '6912-wrong-owner')
# The virtual environment needs to be in a location that is accessible
# by both the user running the test and the runas user
if salt.utils.is_windows():
venv_dir = os.path.normpath(
os.path.join(os.environ['SystemDrive'], '\\', 'ProgramData',
'Temp', '6912-wrong-owner'))
# Create the virtual environment again as it should have been removed
venv_create = self.run_function(
'virtualenv.create', [venv_dir], user=username
)
'virtualenv.create', [venv_dir], user=username,
password='PassWord1!')
if venv_create['retcode'] > 0:
self.skiptest(
'failed to create testcase virtual environment: {0}'.format(
ret
)
)
self.skiptest('failed to create testcase virtual environment: {0}'
''.format(venv_create))
# pip install using a requirements file
req_filename = os.path.join(
RUNTIME_VARS.TMP_STATE_TREE, 'issue-6912-requirements.txt'
)
RUNTIME_VARS.TMP_STATE_TREE, 'issue-6912-requirements.txt')
with salt.utils.fopen(req_filename, 'wb') as reqf:
reqf.write(six.b('pep8'))
try:
ret = self.run_state(
'pip.installed', name='', user=username, bin_env=venv_dir,
requirements='salt://issue-6912-requirements.txt'
)
requirements='salt://issue-6912-requirements.txt',
password='PassWord1!')
self.assertSaltTrueReturn(ret)
if HAS_PWD:
uid = pwd.getpwnam(username).pw_uid
else:
if salt.utils.is_windows():
uid = salt.utils.win_functions.get_sid_from_name(
salt.utils.win_functions.get_current_user()
)
for globmatch in (os.path.join(venv_dir, '**', 'pep8*'),
os.path.join(venv_dir, '*', '**', 'pep8*'),
os.path.join(venv_dir, '*', '*', '**', 'pep8*')):
for path in glob.glob(globmatch):
self.assertEqual(uid, os.stat(path).st_uid)
if HAS_PWD:
self.assertEqual(uid, os.stat(path).st_uid)
elif salt.utils.is_windows():
self.assertEqual(
salt.utils.win_dacl.get_owner(path), username)
finally:
if os.path.isdir(venv_dir):
shutil.rmtree(venv_dir, ignore_errors=True)
os.unlink(req_filename)
# <---- Using runas --------------------------------------------------
# ----- Using user -------------------------------------------------->
venv_create = self.run_function(
'virtualenv.create', [venv_dir], user=username
)
if venv_create['retcode'] > 0:
self.skipTest(
'Failed to create testcase virtual environment: {0}'.format(
ret
)
)
# Using the package name
try:
ret = self.run_state(
'pip.installed', name='pep8', user=username, bin_env=venv_dir
)
self.assertSaltTrueReturn(ret)
if HAS_PWD:
uid = pwd.getpwnam(username).pw_uid
else:
if salt.utils.is_windows():
uid = salt.utils.win_functions.get_sid_from_name(
salt.utils.win_functions.get_current_user()
)
for globmatch in (os.path.join(venv_dir, '**', 'pep8*'),
os.path.join(venv_dir, '*', '**', 'pep8*'),
os.path.join(venv_dir, '*', '*', '**', 'pep8*')):
for path in glob.glob(globmatch):
self.assertEqual(uid, os.stat(path).st_uid)
finally:
if os.path.isdir(venv_dir):
shutil.rmtree(venv_dir, ignore_errors=True)
# Using a requirements file
venv_create = self.run_function(
'virtualenv.create', [venv_dir], user=username
)
if venv_create['retcode'] > 0:
self.skipTest(
'Failed to create testcase virtual environment: {0}'.format(
ret
)
)
req_filename = os.path.join(
RUNTIME_VARS.TMP_STATE_TREE, 'issue-6912-requirements.txt'
)
with salt.utils.fopen(req_filename, 'wb') as reqf:
reqf.write(six.b('pep8'))
try:
ret = self.run_state(
'pip.installed', name='', user=username, bin_env=venv_dir,
requirements='salt://issue-6912-requirements.txt'
)
self.assertSaltTrueReturn(ret)
if HAS_PWD:
uid = pwd.getpwnam(username).pw_uid
else:
if salt.utils.is_windows():
uid = salt.utils.win_functions.get_sid_from_name(
salt.utils.win_functions.get_current_user()
)
for globmatch in (os.path.join(venv_dir, '**', 'pep8*'),
os.path.join(venv_dir, '*', '**', 'pep8*'),
os.path.join(venv_dir, '*', '*', '**', 'pep8*')):
for path in glob.glob(globmatch):
self.assertEqual(uid, os.stat(path).st_uid)
finally:
if os.path.isdir(venv_dir):
shutil.rmtree(venv_dir, ignore_errors=True)
os.unlink(req_filename)
# <---- Using user ---------------------------------------------------
if os._exists(req_filename):
os.unlink(req_filename)
def test_issue_6833_pip_upgrade_pip(self):
# Create the testing virtualenv

View file

@ -51,6 +51,9 @@ from tests.support.unit import skip, _id
from tests.support.mock import patch
from tests.support.paths import FILES, TMP
# Import Salt libs
import salt.utils
log = logging.getLogger(__name__)
@ -576,10 +579,10 @@ def requires_network(only_local_network=False):
return decorator
def with_system_user(username, on_existing='delete', delete=True):
def with_system_user(username, on_existing='delete', delete=True, password=None):
'''
Create and optionally destroy a system user to be used within a test
case. The system user is crated using the ``user`` salt module.
case. The system user is created using the ``user`` salt module.
The decorated testcase function must accept 'username' as an argument.
@ -609,7 +612,10 @@ def with_system_user(username, on_existing='delete', delete=True):
# Let's add the user to the system.
log.debug('Creating system user {0!r}'.format(username))
create_user = cls.run_function('user.add', [username])
kwargs = {'timeout': 60}
if salt.utils.is_windows():
kwargs.update({'password': password})
create_user = cls.run_function('user.add', [username], **kwargs)
if not create_user:
log.debug('Failed to create system user')
# The user was not created
@ -665,7 +671,7 @@ def with_system_user(username, on_existing='delete', delete=True):
finally:
if delete:
delete_user = cls.run_function(
'user.delete', [username, True, True]
'user.delete', [username, True, True], timeout=60
)
if not delete_user:
if failure is None:

View file

@ -17,6 +17,7 @@ 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
# Import 3rd-party libs
try:
@ -43,18 +44,25 @@ class PipStateTest(TestCase, SaltReturnAssertsMixin, LoaderModuleMockMixin):
def test_install_requirements_parsing(self):
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
pip_list = MagicMock(return_value={'pep8': '1.3.3'})
pip_version = MagicMock(return_value='10.0.1')
with patch.dict(pip_state.__salt__, {'pip.version': pip_version}):
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}):
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}
)
if salt.utils.compare_versions(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'})

View file

@ -18,6 +18,7 @@ integration.modules.test_mine
integration.modules.test_network
integration.modules.test_ntp
integration.modules.test_pillar
integration.modules.test_pip
integration.modules.test_pkg
integration.modules.test_publish
integration.modules.test_state
@ -34,6 +35,7 @@ integration.runners.test_jobs
integration.runners.test_salt
integration.sdb.test_env
integration.states.test_host
integration.states.test_pip
integration.states.test_renderers
integration.utils.testprogram
integration.wheel.test_client