def testDFS(self): g = graph.DirectedGraph() a = g.addNode('a') b = g.addNode('b') c = g.addNode('c') d = g.addNode('d') g.addEdge('a', 'b') g.addEdge('b', 'c') g.addEdge('c', 'b') g.addEdge('c', 'd') starts, finishes, trees = g.doDFS(start='a') assert (max(finishes.values()) == finishes[a]) assert (min(finishes.values()) == finishes[d]) assert (min(starts.values()) == starts[a]) assert (max(starts.values()) == starts[d]) assert (len(trees) == 1) starts, finishes, trees = g.doDFS(start='b') assert (max(finishes.values()) == finishes[a]) assert (min(finishes.values()) == finishes[d]) assert (min(starts.values()) == starts[b]) assert (max(starts.values()) == starts[a]) assert (len(trees) == 2) assert (len(trees[a]) == 1) assert (len(trees[b]) == 3)
def testBFS(self): g = graph.DirectedGraph() a = g.addNode('a') b = g.addNode('b') c = g.addNode('c') d = g.addNode('d') g.addEdge('a', 'b') g.addEdge('b', 'c') g.addEdge('c', 'b') g.addEdge('c', 'd') starts, finishes, trees, pred, depth = g.doBFS(start='a') self.assertEqual([starts[x] for x in [a, b, c, d]], [0, 1, 3, 5]) self.assertEqual([finishes[x] for x in [a, b, c, d]], [2, 4, 6, 7]) assert (len(trees) == 1) self.assertEqual(depth[a], 0) self.assertEqual(depth[b], 1) self.assertEqual(depth[c], 2) self.assertEqual(depth[d], 3) starts, finishes, trees, pred, depth = g.doBFS(start='b') self.assertEqual([starts[x] for x in [a, b, c, d]], [6, 0, 1, 3]) self.assertEqual([finishes[x] for x in [a, b, c, d]], [7, 2, 4, 5]) assert (len(trees) == 2) assert (len(trees[a]) == 1) assert (len(trees[b]) == 3) self.assertEqual(depth[a], 0) self.assertEqual(depth[b], 0) self.assertEqual(depth[c], 1) self.assertEqual(depth[d], 2)
def testCreateDotFile(self): g = graph.DirectedGraph() s = StringIO() g.addNode('a') g.addNode('b') g.addEdge('a', 'b') g.generateDotFile(s) s.seek(0) self.assertEquals( s.read(), """\ digraph graphName { n0 [label="a"] n1 [label="b"] n0 -> n1 } """) s = StringIO() g.generateDotFile( s, lambda x: 'Node %s' % x, lambda fromNode, toNode, value: '%s -> %s: %s' % (fromNode, toNode, value)) s.seek(0) self.assertEquals( s.read(), """\ digraph graphName { n0 [label="Node a"] n1 [label="Node b"] n0 -> n1 [label="a -> b: 1"] } """)
def testGetDisconnected(self): g = graph.DirectedGraph() g.addNode('a') assert (sorted(g.getDisconnected()) == ['a']) g.addNode('b') assert (sorted(g.getDisconnected()) == ['a', 'b']) g.addEdge('a', 'b') assert (sorted(g.getDisconnected()) == []) g.addNode('c') g.addNode('d') assert (sorted(g.getDisconnected()) == ['c', 'd']) g.addEdge('a', 'c') assert (sorted(g.getDisconnected()) == ['d'])
def testSCC(self): g = graph.DirectedGraph() a = g.addNode('a') b = g.addNode('b') c = g.addNode('c') d = g.addNode('d') g.addEdge('a', 'b') g.addEdge('b', 'c') g.addEdge('c', 'b') g.addEdge('c', 'd') components = g.getStronglyConnectedComponents() assert (components == [set(['a']), set(['b', 'c']), set(['d'])]) g.addEdge('d', 'a') components = g.getStronglyConnectedComponents() assert (components == [set(['a', 'b', 'c', 'd'])])
def __init__(self, cfg, ui): self._cfg = cfg self._ui = ui self._exclusions = cfg.excludePoms.copy() self._inclusions = None # process excludePackages if cfg.packageAll: # cfg.package is an additional exclude list self._exclusions.extend(cfg.package) else: # cfg.package is an explicity include list self._inclusions = MavenCoordinateGlobList() self._inclusions.extend(cfg.package) self._pkgMap = {} # map group, artifact, version to package self.pkgQueue = graph.DirectedGraph() self._loaded = False
def do(self): grpGraph = graph.DirectedGraph() # get a top to bottom directed graph order for grp in self.recipe.troveMap.values(): nvf = grp.getNameVersionFlavor() grpGraph.addNode(nvf) for child in grp.iterTroveList(strongRefs=True): if child in self.recipe.troveMap: grpGraph.addEdge(nvf, child) order = grpGraph.getTotalOrdering() # build a list of paths, but go in the above order to # ensure sane results if self.checkImageGroups: policySets = dict((x[0], [[x]]) for x in order \ if self.recipe.groups[x[0]].imageGroup) else: policySets = {order[0][0]: [[order[0]]]} for nvf in order: grp = self.recipe.troveMap[nvf] for paths in policySets.values(): for path in [x for x in paths if x[-1] == nvf]: for child in grp.iterTroveList(strongRefs=True): newPath = path + [child] if child in self.recipe.troveMap: if self._pathAllowed(newPath): paths.append(newPath) # now we can use the final group in each chain to determine the # inclusion info for each trove. for groupName, paths in policySets.iteritems(): troveSet = [] for path in paths: grp = self.recipe.troveMap[path[-1]] cache = self.recipe.groups[grp.getName()].cache infoDict = {} for nvf, byDefault, isStrong in grp.iterTroveListInfo(): infoDict[nvf] = (byDefault, isStrong) for trovePath in self.walkTrove(path[:-1], cache, grp): byDefault, isStrong = infoDict[trovePath[-1]] troveSet.append((trovePath, byDefault, isStrong)) if troveSet: self.doTroveSet(troveSet)
def testTotalOrdering(self): g = graph.DirectedGraph() a = g.addNode('a') b = g.addNode('b') c = g.addNode('c') d = g.addNode('d') d = g.addNode('e') g.addEdge('a', 'b') g.addEdge('a', 'c') g.addEdge('a', 'd') g.addEdge('a', 'e') g.addEdge('b', 'e') g.addEdge('c', 'e') g.addEdge('d', 'e') def nodeSort(a, b): return cmp(ord(a[1]), ord(b[1])) assert (g.getTotalOrdering(nodeSort) == ['a', 'b', 'c', 'd', 'e']) # add back edge g.addNode('f') g.addEdge('e', 'f') g.addEdge('f', 'a') self.assertRaises(graph.BackEdgeError, g.getTotalOrdering, nodeSort) g.delete('f') g.delete('d') assert (g.getTotalOrdering(nodeSort) == ['a', 'b', 'c', 'e']) g.delete('a') assert (g.getTotalOrdering(nodeSort) == ['b', 'c', 'e']) g.delete('c') assert (g.getTotalOrdering(nodeSort) == ['b', 'e']) g.delete('e') assert (g.getTotalOrdering(nodeSort) == ['b']) assert (not g.isEmpty()) g.delete('b') assert (g.getTotalOrdering(nodeSort) == []) assert (g.isEmpty())
def testFlatten(self): g = graph.DirectedGraph() a = g.addNode('a') b = g.addNode('b') c = g.addNode('c') d = g.addNode('d') d = g.addNode('e') g.addEdge('a', 'b') g.addEdge('a', 'c') g.addEdge('a', 'd') g.addEdge('a', 'e') g.addEdge('b', 'e') g.addEdge('c', 'e') g.addEdge('d', 'e') g.flatten() assert (sorted(g.iterChildren('a')) == ['b', 'c', 'd', 'e']) assert (sorted(g.iterChildren('b')) == ['e']) assert (sorted(g.iterChildren('c')) == ['e']) assert (sorted(g.iterChildren('d')) == ['e']) assert (sorted(g.iterChildren('e')) == [])
def loadPolicy(recipeObj, policySet=None, internalPolicyModules=(), basePolicy=Policy): # path -> module policyPathMap = {} # bucket -> ordered list of policy objects policies = { TESTSUITE: [], DESTDIR_PREPARATION: [], DESTDIR_MODIFICATION: [], PACKAGE_CREATION: [], PACKAGE_MODIFICATION: [], ENFORCEMENT: [], ERROR_REPORTING: [], GROUP_ENFORCEMENT: [], } # bucket -> dict of policy classes policyMap = dict((b, {}) for b in policies.keys()) # name -> policy classes policyNameMap = {} # Load conary internal policy. Note that these are now loaded first, # so that pluggable policy may override internal policy. Also note # that the order of the internalPolicyModules list matters, as the # *last* module of a given name which is loaded wins. This is # also true of pluggable policy, so the policyDirs config option must # be carefully constructed in reverse order of preference. import conary.build.destdirpolicy import conary.build.derivedpolicy import conary.build.derivedcapsulepolicy import conary.build.infopolicy import conary.build.packagepolicy import conary.build.capsulepolicy import conary.build.grouppolicy for pt in internalPolicyModules: m = sys.modules['conary.build.' + pt] for symbolName in m.__dict__.keys(): policyCls = m.__dict__[symbolName] if type(policyCls) is not classType: continue if symbolName[0] != '_' and issubclass(policyCls, basePolicy): policyNameMap[symbolName] = policyCls # Load pluggable policy for policyDir in recipeObj.cfg.policyDirs: if not os.path.isdir(policyDir): continue for filename in sorted(os.listdir(policyDir)): fullpath = os.sep.join((policyDir, filename)) if not filename.endswith('.py') or not util.isregular(fullpath): continue # do not load shared libraries as policy! desc = [x for x in imp.get_suffixes() if x[0] == '.py'][0] f = file(fullpath) modname = filename[:-3] m = imp.load_module(modname, f, fullpath, desc) f.close() policyPathMap[fullpath] = m for symbolName in m.__dict__: policyCls = m.__dict__[symbolName] if type(policyCls) is not classType: continue if policySet is not None and symbolName not in policySet: continue if symbolName[0].isupper() and issubclass( policyCls, basePolicy): policyNameMap[symbolName] = policyCls # Enforce dependencies missingDeps = [] for policyCls in policyNameMap.values(): if hasattr(policyCls, 'requires'): for reqName, reqType in policyCls.requires: if reqType & REQUIRED and reqName not in policyNameMap: missingDeps.append((policyCls.__name__, reqName)) if missingDeps: raise PolicyError, '\n'.join( ('policy %s missing required policy %s' % (x, y) for x, y in missingDeps)) # Sort and initialize for policyName, policyCls in policyNameMap.iteritems(): policyMap[policyCls.bucket][policyName] = policyNameMap[policyName] for bucket in policyMap.keys(): dg = graph.DirectedGraph() for policyCls in policyMap[bucket].values(): dg.addNode(policyCls) if hasattr(policyCls, 'requires'): for reqName, reqType in policyCls.requires: if reqType & ORDERED and reqName in policyMap[bucket]: if reqType & PRIOR: dg.addEdge(policyNameMap[reqName], policyCls) else: dg.addEdge(policyCls, policyNameMap[reqName]) # test for dependency loops depLoops = [ x for x in dg.getStronglyConnectedComponents() if len(x) > 1 ] if depLoops: # convert to names depLoops = [sorted(x.__name__ for x in y) for y in depLoops] raise PolicyError, '\n'.join( 'found dependency loop: %s' % ', '.join(y) for y in depLoops) # store an ordered list of initialized policy objects policies[bucket] = [ x(recipeObj) for x in dg.getTotalOrdering( nodeSort=lambda a, b: cmp(a[1].__name__, b[1].__name__)) ] return policyPathMap, policies
def testDynamicBFS(self): # Dynamic graphs (the graph structure is not known in advance) g = graph.DirectedGraph() a = g.addNode('a') initialized = {} def getChildrenCallback(nodeIdx): node = g.get(nodeIdx) if nodeIdx not in initialized: if node == 'a': for toIdx in ['b', 'c', 'd']: g.addEdge(node, toIdx) elif node == 'b': for toIdx in ['d', 'e', 'f']: g.addEdge(node, toIdx) elif node in ['c', 'd']: for toIdx in ['g', 'h']: g.addEdge(node, toIdx) elif node == 'e': for toIdx in ['i']: g.addEdge(node, toIdx) elif node == 'i': for toIdx in ['j']: g.addEdge(node, toIdx) elif node == 'j': for toIdx in ['k']: g.addEdge(node, toIdx) initialized[nodeIdx] = True return g.edges[nodeIdx] starts, finishes, trees, pred, depth = g.doBFS( start='a', getChildrenCallback=getChildrenCallback) self.assertTrue(len([x for x in g.iterNodes()]), 13) self.assertFalse(g.getIndex('a') in pred) self.assertEqual(pred[g.getIndex('b')], g.getIndex('a')) self.assertEqual(pred[g.getIndex('c')], g.getIndex('a')) self.assertEqual(pred[g.getIndex('d')], g.getIndex('a')) self.assertEqual(pred[g.getIndex('e')], g.getIndex('b')) self.assertEqual(pred[g.getIndex('f')], g.getIndex('b')) self.assertEqual(pred[g.getIndex('g')], g.getIndex('c')) self.assertEqual(pred[g.getIndex('h')], g.getIndex('c')) self.assertEqual(pred[g.getIndex('i')], g.getIndex('e')) self.assertEqual(pred[g.getIndex('j')], g.getIndex('i')) self.assertEqual(pred[g.getIndex('k')], g.getIndex('j')) self.assertEqual(depth[g.getIndex('a')], 0) self.assertEqual(depth[g.getIndex('b')], 1) self.assertEqual(depth[g.getIndex('c')], 1) for i in ['e', 'f', 'g', 'h']: self.assertEqual(depth[g.getIndex(i)], 2) self.assertEqual(depth[g.getIndex('i')], 3) self.assertEqual(depth[g.getIndex('j')], 4) self.assertEqual(depth[g.getIndex('k')], 5) # Same thing, but limit the depth initialized.clear() starts, finishes, trees, pred, depth = g.doBFS( start='a', getChildrenCallback=getChildrenCallback, depthLimit=3) self.assertEqual(len(trees), 1) self.assertEqual(depth[g.getIndex('a')], 0) self.assertEqual(depth[g.getIndex('b')], 1) self.assertEqual(depth[g.getIndex('c')], 1) for i in ['e', 'f', 'g', 'h']: self.assertEqual(depth[g.getIndex(i)], 2) self.assertEqual(depth[g.getIndex('i')], 3) self.assertFalse(g.getIndex('j') in pred) self.assertFalse(g.getIndex('k') in pred)