def test_should_return_list_of_nodes_when_there_are_no_dependencies(self): nodes = ['a', 'b', 'c', 'd'] g = DependencyGraph() self._add_nodes_and_dependencies(g, nodes, []) result = g.toposort() self.assertEqual(result.sort(), nodes.sort(), 'Should return the node list in any order')
def test_get_dependent(self): nodes = ["a", "b", "c", "d", "e"] dependencies = [("a", "b"), ("b", "c"), ("c", "d"), ("e", "d")] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) self.assertEqual(graph.get_dependent(set("a")), set(("a", "b", "c", "d"))) self.assertEqual(graph.get_dependent(set("e")), set(("d", "e")))
def test_should_sort_in_topological_order_when_there_are_dependencies(self): nodes = ['a', 'b', 'c', 'd', 'e', 'f'] dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('e', 'f')] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) result = graph.toposort() self._check_result(result, dependencies)
def test_should_sort_in_topological_order_when_there_are_dependencies(self): nodes = ["a", "b", "c", "d", "e", "f"] dependencies = [("a", "b"), ("a", "c"), ("b", "d"), ("e", "f")] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) result = graph.toposort() self._check_result(result, dependencies)
def test_should_return_list_of_nodes_when_there_are_no_dependencies(self): nodes = ["a", "b", "c", "d"] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, []) result = graph.toposort() self.assertEqual(result.sort(), nodes.sort(), "Should return the node list in any order")
def test_get_dependent(self): nodes = ['a', 'b', 'c', 'd', 'e'] dependencies = [('a', 'b'), ('b', 'c'), ('c', 'd'), ('e', 'd')] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) self.assertEqual(graph.get_dependent(set('a')), set(('a', 'b', 'c', 'd'))) self.assertEqual(graph.get_dependent(set('e')), set(('d', 'e')))
def create_dependency_graph(self, implementation_dependencies=False): """ Create a DependencyGraph object of the HDL code project """ def add_dependency(start, end): """ Utility to add dependency """ if start.name == end.name: return is_new = dependency_graph.add_dependency(start, end) if is_new: LOGGER.debug('Adding dependency: %s depends on %s', end.name, start.name) def add_dependencies(dependency_function, files): """ Utility to add all dependencies returned by a dependency_function returning an iterator of dependencies """ for source_file in files: for dependency in dependency_function(source_file): add_dependency(dependency, source_file) dependency_graph = DependencyGraph() for source_file in self.get_source_files_in_order(): dependency_graph.add_node(source_file) vhdl_files = [ source_file for source_file in self.get_source_files_in_order() if source_file.file_type == 'vhdl' ] depend_on_package_bodies = self._depend_on_package_body or implementation_dependencies add_dependencies( lambda source_file: self._find_other_vhdl_design_unit_dependencies( source_file, depend_on_package_bodies, implementation_dependencies), vhdl_files) add_dependencies(self._find_primary_secondary_design_unit_dependencies, vhdl_files) verilog_files = [ source_file for source_file in self.get_source_files_in_order() if source_file.file_type in VERILOG_FILE_TYPES ] add_dependencies(self._find_verilog_package_dependencies, verilog_files) add_dependencies(self._find_verilog_module_dependencies, verilog_files) if implementation_dependencies: add_dependencies(self._find_component_design_unit_dependencies, vhdl_files) for source_file, depends_on in self._manual_dependencies: add_dependency(depends_on, source_file) return dependency_graph
def test_get_direct_dependencies_should_return_dependendencies_set(self): nodes = ["a", "b", "c", "d"] dependencies = [("a", "b"), ("a", "c")] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) result = graph.get_direct_dependencies("c") self.assertFalse("b" in result) self.assertTrue("a" in result)
def test_should_sort_in_topological_order_when_there_are_dependencies(self): nodes = ['a', 'b', 'c', 'd', 'e', 'f'] dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('e', 'f')] g = DependencyGraph() self._add_nodes_and_dependencies(g, nodes, dependencies) result = g.toposort() for d in dependencies: self.assertTrue(result.index(d[0]) < result.index(d[1]), "%s is not before %s" % d)
def test_get_direct_dependencies_should_return_dependendencies_set(self): nodes = ['a', 'b', 'c', 'd'] dependencies = [('a', 'b'), ('a', 'c')] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) result = graph.get_direct_dependencies('c') self.assertFalse('b' in result) self.assertTrue('a' in result)
def test_should_sort_in_topological_order_when_there_are_dependencies( self): nodes = ['a', 'b', 'c', 'd', 'e', 'f'] dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('e', 'f')] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) result = graph.toposort() self._check_result(result, dependencies)
def test_get_direct_dependencies_should_return_empty_set_when_no_dependendencies(self): nodes = ['a', 'b', 'c'] dependencies = [] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) result = graph.get_direct_dependencies('b') self.assertTrue(isinstance(result, (set))) self.assertFalse(result)
def test_get_direct_dependencies_should_return_empty_set_when_no_dependendencies( self): nodes = ['a', 'b', 'c'] dependencies = [] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) result = graph.get_direct_dependencies('b') self.assertTrue(isinstance(result, (set))) self.assertFalse(result)
def create_dependency_graph(self, implementation_dependencies=False): """ Create a DependencyGraph object of the HDL code project """ def add_dependency(start, end): """ Utility to add dependency """ if start.name == end.name: return is_new = dependency_graph.add_dependency(start, end) if is_new: LOGGER.debug('Adding dependency: %s depends on %s', end.name, start.name) def add_dependencies(dependency_function, files): """ Utility to add all dependencies returned by a dependency_function returning an iterator of dependencies """ for source_file in files: for dependency in dependency_function(source_file): add_dependency(dependency, source_file) dependency_graph = DependencyGraph() for source_file in self.get_source_files_in_order(): dependency_graph.add_node(source_file) vhdl_files = [source_file for source_file in self.get_source_files_in_order() if source_file.file_type == 'vhdl'] depend_on_package_bodies = self._depend_on_package_body or implementation_dependencies add_dependencies( lambda source_file: self._find_other_vhdl_design_unit_dependencies(source_file, depend_on_package_bodies, implementation_dependencies), vhdl_files) add_dependencies(self._find_primary_secondary_design_unit_dependencies, vhdl_files) verilog_files = [source_file for source_file in self.get_source_files_in_order() if source_file.file_type in VERILOG_FILE_TYPES] add_dependencies(self._find_verilog_package_dependencies, verilog_files) add_dependencies(self._find_verilog_module_dependencies, verilog_files) if implementation_dependencies: add_dependencies(self._find_component_design_unit_dependencies, vhdl_files) for source_file, depends_on in self._manual_dependencies: add_dependency(depends_on, source_file) return dependency_graph
def test_should_sort_in_topological_order_when_there_are_dependencies( self): nodes = ['a', 'b', 'c', 'd', 'e', 'f'] dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('e', 'f')] g = DependencyGraph() self._add_nodes_and_dependencies(g, nodes, dependencies) result = g.toposort() for d in dependencies: self.assertTrue( result.index(d[0]) < result.index(d[1]), "%s is not before %s" % d)
def test_get_dependencies_detects_circular_dependencies(self): nodes = ['a', 'b', 'c'] dependencies = [('b', 'a'), ('c', 'b'), ('a', 'c')] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) try: graph.get_dependencies(set('a')) except CircularDependencyException as exc: self.assertEqual(exc.path, ['a', 'b', 'c', 'a']) else: self.fail("Exception not raised")
def test_should_raise_runtime_error_exception_on_self_dependency(self): nodes = ["a", "b", "c", "d"] dependencies = [("a", "b"), ("a", "c"), ("b", "d"), ("d", "d")] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) try: graph.toposort() except CircularDependencyException as exc: self.assertEqual(exc.path, ["d", "d"]) else: self.fail("Exception not raised")
def test_should_raise_runtime_error_exception_on_long_circular_dependency(self): nodes = ['a', 'b', 'c', 'd'] dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('d', 'a')] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) try: graph.toposort() except CircularDependencyException as exc: self.assertEqual(exc.path, ['a', 'b', 'd', 'a']) else: self.fail("Exception not raised")
def test_get_dependencies_detects_circular_dependencies(self): nodes = ["a", "b", "c"] dependencies = [("b", "a"), ("c", "b"), ("a", "c")] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) try: graph.get_dependencies(set("a")) except CircularDependencyException as exc: self.assertEqual(exc.path, ["a", "b", "c", "a"]) else: self.fail("Exception not raised")
def test_should_raise_runtime_error_exception_on_long_circular_dependency(self): nodes = ["a", "b", "c", "d"] dependencies = [("a", "b"), ("a", "c"), ("b", "d"), ("d", "a")] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) try: graph.toposort() except CircularDependencyException as exc: self.assertEqual(exc.path, ["a", "b", "d", "a"]) else: self.fail("Exception not raised")
def test_should_raise_runtime_error_exception_on_self_dependency(self): nodes = ['a', 'b', 'c', 'd'] dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('d', 'd')] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) try: graph.toposort() except CircularDependencyException as exc: self.assertEqual(exc.path, ['d', 'd']) else: self.fail("Exception not raised")
def test_should_resort_after_additions(self): nodes = ["a", "b", "c", "d", "e", "f"] dependencies = [("a", "b"), ("a", "c"), ("b", "d"), ("e", "f")] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) graph.toposort() dependencies = [("a", "b"), ("a", "c"), ("b", "d"), ("e", "f"), ("b", "g")] graph.add_node("g") graph.add_dependency("b", "g") result = graph.toposort() self._check_result(result, dependencies)
def test_should_resort_after_additions(self): nodes = ['a', 'b', 'c', 'd', 'e', 'f'] dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('e', 'f')] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, dependencies) graph.toposort() dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('e', 'f'), ('b', 'g')] graph.add_node('g') graph.add_dependency('b', 'g') result = graph.toposort() self._check_result(result, dependencies)
def test_should_raise_runtime_error_exception_on_long_circular_dependency( self): nodes = ['a', 'b', 'c', 'd'] dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('d', 'a')] g = DependencyGraph() self._add_nodes_and_dependencies(g, nodes, dependencies) self.assertRaises(RuntimeError, g.toposort)
def _create_dependency_graph(self): """ Create a DependencyGraph object of the HDL code project """ def add_dependency(start, end): """ Utility to add dependency """ if start.name == end.name: return is_new = dependency_graph.add_dependency(start, end) if is_new: LOGGER.info('Adding dependency: %s depends on %s', end.name, start.name) def add_dependencies(dependency_function, files): """ Utility to add all dependencies returned by a dependency_function returning an iterator of dependencies """ for source_file in files: for dependency in dependency_function(source_file): add_dependency(dependency, source_file) dependency_graph = DependencyGraph() for source_file in self.get_source_files_in_order(): dependency_graph.add_node(source_file) vhdl_files = [source_file for source_file in self.get_source_files_in_order() if source_file.file_type == 'vhdl'] add_dependencies(self._find_other_design_unit_dependencies, vhdl_files) add_dependencies(self._find_primary_secondary_design_unit_dependencies, vhdl_files) verilog_files = [source_file for source_file in self.get_source_files_in_order() if source_file.file_type == 'verilog'] add_dependencies(self._find_verilog_package_dependencies, verilog_files) add_dependencies(self._find_verilog_module_dependencies, verilog_files) if self._depend_on_components: add_dependencies(self._find_component_design_unit_dependencies, vhdl_files) return dependency_graph
def test_should_resort_after_additions(self): nodes = ['a', 'b', 'c', 'd', 'e', 'f'] dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('e', 'f')] g = DependencyGraph() self._add_nodes_and_dependencies(g, nodes, dependencies) g.toposort() dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('e', 'f'), ('b', 'g')] g.add_node('g') g.add_dependency('b', 'g') result = g.toposort() for d in dependencies: self.assertTrue( result.index(d[0]) < result.index(d[1]), "%s is not before %s" % d)
def test_should_resort_after_additions(self): nodes = ['a', 'b', 'c', 'd', 'e', 'f'] dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('e', 'f')] g = DependencyGraph() self._add_nodes_and_dependencies(g, nodes, dependencies) g.toposort() dependencies = [('a', 'b'), ('a', 'c'), ('b', 'd'), ('e', 'f'), ('b', 'g')] g.add_node('g') g.add_dependency('b', 'g') result = g.toposort() for d in dependencies: self.assertTrue(result.index(d[0]) < result.index(d[1]), "%s is not before %s" % d)
def _create_dependency_graph(self): def add_dependency(start, end): if start.name == end.name: return is_new = dependency_graph.add_dependency(start, end) if is_new: logger.info('Adding dependency: %s depends on %s', end.name, start.name) def add_dependencies(dependency_function): for source_file in self.get_source_files_in_order(): for dependency in dependency_function(source_file): add_dependency(dependency, source_file) dependency_graph = DependencyGraph() for source_file in self.get_source_files_in_order(): dependency_graph.add_node(source_file) add_dependencies(self._find_other_design_unit_dependencies) add_dependencies(self._find_primary_secondary_design_unit_dependencies) return dependency_graph
def test_should_return_empty_compile_order_for_no_nodes(self): graph = DependencyGraph() self.assertEqual(graph.toposort(), [], 'Should return empty list')
def test_should_return_empty_compile_order_for_no_nodes(self): g = DependencyGraph() self.assertEqual(g.toposort(), [], 'Should return empty list')
def test_should_return_list_of_nodes_when_there_are_no_dependencies(self): nodes = ['a', 'b', 'c', 'd'] graph = DependencyGraph() self._add_nodes_and_dependencies(graph, nodes, []) result = graph.toposort() self.assertEqual(result.sort(), nodes.sort(), 'Should return the node list in any order')