# -*- coding: utf-8 -*- ''' :codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)` tests.unit.modules.archive_test ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ''' # Import Python libs from __future__ import absolute_import # 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, patch from salt.ext.six.moves import zip ensure_in_syspath('../../') # Import salt libs from salt.modules import archive from salt.exceptions import CommandNotFoundError from salt.utils import which_bin class ZipFileMock(MagicMock): def __init__(self, files=None, **kwargs): # pylint: disable=W0231 if files is None: files = ['salt'] MagicMock.__init__(self, **kwargs) self._files = files def namelist(self): return self._files # Globals archive.__salt__ = {} archive.__pillar__ = {} archive.__grains__ = {"id": "0"} archive.__opts__ = {} @skipIf(NO_MOCK, NO_MOCK_REASON) class ArchiveTestCase(TestCase): @patch('salt.utils.which', lambda exe: exe) def test_tar(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.tar( '-zcvf', 'foo.tar', ['/tmp/something-to-compress-1', '/tmp/something-to-compress-2'], template=None ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['tar', '-zcvf', 'foo.tar', '/tmp/something-to-compress-1', '/tmp/something-to-compress-2'], runas=None, python_shell=False, template=None, cwd=None ) mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.tar( '-zcvf', 'foo.tar', '/tmp/something-to-compress-1,/tmp/something-to-compress-2', template=None ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['tar', '-zcvf', 'foo.tar', '/tmp/something-to-compress-1', '/tmp/something-to-compress-2'], runas=None, python_shell=False, template=None, cwd=None ) @patch('salt.utils.which', lambda exe: None) def test_tar_raises_exception_if_not_found(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): self.assertRaises( CommandNotFoundError, archive.tar, 'zxvf', 'foo.tar', '/tmp/something-to-compress' ) self.assertFalse(mock.called) @patch('salt.utils.which', lambda exe: exe) def test_gzip(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.gzip('/tmp/something-to-compress') self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['gzip', '/tmp/something-to-compress'], runas=None, python_shell=False, template=None ) @patch('salt.utils.which', lambda exe: None) def test_gzip_raises_exception_if_not_found(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): self.assertRaises( CommandNotFoundError, archive.gzip, '/tmp/something-to-compress' ) self.assertFalse(mock.called) @patch('salt.utils.which', lambda exe: exe) def test_gunzip(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.gunzip('/tmp/something-to-decompress.tar.gz') self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['gunzip', '/tmp/something-to-decompress.tar.gz'], runas=None, python_shell=False, template=None ) @patch('salt.utils.which', lambda exe: None) def test_gunzip_raises_exception_if_not_found(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): self.assertRaises( CommandNotFoundError, archive.gunzip, '/tmp/something-to-decompress.tar.gz' ) self.assertFalse(mock.called) @patch('salt.utils.which', lambda exe: exe) def test_cmd_zip(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.cmd_zip( '/tmp/salt.{{grains.id}}.zip', '/tmp/tmpePe8yO,/tmp/tmpLeSw1A', template='jinja' ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['zip', '-r', '/tmp/salt.{{grains.id}}.zip', '/tmp/tmpePe8yO', '/tmp/tmpLeSw1A'], runas=None, python_shell=False, template='jinja', cwd=None ) mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.cmd_zip( '/tmp/salt.{{grains.id}}.zip', ['/tmp/tmpePe8yO', '/tmp/tmpLeSw1A'], template='jinja' ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['zip', '-r', '/tmp/salt.{{grains.id}}.zip', '/tmp/tmpePe8yO', '/tmp/tmpLeSw1A'], runas=None, python_shell=False, template='jinja', cwd=None ) @patch('os.path.exists', MagicMock(return_value=True)) @patch('os.path.isdir', MagicMock(return_value=False)) @patch('zipfile.ZipFile', MagicMock()) def test_zip(self): ret = archive.zip_( '/tmp/salt.{{grains.id}}.zip', '/tmp/tmpePe8yO,/tmp/tmpLeSw1A', template='jinja' ) self.assertEqual(['tmp/tmpePe8yO', 'tmp/tmpLeSw1A'], ret) @patch('salt.utils.which', lambda exe: None) def test_zip_raises_exception_if_not_found(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): self.assertRaises( CommandNotFoundError, archive.cmd_zip, '/tmp/salt.{{grains.id}}.zip', '/tmp/tmpePe8yO,/tmp/tmpLeSw1A', template='jinja', ) self.assertFalse(mock.called) @patch('salt.utils.which', lambda exe: exe) def test_cmd_unzip(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.cmd_unzip( '/tmp/salt.{{grains.id}}.zip', '/tmp/dest', excludes='/tmp/tmpePe8yO,/tmp/tmpLeSw1A', template='jinja' ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['unzip', '/tmp/salt.{{grains.id}}.zip', '-d', '/tmp/dest', '-x', '/tmp/tmpePe8yO', '/tmp/tmpLeSw1A'], runas=None, python_shell=False, template='jinja' ) mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.cmd_unzip( '/tmp/salt.{{grains.id}}.zip', '/tmp/dest', excludes=['/tmp/tmpePe8yO', '/tmp/tmpLeSw1A'], template='jinja' ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['unzip', '/tmp/salt.{{grains.id}}.zip', '-d', '/tmp/dest', '-x', '/tmp/tmpePe8yO', '/tmp/tmpLeSw1A'], runas=None, python_shell=False, template='jinja' ) mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.cmd_unzip( '/tmp/salt.{{grains.id}}.zip', '/tmp/dest', excludes='/tmp/tmpePe8yO,/tmp/tmpLeSw1A', template='jinja', options='-fo' ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['unzip', '-fo', '/tmp/salt.{{grains.id}}.zip', '-d', '/tmp/dest', '-x', '/tmp/tmpePe8yO', '/tmp/tmpLeSw1A'], runas=None, python_shell=False, template='jinja' ) mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.cmd_unzip( '/tmp/salt.{{grains.id}}.zip', '/tmp/dest', excludes=['/tmp/tmpePe8yO', '/tmp/tmpLeSw1A'], template='jinja', options='-fo' ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['unzip', '-fo', '/tmp/salt.{{grains.id}}.zip', '-d', '/tmp/dest', '-x', '/tmp/tmpePe8yO', '/tmp/tmpLeSw1A'], runas=None, python_shell=False, template='jinja' ) def test_unzip(self): mock = ZipFileMock() with patch('zipfile.ZipFile', mock): ret = archive.unzip( '/tmp/salt.{{grains.id}}.zip', '/tmp/dest', excludes='/tmp/tmpePe8yO,/tmp/tmpLeSw1A', template='jinja' ) self.assertEqual(['salt'], ret) @patch('salt.utils.which', lambda exe: None) def test_unzip_raises_exception_if_not_found(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): self.assertRaises( CommandNotFoundError, archive.cmd_unzip, '/tmp/salt.{{grains.id}}.zip', '/tmp/dest', excludes='/tmp/tmpePe8yO,/tmp/tmpLeSw1A', template='jinja', ) self.assertFalse(mock.called) @patch('salt.utils.which', lambda exe: exe) def test_rar(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.rar( '/tmp/rarfile.rar', '/tmp/sourcefile1,/tmp/sourcefile2' ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['rar', 'a', '-idp', '/tmp/rarfile.rar', '/tmp/sourcefile1', '/tmp/sourcefile2'], runas=None, python_shell=False, template=None, cwd=None ) mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.rar( '/tmp/rarfile.rar', ['/tmp/sourcefile1', '/tmp/sourcefile2'] ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['rar', 'a', '-idp', '/tmp/rarfile.rar', '/tmp/sourcefile1', '/tmp/sourcefile2'], runas=None, python_shell=False, template=None, cwd=None ) @patch('salt.utils.which', lambda exe: None) def test_rar_raises_exception_if_not_found(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): self.assertRaises( CommandNotFoundError, archive.rar, '/tmp/rarfile.rar', '/tmp/sourcefile1,/tmp/sourcefile2' ) self.assertFalse(mock.called) @skipIf(which_bin(('unrar', 'rar')) is None, 'unrar not installed') @patch('salt.utils.which', lambda exe: exe[0] if isinstance(exe, (list, tuple)) else exe) @patch('salt.utils.which_bin', lambda exe: exe[0] if isinstance(exe, (list, tuple)) else exe) def test_unrar(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.unrar( '/tmp/rarfile.rar', '/home/strongbad/', excludes='file_1,file_2' ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['unrar', 'x', '-idp', '/tmp/rarfile.rar', '-x', 'file_1', '-x', 'file_2', '/home/strongbad/'], runas=None, python_shell=False, template=None ) mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): ret = archive.unrar( '/tmp/rarfile.rar', '/home/strongbad/', excludes=['file_1', 'file_2'] ) self.assertEqual(['salt'], ret) mock.assert_called_once_with( ['unrar', 'x', '-idp', '/tmp/rarfile.rar', '-x', 'file_1', '-x', 'file_2', '/home/strongbad/'], runas=None, python_shell=False, template=None ) @patch('salt.utils.which_bin', lambda exe: None) def test_unrar_raises_exception_if_not_found(self): mock = MagicMock(return_value='salt') with patch.dict(archive.__salt__, {'cmd.run': mock}): self.assertRaises( CommandNotFoundError, archive.unrar, '/tmp/rarfile.rar', '/home/strongbad/', ) self.assertFalse(mock.called) @patch('salt.utils.which_bin', lambda exe: exe) def test_trim_files(self): source = 'file.tar.gz' tmp_dir = 'temp' files = [ '\n'.join(['file1'] * 200), '\n'.join(['file2'] * 200), 'this\nthat\nother', 'this\nthat\nother', 'this\nthat\nother' ] trim_opt = [ True, False, 3, 1, 0 ] trim_100 = (['file1'] * 100) trim_100.append("List trimmed after 100 files.") expected = [ trim_100, ['file2'] * 200, ['this', 'that', 'other'], ['this', 'List trimmed after 1 files.'], ['List trimmed after 0 files.'], ] for test_files, test_trim_opts, test_expected in zip(files, trim_opt, expected): with patch.dict(archive.__salt__, {'cmd.run': MagicMock(return_value=test_files)}): ret = archive.unrar(source, tmp_dir, trim_output=test_trim_opts) self.assertEqual(ret, test_expected) if __name__ == '__main__': from integration import run_tests run_tests(ArchiveTestCase, needs_daemon=False)