Merge pull request #45357 from twangboy/win_fix_test_file

Fix `unit.modules.test_file` for Windows
This commit is contained in:
Nicole Thomas 2018-01-14 08:14:24 -05:00 committed by GitHub
commit c00fddd5bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 206 additions and 69 deletions

View File

@ -1714,7 +1714,7 @@ def _regex_to_static(src, regex):
except Exception as ex:
raise CommandExecutionError("{0}: '{1}'".format(_get_error_message(ex), regex))
return src and src.group() or regex
return src and src.group().rstrip('\r') or regex
def _assert_occurrence(src, probe, target, amount=1):

View File

@ -522,6 +522,7 @@ class FileModuleTestCase(TestCase, LoaderModuleMockMixin):
}
}
@skipIf(salt.utils.is_windows(), 'lsattr is not available on Windows')
def test_check_file_meta_no_lsattr(self):
'''
Ensure that we skip attribute comparison if lsattr(1) is not found
@ -567,17 +568,17 @@ class FileModuleTestCase(TestCase, LoaderModuleMockMixin):
newlines at end of file.
'''
# File ending with a newline
with tempfile.NamedTemporaryFile(mode='w', delete=False) as tfile:
with tempfile.NamedTemporaryFile(mode='wb', delete=False) as tfile:
tfile.write(salt.utils.stringutils.to_str('foo' + os.linesep))
tfile.flush()
filemod.append(tfile.name, 'bar')
expected = os.linesep.join(['foo', 'bar']) + os.linesep
expected = os.linesep.join(['foo', 'bar', ''])
with salt.utils.files.fopen(tfile.name) as tfile2:
self.assertEqual(
salt.utils.stringutils.to_unicode(tfile2.read()), expected)
new_file = salt.utils.stringutils.to_unicode(tfile2.read())
self.assertEqual(new_file, expected)
# File not ending with a newline
with tempfile.NamedTemporaryFile(mode='w', delete=False) as tfile:
with tempfile.NamedTemporaryFile(mode='wb', delete=False) as tfile:
tfile.write(salt.utils.stringutils.to_str('foo'))
tfile.flush()
filemod.append(tfile.name, 'bar')
@ -586,7 +587,7 @@ class FileModuleTestCase(TestCase, LoaderModuleMockMixin):
salt.utils.stringutils.to_unicode(tfile2.read()), expected)
# A newline should be added in empty files
with tempfile.NamedTemporaryFile(mode='w', delete=False) as tfile:
with tempfile.NamedTemporaryFile(mode='wb', delete=False) as tfile:
filemod.append(tfile.name, salt.utils.stringutils.to_str('bar'))
with salt.utils.files.fopen(tfile.name) as tfile2:
self.assertEqual(
@ -810,11 +811,12 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
'''
for mode in ['delete', 'replace']:
_log = MagicMock()
with patch('salt.utils.files.fopen', mock_open(read_data='')):
with patch('os.stat', self._anyattr):
with patch('salt.modules.file.log', _log):
assert not filemod.line('/dummy/path', content='foo', match='bar', mode=mode)
assert 'Cannot find text to {0}'.format(mode) in _log.warning.call_args_list[0][0][0]
with patch('salt.utils.files.fopen', mock_open(read_data='')), \
patch('os.stat', self._anyattr), \
patch('salt.modules.file.log', _log):
self.assertFalse(filemod.line('/dummy/path', content='foo', match='bar', mode=mode))
self.assertIn('Cannot find text to {0}'.format(mode),
_log.warning.call_args_list[0][0][0])
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -827,7 +829,7 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
for mode, err_msg in [(None, 'How to process the file'), ('nonsense', 'Unknown mode')]:
with pytest.raises(CommandExecutionError) as cmd_err:
filemod.line('foo', mode=mode)
assert err_msg in six.text_type(cmd_err)
self.assertIn(err_msg, six.text_type(cmd_err))
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -839,7 +841,8 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
for mode in ['insert', 'ensure', 'replace']:
with pytest.raises(CommandExecutionError) as cmd_err:
filemod.line('foo', mode=mode)
assert 'Content can only be empty if mode is "delete"' in six.text_type(cmd_err)
self.assertIn('Content can only be empty if mode is "delete"',
six.text_type(cmd_err))
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -853,7 +856,8 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
with patch('salt.utils.files.fopen', files_fopen):
with pytest.raises(CommandExecutionError) as cmd_err:
filemod.line('foo', content='test content', mode='insert')
assert '"location" or "before/after"' in six.text_type(cmd_err)
self.assertIn('"location" or "before/after"',
six.text_type(cmd_err))
def test_util_starts_till(self):
'''
@ -862,9 +866,12 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
:return:
'''
src = 'here is something'
assert 1 == filemod._starts_till(src=src, probe='here quite something else')
assert 0 == filemod._starts_till(src=src, probe='here is something')
assert -1 == filemod._starts_till(src=src, probe='and here is something')
self.assertEqual(
filemod._starts_till(src=src, probe='here quite something else'), 1)
self.assertEqual(
filemod._starts_till(src=src, probe='here is something'), 0)
self.assertEqual(
filemod._starts_till(src=src, probe='and here is something'), -1)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -876,16 +883,26 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
See issue #38670
:return:
'''
file_content = 'file_roots:\n base:\n - /srv/salt'
file_modified = 'file_roots:\n base:\n - /srv/salt\n - /srv/custom'
file_content = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt'
])
file_modified = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/custom'
])
cfg_content = '- /srv/custom'
files_fopen = mock_open(read_data=file_content)
with patch('salt.utils.files.fopen', files_fopen):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content=cfg_content, after='- /srv/salt', mode='insert')
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -897,18 +914,37 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
See issue #38670
:return:
'''
file_content = 'file_boots:\n - /rusty\nfile_roots:\n base:\n - /srv/salt\n - /srv/sugar'
file_modified = 'file_boots:\n - /rusty\nfile_roots:\n custom:\n ' \
'- /srv/custom\n base:\n - /srv/salt\n - /srv/sugar'
cfg_content = ' custom:\n - /srv/custom'
file_content = os.linesep.join([
'file_boots:',
' - /rusty',
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/sugar'
])
file_modified = os.linesep.join([
'file_boots:',
' - /rusty',
'file_roots:',
' custom:',
' - /srv/custom',
' base:',
' - /srv/salt',
' - /srv/sugar'
])
cfg_content = os.linesep.join([
' custom:',
' - /srv/custom'
])
for after_line in ['file_r.*', '.*roots']:
files_fopen = mock_open(read_data=file_content)
with patch('salt.utils.files.fopen', files_fopen):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content=cfg_content, after=after_line, mode='insert', indent=False)
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -920,8 +956,19 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
See issue #38670
:return:
'''
file_content = 'file_roots:\n base:\n - /srv/salt\n - /srv/sugar'
file_modified = 'file_roots:\n base:\n - /srv/custom\n - /srv/salt\n - /srv/sugar'
file_content = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/sugar'
])
file_modified = os.linesep.join([
'file_roots:',
' base:',
' - /srv/custom',
' - /srv/salt',
' - /srv/sugar'
])
cfg_content = '- /srv/custom'
for before_line in ['/srv/salt', '/srv/sa.*t', '/sr.*']:
files_fopen = mock_open(read_data=file_content)
@ -929,8 +976,9 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content=cfg_content, before=before_line, mode='insert')
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -942,9 +990,21 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
See issue #38670
:return:
'''
file_content = 'file_roots:\n base:\n - /srv/salt\n - /srv/pepper\n - /srv/sugar'
file_modified = 'file_roots:\n base:\n - /srv/salt\n ' \
'- /srv/pepper\n - /srv/coriander\n - /srv/sugar'
file_content = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/pepper',
' - /srv/sugar'
])
file_modified = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/pepper',
' - /srv/coriander',
' - /srv/sugar'
])
cfg_content = '- /srv/coriander'
for b_line, a_line in [('/srv/sugar', '/srv/salt')]:
files_fopen = mock_open(read_data=file_content)
@ -952,8 +1012,9 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content=cfg_content, before=b_line, after=a_line, mode='insert')
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -964,15 +1025,27 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
:return:
'''
cfg_content = 'everything: fantastic'
file_content = 'file_roots:\n base:\n - /srv/salt\n - /srv/sugar'
file_modified = '{0}\nfile_roots:\n base:\n - /srv/salt\n - /srv/sugar'.format(cfg_content)
file_content = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/sugar'
])
file_modified = os.linesep.join([
cfg_content,
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/sugar'
])
files_fopen = mock_open(read_data=file_content)
with patch('salt.utils.files.fopen', files_fopen):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content=cfg_content, location='start', mode='insert')
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -983,15 +1056,27 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
:return:
'''
cfg_content = 'everything: fantastic'
file_content = 'file_roots:\n base:\n - /srv/salt\n - /srv/sugar'
file_modified = 'file_roots:\n base:\n - /srv/salt\n - /srv/sugar\n{0}'.format(cfg_content)
file_content = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/sugar'
])
file_modified = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/sugar',
cfg_content
])
files_fopen = mock_open(read_data=file_content)
with patch('salt.utils.files.fopen', files_fopen):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content=cfg_content, location='end', mode='insert')
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -1002,15 +1087,25 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
:return:
'''
cfg_content = '/etc/init.d/someservice restart'
file_content = '#!/bin/bash\n\nexit 0'
file_modified = '#!/bin/bash\n\n{0}\nexit 0'.format(cfg_content)
file_content = os.linesep.join([
'#!/bin/bash',
'',
'exit 0'
])
file_modified = os.linesep.join([
'#!/bin/bash',
'',
cfg_content,
'exit 0'
])
files_fopen = mock_open(read_data=file_content)
with patch('salt.utils.files.fopen', files_fopen):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content=cfg_content, before='exit 0', mode='ensure')
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -1021,15 +1116,23 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
:return:
'''
cfg_content = 'exit 0'
file_content = '#!/bin/bash\n/etc/init.d/someservice restart'
file_modified = '#!/bin/bash\n/etc/init.d/someservice restart\n{0}'.format(cfg_content)
file_content = os.linesep.join([
'#!/bin/bash',
'/etc/init.d/someservice restart'
])
file_modified = os.linesep.join([
'#!/bin/bash',
'/etc/init.d/someservice restart',
cfg_content
])
files_fopen = mock_open(read_data=file_content)
with patch('salt.utils.files.fopen', files_fopen):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content=cfg_content, after='/etc/init.d/someservice restart', mode='ensure')
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -1041,7 +1144,10 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
'''
cfg_content = 'EXTRA_GROUPS="dialout cdrom floppy audio video plugdev users"'
# pylint: disable=W1401
file_content = 'NAME_REGEX="^[a-z][-a-z0-9_]*\$"\nSKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)"'
file_content = os.linesep.join([
'NAME_REGEX="^[a-z][-a-z0-9_]*\$"',
'SKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)"'
])
# pylint: enable=W1401
after, before = file_content.split(os.linesep)
file_modified = os.linesep.join([after, cfg_content, before])
@ -1051,8 +1157,9 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content=cfg_content, after=_after, before=_before, mode='ensure')
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -1064,8 +1171,11 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
'''
cfg_content = 'EXTRA_GROUPS="dialout"'
# pylint: disable=W1401
file_content = 'NAME_REGEX="^[a-z][-a-z0-9_]*\$"\nEXTRA_GROUPS="dialout"' \
'\nSKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)"'
file_content = os.linesep.join([
'NAME_REGEX="^[a-z][-a-z0-9_]*\$"',
'EXTRA_GROUPS="dialout"',
'SKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)"'
])
# pylint: enable=W1401
after, before = file_content.split(os.linesep)[0], file_content.split(os.linesep)[2]
for (_after, _before) in [(after, before), ('NAME_.*', 'SKEL_.*')]:
@ -1074,8 +1184,8 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
result = filemod.line('foo', content=cfg_content, after=_after, before=_before, mode='ensure')
assert 0 == len(atomic_opener().write.call_args_list)
assert not result
self.assertEqual(len(atomic_opener().write.call_args_list), 0)
self.assertEqual(result, False)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -1100,7 +1210,9 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
with pytest.raises(CommandExecutionError) as cmd_err:
filemod.line('foo', content=cfg_content, after=_after, before=_before, mode='ensure')
assert 'Found more than one line between boundaries "before" and "after"' in six.text_type(cmd_err)
self.assertIn(
'Found more than one line between boundaries "before" and "after"',
six.text_type(cmd_err))
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -1110,16 +1222,28 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
Test for file.line for deletion of specific line
:return:
'''
file_content = 'file_roots:\n base:\n - /srv/salt\n - /srv/pepper\n - /srv/sugar'
file_modified = 'file_roots:\n base:\n - /srv/salt\n - /srv/sugar'
file_content = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/pepper',
' - /srv/sugar'
])
file_modified = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/sugar'
])
for content in ['/srv/pepper', '/srv/pepp*', '/srv/p.*', '/sr.*pe.*']:
files_fopen = mock_open(read_data=file_content)
with patch('salt.utils.files.fopen', files_fopen):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content=content, mode='delete')
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
@patch('os.path.realpath', MagicMock())
@patch('os.path.isfile', MagicMock(return_value=True))
@ -1129,16 +1253,29 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
Test for file.line for replacement of specific line
:return:
'''
file_content = 'file_roots:\n base:\n - /srv/salt\n - /srv/pepper\n - /srv/sugar'
file_modified = 'file_roots:\n base:\n - /srv/salt\n - /srv/natrium-chloride\n - /srv/sugar'
file_content = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/pepper',
' - /srv/sugar'
])
file_modified = os.linesep.join([
'file_roots:',
' base:',
' - /srv/salt',
' - /srv/natrium-chloride',
' - /srv/sugar'
])
for match in ['/srv/pepper', '/srv/pepp*', '/srv/p.*', '/sr.*pe.*']:
files_fopen = mock_open(read_data=file_content)
with patch('salt.utils.files.fopen', files_fopen):
atomic_opener = mock_open()
with patch('salt.utils.atomicfile.atomic_open', atomic_opener):
filemod.line('foo', content='- /srv/natrium-chloride', match=match, mode='replace')
assert 1 == len(atomic_opener().write.call_args_list)
assert file_modified == atomic_opener().write.call_args_list[0][0][0]
self.assertEqual(len(atomic_opener().write.call_args_list), 1)
self.assertEqual(atomic_opener().write.call_args_list[0][0][0],
file_modified)
class FileBasicsTestCase(TestCase, LoaderModuleMockMixin):