예제 #1
0
    def testDistributedRedirect(self):
        store = self._connect()
        cu = store.db.cursor()

        flavor = deps.Flavor()
        localVer1 = ThawVersion("/localhost@test:trunk/10:1.1-10")
        localVer2 = ThawVersion("/localhost@test:trunk/20:1.2-20")
        remoteVer = ThawVersion("/localhost1@test:trunk/10:1.2-10")

        # this places /localhost1@test:trunk into the branch table, but not
        # the labels table
        trv = trove.Trove("group-foo", localVer1, flavor, None,
                          type = trove.TROVE_TYPE_REDIRECT)
        trv.addRedirect("target", remoteVer.branch(), flavor)
        trv.computeDigests()
        store.addTroveSetStart([], [], [])
        ti = store.addTrove(trv, trv.diff(None)[0], hidden = True)
        store.addTroveDone(ti)

        # and this needs the label to exist
        trv = trove.Trove("group-foo", localVer2, flavor, None)
        trv.addTrove("target", remoteVer, flavor)
        trv.computeDigests()
        ti = store.addTrove(trv, trv.diff(None)[0], hidden = True)
        store.addTroveDone(ti)
예제 #2
0
    def testDistributedRedirect(self):
        store = self._connect()
        cu = store.db.cursor()

        flavor = deps.Flavor()
        localVer1 = ThawVersion("/localhost@test:trunk/10:1.1-10")
        localVer2 = ThawVersion("/localhost@test:trunk/20:1.2-20")
        remoteVer = ThawVersion("/localhost1@test:trunk/10:1.2-10")

        # this places /localhost1@test:trunk into the branch table, but not
        # the labels table
        trv = trove.Trove("group-foo",
                          localVer1,
                          flavor,
                          None,
                          type=trove.TROVE_TYPE_REDIRECT)
        trv.addRedirect("target", remoteVer.branch(), flavor)
        trv.computeDigests()
        store.addTroveSetStart([], [], [])
        ti = store.addTrove(trv, trv.diff(None)[0], hidden=True)
        store.addTroveDone(ti)

        # and this needs the label to exist
        trv = trove.Trove("group-foo", localVer2, flavor, None)
        trv.addTrove("target", remoteVer, flavor)
        trv.computeDigests()
        ti = store.addTrove(trv, trv.diff(None)[0], hidden=True)
        store.addTroveDone(ti)
예제 #3
0
    def testGetSourceVersion(self):
        v = VersionFromString(
            '/conary.rpath.com@rpl:linux/4.3-1-0/autconf213/1')
        assert (not v.isBranchedBinary())
        source = v.getSourceVersion()
        assert (not source.isBranchedBinary())
        assert (source.asString() ==
                '/conary.rpath.com@rpl:linux/4.3-1/autconf213/1')

        # binary branched
        v = VersionFromString(
            '/conary.rpath.com@rpl:linux/4.3-1-1/autconf213/1')
        assert (v.isBranchedBinary())
        source = v.getSourceVersion()
        assert (not source.isBranchedBinary())
        assert (source.asString() == '/conary.rpath.com@rpl:linux/4.3-1')

        # make sure timestamps are removed
        v = ThawVersion('/conary.rpath.com@rpl:linux/1:4.3-1-0/autconf213/2:1')
        source = v.getSourceVersion()
        assert (source.timeStamps() == [0, 0])

        v = ThawVersion('/conary.rpath.com@rpl:linux/1:4.3-1-1/autconf213/2:1')
        source = v.getSourceVersion()
        assert (source.timeStamps() == [0])
예제 #4
0
 def testFindTrove(self):
     db = database.Database(':memory:', ':memory:')
     self.assertEqual(db.getTransactionCounter(), 0)
     flavor = deps.parseFlavor('~readline,!foo')
     v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10-1")
     f1 = files.FileFromFilesystem("/etc/passwd", self.id1)
     trv = trove.Trove("testcomp", v10, flavor, None)
     trv.addFile(self.id1, "/bin/1", v10, f1.fileId())
     trvInfo = db.addTrove(trv)
     db.addTroveDone(trvInfo)
     f2 = files.FileFromFilesystem("/etc/group", self.id2)
     v20 = ThawVersion("/conary.rpath.com@local:blah/20:1.3-2-1")
     trv = trove.Trove("testcomp", v20, flavor, None)
     trv.addFile(self.id2, "/bin/2", v20, f2.fileId())
     trvInfo = db.addTrove(trv)
     db.addTroveDone(trvInfo)
     tup = [('testcomp', v10, flavor)]
     tup2 = [('testcomp', v10, flavor), ('testcomp', v20, flavor)]
     assert (db.findTrove(None, ('testcomp', '1.2-10-1', None)) == tup)
     assert (db.findTrove(None, ('testcomp', '1.2', None)) == tup)
     assert (set(db.findTrove(
         None, ('testcomp', None, parseFlavor('!foo')))) == set(tup2))
     assert (db.findTrove(None, ('testcomp', ':trunk', None)) == tup)
     assert (db.findTrove([Label('conary.rpath.com@test:foo')],
                          ('testcomp', ':trunk', None)) == tup)
     assert (db.findTrove(None, ('testcomp', ':trunk', None)) == tup)
     assert (db.findTrove(None, ('testcomp', '@test:trunk', None)) == tup)
     assert (db.findTrove([Label('conary.rpath.com@blah:foo')],
                          ('testcomp', '@test:trunk', None)) == tup)
     # Transaction counter changes upon commit
     self.assertEqual(db.getTransactionCounter(), 0)
     db.commit()
     self.assertEqual(db.getTransactionCounter(), 1)
예제 #5
0
    def testVersionCache(self):
        versions.thawedVersionCache.clear()
        assert (not versions.thawedVersionCache)
        # test the thawed version cache
        verStr = "/foo.com@spc:bar/1:1.2-3/bang.com@spc:branch/2:2.4-5"
        v1 = ThawVersion(verStr)
        v2 = ThawVersion(verStr)
        assert (id(v1) == id(v2))
        assert (len(versions.thawedVersionCache) == 1)
        del v1
        assert (len(versions.thawedVersionCache) == 1)
        del v2
        assert (not versions.thawedVersionCache)

        versions.stringVersionCache.clear()
        v1 = VersionFromString("/foo.com@spc:bar/1.2-3")
        v2 = VersionFromString("/foo.com@spc:bar/1.2-3", timeStamps=[1.000])
        v3 = VersionFromString("/foo.com@spc:bar/1.2-3")
        v4 = VersionFromString("/foo.com@spc:bar/1.2-3")
        assert (v1.timeStamps() == [0])
        assert (v2.timeStamps() == [1])
        assert (id(v1) != id(v2))
        assert (id(v2) != id(v3))
        assert (id(v1) == id(v3))
        assert (id(v3) == id(v4))
예제 #6
0
    def testHidden(self):
        store = self._connect()
        cu = store.db.cursor()

        flavor = deps.Flavor()
        version = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")

        f = files.FileFromFilesystem("/etc/passwd", self.id)
        trv = trove.Trove("junk:data", version, flavor, None)
        trv.computeDigests()

        store.addTroveSetStart([], set(['/etc']), set(['passwd']))
        ti = store.addTrove(trv, trv.diff(None)[0], hidden=True)
        store.addTroveDone(ti)
        store.addTroveSetDone()

        assert (cu.execute("select count(*) from latestcache").fetchall()[0][0]
                == 0)
        assert (cu.execute("select isPresent from instances").fetchall()[0][0]
                == instances.INSTANCE_PRESENT_HIDDEN)

        store.presentHiddenTroves()
        assert (cu.execute("select count(*) from latestcache").fetchall()[0][0]
                == 3)
        assert (cu.execute("select isPresent from instances").fetchall()[0][0]
                == instances.INSTANCE_PRESENT_NORMAL)
예제 #7
0
 def testFindTrovesNotAcrossLabels(self):
     # Even when acrossLabels is false, if the trove source is not
     # ordered, don't discriminate by label path.
     # This may result in odd results but it is really the only sane
     # thing to do.
     v = ThawVersion('/localhost@rpl:linux/1:1.0-1-1')
     v2 = ThawVersion('/localhost@rpl:branch/2:1.0-1-1')
     ts = SimpleTroveSource([('a:run', v, deps.parseFlavor('')),
                             ('a:run', v2, deps.parseFlavor(''))])
     queries = [('a:run', None, None), ('a:run', '1.0', None),
                ('a:run', '1.0-1-1', None), ('a:run', 'localhost@', None)]
     for q in queries:
         results = ts.findTroves(None, [q],
                                 deps.parseFlavor(''),
                                 acrossLabels=False)
         assert (len(results[q]) == 2)
예제 #8
0
    def testMassiveIterTroves(self):
        store = self._connect()

        infoList = []
        expected = []
        f = deps.parseFlavor('is:x86')
        v = ThawVersion('/conary.rpath.com@test:trunk/10:1-1')
        # add 2000 test components
        store.addTroveSetStart([], [], [])
        for x in xrange(500):
            n = 'test%d:runtime' % x
            t = trove.Trove(n, v, f, None)
            t.computeDigests()
            troveInfo = store.addTrove(t, t.diff(None)[0])
            store.addTroveDone(troveInfo)
            # we want to iterTroves for each of our components (which
            # ends up being a no-op)
            infoList.append((n, v, f))
            expected.append(t)
        store.addTroveSetDone()
        start = time.time()
        result = [x for x in store.iterTroves(infoList)]
        end = time.time()

        # make sure we got the expected results
        assert (result == expected)
        # we should be able to iter through all of these troves in
        # well under one seconds
        if end - start > 5:
            sys.stderr.write("\nWarning: testMassiveIterTroves: test ran in "
                             "%.3f seconds, expected < 5\n\n" % (end - start))
예제 #9
0
    def testCommonFiles(self):
        # this test simulates a trove having the ame file in different
        # path locations with only changed mtimes.
        store = self._connect()
        flavor = deps.Flavor()
        version = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")

        baseNames = set(['file'])
        dirNames = set(['/junk1', '/junk2'])

        f = files.FileFromFilesystem("/etc/passwd", self.id)
        trv = trove.Trove("junk:data", version, flavor, None)
        trv.addFile(self.id1, "/junk1/file", version, f.fileId())
        trv.addFile(self.id2, "/junk2/file", version, f.fileId())
        trv.computeDigests()

        store.db.transaction()
        store.addTroveSetStart([], dirNames, baseNames)
        ti = store.addTrove(trv, trv.diff(None)[0])
        f.inode.mtime.set(1)
        ti.addFile(self.id1,
                   "/junk1/file",
                   f.fileId(),
                   version,
                   fileStream=f.freeze())
        f.inode.mtime.set(2)
        ti.addFile(self.id2,
                   "/junk2/file",
                   f.fileId(),
                   version,
                   fileStream=f.freeze())
        store.addTroveDone(ti)
        store.commit()
예제 #10
0
    def testRedirect(self):
        store = self._connect()

        old = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-3")
        x86 = deps.parseFlavor("is:x86")
        x86_64 = deps.parseFlavor("is:x86_64")

        redir = trove.Trove("trvname", old, x86, None,
                            type = trove.TROVE_TYPE_REDIRECT)
        redir.addRedirect("trv1", old.branch(), x86)
        redir.addRedirect("trv2", old.branch(), x86_64)
        redir.computeDigests()

        store.addTroveSetStart([], [], [])
        troveInfo = store.addTrove(redir, redir.diff(None)[0])
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()

        assert(store.getTrove("trvname", old, x86) == redir)
예제 #11
0
 def testSort(self):
     lst = []
     for i in range(1, 10):
         lst.append(
             ThawVersion("/foo.com@spc:bar/%d:1.0-%d" % ((10 - i), i)))
     # as time goes forward, source count #s go down
     # sorting is by timestamp only, so version with lowest timestamp
     # should be first in resulting list
     lst.sort()
     for i in range(1, 10):
         assert (lst[i - 1].freeze() == "/foo.com@spc:bar/%d.000:1.0-%d" %
                 (i, (10 - i)))
예제 #12
0
    def testTroveMultiFlavor(self):
        # create a package with 3 components, each use a different use
        # flag.  add the package before the components.  the goal is
        # to make the trovestore create more than one flavor
        flags = ('foo', 'bar', 'baz')
        flavors = []
        for flag in flags:
            flavor = deps.Flavor()
            flavor.addDep(
                deps.UseDependency,
                deps.Dependency('use', [(flag, deps.FLAG_SENSE_REQUIRED)]))
            flavor.addDep(deps.InstructionSetDependency,
                          deps.Dependency('x86', []))
            flavors.append(flavor)

        v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")
        store = self._connect()

        # create components to add to the package
        troves = []
        for flag, flavor in zip(flags, flavors):
            trv = trove.Trove('test:%s' % flag, v10, flavor, None)
            trv.computeDigests()
            troves.append(trv)

        # add the package
        union = deps.Flavor()
        for flavor in flavors:
            union.union(flavor)
        trv2 = trove.Trove("test", v10, union, None)
        for trv in troves:
            trv2.addTrove(trv.getName(), v10, trv2.getFlavor())
        trv2.computeDigests()
        store.addTroveSetStart([], [], [])
        troveInfo = store.addTrove(trv2, trv2.diff(None)[0])
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()

        # add the troves
        store.addTroveSetStart([], [], [])
        for trv in troves:
            troveInfo = store.addTrove(trv, trv.diff(None)[0])
            store.addTroveDone(troveInfo)
        store.addTroveSetDone()

        for trv in troves:
            self.assertEqual(
                trv,
                store.getTrove(trv.getName(), trv.getVersion(),
                               trv.getFlavor()))

        troveFlavors = store.getTroveFlavors({'test': [v10]})
        self.assertEqual(troveFlavors['test'][v10], [union.freeze()])
예제 #13
0
    def testVersionCache(self):
        versions.thawedVersionCache.clear()
        assert not versions.thawedVersionCache
        # test the thawed version cache
        verStr = "/foo.com@spc:bar/1:1.2-3/bang.com@spc:branch/2:2.4-5"
        v1 = ThawVersion(verStr)
        v2 = ThawVersion(verStr)
        assert id(v1) == id(v2)
        assert len(versions.thawedVersionCache) == 1
        del v1
        assert len(versions.thawedVersionCache) == 1
        del v2
        assert not versions.thawedVersionCache

        versions.stringVersionCache.clear()
        v1 = VersionFromString("/foo.com@spc:bar/1.2-3")
        v2 = VersionFromString("/foo.com@spc:bar/1.2-3", timeStamps=[1.000])
        v3 = VersionFromString("/foo.com@spc:bar/1.2-3")
        v4 = VersionFromString("/foo.com@spc:bar/1.2-3")
        assert v1.timeStamps() == [0]
        assert v2.timeStamps() == [1]
        assert id(v1) != id(v2)
        assert id(v2) != id(v3)
        assert id(v1) == id(v3)
        assert id(v3) == id(v4)
예제 #14
0
    def testVersionMatching(self):
        v1 = ThawVersion('/localhost@rpl:devel/1:1.0-1-1')
        v2 = ThawVersion('/localhost@rpl:devel/2:2.0-1-1')
        v1b = ThawVersion('/localhost@rpl:branch/3:1.0-1-1')
        v2b = ThawVersion('/localhost@rpl:branch/4:2.0-1-1')
        nodeps = deps.parseFlavor('')
        s = SimplestFindTroveSource()
        n = 'test'
        n2 = 'test2'

        t_v1 = (n, v1, nodeps)
        t_v2 = (n, v2, nodeps)
        t_v1b = (n, v1b, nodeps)
        t_v2b = (n, v2b, nodeps)

        t2_v1 = (n2, v1, nodeps)
        t2_v2 = (n2, v2, nodeps)
        t2_v1b = (n2, v1b, nodeps)
        t2_v2b = (n2, v2b, nodeps)

        lbl_a = v1.branch().label()
        lbl_b = v1b.branch().label()

        s.addTroves(t_v1, t_v2, t_v1b, t_v2b, t2_v1, t2_v2, t2_v1b, t2_v2b)

        d = s.getTroveLeavesByLabel({n : {lbl_a : None}, n2: {lbl_b: None}})
        assert(troveDictMatches(d, [t_v2, t2_v2b]))

        d = s.getTroveVersionsByLabel({n : {lbl_a : None}, n2 :{lbl_b:None}})
        assert(troveDictMatches(d, [t_v1, t_v2, t2_v2b, t2_v1b]))

        d = s.getTroveVersionsByLabel({n : {lbl_a : None, lbl_b: None}})
        assert(troveDictMatches(d, [t_v1, t_v2, t_v1b, t_v2b]))

        d = s.getTroveLeavesByBranch({n : {v1.branch() : None}, 
                                      n2: {v2b.branch() : None}})
        assert(troveDictMatches(d, [t_v2, t2_v2b]))

        d = s.getTroveVersionsByBranch({n : {v1.branch() : None},
                                       n2: {v2b.branch() : None}})
        assert(troveDictMatches(d, [t_v1, t_v2, t2_v1b, t2_v2b]))

        d = s.getTroveVersionFlavors({n  : {v1 : None, v2b : None},
                                      n2 : {v2 : None, v1b : None}})
        assert(troveDictMatches(d, [t_v1, t_v2b, t2_v2, t2_v1b]))
예제 #15
0
    def testRedirect(self):
        store = self._connect()

        old = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-3")
        x86 = deps.parseFlavor("is:x86")
        x86_64 = deps.parseFlavor("is:x86_64")

        redir = trove.Trove("trvname",
                            old,
                            x86,
                            None,
                            type=trove.TROVE_TYPE_REDIRECT)
        redir.addRedirect("trv1", old.branch(), x86)
        redir.addRedirect("trv2", old.branch(), x86_64)
        redir.computeDigests()

        store.addTroveSetStart([], [], [])
        troveInfo = store.addTrove(redir, redir.diff(None)[0])
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()

        assert (store.getTrove("trvname", old, x86) == redir)
