示例#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 _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
示例#4
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)
示例#5
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)