Exemple #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)
Exemple #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)
Exemple #3
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)
Exemple #4
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)
Exemple #5
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]))
Exemple #6
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})
Exemple #7
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()
Exemple #8
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)
Exemple #9
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)
Exemple #10
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()
Exemple #11
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)
Exemple #12
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 ])
Exemple #13
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
Exemple #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]))
Exemple #15
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]))
Exemple #16
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]))
Exemple #17
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})
Exemple #18
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])