예제 #16
0
    def testBrokenPackage(self):
        store = self._connect()

        v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")
        v20 = ThawVersion("/conary.rpath.com@test:trunk/20:1.2-20")
        flavor = deps.Flavor()
        flavor2 = deps.parseFlavor('is:x86')

        trv = trove.Trove("testpkg", v10, flavor, None)
        trv.addTrove("testpkg:runtime", v20, flavor)
        trv.computeDigests()

        store.addTroveSetStart([], [], [])
        troveInfo = store.addTrove(trv, trv.diff(None)[0])
        self.assertRaises(AssertionError, store.addTroveDone, troveInfo)

        store.rollback()

        trv = trove.Trove("testpkg", v10, flavor, None)
        trv.addTrove("testpkg:runtime", v10, flavor2)
        trv.computeDigests()
        troveInfo = store.addTrove(trv, trv.diff(None)[0])
        self.assertRaises(AssertionError, store.addTroveDone, troveInfo)
예제 #17
0
    def testDuplicateStreams(self):
        store = self._connect()
        flavor = deps.Flavor()

        v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")
        v20 = ThawVersion("/conary.rpath.com@test:trunk/20:1.2-20")

        dirNames = set(['/bin', '/etc'])
        baseNames = set(['1', '2'])

        f1 = files.FileFromFilesystem("/etc/passwd", self.id1)

        trv = trove.Trove("testpkg:runtime", v10, flavor, None)
        trv.addFile(f1.pathId(), "/bin/1", v10, f1.fileId())
        trv.computeDigests()

        store.db.transaction()
        store.addTroveSetStart([], dirNames, baseNames)
        troveInfo = store.addTrove(trv, trv.diff(None)[0])
        troveInfo.addFile(f1.pathId(), "/bin/1", f1.fileId(), v10)
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        store.db.commit()

        trv = trove.Trove("testpkg:runtime", v20, flavor, None)
        trv.addFile(f1.pathId(), "/bin/1", v20, f1.fileId())
        trv.addFile(f1.pathId(), "/bin/2", v20, f1.fileId())
        trv.computeDigests()

        store.db.transaction()
        store.addTroveSetStart([], dirNames, baseNames)
        troveInfo = store.addTrove(trv, trv.diff(None)[0])
        troveInfo.addFile(f1.pathId(), "/bin/1", f1.fileId(), v10)
        troveInfo.addFile(f1.pathId(), "/bin/2", f1.fileId(), v10)
        store.addTroveDone(troveInfo)
        store.db.commit()
예제 #18
0
    def testParenthood(self):
        v = ThawVersion("/foo.com@spc:bar/123.0:1.2-3/branch/456:1.1-2")
        assert (v.hasParentVersion())
        parentVersion = v.parentVersion()
        assert (parentVersion.asString() == "/foo.com@spc:bar/1.2-3")
        assert (parentVersion.trailingRevision().timeStamp == 123)

        v = ThawVersion(
            '/conary.rpath.com@rpl:devel//1//rpl-live.rb.rpath.com@rpl:1//local@local:COOK/123:1.0.1-0.6'
        )
        assert (v.hasParentVersion())
        parentVersion = v.parentVersion()
        assert (
            parentVersion.asString() ==
            '/conary.rpath.com@rpl:devel//1//rpl-live.rb.rpath.com@rpl:1/1.0.1-0.6'
        )
        assert (parentVersion.trailingRevision().timeStamp == 0)
예제 #19
0
    def testParenthood(self):
        v = ThawVersion("/foo.com@spc:bar/123.0:1.2-3/branch/456:1.1-2")
        assert v.hasParentVersion()
        parentVersion = v.parentVersion()
        assert parentVersion.asString() == "/foo.com@spc:bar/1.2-3"
        assert parentVersion.trailingRevision().timeStamp == 123

        v = ThawVersion("/conary.rpath.com@rpl:devel//1//rpl-live.rb.rpath.com@rpl:1//local@local:COOK/123:1.0.1-0.6")
        assert v.hasParentVersion()
        parentVersion = v.parentVersion()
        assert parentVersion.asString() == "/conary.rpath.com@rpl:devel//1//rpl-live.rb.rpath.com@rpl:1/1.0.1-0.6"
        assert parentVersion.trailingRevision().timeStamp == 0
예제 #20
0
    def testNodesTable(self):
        db = self.getDB()
        schema.createSchema(db)
        b = versionops.BranchTable(db)
        v = versiontable.VersionTable(db)
        i = items.Items(db)
        sv = versionops.SqlVersioning(db, v, b)
        ver = ThawVersion("/a.b.c@d:e/1:1-1-1")

        itemId = i.getOrAddId("foo")
        nodeId, versionId = sv.createVersion(itemId, ver, 0, None)
        cu = db.cursor()
        cu.execute("select sourceItemId from Nodes where nodeId = ?", nodeId)
        self.assertEqual(cu.fetchall()[0][0], None)
        srcId = i.getOrAddId("foo:source")
        sv.nodes.updateSourceItemId(nodeId, srcId)
        cu.execute("select sourceItemId from Nodes where nodeId = ?", nodeId)
        self.assertEqual(cu.fetchall()[0][0], srcId)
예제 #21
0
    def testRemoved(self):
        store = self._connect()

        old = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-3")
        x86 = deps.parseFlavor("is:x86")

        removed = trove.Trove("trvname",
                              old,
                              x86,
                              None,
                              type=trove.TROVE_TYPE_REMOVED)
        removed.computeDigests()

        store.addTroveSetStart([], [], [])
        troveInfo = store.addTrove(removed, removed.diff(None)[0])
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()

        assert (store.getTrove("trvname", old, x86) == removed)
예제 #22
0
    def testDuplicatePaths(self):
        store = self._connect()

        v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")
        flavor1 = deps.Flavor()
        flavor2 = deps.parseFlavor('is:x86')
        cl = changelog.ChangeLog("test", "*****@*****.**", "Changes\n")
        f1 = files.FileFromFilesystem("/etc/passwd", self.id1)

        trv1 = trove.Trove('testcomp', v10, flavor1, cl)
        trv1.addFile(f1.pathId(), "/bin/1", v10, f1.fileId())

        trv2 = trove.Trove('testcomp', v10, flavor2, cl)
        trv2.addFile(f1.pathId(), "/bin/1", v10, f1.fileId())

        store.db.transaction()
        store.addTroveSetStart([], set(['/bin']), set(['1']))

        troveInfo = store.addTrove(trv1, trv1.diff(None)[0])
        troveInfo.addFile(f1.pathId(),
                          "/bin/1",
                          f1.fileId(),
                          v10,
                          fileStream=f1.freeze())
        store.addTroveDone(troveInfo)

        troveInfo = store.addTrove(trv2, trv2.diff(None)[0])
        troveInfo.addFile(f1.pathId(),
                          "/bin/1",
                          f1.fileId(),
                          v10,
                          fileStream=f1.freeze())
        store.addTroveDone(troveInfo)

        store.addTroveSetDone()
        store.db.commit()

        # make sure the path was inserted into FilePaths and friends once
        cu = store.db.cursor()
        for tbl in ['FilePaths', 'Dirnames', 'Basenames']:
            cu.execute("select count(*) from %s" % tbl)
            self.assertEquals(cu.next()[0], 1)
예제 #23
0
    def testServerErrors(self):
        # try to get the repository to raise the errors from this class
        # by doing Bad Things.
        repos = self.openRepository()

        # add a pkg diff

        t = trove.Trove('foo', ThawVersion('/localhost@rpl:1/1.0:1.0-1-1'),
                        deps.parseFlavor('~!foo'), None)

        # create an absolute changeset
        cs = changeset.ChangeSet()
        cs.newTrove(t.diff(None)[0])
        try:
            repos.commitChangeSet(cs)
        except errors.TroveChecksumMissing, err:
            assert (
                str(err) ==
                'Checksum Missing Error: Trove foo=/localhost@rpl:1/1.0-1-1[~!foo] has no sha1 checksum calculated, so it was rejected.  Please upgrade conary.'
            )
예제 #24
0
    def testTroveSourceStack(self):
        # Test the behaviour of TroveSourceStack instances

        s1 = SimplestFindTroveSource()
        s2 = SimplestFindTroveSource()
        s3 = SimplestFindTroveSource()

        nodeps = deps.parseFlavor('')

        count = 3

        names = []
        versions = []
        for v in range(count):
            sv = str(v + 1)
            versions.append(ThawVersion('/localhost@rpl:devel/%s:1.0-1-1' %
                                        sv))
            names.append("test%s" % sv)

        # Generate troves
        t = []
        for i in range(count):
            l = []
            t.append(l)
            name = names[i]
            for j in range(count):
                l.append((name, versions[j], nodeps))

        s1.addTroves(t[0][1])
        s2.addTroves(t[0][0], t[1][1])
        s3.addTroves(t[0][2], t[1][0], t[2][2])

        # Catch an early bug with a bad index
        try:
            ts1 = stack(s1)
        except Exception, e:
            # No exception expected
            self.fail("Caught exception: %s" % e)
예제 #25
0
    def testRemoval(self):
        threshold = 60 * 5
        # 5 minutes

        def _dbStatus(db):
            stat = {}
            cu = db.cursor()

            for table in db.tables:
                cu.execute("SELECT * FROM %s" % table)
                l = cu.fetchall()
                # throw away anything which looks a timestamp; this will
                # break if the test case takes more than 5 minutes to run
                stat[table] = set()
                for row in l:
                    thisRow = []
                    for item in row:
                        if not isinstance(item, (float, decimal.Decimal)) or \
                                    abs(item - now) > threshold:
                            thisRow.append(item)

                    stat[table].add(tuple(thisRow))

            return stat

        def _checkStateDiff(one, two):
            if one != two:
                assert (one.keys() == two.keys())
                for key in one:
                    if one[key] != two[key]:
                        print "table %s has changed" % key
                raise AssertionError, "\n%s\n!=\n%s" % (one, two)

        store = self._connect()

        # get the current timestamp from the database
        cu = store.db.cursor()
        cu.execute('''create table timestamp(
                      foo     INTEGER,
                      changed NUMERIC(14,0) NOT NULL DEFAULT 0)''')
        store.db.loadSchema()
        store.db.createTrigger('timestamp', 'changed', "INSERT")
        cu.execute('insert into timestamp values(0, 0)')
        cu.execute('select changed from timestamp')
        now = cu.fetchall()[0][0]

        emptyState = _dbStatus(store.db)

        v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")
        v20 = ThawVersion("/conary.rpath.com@test:trunk/20:1.2-20")
        vB = ThawVersion("/conary.rpath.com@test:branch/1:0-0")
        vOtherRepo = ThawVersion("/other.repos.com@some:label/1:0-0")
        branch = v10.branch()

        flavor = deps.parseFlavor('is:x86')
        flavor64 = deps.parseFlavor('is:x86_64')

        store.createTroveBranch("trv:comp", branch)

        f1 = files.FileFromFilesystem("/etc/passwd", self.id1)
        f2 = files.FileFromFilesystem("/etc/services", self.id2)
        # add a file that has no contents sha1
        try:
            d = tempfile.mkdtemp()
            os.symlink('foo', d + '/foo')
            f5 = files.FileFromFilesystem(d + '/foo', self.id5)
        finally:
            shutil.rmtree(d)

        req = deps.parseDep("file: /bin/bash file: /bin/awk")

        dirNames = set(['/bin', ''])
        baseNames = set(['1', '2', 'distributed', 'foo', 'group-foo.recipe'])

        cl = changelog.ChangeLog("test", "*****@*****.**", "changelog\n")

        trv = trove.Trove('trv:comp', v10, flavor, cl)
        trv.addFile(f1.pathId(), "/bin/1", v10, f1.fileId())
        trv.addFile(f2.pathId(), "/bin/2", v10, f2.fileId())
        trv.addFile(self.id4, "/bin/distributed", v10, self.fid4)
        trv.addFile(f5.pathId(), "/bin/foo", v10, f5.fileId())
        trv.troveInfo.size.set(1234)
        trv.setRequires(req)

        store.db.transaction()
        store.addTroveSetStart([], dirNames, baseNames)
        troveInfo = store.addTrove(trv, trv.diff(None)[0])
        troveInfo.addFile(f1.pathId(),
                          "/bin/1",
                          f1.fileId(),
                          v10,
                          fileStream=f1.freeze())
        troveInfo.addFile(f2.pathId(),
                          "/bin/2",
                          f2.fileId(),
                          v10,
                          fileStream=f2.freeze())
        troveInfo.addFile(f5.pathId(),
                          "/bin/foo",
                          f5.fileId(),
                          v10,
                          fileStream=f5.freeze())
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        store.db.commit()
        oneTroveState = _dbStatus(store.db)

        rc = store._removeTrove("trv:comp", v10, flavor)
        self.assertEqual(set(rc), set([f1.contents.sha1(),
                                       f2.contents.sha1()]))
        state = _dbStatus(store.db)
        _checkStateDiff(state, emptyState)
        store.db.rollback()

        # the redir itself doesn't overlap with trv:comp; this makes sure
        # that the tables which the redir target needs are preserved
        redir = trove.Trove('redir:comp',
                            vB,
                            flavor64,
                            cl,
                            type=trove.TROVE_TYPE_REDIRECT)
        redir.addRedirect('trv:comp', v10.branch(), flavor)
        store.addTroveSetStart([], dirNames, baseNames)
        troveInfo = store.addTrove(redir, redir.diff(None)[0])
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        rc = store._removeTrove("trv:comp", v10, flavor)
        redir2 = store.getTrove('redir:comp', vB, flavor64)
        assert (redir == redir2)
        rc = store._removeTrove("redir:comp", vB, flavor64)
        state = _dbStatus(store.db)
        _checkStateDiff(state, emptyState)

        store.db.rollback()

        trv2 = trv.copy()
        trv2.changeVersion(v20)

        store.db.transaction()
        store.addTroveSetStart([], dirNames, baseNames)
        troveInfo = store.addTrove(trv2, trv2.diff(None)[0])
        troveInfo.addFile(f1.pathId(),
                          "/bin/1",
                          f1.fileId(),
                          v10,
                          fileStream=f1.freeze())
        troveInfo.addFile(f2.pathId(),
                          "/bin/2",
                          f2.fileId(),
                          v10,
                          fileStream=f2.freeze())
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        store.db.commit()
        twoTroveState = _dbStatus(store.db)

        rc = store._removeTrove("trv:comp", v20, flavor)
        assert (not rc)
        state = _dbStatus(store.db)
        _checkStateDiff(state, oneTroveState)
        rc = store._removeTrove("trv:comp", v10, flavor)
        assert (set(rc) == set([f1.contents.sha1(), f2.contents.sha1()]))
        state = _dbStatus(store.db)
        _checkStateDiff(state, emptyState)

        store.db.rollback()

        # add a trove which shares a file with trv:comp and make sure removing
        # it doesn't remove the sha1s (make sure the fileIds are different)
        anotherTrove = trove.Trove('another:comp', v10, flavor, cl)
        anotherF = f1.copy()
        anotherF.inode.owner.set('unowned')
        anotherTrove.addFile(f1.pathId(), "/bin/1", v10, anotherF.fileId())
        store.addTroveSetStart([], dirNames, baseNames)
        troveInfo = store.addTrove(anotherTrove, anotherTrove.diff(None)[0])
        troveInfo.addFile(f1.pathId(),
                          "/bin/1",
                          anotherF.fileId(),
                          v10,
                          fileStream=f1.freeze())
        store.addTroveDone(troveInfo)
        rc = store._removeTrove("another:comp", v10, flavor)
        assert (not rc)
        state = _dbStatus(store.db)
        _checkStateDiff(state, twoTroveState)

        store.db.rollback()

        # now try just marking something as removed
        rc = store.markTroveRemoved("trv:comp", v20, flavor)
        assert (not rc)
        removedTrove = store.getTrove("trv:comp", v20, flavor)
        assert (removedTrove.type() == trove.TROVE_TYPE_REMOVED)

        rc = store.markTroveRemoved("trv:comp", v10, flavor)
        assert (set(rc) == set([f1.contents.sha1(), f2.contents.sha1()]))
        removedTrove = store.getTrove("trv:comp", v10, flavor)
        assert (removedTrove.type() == trove.TROVE_TYPE_REMOVED)

        store.db.rollback()

        # test removing group-*:source
        anotherTrove = trove.Trove('group-foo:source', v10, flavor, cl)
        anotherF = f1.copy()
        anotherF.inode.owner.set('unowned')
        anotherTrove.addFile(f1.pathId(), "group-foo.recipe", v10,
                             anotherF.fileId())
        troveInfo = store.addTrove(anotherTrove, anotherTrove.diff(None)[0])
        troveInfo.addFile(f1.pathId(),
                          "group-foo.recipe",
                          anotherF.fileId(),
                          v10,
                          fileStream=anotherF.freeze())
        store.addTroveDone(troveInfo)
        rc = store._removeTrove("group-foo:source", v10, flavor)
        assert (not rc)
        state = _dbStatus(store.db)
        _checkStateDiff(state, twoTroveState)

        store.db.rollback()

        groupTrove = trove.Trove('group-foo', v10, flavor, cl)
        groupTrove.addTrove('foo', vOtherRepo, flavor)
        troveInfo = store.addTrove(groupTrove, groupTrove.diff(None)[0])
        store.addTroveDone(troveInfo)
        rc = store._removeTrove("group-foo", v10, flavor)
        state = _dbStatus(store.db)
        _checkStateDiff(state, twoTroveState)
        store.db.rollback()
