Merge pull request #31690 from jfindlay/mac_tests

Mac tests
This commit is contained in:
Nicole Thomas 2016-03-10 12:03:00 -07:00
commit 98b868c573
25 changed files with 318 additions and 132 deletions

View File

@ -26,19 +26,6 @@ from salt.exceptions import SaltInvocationError
# Import 3rd-party libs
import salt.ext.six as six
try:
from shlex import quote as _cmd_quote # pylint: disable=E0611
except ImportError:
from pipes import quote as _cmd_quote
from salt.exceptions import (
SaltInvocationError
)
try:
from shlex import quote as _cmd_quote # pylint: disable=E0611
except ImportError:
from pipes import quote as _cmd_quote
# Set up logging
log = logging.getLogger(__name__)
@ -92,29 +79,30 @@ except ImportError:
pass
def _check_gpg():
def _gpg():
'''
Looks to see if gpg binary is present on the system.
Returns the path to the gpg binary
'''
# Get the path to the gpg binary.
if salt.utils.which('gpg'):
return __virtualname__
return (False, 'The gpg execution module cannot be loaded: '
'gpg binary is not in the path.')
return salt.utils.which('gpg')
def __virtual__():
'''
Makes sure that python-gnupg and gpg are available.
'''
if _check_gpg() and HAS_LIBS:
if not _gpg():
return (False, 'The gpg execution module cannot be loaded: '
'gpg binary is not in the path.')
if HAS_LIBS:
gnupg_version = distutils.version.LooseVersion(gnupg.__version__)
if gnupg_version >= '1.3.1':
global GPG_1_3_1
GPG_1_3_1 = True
return __virtualname__
return (False, 'The gpg execution module cannot be loaded; either the'
' gnupg module is not installed or the gpg binary is not in the path.')
return (False, 'The gpg execution module cannot be loaded; the'
' gnupg python module is not installed.')
def _create_gpg(user=None, gnupghome=None):
@ -850,15 +838,18 @@ def trust_key(keyid=None,
if trust_level not in _VALID_TRUST_LEVELS:
return 'ERROR: Valid trust levels - {0}'.format(','.join(_VALID_TRUST_LEVELS))
cmd = 'echo "{0}:{1}" | {2} --import-ownertrust'.format(_cmd_quote(fingerprint),
_cmd_quote(NUM_TRUST_DICT[trust_level]),
_cmd_quote(_check_gpg()))
stdin = '{0}:{1}\n'.format(fingerprint, NUM_TRUST_DICT[trust_level])
cmd = [_gpg(), '--import-ownertrust']
_user = user
if user == 'salt':
homeDir = os.path.join(salt.syspaths.CONFIG_DIR, 'gpgkeys')
cmd = '{0} --homedir {1}'.format(cmd, homeDir)
cmd.extend([' --homedir', homeDir])
_user = 'root'
res = __salt__['cmd.run_all'](cmd, runas=_user, python_shell=True)
res = __salt__['cmd.run_all'](cmd,
stdin=stdin,
runas=_user,
python_shell=False)
if not res['retcode'] == 0:
ret['res'] = False

View File

@ -18,6 +18,7 @@ from salt.ext.six import string_types
# Import salt libs
import salt.utils
import salt.utils.decorators as decorators
from salt.utils.locales import sdecode
from salt.exceptions import CommandExecutionError, SaltInvocationError
@ -115,7 +116,8 @@ def add(name,
_dscl([name_path, 'RealName', fullname])
# Make sure home directory exists
__salt__['file.mkdir'](name)
if createhome:
__salt__['file.mkdir'](home, user=uid, group=gid)
# dscl buffers changes, sleep before setting group membership
time.sleep(1)
@ -124,7 +126,7 @@ def add(name,
return True
def delete(name, *args):
def delete(name, remove=False, force=False):
'''
Remove a user from the minion
@ -134,12 +136,19 @@ def delete(name, *args):
salt '*' user.delete foo
'''
### NOTE: *args isn't used here but needs to be included in this function
### for compatibility with the user.absent state
if salt.utils.contains_whitespace(name):
raise SaltInvocationError('Username cannot contain whitespace')
if not info(name):
return True
# force is added for compatibility with user.absent state function
if force:
log.warn('force option is unsupported on MacOS, ignoring')
# remove home directory from filesystem
if remove:
__salt__['file.remove'](info(name)['home'])
# Remove from any groups other than primary group. Needs to be done since
# group membership is managed separately from users and an entry for the
# user will persist even after the user is removed.
@ -396,6 +405,22 @@ def _format_info(data):
'fullname': data.pw_gecos}
@decorators.which('id')
def primary_group(name):
'''
Return the primary group of the named user
.. versionadded:: 2016.3.0
CLI Example:
.. code-block:: bash
salt '*' user.primary_group saltadmin
'''
return __salt__['cmd.run'](['id', '-g', '-n', name])
def list_groups(name):
'''
Return a list of groups the named user belongs to

View File

@ -14,6 +14,7 @@ import copy
# Import salt libs
import salt.utils
import salt.utils.decorators as decorators
from salt.ext import six
from salt.exceptions import CommandExecutionError
@ -574,6 +575,22 @@ def _format_info(data):
'homephone': gecos_field[3]}
@decorators.which('id')
def primary_group(name):
'''
Return the primary group of the named user
.. versionadded:: 2016.3.0
CLI Example:
.. code-block:: bash
salt '*' user.primary_group saltadmin
'''
return __salt__['cmd.run'](['id', '-g', '-n', name])
def list_groups(name):
'''
Return a list of groups the named user belongs to

View File

@ -858,6 +858,41 @@ def path_join(*parts):
))
def abs_readlink(path):
'''
Return the absolute path. If path is a link, dereference it first.
.. code-block:: python
>>> import os
>>> os.makedirs('/tmp/dir')
>>> os.chdir('/tmp/dir')
>>> open('/tmp/dir/target', 'w').close()
>>> os.symlink('target', 'link1')
>>> os.symlink('../dir/target', 'link2')
>>> os.symlink('/tmp/dir/target', 'link3')
>>> abs_readlink('/tmp/dir/target')
'/tmp/dir/target'
>>> abs_readlink('/tmp/dir/link1')
'/tmp/dir/target'
>>> abs_readlink('/tmp/dir/link2')
'/tmp/dir/target'
>>> abs_readlink('/tmp/dir/link3')
'/tmp/dir/target'
>>> from subprocess import call
>>> call(['rm', '-r', '/tmp/dir'])
'''
if os.path.islink(path):
base, lname = os.path.split(os.path.abspath(path))
target = os.readlink(path)
if target.startswith(os.sep):
return os.path.abspath(target)
else: # target path is relative to supplied path
return os.path.abspath(os.path.join(base, target))
else:
return os.path.abspath(path)
def pem_finger(path=None, key=None, sum_type='sha256'):
'''
Pass in either a raw pem string, or the path on disk to the location of a

View File

@ -78,10 +78,7 @@ if salt.utils.is_windows():
import win32api
if platform.uname()[0] == 'Darwin':
SYS_TMP_DIR = '/tmp'
else:
SYS_TMP_DIR = os.environ.get('TMPDIR', tempfile.gettempdir())
SYS_TMP_DIR = salt.utils.abs_readlink(os.environ.get('TMPDIR', tempfile.gettempdir()))
# Gentoo Portage prefers ebuild tests are rooted in ${TMPDIR}
TMP = os.path.join(SYS_TMP_DIR, 'salt-tests-tmpdir')

View File

@ -12,7 +12,11 @@ from __future__ import absolute_import
import os
import tempfile
SYS_TMP_DIR = tempfile.gettempdir()
# Import salt libs
import salt.utils
SYS_TMP_DIR = salt.utils.abs_readlink(os.environ.get('TMPDIR', tempfile.gettempdir()))
# This tempdir path is defined on tests.integration.__init__
TMP = os.path.join(SYS_TMP_DIR, 'salt-tests-tmpdir')

View File

@ -18,27 +18,24 @@ import salt.utils
import salt.ext.six as six
@destructiveTest
@skipIf(salt.utils.is_windows(), 'No mtab on Windows')
@skipIf(salt.utils.is_darwin(), 'No mtab on Darwin')
class DiskModuleVirtualizationTest(integration.ModuleCase):
'''
Test to make sure we return a clean result under Docker. Refs #8976
This is factored into its own class so that we can have some certainty that setUp() and tearDown() are run.
'''
@destructiveTest
@skipIf(salt.utils.is_windows(), 'No mtab on Windows')
def setUp(self):
# Make /etc/mtab unreadable
if os.path.isfile('/etc/mtab'):
shutil.move('/etc/mtab', '/tmp/mtab')
@destructiveTest
@skipIf(salt.utils.is_windows(), 'No mtab on Windows')
def test_no_mtab(self):
ret = self.run_function('disk.usage')
self.assertDictEqual(ret, {})
@destructiveTest
@skipIf(salt.utils.is_windows(), 'No mtab on Windows')
def tearDown(self):
if os.path.isfile('/tmp/mtab'):
shutil.move('/tmp/mtab', '/etc/mtab')
@ -56,12 +53,23 @@ class DiskModuleTest(integration.ModuleCase):
self.assertTrue(isinstance(ret, dict))
if not isinstance(ret, dict):
return
for key, val in six.iteritems(ret):
self.assertTrue('filesystem' in val)
self.assertTrue('1K-blocks' in val)
self.assertTrue('used' in val)
self.assertTrue('available' in val)
self.assertTrue('capacity' in val)
if salt.utils.is_darwin():
for key, val in six.iteritems(ret):
self.assertTrue('filesystem' in val)
self.assertTrue('512-blocks' in val)
self.assertTrue('used' in val)
self.assertTrue('available' in val)
self.assertTrue('capacity' in val)
self.assertTrue('iused' in val)
self.assertTrue('ifree' in val)
self.assertTrue('%iused' in val)
else:
for key, val in six.iteritems(ret):
self.assertTrue('filesystem' in val)
self.assertTrue('1K-blocks' in val)
self.assertTrue('used' in val)
self.assertTrue('available' in val)
self.assertTrue('capacity' in val)
def test_inodeusage(self):
'''
@ -81,4 +89,4 @@ class DiskModuleTest(integration.ModuleCase):
if __name__ == '__main__':
from integration import run_tests
run_tests(DiskModuleTest)
run_tests([DiskModuleVirtualizationTest, DiskModuleTest])

