Пример #1
0
    def __add_message(self, src, line, column, rule_id, msg, tag=None):
        """Add GNATcheck message to current session database.

        :param str src: Message source file.
        :param str line: Message line number.
        :param str column: Message column number.
        :param str rule_id: Message's rule identifier.
        :param str msg: Description of the message.
        """

        # Cache the rules
        if rule_id in self.rules:
            rule = self.rules[rule_id]
        else:
            rule = GNAThub.Rule(rule_id, rule_id, GNAThub.RULE_KIND, self.tool)
            self.rules[rule_id] = rule

        # Set predefined unspecified ranking for all GNATcheck messages
        ranking = GNAThub.RANKING_UNSPECIFIED

        # Cache the messages
        if (rule, msg, ranking) in self.messages:
            message = self.messages[(rule, msg, ranking)]
        else:
            if tag:
                message = GNAThub.Message(rule, msg, ranking, 0, tag)
            else:
                message = GNAThub.Message(rule, msg, ranking)

            self.messages[(rule, msg, ranking)] = message

        # Add the message to the given resource
        self.bulk_data[src].append(
            [message, int(line), int(column), int(column)])
Пример #2
0
    def __add_message(self, src, line, column, rule_id, msg, category):
        """Add GNATprove message to current session database.

        :param str src: message source file
        :param str line: message line number
        :param str column: message column number
        :param str rule_id: message rule identifier
        :param str msg: description of the message
        :param str category: the category of the message
        """

        # Get message ranking value
        ranking = self.__get_ranking(category)

        # Cache the rules
        if rule_id in self.rules:
            rule = self.rules[rule_id]
        else:
            rule = GNAThub.Rule(rule_id, rule_id, GNAThub.RULE_KIND, self.tool)
            self.rules[rule_id] = rule

        # Cache messages
        if (rule, msg, ranking) in self.messages:
            message = self.messages[(rule, msg, ranking)]
        else:
            message = GNAThub.Message(rule, msg, ranking)
            self.messages[(rule, msg, ranking)] = message

        # Add the message to the given resource
        self.bulk_data[src].append(
            [message, int(line), int(column),
             int(column)])
Пример #3
0
 def add_message(rule, message, ranking, line_no, col_begin, col_end):
     bulk_messages.append([
         GNAThub.Message(rule, message, ranking=ranking),
         line_no,
         col_begin,
         col_end,
     ])
Пример #4
0
 def add_message(rule, message, ranking, line_no, column_no):
     bulk_messages.append([
         GNAThub.Message(rule, message, ranking=ranking),
         line_no,
         column_no,
         column_no,
     ])
Пример #5
0
    def __process_file(self, resource, filename, resources_messages):
        """Processe one file, adding in bulk all coverage info found.

        :param GNAThub.Resource resource: the resource being processed
        :param str filename: the name of the resource
        """

        message_data = []

        with open(filename, 'r') as gcov_file:
            # Retrieve information for every source line.
            # Skip the first 2 lines.

            for line in gcov_file.readlines()[2:]:
                matches = self.matcher.match(line)

                if not matches:
                    continue

                (hits, line) = matches.groups()

                # Skip lines that do not contain coverage info
                if hits == '-':
                    continue

                # Line is not covered
                if hits == '#####' or hits == '=====':
                    hits = '0'

                line = int(line)

                # Find the message corresponding to this hits number

                if hits in self.hits:
                    msg = self.hits[hits]
                else:
                    msg = GNAThub.Message(self.rule, hits)
                    self.hits[hits] = msg

                message_data.append([msg, line, 1, 1])

        # Preparing list for tool level insertion of resources messages
        resources_messages.append([resource, message_data])
Пример #6
0
    def parse_metrics(self, node, entity=False):
        """Parse the xml *node* returns a list of metrics"""
        message_data = []

        for metric in node.findall('./metric'):
            name = metric.attrib.get('name')
            if name in self.rules:
                rule = self.rules[name]
            else:
                rule = GNAThub.Rule(name, name, GNAThub.METRIC_KIND, self.tool)
                self.rules[name] = rule

            if (rule, metric.text, GNATmetric.RANKING) in self.messages:
                msg = self.messages[(rule, metric.text, GNATmetric.RANKING)]
            else:
                msg = GNAThub.Message(rule, metric.text, GNATmetric.RANKING)
                self.messages[(rule, metric.text, GNATmetric.RANKING)] = msg

            message_data.append([msg, 0, 1, 1])
        return message_data