예제 #26
0
class SqlDB(rephelp.RepositoryHelper):

    id1 = md5FromString("00010001000100010001000100010001")
    id2 = md5FromString("00010001000100010001000100010002")
    id3 = md5FromString("00010001000100010001000100010003")
    id4 = md5FromString("00010001000100010001000100010004")
    id7 = md5FromString("00010001000100010001000100010007")

    fid1 = sha1FromString("0001000100010001000100010001000100010001")
    fid2 = sha1FromString("0001000100010001000100010001000100010002")
    fid3 = sha1FromString("0001000100010001000100010001000100010003")
    fid4 = sha1FromString("0001000100010001000100010001000100010004")
    fid7 = sha1FromString("0001000100010001000100010001000100010007")

    v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")
    v20 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-20")

    emptyFlavor = deps.Flavor()

    noneTup = (None, None, None)

    def testPins(self):
        def _checkPins(*args):
            assert (db.trovesArePinned(troves) == list(args))

        x86Flavor = deps.parseFlavor('is:x86(cmov)')

        troves = [("first", self.v10, self.emptyFlavor),
                  ("second", self.v20, self.emptyFlavor),
                  ("third", self.v10, x86Flavor)]

        db = sqldb.Database(':memory:')

        for name, ver, flavor in troves:
            ti = db.addTrove(trove.Trove(name, ver, flavor, None))
            db.addTroveDone(ti)

        _checkPins(False, False, False)

        checks = [False] * 3
        for i in range(len(troves)):
            checks[i] = True
            db.pinTroves(*troves[i])
            _checkPins(*checks)

        for i in reversed(range(len(troves))):
            checks[i] = False
            db.pinTroves(*troves[i] + (False, ))
            _checkPins(*checks)

    def testIterAllTroves(self):
        trv1 = self.addComponent('foo:lib', '1')
        trv2 = self.addComponent('foo:debuginfo', '1')
        trv3 = self.addCollection('foo', '1', [':lib', (':debuginfo', False)])
        trv4 = self.addComponent('bar:run', '1', 'bam', filePrimer=1)
        self.updatePkg(['foo', 'bar:run[bam]'])
        db = self.openDatabase()
        assert (set(db.iterAllTroves()) == set(x.getNameVersionFlavor()
                                               for x in [trv1, trv3, trv4]))

    def testDBInstances(self):
        cx = dbstore.connect(":memory:", driver="sqlite")
        cx.loadSchema()
        idb = sqldb.DBInstanceTable(cx)
        idb.addId('fred', 1, 2, [1, 2])
        assert (idb[('fred', 1, 2)] == 1)
        assert (idb.getId(1) == ('fred', 1, 2, 1))
        assert (idb.get(('fred', 1, 2), None) == 1)

        idb.addId('wilma', 5, 6, [1, 2])
        assert (idb[('wilma', 5, 6)] == 2)
        idb.delId(2)
        self.assertRaises(KeyError, idb.__getitem__, ('wilma', 5, 6))
        idb.delId(1)
        assert (idb.get(('fred', 1, 2), None) == None)

    def testDBTroveFiles(self):
        cx = dbstore.connect(":memory:", driver="sqlite")
        cx.loadSchema()
        fs = sqldb.DBTroveFiles(cx)
        cu = cx.cursor()
        fs.addItem(cu, self.id1, 1, "/bin/ls", self.fid1, 11, "abc",
                   ["tag1", "tag2"])
        fs.addItem(cu, self.id2, 2, "/bin/cat", self.fid2, 11, "def", ["tag1"])
        fs.addItem(cu, self.id3, 1, "/bin/dd", self.fid3, 12, "tuv", [])
        fs.addItem(cu, self.id4, 2, "/bin/bc", self.fid4, 12, "xyz", [])
        assert ([x for x in fs[11]] == [("/bin/ls", "abc"),
                                        ("/bin/cat", "def")])
        assert ([x for x in fs[12]] == [("/bin/dd", "tuv"),
                                        ("/bin/bc", "xyz")])
        assert ([x for x in fs.iterFilesWithTag('tag1')
                 ] == ['/bin/cat', '/bin/ls'])
        assert ([x for x in fs.iterFilesWithTag('tag2')] == ['/bin/ls'])

        fs.delInstance(11)
        assert ([x for x in fs[11]] == [])

        # make sure the tags are gone
        assert ([x for x in fs.iterFilesWithTag('tag1')] == [])
        cu = cx.cursor()
        cu.execute('select * from DBFileTags')
        assert ([x for x in cu] == [])

        assert (fs.getFileByFileId(self.fid3, 0) == ("/bin/dd", "tuv"))
        self.assertRaises(KeyError, fs.getFileByFileId, self.fid7, 0)

        assert ([x for x in fs[12]] == [("/bin/dd", "tuv"),
                                        ("/bin/bc", "xyz")])
        fs.removePath(12, "/bin/dd")
        assert ([x for x in fs.getByInstanceId(12)] == [("/bin/bc", "xyz")])
        assert (fs.getFileByFileId(self.fid4,
                                   justPresent=False) == ('/bin/bc', 'xyz'))
        assert ([x for x in fs.getByInstanceId(12, justPresent=False)
                 ] == [("/bin/dd", "tuv"), ("/bin/bc", "xyz")])
        fs.delInstance(12)

        fs.addItem(cu, self.id1, 1, "/bin/ls", self.fid1, 11, "abc", [])
        fs.addItem(cu, self.id2, 2, "/bin/cat", self.fid2, 11, "def", [])
        fs.addItem(cu, self.id3, 1, "/bin/dd", self.fid3, 11, "tuv", [])
        fs.addItem(cu, self.id4, 2, "/bin/bc", self.fid4, 11, "xyz", [])
        assert ([x
                 for x in fs[11]] == [("/bin/ls", "abc"), ("/bin/cat", "def"),
                                      ("/bin/dd", "tuv"), ("/bin/bc", "xyz")])

    def testDatabase1(self):
        db = sqldb.Database(':memory:')

        f1 = files.FileFromFilesystem("/etc/passwd", self.id1)
        f2 = files.FileFromFilesystem("/etc/services", self.id2)
        f3 = files.FileFromFilesystem("/etc/group", self.id3)

        trv = trove.Trove("testcomp", self.v10, self.emptyFlavor, None)
        trv.addFile(self.id1, "/bin/1", self.v10, f1.fileId())
        trv.addFile(self.id2, "/bin/2", self.v10, f2.fileId())
        trv.addFile(self.id3, "/bin/3", self.v10, f3.fileId())
        trv.troveInfo.size.set(1234)
        trv.troveInfo.sourceName.set('thesource')

        req = deps.DependencySet()
        req.addDep(deps.FileDependencies, deps.Dependency("/bin/bash"))
        req.addDep(deps.TroveDependencies, deps.Dependency("foo:runtime"))
        req.addDep(deps.SonameDependencies, deps.Dependency("libtest.so.1"))
        trv.setRequires(req)

        trvInfo = db.addTrove(trv)

        db.addFile(trvInfo,
                   f1.pathId(),
                   "/bin/1",
                   f1.fileId(),
                   self.v10,
                   fileStream=f1.freeze())
        db.addFile(trvInfo,
                   f2.pathId(),
                   "/bin/2",
                   f2.fileId(),
                   self.v10,
                   fileStream=f2.freeze())
        db.addFile(trvInfo,
                   f3.pathId(),
                   "/bin/3",
                   f3.fileId(),
                   self.v10,
                   fileStream=f3.freeze())

        db.addTroveDone(trvInfo)

        dbTrv = db.getTroves([("testcomp", self.v10, self.emptyFlavor)])[0]
        assert (dbTrv == trv)
        assert (dbTrv.__class__ == trove.Trove)
        assert (db.trovesArePinned([("testcomp", self.v10, self.emptyFlavor)
                                    ]) == [False])
        dbTrv = db.getTroves([("testcomp", self.v10, self.emptyFlavor)],
                             withFileObjects=True)[0]
        assert (dbTrv == trv)
        assert (dbTrv.__class__ == trove.TroveWithFileObjects)
        for f in (f1, f2, f3):
            assert (dbTrv.getFileObject(f.fileId()) == f)

        trv2 = trove.Trove("testpkg", self.v10, self.emptyFlavor, None)
        ti = trv2.addTrove(trv.getName(), self.v10, trv.getFlavor())
        trv2.addTrove("weakref", self.v10, trv.getFlavor(), weakRef=True)
        ti = db.addTrove(trv2, pin=True)
        db.addTroveDone(ti)
        assert (db.trovesArePinned([("testpkg", self.v10, self.emptyFlavor)
                                    ]) == [True])
        assert (db.getTroves([("testpkg", self.v10, self.emptyFlavor)
                              ])[0] == trv2)
        assert (db.getTroves([
            ("testpkg", self.v10, self.emptyFlavor)
        ])[0].getVersion().timeStamps() == trv2.getVersion().timeStamps())

        assert (db.getTroves([("testpkg", self.v10, self.emptyFlavor),
                              ("testcomp", self.v10, self.emptyFlavor),
                              ("testitem", self.v10, self.emptyFlavor)],
                             True) == [trv2, trv, None])

        assert (db.getTroves([("testpkg", self.v10, self.emptyFlavor),
                              ("testcomp", self.v10, req)],
                             True) == [trv2, None])

        assert (db.findTroveContainers(["testpkg",
                                        "testcomp"]) == [[],
                                                         [("testpkg", self.v10,
                                                           self.emptyFlavor)]])

        assert (db.getTroveContainers([
            ("testpkg", self.v10, self.emptyFlavor),
            ("testcomp", self.v10, self.emptyFlavor)
        ]) == [[], [("testpkg", self.v10, self.emptyFlavor)]])

        res = db.findTroveReferences(["testpkg", "testcomp"])

        assert (db.findTroveReferences(["testpkg", "testcomp"
                                        ]) == [[],
                                               [("testcomp", self.v10,
                                                 self.emptyFlavor)]])

        v10new = VersionFromString("/conary.rpath.com@test:trunk/1.2-10")
        assert (db.getTroves([("testpkg", v10new, self.emptyFlavor)
                              ])[0] == trv2)
        assert (db.getTroves([
            ("testpkg", v10new, self.emptyFlavor)
        ])[0].getVersion().timeStamps() == trv2.getVersion().timeStamps())

        assert (set(db.findByNames(['testpkg', 'testcomp'])) == set([
            ("testpkg", self.v10, self.emptyFlavor),
            ("testcomp", self.v10, self.emptyFlavor)
        ]))

        db.eraseTrove("testcomp", self.v10, None)
        assert (db.getTroves([("testpkg", self.v10, self.emptyFlavor)
                              ])[0] == trv2)

        trv.computePathHashes()
        trvInfo = db.addTrove(trv)
        db.addFile(trvInfo,
                   f1.pathId(),
                   "/bin/1",
                   f1.fileId(),
                   self.v10,
                   fileStream=f1.freeze())
        db.addFile(trvInfo,
                   f2.pathId(),
                   "/bin/2",
                   f2.fileId(),
                   self.v10,
                   fileStream=f1.freeze())
        db.addFile(trvInfo,
                   f3.pathId(),
                   "/bin/3",
                   f3.fileId(),
                   self.v10,
                   fileStream=f1.freeze())
        db.addTroveDone(trvInfo)

        assert (db.getTroves([("testcomp", self.v10, self.emptyFlavor)
                              ])[0] == trv)
        db.removeFileFromTrove(trv, "/bin/1")
        changedTrv = db.getTroves([trv.getNameVersionFlavor()],
                                  pristine=False)[0]
        otherChangedTrv = db.getTroves([trv.getNameVersionFlavor()],
                                       withFiles=False,
                                       pristine=False)[0]
        assert (len(changedTrv.idMap) + 1 == len(trv.idMap))
        assert (len(changedTrv.troveInfo.pathHashes) + 1 == len(
            trv.troveInfo.pathHashes))
        assert (changedTrv.troveInfo.pathHashes ==
                otherChangedTrv.troveInfo.pathHashes)
        assert (len(otherChangedTrv.idMap) == 0)
        changedTrv.addFile(self.id1, "/bin/1", self.v10, f1.fileId())
        assert (changedTrv.idMap == trv.idMap)
        changedTrv.computePathHashes()
        assert (changedTrv.troveInfo.pathHashes == trv.troveInfo.pathHashes)

        assert (db.getTroves([("testcomp", self.v10, self.emptyFlavor)],
                             pristine=True)[0] == trv)
        db.eraseTrove("testpkg", self.v10, None)
        assert (db.getTroves([("testpkg", self.v10, self.emptyFlavor)
                              ]) == [None])
        self.assertRaises(KeyError, db.instances.getVersion, 100)

        db.eraseTrove("testcomp", self.v10, None)
        db.commit()
        cu = db.db.cursor()

        # make sure the versions got removed; the None entry is still there
        cu.execute("SELECT count(*) FROM Versions")
        assert (cu.next()[0] == 1)

        # make sure the dependency table got cleaned up
        cu.execute("SELECT count(*) FROM Dependencies")
        assert (cu.next()[0] == 0)

        # make sure the instances table got cleaned up
        cu.execute("SELECT count(*) FROM Instances")
        assert (cu.next()[0] == 0)

        # make sure the troveInfo table got cleaned up
        cu.execute("SELECT count(*) FROM TroveInfo")
        assert (cu.next()[0] == 0)

    def testDatabase2(self):
        db = sqldb.Database(':memory:')

        f1 = files.FileFromFilesystem("/etc/passwd", self.id1)
        f2 = files.FileFromFilesystem("/etc/services", self.id2)
        f3 = files.FileFromFilesystem("/etc/group", self.id3)

        trv = trove.Trove("testcomp", self.v10, self.emptyFlavor, None)
        trv.addFile(self.id1, "/bin/1", self.v10, f1.fileId())
        trv.addFile(self.id2, "/bin/2", self.v10, f2.fileId())
        trv.addFile(self.id3, "/bin/3", self.v10, f3.fileId())
        trvInfo = db.addTrove(trv)

        db.addFile(trvInfo,
                   f1.pathId(),
                   "/bin/1",
                   f1.fileId(),
                   self.v10,
                   fileStream=f1.freeze())
        db.addFile(trvInfo,
                   f2.pathId(),
                   "/bin/2",
                   f2.fileId(),
                   self.v10,
                   fileStream=f2.freeze())
        db.addFile(trvInfo,
                   f3.pathId(),
                   "/bin/3",
                   f3.fileId(),
                   self.v10,
                   fileStream=f3.freeze())

        db.addTroveDone(trvInfo)

        assert (db.getTroves([("testcomp", self.v10, self.emptyFlavor),
                              ("testcomp", self.v20, self.emptyFlavor)],
                             True) == [trv, None])
        assert (db.hasTroves([("testcomp", self.v10, self.emptyFlavor),
                              ("testcomp", self.v20, self.emptyFlavor)
                              ]) == [True, False])

        f2 = files.FileFromFilesystem("/etc/hosts", self.id2)

        trv2 = trove.Trove("testcomp", self.v20, self.emptyFlavor, None)
        trv2.addFile(self.id1, "/bin/1", self.v10, self.fid1)
        trv2.addFile(self.id2, "/bin/2", self.v20, self.fid2)

        #trvInfo = db.addTrove(trv2)
        #db.addFile(trvInfo, f2.pathId(), f2, "/bin/2", self.v20)

        #assert(db.getTrove("testcomp", self.v20, None) == trv2)

    def testDatabaseTransactionCounter(self):
        db = sqldb.Database(':memory:')
        field = 'transaction counter'
        # We should have a row
        cu = db.db.cursor()
        cu.execute("SELECT value FROM DatabaseAttributes WHERE name = ?",
                   field)
        row = cu.next()
        self.assertEqual(row[0], '0')

        updateq = "UPDATE DatabaseAttributes SET value = ? WHERE name = ?"
        # Update it manually
        cu.execute(updateq, '10', field)
        db.db.commit()

        self.assertEqual(db.getTransactionCounter(), 10)

        # Increment it
        self.assertEqual(db.incrementTransactionCounter(), 11)
        self.assertEqual(db.getTransactionCounter(), 11)

        # Delete entry, should reset the counter
        cu.execute("DELETE from DatabaseAttributes WHERE name = ?", field)
        db.db.commit()
        self.assertEqual(db.getTransactionCounter(), 0)
        self.assertEqual(db.incrementTransactionCounter(), 1)
        self.assertEqual(db.getTransactionCounter(), 1)

        self.assertEqual(db.incrementTransactionCounter(), 2)
        self.assertEqual(db.getTransactionCounter(), 2)

        # Mess it up
        cu.execute(updateq, 'not an integer', field)
        self.assertEqual(db.getTransactionCounter(), 0)
        self.assertEqual(db.incrementTransactionCounter(), 1)
        self.assertEqual(db.getTransactionCounter(), 1)

    def testDatabaseTroveInfoCleanup(self):
        # remove a trove but leave a reference - its troveInfo data
        # should be removed
        flavor1 = deps.parseFlavor('is:x86(cmov)')
        db = sqldb.Database(':memory:')
        trv1 = trove.Trove("testcomp:runtime", self.v10, flavor1, None)
        trvInfo = db.addTrove(trv1)
        db.addTroveDone(trvInfo)
        trv2 = trove.Trove("testcomp", self.v10, flavor1, None)
        trv2.addTrove(*trv1.getNameVersionFlavor())
        trvInfo = db.addTrove(trv2)
        db.addTroveDone(trvInfo)
        db.commit()

        db.eraseTrove("testcomp:runtime", self.v10, flavor1)
        db.commit()

        cu = db.db.cursor()
        cu.execute('select count(*) from instances join troveInfo '
                   'using(instanceId) where troveName="testcomp:runtime"')
        assert (not cu.fetchall()[0][0])

    def testDatabaseVersionCleanup(self):
        flavor1 = deps.parseFlavor('is:x86(cmov)')
        db = sqldb.Database(':memory:')
        cu = db.db.cursor()
        v10 = ThawVersion('/conary.rpath.com@test:trunk/10:1.2-10')
        v20 = ThawVersion('/conary.rpath.com@test:trunk/10:1.2-20')
        v30 = ThawVersion('/conary.rpath.com@test:trunk/10:1.2-30')

        # test file version cleanup
        trv = trove.Trove('testcomp:runtime', v10, flavor1, None)
        f1 = files.FileFromFilesystem('/etc/passwd', self.id1)
        f2 = files.FileFromFilesystem('/etc/services', self.id2)
        f3 = files.FileFromFilesystem('/etc/group', self.id3)
        trv.addFile(self.id1, '/bin/1', v10, f1.fileId())
        trv.addFile(self.id2, '/bin/2', v20, f2.fileId())
        trv.addFile(self.id3, '/bin/3', v30, f3.fileId())
        trvInfo = db.addTrove(trv)
        db.addFile(trvInfo,
                   f1.pathId(),
                   '/bin/1',
                   f1.fileId(),
                   v10,
                   fileStream=f1.freeze())
        db.addFile(trvInfo,
                   f2.pathId(),
                   '/bin/2',
                   f2.fileId(),
                   v20,
                   fileStream=f2.freeze())
        db.addFile(trvInfo,
                   f3.pathId(),
                   '/bin/3',
                   f3.fileId(),
                   v30,
                   fileStream=f3.freeze())
        db.addTroveDone(trvInfo)
        # check to see how many versions we have
        cu.execute('select count(*) from Versions')
        count = cu.fetchall()[0][0]
        # should have only 0|NULL
        self.assertEqual(count, 4)
        # now erase
        db.eraseTrove('testcomp:runtime', v10, flavor1)
        db.commit()
        cu.execute('select count(*) from Versions')
        count = cu.fetchall()[0][0]
        # should have only 0|NULL
        self.assertEqual(count, 1)

        # test trove version cleanup
        trv1 = trove.Trove('testcomp:runtime', v10, flavor1, None)
        trv2 = trove.Trove('group-test', v20, flavor1, None)
        trv2.addTrove(trv1.getName(),
                      trv1.getVersion(),
                      trv1.getFlavor(),
                      weakRef=True)
        trvInfo = db.addTrove(trv2)
        db.addTroveDone(trvInfo)
        db.commit()
        cu.execute('select count(*) from Versions')
        count = cu.fetchall()[0][0]
        self.assertEqual(count, 3)

        db.eraseTrove('group-test', v20, flavor1)
        db.commit()
        cu.execute('select count(*) from Versions')
        count = cu.fetchall()[0][0]
        # should have only 0|NULL
        self.assertEqual(count, 1)

    def testMultipleFlavorsInstalled(self):
        """
        verify that only one (unique) flavor is returned from
        db.iterVersionByName if multiple troves with the same version
        but different flavors are installed at the same time
        """
        db = sqldb.Database(':memory:')
        flavor1 = deps.parseFlavor('is:x86(cmov)')
        flavor2 = deps.parseFlavor('is:x86(sse)')
        trv1 = trove.Trove("testcomp", self.v10, flavor1, None)
        trv2 = trove.Trove("testcomp", self.v10, flavor2, None)
        ti = db.addTrove(trv1)
        db.addTroveDone(ti)
        ti = db.addTrove(trv2)
        db.addTroveDone(ti)
        assert ([x for x in db.iterVersionByName('testcomp', False)
                 ] == [self.v10])
        assert ([x for x in db.iterVersionByName('testcomp', True)
                 ] == [(self.v10, flavor1), (self.v10, flavor2)])

    def testGroupMissingComponent(self):
        flavor1 = deps.parseFlavor('is:x86(cmov)')
        db = sqldb.Database(':memory:')
        trv1 = trove.Trove("group1", self.v10, flavor1, None)
        ti = trv1.addTrove("subcomp", self.v10, flavor1)
        ti = trv1.addTrove("subcomp2", self.v10, flavor1)
        ti = trv1.addTrove("subcomp3", self.v10, flavor1, weakRef=True)
        ti = db.addTrove(trv1)
        db.addTroveDone(ti)

        trv2 = trove.Trove("group2", self.v10, flavor1, None)
        trv2.addTrove("subcomp", self.v10, flavor1, weakRef=True)
        ti = db.addTrove(trv2)
        db.addTroveDone(ti)

        trv3 = trove.Trove("subcomp2", self.v10, flavor1, None)
        ti = db.addTrove(trv3)
        db.addTroveDone(ti)

        inst, instRefed, strongMissing, weakMissing = db.getCompleteTroveSet(
            ["group1", "subcomp", "subcomp2", "subcomp3"])

        assert (inst == set([("group1", self.v10, flavor1)]))
        # this ensures the version returns has timestamps on it
        assert ([x for x in inst][0][1].freeze())
        assert (strongMissing == set([("subcomp", self.v10, flavor1)]))
        assert (weakMissing == set([("subcomp3", self.v10, flavor1)]))
        assert (instRefed == set([("subcomp2", self.v10, flavor1)]))

    def testVersion2Migration(self):
        dbfile = os.path.join(resources.get_archive(), 'conarydbs',
                              'conarydb-version-2')
        fd, fn = tempfile.mkstemp()
        os.close(fd)
        shutil.copyfile(dbfile, fn)
        db, str = self.captureOutput(sqldb.Database, fn)
        cu = db.db.cursor()
        # make sure that the -*none*- entry has been added
        cu.execute(
            'select count(*) from provides join dependencies on provides.depid=dependencies.depid and name="sqlite:lib" and flag="-*none*-"'
        )
        assert (cu.next() == (1, ))
        db.close()
        os.unlink(fn)

    def testVersion3Migration(self):
        dbfile = os.path.join(resources.get_archive(), 'conarydbs',
                              'conarydb-version-3')
        fd, fn = tempfile.mkstemp()
        os.close(fd)
        shutil.copyfile(dbfile, fn)
        db, str = self.captureOutput(sqldb.Database, fn)
        cu = db.db.cursor()
        db.close()
        os.unlink(fn)

    def testVersion11Migration(self):
        dbfile = os.path.join(resources.get_archive(), 'conarydbs',
                              'conarydb-version-11')
        fd, fn = tempfile.mkstemp()
        os.close(fd)
        shutil.copyfile(dbfile, fn)
        db, str = self.captureOutput(sqldb.Database, fn)
        cu = db.db.cursor()

        # make sure there aren't any install buckets left
        cu.execute("select count(*) from troveinfo where infoType=?",
                   trove._TROVEINFO_TAG_INSTALLBUCKET)
        assert (cu.next()[0] == 0)

        # make sure the path hashs look right for libpng:lib
        cu.execute(
            "select data from troveinfo, instances where "
            "trovename='libpng:lib' and "
            "troveinfo.instanceid=instances.instanceid "
            "and infoType=?", trove._TROVEINFO_TAG_PATH_HASHES)
        ph = trove.PathHashes(cu.next()[0])

        cu.execute("select path from instances, dbtrovefiles where "
                   "instances.instanceid=dbtrovefiles.instanceid "
                   "and troveName='libpng:lib'")
        for path, in cu:
            hash = md5String(path)[:8]
            assert (hash in ph)
            ph.remove(hash)

        assert (not ph)

        db.close()
        os.unlink(fn)

    def testVersion20Migration(self):
        dbfile = os.path.join(resources.get_archive(), 'conarydbs',
                              'conarydb-version-19')
        fd, fn = tempfile.mkstemp()
        os.close(fd)
        shutil.copyfile(dbfile, fn)
        # get a list of tables
        db = dbstore.connect(fn, driver='sqlite')
        db.loadSchema()
        cu = db.cursor()
        tableCounts = dict.fromkeys(db.tables.keys())
        for table in tableCounts.keys():
            tableCounts[table] = cu.execute('select count(*) from %s' %
                                            table).fetchall()[0][0]
        # DBInstances is gone...
        tableCounts.pop('DBInstances')
        # we have a VersionId 0 entry now
        tableCounts['Versions'] += 1
        # new table added
        tableCounts['DatabaseAttributes'] = 1

        # do the migration
        db, str = self.captureOutput(sqldb.Database, fn)
        cu = db.db.cursor()

        # make sure we have all the tables
        db2 = dbstore.connect(fn, driver='sqlite')
        db2.loadSchema()
        cu = db2.cursor()
        tableCounts2 = dict.fromkeys(db2.tables.keys())
        for table in tableCounts2.keys():
            tableCounts2[table] = cu.execute('select count(*) from %s' %
                                             table).fetchall()[0][0]
        self.assertEqual(tableCounts, tableCounts2)

        # check to make sure that we fixed our broken deps and troveinfo
        cu.execute("select count(*) from troveinfo where infoType=3 "
                   "and hex(data) == '31'")
        assert (cu.next()[0] == 0)
        cu.execute("select count(*) from dependencies where "
                   "name like 'conary:%' and flag='1'")
        assert (cu.next()[0] == 0)

        # verify the conary:runtime trove
        v = VersionFromString('/conary.rpath.com@rpl:devel//1/1.0-2-0.1')
        f = deps.parseFlavor('~!bootstrap is: x86')
        t = db.getTroves([('conary:runtime', v, f)])[0]
        t.verifyDigitalSignatures()

        # verify that we can insert a '1.0' into deps and troveinfo
        cu.execute("insert into Dependencies values (NULL, 4, 'test', '1.0')")
        cu.execute("select flag from Dependencies where name='test'")
        assert (cu.next()[0] == '1.0')

        cu.execute("insert into TroveInfo values (300, 3, '1.0')")
        cu.execute("select data from TroveInfo where instanceId=300 and "
                   "infotype=3")
        assert (cu.next()[0] == '1.0')

        db.close()
        db2.close()

        # make sure the addition of DatabaseAttributes happens correctly
        db = dbstore.connect(fn, driver='sqlite')
        db.loadSchema()
        self.assertTrue('DatabaseAttributes' in db.tables)
        cu = db.cursor()
        cu.execute("DROP TABLE DatabaseAttributes")
        db.commit()
        db.close()

        sdb = sqldb.Database(fn)
        self.assertTrue('DatabaseAttributes' in sdb.db.tables)
        del sdb

        os.unlink(fn)

    def testVersion20DeAnalyze(self):
        dbfile = os.path.join(resources.get_archive(), 'conarydbs',
                              'conarydb-version-20-with-analyze')
        fd, fn = tempfile.mkstemp()
        os.close(fd)
        shutil.copyfile(dbfile, fn)
        db = sqldb.Database(fn)
        cu = db.db.cursor()
        cu.execute('select count(*) from sqlite_stat1')
        count = cu.fetchall()[0][0]
        self.assertEqual(count, 0)
        db.close()
        os.unlink(fn)

    def testMigrationReadOnly(self):
        dbfile = os.path.join(resources.get_archive(), 'conarydbs',
                              'conarydb-version-2')
        fd, fn = tempfile.mkstemp()
        os.close(fd)
        shutil.copyfile(dbfile, fn)
        os.chmod(fn, 0444)
        try:
            db = sqldb.Database(fn)
        except sqldb.OldDatabaseSchema:
            pass
        else:
            raise
        os.unlink(fn)

    def testSubtroveUpdates(self):
        db = sqldb.Database(':memory:')

        pkg = trove.Trove("testpkg", self.v10, self.emptyFlavor, None)
        pkg.addTrove("testpkg:comp", self.v10, self.emptyFlavor)
        ti = db.addTrove(pkg)
        db.addTroveDone(ti)

        comp1 = trove.Trove("testpkg:comp", self.v10, self.emptyFlavor, None)
        ti = db.addTrove(comp1)
        db.addTroveDone(ti)
        comp2 = trove.Trove("testpkg:comp", self.v20, self.emptyFlavor, None)
        ti = db.addTrove(comp1)
        db.addTroveDone(ti)
        #
        ti = db.addTrove(
            #("testpkg:comp", self.v10, self.emptyFlavor),
            comp2)
        db.addTroveDone(ti)
        db.eraseTrove("testpkg:comp", self.v10, self.emptyFlavor)

        pristinePkg = db.getTroves([("testpkg", self.v10, self.emptyFlavor)],
                                   pristine=True)[0]
        instPkg = db.getTroves([("testpkg", self.v10, self.emptyFlavor)],
                               pristine=False)[0]
        assert (pristinePkg == pkg)
        assert (instPkg != pkg)

        ti = db.addTrove(
            #("testpkg:comp", self.v20, self.emptyFlavor),
            comp1)
        db.addTroveDone(ti)
        db.eraseTrove("testpkg:comp", self.v20, self.emptyFlavor)

        pristinePkg = db.getTroves([("testpkg", self.v10, self.emptyFlavor)],
                                   pristine=True)[0]
        instPkg = db.getTroves([("testpkg", self.v10, self.emptyFlavor)],
                               pristine=False)[0]
        assert (pristinePkg == pkg)
        assert (instPkg == pkg)

        # make sure there aren't broken bits in TroveTroves
        assert (db.db.cursor().execute(
            "select count(*) from trovetroves").next()[0] == 1)

    def testMapPinned(self):
        # test to ensure that a if you update a pinned trove twice,
        # a duplicate entry does not show up in TroveTroves.
        db = sqldb.Database(':memory:')

        pkg = trove.Trove("testpkg", self.v20, self.emptyFlavor, None)
        pkg.addTrove("testpkg:comp", self.v20, self.emptyFlavor)
        ti = db.addTrove(pkg)
        db.addTroveDone(ti)

        comp1 = trove.Trove("testpkg:comp", self.v10, self.emptyFlavor, None)
        ti = db.addTrove(comp1)
        db.addTroveDone(ti)
        # we've got a trove with a link from trove to component.
        # we assume the component was pinned at v10...now we need to update
        # the link to point to the v10 ver.
        db.mapPinnedTroves([('testpkg:comp', (self.v10, self.emptyFlavor),
                             (self.v20, self.emptyFlavor))])
        cu = db.db.cursor()
        assert (
            cu.execute('SELECT COUNT(*) FROM TroveTroves WHERE inPristine=0'
                       ).next()[0] == 1)
        db.mapPinnedTroves([('testpkg:comp', (self.v10, self.emptyFlavor),
                             (self.v20, self.emptyFlavor))])
        assert (
            cu.execute('SELECT COUNT(*) FROM TroveTroves WHERE inPristine=0'
                       ).next()[0] == 1)
        pkg = db.getTroves([('testpkg', self.v20, self.emptyFlavor)],
                           pristine=False)[0]
        assert (pkg.strongTroves.keys()[0][1] == self.v10)
        assert (pkg.weakTroves.keys() == [])
