예제 #1
0
    def run_dev_packages(self) -> int:
        """Runs the Lint command on all given packages.

        Returns:
            int. 0 on success and 1 if any package failed
        """
        good_pkgs = []
        fail_pkgs = []
        if not self.parallel:
            for project_dir in self.pkgs:

                linter = Linter(project_dir, no_test=not self.run_args['tests'],
                                no_pylint=not self.run_args['pylint'], no_flake8=not self.run_args['flake8'],
                                no_mypy=not self.run_args['mypy'], verbose=self.log_verbose, root=self.root,
                                keep_container=self.keep_container, cpu_num=self.cpu_num,
                                configuration=self.configuration, no_bandit=not self.run_args['bandit'],
                                requirements_3=self.requirements_for_python3,
                                requirements_2=self.requirements_for_python2)
                run_status_code = linter.run_dev_packages()
                if run_status_code > 0:
                    fail_pkgs.append(project_dir)
                else:
                    good_pkgs.append(project_dir)

            self._print_final_results(good_pkgs=good_pkgs, fail_pkgs=fail_pkgs)

            return 1 if fail_pkgs else 0

        else:  # we run parallel processes
            return self.run_parallel_packages(self.pkgs)
예제 #2
0
    def _run_single_package_thread(self, package_dir: str) -> Tuple[int, str]:
        """Run a thread of lint command.

        Args:
            package_dir (str): The package directory to run the command on.

        Returns:
            Tuple[int, str]. The result code for the lint command and the package name.
        """
        try:
            linter = Linter(package_dir,
                            no_test=not self.run_args['tests'],
                            no_pylint=not self.run_args['pylint'],
                            no_flake8=not self.run_args['flake8'],
                            no_mypy=not self.run_args['mypy'],
                            root=self.root,
                            keep_container=self.keep_container,
                            cpu_num=self.cpu_num,
                            configuration=self.configuration,
                            lock=LOCK,
                            no_bandit=not self.run_args['bandit'],
                            no_vulture=not self.run_args['vulture'],
                            no_pslint=not self.run_args['pslint'],
                            requirements_3=self.requirements_for_python3,
                            requirements_2=self.requirements_for_python2)
            return linter.run_dev_packages(), package_dir
        except Exception as ex:
            print_error(
                f'Failed running lint for: {package_dir}. Exception: {ex}')
            return 1, package_dir
예제 #3
0
    def test_run_pytest(self, mocker, linter_obj: Linter,
                        exp_container_exit_code: int, exp_exit_code: int):
        exp_test_json = mocker.MagicMock() if exp_container_exit_code in [
            0, 1, 2, 5
        ] else {}

        # Docker client mocking
        mocker.patch(
            'demisto_sdk.commands.lint.docker_helper.Docker.create_container')
        linter.Docker.create_container().wait.return_value = {
            "StatusCode": exp_container_exit_code
        }

        # Docker related mocking
        mocker.patch.object(linter, 'json')
        linter.json.loads.return_value = exp_test_json
        mocker.patch.object(linter, 'get_file_from_container')

        act_container_exit_code, act_output, act_test_json = linter_obj._docker_run_pytest(
            test_image='test-image',
            keep_container=False,
            test_xml="",
            no_coverage=True)

        assert exp_exit_code == act_container_exit_code
        assert exp_test_json == act_test_json
