예제 #1
0
    def run(self, project: Project, version: ProjectVersion, detector_run: DetectorRun,
            potential_hits: PotentialHits, version_compile: VersionCompile, detector: Detector):
        logger = logging.getLogger("tasks.publish_findings.version")
        logger.info("Publishing findings of %s in %s on %s for upload to %s...",
                    detector, self.experiment_id, version, self.review_site_url)

        if detector_run.is_success():
            logger.info("Uploading %s potential hits.", len(potential_hits.findings))
            result = "success"
        elif detector_run.is_error():
            logger.info("Detector produced an error.")
            result = "error"
        elif detector_run.is_timeout():
            logger.info("Detector timed out.")
            result = "timeout"
        else:
            logger.info("Detector was not run.")
            result = "not run"

        run_info = detector_run.get_run_info()
        postable_potential_hits = [
            self.__to_postable_potential_hit(potential_hit, version_compile, detector_run.findings_path, logger)
            for potential_hit in potential_hits.findings]

        try:
            for postable_potential_hits_slice in self.__slice_by_number_of_files_and_post_size(postable_potential_hits):
                file_paths = self.__get_file_paths(postable_potential_hits_slice)
                postable_data = self.__to_postable_data(run_info, result, postable_potential_hits_slice)
                self.__post(project, version, detector, postable_data, file_paths)
        except RequestException as e:
            raise PublishFailedException(e)
예제 #2
0
    def test_run_outdated(self, read_run_info, _):
        self.detector.md5 = "-md5-"
        read_run_info.return_value = {"md5": "-old-md5-"}

        uut = DetectorRun(self.detector, self.version, self.findings_path)

        assert uut._is_outdated_detector()
예제 #3
0
    def test_run_outdated_on_newer_compile(self, read_yamls_mock, _):
        read_yamls_mock.return_value = {'timestamp': 0}
        compile_timestamp = 1

        uut = DetectorRun(self.detector, self.version, self.findings_path)

        assert uut._newer_compile(compile_timestamp)
예제 #4
0
    def test_adds_findings_file_path_arg(self, _):
        uut = DetectorRun(self.detector, self.version, self.findings_path)
        uut._execute = MagicMock()

        uut.ensure_executed(self.detector_args, None, True, 0, 0, self.logger)

        args = uut._execute.call_args[0][0]
        assert key_findings_file in args
예제 #5
0
    def run(self, detector: Detector, version: ProjectVersion, version_compile: VersionCompile):
        run = DetectorRun(detector, version, self._get_findings_path(detector, version))

        run.ensure_executed(self._get_detector_arguments(version_compile),
                            self.timeout, self.force_detect, self.current_timestamp, version_compile.timestamp,
                            logging.getLogger("task.detect"))

        return run
예제 #6
0
    def test_adds_default_info(self, read_yamls_mock, load_findings_mock, _):
        read_yamls_mock.return_value = {}
        load_findings_mock.return_value = []

        uut = DetectorRun(self.detector, self.version, self.findings_path)

        run_info = uut.get_run_info()

        assert_equals({"number_of_findings": 0, "runtime": 0}, run_info)
예제 #7
0
    def test_load(self, read_run_info, _):
        read_run_info.return_value = {
            "result": "success",
            "runtime": "23.42",
            "message": "-arbitrary text-"
        }

        uut = DetectorRun(self.detector, self.version, self.findings_path)

        assert uut.is_success()
        assert_equals(uut.runtime, "23.42")
        assert_equals(uut.message, "-arbitrary text-")
예제 #8
0
    def setup(self):
        self.version = create_version("-version-",
                                      project=create_project("-project-"))
        self.detector = StubDetector()
        self.findings_path = "-findings-"
        self.findings_file_path = join(self.findings_path, "FINDINGS_FILE")
        self.run_file_path = join(self.findings_path, "run.yml")

        self.detector_args = {}

        self.logger = logging.getLogger("test")

        self.uut = DetectorRun(self.detector, self.version, self.findings_path)