예제 #27
0
    def testDatabaseVersionCleanup(self):
        flavor1 = deps.parseFlavor('is:x86(cmov)')
        db = sqldb.Database(':memory:')
        cu = db.db.cursor()
        v10 = ThawVersion('/conary.rpath.com@test:trunk/10:1.2-10')
        v20 = ThawVersion('/conary.rpath.com@test:trunk/10:1.2-20')
        v30 = ThawVersion('/conary.rpath.com@test:trunk/10:1.2-30')

        # test file version cleanup
        trv = trove.Trove('testcomp:runtime', v10, flavor1, None)
        f1 = files.FileFromFilesystem('/etc/passwd', self.id1)
        f2 = files.FileFromFilesystem('/etc/services', self.id2)
        f3 = files.FileFromFilesystem('/etc/group', self.id3)
        trv.addFile(self.id1, '/bin/1', v10, f1.fileId())
        trv.addFile(self.id2, '/bin/2', v20, f2.fileId())
        trv.addFile(self.id3, '/bin/3', v30, f3.fileId())
        trvInfo = db.addTrove(trv)
        db.addFile(trvInfo,
                   f1.pathId(),
                   '/bin/1',
                   f1.fileId(),
                   v10,
                   fileStream=f1.freeze())
        db.addFile(trvInfo,
                   f2.pathId(),
                   '/bin/2',
                   f2.fileId(),
                   v20,
                   fileStream=f2.freeze())
        db.addFile(trvInfo,
                   f3.pathId(),
                   '/bin/3',
                   f3.fileId(),
                   v30,
                   fileStream=f3.freeze())
        db.addTroveDone(trvInfo)
        # check to see how many versions we have
        cu.execute('select count(*) from Versions')
        count = cu.fetchall()[0][0]
        # should have only 0|NULL
        self.assertEqual(count, 4)
        # now erase
        db.eraseTrove('testcomp:runtime', v10, flavor1)
        db.commit()
        cu.execute('select count(*) from Versions')
        count = cu.fetchall()[0][0]
        # should have only 0|NULL
        self.assertEqual(count, 1)

        # test trove version cleanup
        trv1 = trove.Trove('testcomp:runtime', v10, flavor1, None)
        trv2 = trove.Trove('group-test', v20, flavor1, None)
        trv2.addTrove(trv1.getName(),
                      trv1.getVersion(),
                      trv1.getFlavor(),
                      weakRef=True)
        trvInfo = db.addTrove(trv2)
        db.addTroveDone(trvInfo)
        db.commit()
        cu.execute('select count(*) from Versions')
        count = cu.fetchall()[0][0]
        self.assertEqual(count, 3)

        db.eraseTrove('group-test', v20, flavor1)
        db.commit()
        cu.execute('select count(*) from Versions')
        count = cu.fetchall()[0][0]
        # should have only 0|NULL
        self.assertEqual(count, 1)
