123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548 |
- import os.path
- import pytest
- import salt.modules.archive as archive
- from salt.exceptions import CommandNotFoundError
- from tests.support.mock import MagicMock, patch
- 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
- self.external_attr = 0o0777 << 16
- def namelist(self):
- return self._files
- @pytest.fixture(autouse=True)
- def setup_loader():
- setup_loader_modules = {archive: {"__grains__": {"id": 0}}}
- with pytest.helpers.loader_mock(setup_loader_modules) as loader_mock:
- yield loader_mock
- def test_tar():
- with patch("glob.glob", lambda pathname: [pathname]):
- with patch("salt.utils.path.which", lambda exe: exe):
- 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,
- )
- assert ["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,
- )
- assert ["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,
- )
- def test_tar_raises_exception_if_not_found():
- with patch("salt.utils.path.which", lambda exe: None):
- mock = MagicMock(return_value="salt")
- with patch.dict(archive.__salt__, {"cmd.run": mock}):
- with pytest.raises(CommandNotFoundError):
- archive.tar("zxvf", "foo.tar", "/tmp/something-to-compress")
- assert not mock.called
- def test_gzip():
- mock = MagicMock(return_value="salt")
- with patch.dict(archive.__salt__, {"cmd.run": mock}):
- with patch("salt.utils.path.which", lambda exe: exe):
- ret = archive.gzip("/tmp/something-to-compress")
- assert ["salt"] == ret
- mock.assert_called_once_with(
- ["gzip", "/tmp/something-to-compress"],
- runas=None,
- python_shell=False,
- template=None,
- )
- def test_gzip_raises_exception_if_not_found():
- mock = MagicMock(return_value="salt")
- with patch.dict(archive.__salt__, {"cmd.run": mock}):
- with patch("salt.utils.path.which", lambda exe: None):
- with pytest.raises(CommandNotFoundError):
- archive.gzip("/tmp/something-to-compress")
- assert not mock.called
- def test_gunzip():
- mock = MagicMock(return_value="salt")
- with patch.dict(archive.__salt__, {"cmd.run": mock}):
- with patch("salt.utils.path.which", lambda exe: exe):
- ret = archive.gunzip("/tmp/something-to-decompress.tar.gz")
- assert ["salt"] == ret
- mock.assert_called_once_with(
- ["gunzip", "/tmp/something-to-decompress.tar.gz"],
- runas=None,
- python_shell=False,
- template=None,
- )
- def test_gunzip_raises_exception_if_not_found():
- mock = MagicMock(return_value="salt")
- with patch.dict(archive.__salt__, {"cmd.run": mock}):
- with patch("salt.utils.path.which", lambda exe: None):
- with pytest.raises(CommandNotFoundError):
- archive.gunzip("/tmp/something-to-decompress.tar.gz")
- assert not mock.called
- def test_cmd_zip():
- with patch("glob.glob", lambda pathname: [pathname]):
- with patch("salt.utils.path.which", lambda exe: exe):
- 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",
- )
- assert ["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",
- )
- assert ["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,
- )
- def test_zip():
- with patch("glob.glob", lambda pathname: [pathname]):
- with patch.multiple(
- os.path,
- **{
- "isdir": MagicMock(return_value=False),
- "exists": MagicMock(return_value=True),
- }
- ):
- with patch("zipfile.ZipFile", MagicMock()):
- ret = archive.zip_(
- "/tmp/salt.{{grains.id}}.zip",
- "/tmp/tmpePe8yO,/tmp/tmpLeSw1A",
- template="jinja",
- )
- expected = [
- os.path.join("tmp", "tmpePe8yO"),
- os.path.join("tmp", "tmpLeSw1A"),
- ]
- assert expected == ret
- def test_zip_raises_exception_if_not_found():
- mock = MagicMock(return_value="salt")
- with patch.dict(archive.__salt__, {"cmd.run": mock}):
- with patch("salt.utils.path.which", lambda exe: None):
- with pytest.raises(CommandNotFoundError):
- archive.cmd_zip(
- "/tmp/salt.{{grains.id}}.zip",
- "/tmp/tmpePe8yO,/tmp/tmpLeSw1A",
- template="jinja",
- )
- assert not mock.called
- def test_cmd_unzip():
- def _get_mock():
- """
- Create a new MagicMock for each scenario in this test, so that
- assert_called_once_with doesn't complain that the same mock object
- is called more than once.
- """
- return MagicMock(
- return_value={"stdout": "salt", "stderr": "", "pid": 12345, "retcode": 0}
- )
- with patch("salt.utils.path.which", lambda exe: exe):
- mock = _get_mock()
- with patch.dict(archive.__salt__, {"cmd.run_all": mock}):
- ret = archive.cmd_unzip(
- "/tmp/salt.{{grains.id}}.zip",
- "/tmp/dest",
- excludes="/tmp/tmpePe8yO,/tmp/tmpLeSw1A",
- template="jinja",
- )
- assert ["salt"] == ret
- mock.assert_called_once_with(
- [
- "unzip",
- "/tmp/salt.{{grains.id}}.zip",
- "-d",
- "/tmp/dest",
- "-x",
- "/tmp/tmpePe8yO",
- "/tmp/tmpLeSw1A",
- ],
- output_loglevel="debug",
- python_shell=False,
- redirect_stderr=True,
- runas=None,
- template="jinja",
- )
- mock = _get_mock()
- with patch.dict(archive.__salt__, {"cmd.run_all": mock}):
- ret = archive.cmd_unzip(
- "/tmp/salt.{{grains.id}}.zip",
- "/tmp/dest",
- excludes=["/tmp/tmpePe8yO", "/tmp/tmpLeSw1A"],
- template="jinja",
- )
- assert ["salt"] == ret
- mock.assert_called_once_with(
- [
- "unzip",
- "/tmp/salt.{{grains.id}}.zip",
- "-d",
- "/tmp/dest",
- "-x",
- "/tmp/tmpePe8yO",
- "/tmp/tmpLeSw1A",
- ],
- output_loglevel="debug",
- python_shell=False,
- redirect_stderr=True,
- runas=None,
- template="jinja",
- )
- mock = _get_mock()
- with patch.dict(archive.__salt__, {"cmd.run_all": mock}):
- ret = archive.cmd_unzip(
- "/tmp/salt.{{grains.id}}.zip",
- "/tmp/dest",
- excludes="/tmp/tmpePe8yO,/tmp/tmpLeSw1A",
- template="jinja",
- options="-fo",
- )
- assert ["salt"] == ret
- mock.assert_called_once_with(
- [
- "unzip",
- "-fo",
- "/tmp/salt.{{grains.id}}.zip",
- "-d",
- "/tmp/dest",
- "-x",
- "/tmp/tmpePe8yO",
- "/tmp/tmpLeSw1A",
- ],
- output_loglevel="debug",
- python_shell=False,
- redirect_stderr=True,
- runas=None,
- template="jinja",
- )
- mock = _get_mock()
- with patch.dict(archive.__salt__, {"cmd.run_all": mock}):
- ret = archive.cmd_unzip(
- "/tmp/salt.{{grains.id}}.zip",
- "/tmp/dest",
- excludes=["/tmp/tmpePe8yO", "/tmp/tmpLeSw1A"],
- template="jinja",
- options="-fo",
- )
- assert ["salt"] == ret
- mock.assert_called_once_with(
- [
- "unzip",
- "-fo",
- "/tmp/salt.{{grains.id}}.zip",
- "-d",
- "/tmp/dest",
- "-x",
- "/tmp/tmpePe8yO",
- "/tmp/tmpLeSw1A",
- ],
- output_loglevel="debug",
- python_shell=False,
- redirect_stderr=True,
- runas=None,
- template="jinja",
- )
- mock = _get_mock()
- with patch.dict(archive.__salt__, {"cmd.run_all": mock}):
- ret = archive.cmd_unzip(
- "/tmp/salt.{{grains.id}}.zip",
- "/tmp/dest",
- excludes=["/tmp/tmpePe8yO", "/tmp/tmpLeSw1A"],
- template="jinja",
- options="-fo",
- password="asdf",
- )
- assert ["salt"] == ret
- mock.assert_called_once_with(
- [
- "unzip",
- "-P",
- "asdf",
- "-fo",
- "/tmp/salt.{{grains.id}}.zip",
- "-d",
- "/tmp/dest",
- "-x",
- "/tmp/tmpePe8yO",
- "/tmp/tmpLeSw1A",
- ],
- output_loglevel="quiet",
- python_shell=False,
- redirect_stderr=True,
- runas=None,
- template="jinja",
- )
- def test_unzip():
- mock = ZipFileMock()
- with patch("zipfile.ZipFile", mock):
- ret = archive.unzip(
- "/tmp/salt.{{grains.id}}.zip",
- "/tmp/dest",
- excludes="/tmp/tmpePe8yO,/tmp/tmpLeSw1A",
- template="jinja",
- extract_perms=False,
- )
- assert ["salt"] == ret
- def test_unzip_raises_exception_if_not_found():
- mock = MagicMock(return_value="salt")
- with patch.dict(archive.__salt__, {"cmd.run": mock}):
- with patch("salt.utils.path.which", lambda exe: None):
- with pytest.raises(CommandNotFoundError):
- archive.cmd_unzip(
- "/tmp/salt.{{grains.id}}.zip",
- "/tmp/dest",
- excludes="/tmp/tmpePe8yO,/tmp/tmpLeSw1A",
- template="jinja",
- )
- assert not mock.called
- def test_rar():
- with patch("glob.glob", lambda pathname: [pathname]):
- with patch("salt.utils.path.which", lambda exe: exe):
- mock = MagicMock(return_value="salt")
- with patch.dict(archive.__salt__, {"cmd.run": mock}):
- ret = archive.rar(
- "/tmp/rarfile.rar", "/tmp/sourcefile1,/tmp/sourcefile2"
- )
- assert ["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"]
- )
- assert ["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,
- )
- def test_rar_raises_exception_if_not_found():
- mock = MagicMock(return_value="salt")
- with patch.dict(archive.__salt__, {"cmd.run": mock}):
- with patch("salt.utils.path.which", lambda exe: None):
- with pytest.raises(CommandNotFoundError):
- archive.rar("/tmp/rarfile.rar", "/tmp/sourcefile1,/tmp/sourcefile2")
- assert not mock.called
- @pytest.mark.skip_if_binaries_missing("unrar", "rar", message="unrar not installed")
- def test_unrar():
- with patch(
- "salt.utils.path.which_bin",
- lambda exe: exe[0] if isinstance(exe, (list, tuple)) else exe,
- ):
- with patch(
- "salt.utils.path.which",
- lambda exe: exe[0] if isinstance(exe, (list, tuple)) else exe,
- ):
- 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"
- )
- assert ["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"],
- )
- assert ["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,
- )
- def test_unrar_raises_exception_if_not_found():
- with patch("salt.utils.path.which_bin", lambda exe: None):
- mock = MagicMock(return_value="salt")
- with patch.dict(archive.__salt__, {"cmd.run": mock}):
- with pytest.raises(CommandNotFoundError):
- archive.unrar(
- "/tmp/rarfile.rar", "/home/strongbad/",
- )
- assert not mock.called
- def test_trim_files():
- with patch("salt.utils.path.which_bin", lambda exe: exe):
- 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)
- assert ret == test_expected
|