Пример #7
0
    def __add_message(self, src, line, column, rule_id, msg, category,
                      tool_msg_id, properties):
        """Add CodePeer message to current session database.

        :param str src: message source file
        :param str line: message line number
        :param str column: message column number
        :param str rule_id: message rule identifier
        :param str msg: description of the message
        :param str category: the category of the message
        :param str tool_msg_id: the original id of the message
        :param properties: the message properties
        :type properties: collections.Iterable[GNAThub.Property] or None
        """

        # Get message ranking value
        ranking = self.__get_ranking(category)

        # Cache the rules
        if rule_id in self.rules:
            rule = self.rules[rule_id]
        else:
            rule = GNAThub.Rule(rule_id, rule_id, GNAThub.RULE_KIND, self.tool)
            self.rules[rule_id] = rule

        # Get message id from string
        msg_id = 0
        if tool_msg_id and tool_msg_id.strip().isdigit():
            msg_id = int(tool_msg_id)

        # Cache the messages
        if (rule, msg, ranking, msg_id) in self.messages:
            message = self.messages[(rule, msg, ranking, msg_id)]
        else:
            message = GNAThub.Message(rule, msg, ranking, msg_id, properties)
            self.messages[(rule, msg, ranking, msg_id)] = message

        # Add the message to the given resource
        self.bulk_data[src].append(
            [message, int(line), int(column),
             int(column)])