예제 #28
0
    def testFlavorMatchingAsRepository(self):
        # presumes that version matches work
        # and just tests flavoring
        # uses repository style 
        v1 = ThawVersion('/localhost@rpl:devel/1:1.0-1-1')
        v2 = ThawVersion('/localhost@rpl:devel/2:2.0-1-1')
        nodeps = deps.parseFlavor('')
        rl_nossl = deps.parseFlavor('readline,!ssl')
        rl_ssl = deps.parseFlavor('readline,ssl')
        norl_ssl = deps.parseFlavor('!readline,ssl')
        norl_nossl = deps.parseFlavor('!readline,!ssl')
        p_rl_nossl = deps.parseFlavor('~readline,~!ssl')
        p_rl_ssl = deps.parseFlavor('~readline,~ssl')
        p_norl_ssl = deps.parseFlavor('~!readline,~ssl')
        p_norl_nossl = deps.parseFlavor('~!readline,~!ssl')
        ssl = deps.parseFlavor('ssl')
        rl = deps.parseFlavor('readline')

        s = SimplestFindTroveSource()
        s.searchAsRepository()
        n = 'test:run'
        n2 = 'test2:run'
        t_v1_rl_nossl = (n, v1, rl_nossl)
        t_v1_norl_ssl = (n, v1, norl_ssl)
        t_v2_norl_nossl = (n, v2, norl_nossl)
        t_v2_rl_ssl = (n, v2, rl_ssl)
        lbl_a = v1.branch().label()

        s.addTroves(t_v1_rl_nossl, t_v1_norl_ssl, t_v2_norl_nossl, t_v2_rl_ssl)
        for trv in t_v1_rl_nossl, t_v1_norl_ssl, t_v2_norl_nossl, t_v2_rl_ssl:
            self.addComponent(*trv)
        repos = self.openRepository()

        assert(s.hasTroves([t_v1_rl_nossl])[0])
        for src in s, repos:
            d = s.getTroveLeavesByLabel({n : {lbl_a : [rl_nossl]}})
            assert(troveDictMatches(d, [t_v1_rl_nossl]))
        
            # if you specify flavors, and bestFlavor is False you all 
            # allowed flavors back,  not just the best match.  In this
            # case ~rl, does not match !readline, so we only get the rl,ssl
            # trove returned
            d = src.getTroveLeavesByLabel({n : {lbl_a : [p_rl_nossl]}}, 
                                        bestFlavor=False)
            assert(troveDictMatches(d, [t_v2_rl_ssl, t_v1_rl_nossl]))


            d = src.getTroveLeavesByLabel({n : {lbl_a : [rl_nossl, rl_ssl]}},
                                          bestFlavor=True)
            assert(troveDictMatches(d, [t_v1_rl_nossl, t_v2_rl_ssl]))

            d = src.getTroveLeavesByLabel({n : {lbl_a : [nodeps]}},
                                          bestFlavor=True)
            assert(troveDictMatches(d, [t_v2_norl_nossl]))

            d = src.getTroveLeavesByLabel({n : {lbl_a : [ssl]}},
                                          bestFlavor=True)
            assert(troveDictMatches(d, [t_v1_norl_ssl]))

            d = src.getTroveLeavesByLabel({n : {lbl_a : [p_norl_ssl]}},
                                          bestFlavor=True)
            assert(troveDictMatches(d, [t_v2_rl_ssl]))

        s.searchAsDatabase()

        # with database, only strong flavors are allowed, so only the
        # rl_nossl trove matches even with bestFlavor = False
        d = s.getTroveLeavesByLabel({n : {lbl_a : [p_rl_nossl]}}, 
                                    bestFlavor=False)
        assert(troveDictMatches(d, [t_v1_rl_nossl]))
        
        # same w/ by database
        d = s.getTroveLeavesByLabel({n : {lbl_a : [rl_nossl, rl_ssl]}})
        assert(troveDictMatches(d, [t_v1_rl_nossl, t_v2_rl_ssl]))

        d = s.getTroveLeavesByLabel({n : {lbl_a : [nodeps]}})
        # either of these are acceptable -- both flavors score the same
        # against nodeps.
        assert(troveDictMatches(d, [t_v2_norl_nossl]) or 
               troveDictMatches(d, [t_v2_rl_ssl]))

        # different w/ by database - partial match is good enough
        d = s.getTroveLeavesByLabel({n : {lbl_a : [ssl]}})
        assert(troveDictMatches(d, [t_v2_rl_ssl]))

        # different w/ by database - partial match is good enough
        d = s.getTroveLeavesByLabel({n : {lbl_a : [rl]}})
        assert(troveDictMatches(d, [t_v2_rl_ssl]))

        # different w/ by database - strong flavor means ~!rl must match
        # an entry with either !rl or ~!rl, cannot match rl 
        d = s.getTroveLeavesByLabel({n : {lbl_a : [p_norl_ssl]}})
        assert(troveDictMatches(d, [t_v1_norl_ssl]))
예제 #29
0
    def testShadows(self):
        self.doTestVersion('/foo@spc:linux//shadow/1-1.2')
        self.doTestVersion('/foo@spc:linux//shadow/1-1-1.2')
        self.doTestVersion('/foo@spc:linux//shadow/1-1-1/branch//shadow2/1.1')
        self.doTestVersion('/foo@spc:linux//shadow/1-1-1/branch//shadow2/'
                           '/shadow3/1.1.1')

        self.assertRaises(ParseError, VersionFromString,
                          '/foo@spc:linux//shadow/1-1.2.3')
        self.assertRaises(ParseError, VersionFromString,
                          '/foo@spc:linux//shadow/1-1-1.2.3')
        self.assertRaises(ParseError, VersionFromString,
                          '/foo@spc:linux//shadow/1-1-1/branch/1.1')
        self.assertRaises(
            ParseError, VersionFromString,
            '/foo@spc:linux//shadow/1-1-1/branch//shadow2/1.1.1')
        self.assertRaises(
            ParseError, VersionFromString,
            '/foo@spc:linux//shadow/1-1-1/branch//shadow2/'
            '/shadow3/1.1.1.1')

        trunk = VersionFromString('/foo@spc:linux')
        assert (not trunk.isShadow())
        assert (not trunk.hasParentBranch())
        shadow = trunk.createShadow(Label('foo@spc:shadow'))
        assert (shadow.isShadow())
        assert (shadow.asString() == '/foo@spc:linux//shadow')
        assert (shadow.hasParentBranch())
        assert (shadow.parentBranch() == trunk)
        version = shadow.createVersion(Revision('1.1-1'))
        assert (version.isShadow())
        assert (not version.isModifiedShadow())
        assert (version.asString() == '/foo@spc:linux//shadow/1.1-1')
        assert (
            version.canonicalVersion().asString() == '/foo@spc:linux/1.1-1')
        assert (version.shadowLength() == 1)
        newVer = version.createShadow(Label("foo@spc:shadow2"))
        assert (newVer.asString() == '/foo@spc:linux//shadow//shadow2/1.1-1')
        assert (newVer.shadowLength() == 2)
        assert (newVer.parentVersion().asString() ==
                '/foo@spc:linux//shadow/1.1-1')
        assert (newVer.parentVersion().parentVersion().asString() ==
                '/foo@spc:linux/1.1-1')
        assert (newVer.canonicalVersion().asString() == '/foo@spc:linux/1.1-1')
        assert (newVer.isShadow())
        assert (not newVer.canonicalVersion().isShadow())
        assert (not newVer.canonicalVersion().isModifiedShadow())

        self.assertRaises(AssertionError, newVer.createBranch,
                          Label("foo@spc:shadow2"))
        self.assertRaises(VersionStringError, newVer.createShadow,
                          Label("foo@spc:shadow2"))

        branch = newVer.createBranch(Label("foo@spc:branch"))
        assert (branch.asString() ==
                '/foo@spc:linux//shadow//shadow2/1.1-1/branch')

        branchVer = newVer.createBranch(Label("foo@spc:branch"),
                                        withVerRel=True)
        assert (branchVer.asString() ==
                '/foo@spc:linux//shadow//shadow2/1.1-1/branch/1')
        assert (branchVer.shadowLength() == 0)
        assert (not branchVer.isShadow())

        newVer.incrementSourceCount()
        assert (
            newVer.asString() == '/foo@spc:linux//shadow//shadow2/1.1-1.0.1')
        assert (newVer.isModifiedShadow())
        branchVer.incrementSourceCount()
        assert (branchVer.asString() ==
                '/foo@spc:linux//shadow//shadow2/1.1-1/branch/2')
        assert (ThawVersion(branchVer.freeze()) == branchVer)

        newShadow = branchVer.createShadow(Label('foo@spc:shadow3'))
        assert (newShadow.asString() ==
                '/foo@spc:linux//shadow//shadow2/1.1-1/branch//shadow3/2')
        assert (newShadow.parentVersion().asString() ==
                '/foo@spc:linux//shadow//shadow2/1.1-1/branch/2')
        assert (newShadow.parentVersion().parentVersion().asString() ==
                '/foo@spc:linux//shadow//shadow2/1.1-1')
        assert (newShadow.parentVersion().parentVersion().parentVersion().
                asString() == '/foo@spc:linux//shadow/1.1-1')
        assert (newShadow.parentVersion().parentVersion().parentVersion().
                parentVersion().asString() == '/foo@spc:linux/1.1-1')
        assert (newShadow.canonicalVersion().asString() ==
                '/foo@spc:linux//shadow//shadow2/1.1-1/branch/2')

        # shadowed binary has a parent version
        v = VersionFromString("/foo@spc:linux//shadow/1.2-1-1")
        assert (v.hasParentVersion())
        # shadowed source has a parent version
        v = VersionFromString("/foo@spc:linux//shadow/1.2-1")
        assert (v.hasParentVersion())
        # cooked shadowed binary doesn't has a parent version
        v = VersionFromString("/foo@spc:linux//shadow/1.2-1-0.1")
        assert (not v.hasParentVersion())

        v = VersionFromString("/foo@spc:linux//shadow/1.2-1").copy()
        assert (v.hasParentVersion())
        v.incrementBuildCount()
        assert (v.asString() == "/foo@spc:linux//shadow/1.2-1-0.1")
        assert (not v.hasParentVersion())
        v2 = v.createBranch(LocalLabel(), withVerRel=True)
        assert (v2.asString() ==
                "/foo@spc:linux//shadow/1.2-1-0.1/local@local:LOCAL/1")

        v = VersionFromString("/foo@spc:linux//shadow/1.2-1.1").copy()
        v.incrementBuildCount()
        assert (v.asString() == "/foo@spc:linux//shadow/1.2-1.1-1")
        assert (not v.hasParentVersion())

        # test to make sure versions don't count -0 having a build count
        v = VersionFromString('/a@b:c/4.1.25-18-0/d//e/22.3-1')
        assert (not v.hasParentVersion())

        # If you create a pristine shadow of a modified shadow,
        # that version should NOT be a modifiedShadow
        v = VersionFromString("/foo@spc:linux//shadow//shadow2/1.2-1.1")
        assert (v.isShadow() and not v.isModifiedShadow())
        v = v.parentVersion()
        assert (v.isShadow() and v.isModifiedShadow())

        v = VersionFromString("/foo@spc:linux//shadow//shadow2/1.2-1.0.1")
        assert (v.isShadow() and v.isModifiedShadow())
예제 #30
0
    def testVersion(self):
        self.assertRaises(ParseError, VersionFromString, "0.50.1")

        verStr = "/foo.com@spc:bar/1.000:1.2-3/bang.com@spc:branch/10.000:2.4-5"
        verStr2 = "/foo.com@spc:bar/1.000:1.2-3/bang.com@spc:branch/15.000:2.4-6"
        v = ThawVersion(verStr)
        assert v.freeze() == verStr
        assert v.asString(VersionFromString("/foo.com@spc:bar")) == "1.2-3/bang.com@spc:branch/2.4-5"
        assert v.timeStamps() == [1, 10]
        v = v.copy()
        v.incrementSourceCount()
        assert v.asString() == ThawVersion(verStr2).asString()
        assert v.getHost() == "bang.com"

        # test that cPickle works on a Version object (the changeset cache
        # database pickles versions)
        vpickled = cPickle.dumps(v)
        vunpickled = cPickle.loads(vpickled)
        assert vunpickled.asString() == v.asString()

        v2 = VersionFromString("/foo.com@spc:bar/1.2-3/bang.com@spc:branch/2.4-5", timeStamps=[1.000, 10.000])
        assert v2.freeze() == verStr
        assert [x.asString() for x in v2.iterLabels()] == ["foo.com@spc:bar", "bang.com@spc:branch"]

        last = v.trailingRevision()
        assert last.asString() == "2.4-6"
        assert not v.onLocalLabel()
        assert not v.isInLocalNamespace()
        assert not v.onEmergeLabel()
        assert not v.onLocalCookLabel()
        assert v2.getHost() == "bang.com"

        assert v.trailingLabel() == Label("bang.com@spc:branch")

        branch = v.branch()
        assert branch.getHost() == "bang.com"
        strrep = branch.asString()
        assert strrep == "/foo.com@spc:bar/1.2-3/bang.com@spc:branch"
        branch2 = VersionFromString(branch.asString())
        assert branch == branch2

        frozen = branch.freeze()
        branch2 = ThawVersion(frozen)
        assert branch2 == branch

        newVer = branch2.createVersion(Revision("1.1-2"))
        assert newVer.asString() == "/foo.com@spc:bar/1.2-3/bang.com@spc:branch/1.1-2"
        assert not newVer.onLocalLabel()
        assert not newVer.isInLocalNamespace()
        assert not newVer.onEmergeLabel()
        assert not newVer.onLocalCookLabel()
        assert not newVer.isOnLocalHost()

        assert newVer.canonicalVersion() == newVer
        assert v.hasParentVersion()
        parent = v.parentVersion()
        assert not parent.hasParentVersion()
        assert parent.asString() == "/foo.com@spc:bar/1.2-3"

        # check emerge label
        emerge = parent.createBranch(EmergeLabel(), withVerRel=1)
        assert emerge.getHost() == "local"
        assert emerge.asString() == "/foo.com@spc:bar/1.2-3/local@local:EMERGE/3"
        assert not emerge.onLocalLabel()
        assert emerge.onEmergeLabel()
        assert not emerge.onRollbackLabel()
        assert not emerge.onLocalCookLabel()
        assert emerge.isOnLocalHost()
        assert emerge.isInLocalNamespace()

        # check local cook label
        cook = parent.createBranch(CookLabel(), withVerRel=1)
        assert cook.asString() == "/foo.com@spc:bar/1.2-3/local@local:COOK/3"
        assert not cook.onLocalLabel()
        assert not cook.onEmergeLabel()
        assert not cook.onRollbackLabel()
        assert cook.onLocalCookLabel()
        assert cook.isOnLocalHost()
        assert cook.isInLocalNamespace()

        # check local rollback label
        branch2 = parent.createBranch(RollbackLabel(), withVerRel=1)
        assert branch2.asString() == "/foo.com@spc:bar/1.2-3/local@local:ROLLBACK/3"
        assert not branch2.onLocalLabel()
        assert not branch2.onEmergeLabel()
        assert branch2.onRollbackLabel()
        assert not branch2.onLocalCookLabel()
        assert branch2.isOnLocalHost()
        assert branch2.isInLocalNamespace()

        # check local branch label
        branch2 = parent.createBranch(LocalLabel(), withVerRel=1)
        assert branch2.asString() == "/foo.com@spc:bar/1.2-3/local@local:LOCAL/3"
        assert branch2.onLocalLabel()
        assert not branch2.onEmergeLabel()
        assert not branch2.onRollbackLabel()
        assert not branch2.onLocalCookLabel()
        assert branch2.isOnLocalHost()
        assert branch2.isInLocalNamespace()

        branch3 = VersionFromString(branch2.asString())
        assert branch2 == branch3

        branch2 = branch2.branch()
        assert branch2.asString() == "/foo.com@spc:bar/1.2-3/local@local:LOCAL"

        parent = v.parentVersion()
        assert parent.asString() == "/foo.com@spc:bar/1.2-3"
        branch2 = parent.createBranch(LocalLabel())
        assert branch2.asString() == "/foo.com@spc:bar/1.2-3/local@local:LOCAL"

        shadow = parent.branch().createShadow(Label("foo.com@spc:shadow"))
        assert shadow.asString() == "/foo.com@spc:bar//shadow"
        assert shadow.getHost() == "foo.com"

        branch = VersionFromString("/foo.com@spc:bar")
        v = VersionFromString("1.2-3", branch)
        assert v.asString() == "/foo.com@spc:bar/1.2-3"

        # test getBinaryVersion and getSourceVersion
        v = ThawVersion(verStr)
        b = v.getBinaryVersion()
        assert b.asString() == "/foo.com@spc:bar/1.2-3-0/bang.com@spc:branch/2.4-5"

        # make sure slots are working
        v = ThawVersion("/foo.com@spec:bar/10:1.2-3")
        self.assertRaises(AttributeError, v.__setattr__, "foo", 1)
        v = ThawVersion(v.freeze())
        self.assertRaises(AttributeError, v.__setattr__, "foo", 1)

        v = VersionFromString("/localhost@rpl:linux/1.0-1-0/" "local@local:EMERGE/1/COOK/2")
        assert VersionFromString(v.asString()) == v
예제 #31
0
    def testFlavorMatchingAsRepository(self):
        # presumes that version matches work
        # and just tests flavoring
        # uses repository style
        v1 = ThawVersion('/localhost@rpl:devel/1:1.0-1-1')
        v2 = ThawVersion('/localhost@rpl:devel/2:2.0-1-1')
        nodeps = deps.parseFlavor('')
        rl_nossl = deps.parseFlavor('readline,!ssl')
        rl_ssl = deps.parseFlavor('readline,ssl')
        norl_ssl = deps.parseFlavor('!readline,ssl')
        norl_nossl = deps.parseFlavor('!readline,!ssl')
        p_rl_nossl = deps.parseFlavor('~readline,~!ssl')
        p_rl_ssl = deps.parseFlavor('~readline,~ssl')
        p_norl_ssl = deps.parseFlavor('~!readline,~ssl')
        p_norl_nossl = deps.parseFlavor('~!readline,~!ssl')
        ssl = deps.parseFlavor('ssl')
        rl = deps.parseFlavor('readline')

        s = SimplestFindTroveSource()
        s.searchAsRepository()
        n = 'test:run'
        n2 = 'test2:run'
        t_v1_rl_nossl = (n, v1, rl_nossl)
        t_v1_norl_ssl = (n, v1, norl_ssl)
        t_v2_norl_nossl = (n, v2, norl_nossl)
        t_v2_rl_ssl = (n, v2, rl_ssl)
        lbl_a = v1.branch().label()

        s.addTroves(t_v1_rl_nossl, t_v1_norl_ssl, t_v2_norl_nossl, t_v2_rl_ssl)
        for trv in t_v1_rl_nossl, t_v1_norl_ssl, t_v2_norl_nossl, t_v2_rl_ssl:
            self.addComponent(*trv)
        repos = self.openRepository()

        assert (s.hasTroves([t_v1_rl_nossl])[0])
        for src in s, repos:
            d = s.getTroveLeavesByLabel({n: {lbl_a: [rl_nossl]}})
            assert (troveDictMatches(d, [t_v1_rl_nossl]))

            # if you specify flavors, and bestFlavor is False you all
            # allowed flavors back,  not just the best match.  In this
            # case ~rl, does not match !readline, so we only get the rl,ssl
            # trove returned
            d = src.getTroveLeavesByLabel({n: {
                lbl_a: [p_rl_nossl]
            }},
                                          bestFlavor=False)
            assert (troveDictMatches(d, [t_v2_rl_ssl, t_v1_rl_nossl]))

            d = src.getTroveLeavesByLabel({n: {
                lbl_a: [rl_nossl, rl_ssl]
            }},
                                          bestFlavor=True)
            assert (troveDictMatches(d, [t_v1_rl_nossl, t_v2_rl_ssl]))

            d = src.getTroveLeavesByLabel({n: {
                lbl_a: [nodeps]
            }},
                                          bestFlavor=True)
            assert (troveDictMatches(d, [t_v2_norl_nossl]))

            d = src.getTroveLeavesByLabel({n: {lbl_a: [ssl]}}, bestFlavor=True)
            assert (troveDictMatches(d, [t_v1_norl_ssl]))

            d = src.getTroveLeavesByLabel({n: {
                lbl_a: [p_norl_ssl]
            }},
                                          bestFlavor=True)
            assert (troveDictMatches(d, [t_v2_rl_ssl]))

        s.searchAsDatabase()

        # with database, only strong flavors are allowed, so only the
        # rl_nossl trove matches even with bestFlavor = False
        d = s.getTroveLeavesByLabel({n: {
            lbl_a: [p_rl_nossl]
        }},
                                    bestFlavor=False)
        assert (troveDictMatches(d, [t_v1_rl_nossl]))

        # same w/ by database
        d = s.getTroveLeavesByLabel({n: {lbl_a: [rl_nossl, rl_ssl]}})
        assert (troveDictMatches(d, [t_v1_rl_nossl, t_v2_rl_ssl]))

        d = s.getTroveLeavesByLabel({n: {lbl_a: [nodeps]}})
        # either of these are acceptable -- both flavors score the same
        # against nodeps.
        assert (troveDictMatches(d, [t_v2_norl_nossl])
                or troveDictMatches(d, [t_v2_rl_ssl]))

        # different w/ by database - partial match is good enough
        d = s.getTroveLeavesByLabel({n: {lbl_a: [ssl]}})
        assert (troveDictMatches(d, [t_v2_rl_ssl]))

        # different w/ by database - partial match is good enough
        d = s.getTroveLeavesByLabel({n: {lbl_a: [rl]}})
        assert (troveDictMatches(d, [t_v2_rl_ssl]))

        # different w/ by database - strong flavor means ~!rl must match
        # an entry with either !rl or ~!rl, cannot match rl
        d = s.getTroveLeavesByLabel({n: {lbl_a: [p_norl_ssl]}})
        assert (troveDictMatches(d, [t_v1_norl_ssl]))