View File

@ -38,9 +38,13 @@ def __random_string(size=6):
# Create user strings for tests
ADD_USER = __random_string()
DEL_USER = __random_string()
PRIMARY_GROUP_USER = __random_string()
CHANGE_USER = __random_string()
@destructiveTest
@skipIf(os.geteuid() != 0, 'You must be logged in as root to run this test')
@requires_system_grains
class MacUserModuleTest(integration.ModuleCase):
'''
Integration tests for the mac_user module
@ -59,9 +63,6 @@ class MacUserModuleTest(integration.ModuleCase):
)
)
@destructiveTest
@skipIf(os.geteuid() != 0, 'You must be logged in as root to run this test')
@requires_system_grains
def test_mac_user_add(self, grains=None):
'''
Tests the add function
@ -74,9 +75,6 @@ class MacUserModuleTest(integration.ModuleCase):
self.run_function('user.delete', [ADD_USER])
raise
@destructiveTest
@skipIf(os.geteuid() != 0, 'You must be logged in as root to run this test')
@requires_system_grains
def test_mac_user_delete(self, grains=None):
'''
Tests the delete function
@ -94,9 +92,26 @@ class MacUserModuleTest(integration.ModuleCase):
except CommandExecutionError:
raise
@destructiveTest
@skipIf(os.geteuid() != 0, 'You must be logged in as root to run this test')
@requires_system_grains
def test_mac_user_primary_group(self, grains=None):
'''
Tests the primary_group function
'''
# Create a user to test primary group function
if self.run_function('user.add', [PRIMARY_GROUP_USER]) is not True:
self.run_function('user.delete', [PRIMARY_GROUP_USER])
self.skipTest('Failed to create a user')
try:
# Test mac_user.primary_group
primary_group = self.run_function('user.primary_group', [PRIMARY_GROUP_USER])
uid_info = self.run_function('user.info', [PRIMARY_GROUP_USER])
self.assertIn(primary_group, uid_info['groups'])
except AssertionError:
self.run_function('user.delete', [PRIMARY_GROUP_USER])
raise
def test_mac_user_changes(self, grains=None):
'''
Tests mac_user functions that change user properties
@ -107,7 +122,7 @@ class MacUserModuleTest(integration.ModuleCase):
self.skipTest('Failed to create a user')
try:
# Test mac_user.chudi
# Test mac_user.chuid
self.run_function('user.chuid', [CHANGE_USER, 4376])
uid_info = self.run_function('user.info', [CHANGE_USER])
self.assertEqual(uid_info['uid'], 4376)
@ -141,9 +156,6 @@ class MacUserModuleTest(integration.ModuleCase):
self.run_function('user.delete', [CHANGE_USER])
raise
@destructiveTest
@skipIf(os.geteuid() != 0, 'You must be logged in as root to run this test')
@requires_system_grains
def tearDown(self, grains=None):
'''
Clean up after tests

View File

@ -16,12 +16,18 @@ from salttesting.helpers import (
ensure_in_syspath('../../')
# Import salt libs
import salt.utils
import integration
# Import 3rd-party libs
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
@destructiveTest
@skipIf(os.geteuid() != 0, 'you must be root to run these tests')
# Only run on linux for now until or if we can figure out a way to use
# __grains__ inside of useradd.__virtual__
@skipIf(not salt.utils.is_linux(), 'These tests can only be run on linux')
class UseraddModuleTest(integration.ModuleCase):
def setUp(self):
@ -40,8 +46,6 @@ class UseraddModuleTest(integration.ModuleCase):
for x in range(size)
)
@destructiveTest
@skipIf(os.geteuid() != 0, 'you must be root to run this test')
@requires_system_grains
def test_groups_includes_primary(self, grains=None):
# Let's create a user, which usually creates the group matching the
@ -85,6 +89,27 @@ class UseraddModuleTest(integration.ModuleCase):
self.run_function('user.delete', [uname, True, True])
raise
def test_linux_user_primary_group(self, grains=None):
'''
Tests the primary_group function
'''
name = 'saltyuser'
# Create a user to test primary group function
if self.run_function('user.add', [name]) is not True:
self.run_function('user.delete', [name])
self.skipTest('Failed to create a user')
try:
# Test useradd.primary_group
primary_group = self.run_function('user.primary_group', [name])
uid_info = self.run_function('user.info', [name])
self.assertIn(primary_group, uid_info['groups'])
except:
self.run_function('user.delete', [name])
raise
if __name__ == '__main__':
from integration import run_tests

View File

@ -31,7 +31,7 @@ class EnabledTest(integration.ModuleCase):
'''
ensure that python_shell defaults to True for cmd.run
'''
enabled_ret = '3\nsaltines'
enabled_ret = '3\nsaltines' # the result of running self.cmd in a shell
ret = self.run_function('cmd.run', [self.cmd])
self.assertEqual(ret, enabled_ret)
@ -52,12 +52,12 @@ class EnabledTest(integration.ModuleCase):
state_filename = state_name + '.sls'
state_file = os.path.join(STATE_DIR, state_filename)
enabled_ret = '3 saltines'
enabled_ret = '3 saltines' # the result of running self.cmd in a shell
ret_key = 'test_|-shell_enabled_|-{0}_|-configurable_test_state'.format(enabled_ret)
try:
salt.utils.fopen(state_file, 'w').write(textwrap.dedent('''\
{{% set shell_enabled = salt['cmd.run']("{0}") %}}
{{% set shell_enabled = salt['cmd.run']("{0}").strip() %}}
shell_enabled:
test.configurable_test_state:
@ -77,6 +77,7 @@ class EnabledTest(integration.ModuleCase):
state_filename = state_name + '.sls'
state_file = os.path.join(STATE_DIR, state_filename)
# the result of running self.cmd not in a shell
disabled_ret = ('first second third | wc -l ; export SALTY_VARIABLE=saltines '
'&& echo $SALTY_VARIABLE ; echo duh &> /dev/null')
ret_key = 'test_|-shell_enabled_|-{0}_|-configurable_test_state'.format(disabled_ret)