예제 #4
0
    def test_build_image_no_errors(self, linter_obj: Linter, mocker):
        # Expected returns
        exp_test_image_id = 'test-image'
        exp_errors = ""
        # Jinja2 mocking
        mocker.patch.multiple(linter, Environment=DEFAULT, FileSystemLoader=DEFAULT, exceptions=DEFAULT, hashlib=DEFAULT,
                              copy_dir_to_container=DEFAULT)
        # Facts mocking
        mocker.patch.dict(linter_obj._facts, {
            "images": [],
            "python_version": 0,
            "test": False,
            "lint_files": [],
            "additional_requirements": [],
            "docker_engine": True,
            "env_vars": {
                "CI": True,
                "DEMISTO_LINT_UPDATE_CERTS": "yes"
            }
        })
        mocker.patch.object(linter, 'io')
        # Docker client mocking
        mocker.patch.object(linter_obj, '_docker_client')
        docker_build_response = mocker.MagicMock()
        docker_build_response.short_id = exp_test_image_id
        linter_obj._docker_client.containers.create().commit().short_id = exp_test_image_id

        act_test_image_id, act_errors = linter_obj._docker_image_create(docker_base_image=[exp_test_image_id, 3.7])

        assert act_test_image_id == exp_test_image_id
        assert act_errors == exp_errors
        assert linter_obj._docker_client.images.build.call_count == 0
예제 #5
0
파일: conftest.py 프로젝트: avidan-H/my-sdk
def linter_obj(mocker) -> Linter:
    mocker.patch.object(linter, 'docker')
    return Linter(pack_dir=Path(__file__).parent / 'content' / 'Integrations' /
                  'Sample_integration',
                  content_repo=Path(__file__).parent / 'data',
                  req_3=["pytest==3.0"],
                  req_2=["pytest==2.0"],
                  docker_engine=True)
예제 #6
0
    def _run_single_package_thread(self, package_dir: str) -> Tuple[int, str]:
        """Run a thread of lint command.

        Args:
            package_dir (str): The package directory to run the command on.

        Returns:
            Tuple[int, str]. The result code for the lint command and the package name.
        """
        linter = Linter(package_dir, no_test=not self.run_args['tests'],
                        no_pylint=not self.run_args['pylint'], no_flake8=not self.run_args['flake8'],
                        no_mypy=not self.run_args['mypy'], verbose=self.log_verbose, root=self.root,
                        keep_container=self.keep_container, cpu_num=self.cpu_num, configuration=self.configuration,
                        lock=LOCK, no_bandit=not self.run_args['bandit'], requirements_3=self.requirements_for_python3,
                        requirements_2=self.requirements_for_python2)

        return linter.run_dev_packages(), package_dir
예제 #7
0
    def test_run_mypy_success(self, linter_obj: Linter, lint_files: List[Path], mocker):
        from demisto_sdk.commands.lint import linter

        mocker.patch.object(linter, 'run_command_os')
        linter.run_command_os.return_value = ('Success: no issues found', '', 0)

        exit_code, output = linter_obj._run_mypy(lint_files=lint_files, py_num=3.7)

        assert exit_code == 0b0, "Exit code should be 0"
        assert output == '', "Output should be empty"
예제 #8
0
    def test_run_bandit_usage_stderr(self, linter_obj: Linter, lint_files: List[Path], mocker):
        from demisto_sdk.commands.lint import linter

        mocker.patch.object(linter, 'run_command_os')
        expected_output = 'Error code found'
        linter.run_command_os.return_value = ('not good', expected_output, 1)

        exit_code, output = linter_obj._run_bandit(lint_files=lint_files)

        assert exit_code == 0b1, "Exit code should be 1"
        assert output == expected_output, "Output should be empty"
예제 #9
0
    def test_run_mypy_fail_lint(self, linter_obj: Linter, lint_files: List[Path], mocker):
        from demisto_sdk.commands.lint import linter

        mocker.patch.object(linter, 'run_command_os')
        expected_output = 'Error code found'
        linter.run_command_os.return_value = (expected_output, '', 1)

        exit_code, output = linter_obj._run_mypy(lint_files=lint_files, py_num=3.7)

        assert exit_code == 0b1, "Exit code should be 1"
        assert output == expected_output, "Output should be empty"
