예제 #1
0
    def test_collect_path_events(self):
        """
        Test path event collect before store.
        """
        clang50_trunk_plist = os.path.join(
            self.__plist_test_files, 'clang-5.0-trunk.plist')
        files, reports = plist_parser.parse_plist_file(clang50_trunk_plist,
                                                       None,
                                                       False)
        self.assertEqual(len(reports), 3)

        # Generate dummy file_ids which should come from the database.
        file_ids = {}
        for i, file_name in enumerate(files, 1):
            file_ids[file_name] = i

        msg = "This test is prepared to handle 3 reports."
        self.assertEqual(len(reports), 3, msg)

        report1_path = [
            ttypes.BugPathPos(startLine=19, filePath=None, endCol=7,
                              startCol=5, endLine=19, fileId=1),
            ttypes.BugPathPos(startLine=20, filePath=None, endCol=7,
                              startCol=5, endLine=20, fileId=1),
            ttypes.BugPathPos(startLine=21, filePath=None, endCol=13,
                              startCol=5, endLine=21, fileId=1),
            ttypes.BugPathPos(startLine=7, filePath=None, endCol=7,
                              startCol=5, endLine=7, fileId=1),
            ttypes.BugPathPos(startLine=8, filePath=None, endCol=6,
                              startCol=5, endLine=8, fileId=1),
            ttypes.BugPathPos(startLine=8, filePath=None, endCol=25,
                              startCol=22, endLine=8, fileId=1),
            ttypes.BugPathPos(startLine=8, filePath=None, endCol=20,
                              startCol=10, endLine=8, fileId=1),
            ttypes.BugPathPos(startLine=7, filePath=None, endCol=14,
                              startCol=14, endLine=7, fileId=2)
        ]
        report1_events = [
            ttypes.BugPathEvent(startLine=20, filePath=None, endCol=12,
                                startCol=5, msg="'base' initialized to 0",
                                endLine=20, fileId=1),
            ttypes.BugPathEvent(startLine=21, filePath=None, endCol=18,
                                startCol=15,
                                msg="Passing the value 0 via "
                                "1st parameter 'base'",
                                endLine=21, fileId=1),
            ttypes.BugPathEvent(startLine=21, filePath=None, endCol=19,
                                startCol=5, msg="Calling 'test_func'",
                                endLine=21, fileId=1),
            ttypes.BugPathEvent(startLine=6, filePath=None, endCol=1,
                                startCol=1, msg="Entered call from 'main'",
                                endLine=6, fileId=1),
            ttypes.BugPathEvent(startLine=8, filePath=None, endCol=25,
                                startCol=22,
                                msg="Passing the value 0 via "
                                "1st parameter 'num'", endLine=8, fileId=1),
            ttypes.BugPathEvent(startLine=8, filePath=None, endCol=26,
                                startCol=10, msg="Calling 'generate_id'",
                                endLine=8, fileId=1),
            ttypes.BugPathEvent(startLine=6, filePath=None, endCol=1,
                                startCol=1,
                                msg="Entered call from 'test_func'",
                                endLine=6, fileId=2),
            ttypes.BugPathEvent(startLine=7, filePath=None, endCol=17,
                                startCol=12, msg='Division by zero',
                                endLine=7, fileId=2)
        ]

        path1, events1, _ = store_handler.collect_paths_events(reports[0],
                                                               file_ids,
                                                               files)

        self.assertEqual(path1, report1_path)
        self.assertEqual(events1, report1_events)

        report2_path = []
        report2_events = [
            ttypes.BugPathEvent(startLine=8, filePath=None, endCol=26,
                                startCol=10,
                                msg="Value stored to 'id' is ""never read",
                                endLine=8, fileId=1)
        ]

        path2, events2, _ = store_handler.collect_paths_events(reports[1],
                                                               file_ids,
                                                               files)
        self.assertEqual(path2, report2_path)
        self.assertEqual(events2, report2_events)

        report3_path = [
            ttypes.BugPathPos(startLine=14, filePath=None, endCol=6,
                              startCol=3, endLine=14, fileId=1),
            ttypes.BugPathPos(startLine=15, filePath=None, endCol=3,
                              startCol=3, endLine=15, fileId=1),
            ttypes.BugPathPos(startLine=16, filePath=None, endCol=1,
                              startCol=1, endLine=16, fileId=1)
        ]
        report3_events = [
            ttypes.BugPathEvent(startLine=14, filePath=None, endCol=29,
                                startCol=3,
                                msg="Address of stack memory associated"
                                    " with local variable 'str'"
                                    " is still referred to by the global "
                                    "variable 'p' upon returning to the "
                                    "caller.  This will be a dangling "
                                    "reference",
                                endLine=14, fileId=1)
        ]

        path, events, _ = store_handler.collect_paths_events(reports[2],
                                                             file_ids,
                                                             files)
        self.assertEqual(path, report3_path)
        self.assertEqual(events, report3_events)
