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)
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)
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
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)
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)