예제 #10
0
    def test_run_pylint_with_errors(self, mocker, linter_obj: Linter, exp_container_exit_code: int, exp_container_log: str,
                                    exp_exit_code: int, exp_output: str):
        # Docker client mocking
        mocker.patch.object(linter_obj, '_docker_client')
        linter_obj._docker_client.containers.run().wait.return_value = {"StatusCode": exp_container_exit_code}
        linter_obj._docker_client.containers.run().logs.return_value = exp_container_log.encode('utf-8')
        act_exit_code, act_output = linter_obj._docker_run_pylint(test_image='test-image',
                                                                  keep_container=False)

        assert act_exit_code == exp_exit_code
        assert act_output == exp_output
예제 #11
0
    def test_run_pylint_no_errors(self, mocker, linter_obj: Linter):
        # Expected values
        exp_container_exit_code = 0
        exp_container_log = ""

        # Docker client mocking
        mocker.patch.object(linter_obj, '_docker_client')
        linter_obj._docker_client.containers.run().wait.return_value = {"StatusCode": exp_container_exit_code}
        linter_obj._docker_client.containers.run().logs.return_value = exp_container_log.encode('utf-8')
        act_container_exit_code, act_container_log = linter_obj._docker_run_pylint(test_image='test-image',
                                                                                   keep_container=False)

        assert exp_container_exit_code == act_container_exit_code
        assert exp_container_log == act_container_log
예제 #12
0
    def test_run_pylint_with_errors(self, mocker, linter_obj: Linter,
                                    exp_container_exit_code: int,
                                    exp_container_log: str, exp_exit_code: int,
                                    exp_output: str):
        # Docker client mocking
        mocker.patch(
            'demisto_sdk.commands.lint.docker_helper.Docker.create_container')
        linter.Docker.create_container().wait.return_value = {
            "StatusCode": exp_container_exit_code
        }
        linter.Docker.create_container(
        ).logs.return_value = exp_container_log.encode('utf-8')
        act_exit_code, act_output = linter_obj._docker_run_pylint(
            test_image='test-image', keep_container=False)

        assert act_exit_code == exp_exit_code
        assert act_output == exp_output
예제 #13
0
    def test_run_pytest(self, mocker, linter_obj: Linter, exp_container_exit_code: int, exp_exit_code: int):
        exp_test_json = mocker.MagicMock()

        # Docker client mocking
        mocker.patch.object(linter_obj, '_docker_client')
        linter_obj._docker_client.containers.run().wait.return_value = {"StatusCode": exp_container_exit_code}

        # Docker related mocking
        mocker.patch.object(linter, 'json')
        linter.json.loads.return_value = exp_test_json
        mocker.patch.object(linter, 'get_file_from_container')

        act_container_exit_code, act_output, act_test_json = linter_obj._docker_run_pytest(test_image='test-image',
                                                                                           keep_container=False,
                                                                                           test_xml="")

        assert exp_exit_code == act_container_exit_code
        assert exp_test_json == act_test_json
