2015-02-09 14:52:46 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
'''
|
2018-05-28 21:13:12 +00:00
|
|
|
:codeauthor: Alexander Schwartz <alexander.schwartz@gmx.net>
|
2015-02-09 14:52:46 +00:00
|
|
|
'''
|
|
|
|
|
|
|
|
# Import python libs
|
|
|
|
from __future__ import absolute_import
|
2015-03-17 23:24:02 +00:00
|
|
|
import os
|
2015-02-09 14:52:46 +00:00
|
|
|
|
|
|
|
# Import Salt Testing libs
|
2017-02-19 15:35:30 +00:00
|
|
|
from tests.support.mixins import LoaderModuleMockMixin
|
2017-02-27 13:58:07 +00:00
|
|
|
from tests.support.unit import TestCase, skipIf
|
|
|
|
from tests.support.mock import (
|
2015-03-23 21:45:40 +00:00
|
|
|
NO_MOCK,
|
|
|
|
NO_MOCK_REASON,
|
|
|
|
MagicMock,
|
|
|
|
patch
|
|
|
|
)
|
2015-02-09 14:52:46 +00:00
|
|
|
|
2015-03-21 02:09:19 +00:00
|
|
|
# Import Salt Libs
|
2017-03-21 17:15:36 +00:00
|
|
|
import salt.states.archive as archive
|
2015-03-23 21:45:40 +00:00
|
|
|
from salt.ext.six.moves import zip # pylint: disable=import-error,redefined-builtin
|
2017-09-29 18:11:56 +00:00
|
|
|
import salt.utils
|
2015-02-09 14:52:46 +00:00
|
|
|
|
2015-02-11 19:57:14 +00:00
|
|
|
|
2016-12-19 21:37:58 +00:00
|
|
|
def _isfile_side_effect(path):
|
|
|
|
'''
|
|
|
|
MagicMock side_effect for os.path.isfile(). We don't want to use dict.get
|
|
|
|
here because we want the test to fail if there's a path we haven't
|
|
|
|
accounted for, so that we can add it.
|
|
|
|
|
|
|
|
NOTE: This may fall over on some platforms if /usr/bin/tar does not exist.
|
|
|
|
If so, just add an entry in the dictionary for the path being used for tar.
|
|
|
|
'''
|
|
|
|
return {
|
2017-10-23 17:39:12 +00:00
|
|
|
'/tmp/foo.tar.gz': True,
|
|
|
|
'c:\\tmp\\foo.tar.gz': True,
|
2018-01-17 18:54:35 +00:00
|
|
|
'/private/tmp/foo.tar.gz': True,
|
2017-10-23 17:39:12 +00:00
|
|
|
'/tmp/out': False,
|
|
|
|
'\\tmp\\out': False,
|
|
|
|
'/usr/bin/tar': True,
|
|
|
|
'/bin/tar': True,
|
|
|
|
'/tmp/test_extracted_tar': False,
|
|
|
|
'c:\\tmp\\test_extracted_tar': False,
|
2018-01-17 18:54:35 +00:00
|
|
|
'/private/tmp/test_extracted_tar': False,
|
2016-12-19 21:37:58 +00:00
|
|
|
}[path]
|
|
|
|
|
|
|
|
|
2015-02-09 14:52:46 +00:00
|
|
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
2017-02-19 15:35:30 +00:00
|
|
|
class ArchiveTestCase(TestCase, LoaderModuleMockMixin):
|
2015-02-09 14:52:46 +00:00
|
|
|
|
2017-03-22 12:12:36 +00:00
|
|
|
def setup_loader_modules(self):
|
2017-02-19 15:35:30 +00:00
|
|
|
return {
|
2017-03-22 12:12:36 +00:00
|
|
|
archive: {
|
|
|
|
'__grains__': {'os': 'FooOS!'},
|
2017-04-13 16:14:51 +00:00
|
|
|
'__opts__': {'cachedir': '/tmp',
|
|
|
|
'test': False,
|
|
|
|
'hash_type': 'sha256'},
|
2017-03-22 12:12:36 +00:00
|
|
|
'__env__': 'test'
|
|
|
|
}
|
2017-02-19 15:35:30 +00:00
|
|
|
}
|
2015-02-09 14:52:46 +00:00
|
|
|
|
2015-03-17 23:24:02 +00:00
|
|
|
def test_extracted_tar(self):
|
|
|
|
'''
|
|
|
|
archive.extracted tar options
|
|
|
|
'''
|
|
|
|
|
2017-09-29 18:11:56 +00:00
|
|
|
if salt.utils.is_windows():
|
2017-10-23 17:39:12 +00:00
|
|
|
source = 'c:\\tmp\\foo.tar.gz'
|
|
|
|
tmp_dir = 'c:\\tmp\\test_extracted_tar'
|
2018-01-17 18:54:35 +00:00
|
|
|
elif salt.utils.is_darwin():
|
|
|
|
source = '/private/tmp/foo.tar.gz'
|
|
|
|
tmp_dir = '/private/tmp/test_extracted_tar'
|
2017-10-23 17:39:12 +00:00
|
|
|
else:
|
|
|
|
source = '/tmp/foo.tar.gz'
|
|
|
|
tmp_dir = '/tmp/test_extracted_tar'
|
2015-03-17 23:24:02 +00:00
|
|
|
test_tar_opts = [
|
|
|
|
'--no-anchored foo',
|
|
|
|
'v -p --opt',
|
|
|
|
'-v -p',
|
|
|
|
'--long-opt -z',
|
|
|
|
'z -v -weird-long-opt arg',
|
|
|
|
]
|
|
|
|
ret_tar_opts = [
|
|
|
|
['tar', 'x', '--no-anchored', 'foo', '-f'],
|
|
|
|
['tar', 'xv', '-p', '--opt', '-f'],
|
|
|
|
['tar', 'x', '-v', '-p', '-f'],
|
|
|
|
['tar', 'x', '--long-opt', '-z', '-f'],
|
|
|
|
['tar', 'xz', '-v', '-weird-long-opt', 'arg', '-f'],
|
|
|
|
]
|
|
|
|
|
|
|
|
mock_true = MagicMock(return_value=True)
|
|
|
|
mock_false = MagicMock(return_value=False)
|
2017-01-20 14:49:40 +00:00
|
|
|
ret = {'stdout': ['cheese', 'ham', 'saltines'], 'stderr': 'biscuits', 'retcode': '31337', 'pid': '1337'}
|
2015-03-17 23:24:02 +00:00
|
|
|
mock_run = MagicMock(return_value=ret)
|
2016-11-01 09:09:16 +00:00
|
|
|
mock_source_list = MagicMock(return_value=(source, None))
|
|
|
|
state_single_mock = MagicMock(return_value={'local': {'result': True}})
|
|
|
|
list_mock = MagicMock(return_value={
|
|
|
|
'dirs': [],
|
2017-01-20 14:49:40 +00:00
|
|
|
'files': ['cheese', 'saltines'],
|
|
|
|
'links': ['ham'],
|
2016-11-01 09:09:16 +00:00
|
|
|
'top_level_dirs': [],
|
2017-01-20 14:49:40 +00:00
|
|
|
'top_level_files': ['cheese', 'saltines'],
|
|
|
|
'top_level_links': ['ham'],
|
2016-11-01 09:09:16 +00:00
|
|
|
})
|
2016-12-19 21:37:58 +00:00
|
|
|
isfile_mock = MagicMock(side_effect=_isfile_side_effect)
|
2016-11-01 09:09:16 +00:00
|
|
|
|
|
|
|
with patch.dict(archive.__opts__, {'test': False,
|
2017-04-13 16:14:51 +00:00
|
|
|
'cachedir': tmp_dir,
|
2017-11-09 21:31:38 +00:00
|
|
|
'hash_type': 'sha256'}),\
|
|
|
|
patch.dict(archive.__salt__, {'file.directory_exists': mock_false,
|
|
|
|
'file.file_exists': mock_false,
|
|
|
|
'state.single': state_single_mock,
|
|
|
|
'file.makedirs': mock_true,
|
|
|
|
'cmd.run_all': mock_run,
|
|
|
|
'archive.list': list_mock,
|
|
|
|
'file.source_list': mock_source_list}),\
|
|
|
|
patch.dict(archive.__states__, {'file.directory': mock_true}),\
|
|
|
|
patch.object(os.path, 'isfile', isfile_mock),\
|
|
|
|
patch('salt.utils.which', MagicMock(return_value=True)):
|
|
|
|
|
|
|
|
for test_opts, ret_opts in zip(test_tar_opts, ret_tar_opts):
|
|
|
|
archive.extracted(tmp_dir, source, options=test_opts,
|
|
|
|
enforce_toplevel=False)
|
|
|
|
ret_opts.append(source)
|
|
|
|
mock_run.assert_called_with(ret_opts, cwd=tmp_dir + os.sep,
|
|
|
|
python_shell=False)
|
2015-03-17 23:24:02 +00:00
|
|
|
|
2015-02-09 14:52:46 +00:00
|
|
|
def test_tar_gnutar(self):
|
|
|
|
'''
|
|
|
|
Tests the call of extraction with gnutar
|
|
|
|
'''
|
2015-02-11 19:57:14 +00:00
|
|
|
gnutar = MagicMock(return_value='tar (GNU tar)')
|
2017-10-23 17:39:12 +00:00
|
|
|
source = '/tmp/foo.tar.gz'
|
2016-12-19 21:37:58 +00:00
|
|
|
mock_false = MagicMock(return_value=False)
|
|
|
|
mock_true = MagicMock(return_value=True)
|
2016-11-01 09:09:16 +00:00
|
|
|
state_single_mock = MagicMock(return_value={'local': {'result': True}})
|
2015-02-11 19:57:14 +00:00
|
|
|
run_all = MagicMock(return_value={'retcode': 0, 'stdout': 'stdout', 'stderr': 'stderr'})
|
2016-11-01 09:09:16 +00:00
|
|
|
mock_source_list = MagicMock(return_value=(source, None))
|
|
|
|
list_mock = MagicMock(return_value={
|
|
|
|
'dirs': [],
|
|
|
|
'files': ['stdout'],
|
2017-01-20 14:49:40 +00:00
|
|
|
'links': [],
|
2016-11-01 09:09:16 +00:00
|
|
|
'top_level_dirs': [],
|
|
|
|
'top_level_files': ['stdout'],
|
2017-01-20 14:49:40 +00:00
|
|
|
'top_level_links': [],
|
2016-11-01 09:09:16 +00:00
|
|
|
})
|
2016-12-19 21:37:58 +00:00
|
|
|
isfile_mock = MagicMock(side_effect=_isfile_side_effect)
|
2016-04-26 16:39:43 +00:00
|
|
|
|
|
|
|
with patch.dict(archive.__salt__, {'cmd.run': gnutar,
|
2016-12-19 21:37:58 +00:00
|
|
|
'file.directory_exists': mock_false,
|
|
|
|
'file.file_exists': mock_false,
|
2016-11-01 09:09:16 +00:00
|
|
|
'state.single': state_single_mock,
|
2016-12-19 21:37:58 +00:00
|
|
|
'file.makedirs': mock_true,
|
2016-04-26 16:39:43 +00:00
|
|
|
'cmd.run_all': run_all,
|
2016-11-01 09:09:16 +00:00
|
|
|
'archive.list': list_mock,
|
2017-11-09 21:31:38 +00:00
|
|
|
'file.source_list': mock_source_list}),\
|
|
|
|
patch.dict(archive.__states__, {'file.directory': mock_true}),\
|
|
|
|
patch.object(os.path, 'isfile', isfile_mock),\
|
|
|
|
patch('salt.utils.which', MagicMock(return_value=True)):
|
|
|
|
ret = archive.extracted(os.path.join(os.sep + 'tmp', 'out'),
|
|
|
|
source,
|
|
|
|
options='xvzf',
|
|
|
|
enforce_toplevel=False,
|
|
|
|
keep=True)
|
|
|
|
self.assertEqual(ret['changes']['extracted_files'], 'stdout')
|
2015-02-09 14:52:46 +00:00
|
|
|
|
|
|
|
def test_tar_bsdtar(self):
|
|
|
|
'''
|
|
|
|
Tests the call of extraction with bsdtar
|
|
|
|
'''
|
2015-02-11 19:57:14 +00:00
|
|
|
bsdtar = MagicMock(return_value='tar (bsdtar)')
|
2017-10-23 17:39:12 +00:00
|
|
|
source = '/tmp/foo.tar.gz'
|
2016-12-19 21:37:58 +00:00
|
|
|
mock_false = MagicMock(return_value=False)
|
|
|
|
mock_true = MagicMock(return_value=True)
|
2016-11-01 09:09:16 +00:00
|
|
|
state_single_mock = MagicMock(return_value={'local': {'result': True}})
|
2015-02-11 19:57:14 +00:00
|
|
|
run_all = MagicMock(return_value={'retcode': 0, 'stdout': 'stdout', 'stderr': 'stderr'})
|
2016-11-01 09:09:16 +00:00
|
|
|
mock_source_list = MagicMock(return_value=(source, None))
|
|
|
|
list_mock = MagicMock(return_value={
|
|
|
|
'dirs': [],
|
|
|
|
'files': ['stderr'],
|
2017-01-20 14:49:40 +00:00
|
|
|
'links': [],
|
2016-11-01 09:09:16 +00:00
|
|
|
'top_level_dirs': [],
|
|
|
|
'top_level_files': ['stderr'],
|
2017-01-20 14:49:40 +00:00
|
|
|
'top_level_links': [],
|
2016-11-01 09:09:16 +00:00
|
|
|
})
|
2016-12-19 21:37:58 +00:00
|
|
|
isfile_mock = MagicMock(side_effect=_isfile_side_effect)
|
2016-04-26 16:39:43 +00:00
|
|
|
|
|
|
|
with patch.dict(archive.__salt__, {'cmd.run': bsdtar,
|
2016-12-19 21:37:58 +00:00
|
|
|
'file.directory_exists': mock_false,
|
|
|
|
'file.file_exists': mock_false,
|
2016-11-01 09:09:16 +00:00
|
|
|
'state.single': state_single_mock,
|
2016-12-19 21:37:58 +00:00
|
|
|
'file.makedirs': mock_true,
|
2016-04-26 16:39:43 +00:00
|
|
|
'cmd.run_all': run_all,
|
2016-11-01 09:09:16 +00:00
|
|
|
'archive.list': list_mock,
|
2017-11-09 21:31:38 +00:00
|
|
|
'file.source_list': mock_source_list}),\
|
|
|
|
patch.dict(archive.__states__, {'file.directory': mock_true}),\
|
|
|
|
patch.object(os.path, 'isfile', isfile_mock),\
|
|
|
|
patch('salt.utils.which', MagicMock(return_value=True)):
|
|
|
|
ret = archive.extracted(os.path.join(os.sep + 'tmp', 'out'),
|
|
|
|
source,
|
|
|
|
options='xvzf',
|
|
|
|
enforce_toplevel=False,
|
|
|
|
keep=True)
|
|
|
|
self.assertEqual(ret['changes']['extracted_files'], 'stderr')
|
2018-02-28 01:52:21 +00:00
|
|
|
|
|
|
|
def test_extracted_when_if_missing_path_exists(self):
|
|
|
|
'''
|
|
|
|
When if_missing exists, we should exit without making any changes.
|
|
|
|
|
|
|
|
NOTE: We're not mocking the __salt__ dunder because if we actually run
|
|
|
|
any functions from that dunder, we're doing something wrong. So, in
|
|
|
|
those cases we'll just let it raise a KeyError and cause the test to
|
|
|
|
fail.
|
|
|
|
'''
|
|
|
|
name = if_missing = '/tmp/foo'
|
|
|
|
source = 'salt://foo.bar.tar'
|
|
|
|
with patch.object(os.path, 'exists', MagicMock(return_value=True)):
|
|
|
|
ret = archive.extracted(
|
|
|
|
name,
|
|
|
|
source=source,
|
|
|
|
if_missing=if_missing)
|
|
|
|
self.assertTrue(ret['result'], ret)
|
|
|
|
self.assertEqual(
|
|
|
|
ret['comment'],
|
|
|
|
'Path {0} exists'.format(if_missing)
|
|
|
|
)
|