Пример #1
0
    def test_autoloop(self):
        graph = sd3.cfa.graph.Graph()
        nodes = {}

        # Create nodes
        for i in range(1, 5):
            (nodes[i], _) = graph.add_node("%d" % i)

        graph.set_entry(nodes[1])

        # Create edges
        nodes[1].add_successor(nodes[2])

        # Self loop
        nodes[2].add_successor(nodes[3])

        nodes[2].add_successor(nodes[2])

        nodes[3].add_successor(nodes[4])

        # Build its dominator graph
        dom_graph = sd3.cfa.dominator.build_graph(graph)

        # Find loops
        found_loops = sd3.cfa.loop.find_loops(graph, dom_graph)
        self.assertEqual(len(found_loops), 1)

        expected_loop = self._create_node_set(nodes, [2])
        self.assertSetEqual(set(found_loops[0].get_node_list()), expected_loop)
Пример #2
0
    def _build_graph(self):
        graph = sd3.cfa.graph.Graph()
        nodes = {}

        # Create nodes
        for i in range(1, 12):
            (nodes[i], _) = graph.add_node("%d" % i)

        graph.set_entry(nodes[1])

        # Create edges
        nodes[1].add_successor(nodes[2])
        nodes[1].add_successor(nodes[3])

        nodes[2].add_successor(nodes[3])

        nodes[3].add_successor(nodes[4])

        nodes[4].add_successor(nodes[3])
        nodes[4].add_successor(nodes[5])
        nodes[4].add_successor(nodes[6])

        nodes[5].add_successor(nodes[7])

        nodes[6].add_successor(nodes[7])

        nodes[7].add_successor(nodes[3])
        nodes[7].add_successor(nodes[8])

        nodes[8].add_successor(nodes[9])
        nodes[8].add_successor(nodes[10])

        nodes[9].add_successor(nodes[11])

        nodes[10].add_successor(nodes[3])
        nodes[10].add_successor(nodes[7])
        nodes[10].add_successor(nodes[11])

        nodes[11].add_successor(nodes[1])

        return (graph, nodes)
Пример #3
0
    def test_shortest_path(self):
        graph = sd3.cfa.graph.Graph()

        # Create nodes
        (node1, _) = graph.add_node(1)
        (node2, _) = graph.add_node(2)
        (node3, _) = graph.add_node(3)
        (node4, _) = graph.add_node(4)
        (node5, _) = graph.add_node(5)
        (node6, _) = graph.add_node(6)
        (node7, _) = graph.add_node(7)

        # Create edges
        node1.add_successor(node2)
        node1.add_successor(node5)
        node1.add_successor(node7)

        node2.add_successor(node3)
        node2.add_successor(node4)

        node3.add_successor(node4)
        node3.add_successor(node7)

        node5.add_successor(node3)
        node5.add_successor(node5)
        node5.add_successor(node6)

        node7.add_successor(node6)

        # Check some paths
        self.assertEqual(sd3.cfa.shortestpath.get(graph, node1, node3), 2)
        self.assertEqual(sd3.cfa.shortestpath.get(graph, node1, node4), 2)
        self.assertEqual(sd3.cfa.shortestpath.get(graph, node1, node6), 2)
        self.assertEqual(sd3.cfa.shortestpath.get(graph, node1, node7), 1)

        self.assertEqual(sd3.cfa.shortestpath.get(graph, node2, node4), 1)
        self.assertEqual(sd3.cfa.shortestpath.get(graph, node2, node1),
                         sd3.cfa.shortestpath.INFINITE)

        self.assertEqual(sd3.cfa.shortestpath.get(graph, node5, node6), 1)
Пример #4
0
    def _build_dominators_graph(self):
        graph = sd3.cfa.graph.Graph()

        node_map = {}

        # Create nodes
        for node in self.nodes:
            (graph_node, _) = graph.add_node(node.get_id())

            parent_node = node.get_graph_node()
            graph_node.set_data(parent_node.get_data())
            node_map[node] = graph_node

        # Create edges
        for node in self.nodes:
            graph_node = node_map[node]

            for dom in node.get_dominators():
                graph_dom = node_map[dom]
                graph_dom.add_successor(graph_node)

        graph.set_entry(node_map[self.entry_node])

        return graph