예제 #32
0
    def testMetadata(self):
        store = self._connect()
        emptyFlavor = deps.Flavor()
        v1 = ThawVersion("/conary.rpath.com@test:trunk/1:1-1")
        branch = v1.branch()
        store.createTroveBranch("testtrove", branch)

        md_v1_l = {
            "shortDesc": "Short Desc",
            "longDesc": "Long Desc",
            "url": ["url1", "url2"],
            "license": ["CPL", "GPL"],
            "category": ["cat1", "cat2"],
            "version": "/conary.rpath.com@test:trunk/1-1",
            "source": "local",
            "language": "C",
        }
        md_v1_fr_l = {
            "shortDesc": "French Short Desc",
            "longDesc": "French Long Desc",
            "url": ["url1", "url2"],
            "license": ["CPL", "GPL"],
            "category": ["cat1", "cat2"],
            "version": "/conary.rpath.com@test:trunk/1-1",
            "source": "local",
            "language": "fr",
        }
        md_v2_l = {
            "shortDesc": "Short Desc V2",
            "longDesc": "Long Desc V2",
            "url": ["url1v2"],
            "license": ["CPLv2", "GPLv2"],
            "category": ['cat1v2', 'cat2v2', 'cat3v2'],
            "version": "/conary.rpath.com@test:trunk/1-2",
            "source": "foo",
            "language": "C",
        }

        trv3 = trove.Trove("testpkg3", v1, emptyFlavor, None)
        branch = v1.branch()

        store.db.transaction()

        store.updateMetadata("testpkg3",
                             branch,
                             "Short Desc",
                             "Long Desc",
                             urls=['url1', 'url2'],
                             categories=['cat1', 'cat2'],
                             licenses=['GPL', 'CPL'],
                             source="",
                             language="C")

        store.updateMetadata("testpkg3", branch, "French Short Desc",
                             "French Long Desc", [], [], [], "", "fr")

        store.db.commit()

        md_v1 = store.getMetadata("testpkg3", branch)
        md_v1_fr = store.getMetadata("testpkg3", branch, language="fr")

        self.assertEqual(md_v1.freeze(), md_v1_l)
        self.assertEqual(md_v1_fr.freeze(), md_v1_fr_l)

        v2 = ThawVersion("/conary.rpath.com@test:trunk/1:1-2")

        store.db.transaction()

        store.updateMetadata("testpkg3",
                             branch,
                             "Short Desc V2",
                             "Long Desc V2",
                             urls=['url1v2'],
                             categories=['cat1v2', 'cat2v2', 'cat3v2'],
                             licenses=['CPLv2', 'GPLv2'],
                             source="foo",
                             language="C")

        store.db.commit()

        md_v2 = store.getMetadata("testpkg3", branch)
        md_v1 = store.getMetadata("testpkg3", branch, version=v1)
        md_v1_fr = store.getMetadata("testpkg3",
                                     branch,
                                     version=v1,
                                     language="fr")

        self.assertEqual(md_v2.freeze(), md_v2_l)
        self.assertEqual(md_v1.freeze(), md_v1_l)
        self.assertEqual(md_v1_fr.freeze(), md_v1_fr_l)
예제 #33
0
    def testRemoval(self):
        threshold = 60 * 5;         # 5 minutes

        def _dbStatus(db):
            stat = {}
            cu = db.cursor()

            for table in db.tables:
                cu.execute("SELECT * FROM %s" % table)
                l = cu.fetchall()
                # throw away anything which looks a timestamp; this will
                # break if the test case takes more than 5 minutes to run
                stat[table] = set()
                for row in l:
                    thisRow = []
                    for item in row:
                        if not isinstance(item, (float, decimal.Decimal)) or \
                                    abs(item - now) > threshold:
                            thisRow.append(item)

                    stat[table].add(tuple(thisRow))

            return stat

        def _checkStateDiff(one, two):
            if one != two:
                assert(one.keys() == two.keys())
                for key in one:
                    if one[key] != two[key]:
                        print "table %s has changed" % key
                raise AssertionError, "\n%s\n!=\n%s" % (one, two)

        store = self._connect()

        # get the current timestamp from the database
        cu = store.db.cursor()
        cu.execute('''create table timestamp(
                      foo     INTEGER,
                      changed NUMERIC(14,0) NOT NULL DEFAULT 0)''')
        store.db.loadSchema()
        store.db.createTrigger('timestamp', 'changed', "INSERT")
        cu.execute('insert into timestamp values(0, 0)')
        cu.execute('select changed from timestamp')
        now = cu.fetchall()[0][0]

        emptyState = _dbStatus(store.db)

        v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")
        v20 = ThawVersion("/conary.rpath.com@test:trunk/20:1.2-20")
        vB = ThawVersion("/conary.rpath.com@test:branch/1:0-0")
        vOtherRepo = ThawVersion("/other.repos.com@some:label/1:0-0")
        branch = v10.branch()

        flavor = deps.parseFlavor('is:x86')
        flavor64 = deps.parseFlavor('is:x86_64')

        store.createTroveBranch("trv:comp", branch)

        f1 = files.FileFromFilesystem("/etc/passwd", self.id1)
        f2 = files.FileFromFilesystem("/etc/services", self.id2)
        # add a file that has no contents sha1
        try:
            d = tempfile.mkdtemp()
            os.symlink('foo', d + '/foo')
            f5 = files.FileFromFilesystem(d + '/foo', self.id5)
        finally:
            shutil.rmtree(d)

        req = deps.parseDep("file: /bin/bash file: /bin/awk")

        dirNames = set(['/bin', ''])
        baseNames = set(['1', '2', 'distributed', 'foo', 'group-foo.recipe'])

        cl = changelog.ChangeLog("test", "*****@*****.**", "changelog\n")

        trv = trove.Trove('trv:comp', v10, flavor, cl)
        trv.addFile(f1.pathId(), "/bin/1", v10, f1.fileId())
        trv.addFile(f2.pathId(), "/bin/2", v10, f2.fileId())
        trv.addFile(self.id4, "/bin/distributed", v10, self.fid4)
        trv.addFile(f5.pathId(), "/bin/foo", v10, f5.fileId())
        trv.troveInfo.size.set(1234)
        trv.setRequires(req)

        store.db.transaction()
        store.addTroveSetStart([], dirNames, baseNames)
        troveInfo = store.addTrove(trv, trv.diff(None)[0])
        troveInfo.addFile(f1.pathId(), "/bin/1", f1.fileId(), v10,
                          fileStream = f1.freeze())
        troveInfo.addFile(f2.pathId(), "/bin/2", f2.fileId(), v10,
                          fileStream = f2.freeze())
        troveInfo.addFile(f5.pathId(), "/bin/foo", f5.fileId(), v10,
                          fileStream = f5.freeze())
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        store.db.commit()
        oneTroveState = _dbStatus(store.db)

        rc = store._removeTrove("trv:comp", v10, flavor)
        self.assertEqual(set(rc), set([ f1.contents.sha1(), f2.contents.sha1() ]))
        state = _dbStatus(store.db)
        _checkStateDiff(state, emptyState)
        store.db.rollback()

        # the redir itself doesn't overlap with trv:comp; this makes sure
        # that the tables which the redir target needs are preserved
        redir = trove.Trove('redir:comp', vB, flavor64, cl,
                            type = trove.TROVE_TYPE_REDIRECT)
        redir.addRedirect('trv:comp', v10.branch(), flavor)
        store.addTroveSetStart([], dirNames, baseNames)
        troveInfo = store.addTrove(redir, redir.diff(None)[0])
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        rc = store._removeTrove("trv:comp", v10, flavor)
        redir2 = store.getTrove('redir:comp', vB, flavor64)
        assert(redir == redir2)
        rc = store._removeTrove("redir:comp", vB, flavor64)
        state = _dbStatus(store.db)
        _checkStateDiff(state, emptyState)

        store.db.rollback()

        trv2 = trv.copy()
        trv2.changeVersion(v20)

        store.db.transaction()
        store.addTroveSetStart([], dirNames, baseNames)
        troveInfo = store.addTrove(trv2, trv2.diff(None)[0])
        troveInfo.addFile(f1.pathId(), "/bin/1", f1.fileId(), v10,
                          fileStream = f1.freeze())
        troveInfo.addFile(f2.pathId(), "/bin/2", f2.fileId(), v10,
                          fileStream = f2.freeze())
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        store.db.commit()
        twoTroveState = _dbStatus(store.db)

        rc = store._removeTrove("trv:comp", v20, flavor)
        assert(not rc)
        state = _dbStatus(store.db)
        _checkStateDiff(state, oneTroveState)
        rc = store._removeTrove("trv:comp", v10, flavor)
        assert(set(rc) == set([ f1.contents.sha1(), f2.contents.sha1() ]))
        state = _dbStatus(store.db)
        _checkStateDiff(state, emptyState)

        store.db.rollback()

        # add a trove which shares a file with trv:comp and make sure removing
        # it doesn't remove the sha1s (make sure the fileIds are different)
        anotherTrove = trove.Trove('another:comp', v10, flavor, cl)
        anotherF = f1.copy()
        anotherF.inode.owner.set('unowned')
        anotherTrove.addFile(f1.pathId(), "/bin/1", v10, anotherF.fileId())
        store.addTroveSetStart([], dirNames, baseNames)
        troveInfo = store.addTrove(anotherTrove, anotherTrove.diff(None)[0])
        troveInfo.addFile(f1.pathId(), "/bin/1", anotherF.fileId(),
                          v10, fileStream = f1.freeze())
        store.addTroveDone(troveInfo)
        rc = store._removeTrove("another:comp", v10, flavor)
        assert(not rc)
        state = _dbStatus(store.db)
        _checkStateDiff(state, twoTroveState)

        store.db.rollback()

        # now try just marking something as removed
        rc = store.markTroveRemoved("trv:comp", v20, flavor)
        assert(not rc)
        removedTrove = store.getTrove("trv:comp", v20, flavor)
        assert(removedTrove.type() == trove.TROVE_TYPE_REMOVED)

        rc = store.markTroveRemoved("trv:comp", v10, flavor)
        assert(set(rc) == set([ f1.contents.sha1(), f2.contents.sha1() ]))
        removedTrove = store.getTrove("trv:comp", v10, flavor)
        assert(removedTrove.type() == trove.TROVE_TYPE_REMOVED)

        store.db.rollback()

        # test removing group-*:source
        anotherTrove = trove.Trove('group-foo:source', v10, flavor, cl)
        anotherF = f1.copy()
        anotherF.inode.owner.set('unowned')
        anotherTrove.addFile(f1.pathId(), "group-foo.recipe", v10,
                             anotherF.fileId())
        troveInfo = store.addTrove(anotherTrove, anotherTrove.diff(None)[0])
        troveInfo.addFile(f1.pathId(), "group-foo.recipe", anotherF.fileId(),
                          v10, fileStream = anotherF.freeze())
        store.addTroveDone(troveInfo)
        rc = store._removeTrove("group-foo:source", v10, flavor)
        assert(not rc)
        state = _dbStatus(store.db)
        _checkStateDiff(state, twoTroveState)

        store.db.rollback()

        groupTrove = trove.Trove('group-foo', v10, flavor, cl)
        groupTrove.addTrove('foo', vOtherRepo, flavor)
        troveInfo = store.addTrove(groupTrove, groupTrove.diff(None)[0])
        store.addTroveDone(troveInfo)
        rc = store._removeTrove("group-foo", v10, flavor)
        state = _dbStatus(store.db)
        _checkStateDiff(state, twoTroveState)
        store.db.rollback()
예제 #34
0
    def getJobs(self, jobIdList, withTroves=False, withConfigs=False):
        if not jobIdList:
            return []
        cu = self.db.cursor()
        jobIds = ','.join('%d' % x for x in jobIdList)
        results = cu.execute("""
            SELECT jobId, uuid, owner, state, status, start, finish,
                failureReason, failureData, pid
            FROM Jobs WHERE jobId IN (%s)
            """ % (jobIds, ))

        jobsById = {}
        for (jobId, uuid, owner, state, status, start, finish, failureReason,
             failureData, pid) in results:
            if state is None:
                # quick catch check for missing jobs
                raise KeyError, jobId

            failureReason = thaw('FailureReason',
                                 (failureReason, cu.frombinary(failureData)))
            job = buildjob.BuildJob(jobId,
                                    status=status,
                                    state=state,
                                    start=float(start),
                                    finish=float(finish),
                                    failureReason=failureReason,
                                    uuid=uuid,
                                    pid=pid,
                                    owner=owner)
            jobsById[jobId] = job

        if withTroves:
            results = cu.execute("""
                SELECT jobId, BuildTroves.troveId, troveName, version,
                    flavor, context, state, status, failureReason,
                    failureData, start, finish, logPath, pid, recipeType,
                    buildType, troveType, Chroots.path, Chroots.nodeName
                FROM BuildTroves
                LEFT JOIN Chroots USING(chrootId)
                WHERE jobId IN (%s)
            """ % (jobIds, ))

            trovesById = {}

            for (jobId, troveId, name, version, flavor, context, state, status,
                 failureReason, failureData, start, finish, logPath, pid,
                 recipeType, buildType, troveType, chrootPath,
                 chrootHost) in results:

                if chrootPath is None:
                    chrootPath = ''
                    chrootHost = ''
                version = versions.ThawVersion(version)
                flavor = ThawFlavor(flavor)
                failureReason = thaw(
                    'FailureReason',
                    (failureReason, cu.frombinary(failureData)))
                troveClass = buildtrove.getClassForTroveType(troveType)
                buildTrove = troveClass(jobId,
                                        name,
                                        version,
                                        flavor,
                                        state=state,
                                        start=float(start),
                                        finish=float(finish),
                                        logPath=logPath,
                                        status=status,
                                        failureReason=failureReason,
                                        pid=pid,
                                        recipeType=recipeType,
                                        chrootPath=chrootPath,
                                        chrootHost=chrootHost,
                                        buildType=buildType,
                                        context=context)
                trovesById[troveId] = buildTrove
                jobsById[jobId].addTrove(name, version, flavor, context,
                                         buildTrove)

            results = cu.execute("""
                SELECT BuildTroves.troveId, BinaryTroves.troveName,
                    BinaryTroves.version, BinaryTroves.flavor
                FROM BuildTroves
                JOIN BinaryTroves USING(troveId)
                WHERE jobId IN (%s)
                """ % (jobIds, ))
            builtTroves = {}
            for troveId, name, version, flavor in results:
                builtTroves.setdefault(troveId, []).append(
                    (name, ThawVersion(version), ThawFlavor(flavor)))
            for troveId, binTroves in builtTroves.iteritems():
                trv = trovesById.get(troveId)
                if trv is not None:
                    trv.setBuiltTroves(binTroves)

            cu.execute("""
                SELECT troveId, key, value
                FROM TroveSettings
                WHERE jobId IN (%s)
                ORDER BY key, ord
                """ % (jobIds, ))
            troveSettings = {}
            for troveId, key, value in cu:
                d = troveSettings.setdefault(troveId, {})
                d.setdefault(key, []).append(value)
            for troveId, settings in troveSettings.items():
                settingsClass = settings.pop('_class')[0]
                trv = trovesById.get(troveId)
                if trv is not None:
                    trv.settings = thaw('TroveSettings',
                                        (settingsClass, settings))
        else:
            results = cu.execute("""
                SELECT jobId, troveName, version, flavor, context
                FROM BuildTroves
                WHERE jobId IN (%s)
                """ % (jobIds, ))
            for (jobId, n, v, f, context) in results:
                jobsById[jobId].addTrove(n, versions.ThawVersion(v),
                                         ThawFlavor(f), context)
        if withConfigs:
            cu.execute("""
                SELECT jobId, context, key, value
                FROM JobConfig
                WHERE jobId IN (%s)
                ORDER BY key, ord
                """ % (jobIds, ))
            jobConfigD = {}
            for jobId, context, key, value in cu:
                configD = jobConfigD.setdefault(jobId, {})
                d = configD.setdefault(context, {})
                d.setdefault(key, []).append(value)
            for jobId, configD in jobConfigD.items():
                configD = dict((x[0], thaw('BuildConfiguration', x[1]))
                               for x in configD.iteritems())
                jobsById[jobId].setConfigs(configD)

        return [jobsById[jobId] for jobId in jobIdList]