Пример #8
0
    def report(self):
        """Parse GNATstack output file report.

        Returns according to the success of the analysis:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution and analysis
            * ``GNAThub.EXEC_FAILURE``: on any error
        """
        # Clear existing references only if not incremental run
        if not GNAThub.incremental():
            self.log.info('clear existing results if any')
            GNAThub.Tool.clear_references(self.name)

        self.info('analyse report')

        self.tool = GNAThub.Tool(self.name)
        if not os.path.exists(self.output):
            self.error('no report found')
            return GNAThub.EXEC_FAILURE
        self.log.debug('parse XML report: %s', self.output)

        # List of resource messages suitable for tool level bulk insertion
        resources_messages = []
        # Map of list of messages by entities
        entities_messages_map = {}
        # List of entity messages suitable for tool level bulk insertion
        entities_messages = []
        # List of indirect call location
        indirect_loc_list = []

        try:
            tree = ElementTree.parse(self.output)
            global_node = tree.find('./global')

            # Retrieve the metrics and the map of subprogram by id
            subprograms = tree.find('./subprogramset').findall('./subprogram')
            if subprograms:
                unknown_global = GNAThub.Rule("Unknown Global Stack Usage",
                                              "Unknown Global Stack Usage",
                                              GNAThub.METRIC_KIND, self.tool)
                static_global = GNAThub.Rule("Static Global Stack Usage",
                                             "Static Global Stack Usage",
                                             GNAThub.METRIC_KIND, self.tool)
                unknown_local = GNAThub.Rule("Unknown Local Stack Usage",
                                             "Unknown Local Stack Usage",
                                             GNAThub.METRIC_KIND, self.tool)
                static_local = GNAThub.Rule("Static Local Stack Usage",
                                            "Static Local Stack Usage",
                                            GNAThub.METRIC_KIND, self.tool)
            for node in subprograms:
                subprogram_id = node.attrib.get('id')
                locations = node.find('./locationset').findall('./location')
                global_usage = node.find('./globalstackusage')
                local_usage = node.find('./localstackusage')
                name = node.attrib.get('prefixname')
                if name == "indirect call":
                    # The columns are only defined here so save them for later
                    line = locations[0].attrib.get('line')
                    column = locations[0].attrib.get('column')
                    indirect_loc_list.append([line, column])
                    continue
                else:
                    name = self.pp_name(name)

                if not locations:
                    if subprogram_id not in self.subprograms_without_location:
                        self.subprograms_without_location[subprogram_id] = name

                for loc in locations:
                    file = loc.attrib.get('file')
                    line = loc.attrib.get('line')
                    column = loc.attrib.get('column')
                    if file in self.resources:
                        resource = self.resources[file]
                    else:
                        resource = GNAThub.Resource(file, GNAThub.FILE_KIND)
                        self.resources[file] = resource

                    # entities default value for kind is set to "procedure"
                    entity = GNAThub.Entity(name, "action", int(line),
                                            int(column), int(column), resource)
                    # Only link the id to the first location of the entity
                    if subprogram_id not in self.subprograms:
                        self.subprograms[subprogram_id] = entity
                    else:
                        continue

                    size = global_usage.attrib.get('size')
                    if global_usage.attrib.get('qualifier') == "UNKNOWN":
                        metric = unknown_global
                    else:
                        metric = static_global
                    global_metric = GNAThub.Message(metric,
                                                    size,
                                                    ranking=GNATstack.RANKING)

                    size = local_usage.attrib.get('size')
                    if local_usage.attrib.get('qualifier') == "UNKNOWN":
                        metric = unknown_local
                    else:
                        metric = static_local
                    local_metric = GNAThub.Message(metric,
                                                   size,
                                                   ranking=GNATstack.RANKING)

                    entities_messages_map[subprogram_id] = ([[
                        global_metric, 0, 1, 1
                    ], [local_metric, 0, 1, 1]])

            # Analyse the indirect calls
            indirects = global_node.find('./indirectset').findall('./indirect')
            if indirects:
                indirect_rule = GNAThub.Rule("Indirect Call", "Indirect Call",
                                             GNAThub.RULE_KIND, self.tool)
            for node in indirects:
                indirect_id = node.attrib.get('id')
                if indirect_id not in self.subprograms:
                    continue

                set = node.find('./indirectcallset').findall('./indirectcall')
                for call in set:
                    line = call.find('./line').find('./value').text
                    # Go through the list of saved locations and use the
                    # line to retrieve a corresponding column
                    column = 1
                    pos = -1
                    for ix in range(len(indirect_loc_list)):
                        if indirect_loc_list[ix][0] == line:
                            pos = ix
                            column = indirect_loc_list[pos][1]
                            continue
                    if pos != -1:
                        indirect_loc_list.pop(pos)
                    message = GNAThub.Message(indirect_rule,
                                              self.pp_msg(
                                                  indirect_id,
                                                  "indirect call"),
                                              ranking=GNATstack.RANKING)
                    entities_messages_map[indirect_id].append(
                        [message, int(line),
                         int(column),
                         int(column)])

            # Analyse the external calls
            externals = global_node.find('./externalset').findall('./external')
            if externals:
                external_rule = GNAThub.Rule("External Call", "External Call",
                                             GNAThub.RULE_KIND, self.tool)
            for node in externals:
                subprogram_id = node.attrib.get('id')
                if subprogram_id not in self.subprograms:
                    continue
                message = GNAThub.Message(external_rule,
                                          self.pp_msg(subprogram_id,
                                                      "external call"),
                                          ranking=GNATstack.RANKING)
                entities_messages_map[subprogram_id].append([message, 0, 1, 1])

            # Analyse the potential cycle
            cycles = global_node.find('./cycleset').findall('./cycle')
            if cycles:
                cycle_rule = GNAThub.Rule("Potential Cycle", "Potential Cycle",
                                          GNAThub.RULE_KIND, self.tool)
            for node in cycles:
                cycle_subprograms = node.findall('./subprogram')
                cycle_list = []
                for sub in cycle_subprograms:
                    subprogram_id = sub.attrib.get('id')
                    cycle_list.append(self.subprograms[subprogram_id].name)
                subprogram_id = cycle_subprograms[0].attrib.get('id')
                cycle_list.append(self.subprograms[subprogram_id].name)
                message = GNAThub.Message(cycle_rule,
                                          "potential cycle detected:\n\t\t" +
                                          "\n\t\t".join(cycle_list),
                                          ranking=GNATstack.RANKING)
                entities_messages_map[subprogram_id].append([message, 0, 1, 1])

            # Analyse the unbounded frames
            unboundeds = (
                global_node.find('./unboundedset').findall('./unbounded'))
            if unboundeds:
                unbounded_rule = GNAThub.Rule("Unbounded Frame",
                                              "Unbounded Frame",
                                              GNAThub.RULE_KIND, self.tool)
            for node in unboundeds:
                subprogram_id = node.attrib.get('id')
                if subprogram_id in self.subprograms:
                    message = GNAThub.Message(unbounded_rule,
                                              self.pp_msg(
                                                  subprogram_id,
                                                  "unbounded frame"),
                                              ranking=GNATstack.RANKING)
                    entities_messages_map[subprogram_id].append(
                        [message, 0, 1, 1])

            # Analyse the entry points
            entries = tree.find('./entryset').findall('./entry')
            # There is always an entry, so create the rule anyway
            entry_rule = GNAThub.Rule("Entry point", "Entry point",
                                      GNAThub.RULE_KIND, self.tool)
            for node in entries:
                subprogram_id = node.attrib.get('id')

                if subprogram_id not in self.subprograms:
                    continue
                entity = self.subprograms[subprogram_id]
                local_stack = node.find('./localstackusage')
                size = local_stack.attrib.get('size')
                qualifier = local_stack.attrib.get('qualifier')

                if qualifier == "UNKNOWN":
                    text = "The estimated"
                else:
                    text = "The"
                text += (' call stack size for the entry point "%s" is %s' %
                         (entity.name, str(size)))

                callchain_list = []
                for sub in node.find('./callchain').findall('./subprogram'):
                    chain_id = sub.attrib.get('id')
                    if chain_id in self.subprograms:
                        callchain_list.append(self.subprograms[chain_id].name)
                    elif chain_id in self.subprograms_without_location:
                        callchain_list.append(
                            self.subprograms_without_location[chain_id])
                    else:
                        continue

                text += (" and the callchain is:\n\t\t%s" %
                         "\n\t\t".join(callchain_list))
                message = GNAThub.Message(entry_rule,
                                          text,
                                          ranking=GNATstack.RANKING)
                entities_messages_map[subprogram_id].append([message, 0, 1, 1])

            # Project message explaining the accuracy of the metrics
            accurate = global_node.find('./accurate')
            if accurate.find('./value').text == "FALSE":
                project = GNAThub.Resource(GNAThub.Project.name(),
                                           GNAThub.PROJECT_KIND)
                rule = GNAThub.Rule("Accuracy", "Accuracy", GNAThub.RULE_KIND,
                                    self.tool)
                text = ("worst case may not be accurate because of: " +
                        ("indirect calls/" if indirects else "") +
                        ("cycles/" if cycles else "") +
                        ("unbounded frames/" if unboundeds else "") +
                        ("external calls" if externals else ""))
                text = text[:-1] if text[-1] == '/' else text
                message = GNAThub.Message(rule,
                                          text,
                                          ranking=GNATstack.RANKING)
                resources_messages.append([project, [[message, 0, 1, 1]]])

            # Insert the messages and the metrics
            for key, value in entities_messages_map.items():
                entities_messages.append([self.subprograms[key], value])
            self.tool.add_messages(resources_messages, entities_messages)
        except ParseError as why:
            self.log.exception('failed to parse XML report')
            self.error('%s (%s:%s)' % (why, why.filename, why.lineno))
            return GNAThub.EXEC_FAILURE
        else:
            return GNAThub.EXEC_SUCCESS
Пример #9
0
)


base = GNAThub.Project.source_file('simple.adb')
resource = GNAThub.Resource.get(base)
assertIsNotNone(resource)
tool = GNAThub.Tool('test-tool')
assertIsNotNone(tool)
rule = GNAThub.Rule('test-rule', 'test-rule-name', GNAThub.RULE_KIND, tool)
assertIsNotNone(rule)
prop0 = GNAThub.Property('test-prop-0', 'test-prop-name-0')
assertIsNotNone(prop0)
prop1 = GNAThub.Property('test-prop-1', 'test-prop-name-1')
assertIsNotNone(prop1)

msg0 = GNAThub.Message(rule, 'test message', properties=None)
assertIsNotNone(msg0)
assertEmpty(msg0.get_properties())

msg1 = GNAThub.Message(rule, 'test message', properties=[prop0, prop1])
assertIsNotNone(msg1)

for msg in msg0, msg1:
    resource.add_message(msg)

assertNotEmpty(msg1.get_properties())
msg1_prop0 = msg1.get_properties()[0]
assertEqual(prop0.name, msg1_prop0.name)
assertEqual(prop0.identifier, msg1_prop0.identifier)

with assertRaises(Exception):