Пример #5
0
    def test_graph(self):
        node_id = 1
        second_node_id = 2
        third_node_id = 2

        # New graph is empty
        graph = sd3.cfa.graph.Graph()
        self.assertIsNone(graph.get_entry())
        self.assertEqual(len(graph.get_node_list()), 0)

        # Forbid entry set on an unknown node
        node = sd3.cfa.graph.Node(node_id)
        self.assertRaises(KeyError, graph.set_entry, node)
        self.assertRaises(KeyError, graph.set_exit, node)

        # Test node add
        (node, is_new) = graph.add_node(node_id)
        self.assertEqual(node.get_id(), node_id)
        self.assertTrue(is_new)
        self.assertTrue(graph.has_node(node_id))

        # Test node add with the same id
        (existing_node, is_new) = graph.add_node(node_id)
        self.assertEqual(existing_node.get_id(), node_id)
        self.assertFalse(is_new)

        # Test that node can be fetched
        self.assertIs(graph.get_node(node_id), node)

        # Test set entry with an invalid node
        fake_node = sd3.cfa.graph.Node(node_id)
        self.assertRaises(KeyError, graph.set_entry, fake_node)
        self.assertRaises(KeyError, graph.set_exit, fake_node)

        # Test valid entry set
        graph.set_entry(node)
        self.assertIs(graph.get_entry(), node)

        # Test valid exit set
        graph.set_exit(node)
        self.assertIs(graph.get_exit(), node)

        # Test node list
        (second_node, _) = graph.add_node(second_node_id)
        self.assertListEqual(graph.get_node_list(), [node, second_node])

        # Test node iterator
        nodes_id = set()
        nodes_it = set()
        for it_node_id, it_node in graph.get_node_it():
            nodes_id.add(it_node_id)
            nodes_it.add(it_node)

        self.assertSetEqual(nodes_id, {node_id, second_node_id})
        self.assertSetEqual(nodes_it, {node, second_node})

        # Test edges
        (third_node, _) = graph.add_node(third_node_id)

        node.add_successor(second_node)
        second_node.add_successor(third_node)

        edge_set = set()
        for edge in list(graph.get_edges_it()):
            edge_set.add((edge.get_src(), edge.get_dest()))

        expected_edge_set = set()
        expected_edge_set.add((node, second_node))
        expected_edge_set.add((second_node, third_node))

        self.assertSetEqual(edge_set, expected_edge_set)

        # Run draw to test that the function doesn't crash
        node_id_str = lambda n: "%s" % n.get_id()
        (fd, path) = tempfile.mkstemp(suffix=".png")
        graph.draw(path, node_id_str=node_id_str)

        os.close(fd)
        os.remove(path)
Пример #6
0
    def test(self):
        graph = sd3.cfa.graph.Graph()
        nodes = {}

        # Create nodes
        for i in range(1, 12):
            (nodes[i], _) = graph.add_node("%d" % i)

        graph.set_entry(nodes[1])

        # Create edges
        nodes[1].add_successor(nodes[2])
        nodes[1].add_successor(nodes[3])

        nodes[2].add_successor(nodes[3])

        nodes[3].add_successor(nodes[4])

        nodes[4].add_successor(nodes[3])
        nodes[4].add_successor(nodes[5])
        nodes[4].add_successor(nodes[6])

        nodes[5].add_successor(nodes[7])

        nodes[6].add_successor(nodes[7])

        nodes[7].add_successor(nodes[3])
        nodes[7].add_successor(nodes[8])

        nodes[8].add_successor(nodes[9])
        nodes[8].add_successor(nodes[10])

        nodes[9].add_successor(nodes[11])

        nodes[10].add_successor(nodes[3])
        nodes[10].add_successor(nodes[7])
        nodes[10].add_successor(nodes[11])

        nodes[11].add_successor(nodes[1])

        # Build dominator tree
        dom_graph = sd3.cfa.dominator.build_graph(graph)

        nodes = {}

        # Create nodes
        for i in range(1, 12):
            nodes[i] = dom_graph.get_node("%d" % i)

        node_list = list(nodes)
        self._test_successors(node_list, nodes[1], [nodes[2], nodes[3]])
        self._test_successors(node_list, nodes[2], [])
        self._test_successors(node_list, nodes[3], [nodes[4]])
        self._test_successors(node_list, nodes[4],
                              [nodes[5], nodes[6], nodes[7]])
        self._test_successors(node_list, nodes[5], [])
        self._test_successors(node_list, nodes[6], [])
        self._test_successors(node_list, nodes[7], [nodes[8]])
        self._test_successors(node_list, nodes[8],
                              [nodes[9], nodes[10], nodes[11]])
        self._test_successors(node_list, nodes[9], [])
        self._test_successors(node_list, nodes[10], [])
        self._test_successors(node_list, nodes[11], [])

        # Test dominates function
        self.assertTrue(sd3.cfa.dominator.dominates(nodes[1], nodes[2]))
        self.assertTrue(sd3.cfa.dominator.dominates(nodes[1], nodes[5]))
        self.assertTrue(sd3.cfa.dominator.dominates(nodes[1], nodes[11]))

        self.assertTrue(sd3.cfa.dominator.dominates(nodes[4], nodes[9]))

        self.assertFalse(sd3.cfa.dominator.dominates(nodes[5], nodes[7]))

        self.assertFalse(sd3.cfa.dominator.dominates(nodes[10], nodes[8]))

        self.assertFalse(sd3.cfa.dominator.dominates(nodes[2], nodes[1]))

        # Run draw to test that the function doesn't crash
        (fd, path) = tempfile.mkstemp(suffix=".png")
        sd3.cfa.dominator.draw_graph(dom_graph, path)