예제 #1
0
    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()
예제 #2
0
 def setUp(self):
     self.setupStep(buildstep.BuildStep())
예제 #3
0
 def setUp(self):
     self.step = buildstep.BuildStep()
예제 #4
0
 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')
예제 #5
0
 def test_getResultSummary_descriptionSuffix_failure(self):
     st = buildstep.BuildStep()
     st.results = FAILURE
     st.description = 'fooing'
     self.checkSummary(st.getResultSummary(), u'fooing (failure)')
예제 #6
0
 def test_getResultSummary_descriptionDone(self):
     st = buildstep.BuildStep()
     st.results = SUCCESS
     st.description = 'fooing'
     st.descriptionDone = 'fooed'
     self.checkSummary(st.getResultSummary(), u'fooed')
예제 #7
0
 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')
예제 #8
0
 def test_getCurrentSummary_description_list(self):
     st = buildstep.BuildStep()
     st.description = ['foo', 'ing']
     self.checkSummary(st.getCurrentSummary(), u'foo ing')
예제 #9
0
 def test_getResultSummary(self):
     st = buildstep.BuildStep()
     st.results = SUCCESS
     st.description = None
     self.checkSummary(st.getResultSummary(), u'finished')
예제 #10
0
 def test_getCurrentSummary_descriptionSuffix(self):
     st = buildstep.BuildStep()
     st.description = 'fooing'
     st.descriptionSuffix = 'bar'
     self.checkSummary(st.getCurrentSummary(), u'fooing bar')
예제 #11
0
 def test_getCurrentSummary(self):
     st = buildstep.BuildStep()
     st.description = None
     self.checkSummary(st.getCurrentSummary(), u'running')
예제 #12
0
 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})
예제 #13
0
 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)
예제 #14
0
 def test_hasStatistic(self):
     step = buildstep.BuildStep()
     self.assertFalse(step.hasStatistic('rbi'))
     step.setStatistic('rbi', 13)
     self.assertTrue(step.hasStatistic('rbi'))