예제 #9
0
    def test_skips_execution_if_previous_run_succeeded(self, _):
        uut = DetectorRun(self.detector, self.version, self.findings_path)
        uut._execute = MagicMock()

        uut.is_outdated = lambda _: False
        uut.is_error = lambda: False
        uut.is_success = lambda: True

        uut.ensure_executed(self.detector_args, None, False, 0, 0, self.logger)

        uut._execute.assert_not_called()
예제 #10
0
    def test_adds_rank(self, read_yamls_mock, _):
        read_yamls_mock.return_value.__enter__.return_value = [{
            "name": "f1"
        }, {
            "name": "f2"
        }]
        execution = DetectorRun(StubDetector(), create_version("-v-"),
                                "-findings-path-")

        findings = execution._load_findings()

        assert_equals(findings, [
            Finding({
                "name": "f1",
                "rank": 0
            }),
            Finding({
                "name": "f2",
                "rank": 1
            })
        ])
예제 #11
0
    def test_force_detect_on_new_detector(self, _):
        uut = DetectorRun(self.detector, self.version, self.findings_path)
        uut._execute = MagicMock()

        uut.is_success = lambda: True
        uut.is_outdated = lambda _: True

        uut.ensure_executed(self.detector_args, None, False, 0, 0, self.logger)

        uut._execute.assert_called_with(ANY, None, 0, ANY)