예제 #35
0
    def testMetadata(self):
        store = self._connect()
        emptyFlavor = deps.Flavor()
        v1 = ThawVersion("/conary.rpath.com@test:trunk/1:1-1")
        branch = v1.branch()
        store.createTroveBranch("testtrove", branch)

        md_v1_l = {"shortDesc":    "Short Desc",
                   "longDesc":     "Long Desc",
                   "url":          ["url1", "url2"],
                   "license":      ["CPL", "GPL"],
                   "category":     ["cat1", "cat2"],
                   "version":      "/conary.rpath.com@test:trunk/1-1",
                   "source":       "local",
                   "language":     "C",
        }
        md_v1_fr_l = {"shortDesc": "French Short Desc",
                      "longDesc":  "French Long Desc",
                      "url":       ["url1", "url2"],
                      "license":   ["CPL", "GPL"],
                      "category":  ["cat1", "cat2"],
                      "version":   "/conary.rpath.com@test:trunk/1-1",
                      "source":    "local",
                      "language":  "fr",
        }
        md_v2_l = {"shortDesc":    "Short Desc V2",
                   "longDesc":     "Long Desc V2",
                   "url":          ["url1v2"],
                   "license":      ["CPLv2", "GPLv2"],
                   "category":     ['cat1v2', 'cat2v2', 'cat3v2'],
                   "version":      "/conary.rpath.com@test:trunk/1-2",
                   "source":       "foo",
                   "language":     "C",
        }

        trv3 = trove.Trove("testpkg3", v1, emptyFlavor, None)
        branch = v1.branch()

        store.db.transaction()

        store.updateMetadata("testpkg3", branch, "Short Desc",
            "Long Desc", urls=['url1', 'url2'],
            categories=['cat1', 'cat2'], licenses=['GPL', 'CPL'],
            source="", language="C")

        store.updateMetadata("testpkg3", branch, "French Short Desc",
            "French Long Desc", [], [], [], "", "fr")

        store.db.commit()

        md_v1 = store.getMetadata("testpkg3", branch)
        md_v1_fr = store.getMetadata("testpkg3", branch, language="fr")

        self.assertEqual(md_v1.freeze(), md_v1_l)
        self.assertEqual(md_v1_fr.freeze(), md_v1_fr_l)


        v2 = ThawVersion("/conary.rpath.com@test:trunk/1:1-2")

        store.db.transaction()

        store.updateMetadata("testpkg3", branch, "Short Desc V2",
            "Long Desc V2", urls=['url1v2'],
            categories=['cat1v2', 'cat2v2', 'cat3v2'],
            licenses=['CPLv2', 'GPLv2'], source="foo", language="C")

        store.db.commit()

        md_v2 = store.getMetadata("testpkg3", branch)
        md_v1 = store.getMetadata("testpkg3", branch, version=v1)
        md_v1_fr = store.getMetadata("testpkg3", branch, version=v1, language="fr")

        self.assertEqual(md_v2.freeze(), md_v2_l)
        self.assertEqual(md_v1.freeze(), md_v1_l)
        self.assertEqual(md_v1_fr.freeze(), md_v1_fr_l)
예제 #36
0
    def getTroves(self, troveList):
        if not troveList:
            return []
        cu = self.db.cursor()
        trovesById = {}
        trovesByNVF = {}
        for jobId, troveName, version, flavor, context in troveList:
            cu.execute(
                """
                SELECT BuildTroves.troveId, pid, state, status, failureReason,
                    failureData, start, finish, logPath, recipeType,
                    Chroots.nodeName, Chroots.path, troveType
                FROM BuildTroves
                LEFT JOIN Chroots USING(chrootId)
                WHERE jobId = ? AND troveName = ? AND version = ?
                    AND flavor = ? AND context = ?
                """, jobId, troveName, version.freeze(), flavor.freeze(),
                context)
            row = cu.fetchone()
            if not row:
                continue
            (troveId, pid, state, status, failureReason, failureData, start,
             finish, logPath, recipeType, chrootHost, chrootPath,
             troveType) = row
            if chrootPath is None:
                chrootPath = chrootHost = ''
            failureReason = thaw('FailureReason',
                                 (failureReason, cu.frombinary(failureData)))

            troveClass = buildtrove.getClassForTroveType(troveType)
            buildTrove = troveClass(jobId,
                                    troveName,
                                    version,
                                    flavor,
                                    context=context,
                                    pid=pid,
                                    state=state,
                                    start=float(start),
                                    finish=float(finish),
                                    logPath=logPath,
                                    status=status,
                                    failureReason=failureReason,
                                    recipeType=recipeType,
                                    chrootPath=chrootPath,
                                    chrootHost=chrootHost)
            trovesById[troveId] = buildTrove
            trovesByNVF[(jobId, troveName, version, flavor,
                         context)] = buildTrove
        if not trovesByNVF:
            raise KeyError(troveList[0])
        troveIds = ','.join('%d' % x for x in trovesById)

        cu.execute("""
            SELECT troveId, troveName, version, flavor
            FROM BinaryTroves
            WHERE troveId IN (%s)
            """ % (troveIds, ))
        builtTroves = {}
        for troveId, troveName, version, flavor in cu:
            builtTroves.setdefault(troveId, []).append(
                (troveName, ThawVersion(version), ThawFlavor(flavor)))
        for troveId, binTroves in builtTroves.iteritems():
            trovesById[troveId].setBuiltTroves(binTroves)

        cu.execute("""
            SELECT troveId, key, value
            FROM TroveSettings
            WHERE troveId IN (%s)
            ORDER BY key, ord
            """ % (troveIds, ))
        troveSettings = {}
        for troveId, key, value in cu:
            d = troveSettings.setdefault(troveId, {})
            d.setdefault(key, []).append(value)
        for troveId, settings in troveSettings.items():
            settingsClass = settings.pop('_class')[0]
            trovesById[troveId].settings = thaw('TroveSettings',
                                                (settingsClass, settings))

        out = []
        for tup in troveList:
            if tup in trovesByNVF:
                out.append(trovesByNVF[tup])
            else:
                raise KeyError(tup)
        return out
예제 #37
0
    def testTroves(self, flavor=None):
        if flavor is None:
            flavor = deps.Flavor()

        store = self._connect()

        dirSet = set(['/etc', '/bin'])
        baseSet = set(
            ['passwd', 'services', 'group', '1', '2', '3', 'distributed'])

        v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")

        branch = v10.branch()
        store.createTroveBranch("testtrove", branch)

        f1 = files.FileFromFilesystem("/etc/passwd", self.id1)
        f2 = files.FileFromFilesystem("/etc/services", self.id2)
        f3 = files.FileFromFilesystem("/etc/group", self.id3)
        # make a really huge dependency, thus a very large file stream
        req = deps.DependencySet()
        for x in xrange(10000):
            req.addDep(deps.SonameDependencies,
                       deps.Dependency("libtest.so.%d" % x))
        f3.requires.set(req)
        # make sure it's way too big for a blob in mysql
        assert (len(f3.freeze()) >= 50000)

        cl = changelog.ChangeLog(
            "test", "*****@*****.**", """\
Some changes are good.
Some changes are bad.
Some changes just are.
""")

        trv = trove.Trove('testcomp', v10, flavor, cl)
        trv.addFile(f1.pathId(), "/bin/1", v10, f1.fileId())
        trv.addFile(f2.pathId(), "/bin/2", v10, f2.fileId())
        trv.addFile(f3.pathId(), "/bin/3", v10, f3.fileId())
        trv.addFile(self.id4, "/bin/distributed", v10, self.fid4)
        trv.troveInfo.size.set(1234)
        trv.troveInfo.sourceName.set('somesource')

        req = deps.DependencySet()
        req.addDep(deps.FileDependencies, deps.Dependency("/bin/bash"))
        req.addDep(deps.TroveDependencies, deps.Dependency("foo:runtime"))
        req.addDep(deps.SonameDependencies, deps.Dependency("libtest.so.1"))
        trv.setRequires(req)

        # this also lets us peek at the database to make sure libtest.so.1
        # is only in the dep table once
        prv = deps.DependencySet()
        prv.addDep(deps.SonameDependencies, deps.Dependency("libtest.so.1"))
        trv.setProvides(prv)
        trv.computeDigests()

        store.db.transaction()
        store.addTroveSetStart([], dirSet, baseSet)
        troveInfo = store.addTrove(trv, trv.diff(None)[0])
        troveInfo.addFile(f1.pathId(),
                          "/bin/1",
                          f1.fileId(),
                          v10,
                          fileStream=f1.freeze())
        troveInfo.addFile(f2.pathId(),
                          "/bin/2",
                          f2.fileId(),
                          v10,
                          fileStream=f2.freeze())
        troveInfo.addFile(f3.pathId(),
                          "/bin/3",
                          f3.fileId(),
                          v10,
                          fileStream=f3.freeze())
        troveInfo.addFile(self.id4, "/bin/distributed", self.fid4, v10)
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        store.db.commit()

        cu = store.db.cursor()
        cu.execute("SELECT count(*) FROM Dependencies WHERE "
                   "name = 'libtest.so.1'")
        self.assertEqual(cu.next(), (1, ))

        # make sure the sha1s were stored
        cu.execute("""
        SELECT dirname, basename, sha1
        FROM TroveFiles
        JOIN FileStreams USING (streamId)
        JOIN FilePaths ON TroveFiles.filePathId = FilePaths.filePathId
        JOIN Dirnames ON FilePaths.dirnameId = Dirnames.dirnameId
        JOIN Basenames ON FilePaths.basenameId = Basenames.basenameId
        ORDER BY dirname,basename""")
        items = [(os.path.join(cu.frombinary(x[0]),
                               cu.frombinary(x[1])), cu.frombinary(x[2]))
                 for x in cu.fetchall()]
        self.assertEqual(items, [("/bin/1", f1.contents.sha1()),
                                 ("/bin/2", f2.contents.sha1()),
                                 ("/bin/3", f3.contents.sha1()),
                                 ("/bin/distributed", None)])

        cl = changelog.ChangeLog("test", "*****@*****.**", "another log\n")

        fromRepos = store.getTrove("testcomp", v10, flavor, cl)
        self.assertEqual(fromRepos, trv)
        self.assertEqual(fromRepos.getVersion().timeStamps(),
                         trv.getVersion().timeStamps())
        self.assertEqual(fromRepos.getChangeLog(), trv.getChangeLog())

        self.assertEqual([
            x for x in store.getTrove("testcomp", v10, flavor,
                                      withFiles=False).iterFileList()
        ], [])

        l = store.iterFilesInTrove("testcomp", v10, flavor, sortByPath=True)
        l = [x for x in l]
        self.assertEqual(l, [(f1.pathId(), "/bin/1", f1.fileId(), v10),
                             (f2.pathId(), "/bin/2", f2.fileId(), v10),
                             (f3.pathId(), "/bin/3", f3.fileId(), v10),
                             (self.id4, "/bin/distributed", self.fid4, v10)])

        cl = changelog.ChangeLog("test", "*****@*****.**", "log for testpkg\n")
        trv2 = trove.Trove("testpkg", v10, flavor, cl)
        trv2.addTrove(trv.getName(), v10, flavor)
        trv2.addTrove("weakref", v10, flavor, weakRef=True)
        trv2.computeDigests()
        store.addTroveSetStart([], dirSet, baseSet)
        troveInfo = store.addTrove(trv2, trv2.diff(None)[0])
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        self.assertEqual(store.getTrove("testpkg", v10, flavor), trv2)

        self.assertEqual([
            x for x in store.iterTroves([("testcomp", v10,
                                          flavor), ("testpkg", v10, flavor)])
        ], [trv, trv2])
        self.assertEqual([
            x for x in store.iterTroves([("testpkg", v10,
                                          flavor), ("testcomp", v10, flavor)])
        ], [trv2, trv])
        self.assertEqual([
            x for x in store.iterTroves([("testpkg", v10,
                                          flavor), ("testpkg", v10, flavor)])
        ], [trv2, trv2])
        self.assertEqual([
            x for x in store.iterTroves([("testpkg", v10,
                                          flavor), ("blah", v10, flavor)])
        ], [trv2, None])
        self.assertEqual([
            x for x in store.iterTroves([("blah", v10,
                                          flavor), ("testpkg", v10, flavor)])
        ], [None, trv2])
        self.assertEqual(
            [x for x in store.iterTroves([("blah", v10, flavor)])], [None])
        self.assertEqual([
            x for x in store.iterTroves([(
                "testcomp", v10, flavor), ("blah", v10,
                                           flavor), ("testpkg", v10, flavor)])
        ], [trv, None, trv2])

        # erasing doesn't work
        #store.eraseTrove("testcomp", v10, None)
        #store.commit()
        self.assertEqual(store.getTrove("testpkg", v10, flavor), trv2)

        map = {'testpkg': [v10]}
        flavors = store.getTroveFlavors(map)
        if flavor is not None:
            flavorStr = flavor.freeze()
        else:
            flavorStr = ''
        self.assertEqual(flavors, {'testpkg': {v10: [flavorStr]}})

        map = {'testpkg3': [v10]}
        flavors = store.getTroveFlavors(map)
        self.assertEqual(flavors, {'testpkg3': {v10: []}})

        # test getFiles
        fileObjs = store.getFiles([(f1.pathId(), f1.fileId()),
                                   (f2.pathId(), f2.fileId())])
        self.assertEqual(fileObjs[(f1.pathId(), f1.fileId())], f1)
        self.assertEqual(fileObjs[(f2.pathId(), f2.fileId())], f2)

        # test that asking for an invalid fileid/pathid pair results
        # in no entry for the (pathid, fileid) in the returned dict
        invalidPathId = md5FromString('9' * 32)
        invalidFileId = sha1FromString('9' * 40)
        fileObjs = store.getFiles([(invalidPathId, invalidFileId)])
        # make sure fileObjs is empty
        assert (not fileObjs)

        # test that asking for contents that have to come from
        # a different repository works - we should get None
        # back
        fileObjs = store.getFiles([(self.id4, self.fid4)])
        self.assertEqual(fileObjs, {(self.id4, self.fid4): None})
예제 #38
0
    def testVersionMatching(self):
        v1 = ThawVersion('/localhost@rpl:devel/1:1.0-1-1')
        v2 = ThawVersion('/localhost@rpl:devel/2:2.0-1-1')
        v1b = ThawVersion('/localhost@rpl:branch/3:1.0-1-1')
        v2b = ThawVersion('/localhost@rpl:branch/4:2.0-1-1')
        nodeps = deps.parseFlavor('')
        s = SimplestFindTroveSource()
        n = 'test'
        n2 = 'test2'

        t_v1 = (n, v1, nodeps)
        t_v2 = (n, v2, nodeps)
        t_v1b = (n, v1b, nodeps)
        t_v2b = (n, v2b, nodeps)

        t2_v1 = (n2, v1, nodeps)
        t2_v2 = (n2, v2, nodeps)
        t2_v1b = (n2, v1b, nodeps)
        t2_v2b = (n2, v2b, nodeps)

        lbl_a = v1.branch().label()
        lbl_b = v1b.branch().label()

        s.addTroves(t_v1, t_v2, t_v1b, t_v2b, t2_v1, t2_v2, t2_v1b, t2_v2b)

        d = s.getTroveLeavesByLabel({n: {lbl_a: None}, n2: {lbl_b: None}})
        assert (troveDictMatches(d, [t_v2, t2_v2b]))

        d = s.getTroveVersionsByLabel({n: {lbl_a: None}, n2: {lbl_b: None}})
        assert (troveDictMatches(d, [t_v1, t_v2, t2_v2b, t2_v1b]))

        d = s.getTroveVersionsByLabel({n: {lbl_a: None, lbl_b: None}})
        assert (troveDictMatches(d, [t_v1, t_v2, t_v1b, t_v2b]))

        d = s.getTroveLeavesByBranch({
            n: {
                v1.branch(): None
            },
            n2: {
                v2b.branch(): None
            }
        })
        assert (troveDictMatches(d, [t_v2, t2_v2b]))

        d = s.getTroveVersionsByBranch({
            n: {
                v1.branch(): None
            },
            n2: {
                v2b.branch(): None
            }
        })
        assert (troveDictMatches(d, [t_v1, t_v2, t2_v1b, t2_v2b]))

        d = s.getTroveVersionFlavors({
            n: {
                v1: None,
                v2b: None
            },
            n2: {
                v2: None,
                v1b: None
            }
        })
        assert (troveDictMatches(d, [t_v1, t_v2b, t2_v2, t2_v1b]))
