def testPerlReqs(self): self.openRmakeRepository() repos = self.openRepository() trvname = "perl-dummy" perl = self.addComponent('perl:lib', provides='perl: CGI perl: strict') trv = self.makeSourceTrove(trvname, testPerlRecipe) troveTup = repos.findTrove(self.cfg.buildLabel, (trvname + ':source', None, None), None)[0] cookFlavor = deps.parseFlavor('readline,ssl,X') troveTup = (troveTup[0], troveTup[1], cookFlavor) db = self.openRmakeDatabase() job = self.newJob(troveTup) buildTrove = buildtrove.BuildTrove(job.jobId, *troveTup) buildTrove.setPublisher(job.getPublisher()) logFile = logfile.LogFile(self.workDir + '/chrootlog') logFile.redirectOutput() mgr, factory, cfg, client = self._createRoot([perl], buildTrove, start=True) logPath = client.buildTrove(cfg, cfg.getTargetLabel(troveTup[1]), *troveTup) result = client.checkResults(wait=20, *troveTup) client.stop() logFile.restoreOutput() assert (result) assert (result.isBuildSuccess()) cs = changeset.ChangeSetFromFile(result.getChangeSetFile()) trvHash = {} for trv in cs.iterNewTroveList(): trvHash[trv.getName()] = trv # this also checks to make sure build logging is turned on if len(trvHash) < 3: raise RuntimeError('logging turned off!') self.failUnless(trvname in trvHash) self.failUnless(trvname + ':data' in trvHash) self.failUnless(trvname + ':debuginfo' in trvHash) trv = trvHash[trvname + ':data'] dps = [(d[0].tagName, d[1].getName()) for d in trv.getRequires().iterDeps()] dps.sort() self.failUnlessEqual(dps, [('perl', ('CGI', )), ('perl', ('strict', ))])
def testInit(self): bt = buildtrove.BuildTrove(1, *self.makeTroveTuple('foo:source')) bt.setConfig(self.buildCfg) it = imagetrove.ImageTrove(1, *self.makeTroveTuple('group-foo')) publisher = mock.MockObject() dh = dephandler.DependencyHandler(publisher, None, [bt], [it]) assert (dh.moreToDo()) bt.troveBuilt([]) assert (dh.hasSpecialTroves()) assert (dh.popSpecialTrove() == it) assert (dh.specialTroves)
def testBuildTrove(self): trv = self.addComponent('blah:source', '1.0') bt = buildtrove.BuildTrove(1, trv.getName(), trv.getVersion(), trv.getFlavor()) f = failure.MissingDependencies([ (trv.getNameVersionFlavor(), deps.parseDep('trove: blam trove:foo')) ]) bt.setFailureReason(f) frz = apiutils.freeze('BuildTrove', bt) bt2 = apiutils.thaw('BuildTrove', frz) assert (bt2.getFailureReason() == bt.getFailureReason()) assert (bt2.getFlavor() == bt.getFlavor())
def testJobLogging(self): events = {} def _markEvent(apiVersion, eventList): for (event, subEvent), args in eventList: obj = args[0] events.setdefault(obj, []).append((event, args)) def checkEvent(obj, *eventList): self.assertEqual([x[0] for x in events[obj]], list(eventList)) events[obj] = [] db = self.openRmakeDatabase() trv = self.addComponent('foo:source', '1.0', '') job = buildjob.NewBuildJob(db, [trv.getNameVersionFlavor()]) bt = buildtrove.BuildTrove(job.jobId, *trv.getNameVersionFlavor()) publisher = job.getPublisher() publisher.subscribeAll(_markEvent, dispatcher=True) job.setBuildTroves([bt]) checkEvent(job, publisher.JOB_TROVES_SET) built = self.addComponent('foo:run', '1.0', 'flavor') repos = self.openRepository() cs = repos.createChangeSet([('foo:run', (None, None), (built.getVersion(), built.getFlavor()), True)]) bt.troveBuilding() checkEvent(bt, publisher.TROVE_STATE_UPDATED, publisher.TROVE_BUILDING) bt.log('some other state change') checkEvent(bt, publisher.TROVE_LOG_UPDATED) bt.troveBuilt( [x.getNewNameVersionFlavor() for x in cs.iterNewTroveList()]) checkEvent(bt, publisher.TROVE_STATE_UPDATED, publisher.TROVE_BUILT) bt.troveFailed(failure.BuildFailed('failureReason', 'foo')) checkEvent(bt, publisher.TROVE_STATE_UPDATED, publisher.TROVE_FAILED) job.jobFailed('foo') checkEvent(job, publisher.JOB_STATE_UPDATED, publisher.JOB_FAILED) job.jobLoading('foo') checkEvent(job, publisher.JOB_STATE_UPDATED) job.jobLoaded({}) checkEvent(job, publisher.JOB_STATE_UPDATED, publisher.JOB_LOADED) job.jobPassed('foo') checkEvent(job, publisher.JOB_STATE_UPDATED) checkEvent(bt) job.jobCommitting() checkEvent(job, publisher.JOB_STATE_UPDATED) job.jobCommitted([trv]) checkEvent(job, publisher.JOB_STATE_UPDATED, publisher.JOB_COMMITTED)
def addTrove(self, name, version, flavor, context='', buildTrove=None): if buildTrove: assert (buildTrove.getContext() == context) else: buildTrove = buildtrove.BuildTrove(None, name, version, flavor, context=context) buildTrove.setPublisher(self.getPublisher()) self.troves[name, version, flavor, context] = buildTrove self.troveContexts.setdefault((name, version, flavor), []).append(context) if buildTrove.getConfig(): self.setTroveConfig(buildTrove, buildTrove.getConfig())
def testLoadCommand(self): job = buildjob.BuildJob(1) trv1 = buildtrove.BuildTrove(1, *self.getNVF('foo:source')) trv2 = buildtrove.BuildTrove(1, *self.getNVF('bar:source')) job.addBuildTrove(trv1) job.addBuildTrove(trv2) result1 = buildtrove.LoadTroveResult() result1.packages = set(['foo', 'baz']) result2 = buildtrove.LoadTroveResult() result2.buildRequirements = set(['initscripts:runtime']) troves = [trv1, trv2] tups = [x.getNameVersionFlavor(True) for x in troves] results = [result1, result2] resultSet = dict(zip(tups, results)) def getSourceTrovesFromJob(job_, troves_, repos, reposName): self.assertEqual(job_, job) self.assertEqual(troves_, troves) self.assertEqual(reposName, self.rmakeCfg.reposName) return resultSet self.mock(recipeutil, 'getSourceTrovesFromJob', getSourceTrovesFromJob) mock.mock(conaryclient, 'ConaryClient') # call cmd = command.LoadCommand(self.rmakeCfg, 'cmd', job.jobId, None, job, tups, self.rmakeCfg.reposName) cmd.publisher = mock.MockObject() cmd.runAttachedCommand() cmd.publisher.attach._mock.assertCalled(trv1) cmd.publisher.attach._mock.assertCalled(trv2) self.assertEqual(trv1.packages, set(['foo', 'baz'])) self.assertEqual(trv2.buildRequirements, set(['initscripts:runtime']))
def buildTroves(self, troveList, cfg): """ Request to build the given sources and build environment. jobId of created job @param job: buildJob containing the troves to build and their configuration @type job: buildJob @rtype: int @return: jobId of created job. @raise: rMakeError: If server cannot add job. """ job = buildjob.BuildJob() troveList = [buildtrove.BuildTrove(None, *x) for x in troveList] for trove in troveList: job.addTrove(buildTrove=trove, *trove.getNameVersionFlavor()) job.setMainConfig(cfg) return self.buildJob(job)
def testChrootServer(self): raise testsuite.SkipTestException("Test is unreliable") repos = self.openRepository() targetLabel = versions.Label('localhost@rpl:branch') cfg = buildcfg.BuildConfiguration(False, conaryConfig=self.cfg, root=self.cfg.root, serverConfig=self.rmakeCfg, strictMode=False) cfg.defaultBuildReqs = [] cfg.targetLabel = targetLabel trv = self.makeSourceTrove('test1', test1Recipe) troveTup = repos.findTrove(self.cfg.buildLabel, ('test1:source', None, None), None)[0] cookFlavor = deps.parseFlavor('readline,ssl,X') troveTup = (troveTup[0], troveTup[1], cookFlavor) db = self.openRmakeDatabase() job = self.newJob(troveTup) buildTrove = buildtrove.BuildTrove(job.jobId, *troveTup) buildTrove.setPublisher(job.getPublisher()) cfg.root = self.cfg.root client = rootserver.ChrootClient( '/', ShimAddress(rootserver.ChrootServer(None, cfg, quiet=True))) logPath = self.discardOutput(client.buildTrove, cfg, cfg.getTargetLabel(troveTup[1]), *troveTup) result = client.checkResults(wait=10, *troveTup) assert (result.isBuildSuccess()) repos.commitChangeSetFile(result.getChangeSetFile()) troveTup = repos.findTrove( targetLabel, ('test1', None, deps.parseFlavor('readline,ssl')), None)[0] assert (troveTup[1].branch().label() == targetLabel) assert (str(troveTup[2]) == 'readline,ssl')
def testPerlReqsScriptCopy(self): self.openRmakeRepository() repos = self.openRepository() trvname = "perl-dummy" perl = self.addComponent('perl:lib', provides='perl: CGI perl: strict') trv = self.makeSourceTrove(trvname, testPerlRecipe) troveTup = repos.findTrove(self.cfg.buildLabel, (trvname + ':source', None, None), None)[0] cookFlavor = deps.parseFlavor('readline,ssl,X') troveTup = (troveTup[0], troveTup[1], cookFlavor) db = self.openRmakeDatabase() job = self.newJob(troveTup) buildTrove = buildtrove.BuildTrove(job.jobId, *troveTup) buildTrove.setPublisher(job.getPublisher()) logFile = logfile.LogFile(self.workDir + '/chrootlog') logFile.redirectOutput() mgr, factory, cfg, _ = self._createRoot([perl], buildTrove, start=False) logFile.restoreOutput() # Is the scripts directory copied? conaryDir = os.path.dirname(sys.modules['conary'].__file__) scriptsDir = os.path.realpath(os.path.join(conaryDir, '../scripts')) if not os.path.exists(scriptsDir): raise testsuite.SkipTestException( 'Cant test copy in conary when scripts dir doesnt exist') rootfact = factory.chroot self.failUnless(scriptsDir in [x[0] for x in rootfact.dirsToCopy]) perlreqs = os.path.join(scriptsDir, 'perlreqs.pl') self.failUnless(perlreqs in [x[0] for x in rootfact.filesToCopy])
def testFindTroves(self): db = self.openRmakeDatabase() trv = self.addComponent('foo:source', '1.0', '') binTrove = self.addComponent('foo:run', '1.0', 'ssl,!readline') job = buildjob.NewBuildJob(db, [trv.getNameVersionFlavor()]) job.addTrove('foo:source', trv.getVersion(), deps.parseFlavor('ssl')) results = job.findTrove(None, ('foo:source', None, deps.parseFlavor('ssl'))) assert (len(results) == 1) buildTrove = buildtrove.BuildTrove(job.jobId, *trv.getNameVersionFlavor()) job.setBuildTroves([buildTrove]) buildTrove = job.troves.values()[0] buildTrove.setBinaryTroves([binTrove.getNameVersionFlavor()]) results = job.findTrove( None, ('foo:run', None, deps.parseFlavor('!readline'))) assert (len(results) == 1) assert (results[0][2] == deps.parseFlavor('ssl,!readline'))
def testDisplay(self): bt = buildtrove.BuildTrove(1, *self.makeTroveTuple('foo:source')) assert(str(bt) == "<BuildTrove('foo:source=localhost@rpl:linux[]')>")
def testIsSpecial(self): bt = buildtrove.BuildTrove(1, *self.makeTroveTuple('foo:source')) assert(not bt.isSpecial()) bt = imagetrove.ImageTrove(1, *self.makeTroveTuple('foo')) assert(bt.isSpecial())
def testChrootFactory2(self): self.openRmakeRepository() repos = self.openRepository() self.addComponent('test1:source', '1.0', '', [('test1.recipe', test1Recipe)]) self.addComponent( 'test1:source', '2.0', '', [('test1.recipe', test1Recipe.replace('1.0', '2.0'))]) rootDir = self.rmakeCfg.getChrootDir() + '/testBuildReqs' self.makeSourceTrove('testBuildReqs', testBuildReqsRecipe % dict(rootDir=rootDir)) troveTup = repos.findTrove(self.cfg.buildLabel, ('testBuildReqs:source', None, None), None)[0] cookFlavor = deps.parseFlavor('readline,ssl,X') troveTup = (troveTup[0], troveTup[1], cookFlavor) db = self.openRmakeDatabase() job = self.newJob(troveTup) buildTrove = buildtrove.BuildTrove(job.jobId, *troveTup) buildTrove.setPublisher(job.getPublisher()) cfg = buildcfg.BuildConfiguration(False, conaryConfig=self.cfg, root=self.cfg.root, serverConfig=self.rmakeCfg) cfg.defaultBuildReqs = [] trv1 = self.addComponent( 'test1:runtime', '1.0', '', [('/usr/bin/test1', rephelp.RegularFile(contents='#!/bin/sh', perms=0755))]) trv2 = self.addCollection('test1', '1.0', [':runtime']) trv3 = self.addComponent( 'test2:runtime', '1.0', '', [('/usr/bin/test2', rephelp.RegularFile(contents='#!/bin/sh', perms=0755))]) trv4 = self.addComponent('testunreadable:runtime', '1.0', '', [ ('/usr/untraverseable', rephelp.Directory(perms=0700)), ('/usr/symlink', rephelp.Symlink(target='/usr/untraverseable')), ('/usr/untraverseable/unreadable', rephelp.RegularFile(perms=0600)) ]) self.rmakeCfg.chrootUser = '******' mgr = rootmanager.ChrootManager(self.rmakeCfg) jobList = [ (x[0], (None, None), (x[1], x[2]), False) for x in (trv1.getNameVersionFlavor(), trv2.getNameVersionFlavor(), trv3.getNameVersionFlavor(), trv4.getNameVersionFlavor()) ] logFile = logfile.LogFile(self.workDir + '/chrootlog') logFile.redirectOutput() factory = mgr.getRootFactory(cfg, jobList, [], [], buildTrove) factory.create() chrootClient = factory.start() try: logPath = chrootClient.buildTrove(cfg, cfg.getTargetLabel(troveTup[1]), *troveTup) result = chrootClient.checkResults(wait=20, *troveTup) logFile.restoreOutput() assert (result) assert result.isBuildSuccess(), repr(result.getFailureReason()) untraverseable = mgr.baseDir + '/testBuildReqs/usr/untraverseable' self.assertEquals(stat.S_IMODE(os.stat(untraverseable).st_mode), 0705) unreadable = untraverseable + '/unreadable' self.assertEquals(stat.S_IMODE(os.stat(unreadable).st_mode), 0604) cs = changeset.ChangeSetFromFile(result.getChangeSetFile()) trvCs = [ x for x in cs.iterNewTroveList() if x.getName() == 'testBuildReqs:runtime' ][0] trv = trove.Trove(trvCs) files = [x[1] for x in trv.iterFileList()] # make sure the loadInstalled picked the recipe that # matches the installed package. assert ('/foo/1.0' in files) finally: chrootClient.stop()
def getBuildJob(buildConfig, conaryclient, troveSpecList, message=None, recurseGroups=BUILD_RECURSE_GROUPS_NONE, configDict=None, oldTroveDict=None, updateSpecs=None, rebuild=False): trovesByContext = {} for troveSpec in list(troveSpecList): if not isinstance(troveSpec, tuple): troveSpec = cmdutil.parseTroveSpec(troveSpec) if len(troveSpec) == 3: context = '' else: context = troveSpec[3] troveSpec = troveSpec[:3] if troveSpec[2] is None: troveSpec = (troveSpec[0], troveSpec[1], deps.parseFlavor('')) trovesByContext.setdefault(context, []).append(troveSpec) job = buildjob.BuildJob() # don't store all the contexts with this job - they're useless past the # initialization step. if configDict: mainConfig = configDict[''] job.setMainConfig(configDict['']) else: cfg = copy.deepcopy(buildConfig) cfg.dropContexts() mainConfig = cfg mainConfig.recurseGroups = int(recurseGroups) job.setMainConfig(mainConfig) baseMatchRules = mainConfig.matchTroveRule for contextStr, troveSpecList in trovesByContext.iteritems(): contextBaseMatchRules = baseMatchRules if configDict and contextStr in configDict: cfg = configDict[contextStr] elif contextStr: # making this a copy is critical cfg = copy.deepcopy(buildConfig) for context in contextStr.split(','): cfg.setContext(context) cfg.dropContexts() else: # don't bother with baseMatchRules in the base config. contextBaseMatchRules = [] cfg = copy.deepcopy(buildConfig) cfg.dropContexts() contextStr = '' job.setMainConfig(cfg) cfg.initializeFlavors() use.setBuildFlagsFromFlavor(None, cfg.buildFlavor, error=False) if not cfg.buildLabel and cfg.installLabelPath: cfg.buildLabel = cfg.installLabelPath[0] troveSpecList = list(set(troveSpecList)) troveList = getTrovesToBuild(cfg, conaryclient, troveSpecList, message=None, recurseGroups=recurseGroups, matchSpecs=contextBaseMatchRules + cfg.matchTroveRule, reposName=mainConfig.reposName, updateSpecs=updateSpecs) if updateSpecs and oldTroveDict and contextStr in oldTroveDict: troveList = _matchUpdateRestrictions(mainConfig.reposName, oldTroveDict[contextStr], troveList, updateSpecs) if rebuild: prebuiltBinaries = _findLatestBinariesForTroves(conaryclient, mainConfig.reposName, troveList) if not job.getMainConfig().prebuiltBinaries: job.getMainConfig().prebuiltBinaries = prebuiltBinaries else: job.getMainConfig().prebuiltBinaries.extend(prebuiltBinaries) if mainConfig.prepOnly: buildType = buildtrove.TROVE_BUILD_TYPE_PREP else: buildType = buildtrove.TROVE_BUILD_TYPE_NORMAL for name, version, flavor in troveList: if flavor is None: flavor = deps.parseFlavor('') bt = buildtrove.BuildTrove(None, name, version, flavor, context=contextStr, buildType=buildType) job.addTrove(name, version, flavor, contextStr, bt) job.setTroveConfig(bt, cfg) return job