def testBlockDevice(self): foo = filetypes.BlockDevice(8, 1) fileObj = foo.get(pathId) self.assertEquals(fileObj.lsTag, 'b') self.assertEquals(fileObj.devt.major(), 8) self.assertEquals(fileObj.devt.minor(), 1) self.assertEquals(foo.getContents(), None) requires = deps.ThawDependencySet('4#foo::runtime') provides = deps.ThawDependencySet('11#foo') foo = filetypes.BlockDevice(8, 1, provides=provides, requires=requires) fileObj = foo.get(pathId) self.assertEquals(fileObj.provides(), provides) self.assertEquals(fileObj.requires(), requires)
def getDepCacheEntry(self, troveTup): result = self.depCache.get(troveTup) if result is None: return None origResult = result if type(result[0]) is str: result = (deps.ThawDependencySet(result[0]), result[1]) if type(result[1]) is str: result = (result[0], deps.ThawDependencySet(result[1])) if result != origResult: self.depCache[troveTup] = result return result
def testRegularFileBasics(self): foo = filetypes.RegularFile(contents='foo1') fileObj = foo.get(pathId) f = foo.getContents() self.assertEquals(f.read(), 'foo1') self.assertEquals(fileObj.flags(), 0) self.assertEquals(fileObj.flavor(), deps.Flavor()) self.assertEquals(fileObj.provides(), deps.DependencySet()) self.assertEquals(fileObj.requires(), deps.DependencySet()) self.assertEquals(fileObj.inode.perms(), 0644) self.assertEquals(fileObj.inode.owner(), 'root') self.assertEquals(fileObj.inode.group(), 'root') self.assertEquals(fileObj.lsTag, '-') self.assertEquals(fileObj.linkGroup(), None) self.assertEquals( fileObj.fileId(), '(\x01\x9a\xcbz\xbb\x93\x15\x01c\xcf\xd5\x14\xef\xf7,S\xbb\xf8p') requires = deps.ThawDependencySet('4#foo::runtime') provides = deps.ThawDependencySet('11#foo') flv = deps.parseFlavor('xen,domU is: x86') bar = filetypes.RegularFile(contents=StringIO('bar'), config=True, provides=provides, requires=requires, flavor=flv, owner='foo', group='bar', perms=0700, mtime=12345, tags=['tag1', 'tag2']) fileObj = bar.get(pathId) self.assertEquals(bool(fileObj.flags.isInitialContents()), False) self.assertEquals(bool(fileObj.flags.isTransient()), False) self.assertEquals(bool(fileObj.flags.isConfig()), True) self.assertEquals(fileObj.requires(), requires) self.assertEquals(fileObj.provides(), provides) self.assertEquals(fileObj.flavor(), flv) self.assertEquals(fileObj.inode.perms(), 0700) self.assertEquals(fileObj.inode.owner(), 'foo') self.assertEquals(fileObj.inode.group(), 'bar') self.assertEquals(fileObj.inode.mtime(), 12345) self.assertEquals(fileObj.tags(), ['tag1', 'tag2'])
def _loadDepSolutions(self): if self.version < (2, 0): # Earlier versions were missing timestamps, which interferes with # dep solver tie-breaking. return depSolutionsList = self._loadPickle(self._depSolutionsPathId) for (sig, depSet, aResult) in depSolutionsList: depSet = deps.ThawDependencySet(depSet) allResults = [] for resultList in aResult: allResults.append([(x[0], versions.ThawVersion(x[1]), deps.ThawFlavor(x[2])) for x in resultList]) self.addDepSolution(sig, depSet, allResults)
def _loadDepSolutions(self): if self.version < (3, 0): # Version 1 was missing timestamps, which interferes with dep # solver tie-breaking. # Version 2 could have bogus unresolved dep solutions due to a bug # so the version was bumped to invalidate those. return depSolutionsList = self._loadPickle(self._depSolutionsPathId) for (sig, depSet, aResult) in depSolutionsList: depSet = deps.ThawDependencySet(depSet) allResults = [] for resultList in aResult: allResults.append([ (x[0], versions.ThawVersion(x[1]), deps.ThawFlavor(x[2])) for x in resultList]) self.addDepSolution(sig, depSet, allResults)
def testRPMCapsuleUserGroup(self): recipestr1 = r""" class TestGroup(CapsuleRecipe): name = 'test' version = '0' clearBuildReqs() def setup(r): r.addCapsule('ownerships-1.0-1.i386.rpm') """ built, d = self.buildRecipe(recipestr1, "TestGroup") nvf = built[0] nvf = nvf[0], versions.VersionFromString(nvf[1]), nvf[2] repos = self.openRepository() trv = repos.getTrove(*nvf) self.assertEquals( trv.requires(), deps.ThawDependencySet( '17#CompressedFileNames|17#PayloadFilesHavePrefix|' '17#PayloadIsBzip2'))
def testUserInfoGroupInfoSplitting(self): """ We need to create users and groups sepparately to handle dependency loops in group memebership. For instance on CentOS 6 the daemon user is in the bin, lp, and daemon groups. The lp user is in the daemon and lp groups. This means that neither of these users can be installed due to the depency loop. The install code does put all of the uesrs into the same install job, but then can't deal with the loop. (CNY-3731) """ daemonInfoRecipe = """ class InfoDaemon(UserInfoRecipe): name = 'info-daemon' version = '1' clearBuildReqs() def setup(r): r.User('daemon', 2, supplemental=['lp', 'bin']) """ lpInfoRecipe = """ class InfoLp(UserInfoRecipe): name = 'info-lp' version = '1' clearBuildReqs() def setup(r): r.User('lp', 3, supplemental=['daemon', ]) """ binInfoRecipe = """ class InfoBin(UserInfoRecipe): name = 'info-bin' version = '1' clearBuildReqs() def setup(r): r.User('bin', 4, supplemental=['daemon', ]) """ comps1, r1 = self.buildRecipe(daemonInfoRecipe, 'InfoDaemon') comps2, r2 = self.buildRecipe(lpInfoRecipe, 'InfoLp') comps3, r3 = self.buildRecipe(binInfoRecipe, 'InfoBin') # Make sure there is a :user and :group component for each package. for comps in (comps1, comps2, comps3): self.failUnlessEqual(len([ x for x in comps if x[0].endswith(':user') or x[0].endswith(':group') ]), 2) group1, user1 = sorted(comps1) group2, user2 = sorted(comps2) group3, user3 = sorted(comps3) repos = self.openRepository() user1nvf = repos.findTrove(None, user1) user2nvf = repos.findTrove(None, user2) user3nvf = repos.findTrove(None, user3) user1trv = repos.getTrove(*user1nvf[0]) user2trv = repos.getTrove(*user2nvf[0]) user3trv = repos.getTrove(*user3nvf[0]) group1nvf = repos.findTrove(None, group1) group2nvf = repos.findTrove(None, group2) group3nvf = repos.findTrove(None, group3) group1trv = repos.getTrove(*group1nvf[0]) group2trv = repos.getTrove(*group2nvf[0]) group3trv = repos.getTrove(*group3nvf[0]) # info-daemon:user should require info-bin:group, info-daemon:group, # and info-lp:group. self.failUnlessEqual(user1trv.requires, deps.ThawDependencySet('8#bin|8#daemon|8#lp')) # info-lp:user should require info-daemon:group and info-lp:group. self.failUnlessEqual(user2trv.requires, deps.ThawDependencySet('8#daemon|8#lp')) # info-bin:user should require info-bin:group and info-dameon:group. self.failUnlessEqual(user3trv.requires, deps.ThawDependencySet('8#bin|8#daemon')) # Make sure the user components don't provide groups. self.failUnlessEqual(user1trv.provides, deps.ThawDependencySet('4#info-daemon::user|7#daemon')) self.failUnlessEqual(user2trv.provides, deps.ThawDependencySet('4#info-lp::user|7#lp')) self.failUnlessEqual(user3trv.provides, deps.ThawDependencySet('4#info-bin::user|7#bin')) # Make sure the group components provide the groups self.failUnlessEqual(group1trv.provides, deps.ThawDependencySet('4#info-daemon::group|8#daemon')) self.failUnlessEqual(group2trv.provides, deps.ThawDependencySet('4#info-lp::group|8#lp')) self.failUnlessEqual(group3trv.provides, deps.ThawDependencySet('4#info-bin::group|8#bin')) # And that the groups don't require anything self.failUnlessEqual(group1trv.requires, deps.ThawDependencySet('')) self.failUnlessEqual(group2trv.requires, deps.ThawDependencySet('')) self.failUnlessEqual(group3trv.requires, deps.ThawDependencySet('')) self.updatePkg('info-daemon:user', resolve=True)
def resolve(self, groupIds, label, depList, troveList=[], leavesOnly=False): """ Determine troves that provide the given dependencies, restricting by label and limiting to latest version for each (name, flavor) pair. """ cu = self.db.cursor() # need to make sure that depList does not contain duplicates # for efficiency reasons requires = {} for depStr in depList: depSet = deps.ThawDependencySet(depStr) requires[depSet] = depStr depSetList = requires.keys() depNums = self._setupDepSets(cu, depSetList) # 1. look up inmstances whose provides fully satisfy all the # flags of every depName within a depSet (flagCount check) # 2. out of those instances, only consider the ones that fully # satisfy all the depName deps within a depSet (depCount # check) # 3. filter only the instanceIds the user has access to query = """ select distinct tmpDepNum.idx as idx, tmpDepNum.depNum as depNum, Items.item, flavor, version, Nodes.timeStamps, Nodes.finalTimestamp as finalTimestamp from tmpDepNum join ( select tmpDeps.idx as idx, tmpDeps.depNum as depNum, Provides.instanceId as instanceid, count(*) as flagCount from tmpDeps join Dependencies using(class, name, flag) join Provides using(depId) group by tmpDeps.idx, tmpDeps.depNum, Provides.instanceId ) as DepSelect using(idx, depNum, flagCount) join Instances on Instances.instanceId = DepSelect.instanceId join Nodes using(itemId, versionId) """ where = [ "ugi.userGroupId in (%s)" % (",".join("%d" % x for x in groupIds), ) ] args = [] if troveList: self._setupTroveList(cu, troveList) query += """ join tmpInstances as ti on ti.instanceId = Instances.instanceId join UserGroupInstancesCache as ugi on ugi.instanceId = ti.instanceId """ else: if leavesOnly: query += """ join LatestCache as ugi using (itemId, versionId, branchId) """ where.append("ugi.latestType = %d" % trovesource.TROVE_QUERY_NORMAL) where.append("ugi.flavorId = Instances.flavorId") else: query += """ join UserGroupInstancesCache as ugi on ugi.instanceId = Instances.instanceId """ # restrict by label if label: query += """ join LabelMap on Instances.itemId = LabelMap.itemId and Nodes.branchId = LabelMap.branchId join Labels using (labelId) """ where.append("Labels.label = ?") args.append(label) # final joins to allow us to extract the query results as strings query += """ join Items on Instances.itemId = Items.itemId join Versions on Instances.versionId = Versions.versionId join Flavors on Instances.flavorId = Flavors.flavorId where %s order by idx, depNum, finalTimestamp desc """ % (" and ".join(where)) cu.execute(query, args) # sqlite version 3.2.2 have trouble sorting correctly the # results from the previous query. If we're running on sqlite, # we take the hit here and resort the results in Python... if self.db.driver == "sqlite": # order by idx, depNum, finalTimestamp desc retList = sorted(cu, key=lambda a: (a[0], a[1], -a[6])) else: retList = cu ret = {} for (depId, depNum, troveName, flavorStr, versionStr, timeStamps, ft) in retList: retd = ret.setdefault(depId, [{} for x in xrange(depNums[depId])]) # remember the first version of each (n,f) tuple for each query retd[depNum].setdefault((troveName, flavorStr), (versionStr, timeStamps)) ret2 = {} for depId, depDictList in ret.iteritems(): key = requires[depSetList[depId]] retList = ret2.setdefault(key, [[] for x in xrange(len(depDictList))]) for i, depDict in enumerate(depDictList): retList[i] = [(trv[0], versions.strToFrozen(ver[0], ver[1].split(":")), trv[1]) for trv, ver in depDict.iteritems()] # fill in the result dictionary for the values we have not resolved deps for result = {} for depId, depSet in enumerate(depSetList): result.setdefault(requires[depSet], [[] for x in xrange(depNums[depId])]) result.update(ret2) return result