DownloadAndArchivePythonLibrary

The script downloads a Python library using PIP, archives it, and returns the file to the war room.

python · Common Scripts

Details

IDDownloadAndArchivePythonLibrary
Languagepython
From Version6.10.0
Docker Imagedemisto/py3-tools:1.0.0.11597437
TagsUtility file

README

The script downloads a Python library using PIP, archives it and return in to the war room.

Script Data


Name Description
Script Type python3
Tags Utility, file
Cortex XSOAR Version 6.10.0

Inputs


Argument Name Description
library_name The Python library you wish to download and archive.

Outputs


There are no outputs for this script.

import subprocess
import unittest
import zipfile
from pathlib import Path
from unittest.mock import MagicMock, mock_open, patch

# Import the functions from the script
from DownloadAndArchivePythonLibrary import installLibrary, main


class TestInstallLibrary(unittest.TestCase):
    @patch("DownloadAndArchivePythonLibrary.subprocess.Popen")
    @patch("DownloadAndArchivePythonLibrary.zipfile.ZipFile")
    @patch("DownloadAndArchivePythonLibrary.os.walk")
    @patch("DownloadAndArchivePythonLibrary.mkdtemp")
    @patch("DownloadAndArchivePythonLibrary.open", new_callable=mock_open, read_data=b"test data")
    @patch("DownloadAndArchivePythonLibrary.fileResult")
    def test_installLibrary(self, mock_fileResult, mock_open, mock_mkdtemp, mock_os_walk, mock_zipfile, mock_popen):
        # Prepare
        mock_dir_path = Path("/fake/dir")
        mock_mkdtemp.return_value = mock_dir_path

        mock_popen_instance = MagicMock()
        mock_popen_instance.communicate.return_value = (b"success", b"")
        mock_popen_instance.returncode = 0
        mock_popen.return_value = mock_popen_instance

        mock_zipfile_instance = MagicMock()
        mock_zipfile.return_value.__enter__.return_value = mock_zipfile_instance

        mock_os_walk.return_value = [("/fake/dir", ("subdir",), ("file1.py", "file2.py"))]

        expected_result = {
            "Type": 3,
            "File": "fake_library.zip",
            "FileID": "fake_library.zip",
            "Contents": b"test data",
            "ContentsFormat": "text",
        }
        mock_fileResult.return_value = expected_result

        # Run
        result = installLibrary(mock_dir_path, "fake_library")

        # Check
        # Ensure subprocess was called with the correct command
        mock_popen.assert_called_once_with(
            ["python3", "-m", "pip", "install", "--target", str(mock_dir_path), "fake_library"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )

        # Ensure zipfile was created with the correct path and mode
        mock_zipfile.assert_called_once_with(
            mock_dir_path / "fake_library.zip", "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9
        )

        # Ensure files were added to the zip archive
        expected_arcnames = [Path("python") / "file1.py", Path("python") / "file2.py"]
        mock_zipfile_instance.write.assert_any_call(Path("/fake/dir/file1.py"), arcname=expected_arcnames[0])
        mock_zipfile_instance.write.assert_any_call(Path("/fake/dir/file2.py"), arcname=expected_arcnames[1])

        # Ensure the correct result is returned
        assert result == expected_result

    @patch("DownloadAndArchivePythonLibrary.installLibrary")
    @patch("DownloadAndArchivePythonLibrary.demisto.args")
    @patch("DownloadAndArchivePythonLibrary.return_results")
    @patch("DownloadAndArchivePythonLibrary.return_error")
    @patch("DownloadAndArchivePythonLibrary.Path")
    @patch("DownloadAndArchivePythonLibrary.mkdtemp")
    def test_main_success(self, mock_mkdtemp, mock_path, mock_return_error, mock_return_results, mock_args, mock_installLibrary):
        # Prepare
        mock_args.return_value = {"library_name": "fake_library"}
        mock_dir_path = Path("/fake/dir")
        mock_mkdtemp.return_value = mock_dir_path

        expected_result = {
            "Type": 3,
            "File": "fake_library.zip",
            "FileID": "fake_library.zip",
            "Contents": b"test data",
            "ContentsFormat": "text",
        }
        mock_installLibrary.return_value = expected_result

        # Run
        main()

        # Check
        mock_return_results.assert_called_once_with(expected_result)
        mock_return_error.assert_not_called()

    @patch("DownloadAndArchivePythonLibrary.installLibrary")
    @patch("DownloadAndArchivePythonLibrary.demisto.args")
    @patch("DownloadAndArchivePythonLibrary.return_results")
    @patch("DownloadAndArchivePythonLibrary.return_error")
    @patch("DownloadAndArchivePythonLibrary.Path")
    @patch("DownloadAndArchivePythonLibrary.mkdtemp")
    def test_main_failure(self, mock_mkdtemp, mock_path, mock_return_error, mock_return_results, mock_args, mock_installLibrary):
        # Prepare
        mock_args.return_value = {"library_name": "fake_library"}
        mock_dir_path = Path("/fake/dir")
        mock_mkdtemp.return_value = mock_dir_path

        mock_installLibrary.side_effect = Exception("Test Exception")

        # Run
        main()

        # Check
        mock_return_error.assert_called_once_with("An error occurred: Test Exception")
        mock_return_results.assert_not_called()


if __name__ == "__main__":
    unittest.main()