예제 #2
0
def collect_paths_events(report: ReportType, file_ids: Dict[str, int],
                         files: Dict[str, str]) -> PathEvents:
    """
    This function creates the BugPathPos and BugPathEvent objects which belong
    to a report.

    report -- A report object from the parsed plist file.
    file_ids -- A dictionary which maps the file paths to file IDs in the
                database.
    files -- A list containing the file paths from the parsed plist file. The
             order of this list must be the same as in the plist file.

    #TODO Multiple ranges could belong to an event or control node.
    Only the first range from the list of ranges is stored into the
    database. Further improvement can be to store and view all ranges
    if there are more than one.
    """
    path_events = PathEvents([], [], [])

    events = [i for i in report.bug_path if i.get('kind') == 'event']

    # Create remaining data for bugs and send them to the server.  In plist
    # file the source and target of the arrows are provided as starting and
    # ending ranges of the arrow. The path A->B->C is given as A->B and
    # B->C, thus range B is provided twice. So in the loop only target
    # points of the arrows are stored, and an extra insertion is done for
    # the source of the first arrow before the loop.
    report_path = [i for i in report.bug_path if i.get('kind') == 'control']

    if report_path:
        start_range = report_path[0]['edges'][0]['start']
        start1_line = start_range[0]['line']
        start1_col = start_range[0]['col']
        start2_line = start_range[1]['line']
        start2_col = start_range[1]['col']
        source_file_path = files[start_range[1]['file']]
        path_events.paths.append(
            ttypes.BugPathPos(start1_line, start1_col, start2_line, start2_col,
                              file_ids[source_file_path]))

    for path in report_path:
        try:
            end_range = path['edges'][0]['end']
            end1_line = end_range[0]['line']
            end1_col = end_range[0]['col']
            end2_line = end_range[1]['line']
            end2_col = end_range[1]['col']
            source_file_path = files[end_range[1]['file']]
            path_events.paths.append(
                ttypes.BugPathPos(end1_line, end1_col, end2_line, end2_col,
                                  file_ids[source_file_path]))
        except IndexError:
            # Edges might be empty nothing can be stored.
            continue

    for event in events:
        file_path = files[event['location']['file']]

        start_loc = event['location']
        end_loc = event['location']
        # Range can provide more precise location information.
        # Use that if available.
        ranges = event.get("ranges")
        if ranges:
            start_loc = ranges[0][0]
            end_loc = ranges[0][1]

        path_events.events.append(
            ttypes.BugPathEvent(start_loc['line'], start_loc['col'],
                                end_loc['line'], end_loc['col'],
                                event['message'], file_ids[file_path]))

    for macro in report.macro_expansions:
        if not macro['expansion']:
            continue

        file_path = files[macro['location']['file']]

        start_loc = macro['location']
        end_loc = macro['location']
        # Range can provide more precise location information.
        # Use that if available.
        ranges = macro.get("ranges")
        if ranges:
            start_loc = ranges[0][0]
            end_loc = ranges[0][1]

        path_events.extended_data.append(
            ttypes.ExtendedReportData(ttypes.ExtendedReportDataType.MACRO,
                                      start_loc['line'], start_loc['col'],
                                      end_loc['line'], end_loc['col'],
                                      macro['expansion'], file_ids[file_path]))

    for note in report.notes:
        if not note['message']:
            continue

        file_path = files[note['location']['file']]

        start_loc = note['location']
        end_loc = note['location']
        # Range can provide more precise location information.
        # Use that if available.
        ranges = note.get("ranges")
        if ranges:
            start_loc = ranges[0][0]
            end_loc = ranges[0][1]

        path_events.extended_data.append(
            ttypes.ExtendedReportData(ttypes.ExtendedReportDataType.NOTE,
                                      start_loc['line'], start_loc['col'],
                                      end_loc['line'], end_loc['col'],
                                      note['message'], file_ids[file_path]))

    return path_events