示例#1
0
    def postprocess_result(self, skip_handler: Optional[SkipListHandler]):
        """
        Generate analyzer result output file which can be parsed and stored
        into the database.
        """
        LOG.debug_analyzer(self.analyzer_stdout)
        tidy_stdout = self.analyzer_stdout.splitlines()

        reports = Parser().get_reports_from_iter(tidy_stdout)
        reports = [r for r in reports if not r.skip(skip_handler)]

        # In the earlier versions of CodeChecker Clang Tidy never used context
        # free hash even if we enabled it with '--report-hash context-free'
        # when calling the analyze command. To do not break every hash
        # automatically when using this option we introduced a new choice for
        # --report-hash option ('context-free-v2') and we still do not use
        # context free hash for 'context-free' choice.
        hash_type = HashType.PATH_SENSITIVE
        if self.report_hash_type == 'context-free-v2':
            hash_type = HashType.CONTEXT_FREE
        elif self.report_hash_type == 'diagnostic-message':
            hash_type = HashType.DIAGNOSTIC_MESSAGE

        for report in reports:
            report.report_hash = get_report_hash(report, hash_type)

        report_file.create(self.analyzer_result_file, reports,
                           self.checker_labels, self.analyzer_info)
示例#2
0
    def get_reports(self,
                    analyzer_result_file_path: str,
                    source_dir_path: Optional[str] = None) -> List[Report]:
        """ Get reports from the given analyzer result file. """
        reports: List[Report] = []

        if not source_dir_path:
            source_dir_path = os.path.dirname(analyzer_result_file_path)

        try:
            with open(analyzer_result_file_path, 'rb') as fp:
                plist = parse(fp)

            if not plist:
                return reports

            metadata = plist.get('metadata')

            files = get_file_index_map(plist, source_dir_path,
                                       self._file_cache)

            for diag in plist.get('diagnostics', []):
                report = self.__create_report(analyzer_result_file_path, diag,
                                              files, metadata)

                if report.report_hash is None:
                    report.report_hash = get_report_hash(
                        report, HashType.PATH_SENSITIVE)

                reports.append(report)
        except KeyError as ex:
            LOG.warning(
                "Failed to get file path id! Found files: %s. "
                "KeyError: %s", files, ex)
        except IndexError as iex:
            LOG.warning("Indexing error during processing plist file %s",
                        analyzer_result_file_path)
            LOG.warning(type(iex))
            LOG.warning(repr(iex))
            _, _, exc_traceback = sys.exc_info()
            traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
        except Exception as ex:
            LOG.warning(
                "Error during processing reports from the plist "
                "file: %s", analyzer_result_file_path)
            traceback.print_exc()
            LOG.warning(type(ex))
            LOG.warning(ex)
        finally:
            return reports
示例#3
0
    def replace_report_hash(
        self,
        plist_file_path: str,
        hash_type=HashType.CONTEXT_FREE
    ):
        """
        Override hash in the given file by using the given version hash.
        """
        try:
            with open(plist_file_path, 'rb+') as f:
                plist = plistlib.load(f)
                f.seek(0)
                f.truncate()

                metadata = plist.get('metadata')
                analyzer_result_dir_path = os.path.dirname(plist_file_path)

                file_cache: Dict[str, File] = {}
                files = get_file_index_map(
                    plist, analyzer_result_dir_path, file_cache)

                for diag in plist['diagnostics']:
                    report = self.__create_report(
                        plist_file_path, diag, files, metadata)
                    diag['issue_hash_content_of_line_in_context'] = \
                        get_report_hash(report, hash_type)

                plistlib.dump(plist, f)
        except (TypeError, AttributeError,
                plistlib.InvalidFileException) as err:
            LOG.warning('Failed to process plist file: %s wrong file format?',
                        plist_file_path)
            LOG.warning(err)
        except IndexError as iex:
            LOG.warning('Indexing error during processing plist file %s',
                        plist_file_path)
            LOG.warning(type(iex))
            LOG.warning(repr(iex))
            _, _, exc_traceback = sys.exc_info()
            traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
        except Exception as ex:
            LOG.warning('Error during processing reports from the plist '
                        'file: %s', plist_file_path)
            traceback.print_exc()
            LOG.warning(type(ex))
            LOG.warning(ex)
    def test_gen_report_hash_context_free(self):
        """ Test context free hash generation for multi errors. """
        test_plist = os.path.join(self.test_file_dir, 'cpp',
                                  'multi_error.plist')

        expected_report_hash = {
            'f48840093ef89e291fb68a95a5181612':
            'c2a2856f566ed67ed1c3596ad06d42db',
            'e4907182b363faf2ec905fc32cc5a4ab':
            '5a92e13f07c81c6d3197e7d910827e6e'
        }

        reports = get_reports(test_plist)
        for report in reports:
            report_hash = get_report_hash(report, HashType.CONTEXT_FREE)
            self.assertEqual(report_hash,
                             expected_report_hash[report.report_hash])
    def test_gen_report_hash_path_sensitive(self):
        """ Test path sensitive report hash generation for multiple errors. """
        test_plist = os.path.join(self.test_file_dir, 'cpp',
                                  'multi_error.plist')

        expected_report_hash = {
            'f48840093ef89e291fb68a95a5181612':
            'fdf11db1183dba2da4cd188e70d142e5',
            'e4907182b363faf2ec905fc32cc5a4ab':
            '774799eb31f5fb8514988a7f6736b33e'
        }

        reports = get_reports(test_plist)
        for report in reports:
            report_hash = get_report_hash(report, HashType.PATH_SENSITIVE)
            self.assertEqual(report_hash,
                             expected_report_hash[report.report_hash])
    def test_gen_report_hash_diag_messages(self):
        """ Test diagnostic message hash generation for multi errors. """
        test_plist = os.path.join(self.test_file_dir, 'cpp',
                                  'multi_error.plist')

        expected_report_hash = {
            'f48840093ef89e291fb68a95a5181612':
            'c137804816bf2d5a67b6c067cd2ab5e8',
            'e4907182b363faf2ec905fc32cc5a4ab':
            'd08c2f8c5c4d8533e1de3fa88241f813'
        }

        reports = get_reports(test_plist)
        for report in reports:
            report_hash = get_report_hash(report, HashType.DIAGNOSTIC_MESSAGE)
            self.assertEqual(report_hash,
                             expected_report_hash[report.report_hash])
示例#7
0
    def postprocess_result(self, skip_handler: Optional[SkipListHandler]):
        """
        Generate analyzer result output file which can be parsed and stored
        into the database.
        """
        if os.path.exists(self.analyzer_result_file):
            reports = report_file.get_reports(self.analyzer_result_file,
                                              self.checker_labels)
            reports = [r for r in reports if not r.skip(skip_handler)]

            hash_type = None
            if self.report_hash_type in ['context-free', 'context-free-v2']:
                hash_type = HashType.CONTEXT_FREE
            elif self.report_hash_type == 'diagnostic-message':
                hash_type = HashType.DIAGNOSTIC_MESSAGE

            if hash_type is not None:
                for report in reports:
                    report.report_hash = get_report_hash(report, hash_type)

            report_file.create(self.analyzer_result_file, reports,
                               self.checker_labels, self.analyzer_info)
示例#8
0
 def _add_report_hash(self, report: Report):
     """ Generate report hash for the given plist data. """
     report.report_hash = get_report_hash(report, HashType.CONTEXT_FREE)