def startBuild(self, build_status, workerforbuilder): """This method sets up the build, then starts it by invoking the first Step. It returns a Deferred which will fire when the build finishes. This Deferred is guaranteed to never errback.""" self.workerforbuilder = workerforbuilder self.conn = None worker = workerforbuilder.worker log.msg("{}.startBuild".format(self)) self.build_status = build_status # TODO: this will go away when build collapsing is implemented; until # then we just assign the build to the first buildrequest brid = self.requests[0].id builderid = yield self.getBuilderId() self.buildid, self.number = \ yield self.master.data.updates.addBuild( builderid=builderid, buildrequestid=brid, workerid=worker.workerid) self.stopBuildConsumer = yield self.master.mq.startConsuming(self.controlStopBuild, ("control", "builds", str(self.buildid), "stop")) # the preparation step counts the time needed for preparing the worker and getting the # locks. # we cannot use a real step as we don't have a worker yet. self.preparation_step = buildstep.BuildStep(name="worker_preparation") self.preparation_step.setBuild(self) yield self.preparation_step.addStep() self.setupOwnProperties() # then narrow WorkerLocks down to the right worker self.locks = [(l.getLockForWorker(workerforbuilder.worker.workername), a) for l, a in self.locks] metrics.MetricCountEvent.log('active_builds', 1) # make sure properties are available to people listening on 'new' # events yield self._flushProperties(None) self.build_status.buildStarted(self) yield self.master.data.updates.setBuildStateString(self.buildid, 'starting') yield self.master.data.updates.generateNewBuildEvent(self.buildid) try: self.setupBuild() # create .steps except Exception: yield self.buildPreparationFailure(Failure(), "setupBuild") self.buildFinished(['Build.setupBuild', 'failed'], EXCEPTION) return # flush properties in the beginning of the build yield self._flushProperties(None) yield self.master.data.updates.setBuildStateString(self.buildid, 'preparing worker') try: ready_or_failure = yield workerforbuilder.prepare(self) except Exception: ready_or_failure = Failure() # If prepare returns True then it is ready and we start a build # If it returns failure then we don't start a new build. if ready_or_failure is not True: yield self.buildPreparationFailure(ready_or_failure, "worker_prepare") if self.stopped: self.buildFinished(["worker", "cancelled"], self.results) elif isinstance(ready_or_failure, Failure) and \ ready_or_failure.check(interfaces.LatentWorkerCannotSubstantiate): self.buildFinished(["worker", "cannot", "substantiate"], EXCEPTION) else: self.buildFinished(["worker", "not", "available"], RETRY) return # ping the worker to make sure they're still there. If they've # fallen off the map (due to a NAT timeout or something), this # will fail in a couple of minutes, depending upon the TCP # timeout. # # TODO: This can unnecessarily suspend the starting of a build, in # situations where the worker is live but is pushing lots of data to # us in a build. yield self.master.data.updates.setBuildStateString(self.buildid, 'pinging worker') log.msg("starting build {}.. pinging the worker {}".format(self, workerforbuilder)) try: ping_success_or_failure = yield workerforbuilder.ping() except Exception: ping_success_or_failure = Failure() if ping_success_or_failure is not True: yield self.buildPreparationFailure(ping_success_or_failure, "worker_ping") self.buildFinished(["worker", "not", "pinged"], RETRY) return self.conn = workerforbuilder.worker.conn # To retrieve the builddir property, the worker must be attached as we # depend on its path_module. Latent workers become attached only after # preparing them, so we can't setup the builddir property earlier like # the rest of properties self.setupWorkerBuildirProperty(workerforbuilder) self.setupWorkerForBuilder(workerforbuilder) self.subs = self.conn.notifyOnDisconnect(self.lostRemote) # tell the remote that it's starting a build, too try: yield self.conn.remoteStartBuild(self.builder.name) except Exception: yield self.buildPreparationFailure(Failure(), "start_build") self.buildFinished(["worker", "not", "building"], RETRY) return yield self.master.data.updates.setBuildStateString(self.buildid, 'acquiring locks') yield self.acquireLocks() yield self.master.data.updates.setStepStateString(self.preparation_step.stepid, "worker ready") yield self.master.data.updates.finishStep(self.preparation_step.stepid, SUCCESS, False) yield self.master.data.updates.setBuildStateString(self.buildid, 'building') # start the sequence of steps self.startNextStep()
def setUp(self): self.setupStep(buildstep.BuildStep())
def setUp(self): self.step = buildstep.BuildStep()
def test_getResultSummary_descriptionSuffix_list(self): st = buildstep.BuildStep() st.results = SUCCESS st.description = ['foo', 'ing'] st.descriptionSuffix = ['bar', 'bar2'] self.checkSummary(st.getResultSummary(), u'foo ing bar bar2')
def test_getResultSummary_descriptionSuffix_failure(self): st = buildstep.BuildStep() st.results = FAILURE st.description = 'fooing' self.checkSummary(st.getResultSummary(), u'fooing (failure)')
def test_getResultSummary_descriptionDone(self): st = buildstep.BuildStep() st.results = SUCCESS st.description = 'fooing' st.descriptionDone = 'fooed' self.checkSummary(st.getResultSummary(), u'fooed')
def test_getResultSummary_descriptionDone_and_Suffix(self): st = buildstep.BuildStep() st.results = SUCCESS st.descriptionDone = 'fooed' st.descriptionSuffix = 'bar' self.checkSummary(st.getResultSummary(), u'fooed bar')
def test_getCurrentSummary_description_list(self): st = buildstep.BuildStep() st.description = ['foo', 'ing'] self.checkSummary(st.getCurrentSummary(), u'foo ing')
def test_getResultSummary(self): st = buildstep.BuildStep() st.results = SUCCESS st.description = None self.checkSummary(st.getResultSummary(), u'finished')
def test_getCurrentSummary_descriptionSuffix(self): st = buildstep.BuildStep() st.description = 'fooing' st.descriptionSuffix = 'bar' self.checkSummary(st.getCurrentSummary(), u'fooing bar')
def test_getCurrentSummary(self): st = buildstep.BuildStep() st.description = None self.checkSummary(st.getCurrentSummary(), u'running')
def test_getStatistics(self): step = buildstep.BuildStep() step.setStatistic('rbi', 13) step.setStatistic('ba', 0.298) self.assertEqual(step.getStatistics(), {'rbi': 13, 'ba': 0.298})
def test_getStatistic(self): step = buildstep.BuildStep() self.assertEqual(step.getStatistic('rbi', 99), 99) self.assertEqual(step.getStatistic('rbi'), None) step.setStatistic('rbi', 13) self.assertEqual(step.getStatistic('rbi'), 13)
def test_hasStatistic(self): step = buildstep.BuildStep() self.assertFalse(step.hasStatistic('rbi')) step.setStatistic('rbi', 13) self.assertTrue(step.hasStatistic('rbi'))