View File

@ -142,14 +142,14 @@ class CMDTest(integration.ModuleCase,
state_filename = state_name + '.sls'
state_file = os.path.join(STATE_DIR, state_filename)
saltines_key = 'cmd_|-saltines_|-/bin/true_|-run'
saltines_key = 'cmd_|-saltines_|-echo_|-run'
biscuits_key = 'cmd_|-biscuits_|-echo hello_|-wait'
try:
salt.utils.fopen(state_file, 'w').write(textwrap.dedent('''\
saltines:
cmd.run:
- name: /bin/true
- name: echo
- cwd: /
- stateful: True

View File

@ -1831,7 +1831,9 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
self.assertEqual(pwd.getpwuid(onestats.st_uid).pw_name, user)
self.assertEqual(pwd.getpwuid(twostats.st_uid).pw_name, 'root')
self.assertEqual(grp.getgrgid(onestats.st_gid).gr_name, group)
self.assertEqual(grp.getgrgid(twostats.st_gid).gr_name, 'root')
if salt.utils.which('id'):
root_group = self.run_function('user.primary_group', ['root'])
self.assertEqual(grp.getgrgid(twostats.st_gid).gr_name, root_group)
finally:
if os.path.isdir(tmp_dir):
shutil.rmtree(tmp_dir)

View File

@ -30,7 +30,8 @@ _PKG_TARGETS = {
'Debian': ['python-plist', 'apg'],
'RedHat': ['xz-devel', 'zsh-html'],
'FreeBSD': ['aalib', 'pth'],
'Suse': ['aalib', 'python-pssh']
'Suse': ['aalib', 'python-pssh'],
'MacOS': ['libpng', 'jpeg'],
}
_PKG_TARGETS_32 = {

View File

@ -246,4 +246,4 @@ class SSHAuthStateTests(integration.ModuleCase,
if __name__ == '__main__':
from integration import run_tests
run_tests(SSHKnownHostsStateTest)
run_tests([SSHKnownHostsStateTest, SSHAuthStateTests])

View File

@ -22,6 +22,7 @@ from salttesting.helpers import (
ensure_in_syspath('../../')
# Import salt libs
import salt.utils
import integration
@ -107,8 +108,12 @@ class UserTest(integration.ModuleCase,
If you run the test and it fails, please fix the code it's testing to
work on your operating system.
'''
# MacOS users' primary group defaults to staff (20), not the name of
# user
gid_from_name = False if grains['os_family'] == 'MacOS' else True
ret = self.run_state('user.present', name='salt_test',
gid_from_name=True, home='/var/lib/salt_test')
gid_from_name=gid_from_name, home='/var/lib/salt_test')
self.assertSaltTrueReturn(ret)
ret = self.run_function('user.info', ['salt_test'])
@ -118,6 +123,8 @@ class UserTest(integration.ModuleCase,
self.assertTrue(os.path.isdir('/var/lib/salt_test'))
if grains['os_family'] in ('Suse',):
self.assertEqual(group_name, 'users')
elif grains['os_family'] == 'MacOS':
self.assertEqual(group_name, 'staff')
else:
self.assertEqual(group_name, 'salt_test')
@ -186,9 +193,11 @@ class UserTest(integration.ModuleCase,
ret = self.run_function('user.info', ['salt_test'])
self.assertReturnNonEmptySaltType(ret)
self.assertEqual('', ret['fullname'])
self.assertEqual('', ret['roomnumber'])
self.assertEqual('', ret['workphone'])
self.assertEqual('', ret['homephone'])
# MacOS does not supply the following GECOS fields
if not salt.utils.is_darwin():
self.assertEqual('', ret['roomnumber'])
self.assertEqual('', ret['workphone'])
self.assertEqual('', ret['homephone'])
ret = self.run_state('user.absent', name='salt_test')
self.assertSaltTrueReturn(ret)

View File

@ -40,7 +40,17 @@ try:
except OSError as err:
print('Failed to change directory to salt\'s source: {0}'.format(err))
REQUIRED_OPEN_FILES = 3072
# Soft and hard limits on max open filehandles
MAX_OPEN_FILES = {
'integration': {
'soft_limit': 3072,
'hard_limit': 4096,
},
'unit': {
'soft_limit': 1024,
'hard_limit': 2048,
},
}
class SaltTestsuiteParser(SaltCoverageTestingParser):
@ -292,7 +302,7 @@ class SaltTestsuiteParser(SaltCoverageTestingParser):
def start_daemons_only(self):
if not salt.utils.is_windows():
self.prep_filehandles()
self.set_filehandle_limits('integration')
try:
print_header(
' * Setting up Salt daemons for interactive use',
@ -335,32 +345,51 @@ class SaltTestsuiteParser(SaltCoverageTestingParser):
while True:
time.sleep(1)
def prep_filehandles(self):
smax_open_files, hmax_open_files = resource.getrlimit(
resource.RLIMIT_NOFILE
)
if smax_open_files < REQUIRED_OPEN_FILES:
def set_filehandle_limits(self, limits='integration'):
'''
Set soft and hard limits on open file handles at required thresholds
for integration tests or unit tests
'''
# Get current limits
prev_soft, prev_hard = resource.getrlimit(resource.RLIMIT_NOFILE)
# Get required limits
min_soft = MAX_OPEN_FILES[limits]['soft_limit']
min_hard = MAX_OPEN_FILES[limits]['hard_limit']
# Check minimum required limits
set_limits = False
if prev_soft < min_soft:
soft = min_soft
set_limits = True
else:
soft = prev_soft
if prev_hard < min_hard:
hard = min_hard
set_limits = True
else:
hard = prev_hard
# Increase limits
if set_limits:
print(
' * Max open files setting is too low({0}) for running the '
'tests'.format(smax_open_files)
' * Max open files settings is too low (soft: {0}, hard: {1}) '
'for running the tests'.format(prev_soft, prev_hard)
)
print(
' * Trying to raise the limit to {0}'.format(REQUIRED_OPEN_FILES)
' * Trying to raise the limits to soft: '
'{0}, hard: {1}'.format(soft, hard)
)
if hmax_open_files < 4096:
hmax_open_files = 4096 # Decent default?
try:
resource.setrlimit(
resource.RLIMIT_NOFILE,
(REQUIRED_OPEN_FILES, hmax_open_files)
)
resource.setrlimit(resource.RLIMIT_NOFILE, (soft, hard))
except Exception as err:
print(
'ERROR: Failed to raise the max open files setting -> '
'ERROR: Failed to raise the max open files settings -> '
'{0}'.format(err)
)
print('Please issue the following command on your console:')
print(' ulimit -n {0}'.format(REQUIRED_OPEN_FILES))
print(' ulimit -n {0}'.format(soft))
self.exit()
finally:
print('~' * getattr(self.options, 'output_columns', PNUM))
@ -401,7 +430,7 @@ class SaltTestsuiteParser(SaltCoverageTestingParser):
# We don't need the tests daemon running
return [True]
if not salt.utils.is_windows():
self.prep_filehandles()
self.set_filehandle_limits('integration')
try:
print_header(
@ -480,6 +509,9 @@ class SaltTestsuiteParser(SaltCoverageTestingParser):
status = []
if self.options.unit:
# MacOS needs more open filehandles for running unit test suite
self.set_filehandle_limits('unit')
results = self.run_suite(
os.path.join(TEST_DIR, 'unit'), 'Unit', '*_test.py'
)

View File

@ -37,6 +37,8 @@ class TestBlockdevModule(TestCase):
ret = blockdev.tune('/dev/sda', **kwargs)
self.assertTrue(ret)
@skipIf(not salt.utils.which('sync'), 'sync not found')
@skipIf(not salt.utils.which('mkfs'), 'mkfs not found')
def test_format(self):
'''
unit tests for blockdev.format

View File

@ -7,6 +7,7 @@ from __future__ import absolute_import
# Import Salt Testing Libs
from salttesting import TestCase, skipIf
from salttesting.mock import (
mock_open,
MagicMock,
patch,
NO_MOCK,
@ -87,23 +88,27 @@ class BtrfsTestCase(TestCase):
ret = [{'range': '/dev/sda1',
'mount_point': False,
'log': False, 'passed': True}]
mock = MagicMock(return_value={'retcode': 1,
'stderr': '',
'stdout': 'Salt'})
with patch.dict(btrfs.__salt__, {'cmd.run_all': mock}):
self.assertListEqual(btrfs.defragment('/dev/sda1'), ret)
mock_run = MagicMock(return_value={'retcode': 1,
'stderr': '',
'stdout': 'Salt'})
with patch.dict(btrfs.__salt__, {'cmd.run_all': mock_run}):
mock_file = mock_open(read_data='/dev/sda1 / ext4 rw,data=ordered 0 0')
with patch.object(salt.utils, 'fopen', mock_file):
self.assertListEqual(btrfs.defragment('/dev/sda1'), ret)
@patch('salt.utils.fsutils._is_device', MagicMock(return_value=True))
def test_defragment_error(self):
'''
Test if it gives device not mount error
'''
mock = MagicMock(return_value={'retcode': 1,
'stderr': '',
'stdout': 'Salt'})
with patch.dict(btrfs.__salt__, {'cmd.run_all': mock}):
self.assertRaises(CommandExecutionError, btrfs.defragment,
'/dev/sda1')
mock_run = MagicMock(return_value={'retcode': 1,
'stderr': '',
'stdout': 'Salt'})
with patch.dict(btrfs.__salt__, {'cmd.run_all': mock_run}):
mock_file = mock_open(read_data='/dev/sda1 / ext4 rw,data=ordered 0 0')
with patch.object(salt.utils, 'fopen', mock_file):
self.assertRaises(CommandExecutionError, btrfs.defragment,
'/dev/sda1')
# 'features' function tests: 1
@ -158,13 +163,15 @@ class BtrfsTestCase(TestCase):
'''
Test if it create a file system on the specified device.
'''
mock = MagicMock(return_value={'retcode': 1,
'stderr': '',
'stdout': 'Salt'})
mock_cmd = MagicMock(return_value={'retcode': 1,
'stderr': '',
'stdout': 'Salt'})
mock_info = MagicMock(return_value=[])
with patch.dict(btrfs.__salt__, {'cmd.run_all': mock,
with patch.dict(btrfs.__salt__, {'cmd.run_all': mock_cmd,
'btrfs.info': mock_info}):
self.assertDictEqual(btrfs.mkfs('/dev/sda1'), {'log': 'Salt'})
mock_file = mock_open(read_data='/dev/sda1 / ext4 rw,data=ordered 0 0')
with patch.object(salt.utils, 'fopen', mock_file):
self.assertDictEqual(btrfs.mkfs('/dev/sda1'), {'log': 'Salt'})
def test_mkfs_error(self):
'''
@ -304,14 +311,16 @@ class BtrfsTestCase(TestCase):
'''
Test if it gives migration error
'''
mock = MagicMock(return_value={'retcode': 1,
'stderr': '',
'stdout': 'Salt'})
with patch.dict(btrfs.__salt__, {'cmd.run_all': mock}):
mock = MagicMock(return_value={'/dev/sda1': {'type': 'ext4'}})
with patch.object(salt.utils.fsutils, '_blkid_output', mock):
self.assertRaises(CommandExecutionError, btrfs.convert,
'/dev/sda1')
mock_run = MagicMock(return_value={'retcode': 1,
'stderr': '',
'stdout': 'Salt'})
with patch.dict(btrfs.__salt__, {'cmd.run_all': mock_run}):
mock_blk = MagicMock(return_value={'/dev/sda1': {'type': 'ext4'}})
with patch.object(salt.utils.fsutils, '_blkid_output', mock_blk):
mock_file = mock_open(read_data='/dev/sda1 / ext4 rw,data=ordered 0 0')
with patch.object(salt.utils, 'fopen', mock_file):
self.assertRaises(CommandExecutionError, btrfs.convert,
'/dev/sda1')
# 'add' function tests: 1

View File

@ -97,6 +97,7 @@ class LinuxSysctlTestCase(TestCase):
1, config=None)
@patch('os.path.isfile', MagicMock(return_value=False))
@patch('os.path.exists', MagicMock(return_value=True))
def test_persist_no_conf_success(self):
'''
Tests successful add of config file when previously not one
@ -120,6 +121,7 @@ class LinuxSysctlTestCase(TestCase):
'#\n# Kernel sysctl configuration\n#\n')
@patch('os.path.isfile', MagicMock(return_value=True))
@patch('os.path.exists', MagicMock(return_value=True))
def test_persist_read_conf_success(self):
'''
Tests sysctl.conf read success

View File

@ -106,12 +106,13 @@ class MountTestCase(TestCase):
'''
Remove the mount point from the fstab
'''
mock = MagicMock(return_value={})
with patch.object(mount, 'fstab', mock):
self.assertTrue(mount.rm_fstab('name', 'device'))
mock_fstab = MagicMock(return_value={})
with patch.object(mount, 'fstab', mock_fstab):
with patch('salt.utils.fopen', mock_open()):
self.assertTrue(mount.rm_fstab('name', 'device'))
mock = MagicMock(return_value={'name': 'name'})
with patch.object(mount, 'fstab', mock):
mock_fstab = MagicMock(return_value={'name': 'name'})
with patch.object(mount, 'fstab', mock_fstab):
with patch('salt.utils.fopen', mock_open()) as m_open:
helper_open = m_open()
helper_open.write.assertRaises(CommandExecutionError,

View File

@ -13,9 +13,15 @@ from salttesting.mock import MagicMock, patch, call, Mock
ensure_in_syspath('../../')
# Import Salt libs
from salt.modules import ps
import salt.ext.six as six
HAS_PSUTIL = ps.__virtual__()
ps_virtual = ps.__virtual__()
if ps_virtual is True or isinstance(ps_virtual, six.string_types):
HAS_PSUTIL = True
else:
HAS_PSUTIL = False
HAS_PSUTIL_VERSION = False
# Import 3rd-party libs

View File

@ -63,8 +63,10 @@ class PwGroupTestCase(TestCase):
'''
Tests for return info on all groups
'''
mock = MagicMock(return_value={'group.getent': 1})
with patch.dict(pw_group.__context__, mock):
mock_getent = [{'passwd': 'x',
'gid': 0,
'name': 'root'}]
with patch.dict(pw_group.__context__, {'group.getent': mock_getent}):
self.assertDictContainsSubset({'passwd': 'x',
'gid': 0,
'name': 'root'}, pw_group.getent()[0])

View File

@ -51,6 +51,7 @@ class GPGTestCase(TestCase):
with patch.dict(gpg.__salt__, {'config.get': MagicMock(return_value=False)}):
self.assertEqual(gpg._get_key_dir(), def_dir)
@patch('salt.utils.which', MagicMock())
def test__decrypt_ciphertext(self):
'''
test _decrypt_ciphertext

View File

@ -7,7 +7,7 @@ import pprint
# Import Salt Testing libs
from salttesting import skipIf, TestCase
from salttesting.helpers import ensure_in_syspath
from salttesting.helpers import destructiveTest, ensure_in_syspath
from salttesting.mock import (
NO_MOCK,
NO_MOCK_REASON,
@ -959,11 +959,12 @@ class FileTestCase(TestCase):
# 'comment' function tests: 1
@destructiveTest
def test_comment(self):
'''
Test to comment out specified lines in a file.
'''
name = '/etc/fstab'
name = '/etc/aliases' if salt.utils.is_darwin() else '/etc/fstab'
regex = 'bind 127.0.0.1'
ret = {'name': name,
@ -1003,7 +1004,7 @@ class FileTestCase(TestCase):
'file.comment_line': mock_t}):
with patch.dict(filestate.__opts__, {'test': True}):
comt = ('File {0} is set to be updated'.format(name))
ret.update({'comment': comt, 'result': None, 'pchanges': {'/etc/fstab': 'updated'}})
ret.update({'comment': comt, 'result': None, 'pchanges': {name: 'updated'}})
self.assertDictEqual(filestate.comment(name, regex), ret)
with patch.dict(filestate.__opts__, {'test': False}):
@ -1016,11 +1017,12 @@ class FileTestCase(TestCase):
# 'uncomment' function tests: 1
@destructiveTest
def test_uncomment(self):
'''
Test to uncomment specified commented lines in a file
'''
name = '/etc/fstab'
name = '/etc/aliases' if salt.utils.is_darwin() else '/etc/fstab'
regex = 'bind 127.0.0.1'
ret = {'name': name,
@ -1058,7 +1060,7 @@ class FileTestCase(TestCase):
with patch.dict(filestate.__opts__, {'test': True}):
comt = ('File {0} is set to be updated'.format(name))
ret.update({'comment': comt, 'result': None, 'pchanges': {'/etc/fstab': 'updated'}, })
ret.update({'comment': comt, 'result': None, 'pchanges': {name: 'updated'}, })
self.assertDictEqual(filestate.uncomment(name, regex), ret)
with patch.dict(filestate.__opts__, {'test': False}):

View File

@ -74,6 +74,7 @@ class BaseTCPReqCase(TestCase):
del cls.server_channel
@skipIf(salt.utils.is_darwin(), 'hanging test suite on MacOS')
class ClearReqTestCases(BaseTCPReqCase, ReqChannelMixin):
'''
Test all of the clear msg stuff
@ -90,6 +91,7 @@ class ClearReqTestCases(BaseTCPReqCase, ReqChannelMixin):
raise tornado.gen.Return((payload, {'fun': 'send_clear'}))
@skipIf(salt.utils.is_darwin(), 'hanging test suite on MacOS')
class AESReqTestCases(BaseTCPReqCase, ReqChannelMixin):
def setUp(self):
self.channel = salt.transport.client.ReqChannel.factory(self.minion_opts)