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)
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)
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 _createCs(version): # create an absolute changeset flavor = deps.parseFlavor('') cs = changeset.ChangeSet() # add a pkg diff v = versions.VersionFromString(version, timeStamps=[1.000]) old = trove.Trove('test', v, flavor, None) old.setIsCollection(True) old.addTrove('test:foo', v, flavor, byDefault=True) old.addTrove('test:bar', v, flavor, byDefault=False) old.computeDigests() # add the 'test' package diff = old.diff(None)[0] cs.newTrove(diff) cs.addPrimaryTrove('test', v, flavor) # add the test:foo component oldfoo = trove.Trove('test:foo', v, flavor, None) oldfoo.computeDigests() diff = oldfoo.diff(None)[0] cs.newTrove(diff) # add the test:bar component oldbar = trove.Trove('test:bar', v, flavor, None) oldbar.computeDigests() diff = oldbar.diff(None)[0] cs.newTrove(diff) return cs
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() == [])
def _logDifferenceInPrebuiltReqs(self, trv, buildReqTups, preBuiltReqs): existsTrv = trove.Trove('@update', versions.NewVersion(), deps.Flavor(), None) availableTrv = trove.Trove('@update', versions.NewVersion(), deps.Flavor(), None) for troveNVF in preBuiltReqs: existsTrv.addTrove(*troveNVF) for troveNVF in buildReqTups: availableTrv.addTrove(*troveNVF) jobs = availableTrv.diff(existsTrv)[2] formatter = display.JobTupFormatter(affinityDb=None) formatter.dcfg.setTroveDisplay(fullVersions=True, fullFlavors=True, showComponents=True) formatter.dcfg.setJobDisplay(compressJobs=True) formatter.prepareJobLists([jobs]) self.logger.info('Could count %s=%s[%s]{%s} as prebuilt - the' ' following changes have been made in its' ' buildreqs:' % trv.getNameVersionFlavor( withContext=True)) for line in formatter.formatJobTups(jobs): self.logger.info(line) self.logger.info('...Rebuilding')
def testFreezeThawTroveMap(self): db = database.Database(':memory:', ':memory:') uJob = database.UpdateJob(db) uJob.setTransactionCounter(100) now = 1234567890.0 v1 = VersionFromString('/a@b:c/1.0-1', timeStamps=[now]) v2 = VersionFromString('/a@b:c/1.0-2', timeStamps=[now + 1]) flv1 = parseFlavor("") flv2 = parseFlavor("is: x86") trv1 = trove.Trove("trove1", v1, flv1) trv2 = trove.Trove("trove2", v2, flv2) nvf1 = trv1.getNameVersionFlavor() nvf2 = trv2.getNameVersionFlavor() uJob._troveMap[nvf1] = trv1 uJob._troveMap[nvf2] = trv2 expKeys = set([nvf1, nvf2]) uJob.freeze(self.workDir) uJob = database.UpdateJob(db) uJob.thaw(self.workDir) self.assertEqual(uJob.getTransactionCounter(), 100) self.assertEqual(set(uJob._troveMap.keys()), expKeys) self.assertEqual( trv1.diff(None)[0].freeze(), uJob._troveMap[nvf1].diff(None)[0].freeze()) self.assertEqual( trv2.diff(None)[0].freeze(), uJob._troveMap[nvf2].diff(None)[0].freeze())
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()])
def testRPMCapsuleMtimeOverlapConflictsOK(self): '''make sure that conflicting overlapping mtimes can be overridden''' recipestr = """ class TestRPMCapsulePathOverlapConflictsOK(CapsuleRecipe): name = 'simple' version = '1.0' clearBuildReqs() def setup(r): r.addCapsule('simple-1.0.1-1.i386.rpm') r.addCapsule('simple-1.0-1.i386.rpm') """ pkgName = 'simple' rpmNames = ['simple-1.0.1-1.i386.rpm', 'simple-1.0-1.i386.rpm'] builtPkgNames = ['simple'] pkgNames, built, cs = self._cookAndInstall(recipestr, rpmNames, pkgName, builtPkgNames) self.assertEquals(pkgNames, ['simple', 'simple:rpm']) # Ensure that all the paths exist that should, including overlap for tcs in cs.iterNewTroveList(): trv = trove.Trove(tcs) troveName = trv.getName() if troveName.endswith(':rpm'): paths = [x[1] for x in trv.iterFileList()] self.assertEquals(sorted(paths), ['/config', '/dir', '/normal'])
def testFileContentsMissing(self): # currently causes a 500 error #raise testhelp.SkipTestException # create an absolute changeset cs = changeset.ChangeSet() # add a pkg diff flavor = deps.deps.parseFlavor('') v = versions.VersionFromString('/%s/1.0-1-1' %self.cfg.buildLabel.asString()).copy() v.resetTimeStamps() t = trove.Trove('test:test', v, flavor, None) path = self.workDir + '/blah' f = open(path, 'w') f.write('hello, world!\n') f.close() pathId = sha1helper.md5String('/blah') f = files.FileFromFilesystem(path, pathId) # add the file, but munge the fileid fileId = f.fileId() cs.addFile(None, fileId, f.freeze()) t.addFile(pathId, '/blah', v, fileId) # skip adding the file contents t.computeDigests() diff = t.diff(None, absolute = 1)[0] cs.newTrove(diff) repos = self.openRepository() try: repos.commitChangeSet(cs) assert 0, "Did not raise integrity error" except errors.IntegrityError, e: assert(str(e).startswith("Missing file contents for pathId e806729b6a2b568fa7e77c3efa3a9684, fileId"))
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)
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()
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))
def _handleJob(self, job, recursed, idx): t = self.trvIterator.next() if t is not None: if self.withFiles: t, streams = t else: streams = {} if t is None: if recursed: # synthesize a removed trove for this missing # trove t = trove.Trove(job[0], job[idx][0], job[idx][1], type=trove.TROVE_TYPE_REMOVED) t.setIsMissing(True) t.computeDigests() # synthesize empty filestreams streams = {} else: # drain the iterator, in order to complete # the sql queries for x in self.trvIterator: pass raise errors.TroveMissing(job[0], job[idx][0]) return t, streams
def getCML(self, troveCache, nvf): key = "%s=%s[%s]" % nvf lines = troveCache.getCachedFile(key) if lines is not None: return lines cs = troveCache.getRepos().createChangeSet([(nvf[0], (None, None), (nvf[1], nvf[2]), True)], withFiles=True, withFileContents=True) trv = trove.Trove(cs.getNewTroveVersion(*nvf)) files = list(trv.iterFileList()) if nvf[0].endswith(':source'): files = [x for x in files if x[1].endswith('.cml')] if len(files) > 1: raise IncludeException( 'Too many cml files found in %s=%s[%s]: %s' % (nvf + (" ".join(x[1] for x in sorted(files)), ))) elif not files: raise IncludeException('No cml files found in %s=%s[%s]' % nvf) fileContents = cs.getFileContents(files[0][0], files[0][2]) lines = fileContents[1].get().readlines() troveCache.cacheFile(key, lines) return lines
def testNetworkSearchSource(self): repos = self.openRepository() trv1 = self.addComponent('foo:runtime', '1', 'ssl') trv2 = self.addComponent('foo:runtime', '2', '!ssl') s = searchsource.NetworkSearchSource(repos, self.cfg.installLabelPath, parseFlavor('ssl')) tup = s.findTrove(('foo:runtime', None, None))[0] assert(tup == trv1.getNameVersionFlavor()) tup = s.findTrove(('foo:runtime', None, parseFlavor('!ssl')))[0] assert(tup == trv2.getNameVersionFlavor()) trv = s.getTrove(*tup) assert(trv == trv2) cs = s.createChangeSet([(tup[0], (None, None), (tup[1], tup[2]), True)]) trvCs = cs.getNewTroveVersion(*trv.getNameVersionFlavor()) trv = trove.Trove(trvCs) assert(trv == trv2) assert(list(s.iterFilesInTrove(*trv.getNameVersionFlavor())) == list(repos.iterFilesInTrove(*trv.getNameVersionFlavor()))) # test dep resolution - the resolve source for this should check # the right branch. self.cfg.installLabelPath = [versions.Label('localhost@rpl:branch')] self.addComponent('bar:runtime', ':branch/1', filePrimer=1, requires='trove:foo:runtime') self.checkUpdate('bar:runtime', ['bar:runtime', 'foo:runtime=1'], resolveSource=s.getResolveMethod(), resolve=True)
def tempSourceTrove(recipePath, package, helper): from conary import state from conary import checkin from conary import trove from conary.lib import util as cnyutil pkgname = package.name.split(':')[0] nvf, cs = _makeSourceTrove(package, helper) targetDir = os.path.join(os.path.dirname(recipePath), pkgname) cnyutil.mkdirChain(targetDir) sourceStateMap = {} pathMap = {} conaryStateTargets = {} troveCs = cs.getNewTroveVersion(*nvf) trv = trove.Trove(troveCs) sourceState = state.SourceState(nvf[0], nvf[1], nvf[1].branch()) if trv.getFactory(): sourceState.setFactory(trv.getFactory()) conaryState = state.ConaryState(helper.cfg.context, sourceState) sourceStateMap[trv.getNameVersionFlavor()] = sourceState conaryStateTargets[targetDir] = conaryState for (pathId, path, fileId, version) in troveCs.getNewFileList(): pathMap[(nvf, path)] = (targetDir, pathId, fileId, version) # Explode changeset contents. checkin.CheckoutExploder(cs, pathMap, sourceStateMap) # Write out CONARY state files. for targetDir, conaryState in conaryStateTargets.iteritems(): conaryState.write(targetDir + '/CONARY') return trv, targetDir
def testRPMObsoletes(self): '''make sure that obsoletes is represented in troveinfo''' recipestr = """ class TestRPMObsoletes(CapsuleRecipe): name = 'obsolete' version = '1.0' clearBuildReqs() def setup(r): r.addCapsule('obsolete-1.0-1.i386.rpm') """ pkgName = 'obsolete' rpmName = 'obsolete-1.0-1.i386.rpm' r1 = self._cookPkgs(recipestr, rpmName, pkgName, 'obsolete') trvCs = [ x for x in r1[2].iterNewTroveList() if x.getName() == 'obsolete:rpm' ][0] archivePath = resources.get_archive() trv = trove.Trove(trvCs) f = open(archivePath + '/' + rpmName, "r") h = rpmhelper.readHeader(f) obs = [x[1] for x in trv.troveInfo.capsule.rpm.obsoletes.iterAll()] obl = [(x.name(), x.flags(), x.version()) for x in obs] obl.sort() reference = [('bar', 2L, '1.0'), ('baz', 4L, '2.0'), ('foo', 0L, '')] self.assertEqual(obl, reference)
def testRPMSHA1SigTag(self): '''make sure that SHA1HEADER/SIG_SHA1 is represented in troveinfo''' recipestr = """ class TestRPMSHA1(CapsuleRecipe): name = 'simple' version = '1.0' clearBuildReqs() def setup(r): r.addCapsule('simple-1.0-1.i386.rpm') """ pkgName = 'simple' rpmName = 'simple-1.0-1.i386.rpm' r = self._cookPkgs(recipestr, rpmName, pkgName, 'simple') trvCs = [ x for x in r[2].iterNewTroveList() if x.getName() == 'simple:rpm' ][0] archivePath = resources.get_archive() trv = trove.Trove(trvCs) f = open(archivePath + '/' + rpmName, "r") h = rpmhelper.readHeader(f) sha1header = trv.troveInfo.capsule.rpm.sha1header() self.assertEqual(h.get(rpmhelper.SIG_SHA1), sha1helper.sha1ToString(sha1header))
def testFileIdWrong(self): # create an absolute changeset cs = changeset.ChangeSet() # add a pkg diff flavor = deps.deps.parseFlavor('') v = versions.VersionFromString('/%s/1.0-1-1' %self.cfg.buildLabel.asString()).copy() v.resetTimeStamps() t = trove.Trove('test:test', v, flavor, None) path = self.workDir + '/blah' f = open(path, 'w') f.write('hello, world!\n') f.close() pathId = sha1helper.md5String('/blah') f = files.FileFromFilesystem(path, pathId) # add the file, but munge the fileid brokenFileId = ''.join(reversed(f.fileId())) cs.addFile(None, brokenFileId, f.freeze()) t.addFile(pathId, '/blah', v, brokenFileId) t.computeDigests() diff = t.diff(None, absolute = 1)[0] cs.newTrove(diff) repos = self.openRepository() try: repos.commitChangeSet(cs) assert 0, "Integrity Error not raised" except errors.TroveIntegrityError, e: assert(str(e) == 'fileObj.fileId() != fileId in changeset for ' 'pathId %s' % sha1helper.md5ToString(pathId))
def testFileObjMissing(self): # create an absolute changeset cs = changeset.ChangeSet() # add a pkg diff flavor = deps.deps.parseFlavor('') v = versions.VersionFromString('/%s/1.0-1-1' %self.cfg.buildLabel.asString()).copy() v.resetTimeStamps() t = trove.Trove('test:test', v, flavor, None) path = self.workDir + '/blah' f = open(path, 'w') f.write('hello, world!\n') f.close() pathId = sha1helper.md5String('/blah') f = files.FileFromFilesystem(path, pathId) # add the file, and SKIP including # the filestream by using cs.addFile(). This creates an # incomplete changeset t.addFile(pathId, '/blah', v, f.fileId()) cs.addFileContents(pathId, f.fileId(), changeset.ChangedFileTypes.file, filecontents.FromFilesystem(path), f.flags.isConfig()) t.computeDigests() diff = t.diff(None, absolute = 1)[0] cs.newTrove(diff) repos = self.openRepository() try: repos.commitChangeSet(cs) assert 0, "Did not raise IntegrityError" except errors.IntegrityError, e: assert(str(e).startswith("Incomplete changeset specified: missing pathId e806729b6a2b568fa7e77c3efa3a9684 fileId"))
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 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)
def install(self, flags, troveCs): if troveCs.getOldVersion(): oldTrv = self.db.getTrove(*troveCs.getOldNameVersionFlavor()) trv = oldTrv.copy() trv.applyChangeSet(troveCs) else: oldTrv = None trv = trove.Trove(troveCs) #if oldTrv and oldTrv.troveInfo.capsule == trv.troveInfo.capsule: # the capsule hasn't changed, so don't reinstall it #return None for pathId, path, fileId, version in trv.iterFileList(capsules=True): # there should only be one... break assert (pathId == trove.CAPSULE_PATHID) if oldTrv: for oldPathId, oldPath, oldFileId, oldVersion in \ oldTrv.iterFileList(capsules = True): # there should only be one... break assert (oldPathId == trove.CAPSULE_PATHID) if (oldFileId == fileId or oldTrv.troveInfo.capsule == trv.troveInfo.capsule): # good enough. this means changing capsule information # in trove info won't fool us into trying to reinstall # capsules which haven't changed. we check the capsule # information as well because derived packages change # the capsule fileIds. ugh. # # we do it in this order to make sure the test suite tests # both sides of the "or" above return self.remove(oldTrv) # is the capsule new or changed? changedFileInfos = [ x for x in troveCs.getChangedFileList() if x[0] == trove.CAPSULE_PATHID ] if changedFileInfos: oldFileId = oldTrv.getFile(pathId)[1] oldFileObjs = self.db.getFileStream(oldFileId) fileObj = files.ThawFile(oldFileObjs, pathId) fileChange = self.changeSet.getFileChange(oldFileId, fileId) fileObj.twm(fileChange, fileObj) sha1 = fileObj.contents.sha1() else: fileStream = self.changeSet.getFileChange(None, fileId) sha1 = files.frozenFileContentInfo(fileStream).sha1() self.installs.append((troveCs, (pathId, path, fileId, sha1))) return (oldTrv, trv)
def testLocalFactoryWithLocalRecipe(self): os.chdir(self.workDir) self.newpkg("foo", factory="test") os.chdir("foo") self.writeFile( "factory-test.recipe", """ class TestFactory(Factory): name = "factory-test" version = "1.0" def getRecipeClass(self): class TestSubclass(PackageRecipe): name = "testsubclass" version = "1.0" internalAbstractBaseClass = True clearBuildReqs() return TestSubclass """) self.writeFile( "foo.recipe", """ # CNY-2813. importing log inside a recipe used to reset the loglevel from conary.lib import log class FooRecipe(FactoryRecipeClass): name = "foo" version = "1.1" def setup(self): self.Create("/etc/foo", "foo") """) self.addfile("foo.recipe") repos = self.openRepository() cstate = state.ConaryStateFromFile('CONARY') level = log.getVerbosity() try: log.setVerbosity(log.INFO) klass = logging.getLoggerClass() self.discardOutput(cook.cookCommand, self.cfg, [cstate], False, {}) self.assertEquals(klass, logging.getLoggerClass()) finally: log.setVerbosity(level) ccs = changeset.ChangeSetFromFile( os.path.join(self.workDir, 'foo', 'foo-1.1.ccs')) trvs = [trove.Trove(x) for x in ccs.iterNewTroveList()] trv = [x for x in trvs if x.getName() == 'foo:debuginfo'][0] files = [x for x in trv.iterFileList() if \ x[1] == '/usr/src/debug/buildlogs/foo-1.1-log.bz2'] fileId, path, pathId, ver = files[0] fileInfo, fileObj = ccs.getFileContents(fileId, pathId) decomp = bz2.BZ2Decompressor() data = decomp.decompress(fileObj.f.read()) self.assertFalse("+ Processing" not in data, "build log data appears to be incomplete")
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 doProcess(self, recipe): # map paths into the correct components for trvCs in self.recipe.cs.iterNewTroveList(): trv = trove.Trove(trvCs) if not trv.isCollection(): f = filter.PathSet((x[1] for x in trv.iterFileList()), name=trv.getName().split(':')[1]) self.derivedFilters.append(f) capsulepolicy.ComponentSpec.doProcess(self, recipe)
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 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)
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])