예제 #1
0
    def MergeChildren(node_a: ActionNode, node_b: ActionNode) -> None:
        assert not node_a.dead
        assert not node_b.dead
        assert node_a.action.name is not node_b.action.name
        node_a.AssertValidity()
        node_b.AssertValidity()

        node_a_name = node_a.action.name
        node_b_name = node_b.action.name

        children_a = list(node_a.children.copy().values())
        children_b = list(node_b.children.copy().values())

        for child in children_a + children_b:
            child = child.ResolveToAliveNode()
            child.AssertValidity()
            child_name = child.action.name
            if (child_name in node_a.children
                    and child_name in node_b.children):
                MergeNodes(node_a.children[child_name],
                           node_b.children[child_name])
            elif child_name in node_a.children:
                if (node_b_name in child.parents):
                    node_b = MergeNodes(node_b, child.parents[node_b_name])
                else:
                    node_b.AddChild(child)
            elif child_name in node_b.children:
                if (node_a_name in child.parents):
                    node_a = MergeNodes(node_a, child.parents[node_a_name])
                else:
                    node_a.AddChild(child)
            else:
                assert False
            node_a = node_a.ResolveToAliveNode()
            node_b = node_b.ResolveToAliveNode()

        resolved_children = ({
            k: node_a.children.get(k).ResolveToAliveNode()
            for k in node_a.children.keys()
        })
        node_a.children = resolved_children.copy()
        node_b.children = resolved_children

        merged_state_check_coverage = MergeStateCheckCoverage(
            node_a.state_check_actions_coverage,
            node_b.state_check_actions_coverage)
        node_a.state_check_actions.update(node_b.state_check_actions)
        node_a.state_check_actions_coverage = merged_state_check_coverage
        node_b.state_check_actions.update(node_a.state_check_actions)
        node_b.state_check_actions_coverage = merged_state_check_coverage.copy(
        )
        node_a.AssertValidity()
        node_b.AssertValidity()
예제 #2
0
    def AddActionListToGraph(parent: ActionNode, current: ActionNode,
                             action_list: List[Action], end: ActionNode,
                             partial_tests: Set[CoverageTest]) -> None:
        nonlocal root_node
        assert isinstance(parent, ActionNode)
        assert isinstance(end, ActionNode)
        assert len(action_list) > 0
        only_state_check_actions = True
        current.AssertValidity()
        end.AssertValidity()
        for action in action_list:
            assert isinstance(action, Action)
            if action.is_state_check:
                parent.AddStateCheckAction(action, ActionCoverage.PARTIAL)
                parent.partial_coverage_tests.update(partial_tests)
                continue
            only_state_check_actions = False
            if action.name in parent.children:
                current = parent.children[action.name]
            else:
                current = ActionNode(action)
                current.coverage = ActionCoverage.PARTIAL
                parent.AddChild(current)
            current.partial_coverage_tests.update(partial_tests)
            parent = current
        if current == end:
            return
        if only_state_check_actions:
            # If only state_check actions were added, then no need to add a new
            # edge.
            return
        logging.info("Merging children of\n{" + parent.GetGraphPathStr() +
                     "}\n{" + end.GetGraphPathStr() + "}")
        if current.action.name is end.action.name:
            MergeNodes(current, end)
        else:
            MergeChildren(current, end)

        root_node.AssertChildrenValidity()
예제 #3
0
    def MergeNodes(node_a: ActionNode, node_b: ActionNode) -> ActionNode:
        assert not node_a.dead
        assert not node_b.dead
        if node_a == node_b:
            return node_a
        assert node_a.action.name == node_b.action.name
        logging.info("Merging nodes with paths:\n{" +
                     node_a.GetGraphPathStr() + "},\n{" +
                     node_b.GetGraphPathStr() + "}")
        new_node = ActionNode(node_a.action)
        new_node.coverage = (ActionCoverage.FULL
                             if node_a.coverage == ActionCoverage.FULL
                             or node_b.coverage == ActionCoverage.FULL else
                             ActionCoverage.PARTIAL)
        new_node.state_check_actions = node_a.state_check_actions
        new_node.state_check_actions.update(node_b.state_check_actions)
        new_node.state_check_actions_coverage = MergeStateCheckCoverage(
            node_a.state_check_actions_coverage,
            node_b.state_check_actions_coverage)
        new_node.full_coverage_tests = node_a.full_coverage_tests
        new_node.full_coverage_tests.update(node_b.full_coverage_tests)
        new_node.partial_coverage_tests = node_a.partial_coverage_tests
        new_node.partial_coverage_tests.update(node_b.partial_coverage_tests)
        children_a = node_a.children.copy()
        children_b = node_b.children.copy()
        parents_a = node_a.parents.copy()
        parents_b = node_b.parents.copy()

        # Fully remove the merging nodes from the graph
        for child in list(children_a.values()) + list(children_b.values()):
            if new_node.action.name in child.parents:
                del child.parents[new_node.action.name]
        for parent in list(parents_a.values()) + list(parents_b.values()):
            if new_node.action.name in parent.children:
                del parent.children[new_node.action.name]

        # Merge children.
        # Start by adding the non-intersecting children to the dictionary.
        children = ({
            k: children_a.get(k, children_b.get(k)).ResolveToAliveNode()
            for k in (children_a.keys() ^ children_b.keys())
        })
        # For all children that are the same, they must be merged.
        children.update({
            k: MergeNodes(children_a[k].ResolveToAliveNode(),
                          children_b[k].ResolveToAliveNode())
            for k in (children_a.keys() & children_b.keys())
        })

        # Merge parents.
        # Start by adding the non-intersecting parents to the dictionary.
        parents = ({
            k: parents_a.get(k, parents_b.get(k)).ResolveToAliveNode()
            for k in (parents_a.keys() ^ parents_b.keys())
        })
        # For all parents that are the same, they must be merged.
        parents.update({
            k: MergeNodes(parents_a[k].ResolveToAliveNode(),
                          parents_b[k].ResolveToAliveNode())
            for k in (parents_a.keys() & parents_b.keys())
        })

        # Re-add the node back into the graph.
        for child in children.values():
            child = child.ResolveToAliveNode()
            new_node.AddChild(child)
        for parent in parents.values():
            parent = parent.ResolveToAliveNode()
            parent.AddChild(new_node)

        node_a.dead = new_node
        node_b.dead = new_node
        new_node.AssertValidity()
        return new_node