# -*- coding: utf-8 -*- # Import python libs from __future__ import absolute_import import json import pprint # Import Salt Testing libs from salttesting import skipIf, TestCase from salttesting.helpers import ensure_in_syspath from salttesting.mock import ( NO_MOCK, NO_MOCK_REASON, MagicMock, mock_open, patch) ensure_in_syspath('../../') # Import third party libs import yaml # Import salt libs import salt.states.file as filestate from salt.exceptions import CommandExecutionError import salt import os import shutil filestate.__env__ = 'base' filestate.__salt__ = {'file.manage_file': False} filestate.__opts__ = {'test': False, 'cachedir': ''} filestate.__instance_id__ = '' filestate.__grains__ = {} filestate.__low__ = {} @skipIf(NO_MOCK, NO_MOCK_REASON) class TestFileState(TestCase): def test_serialize(self): def returner(contents, *args, **kwargs): returner.returned = contents returner.returned = None filestate.__salt__ = { 'file.manage_file': returner } dataset = { "foo": True, "bar": 42, "baz": [1, 2, 3], "qux": 2.0 } filestate.serialize('/tmp', dataset) self.assertEqual(yaml.load(returner.returned), dataset) filestate.serialize('/tmp', dataset, formatter="yaml") self.assertEqual(yaml.load(returner.returned), dataset) filestate.serialize('/tmp', dataset, formatter="json") self.assertEqual(json.loads(returner.returned), dataset) filestate.serialize('/tmp', dataset, formatter="python") self.assertEqual(returner.returned, pprint.pformat(dataset)) def test_contents_and_contents_pillar(self): def returner(contents, *args, **kwargs): returner.returned = contents returner.returned = None filestate.__salt__ = { 'file.manage_file': returner } manage_mode_mock = MagicMock() filestate.__salt__['config.manage_mode'] = manage_mode_mock ret = filestate.managed('/tmp/foo', contents='hi', contents_pillar='foo:bar') self.assertEqual(False, ret['result']) def test_contents_pillar_adds_newline(self): # make sure the newline pillar_value = 'i am the pillar value' expected = '{0}\n'.format(pillar_value) self.run_contents_pillar(pillar_value, expected) def test_contents_pillar_doesnt_add_more_newlines(self): # make sure the newline pillar_value = 'i am the pillar value\n' self.run_contents_pillar(pillar_value, expected=pillar_value) def run_contents_pillar(self, pillar_value, expected): returner = MagicMock(return_value=None) filestate.__salt__ = { 'file.manage_file': returner } path = '/tmp/foo' pillar_path = 'foo:bar' # the values don't matter here filestate.__salt__['config.manage_mode'] = MagicMock() filestate.__salt__['file.source_list'] = MagicMock(return_value=[None, None]) filestate.__salt__['file.get_managed'] = MagicMock(return_value=[None, None, None]) # pillar.get should return the pillar_value pillar_mock = MagicMock(return_value=pillar_value) filestate.__salt__['pillar.get'] = pillar_mock ret = filestate.managed(path, contents_pillar=pillar_path) # make sure the pillar_mock is called with the given path pillar_mock.assert_called_once_with(pillar_path) # make sure no errors are returned self.assertEqual(None, ret) # make sure the value is correct self.assertEqual(expected, returner.call_args[0][-3]) @skipIf(NO_MOCK, NO_MOCK_REASON) class FileTestCase(TestCase): ''' Test cases for salt.states.file ''' # 'symlink' function tests: 1 def test_symlink(self): ''' Test to create a symlink. ''' name = '/etc/grub.conf' target = '/boot/grub/grub.conf' user = 'salt' group = 'saltstack' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock_uid = MagicMock(side_effect=['', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12']) mock_gid = MagicMock(side_effect=['', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12']) mock_if = MagicMock(side_effect=[False, True, False, False, False, False, False, False]) mock_dir = MagicMock(side_effect=[True, True, True, True, False, True, True, True, True, False, True, False]) mock_ret = MagicMock(return_value=target) mock_user = MagicMock(return_value=user) mock_grp = MagicMock(return_value=group) mock_file = MagicMock(side_effect=[OSError, True]) with patch.dict(filestate.__salt__, {'config.manage_mode': mock_t, 'file.user_to_uid': mock_uid, 'file.group_to_gid': mock_gid, 'file.is_link': mock_if, 'file.readlink': mock_ret, 'file.get_user': mock_user, 'file.get_group': mock_grp, 'file.symlink': mock_file}): comt = ('Must provide name to file.symlink') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.symlink('', target), ret) comt = ('User salt does not exist. Group saltstack does not exist.') ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.symlink(name, target, user=user, group=group), ret) with patch.dict(filestate.__opts__, {'test': True}): with patch.object(os.path, 'exists', mock_f): comt = ('Symlink /etc/grub.conf to /boot/grub/grub.conf' ' is set for creation') ret.update({'comment': comt, 'result': None}) self.assertDictEqual(filestate.symlink(name, target, user=user, group=group), ret) with patch.dict(filestate.__opts__, {'test': False}): with patch.object(os.path, 'isdir', mock_f): comt = ('Directory /etc for symlink is not present') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.symlink(name, target, user=user, group=group), ret) with patch.object(os.path, 'isdir', mock_t): comt = ('Symlink {0} is present and owned by ' '{1}:{2}'.format(name, user, group)) ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.symlink(name, target, user=user, group=group), ret) with patch.object(os.path, 'isdir', mock_dir): with patch.object(os.path, 'lexists', mock_t): comt = ('File exists where the backup target SALT' ' should go') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.symlink (name, target, user=user, group=group, backupname='SALT'), ret) comt = ('Something exists where the backup target' ' SALTshould go') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.symlink (name, target, user=user, group=group, backupname='SALT', force=True), ret) with patch.object(os.path, 'isfile', mock_t): comt = ('File exists where the symlink {0} should be' .format(name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.symlink (name, target, user=user, group=group), ret) with patch.object(os.path, 'isfile', mock_f): comt = ('Directory exists where the symlink {0}' ' should be'.format(name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.symlink (name, target, user=user, group=group), ret) with patch.object(os.path, 'exists', mock_f): comt = ('Unable to create new symlink {0} -> ' '{1}: '.format(name, target)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.symlink (name, target, user=user, group=group), ret) comt = ('Created new symlink {0} -> ' '{1}'.format(name, target)) ret.update({'comment': comt, 'result': True, 'changes': {'new': name}}) self.assertDictEqual(filestate.symlink (name, target, user=user, group=group), ret) # 'absent' function tests: 1 @patch.object(os.path, 'islink', MagicMock(return_value=False)) def test_absent(self): ''' Test to make sure that the named file or directory is absent. ''' name = '/fake/file.conf' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock_file = MagicMock(side_effect=[True, CommandExecutionError]) mock_tree = MagicMock(side_effect=[True, OSError]) comt = ('Must provide name to file.absent') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.absent(''), ret) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path' .format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.absent(name), ret) with patch.object(os.path, 'isabs', mock_t): comt = ('Refusing to make "/" absent') ret.update({'comment': comt, 'name': '/'}) self.assertDictEqual(filestate.absent('/'), ret) with patch.object(os.path, 'isfile', mock_t): with patch.dict(filestate.__opts__, {'test': True}): comt = ('File {0} is set for removal'.format(name)) ret.update({'comment': comt, 'name': name, 'result': None}) self.assertDictEqual(filestate.absent(name), ret) with patch.dict(filestate.__opts__, {'test': False}): with patch.dict(filestate.__salt__, {'file.remove': mock_file}): comt = ('Removed file {0}'.format(name)) ret.update({'comment': comt, 'result': True, 'changes': {'removed': name}}) self.assertDictEqual(filestate.absent(name), ret) comt = ('Removed file {0}'.format(name)) ret.update({'comment': '', 'result': False, 'changes': {}}) self.assertDictEqual(filestate.absent(name), ret) with patch.object(os.path, 'isfile', mock_f): with patch.object(os.path, 'isdir', mock_t): with patch.dict(filestate.__opts__, {'test': True}): comt = ('Directory {0} is set for removal'.format(name)) ret.update({'comment': comt, 'result': None}) self.assertDictEqual(filestate.absent(name), ret) with patch.dict(filestate.__opts__, {'test': False}): with patch.object(shutil, 'rmtree', mock_tree): comt = ('Removed directory {0}'.format(name)) ret.update({'comment': comt, 'result': True, 'changes': {'removed': name}}) self.assertDictEqual(filestate.absent(name), ret) comt = ('Failed to remove directory {0}'.format(name)) ret.update({'comment': comt, 'result': False, 'changes': {}}) self.assertDictEqual(filestate.absent(name), ret) with patch.object(os.path, 'isdir', mock_f): with patch.dict(filestate.__opts__, {'test': True}): comt = ('File {0} is not present'.format(name)) ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.absent(name), ret) # 'exists' function tests: 1 def test_exists(self): ''' Test to verify that the named file or directory is present or exists. ''' name = '/etc/grub.conf' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) comt = ('Must provide name to file.exists') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.exists(''), ret) with patch.object(os.path, 'exists', mock_f): comt = ('Specified path {0} does not exist'.format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.exists(name), ret) with patch.object(os.path, 'exists', mock_t): comt = ('Path {0} exists'.format(name)) ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.exists(name), ret) # 'missing' function tests: 1 def test_missing(self): ''' Test to verify that the named file or directory is missing. ''' name = '/etc/grub.conf' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) comt = ('Must provide name to file.missing') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.missing(''), ret) with patch.object(os.path, 'exists', mock_t): comt = ('Specified path {0} exists'.format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.missing(name), ret) with patch.object(os.path, 'exists', mock_f): comt = ('Path {0} is missing'.format(name)) ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.missing(name), ret) # 'managed' function tests: 1 @patch('salt.states.file._load_accumulators', MagicMock(return_value=([], []))) def test_managed(self): ''' Test to manage a given file, this function allows for a file to be downloaded from the salt master and potentially run through a templating system. ''' name = '/etc/grub.conf' user = 'salt' group = 'saltstack' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock_uid = MagicMock(side_effect=['', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12']) mock_gid = MagicMock(side_effect=['', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12']) mock_if = MagicMock(side_effect=[True, False, False, False, False, False, False, False]) mock_ret = MagicMock(return_value=(ret, None)) mock_dict = MagicMock(return_value={}) mock_cp = MagicMock(side_effect=[Exception, True]) mock_ex = MagicMock(side_effect=[Exception, {'changes': {name: name}}, True, Exception]) mock_mng = MagicMock(side_effect=[Exception, ('', '', ''), ('', '', ''), ('', '', True), ('', '', True), ('', '', ''), ('', '', '')]) mock_file = MagicMock(side_effect=[CommandExecutionError, ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', ''), ('', '')]) with patch.dict(filestate.__salt__, {'config.manage_mode': mock_t, 'file.user_to_uid': mock_uid, 'file.group_to_gid': mock_gid, 'file.file_exists': mock_if, 'file.check_perms': mock_ret, 'file.check_managed_changes': mock_dict, 'file.get_managed': mock_mng, 'file.source_list': mock_file, 'file.copy': mock_cp, 'file.manage_file': mock_ex, 'cmd.retcode': mock_t}): comt = ('Must provide name to file.exists') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.managed(''), ret) with patch.object(os.path, 'isfile', mock_f): comt = ('File {0} is not present and is not set for ' 'creation'.format(name)) ret.update({'comment': comt, 'name': name, 'result': True}) self.assertDictEqual(filestate.managed(name, create=False), ret) comt = ('User salt is not available Group saltstack' ' is not available') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.managed(name, user=user, group=group), ret) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path' .format(name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.managed(name, user=user, group=group), ret) with patch.object(os.path, 'isabs', mock_t): with patch.object(os.path, 'isdir', mock_t): comt = ('Specified target {0} is a directory'.format(name)) ret.update({'comment': comt}) self.assertDictEqual(filestate.managed(name, user=user, group=group), ret) with patch.object(os.path, 'isdir', mock_f): comt = ('Context must be formed as a dict') ret.update({'comment': comt}) self.assertDictEqual(filestate.managed(name, user=user, group=group, context=True), ret) comt = ('Defaults must be formed as a dict') ret.update({'comment': comt}) self.assertDictEqual(filestate.managed(name, user=user, group=group, defaults=True), ret) comt = ('Only one of contents, contents_pillar, ' 'and contents_grains is permitted') ret.update({'comment': comt}) self.assertDictEqual(filestate.managed (name, user=user, group=group, contents='A', contents_grains='B', contents_pillar='C'), ret) with patch.object(os.path, 'exists', mock_t): with patch.dict(filestate.__opts__, {'test': True}): comt = ('File {0} not updated'.format(name)) ret.update({'comment': comt}) self.assertDictEqual(filestate.managed (name, user=user, group=group, replace=False), ret) comt = ('The file {0} is in the correct state' .format(name)) ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.managed (name, user=user, contents='A', group=group), ret) with patch.object(os.path, 'exists', mock_f): with patch.dict(filestate.__opts__, {'test': False}): comt = ('Unable to manage file: ') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.managed (name, user=user, group=group, contents='A'), ret) comt = ('Unable to manage file: ') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.managed (name, user=user, group=group, contents='A'), ret) with patch.object(salt.utils, 'mkstemp', return_value=name): comt = ('Unable to copy file {0} to {1}: ' .format(name, name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.managed (name, user=user, group=group, check_cmd='A'), ret) comt = ('Unable to check_cmd file: ') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.managed (name, user=user, group=group, check_cmd='A'), ret) comt = ('check_cmd execution failed') ret.update({'comment': comt, 'result': False, 'skip_watch': True}) self.assertDictEqual(filestate.managed (name, user=user, group=group, check_cmd='A'), ret) comt = ('check_cmd execution failed') ret.update({'comment': True}) ret.pop('skip_watch', None) self.assertDictEqual(filestate.managed (name, user=user, group=group), ret) self.assertTrue(filestate.managed (name, user=user, group=group)) comt = ('Unable to manage file: ') ret.update({'comment': comt}) self.assertDictEqual(filestate.managed (name, user=user, group=group), ret) # 'directory' function tests: 1 def test_directory(self): ''' Test to ensure that a named directory is present and has the right perms ''' name = '/etc/grub.conf' user = 'salt' group = 'saltstack' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.directory') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.directory(''), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock_perms = MagicMock(return_value=(ret, '')) mock_uid = MagicMock(side_effect=['', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12', 'U12']) mock_gid = MagicMock(side_effect=['', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12', 'G12']) with patch.dict(filestate.__salt__, {'config.manage_mode': mock_t, 'file.user_to_uid': mock_uid, 'file.group_to_gid': mock_gid, 'file.stats': mock_f, 'file.check_perms': mock_perms}): comt = ('User salt is not available Group saltstack' ' is not available') ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.directory(name, user=user, group=group), ret) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path' .format(name)) ret.update({'comment': comt}) self.assertDictEqual(filestate.directory(name, user=user, group=group), ret) with patch.object(os.path, 'isabs', mock_t): with patch.object(os.path, 'isfile', MagicMock(side_effect=[True, True, False, True, True, True, False])): with patch.object(os.path, 'lexists', mock_t): with patch.object(os.path, 'islink', mock_f): with patch.object(os.path, 'isdir', mock_f): comt = ('File exists where the backup target' ' A should go') ret.update({'comment': comt}) self.assertDictEqual(filestate.directory (name, user=user, group=group, backupname='A'), ret) comt = ('Something exists where the backup' ' target Ashould go') ret.update({'comment': comt}) self.assertDictEqual(filestate.directory (name, user=user, group=group, force=True, backupname='A'), ret) comt = ('Specified location {0} exists and is a file' .format(name)) ret.update({'comment': comt}) self.assertDictEqual(filestate.directory(name, user=user, group=group), ret) with patch.object(os.path, 'islink', mock_t): comt = ('Specified location {0} exists and is a symlink' .format(name)) ret.update({'comment': comt}) self.assertDictEqual(filestate.directory(name, user=user, group=group), ret) with patch.object(os.path, 'isfile', mock_f): with patch.dict(filestate.__opts__, {'test': True}): comt = ('The following files will be changed:\n{0}:' ' directory - new\n'.format(name)) ret.update({'comment': comt, 'result': None}) self.assertDictEqual(filestate.directory(name, user=user, group=group), ret) with patch.dict(filestate.__opts__, {'test': False}): with patch.object(os.path, 'isdir', mock_f): comt = ('No directory to create {0} in' .format(name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.directory (name, user=user, group=group), ret) with patch.object(os.path, 'isdir', MagicMock(side_effect=[True, False])): comt = ('Failed to create directory {0}' .format(name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.directory (name, user=user, group=group), ret) recurse = ['ignore_files', 'ignore_dirs'] with patch.object(os.path, 'isdir', mock_t): self.assertDictEqual(filestate.directory (name, user=user, recurse=recurse, group=group), ret) self.assertDictEqual(filestate.directory (name, user=user, group=group), ret) # 'recurse' function tests: 1 def test_recurse(self): ''' Test to recurse through a subdirectory on the master and copy said subdirectory over to the specified path. ''' name = '/opt/code/flask' source = 'salt://code/flask' user = 'salt' group = 'saltstack' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ("'mode' is not allowed in 'file.recurse'." " Please use 'file_mode' and 'dir_mode'.") ret.update({'comment': comt}) self.assertDictEqual(filestate.recurse(name, source, mode='W'), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock_uid = MagicMock(return_value='') mock_gid = MagicMock(return_value='') mock_l = MagicMock(return_value=[]) mock_emt = MagicMock(side_effect=[[], ['code/flask'], ['code/flask']]) mock_lst = MagicMock(side_effect=[CommandExecutionError, (source, ''), (source, ''), (source, '')]) with patch.dict(filestate.__salt__, {'config.manage_mode': mock_t, 'file.user_to_uid': mock_uid, 'file.group_to_gid': mock_gid, 'file.source_list': mock_lst, 'cp.list_master_dirs': mock_emt, 'cp.list_master': mock_l}): comt = ('User salt is not available Group saltstack' ' is not available') ret.update({'comment': comt}) self.assertDictEqual(filestate.recurse(name, source, user=user, group=group), ret) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path' .format(name)) ret.update({'comment': comt}) self.assertDictEqual(filestate.recurse(name, source), ret) with patch.object(os.path, 'isabs', mock_t): comt = ("Invalid source '1' (must be a salt:// URI)") ret.update({'comment': comt}) self.assertDictEqual(filestate.recurse(name, 1), ret) comt = ("Invalid source '//code/flask' (must be a salt:// URI)") ret.update({'comment': comt}) self.assertDictEqual(filestate.recurse(name, '//code/flask'), ret) comt = ('Recurse failed: ') ret.update({'comment': comt}) self.assertDictEqual(filestate.recurse(name, source), ret) comt = ("The directory 'salt://code/flask' does not exist" " on the salt fileserver in saltenv 'base'") ret.update({'comment': comt}) self.assertDictEqual(filestate.recurse(name, source), ret) with patch.object(os.path, 'isdir', mock_f): with patch.object(os.path, 'exists', mock_t): comt = ('The path {0} exists and is not a directory' .format(name)) ret.update({'comment': comt}) self.assertDictEqual(filestate.recurse(name, source), ret) with patch.object(os.path, 'isdir', mock_t): comt = ('The directory {0} is in the correct state' .format(name)) ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.recurse(name, source), ret) # 'replace' function tests: 1 def test_replace(self): ''' Test to maintain an edit in a file. ''' name = '/etc/grub.conf' pattern = ('CentOS +') repl = 'salt' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.replace') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.replace('', pattern, repl), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path'.format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.replace(name, pattern, repl), ret) with patch.object(os.path, 'isabs', mock_t): with patch.object(os.path, 'exists', mock_t): with patch.dict(filestate.__salt__, {'file.replace': mock_f}): with patch.dict(filestate.__opts__, {'test': False}): comt = ('No changes needed to be made') ret.update({'comment': comt, 'name': name, 'result': True}) self.assertDictEqual(filestate.replace(name, pattern, repl), ret) # 'blockreplace' function tests: 1 @patch('salt.states.file._load_accumulators', MagicMock(return_value=([], []))) def test_blockreplace(self): ''' Test to maintain an edit in a file in a zone delimited by two line markers. ''' name = '/etc/hosts' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.blockreplace') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.blockreplace(''), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path'.format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.blockreplace(name), ret) with patch.object(os.path, 'isabs', mock_t): with patch.dict(filestate.__salt__, {'file.blockreplace': mock_t}): with patch.dict(filestate.__opts__, {'test': True}): comt = ('Changes would be made') ret.update({'comment': comt, 'result': None, 'changes': {'diff': True}}) self.assertDictEqual(filestate.blockreplace(name), ret) # 'comment' function tests: 1 def test_comment(self): ''' Test to comment out specified lines in a file. ''' name = '/etc/fstab' regex = 'bind 127.0.0.1' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.comment') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.comment('', regex), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock = MagicMock(side_effect=[False, True, False, False]) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path'.format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.comment(name, regex), ret) with patch.object(os.path, 'isabs', mock_t): with patch.dict(filestate.__salt__, {'file.contains_regex_multiline': mock, 'file.search': mock}): comt = ('Pattern already commented') ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.comment(name, regex), ret) comt = ('{0}: Pattern not found'.format(regex)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.comment(name, regex), ret) with patch.dict(filestate.__salt__, {'file.contains_regex_multiline': mock_t, 'file.search': mock_t, 'file.comment': 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}) self.assertDictEqual(filestate.comment(name, regex), ret) with patch.dict(filestate.__opts__, {'test': False}): with patch.object(salt.utils, 'fopen', MagicMock(mock_open())): comt = ('Commented lines successfully') ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.comment(name, regex), ret) # 'uncomment' function tests: 1 def test_uncomment(self): ''' Test to uncomment specified commented lines in a file ''' name = '/etc/fstab' regex = 'bind 127.0.0.1' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.uncomment') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.uncomment('', regex), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock = MagicMock(side_effect=[True, False, False, False, True, False, True, True]) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path'.format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.uncomment(name, regex), ret) with patch.object(os.path, 'isabs', mock_t): with patch.dict(filestate.__salt__, {'file.contains_regex_multiline': mock, 'file.search': mock, 'file.uncomment': mock_t}): comt = ('Pattern already uncommented') ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.uncomment(name, regex), ret) comt = ('{0}: Pattern not found'.format(regex)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.uncomment(name, regex), ret) with patch.dict(filestate.__opts__, {'test': True}): comt = ('File {0} is set to be updated'.format(name)) ret.update({'comment': comt, 'result': None}) self.assertDictEqual(filestate.uncomment(name, regex), ret) with patch.dict(filestate.__opts__, {'test': False}): with patch.object(salt.utils, 'fopen', MagicMock(mock_open())): comt = ('Uncommented lines successfully') ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.uncomment(name, regex), ret) # 'append' function tests: 1 def test_append(self): ''' Test to ensure that some text appears at the end of a file. ''' name = '/etc/motd' source = ['salt://motd/hr-messages.tmpl'] sources = ['salt://motd/devops-messages.tmpl'] text = ['Trust no one unless you have eaten much salt with him.'] ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.append') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.append(''), ret) comt = ('source and sources are mutually exclusive') ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.append(name, source=source, sources=sources), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock_err = MagicMock(side_effect=[TypeError, True, True]) with patch.dict(filestate.__salt__, {'file.directory_exists': mock_f, 'file.makedirs': mock_t, 'file.stats': mock_f, 'cp.get_template': mock_f, 'file.contains_regex_multiline': mock_err, 'file.search': mock_err}): with patch.object(os.path, 'isdir', mock_t): comt = ('The following files will be changed:\n/etc:' ' directory - new\n') ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.append(name, makedirs=True), ret) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path' .format(name)) ret.update({'comment': comt}) self.assertDictEqual(filestate.append(name), ret) with patch.object(os.path, 'isabs', mock_t): with patch.object(os.path, 'exists', mock_t): comt = ("Failed to load template file {0}".format(source)) ret.update({'comment': comt, 'name': source, 'data': []}) self.assertDictEqual(filestate.append(name, source=source), ret) ret.pop('data', None) ret.update({'name': name}) with patch.object(salt.utils, 'fopen', MagicMock(mock_open(read_data=''))): comt = ('No text found to append. Nothing appended') ret.update({'comment': comt}) self.assertDictEqual(filestate.append(name, text=text), ret) with patch.object(salt.utils, 'istextfile', mock_f): with patch.dict(filestate.__opts__, {'test': True}): change = {'diff': 'Replace binary file'} ret.update({'comment': '', 'result': None, 'changes': change}) self.assertDictEqual(filestate.append (name, text=text), ret) with patch.dict(filestate.__opts__, {'test': False}): comt = ('File {0} is in correct state' .format(name)) ret.update({'comment': comt, 'result': True, 'changes': {}}) self.assertDictEqual(filestate.append (name, text=text), ret) # 'prepend' function tests: 1 def test_prepend(self): ''' Test to ensure that some text appears at the beginning of a file. ''' name = '/etc/motd' source = ['salt://motd/hr-messages.tmpl'] sources = ['salt://motd/devops-messages.tmpl'] text = ['Trust no one unless you have eaten much salt with him.'] ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.prepend') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.prepend(''), ret) comt = ('source and sources are mutually exclusive') ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.prepend(name, source=source, sources=sources), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) with patch.dict(filestate.__salt__, {'file.directory_exists': mock_f, 'file.makedirs': mock_t, 'file.stats': mock_f, 'cp.get_template': mock_f, 'file.contains_regex_multiline': mock_f, 'file.search': mock_f, 'file.prepend': mock_t}): with patch.object(os.path, 'isdir', mock_t): comt = ('The following files will be changed:\n/etc:' ' directory - new\n') ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.prepend(name, makedirs=True), ret) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path' .format(name)) ret.update({'comment': comt}) self.assertDictEqual(filestate.prepend(name), ret) with patch.object(os.path, 'isabs', mock_t): with patch.object(os.path, 'exists', mock_t): comt = ("Failed to load template file {0}".format(source)) ret.update({'comment': comt, 'name': source, 'data': []}) self.assertDictEqual(filestate.prepend(name, source=source), ret) ret.pop('data', None) ret.update({'name': name}) with patch.object(salt.utils, 'fopen', MagicMock(mock_open(read_data=''))): with patch.object(salt.utils, 'istextfile', mock_f): with patch.dict(filestate.__opts__, {'test': True}): change = {'diff': 'Replace binary file'} comt = ('File {0} is set to be updated' .format(name)) ret.update({'comment': comt, 'result': None, 'changes': change}) self.assertDictEqual(filestate.prepend (name, text=text), ret) with patch.dict(filestate.__opts__, {'test': False}): comt = ('Prepended 1 lines') ret.update({'comment': comt, 'result': True, 'changes': {}}) self.assertDictEqual(filestate.prepend (name, text=text), ret) # 'patch' function tests: 1 def test_patch(self): ''' Test to apply a patch to a file. ''' name = '/opt/file.txt' source = 'salt://file.patch' ha_sh = 'md5=e138491e9d5b97023cea823fe17bac22' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.patch') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.patch(''), ret) comt = ('{0}: file not found'.format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.patch(name), ret) mock_t = MagicMock(return_value=True) mock_true = MagicMock(side_effect=[True, False, False, False, False]) mock_false = MagicMock(side_effect=[False, True, True, True]) mock_ret = MagicMock(return_value={'retcode': True}) with patch.object(os.path, 'isabs', mock_t): with patch.object(os.path, 'exists', mock_t): comt = ('Source is required') ret.update({'comment': comt}) self.assertDictEqual(filestate.patch(name), ret) comt = ('Hash is required') ret.update({'comment': comt}) self.assertDictEqual(filestate.patch(name, source=source), ret) with patch.dict(filestate.__salt__, {'file.check_hash': mock_true, 'cp.cache_file': mock_false, 'file.patch': mock_ret}): comt = ('Patch is already applied') ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.patch(name, source=source, hash=ha_sh), ret) comt = ("Unable to cache salt://file.patch" " from saltenv 'base'") ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.patch(name, source=source, hash=ha_sh), ret) with patch.dict(filestate.__opts__, {'test': True}): comt = ('File /opt/file.txt will be patched') ret.update({'comment': comt, 'result': None, 'changes': {'retcode': True}}) self.assertDictEqual(filestate.patch(name, source=source, hash=ha_sh), ret) with patch.dict(filestate.__opts__, {'test': False}): ret.update({'comment': '', 'result': False}) self.assertDictEqual(filestate.patch(name, source=source, hash=ha_sh), ret) self.assertDictEqual(filestate.patch (name, source=source, hash=ha_sh, dry_run_first=False), ret) # 'touch' function tests: 1 def test_touch(self): ''' Test to replicate the 'nix "touch" command to create a new empty file or update the atime and mtime of an existing file. ''' name = '/var/log/httpd/logrotate.empty' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.touch') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.touch(''), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path'.format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.touch(name), ret) with patch.object(os.path, 'isabs', mock_t): with patch.object(os.path, 'exists', mock_f): with patch.dict(filestate.__opts__, {'test': True}): comt = ('File {0} is set to be created'.format(name)) ret.update({'comment': comt, 'result': None}) self.assertDictEqual(filestate.touch(name), ret) with patch.dict(filestate.__opts__, {'test': False}): with patch.object(os.path, 'isdir', mock_f): comt = ('Directory not present to touch file {0}' .format(name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.touch(name), ret) with patch.object(os.path, 'isdir', mock_t): with patch.dict(filestate.__salt__, {'file.touch': mock_t}): comt = ('Created empty file {0}'.format(name)) ret.update({'comment': comt, 'result': True, 'changes': {'new': name}}) self.assertDictEqual(filestate.touch(name), ret) # 'copy' function tests: 1 def test_copy(self): ''' Test if the source file exists on the system, copy it to the named file. ''' name = '/tmp/salt' source = '/tmp/salt/salt' user = 'salt' group = 'saltstack' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.comment') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.copy('', source), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock_uid = MagicMock(side_effect=['']) mock_gid = MagicMock(side_effect=['']) mock_user = MagicMock(return_value=user) mock_grp = MagicMock(return_value=group) mock_io = MagicMock(side_effect=IOError) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path'.format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.copy(name, source), ret) with patch.object(os.path, 'isabs', mock_t): with patch.object(os.path, 'exists', mock_f): comt = ('Source file "{0}" is not present'.format(source)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.copy(name, source), ret) with patch.object(os.path, 'exists', mock_t): with patch.dict(filestate.__salt__, {'file.user_to_uid': mock_uid, 'file.group_to_gid': mock_gid, 'file.get_user': mock_user, 'file.get_group': mock_grp, 'file.get_mode': mock_grp, 'file.check_perms': mock_t}): comt = ('User salt is not available Group ' 'saltstack is not available') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.copy(name, source, user=user, group=group), ret) comt1 = ('Failed to delete "{0}" in preparation for' ' forced move'.format(name)) comt2 = ('The target file "{0}" exists and will not be ' 'overwritten'.format(name)) comt3 = ('File "{0}" is set to be copied to "{1}"' .format(source, name)) with patch.object(os.path, 'isdir', mock_f): with patch.object(os.path, 'lexists', mock_t): with patch.dict(filestate.__opts__, {'test': False}): with patch.object(os.path, 'isfile', mock_f): with patch.object(os.path, 'islink', mock_io): ret.update({'comment': comt1, 'result': False}) self.assertDictEqual(filestate.copy (name, source, preserve=True, force=True), ret) with patch.object(os.path, 'isfile', mock_t): ret.update({'comment': comt2, 'result': True}) self.assertDictEqual(filestate.copy (name, source, preserve=True), ret) with patch.object(os.path, 'lexists', mock_f): with patch.dict(filestate.__opts__, {'test': True}): ret.update({'comment': comt3, 'result': None}) self.assertDictEqual(filestate.copy (name, source, preserve=True), ret) with patch.dict(filestate.__opts__, {'test': False}): comt = ('The target directory /tmp is' ' not present') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.copy (name, source, preserve=True), ret) with patch.object(os.path, 'isdir', mock_t): with patch.dict(filestate.__opts__, {'test': False}): with patch.object(shutil, 'copy', MagicMock(side_effect=[IOError, True])): comt = ('Failed to copy "{0}" to "{1}"' .format(source, name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.copy (name, source, preserve=True), ret) comt = ('Copied "{0}" to "{1}"'.format(source, name)) ret.update({'comment': comt, 'result': True, 'changes': {name: source}}) self.assertDictEqual(filestate.copy (name, source, preserve=True), ret) # 'rename' function tests: 1 def test_rename(self): ''' Test if the source file exists on the system, rename it to the named file. ''' name = '/tmp/salt' source = '/tmp/salt/salt' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.rename') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.rename('', source), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock_lex = MagicMock(side_effect=[False, True, True, True, True, True, True, True, False, True, False, True, False, True, False]) with patch.object(os.path, 'isabs', mock_f): comt = ('Specified file {0} is not an absolute path'.format(name)) ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.rename(name, source), ret) with patch.object(os.path, 'isabs', mock_t): with patch.object(os.path, 'lexists', mock_lex): comt = ('Source file "{0}" has already been moved out of ' 'place'.format(source)) ret.update({'comment': comt, 'result': True}) self.assertDictEqual(filestate.rename(name, source), ret) comt = ('The target file "{0}" exists and will not be ' 'overwritten'.format(name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.rename(name, source), ret) with patch.dict(filestate.__opts__, {'test': False}): comt = ('Failed to delete "{0}" in preparation for ' 'forced move'.format(name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.rename(name, source, force=True), ret) with patch.dict(filestate.__opts__, {'test': True}): comt = ('File "{0}" is set to be moved to "{1}"' .format(source, name)) ret.update({'comment': comt, 'result': None}) self.assertDictEqual(filestate.rename(name, source), ret) with patch.object(os.path, 'isdir', mock_f): with patch.dict(filestate.__opts__, {'test': False}): comt = ('The target directory /tmp is not present') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.rename(name, source), ret) with patch.object(os.path, 'isdir', mock_t): with patch.object(os.path, 'islink', mock_f): with patch.dict(filestate.__opts__, {'test': False}): with patch.object(shutil, 'move', MagicMock(side_effect=[IOError, True])): comt = ('Failed to move "{0}" to "{1}"' .format(source, name)) ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.rename(name, source), ret) comt = ('Moved "{0}" to "{1}"'.format(source, name)) ret.update({'comment': comt, 'result': True, 'changes': {name: source}}) self.assertDictEqual(filestate.rename(name, source), ret) # 'accumulated' function tests: 1 @patch('salt.states.file._load_accumulators', MagicMock(return_value=({}, {}))) @patch('salt.states.file._persist_accummulators', MagicMock(return_value=True)) def test_accumulated(self): ''' Test to prepare accumulator which can be used in template in file. ''' name = 'animals_doing_things' filename = '/tmp/animal_file.txt' text = ' jumps over the lazy dog.' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.accumulated') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.accumulated('', filename, text), ret) comt = ('No text supplied for accumulator') ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.accumulated(name, filename, None), ret) with patch.dict(filestate.__low__, {'require_in': 'file', 'watch_in': 'salt', '__sls__': 'SLS', '__id__': 'ID'}): comt = ('Orphaned accumulator animals_doing_things in SLS:ID') ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.accumulated(name, filename, text), ret) with patch.dict(filestate.__low__, {'require_in': [{'file': 'A'}], 'watch_in': [{'B': 'C'}], '__sls__': 'SLS', '__id__': 'ID'}): comt = ('Accumulator {0} for file {1} ' 'was charged by text'.format(name, filename)) ret.update({'comment': comt, 'name': name, 'result': True}) self.assertDictEqual(filestate.accumulated(name, filename, text), ret) # 'serialize' function tests: 1 def test_serialize(self): ''' Test to serializes dataset and store it into managed file. ''' name = '/etc/dummy/package.json' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.serialize') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.serialize(''), ret) mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) with patch.object(os.path, 'isfile', mock_f): comt = ('File {0} is not present and is not set for ' 'creation'.format(name)) ret.update({'comment': comt, 'name': name, 'result': True}) self.assertDictEqual(filestate.serialize(name, create=False), ret) comt = ("Only one of 'dataset' and 'dataset_pillar' is permitted") ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.serialize(name, dataset=True, dataset_pillar=True), ret) comt = ("Neither 'dataset' nor 'dataset_pillar' was defined") ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.serialize(name), ret) with patch.object(os.path, 'isfile', mock_t): comt = ('Python format is not supported for merging') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.serialize(name, dataset=True, merge_if_exists=True, formatter='python'), ret) comt = ('A format is not supported') ret.update({'comment': comt, 'result': False}) self.assertDictEqual(filestate.serialize(name, dataset=True, formatter='A'), ret) mock_changes = MagicMock(return_value=True) mock_no_changes = MagicMock(return_value=False) # __opts__['test']=True with changes with patch.dict(filestate.__salt__, {'file.check_managed_changes': mock_changes}): with patch.dict(filestate.__opts__, {'test': True}): comt = ('Dataset will be serialized and stored into {0}' .format(name)) ret.update({'comment': comt, 'result': None, 'changes': True}) self.assertDictEqual( filestate.serialize(name, dataset=True, formatter='python'), ret) # __opts__['test']=True without changes with patch.dict(filestate.__salt__, {'file.check_managed_changes': mock_no_changes}): with patch.dict(filestate.__opts__, {'test': True}): comt = ('The file {0} is in the correct state' .format(name)) ret.update({'comment': comt, 'result': True, 'changes': False}) self.assertDictEqual( filestate.serialize(name, dataset=True, formatter='python'), ret) mock = MagicMock(return_value=ret) with patch.dict(filestate.__opts__, {'test': False}): with patch.dict(filestate.__salt__, {'file.manage_file': mock}): comt = ('Dataset will be serialized and stored into {0}' .format(name)) ret.update({'comment': comt, 'result': None}) self.assertDictEqual(filestate.serialize(name, dataset=True, formatter='python'), ret) # 'mknod' function tests: 1 def test_mknod(self): ''' Test to create a special file similar to the 'nix mknod command. ''' name = '/dev/AA' ntype = 'a' ret = {'name': name, 'result': False, 'comment': '', 'changes': {}} comt = ('Must provide name to file.mknod') ret.update({'comment': comt, 'name': ''}) self.assertDictEqual(filestate.mknod('', ntype), ret) comt = ("Node type unavailable: 'a'. Available node types are " "character ('c'), block ('b'), and pipe ('p')") ret.update({'comment': comt, 'name': name}) self.assertDictEqual(filestate.mknod(name, ntype), ret) # 'mod_run_check_cmd' function tests: 1 def test_mod_run_check_cmd(self): ''' Test to execute the check_cmd logic. ''' cmd = 'A' filename = 'B' ret = {'comment': 'check_cmd execution failed', 'result': False, 'skip_watch': True} mock = MagicMock(side_effect=[1, 0]) with patch.dict(filestate.__salt__, {'cmd.retcode': mock}): self.assertDictEqual(filestate.mod_run_check_cmd(cmd, filename), ret) self.assertTrue(filestate.mod_run_check_cmd(cmd, filename)) if __name__ == '__main__': from integration import run_tests run_tests(FileTestCase, needs_daemon=False) run_tests(TestFileState, needs_daemon=False)