예제 #14
0
    def run_dev_packages(self, parallel: int, no_flake8: bool, no_bandit: bool,
                         no_mypy: bool, no_pylint: bool, no_vulture: bool,
                         no_test: bool, no_pwsh_analyze: bool,
                         no_pwsh_test: bool, keep_container: bool,
                         test_xml: str, failure_report: str) -> int:
        """ Runs the Lint command on all given packages.

        Args:
            parallel(int): Whether to run command on multiple threads
            no_flake8(bool): Whether to skip flake8
            no_bandit(bool): Whether to skip bandit
            no_mypy(bool): Whether to skip mypy
            no_vulture(bool): Whether to skip vulture
            no_pylint(bool): Whether to skip pylint
            no_test(bool): Whether to skip pytest
            no_pwsh_analyze(bool): Whether to skip powershell code analyzing
            no_pwsh_test(bool): whether to skip powershell tests
            keep_container(bool): Whether to keep the test container
            test_xml(str): Path for saving pytest xml results
            failure_report(str): Path for store failed packs report

        Returns:
            int: exit code by fail exit codes by var EXIT_CODES
        """
        lint_status: Dict = {
            "fail_packs_flake8": [],
            "fail_packs_bandit": [],
            "fail_packs_mypy": [],
            "fail_packs_vulture": [],
            "fail_packs_pylint": [],
            "fail_packs_pytest": [],
            "fail_packs_pwsh_analyze": [],
            "fail_packs_pwsh_test": [],
            "fail_packs_image": [],
        }

        # Python or powershell or both
        pkgs_type = []

        # Detailed packages status
        pkgs_status = {}

        # Skiped lint and test codes
        skipped_code = build_skipped_exit_code(
            no_flake8=no_flake8,
            no_bandit=no_bandit,
            no_mypy=no_mypy,
            no_vulture=no_vulture,
            no_pylint=no_pylint,
            no_test=no_test,
            no_pwsh_analyze=no_pwsh_analyze,
            no_pwsh_test=no_pwsh_test,
            docker_engine=self._facts["docker_engine"])

        with concurrent.futures.ThreadPoolExecutor(
                max_workers=parallel) as executor:
            return_exit_code: int = 0
            results = []
            # Executing lint checks in different threads
            for pack in self._pkgs:
                linter: Linter = Linter(
                    pack_dir=pack,
                    content_repo="" if not self._facts["content_repo"] else
                    Path(self._facts["content_repo"].working_dir),
                    req_2=self._facts["requirements_2"],
                    req_3=self._facts["requirements_3"],
                    docker_engine=self._facts["docker_engine"])
                results.append(
                    executor.submit(fn=linter.run_dev_packages,
                                    no_flake8=no_flake8,
                                    no_bandit=no_bandit,
                                    no_mypy=no_mypy,
                                    no_vulture=no_vulture,
                                    no_pylint=no_pylint,
                                    no_test=no_test,
                                    no_pwsh_analyze=no_pwsh_analyze,
                                    no_pwsh_test=no_pwsh_test,
                                    modules=self._facts["test_modules"],
                                    keep_container=keep_container,
                                    test_xml=test_xml))
            try:
                for future in concurrent.futures.as_completed(results):
                    pkg_status = future.result()
                    pkgs_status[pkg_status["pkg"]] = pkg_status
                    if pkg_status["exit_code"]:
                        for check, code in EXIT_CODES.items():
                            if pkg_status["exit_code"] & code:
                                lint_status[f"fail_packs_{check}"].append(
                                    pkg_status["pkg"])
                        if not return_exit_code & pkg_status["exit_code"]:
                            return_exit_code += pkg_status["exit_code"]
                    if pkg_status["pack_type"] not in pkgs_type:
                        pkgs_type.append(pkg_status["pack_type"])
            except KeyboardInterrupt:
                print_warning("Stop demisto-sdk lint - Due to 'Ctrl C' signal")
                try:
                    executor.shutdown(wait=False)
                except Exception:
                    pass
                return 1
            except Exception as e:
                print_warning(f"Stop demisto-sdk lint - Due to Exception {e}")
                try:
                    executor.shutdown(wait=False)
                except Exception:
                    pass
                return 1

        self._report_results(lint_status=lint_status,
                             pkgs_status=pkgs_status,
                             return_exit_code=return_exit_code,
                             skipped_code=int(skipped_code),
                             pkgs_type=pkgs_type)
        self._create_failed_packs_report(lint_status=lint_status,
                                         path=failure_report)

        return return_exit_code
예제 #15
0
 def test_run_bandit(self, directory):
     linter = Linter(directory)
     linter.run_bandit(3.7)
예제 #16
0
 def test_run_mypy(self, directory):
     linter = Linter(directory)
     linter.run_mypy("2.7")
예제 #17
0
 def test_get_common_server_python(self, directory):
     linter = Linter(directory)
     ans = linter.get_common_server_python()
     linter.remove_common_server_python()
     assert ans
예제 #18
0
 def test_run_vulture(self, directory):
     linter = Linter(directory)
     linter.run_vulture(3.7)