예제 #12
0
class TestDetectorRun:
    # noinspection PyAttributeOutsideInit
    def setup(self):
        self.version = create_version("-version-",
                                      project=create_project("-project-"))
        self.detector = StubDetector()
        self.findings_path = "-findings-"
        self.findings_file_path = join(self.findings_path, "FINDINGS_FILE")
        self.run_file_path = join(self.findings_path, "run.yml")

        self.detector_args = {}

        self.logger = logging.getLogger("test")

        self.uut = DetectorRun(self.detector, self.version, self.findings_path)

    @patch("data.detector_run.read_yaml_if_exists")
    def test_run_outdated(self, read_run_info, _):
        self.detector.md5 = "-md5-"
        read_run_info.return_value = {"md5": "-old-md5-"}

        uut = DetectorRun(self.detector, self.version, self.findings_path)

        assert uut._is_outdated_detector()

    @patch("data.detector_run.read_yaml_if_exists")
    def test_run_up_to_date(self, read_run_info, _):
        self.detector.md5 = "-md5-"
        read_run_info.return_value = {"md5": "-md5-"}

        assert not self.uut._is_outdated_detector()

    @patch("data.detector_run.read_yaml_if_exists")
    def test_error_is_failure(self, read_run_info, _):
        read_run_info.return_value = {"result": "error"}

        assert self.uut.is_failure()

    @patch("data.detector_run.read_yaml_if_exists")
    def test_timeout_is_failure(self, read_run_info, _):
        read_run_info.return_value = {"result": "timeout"}

        assert self.uut.is_failure()

    @patch("data.detector_run.read_yaml_if_exists")
    def test_load(self, read_run_info, _):
        read_run_info.return_value = {
            "result": "success",
            "runtime": "23.42",
            "message": "-arbitrary text-"
        }

        uut = DetectorRun(self.detector, self.version, self.findings_path)

        assert uut.is_success()
        assert_equals(uut.runtime, "23.42")
        assert_equals(uut.message, "-arbitrary text-")

    def test_execute_sets_success(self, write_yaml_mock):
        self.uut._execute("-compiles-", 42, 0, self.logger)

        assert_equals(Result.success, self.uut.result)

    def test_execute_sets_error(self, write_yaml_mock):
        self.detector.runner_interface.execute = MagicMock(
            side_effect=CommandFailedError("-cmd-", "-out-"))

        self.uut._execute("-compiles-", 42, 0, self.logger)

        assert_equals(Result.error, self.uut.result)

    def test_execute_captures_error_output(self, write_yaml_mock):
        self.detector.runner_interface.execute = MagicMock(
            side_effect=CommandFailedError("-cmd-", "-out-"))

        self.uut._execute("-compiles-", 42, 0, self.logger)

        assert_equals("Failed to execute '-cmd-': -out-", self.uut.message)

    def test_execute_cuts_output_if_too_long(self, write_yaml_mock):
        long_output = "\n".join(["line " + str(i) for i in range(1, 8000)])
        self.detector.runner_interface.execute = MagicMock(
            side_effect=CommandFailedError("-cmd-", long_output))

        self.uut._execute("-compiles-", 42, 0, self.logger)

        print(self.uut.message)
        assert_equals(5000, len(str.splitlines(self.uut.message)))

    def test_execute_sets_timeout(self, write_yaml_mock):
        self.detector.runner_interface.execute = MagicMock(
            side_effect=TimeoutError())

        self.uut._execute("-compiles-", 42, 0, self.logger)

        assert_equals(Result.timeout, self.uut.result)

    def test_saves_after_execution(self, write_yaml_mock):
        self.uut._execute("-compiles-", 42, 1337, self.logger)

        write_yaml_mock.assert_called_with(
            {
                'result': 'success',
                'message': '',
                'md5': self.detector.md5,
                'runtime': ANY,
                'timestamp': 1337
            },
            file='-findings-/run.yml')

    def test_skips_execution_if_previous_run_succeeded(self, _):
        uut = DetectorRun(self.detector, self.version, self.findings_path)
        uut._execute = MagicMock()

        uut.is_outdated = lambda _: False
        uut.is_error = lambda: False
        uut.is_success = lambda: True

        uut.ensure_executed(self.detector_args, None, False, 0, 0, self.logger)

        uut._execute.assert_not_called()

    def test_skips_detect_if_previous_run_was_error(self, _):
        uut = DetectorRun(self.detector, self.version, self.findings_path)
        uut._execute = MagicMock()

        uut.is_outdated = lambda _: False
        uut.is_error = lambda: True

        uut.ensure_executed(self.detector_args, None, False, 0, 0, self.logger)

        uut._execute.assert_not_called()

    def test_force_detect_on_new_detector(self, _):
        uut = DetectorRun(self.detector, self.version, self.findings_path)
        uut._execute = MagicMock()

        uut.is_success = lambda: True
        uut.is_outdated = lambda _: True

        uut.ensure_executed(self.detector_args, None, False, 0, 0, self.logger)

        uut._execute.assert_called_with(ANY, None, 0, ANY)

    def test_adds_run_file_path_arg(self, _):
        uut = DetectorRun(self.detector, self.version, self.findings_path)
        uut._execute = MagicMock()

        uut.ensure_executed(self.detector_args, None, True, 0, 0, self.logger)

        args = uut._execute.call_args[0][0]
        assert key_run_file in args

    def test_adds_findings_file_path_arg(self, _):
        uut = DetectorRun(self.detector, self.version, self.findings_path)
        uut._execute = MagicMock()

        uut.ensure_executed(self.detector_args, None, True, 0, 0, self.logger)

        args = uut._execute.call_args[0][0]
        assert key_findings_file in args

    @patch("data.detector_run.open_yamls_if_exists")
    def test_adds_rank(self, read_yamls_mock, _):
        read_yamls_mock.return_value.__enter__.return_value = [{
            "name": "f1"
        }, {
            "name": "f2"
        }]
        execution = DetectorRun(StubDetector(), create_version("-v-"),
                                "-findings-path-")

        findings = execution._load_findings()

        assert_equals(findings, [
            Finding({
                "name": "f1",
                "rank": 0
            }),
            Finding({
                "name": "f2",
                "rank": 1
            })
        ])

    @patch("data.detector_run.open_yamls_if_exists")
    def test_run_outdated_on_newer_compile(self, read_yamls_mock, _):
        read_yamls_mock.return_value = {'timestamp': 0}
        compile_timestamp = 1

        uut = DetectorRun(self.detector, self.version, self.findings_path)

        assert uut._newer_compile(compile_timestamp)

    @patch("data.detector_run.DetectorRun._load_findings")
    @patch("data.detector_run.open_yamls_if_exists")
    def test_adds_default_info(self, read_yamls_mock, load_findings_mock, _):
        read_yamls_mock.return_value = {}
        load_findings_mock.return_value = []

        uut = DetectorRun(self.detector, self.version, self.findings_path)

        run_info = uut.get_run_info()

        assert_equals({"number_of_findings": 0, "runtime": 0}, run_info)