Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    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"]
}
""")
Example #4
0
    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'])
Example #5
0
    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'])])
Example #6
0
    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
Example #7
0
 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)
Example #8
0
    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())
Example #9
0
    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')) == [])
Example #10
0
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
Example #11
0
    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)