예제 #39
0
    def testVersion(self):
        self.assertRaises(ParseError, VersionFromString, '0.50.1')

        verStr = "/foo.com@spc:bar/1.000:1.2-3/bang.com@spc:branch/10.000:2.4-5"
        verStr2 = "/foo.com@spc:bar/1.000:1.2-3/bang.com@spc:branch/15.000:2.4-6"
        v = ThawVersion(verStr)
        assert (v.freeze() == verStr)
        assert (v.asString(VersionFromString("/foo.com@spc:bar")) ==
                "1.2-3/bang.com@spc:branch/2.4-5")
        assert (v.timeStamps() == [1, 10])
        v = v.copy()
        v.incrementSourceCount()
        assert (v.asString() == ThawVersion(verStr2).asString())
        assert (v.getHost() == 'bang.com')

        # test that cPickle works on a Version object (the changeset cache
        # database pickles versions)
        vpickled = cPickle.dumps(v)
        vunpickled = cPickle.loads(vpickled)
        assert (vunpickled.asString() == v.asString())

        v2 = VersionFromString(
            "/foo.com@spc:bar/1.2-3/bang.com@spc:branch/2.4-5",
            timeStamps=[1.000, 10.000])
        assert (v2.freeze() == verStr)
        assert ([x.asString() for x in v2.iterLabels()
                 ] == ['foo.com@spc:bar', 'bang.com@spc:branch'])

        last = v.trailingRevision()
        assert (last.asString() == "2.4-6")
        assert (not v.onLocalLabel())
        assert (not v.isInLocalNamespace())
        assert (not v.onEmergeLabel())
        assert (not v.onLocalCookLabel())
        assert (v2.getHost() == 'bang.com')

        assert (v.trailingLabel() == Label('bang.com@spc:branch'))

        branch = v.branch()
        assert (branch.getHost() == 'bang.com')
        strrep = branch.asString()
        assert (strrep == "/foo.com@spc:bar/1.2-3/bang.com@spc:branch")
        branch2 = VersionFromString(branch.asString())
        assert (branch == branch2)

        frozen = branch.freeze()
        branch2 = ThawVersion(frozen)
        assert (branch2 == branch)

        newVer = branch2.createVersion(Revision("1.1-2"))
        assert (newVer.asString() ==
                "/foo.com@spc:bar/1.2-3/bang.com@spc:branch/1.1-2")
        assert (not newVer.onLocalLabel())
        assert (not newVer.isInLocalNamespace())
        assert (not newVer.onEmergeLabel())
        assert (not newVer.onLocalCookLabel())
        assert (not newVer.isOnLocalHost())

        assert (newVer.canonicalVersion() == newVer)
        assert (v.hasParentVersion())
        parent = v.parentVersion()
        assert (not parent.hasParentVersion())
        assert (parent.asString() == "/foo.com@spc:bar/1.2-3")

        # check emerge label
        emerge = parent.createBranch(EmergeLabel(), withVerRel=1)
        assert (emerge.getHost() == 'local')
        assert (
            emerge.asString() == "/foo.com@spc:bar/1.2-3/local@local:EMERGE/3")
        assert (not emerge.onLocalLabel())
        assert (emerge.onEmergeLabel())
        assert (not emerge.onRollbackLabel())
        assert (not emerge.onLocalCookLabel())
        assert (emerge.isOnLocalHost())
        assert (emerge.isInLocalNamespace())

        # check local cook label
        cook = parent.createBranch(CookLabel(), withVerRel=1)
        assert (cook.asString() == "/foo.com@spc:bar/1.2-3/local@local:COOK/3")
        assert (not cook.onLocalLabel())
        assert (not cook.onEmergeLabel())
        assert (not cook.onRollbackLabel())
        assert (cook.onLocalCookLabel())
        assert (cook.isOnLocalHost())
        assert (cook.isInLocalNamespace())

        # check local rollback label
        branch2 = parent.createBranch(RollbackLabel(), withVerRel=1)
        assert (branch2.asString() ==
                "/foo.com@spc:bar/1.2-3/local@local:ROLLBACK/3")
        assert (not branch2.onLocalLabel())
        assert (not branch2.onEmergeLabel())
        assert (branch2.onRollbackLabel())
        assert (not branch2.onLocalCookLabel())
        assert (branch2.isOnLocalHost())
        assert (branch2.isInLocalNamespace())

        # check local branch label
        branch2 = parent.createBranch(LocalLabel(), withVerRel=1)
        assert (
            branch2.asString() == "/foo.com@spc:bar/1.2-3/local@local:LOCAL/3")
        assert (branch2.onLocalLabel())
        assert (not branch2.onEmergeLabel())
        assert (not branch2.onRollbackLabel())
        assert (not branch2.onLocalCookLabel())
        assert (branch2.isOnLocalHost())
        assert (branch2.isInLocalNamespace())

        branch3 = VersionFromString(branch2.asString())
        assert (branch2 == branch3)

        branch2 = branch2.branch()
        assert (
            branch2.asString() == "/foo.com@spc:bar/1.2-3/local@local:LOCAL")

        parent = v.parentVersion()
        assert (parent.asString() == "/foo.com@spc:bar/1.2-3")
        branch2 = parent.createBranch(LocalLabel())
        assert (
            branch2.asString() == "/foo.com@spc:bar/1.2-3/local@local:LOCAL")

        shadow = parent.branch().createShadow(Label('foo.com@spc:shadow'))
        assert (shadow.asString() == "/foo.com@spc:bar//shadow")
        assert (shadow.getHost() == 'foo.com')

        branch = VersionFromString("/foo.com@spc:bar")
        v = VersionFromString("1.2-3", branch)
        assert (v.asString() == "/foo.com@spc:bar/1.2-3")

        # test getBinaryVersion and getSourceVersion
        v = ThawVersion(verStr)
        b = v.getBinaryVersion()
        assert (b.asString() ==
                "/foo.com@spc:bar/1.2-3-0/bang.com@spc:branch/2.4-5")

        # make sure slots are working
        v = ThawVersion("/foo.com@spec:bar/10:1.2-3")
        self.assertRaises(AttributeError, v.__setattr__, "foo", 1)
        v = ThawVersion(v.freeze())
        self.assertRaises(AttributeError, v.__setattr__, "foo", 1)

        v = VersionFromString('/localhost@rpl:linux/1.0-1-0/'
                              'local@local:EMERGE/1/COOK/2')
        assert (VersionFromString(v.asString()) == v)
예제 #40
0
    def testTroves(self, flavor=None):
        if flavor is None:
            flavor = deps.Flavor()

        store = self._connect()

        dirSet = set(['/etc', '/bin'])
        baseSet = set(['passwd', 'services', 'group', '1', '2', '3',
                       'distributed'])

        v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")

        branch = v10.branch()
        store.createTroveBranch("testtrove", branch)

        f1 = files.FileFromFilesystem("/etc/passwd", self.id1)
        f2 = files.FileFromFilesystem("/etc/services", self.id2)
        f3 = files.FileFromFilesystem("/etc/group", self.id3)
        # make a really huge dependency, thus a very large file stream
        req = deps.DependencySet()
        for x in xrange(10000):
            req.addDep(deps.SonameDependencies, deps.Dependency("libtest.so.%d" %x))
        f3.requires.set(req)
        # make sure it's way too big for a blob in mysql
        assert(len(f3.freeze()) >= 50000)

        cl = changelog.ChangeLog("test", "*****@*****.**", """\
Some changes are good.
Some changes are bad.
Some changes just are.
""")

        trv = trove.Trove('testcomp', v10, flavor, cl)
        trv.addFile(f1.pathId(), "/bin/1", v10, f1.fileId())
        trv.addFile(f2.pathId(), "/bin/2", v10, f2.fileId())
        trv.addFile(f3.pathId(), "/bin/3", v10, f3.fileId())
        trv.addFile(self.id4, "/bin/distributed", v10, self.fid4)
        trv.troveInfo.size.set(1234)
        trv.troveInfo.sourceName.set('somesource')

        req = deps.DependencySet()
        req.addDep(deps.FileDependencies, deps.Dependency("/bin/bash"))
        req.addDep(deps.TroveDependencies, deps.Dependency("foo:runtime"))
        req.addDep(deps.SonameDependencies, deps.Dependency("libtest.so.1"))
        trv.setRequires(req)

        # this also lets us peek at the database to make sure libtest.so.1
        # is only in the dep table once
        prv = deps.DependencySet()
        prv.addDep(deps.SonameDependencies, deps.Dependency("libtest.so.1"))
        trv.setProvides(prv)
        trv.computeDigests()

        store.db.transaction()
        store.addTroveSetStart([], dirSet, baseSet)
        troveInfo = store.addTrove(trv, trv.diff(None)[0])
        troveInfo.addFile(f1.pathId(), "/bin/1", f1.fileId(), v10,
                          fileStream = f1.freeze())
        troveInfo.addFile(f2.pathId(), "/bin/2", f2.fileId(), v10,
                          fileStream = f2.freeze())
        troveInfo.addFile(f3.pathId(), "/bin/3", f3.fileId(), v10,
                          fileStream = f3.freeze())
        troveInfo.addFile(self.id4, "/bin/distributed", self.fid4, v10)
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        store.db.commit()

        cu = store.db.cursor()
        cu.execute("SELECT count(*) FROM Dependencies WHERE "
                   "name = 'libtest.so.1'")
        self.assertEqual(cu.next(), (1,))

        # make sure the sha1s were stored
        cu.execute("""
        SELECT dirname, basename, sha1
        FROM TroveFiles
        JOIN FileStreams USING (streamId)
        JOIN FilePaths ON TroveFiles.filePathId = FilePaths.filePathId
        JOIN Dirnames ON FilePaths.dirnameId = Dirnames.dirnameId
        JOIN Basenames ON FilePaths.basenameId = Basenames.basenameId
        ORDER BY dirname,basename""")
        items = [(os.path.join(cu.frombinary(x[0]), cu.frombinary(x[1])),
            cu.frombinary(x[2])) for x in cu.fetchall()]
        self.assertEqual(items,
                             [ ("/bin/1", f1.contents.sha1()),
                               ("/bin/2", f2.contents.sha1()),
                               ("/bin/3", f3.contents.sha1()),
                               ("/bin/distributed", None) ])

        cl = changelog.ChangeLog("test", "*****@*****.**", "another log\n")

        fromRepos = store.getTrove("testcomp", v10, flavor, cl)
        self.assertEqual(fromRepos, trv)
        self.assertEqual(fromRepos.getVersion().timeStamps(),
                             trv.getVersion().timeStamps())
        self.assertEqual(fromRepos.getChangeLog(), trv.getChangeLog())

        self.assertEqual(
            [ x for x in store.getTrove("testcomp", v10, flavor,
                                        withFiles = False).iterFileList() ],
            [] )

        l = store.iterFilesInTrove("testcomp", v10, flavor, sortByPath = True)
        l = [ x for x in l ]
        self.assertEqual(l,
                             [ (f1.pathId(), "/bin/1", f1.fileId(), v10),
                               (f2.pathId(), "/bin/2", f2.fileId(), v10),
                               (f3.pathId(), "/bin/3", f3.fileId(), v10),
                               (self.id4, "/bin/distributed", self.fid4, v10)])

        cl = changelog.ChangeLog("test", "*****@*****.**", "log for testpkg\n")
        trv2 = trove.Trove("testpkg", v10, flavor, cl)
        trv2.addTrove(trv.getName(), v10, flavor)
        trv2.addTrove("weakref", v10, flavor, weakRef = True)
        trv2.computeDigests()
        store.addTroveSetStart([], dirSet, baseSet)
        troveInfo = store.addTrove(trv2, trv2.diff(None)[0])
        store.addTroveDone(troveInfo)
        store.addTroveSetDone()
        self.assertEqual(store.getTrove("testpkg", v10, flavor), trv2)
      
        self.assertEqual(
            [ x for x in store.iterTroves([ ("testcomp", v10, flavor),
                                            ("testpkg", v10, flavor ) ]) ],
            [trv, trv2] )
        self.assertEqual(
            [ x for x in store.iterTroves([ ("testpkg", v10, flavor ),
                                            ("testcomp", v10, flavor) ]) ],
            [trv2, trv] )
        self.assertEqual(
            [ x for x in store.iterTroves([ ("testpkg", v10, flavor),
                                            ("testpkg", v10, flavor) ]) ],
            [trv2, trv2] )
        self.assertEqual(
            [ x for x in store.iterTroves([ ("testpkg", v10, flavor ),
                                            ("blah", v10, flavor) ]) ],
            [trv2, None] )
        self.assertEqual(
            [ x for x in store.iterTroves([ ("blah", v10, flavor ),
                                            ("testpkg", v10, flavor) ]) ],
            [None, trv2] )
        self.assertEqual(
            [ x for x in store.iterTroves([ ("blah", v10, flavor ) ]) ],
            [None] )
        self.assertEqual(
            [ x for x in store.iterTroves([ ("testcomp", v10, flavor),
                                            ("blah", v10, flavor ),
                                            ("testpkg", v10, flavor ) ]) ],
            [trv, None, trv2] )

        # erasing doesn't work
        #store.eraseTrove("testcomp", v10, None)
        #store.commit()
        self.assertEqual(store.getTrove("testpkg", v10, flavor), trv2)
        
        map = { 'testpkg': [ v10 ]}
        flavors = store.getTroveFlavors(map)
        if flavor is not None:
            flavorStr = flavor.freeze()
        else:
            flavorStr = ''
        self.assertEqual(flavors, { 'testpkg': {v10: [flavorStr]}})

        map = { 'testpkg3': [ v10 ]}
        flavors = store.getTroveFlavors(map)
        self.assertEqual(flavors, { 'testpkg3': {v10: []}})

        # test getFiles
        fileObjs = store.getFiles([(f1.pathId(), f1.fileId()),
                                   (f2.pathId(), f2.fileId())])
        self.assertEqual(fileObjs[(f1.pathId(), f1.fileId())], f1)
        self.assertEqual(fileObjs[(f2.pathId(), f2.fileId())], f2)

        # test that asking for an invalid fileid/pathid pair results
        # in no entry for the (pathid, fileid) in the returned dict
        invalidPathId = md5FromString('9' * 32)
        invalidFileId = sha1FromString('9' * 40)
        fileObjs = store.getFiles([(invalidPathId, invalidFileId)])
        # make sure fileObjs is empty
        assert(not fileObjs)

        # test that asking for contents that have to come from
        # a different repository works - we should get None
        # back
        fileObjs = store.getFiles([(self.id4, self.fid4)])
        self.assertEqual(fileObjs, {(self.id4, self.fid4): None})
예제 #41
0
    def _mangleGroups(self, group):
        """
        Map all packages in the group to packages on the prod label
        using the clonedFrom information
        """

        log.info('mangling the group model')

        grpPkgs = {}

        toProd = {}

        toRemove = set()

        parent = False

        clonedFromMap = dict(self._updater._conaryhelper.getClonedFromForLabel(self._cfg.targetLabel))

        for pkg in group.iterpackages():
            if not pkg.version:
                continue
            name = str(pkg.name)
            version = ThawVersion(str(pkg.version))
            flavor = ThawFlavor(str(pkg.flavor))

            grpPkgs.setdefault((name, version), set()).add(flavor)


        for (name, version), flavors in grpPkgs.iteritems():
            for flavor in flavors:
                # Get the nevra for this name, version, and flavor
                nevra = clonedFromMap.get((name, version, flavor))

                # If the package is already in the toAdd map, skip over it.
                if [ x for x in toProd
                    if x[0] == name and flavor in toProd[(x[0], x[1])] ]:
                    log.warn('%s %s is already in the toProd map' % (name,flavor))
                    continue


                # Package didn't change not sure this should happen
                if not nevra and (name,version,flavor) in clonedFromMap.values():
                    continue

                # Another hack for rhel 5 client workstation
                if self._cfg.topParentSourceGroup:
                    parent = True

                if 'rhel-5-client-workstation' in str(self._cfg.topSourceGroup):
                    parent = True

                if not nevra and parent:
                    log.warn('Child platform')
                    for original, clone in clonedFromMap.iteritems(): 
                        if (name == original[0] and 
                            version.trailingRevision() == original[1].trailingRevision() 
                            and flavor == original[2]):
                            log.warn('adding %s' % str(clone))
                            n2, v2, f2 = clone
                            toProd.setdefault((n2, v2), set()).add(f2)
                            toRemove.add((name, version, flavor))
                            break
                    continue

                # Feels like a hack for RHEL4AS... might revisit this later
                #if not flavor.thaw():
                #    log.warn('No flavor for %s %s %s' % (name, version, flavor))
                #    for original, clone in clonedFromMap.iteritems(): 
                #        if original[0] == name and original[1] == version:
                #            n2, v2, f2 = clone
                #            toProd.setdefault((n2, v2), set()).add(f2)
                #    toRemove.add((name, version, flavor))
                #    continue

                toRemove.add((name, version, flavor))

                n2, v2, f2 = nevra
                toProd.setdefault((n2, v2), set()).add(f2)

        ##
        # Remove any packages that were flagged for removal.
        ##

        for n, v, f in toRemove:
            log.info('removing %s[%s]' % (n, f))
            group.removePackage(n, flavor=f)

        ##
        # Actually add the packages to the group model.
        ##

        for (name, version), flavors in toProd.iteritems():
            for f in flavors:
                log.info('adding %s=%s[%s]' % (name, version, f))
            group.addPackage(name, version, flavors)

        return group
예제 #42
0
    def testSqlVersioning(self):
        db = self.getDB()
        schema.createSchema(db)

        vTbl = versiontable.VersionTable(db)
        bTbl = versionops.BranchTable(db)
        sv = versionops.SqlVersioning(db, vTbl, bTbl)
        i = items.Items(db)
        # we need the FileStreams table for eraseVersion to work
        # properly. It is created as part of the createTroves() call

        v5 = ThawVersion("/conary.rpath.com@test:trunk/5:1.2-5")
        v10 = ThawVersion("/conary.rpath.com@test:trunk/10:1.2-10")
        v15 = ThawVersion("/conary.rpath.com@test:trunk/15:1.2-15")
        v20 = ThawVersion("/conary.rpath.com@test:trunk/20:1.2-20")

        branch = v10.branch()
        itemId = i.addId('foo')
        sv.createBranch(itemId, branch)

        sv.createVersion(itemId, v10, 0, "foo:source")
        assert(bTbl.has_key(branch))
        assert(vTbl.has_key(v10))
        assert(sv.hasVersion(itemId, vTbl[v10]))
        assert(i.has_key("foo:source"))
        assert(not sv.hasVersion(2, vTbl[v10]))

        branchId = bTbl[branch]

        itemId2 = i.addId('bar')
        sv.createBranch(itemId2, branch)
        sv.createVersion(itemId2, v10, 0, None)
        self.assertRaises(versionops.DuplicateVersionError,
                          sv.createVersion, itemId2, v10, 0, None)

        assert([vTbl.getId(x) for x in sv.versionsOnBranch(1, branchId)]
                    == [ str(v10) ])

        sv.createVersion(1, v20, 0, None)
        assert([vTbl.getId(x) for x in sv.versionsOnBranch(1, branchId)]
                    == [ str(v20), str(v10) ])

        sv.createVersion(1, v15, 0, None)
        db.commit()
        assert([vTbl.getId(x) for x in sv.versionsOnBranch(1, branchId)] ==
               [ str(v20), str(v15), str(v10) ])

        sv.createVersion(1, v5, 0, None)
        assert([vTbl.getId(x) for x in sv.versionsOnBranch(1, branchId)] ==
               [ str(v20), str(v15), str(v10), str(v5) ])

        label = Label("conary.rpath.com@test:trunk")
        assert [bTbl.getId(x) for x in sv.branchesOfLabel(1, label) ]\
                    == [ branch ]

        brLabel = Label("conary.rpath.com@test:br1")

        branch1 = v10.createBranch(brLabel, withVerRel = False)
        branch2 = v20.createBranch(brLabel, withVerRel = False)

        sv.createBranch(1, branch1)
        sv.createBranch(1, branch2)

        assert([bTbl.getId(x) for x in sv.branchesOfLabel(1, brLabel)] == \
               [branch1, branch2])

        assert([bTbl.getId(x) for x in sv.branchesOfItem(1)] ==
                    [ branch, branch1, branch2 ])