def test_blamelist_for_patch(self):
     r = FakeRequest()
     r.sources.extend([self.patchSource])
     build = Build([r])
     blamelist = build.blamelist()
     # If no patch is set, author will not be est
     self.assertEqual(blamelist, [])
Exemple #2
0
 def setupPropsIfNeeded(props):
     if props is not None:
         return
     props = Properties()
     Build.setupPropertiesKnownBeforeBuildStarts(props, [buildrequest],
                                                 self, workerforbuilder)
     return props
    def testStopBuildWaitingForLocks(self):
        r = FakeRequest()

        b = Build([r])
        b.setBuilder(Mock())
        b.builder.botmaster = FakeMaster()
        slavebuilder = Mock()
        status = Mock()

        l = SlaveLock('lock')
        lock_access = l.access('counting')
        l.access = lambda mode: lock_access
        real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)
        b.setLocks([l])

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        step.alwaysRun = False
        b.setStepFactories([(step, {})])

        real_lock.claim(Mock(), l.access('counting'))

        def acquireLocks(res=None):
            retval = Build.acquireLocks(b, res)
            b.stopBuild('stop it')
            return retval
        b.acquireLocks = acquireLocks

        b.startBuild(status, None, slavebuilder)

        self.assert_( ('startStep', (b.remote,), {}) not in step.method_calls)
        self.assert_(b.currentStep is None)
        self.assertEqual(b.result, EXCEPTION)
        self.assert_( ('interrupt', ('stop it',), {}) not in step.method_calls)
Exemple #4
0
    def canStartBuild(self, workerforbuilder, buildrequest):
        can_start = True

        # check whether the locks that the build will acquire can actually be
        # acquired
        locks = self.config.locks
        if IRenderable.providedBy(locks):
            # collect properties that would be set for a build if we
            # started it now and render locks using it
            props = Properties()
            Build.setupPropertiesKnownBeforeBuildStarts(props, [buildrequest],
                                                        self, workerforbuilder)
            locks = yield props.render(locks)

        locks = [(self.botmaster.getLockFromLockAccess(access), access)
                 for access in locks]
        if locks:
            can_start = Build._canAcquireLocks(locks, workerforbuilder)
        if can_start is False:
            defer.returnValue(can_start)

        if callable(self.config.canStartBuild):
            can_start = yield self.config.canStartBuild(self, workerforbuilder,
                                                        buildrequest)
        defer.returnValue(can_start)
Exemple #5
0
    def canStartWithWorkerForBuilder(self, workerforbuilder, buildrequests=None):
        locks = self.config.locks
        if IRenderable.providedBy(locks):
            if buildrequests is None:
                raise RuntimeError("buildrequests parameter must be specified "
                                   " when using renderable builder locks. Not "
                                   "specifying buildrequests is deprecated")

            # collect properties that would be set for a build if we
            # started it now and render locks using it
            props = Properties()
            Build.setupPropertiesKnownBeforeBuildStarts(props, buildrequests,
                                                        self, workerforbuilder)
            locks = yield props.render(locks)

        # Make sure we don't warn and throw an exception at the same time
        if buildrequests is None:
            warnings.warn(
                "Not passing corresponding buildrequests to "
                "Builder.canStartWithWorkerForBuilder is deprecated")

        locks = [(self.botmaster.getLockFromLockAccess(access), access)
                 for access in locks]
        can_start = Build.canStartWithWorkerForBuilder(locks, workerforbuilder)
        defer.returnValue(can_start)
    def testBuildLocksAcquired(self):
        r = FakeRequest()

        b = Build([r])
        b.setBuilder(Mock())
        b.builder.botmaster = FakeMaster()
        slavebuilder = Mock()
        status = Mock()

        l = SlaveLock("lock")
        claimCount = [0]
        lock_access = l.access("counting")
        l.access = lambda mode: lock_access
        real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)

        def claim(owner, access):
            claimCount[0] += 1
            return real_lock.old_claim(owner, access)

        real_lock.old_claim = real_lock.claim
        real_lock.claim = claim
        b.setLocks([l])

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        b.setStepFactories([(step, {})])

        b.startBuild(status, None, slavebuilder)

        self.assertEqual(b.result, SUCCESS)
        self.assert_(("startStep", (b.remote,), {}) in step.method_calls)
        self.assertEquals(claimCount[0], 1)
    def testBuildWaitingForLocks(self):
        r = FakeRequest()

        b = Build([r])
        b.setBuilder(Mock())
        b.builder.botmaster = FakeMaster()
        slavebuilder = Mock()
        status = Mock()

        l = SlaveLock('lock')
        claimCount = [0]
        lock_access = l.access('counting')
        l.access = lambda mode: lock_access
        real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)
        def claim(owner, access):
            claimCount[0] += 1
            return real_lock.old_claim(owner, access)
        real_lock.old_claim = real_lock.claim
        real_lock.claim = claim
        b.setLocks([l])

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        b.setStepFactories([(step, {})])

        real_lock.claim(Mock(), l.access('counting'))

        b.startBuild(status, None, slavebuilder)

        self.assert_( ('startStep', (b.remote,), {}) not in step.method_calls)
        self.assertEquals(claimCount[0], 1)
        self.assert_(b.currentStep is None)
        self.assert_(b._acquiringLock is not None)
Exemple #8
0
    def _startBuildFor(self, workerforbuilder, buildrequests):
        build = self.config.factory.newBuild(buildrequests)
        build.setBuilder(self)

        props = build.getProperties()

        # give the properties a reference back to this build
        props.build = build

        Build.setupPropertiesKnownBeforeBuildStarts(
            props, build.requests, build.builder, workerforbuilder)

        log.msg("starting build %s using worker %s" %
                (build, workerforbuilder))

        # set up locks
        locks = yield build.render(self.config.locks)
        yield build.setLocks(locks)

        if self.config.env:
            build.setWorkerEnvironment(self.config.env)

        # append the build to self.building
        self.building.append(build)

        # The worker is ready to go. workerforbuilder.buildStarted() sets its
        # state to BUILDING (so we won't try to use it for any other builds).
        # This gets set back to IDLE by the Build itself when it finishes.
        # Note: This can't be done in `Build.startBuild`, since it needs to be done
        # synchronously, before the BuildRequestDistributor looks at
        # another build request.
        workerforbuilder.buildStarted()

        # create the BuildStatus object that goes with the Build
        bs = self.builder_status.newBuild()

        # let status know
        self.master.status.build_started(buildrequests[0].id, self.name, bs)

        # start the build. This will first set up the steps, then tell the
        # BuildStatus that it has started, which will announce it to the world
        # (through our BuilderStatus object, which is its parent).  Finally it
        # will start the actual build process.  This is done with a fresh
        # Deferred since _startBuildFor should not wait until the build is
        # finished.  This uses `maybeDeferred` to ensure that any exceptions
        # raised by startBuild are treated as deferred errbacks (see
        # http://trac.buildbot.net/ticket/2428).
        d = defer.maybeDeferred(build.startBuild,
                                bs, workerforbuilder)
        # this shouldn't happen. if it does, the worker will be wedged
        d.addErrback(log.err, 'from a running build; this is a '
                     'serious error - please file a bug at http://buildbot.net')

        defer.returnValue(True)
    def test_getWorkerName_old_api(self):
        class FakeProperties(Mock):
            implements(interfaces.IProperties)

        import posixpath

        r = FakeRequest()
        build = Build([r])
        build.properties = FakeProperties()
        build.builder = FakeBuilder(self.master)
        build.build_status = FakeBuildStatus()

        w = worker.FakeWorker(self.master)
        w.path_module = posixpath
        w.properties = FakeProperties()
        w.workername = 'worker name'
        w.worker_basedir = None

        workerforbuilder = Mock(name='workerforbuilder')
        workerforbuilder.worker = w

        build.setupWorkerForBuilder(workerforbuilder)

        with assertNotProducesWarnings(DeprecatedWorkerAPIWarning):
            new = build.getWorkerName()

        with assertProducesWarning(
                DeprecatedWorkerNameWarning,
                message_pattern="'getSlaveName' method is deprecated"):
            old = build.getSlaveName()

        self.assertEqual(old, 'worker name')
        self.assertIdentical(new, old)
    def setUp(self):
        @implementer(interfaces.IProperties)
        class FakeProperties(Mock):
            pass
        FakeProperties.render = Mock(side_effect=lambda x: x)

        class FakeBuildStatus(Mock):
            pass
        r = FakeRequest()
        r.sources = [FakeSource()]
        r.sources[0].changes = [FakeChange()]
        r.sources[0].revision = "12345"
        self.master = fakemaster.make_master(wantData=True, testcase=self)
        self.worker = worker.FakeWorker(self.master)
        self.worker.attached(None)
        self.workerforbuilder = Mock(name='workerforbuilder')
        self.workerforbuilder.worker = self.worker
        self.build = Build([r])
        self.build.setStepFactories([])
        self.builder = FakeBuilder(
            fakemaster.make_master(wantData=True, testcase=self))
        self.build.setBuilder(self.builder)
        self.properties = self.build.properties = FakeProperties()
        self.build_status = FakeBuildStatus()
        self.build._flushProperties = Mock()
        self.build.startBuild(self.build_status, self.workerforbuilder)
 def setUp(self):
     r = FakeRequest()
     self.build = Build([r])
     self.build.setStepFactories([])
     self.builder = Mock()
     self.build.setBuilder(self.builder)
     self.build_status = FakeBuildStatus()
     self.build.startBuild(self.build_status, None, Mock())
 def testStepDoneRetryOverridesAnythingElse(self):
     r = FakeRequest()
     b = Build([r])
     b.results = [RETRY]
     b.result = RETRY
     b.remote = Mock()
     step = FakeBuildStep()
     step.alwaysRun = True
     b.stepDone(WARNINGS, step)
     b.stepDone(FAILURE, step)
     b.stepDone(SUCCESS, step)
     terminate = b.stepDone(EXCEPTION, step)
     self.assertEqual(terminate, True)
     self.assertEqual(b.result, RETRY)
    def testStopBuild(self):
        r = FakeRequest()

        b = Build([r])
        b.setBuilder(Mock())

        step = Mock()
        step.return_value = step
        b.setStepFactories([(step, {})])

        slavebuilder = Mock()
        status = Mock()

        def startStep(*args, **kw):
            # Now interrupt the build
            b.stopBuild("stop it")
            return defer.Deferred()

        step.startStep = startStep

        b.startBuild(status, None, slavebuilder)

        self.assertEqual(b.result, EXCEPTION)

        self.assert_(("interrupt", ("stop it",), {}) in step.method_calls)
class TestMultipleSourceStamps(unittest.TestCase):

    def setUp(self):
        r = FakeRequest()
        s1 = FakeSource()
        s1.repository = "repoA"
        s1.codebase = "A"
        s1.changes = [FakeChange(10), FakeChange(11)]
        s1.revision = "12345"
        s2 = FakeSource()
        s2.repository = "repoB"
        s2.codebase = "B"
        s2.changes = [FakeChange(12), FakeChange(13)]
        s2.revision = "67890"
        s3 = FakeSource()
        s3.repository = "repoC"
        # no codebase defined
        s3.changes = [FakeChange(14), FakeChange(15)]
        s3.revision = "111213"
        r.sources.extend([s1, s2, s3])

        self.build = Build([r])

    def test_buildReturnSourceStamp(self):
        """
        Test that a build returns the correct sourcestamp
        """
        source1 = self.build.getSourceStamp("A")
        source2 = self.build.getSourceStamp("B")

        self.assertEqual(
            [source1.repository, source1.revision], ["repoA", "12345"])
        self.assertEqual(
            [source2.repository, source2.revision], ["repoB", "67890"])

    def test_buildReturnSourceStamp_empty_codebase(self):
        """
        Test that a build returns the correct sourcestamp if codebase is empty
        """
        codebase = ''
        source3 = self.build.getSourceStamp(codebase)
        self.assertTrue(source3 is not None)
        self.assertEqual(
            [source3.repository, source3.revision], ["repoC", "111213"])
    def testBuildLocksOrder(self):
        """Test that locks are acquired in FIFO order; specifically that
        counting locks cannot jump ahead of exclusive locks"""
        eBuild = self.build

        cBuilder = FakeBuilder(self.master)
        cBuild = Build([self.request])
        cBuild.setBuilder(cBuilder)

        eWorker = Mock()
        cWorker = Mock()

        eWorker.worker = self.worker
        cWorker.worker = self.worker
        eWorker.prepare = cWorker.prepare = lambda _: True
        eWorker.ping = cWorker.ping = lambda: True

        l = WorkerLock("lock", 2)
        claimLog = []
        realLock = self.master.botmaster.getLockByID(l).getLock(self.worker)

        def claim(owner, access):
            claimLog.append(owner)
            return realLock.oldClaim(owner, access)

        realLock.oldClaim = realLock.claim
        realLock.claim = claim

        eBuild.setLocks([l.access("exclusive")])
        cBuild.setLocks([l.access("counting")])

        fakeBuild = Mock()
        fakeBuildAccess = l.access("counting")
        realLock.claim(fakeBuild, fakeBuildAccess)

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        eBuild.setStepFactories([FakeStepFactory(step)])
        cBuild.setStepFactories([FakeStepFactory(step)])

        e = eBuild.startBuild(FakeBuildStatus(), eWorker)
        c = cBuild.startBuild(FakeBuildStatus(), cWorker)
        d = defer.DeferredList([e, c])

        realLock.release(fakeBuild, fakeBuildAccess)

        def check(ign):
            self.assertEqual(eBuild.results, SUCCESS)
            self.assertEqual(cBuild.results, SUCCESS)
            self.assertEqual(claimLog, [fakeBuild, eBuild, cBuild])

        d.addCallback(check)
        return d
 def setUp(self):
     r = FakeRequest()
     r.sources = [FakeSource()]
     r.sources[0].changes = [FakeChange()]
     r.sources[0].revision = "12345"
     
     self.build = Build([r])
     self.builder = Mock()
     self.builder.botmaster = FakeMaster()
     self.build.setBuilder(self.builder)
 def setUp(self):
     r = FakeRequest()
     r.sources = [FakeSource()]
     r.sources[0].changes = [FakeChange()]
     r.sources[0].revision = "12345"
     self.build = Build([r])
     self.build.setStepFactories([])
     self.builder = Mock()
     self.build.setBuilder(self.builder)
     self.build_status = FakeBuildStatus()
     self.build.startBuild(self.build_status, None, Mock())
    def testBuildLocksOrder(self):
        """Test that locks are acquired in FIFO order; specifically that
        counting locks cannot jump ahead of exclusive locks"""
        eBuild = self.build

        cBuilder = self.createBuilder()
        cBuild = Build([self.request])
        cBuild.setBuilder(cBuilder)

        eSlavebuilder = Mock()
        cSlavebuilder = Mock()

        slave = eSlavebuilder.slave
        cSlavebuilder.slave = slave

        l = SlaveLock('lock', 2)
        claimLog = []
        realLock = self.master.botmaster.getLockByID(l).getLock(slave)

        def claim(owner, access):
            claimLog.append(owner)
            return realLock.oldClaim(owner, access)
        realLock.oldClaim = realLock.claim
        realLock.claim = claim

        eBuild.setLocks([l.access('exclusive')])
        cBuild.setLocks([l.access('counting')])

        fakeBuild = Mock()
        fakeBuildAccess = l.access('counting')
        realLock.claim(fakeBuild, fakeBuildAccess)

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        eBuild.setStepFactories([FakeStepFactory(step)])
        cBuild.setStepFactories([FakeStepFactory(step)])

        e = eBuild.startBuild(FakeBuildStatus(), None, eSlavebuilder)
        c = cBuild.startBuild(FakeBuildStatus(), None, cSlavebuilder)
        d = defer.DeferredList([e, c])

        realLock.release(fakeBuild, fakeBuildAccess)

        def check(ign):
            self.assertEqual(eBuild.result, SUCCESS)
            self.assertEqual(cBuild.result, SUCCESS)
            self.assertEquals(claimLog, [fakeBuild, eBuild, cBuild])

        d.addCallback(check)
        return d
    def test_workername_old_api(self):
        @implementer(interfaces.IProperties)
        class FakeProperties(Mock):
            pass

        import posixpath

        r = FakeRequest()
        build = Build([r])
        build.properties = FakeProperties()
        build.builder = FakeBuilder(self.master)
        build.build_status = FakeBuildStatus()

        w = worker.FakeWorker(self.master)
        w.path_module = posixpath
        w.properties = FakeProperties()
        w.workername = "worker name"
        w.worker_basedir = None

        workerforbuilder = Mock(name="workerforbuilder")
        workerforbuilder.worker = w

        build.setupWorkerForBuilder(workerforbuilder)

        with assertNotProducesWarnings(DeprecatedWorkerAPIWarning):
            new = build.workername

        with assertProducesWarning(DeprecatedWorkerNameWarning, message_pattern="'slavename' attribute is deprecated"):
            old = build.slavename

        self.assertEqual(old, "worker name")
        self.assertIdentical(new, old)
    def setUp(self):
        r = FakeRequest()
        r.sources = [FakeSource()]
        r.sources[0].changes = [FakeChange()]
        r.sources[0].revision = "12345"

        self.request = r
        self.master = FakeMaster()

        self.master.botmaster = FakeBotMaster(master=self.master)

        self.builder = self.createBuilder()
        self.build = Build([r])
        self.build.setBuilder(self.builder)
Exemple #21
0
 def setUp(self):
     self.setUpTestReactor()
     self.props = {}
     r = FakeRequest()
     r.sources = []
     r.sources.append(FakeSource())
     r.sources[0].changes = [FakeChange()]
     r.sources[0].repository = "http://svn-repo-A"
     r.sources[0].codebase = "A"
     r.sources[0].branch = "develop"
     r.sources[0].revision = "12345"
     r.sources.append(FakeSource())
     r.sources[1].changes = [FakeChange()]
     r.sources[1].repository = "http://svn-repo-B"
     r.sources[1].codebase = "B"
     r.sources[1].revision = "34567"
     self.build = Build([r])
     self.build.setStepFactories([])
     self.builder = FakeBuilder(fakemaster.make_master(self, wantData=True))
     self.build.setBuilder(self.builder)
     self.build.build_status = FakeBuildStatus()
     # record properties that will be set
     self.build.properties.setProperty = self.setProperty
Exemple #22
0
    def setUp(self):
        r = FakeRequest()
        r.sources = [FakeSource()]
        r.sources[0].changes = [FakeChange()]
        r.sources[0].revision = "12345"

        self.request = r
        self.master = fakemaster.make_master(wantData=True, testcase=self)

        self.worker = worker.FakeWorker(self.master)
        self.worker.attached(None)
        self.builder = FakeBuilder(self.master)
        self.build = Build([r])
        self.build.conn = fakeprotocol.FakeConnection(self.master, self.worker)

        self.workerforbuilder = Mock(name='workerforbuilder')
        self.workerforbuilder.worker = self.worker
        self.workerforbuilder.prepare = lambda _: True
        self.workerforbuilder.ping = lambda: True

        self.build.setBuilder(self.builder)
        self.build.text = []
        self.build.buildid = 666
Exemple #23
0
    def setUp(self):
        self.setUpTestReactor()
        r = FakeRequest()
        r.sources = [FakeSource()]
        r.sources[0].changes = [FakeChange()]
        r.sources[0].revision = "12345"

        self.request = r
        self.master = fakemaster.make_master(self, wantData=True)

        self.worker = worker.FakeWorker(self.master)
        self.worker.attached(None)
        self.builder = FakeBuilder(self.master)
        self.build = Build([r])
        self.build.conn = fakeprotocol.FakeConnection(self.worker)

        self.workerforbuilder = Mock(name='workerforbuilder')
        self.workerforbuilder.worker = self.worker
        self.workerforbuilder.substantiate_if_needed = lambda _: True
        self.workerforbuilder.ping = lambda: True

        self.build.setBuilder(self.builder)
        self.build.text = []
        self.build.buildid = 666
Exemple #24
0
    def setUp(self):
        class FakeProperties(Mock):
            implements(interfaces.IProperties)

        class FakeBuildStatus(Mock):
            pass
        r = FakeRequest()
        r.sources = [FakeSource()]
        r.sources[0].changes = [FakeChange()]
        r.sources[0].revision = "12345"
        self.master = fakemaster.make_master(wantData=True, testcase=self)
        self.slave = slave.FakeSlave(self.master)
        self.slave.attached(None)
        self.slavebuilder = Mock(name='slavebuilder')
        self.slavebuilder.slave = self.slave
        self.build = Build([r])
        self.build.setStepFactories([])
        self.builder = FakeBuilder(
            fakemaster.make_master(wantData=True, testcase=self))
        self.build.setBuilder(self.builder)
        self.properties = self.build.properties = FakeProperties()
        self.build_status = FakeBuildStatus()
        self.build._flushProperties = Mock()
        self.build.startBuild(self.build_status, None, self.slavebuilder)
 def testStepDoneFailOverridesWarnings(self):
     r = FakeRequest()
     b = Build([r])
     b.results = [SUCCESS, WARNINGS]
     b.result = WARNINGS
     b.remote = Mock()
     step = FakeBuildStep()
     terminate = b.stepDone(FAILURE, step)
     self.assertEqual(terminate, False)
     self.assertEqual(b.result, FAILURE)
 def testStepDoneWarnings(self):
     r = FakeRequest()
     b = Build([r])
     b.results = [SUCCESS]
     b.result = SUCCESS
     b.remote = Mock()
     step = FakeBuildStep()
     terminate = b.stepDone(WARNINGS, step)
     self.assertEqual(terminate, False)
     self.assertEqual(b.result, WARNINGS)
 def testStepDoneFail(self):
     r = FakeRequest()
     b = Build([r])
     b.results = [SUCCESS]
     b.result = SUCCESS
     b.remote = Mock()
     step = FakeBuildStep()
     terminate = b.stepDone(FAILURE, step)
     self.assertEqual(terminate, False)
     self.assertEqual(b.result, FAILURE)
 def testStepDoneWarningsDontOverrideFailure(self):
     r = FakeRequest()
     b = Build([r])
     b.results = [FAILURE]
     b.result = FAILURE
     b.remote = Mock()
     step = FakeBuildStep()
     terminate = b.stepDone(WARNINGS, step)
     self.assertEqual(terminate, False)
     self.assertEqual(b.result, FAILURE)
    def testRunSuccessfulBuild(self):
        r = FakeRequest()

        b = Build([r])
        b.setBuilder(Mock())

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        b.setStepFactories([(step, {})])

        slavebuilder = Mock()
        status = Mock()

        b.startBuild(status, None, slavebuilder)

        self.assertEqual(b.result, SUCCESS)
        self.assert_( ('startStep', (b.remote,), {}) in step.method_calls)
 def testStepDoneHaltOnFailure(self):
     r = FakeRequest()
     b = Build([r])
     b.results = []
     b.result = SUCCESS
     b.remote = Mock()
     step = FakeBuildStep()
     step.haltOnFailure = True
     terminate = b.stepDone(FAILURE, step)
     self.assertEqual(terminate, True)
     self.assertEqual(b.result, FAILURE)
 def setUp(self):
     self.props = {}
     r = FakeRequest()
     r.sources = []
     r.sources.append(FakeSource())
     r.sources[0].changes = [FakeChange()]
     r.sources[0].repository = "http://svn-repo-A"
     r.sources[0].codebase = "A"
     r.sources[0].branch = "develop"
     r.sources[0].revision = "12345"
     self.build = Build([r])
     self.build.setStepFactories([])
     self.builder = Mock()
     self.build.setBuilder(self.builder)
     self.build.build_status = FakeBuildStatus()
     # record properties that will be set
     self.build.build_status.setProperty = self.setProperty
 def testStepDoneHaltOnFailureFlunkOnWarnings(self):
     r = FakeRequest()
     b = Build([r])
     b.results = [SUCCESS]
     b.result = SUCCESS
     b.remote = Mock()
     step = FakeBuildStep()
     step.flunkOnWarnings = True
     self.haltOnFailure = True
     terminate = b.stepDone(WARNINGS, step)
     self.assertEqual(terminate, False)
     self.assertEqual(b.result, FAILURE)
 def testStepDoneWarnOnFailure(self):
     r = FakeRequest()
     b = Build([r])
     b.results = [SUCCESS]
     b.result = SUCCESS
     b.remote = Mock()
     step = FakeBuildStep()
     step.warnOnFailure = True
     step.flunkOnFailure = False
     terminate = b.stepDone(FAILURE, step)
     self.assertEqual(terminate, False)
     self.assertEqual(b.result, WARNINGS)
Exemple #34
0
    def canStartBuild(self, workerforbuilder, buildrequest):
        can_start = True

        # check whether the locks that the build will acquire can actually be
        # acquired
        locks = self.config.locks
        worker = workerforbuilder.worker
        props = None

        # don't unnecessarily setup properties for build
        def setupPropsIfNeeded(props):
            if props is not None:
                return props
            props = Properties()
            Build.setupPropertiesKnownBeforeBuildStarts(
                props, [buildrequest], self, workerforbuilder)
            return props

        if worker.builds_may_be_incompatible:
            # Check if the latent worker is actually compatible with the build.
            # The instance type of the worker may depend on the properties of
            # the build that substantiated it.
            props = setupPropsIfNeeded(props)
            can_start = yield worker.isCompatibleWithBuild(props)
            if not can_start:
                return False

        if IRenderable.providedBy(locks):
            # collect properties that would be set for a build if we
            # started it now and render locks using it
            props = setupPropsIfNeeded(props)
            locks = yield props.render(locks)

        locks = yield self.botmaster.getLockFromLockAccesses(
            locks, self.config_version)

        if locks:
            can_start = Build._canAcquireLocks(locks, workerforbuilder)
            if can_start is False:
                return can_start

        if callable(self.config.canStartBuild):
            can_start = yield self.config.canStartBuild(
                self, workerforbuilder, buildrequest)
        return can_start
Exemple #35
0
    def canStartBuild(self, workerforbuilder, buildrequest):
        can_start = True

        # check whether the locks that the build will acquire can actually be
        # acquired
        locks = self.config.locks
        worker = workerforbuilder.worker
        props = None

        # don't unnecessarily setup properties for build
        def setupPropsIfNeeded(props):
            if props is not None:
                return
            props = Properties()
            Build.setupPropertiesKnownBeforeBuildStarts(props, [buildrequest],
                                                        self, workerforbuilder)
            return props

        if worker.builds_may_be_incompatible:
            # Check if the latent worker is actually compatible with the build.
            # The instance type of the worker may depend on the properties of
            # the build that substantiated it.
            props = setupPropsIfNeeded(props)
            can_start = yield worker.isCompatibleWithBuild(props)
            if not can_start:
                return False

        if IRenderable.providedBy(locks):
            # collect properties that would be set for a build if we
            # started it now and render locks using it
            props = setupPropsIfNeeded(props)
            locks = yield props.render(locks)

        locks = [(self.botmaster.getLockFromLockAccess(access), access)
                 for access in locks]
        if locks:
            can_start = Build._canAcquireLocks(locks, workerforbuilder)
            if can_start is False:
                return can_start

        if callable(self.config.canStartBuild):
            can_start = yield self.config.canStartBuild(self, workerforbuilder,
                                                        buildrequest)
        return can_start
    def testAlwaysRunStepStopBuild(self):
        """Test that steps marked with alwaysRun=True still get run even if
        the build is stopped."""

        # Create a build with 2 steps, the first one will get interrupted, and
        # the second one is marked with alwaysRun=True
        r = FakeRequest()

        b = Build([r])
        b.setBuilder(Mock())

        step1 = Mock()
        step1.return_value = step1
        step1.alwaysRun = False
        step2 = Mock()
        step2.return_value = step2
        step2.alwaysRun = True
        b.setStepFactories([
            (step1, {}),
            (step2, {}),
            ])

        slavebuilder = Mock()
        status = Mock()

        def startStep1(*args, **kw):
            # Now interrupt the build
            b.stopBuild("stop it")
            return defer.succeed( SUCCESS )
        step1.startStep = startStep1
        step1.stepDone.return_value = False

        step2Started = [False]
        def startStep2(*args, **kw):
            step2Started[0] = True
            return defer.succeed( SUCCESS )
        step2.startStep = startStep2
        step1.stepDone.return_value = False

        d = b.startBuild(status, None, slavebuilder)
        def check(ign):
            self.assertEqual(b.result, EXCEPTION)
            self.assert_( ('interrupt', ('stop it',), {}) in step1.method_calls)
            self.assert_(step2Started[0])
        d.addCallback(check)
        return d
Exemple #37
0
    def setUp(self):
        class FakeBuildStatus(Mock):
            implements(interfaces.IProperties)

        r = FakeRequest()
        r.sources = [FakeSource()]
        r.sources[0].changes = [FakeChange()]
        r.sources[0].revision = "12345"
        self.master = fakemaster.make_master(wantData=True, testcase=self)
        self.slave = slave.FakeSlave(self.master)
        self.slave.attached(None)
        self.slavebuilder = Mock(name="slavebuilder")
        self.slavebuilder.slave = self.slave
        self.build = Build([r])
        self.build.setStepFactories([])
        self.builder = FakeBuilder(fakemaster.make_master(wantData=True, testcase=self))
        self.build.setBuilder(self.builder)
        self.build_status = FakeBuildStatus()
        self.build.startBuild(self.build_status, None, self.slavebuilder)
    def testStopBuildWaitingForStepLocks(self):
        r = FakeRequest()

        b = Build([r])
        b.setBuilder(Mock())
        b.builder.botmaster = FakeMaster()
        slavebuilder = Mock()
        status = Mock()

        l = SlaveLock('lock')
        lock_access = l.access('counting')
        l.access = lambda mode: lock_access
        real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)

        step = LoggingBuildStep(locks=[lock_access])
        def factory(*args):
            return step
        b.setStepFactories([(factory, {})])

        real_lock.claim(Mock(), l.access('counting'))

        gotLocks = [False]

        def acquireLocks(res=None):
            gotLocks[0] = True
            retval = LoggingBuildStep.acquireLocks(step, res)
            self.assert_(b.currentStep is step)
            b.stopBuild('stop it')
            return retval
        step.acquireLocks = acquireLocks
        step.setStepStatus = Mock()
        step.step_status = Mock()
        step.step_status.addLog().chunkSize = 10
        step.step_status.getLogs.return_value = []

        b.startBuild(status, None, slavebuilder)

        self.assertEqual(gotLocks, [True])
        self.assert_(('stepStarted', (), {}) in step.step_status.method_calls)
        self.assertEqual(b.result, EXCEPTION)
    def testStopBuild(self):
        r = FakeRequest()

        b = Build([r])
        b.setBuilder(Mock())

        step = Mock()
        step.return_value = step
        b.setStepFactories([(step, {})])

        slavebuilder = Mock()
        status = Mock()

        def startStep(*args, **kw):
            # Now interrupt the build
            b.stopBuild("stop it")
            return defer.Deferred()
        step.startStep = startStep

        b.startBuild(status, None, slavebuilder)

        self.assertEqual(b.result, EXCEPTION)

        self.assert_( ('interrupt', ('stop it',), {}) in step.method_calls)
Exemple #40
0
class TestSetupProperties_MultipleSources(unittest.TestCase):

    """
    Test that the property values, based on the available requests, are
    initialized properly
    """

    def setUp(self):
        self.props = {}
        r = FakeRequest()
        r.sources = []
        r.sources.append(FakeSource())
        r.sources[0].changes = [FakeChange()]
        r.sources[0].repository = "http://svn-repo-A"
        r.sources[0].codebase = "A"
        r.sources[0].branch = "develop"
        r.sources[0].revision = "12345"
        r.sources.append(FakeSource())
        r.sources[1].changes = [FakeChange()]
        r.sources[1].repository = "http://svn-repo-B"
        r.sources[1].codebase = "B"
        r.sources[1].revision = "34567"
        self.build = Build([r])
        self.build.setStepFactories([])
        self.builder = FakeBuilder(
            fakemaster.make_master(wantData=True, testcase=self))
        self.build.setBuilder(self.builder)
        self.build.build_status = FakeBuildStatus()
        # record properties that will be set
        self.build.properties.setProperty = self.setProperty

    def setProperty(self, n, v, s, runtime=False):
        if s not in self.props:
            self.props[s] = {}
        if not self.props[s]:
            self.props[s] = {}
        self.props[s][n] = v

    def test_sourcestamp_properties_not_set(self):
        self.build.setupProperties()
        self.assertTrue("codebase" not in self.props["Build"])
        self.assertTrue("revision" not in self.props["Build"])
        self.assertTrue("branch" not in self.props["Build"])
        self.assertTrue("project" not in self.props["Build"])
        self.assertTrue("repository" not in self.props["Build"])
Exemple #41
0
 def test_properties_revision(self):
     Build.setupBuildProperties(self.build.getProperties(), [self.r], self.r.sources)
     revision = self.props["Build"]["revision"]
     self.assertEqual(revision, "12345")
Exemple #42
0
 def test_properties_branch(self):
     Build.setupBuildProperties(self.build.getProperties(), [self.r], self.r.sources)
     branch = self.props["Build"]["branch"]
     self.assertEqual(branch, "develop")
Exemple #43
0
 def test_property_project(self):
     Build.setupBuildProperties(self.build.getProperties(), [self.r], self.r.sources)
     project = self.props["Build"]["project"]
     self.assertEqual(project, '')
Exemple #44
0
    def testBuildcanStartWithSlavebuilder(self):
        b = self.build

        slavebuilder1 = Mock()
        slavebuilder2 = Mock()

        l = SlaveLock('lock')
        counting_access = l.access('counting')
        real_lock = b.builder.botmaster.getLockByID(l)

        # no locks, so both these pass (call twice to verify there's no state/memory)
        lock_list = [(real_lock, counting_access)]
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))

        slave_lock_1 = real_lock.getLock(slavebuilder1.slave)
        slave_lock_2 = real_lock.getLock(slavebuilder2.slave)

        # then have slavebuilder2 claim its lock:
        slave_lock_2.claim(slavebuilder2, counting_access)
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertFalse(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
        self.assertFalse(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
        slave_lock_2.release(slavebuilder2, counting_access)

        # then have slavebuilder1 claim its lock:
        slave_lock_1.claim(slavebuilder1, counting_access)
        self.assertFalse(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertFalse(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
        slave_lock_1.release(slavebuilder1, counting_access)
Exemple #45
0
    def testBuild_canAcquireLocks(self):
        b = self.build

        workerforbuilder1 = Mock()
        workerforbuilder2 = Mock()

        lock = WorkerLock('lock')
        counting_access = lock.access('counting')

        real_lock = yield b.builder.botmaster.getLockByID(lock, 0)

        # no locks, so both these pass (call twice to verify there's no
        # state/memory)
        lock_list = [(real_lock, counting_access)]
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder2))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder2))

        worker_lock_1 = real_lock.getLockForWorker(
            workerforbuilder1.worker.workername)
        worker_lock_2 = real_lock.getLockForWorker(
            workerforbuilder2.worker.workername)

        # then have workerforbuilder2 claim its lock:
        worker_lock_2.claim(workerforbuilder2, counting_access)
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertFalse(
            Build._canAcquireLocks(lock_list, workerforbuilder2))
        self.assertFalse(
            Build._canAcquireLocks(lock_list, workerforbuilder2))
        worker_lock_2.release(workerforbuilder2, counting_access)

        # then have workerforbuilder1 claim its lock:
        worker_lock_1.claim(workerforbuilder1, counting_access)
        self.assertFalse(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertFalse(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder2))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder2))
        worker_lock_1.release(workerforbuilder1, counting_access)
Exemple #46
0
class TestBuildProperties(unittest.TestCase):
    """
    Test that a Build has the necessary L{IProperties} methods, and that they
    properly delegate to the C{build_status} attribute - so really just a test
    of the L{IProperties} adapter.
    """
    def setUp(self):
        r = FakeRequest()
        r.sources = [FakeSource()]
        r.sources[0].changes = [FakeChange()]
        r.sources[0].revision = "12345"
        self.build = Build([r])
        self.build.setStepFactories([])
        self.builder = Mock()
        self.build.setBuilder(self.builder)
        self.build_status = FakeBuildStatus()
        self.build.startBuild(self.build_status, None, Mock())

    def test_getProperty(self):
        self.build.getProperty('x')
        self.build_status.getProperty.assert_called_with('x', None)

    def test_getProperty_default(self):
        self.build.getProperty('x', 'nox')
        self.build_status.getProperty.assert_called_with('x', 'nox')

    def test_setProperty(self):
        self.build.setProperty('n', 'v', 's')
        self.build_status.setProperty.assert_called_with('n',
                                                         'v',
                                                         's',
                                                         runtime=True)

    def test_hasProperty(self):
        self.build_status.hasProperty.return_value = True
        self.assertTrue(self.build.hasProperty('p'))
        self.build_status.hasProperty.assert_called_with('p')

    def test_has_key(self):
        self.build_status.has_key.return_value = True
        # getattr because pep8 doesn't like calls to has_key
        self.assertTrue(getattr(self.build, 'has_key')('p'))
        # has_key calls through to hasProperty
        self.build_status.hasProperty.assert_called_with('p')

    def test_render(self):
        self.build.render("xyz")
        self.build_status.render.assert_called_with("xyz")
Exemple #47
0
class TestSetupProperties_SingleSource(unittest.TestCase):
    """
    Test that the property values, based on the available requests, are
    initialized properly
    """
    def setUp(self):
        self.props = {}
        r = FakeRequest()
        r.sources = []
        r.sources.append(FakeSource())
        r.sources[0].changes = [FakeChange()]
        r.sources[0].repository = "http://svn-repo-A"
        r.sources[0].codebase = "A"
        r.sources[0].branch = "develop"
        r.sources[0].revision = "12345"
        self.build = Build([r])
        self.build.setStepFactories([])
        self.builder = Mock()
        self.build.setBuilder(self.builder)
        self.build.build_status = FakeBuildStatus()
        # record properties that will be set
        self.build.build_status.setProperty = self.setProperty

    def setProperty(self, n, v, s, runtime=False):
        if s not in self.props:
            self.props[s] = {}
        if not self.props[s]:
            self.props[s] = {}
        self.props[s][n] = v

    def test_properties_codebase(self):
        self.build.setupProperties()
        codebase = self.props["Build"]["codebase"]
        self.assertEqual(codebase, "A")

    def test_properties_repository(self):
        self.build.setupProperties()
        repository = self.props["Build"]["repository"]
        self.assertEqual(repository, "http://svn-repo-A")

    def test_properties_revision(self):
        self.build.setupProperties()
        revision = self.props["Build"]["revision"]
        self.assertEqual(revision, "12345")

    def test_properties_branch(self):
        self.build.setupProperties()
        branch = self.props["Build"]["branch"]
        self.assertEqual(branch, "develop")

    def test_property_project(self):
        self.build.setupProperties()
        project = self.props["Build"]["project"]
        self.assertEqual(project, '')
Exemple #48
0
 def test_blamelist_for_patch(self):
     r = FakeRequest()
     r.sources.extend([self.patchSource])
     build = Build([r])
     blamelist = build.blamelist()
     self.assertEqual(blamelist, ['jeff'])
Exemple #49
0
 def test_blamelist_for_changes(self):
     r = FakeRequest()
     r.sources.extend([self.sourceByMe, self.sourceByHim])
     build = Build([r])
     blamelist = build.blamelist()
     self.assertEqual(blamelist, ['him', 'me'])
Exemple #50
0
 def acquireLocks(res=None):
     retval = Build.acquireLocks(b, res)
     b.stopBuild('stop it')
     return retval
Exemple #51
0
class TestBuild(TestReactorMixin, unittest.TestCase):

    def setUp(self):
        self.setUpTestReactor()
        r = FakeRequest()
        r.sources = [FakeSource()]
        r.sources[0].changes = [FakeChange()]
        r.sources[0].revision = "12345"

        self.request = r
        self.master = fakemaster.make_master(self, wantData=True)

        self.worker = worker.FakeWorker(self.master)
        self.worker.attached(None)
        self.builder = FakeBuilder(self.master)
        self.build = Build([r])
        self.build.conn = fakeprotocol.FakeConnection(self.master, self.worker)

        self.workerforbuilder = Mock(name='workerforbuilder')
        self.workerforbuilder.worker = self.worker
        self.workerforbuilder.substantiate_if_needed = lambda _: True
        self.workerforbuilder.ping = lambda: True

        self.build.setBuilder(self.builder)
        self.build.text = []
        self.build.buildid = 666

    def assertWorkerPreparationFailure(self, reason):
        states = "".join(self.master.data.updates.stepStateString.values())
        self.assertIn(states, reason)

    def testRunSuccessfulBuild(self):
        b = self.build

        step = FakeBuildStep()
        b.setStepFactories([FakeStepFactory(step)])

        b.startBuild(self.workerforbuilder)

        self.assertEqual(b.results, SUCCESS)

    def testStopBuild(self):
        b = self.build

        step = FakeBuildStep()
        b.setStepFactories([FakeStepFactory(step)])

        def startStep(*args, **kw):
            # Now interrupt the build
            b.stopBuild("stop it")
            return defer.Deferred()
        step.startStep = startStep

        b.startBuild(self.workerforbuilder)

        self.assertEqual(b.results, CANCELLED)

        self.assertIn('stop it', step.interrupted)

    def test_build_retry_when_worker_substantiate_returns_false(self):
        b = self.build

        step = FakeBuildStep()
        b.setStepFactories([FakeStepFactory(step)])

        self.workerforbuilder.substantiate_if_needed = lambda _: False
        b.startBuild(self.workerforbuilder)
        self.assertEqual(b.results, RETRY)
        self.assertWorkerPreparationFailure('error while worker_prepare')

    def test_build_cancelled_when_worker_substantiate_returns_false_due_to_cancel(self):
        b = self.build

        step = FakeBuildStep()
        b.setStepFactories([FakeStepFactory(step)])

        d = defer.Deferred()
        self.workerforbuilder.substantiate_if_needed = lambda _: d
        b.startBuild(self.workerforbuilder)
        b.stopBuild('Cancel Build', CANCELLED)
        d.callback(False)
        self.assertEqual(b.results, CANCELLED)
        self.assertWorkerPreparationFailure('error while worker_prepare')

    def test_build_retry_when_worker_substantiate_returns_false_due_to_cancel(self):
        b = self.build

        step = FakeBuildStep()
        b.setStepFactories([FakeStepFactory(step)])

        d = defer.Deferred()
        self.workerforbuilder.substantiate_if_needed = lambda _: d
        b.startBuild(self.workerforbuilder)
        b.stopBuild('Cancel Build', RETRY)
        d.callback(False)
        self.assertEqual(b.results, RETRY)
        self.assertWorkerPreparationFailure('error while worker_prepare')

    @defer.inlineCallbacks
    def testAlwaysRunStepStopBuild(self):
        """Test that steps marked with alwaysRun=True still get run even if
        the build is stopped."""

        # Create a build with 2 steps, the first one will get interrupted, and
        # the second one is marked with alwaysRun=True
        b = self.build

        step1 = FakeBuildStep()
        step1.alwaysRun = False
        step1.results = None
        step2 = FakeBuildStep()
        step2.alwaysRun = True
        step2.results = None
        b.setStepFactories([
            FakeStepFactory(step1),
            FakeStepFactory(step2),
        ])

        def startStep1(*args, **kw):
            # Now interrupt the build
            b.stopBuild("stop it")
            return defer.succeed(SUCCESS)
        step1.startStep = startStep1
        step1.stepDone = lambda: False

        step2Started = [False]

        def startStep2(*args, **kw):
            step2Started[0] = True
            return defer.succeed(SUCCESS)
        step2.startStep = startStep2
        step1.stepDone = lambda: False

        yield b.startBuild(self.workerforbuilder)

        self.assertEqual(b.results, CANCELLED)
        self.assertIn('stop it', step1.interrupted)
        self.assertTrue(step2Started[0])

    @defer.inlineCallbacks
    def test_start_step_throws_exception(self):
        b = self.build

        step1 = FakeBuildStep()
        b.setStepFactories([
            FakeStepFactory(step1),
        ])

        def startStep(*args, **kw):
            raise TestException()

        step1.startStep = startStep

        yield b.startBuild(self.workerforbuilder)

        self.assertEqual(b.results, EXCEPTION)
        self.flushLoggedErrors(TestException)

    @defer.inlineCallbacks
    def testBuild_canAcquireLocks(self):
        b = self.build

        workerforbuilder1 = Mock()
        workerforbuilder2 = Mock()

        lock = WorkerLock('lock')
        counting_access = lock.access('counting')

        real_lock = yield b.builder.botmaster.getLockByID(lock, 0)

        # no locks, so both these pass (call twice to verify there's no
        # state/memory)
        lock_list = [(real_lock, counting_access)]
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder2))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder2))

        worker_lock_1 = real_lock.getLockForWorker(
            workerforbuilder1.worker.workername)
        worker_lock_2 = real_lock.getLockForWorker(
            workerforbuilder2.worker.workername)

        # then have workerforbuilder2 claim its lock:
        worker_lock_2.claim(workerforbuilder2, counting_access)
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertFalse(
            Build._canAcquireLocks(lock_list, workerforbuilder2))
        self.assertFalse(
            Build._canAcquireLocks(lock_list, workerforbuilder2))
        worker_lock_2.release(workerforbuilder2, counting_access)

        # then have workerforbuilder1 claim its lock:
        worker_lock_1.claim(workerforbuilder1, counting_access)
        self.assertFalse(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertFalse(
            Build._canAcquireLocks(lock_list, workerforbuilder1))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder2))
        self.assertTrue(
            Build._canAcquireLocks(lock_list, workerforbuilder2))
        worker_lock_1.release(workerforbuilder1, counting_access)

    def testBuilddirPropType(self):

        b = self.build

        b.builder.config.workerbuilddir = 'test'
        self.workerforbuilder.worker.worker_basedir = "/srv/buildbot/worker"
        self.workerforbuilder.worker.path_module = posixpath
        b.getProperties = Mock()
        b.setProperty = Mock()

        b.setupWorkerBuildirProperty(self.workerforbuilder)

        expected_path = '/srv/buildbot/worker/test'

        b.setProperty.assert_has_calls(
            [call('builddir', expected_path, 'Worker')],
            any_order=True)

    @defer.inlineCallbacks
    def testBuildLocksAcquired(self):
        b = self.build

        lock = WorkerLock('lock')
        claimCount = [0]
        lock_access = lock.access('counting')
        lock.access = lambda mode: lock_access

        real_workerlock = yield b.builder.botmaster.getLockByID(lock, 0)
        real_lock = real_workerlock.getLockForWorker(self.workerforbuilder.worker.workername)

        def claim(owner, access):
            claimCount[0] += 1
            return real_lock.old_claim(owner, access)
        real_lock.old_claim = real_lock.claim
        real_lock.claim = claim
        yield b.setLocks([lock_access])

        step = FakeBuildStep()
        b.setStepFactories([FakeStepFactory(step)])

        b.startBuild(self.workerforbuilder)

        self.assertEqual(b.results, SUCCESS)
        self.assertEqual(claimCount[0], 1)

    @defer.inlineCallbacks
    def testBuildLocksOrder(self):
        """Test that locks are acquired in FIFO order; specifically that
        counting locks cannot jump ahead of exclusive locks"""
        eBuild = self.build
        cBuilder = FakeBuilder(self.master)
        cBuild = Build([self.request])
        cBuild.setBuilder(cBuilder)

        eWorker = Mock()
        cWorker = Mock()

        eWorker.worker = self.worker
        cWorker.worker = self.worker
        eWorker.substantiate_if_needed = cWorker.substantiate_if_needed = lambda _: True
        eWorker.ping = cWorker.ping = lambda: True

        lock = WorkerLock('lock', 2)
        claimLog = []

        real_workerlock = yield self.master.botmaster.getLockByID(lock, 0)
        realLock = real_workerlock.getLockForWorker(self.worker.workername)

        def claim(owner, access):
            claimLog.append(owner)
            return realLock.oldClaim(owner, access)
        realLock.oldClaim = realLock.claim
        realLock.claim = claim

        yield eBuild.setLocks([lock.access('exclusive')])
        yield cBuild.setLocks([lock.access('counting')])

        fakeBuild = Mock()
        fakeBuildAccess = lock.access('counting')
        realLock.claim(fakeBuild, fakeBuildAccess)

        step = FakeBuildStep()
        eBuild.setStepFactories([FakeStepFactory(step)])
        cBuild.setStepFactories([FakeStepFactory(step)])

        e = eBuild.startBuild(eWorker)
        c = cBuild.startBuild(cWorker)
        d = defer.DeferredList([e, c])

        realLock.release(fakeBuild, fakeBuildAccess)

        yield d
        self.assertEqual(eBuild.results, SUCCESS)
        self.assertEqual(cBuild.results, SUCCESS)
        self.assertEqual(claimLog, [fakeBuild, eBuild, cBuild])

    @defer.inlineCallbacks
    def testBuildWaitingForLocks(self):
        b = self.build

        lock = WorkerLock('lock')
        claimCount = [0]
        lock_access = lock.access('counting')
        lock.access = lambda mode: lock_access

        real_workerlock = yield b.builder.botmaster.getLockByID(lock, 0)
        real_lock = real_workerlock.getLockForWorker(self.workerforbuilder.worker.workername)

        def claim(owner, access):
            claimCount[0] += 1
            return real_lock.old_claim(owner, access)
        real_lock.old_claim = real_lock.claim
        real_lock.claim = claim
        yield b.setLocks([lock_access])

        step = FakeBuildStep()
        b.setStepFactories([FakeStepFactory(step)])

        real_lock.claim(Mock(), lock.access('counting'))

        b.startBuild(self.workerforbuilder)

        self.assertEqual(claimCount[0], 1)
        self.assertTrue(b.currentStep is None)
        self.assertTrue(b._acquiringLock is not None)

    @defer.inlineCallbacks
    def testStopBuildWaitingForLocks(self):
        b = self.build

        lock = WorkerLock('lock')
        lock_access = lock.access('counting')
        lock.access = lambda mode: lock_access

        real_workerlock = yield b.builder.botmaster.getLockByID(lock, 0)
        real_lock = real_workerlock.getLockForWorker(self.workerforbuilder.worker.workername)

        yield b.setLocks([lock_access])

        step = FakeBuildStep()
        step.alwaysRun = False
        b.setStepFactories([FakeStepFactory(step)])

        real_lock.claim(Mock(), lock.access('counting'))

        def acquireLocks(res=None):
            retval = Build.acquireLocks(b, res)
            b.stopBuild('stop it')
            return retval
        b.acquireLocks = acquireLocks

        b.startBuild(self.workerforbuilder)

        self.assertTrue(b.currentStep is None)
        self.assertEqual(b.results, CANCELLED)

    @defer.inlineCallbacks
    def testStopBuildWaitingForLocks_lostRemote(self):
        b = self.build

        lock = WorkerLock('lock')
        lock_access = lock.access('counting')
        lock.access = lambda mode: lock_access

        real_workerlock = yield b.builder.botmaster.getLockByID(lock, 0)
        real_lock = real_workerlock.getLockForWorker(self.workerforbuilder.worker.workername)

        yield b.setLocks([lock_access])

        step = FakeBuildStep()
        step.alwaysRun = False
        b.setStepFactories([FakeStepFactory(step)])

        real_lock.claim(Mock(), lock.access('counting'))

        def acquireLocks(res=None):
            retval = Build.acquireLocks(b, res)
            b.lostRemote()
            return retval
        b.acquireLocks = acquireLocks

        b.startBuild(self.workerforbuilder)

        self.assertTrue(b.currentStep is None)
        self.assertEqual(b.results, RETRY)

    @defer.inlineCallbacks
    def testStopBuildWaitingForStepLocks(self):
        b = self.build

        lock = WorkerLock('lock')
        lock_access = lock.access('counting')
        lock.access = lambda mode: lock_access

        real_workerlock = yield b.builder.botmaster.getLockByID(lock, 0)
        real_lock = real_workerlock.getLockForWorker(self.workerforbuilder.worker.workername)

        step = BuildStep(locks=[lock_access])
        b.setStepFactories([FakeStepFactory(step)])

        real_lock.claim(Mock(), lock.access('counting'))

        gotLocks = [False]

        def acquireLocks(res=None):
            gotLocks[0] = True
            retval = BuildStep.acquireLocks(step, res)
            self.assertTrue(b.currentStep is step)
            b.stopBuild('stop it')
            return retval
        step.acquireLocks = acquireLocks

        b.startBuild(self.workerforbuilder)

        self.assertEqual(gotLocks, [True])
        self.assertEqual(b.results, CANCELLED)

    def testStepDone(self):
        b = self.build
        b.results = SUCCESS
        step = FakeBuildStep()
        terminate = b.stepDone(SUCCESS, step)
        self.assertFalse(terminate.result)
        self.assertEqual(b.results, SUCCESS)

    def testStepDoneHaltOnFailure(self):
        b = self.build
        b.results = SUCCESS
        step = FakeBuildStep()
        step.haltOnFailure = True
        terminate = b.stepDone(FAILURE, step)
        self.assertTrue(terminate.result)
        self.assertEqual(b.results, FAILURE)

    def testStepDoneHaltOnFailureNoFlunkOnFailure(self):
        b = self.build
        b.results = SUCCESS
        step = FakeBuildStep()
        step.flunkOnFailure = False
        step.haltOnFailure = True
        terminate = b.stepDone(FAILURE, step)
        self.assertTrue(terminate.result)
        self.assertEqual(b.results, SUCCESS)

    def testStepDoneFlunkOnWarningsFlunkOnFailure(self):
        b = self.build
        b.results = SUCCESS
        step = FakeBuildStep()
        step.flunkOnFailure = True
        step.flunkOnWarnings = True
        b.stepDone(WARNINGS, step)
        terminate = b.stepDone(FAILURE, step)
        self.assertFalse(terminate.result)
        self.assertEqual(b.results, FAILURE)

    def testStepDoneNoWarnOnWarnings(self):
        b = self.build
        b.results = SUCCESS
        step = FakeBuildStep()
        step.warnOnWarnings = False
        terminate = b.stepDone(WARNINGS, step)
        self.assertFalse(terminate.result)
        self.assertEqual(b.results, SUCCESS)

    def testStepDoneWarnings(self):
        b = self.build
        b.results = SUCCESS
        step = FakeBuildStep()
        terminate = b.stepDone(WARNINGS, step)
        self.assertFalse(terminate.result)
        self.assertEqual(b.results, WARNINGS)

    def testStepDoneFail(self):
        b = self.build
        b.results = SUCCESS
        step = FakeBuildStep()
        terminate = b.stepDone(FAILURE, step)
        self.assertFalse(terminate.result)
        self.assertEqual(b.results, FAILURE)

    def testStepDoneFailOverridesWarnings(self):
        b = self.build
        b.results = WARNINGS
        step = FakeBuildStep()
        terminate = b.stepDone(FAILURE, step)
        self.assertFalse(terminate.result)
        self.assertEqual(b.results, FAILURE)

    def testStepDoneWarnOnFailure(self):
        b = self.build
        b.results = SUCCESS
        step = FakeBuildStep()
        step.warnOnFailure = True
        step.flunkOnFailure = False
        terminate = b.stepDone(FAILURE, step)
        self.assertFalse(terminate.result)
        self.assertEqual(b.results, WARNINGS)

    def testStepDoneFlunkOnWarnings(self):
        b = self.build
        b.results = SUCCESS
        step = FakeBuildStep()
        step.flunkOnWarnings = True
        terminate = b.stepDone(WARNINGS, step)
        self.assertFalse(terminate.result)
        self.assertEqual(b.results, FAILURE)

    def testStepDoneHaltOnFailureFlunkOnWarnings(self):
        b = self.build
        b.results = SUCCESS
        step = FakeBuildStep()
        step.flunkOnWarnings = True
        self.haltOnFailure = True
        terminate = b.stepDone(WARNINGS, step)
        self.assertFalse(terminate.result)
        self.assertEqual(b.results, FAILURE)

    def testStepDoneWarningsDontOverrideFailure(self):
        b = self.build
        b.results = FAILURE
        step = FakeBuildStep()
        terminate = b.stepDone(WARNINGS, step)
        self.assertFalse(terminate.result)
        self.assertEqual(b.results, FAILURE)

    def testStepDoneRetryOverridesAnythingElse(self):
        b = self.build
        b.results = RETRY
        step = FakeBuildStep()
        step.alwaysRun = True
        b.stepDone(WARNINGS, step)
        b.stepDone(FAILURE, step)
        b.stepDone(SUCCESS, step)
        terminate = b.stepDone(EXCEPTION, step)
        self.assertTrue(terminate.result)
        self.assertEqual(b.results, RETRY)

    def test_getSummaryStatistic(self):
        b = self.build

        b.executedSteps = [
            BuildStep(),
            BuildStep(),
            BuildStep()
        ]
        b.executedSteps[0].setStatistic('casualties', 7)
        b.executedSteps[2].setStatistic('casualties', 4)

        add = operator.add
        self.assertEqual(b.getSummaryStatistic('casualties', add), 11)
        self.assertEqual(b.getSummaryStatistic('casualties', add, 10), 21)

    def create_fake_steps(self, names):
        steps = []

        def create_fake_step(name):
            step = FakeBuildStep()
            step.name = name
            return step

        for name in names:
            step = create_fake_step(name)
            steps.append(step)
        return steps

    @defer.inlineCallbacks
    def test_start_build_sets_properties(self):
        b = self.build
        b.setProperty("foo", "bar", "test")

        step = FakeBuildStep()
        b.setStepFactories([FakeStepFactory(step)])

        yield b.startBuild(self.workerforbuilder)
        self.assertEqual(b.results, SUCCESS)

        # remove duplicates, note that set() can't be used as properties contain complex
        # data structures. Also, remove builddir which depends on the platform
        got_properties = []
        for prop in sorted(self.master.data.updates.properties):
            if prop not in got_properties and prop[1] != 'builddir':
                got_properties.append(prop)

        self.assertEqual(got_properties, [
            (10, 'branch', None, 'Build'),
            (10, 'buildnumber', 1, 'Build'),
            (10, 'codebase', '', 'Build'),
            (10, 'foo', 'bar', 'test'),  # custom property
            (10, 'owners', ['me'], 'Build'),
            (10, 'project', '', 'Build'),
            (10, 'repository', '', 'Build'),
            (10, 'revision', '12345', 'Build')
        ])

    @defer.inlineCallbacks
    def testAddStepsAfterCurrentStep(self):
        b = self.build

        steps = self.create_fake_steps(["a", "b", "c"])

        def startStepB(*args, **kw):
            new_steps = self.create_fake_steps(["d", "e"])
            b.addStepsAfterCurrentStep([FakeStepFactory(s) for s in new_steps])
            return SUCCESS

        steps[1].startStep = startStepB
        b.setStepFactories([FakeStepFactory(s) for s in steps])

        yield b.startBuild(self.workerforbuilder)
        self.assertEqual(b.results, SUCCESS)
        expected_names = ["a", "b", "d", "e", "c"]
        executed_names = [s.name for s in b.executedSteps]
        self.assertEqual(executed_names, expected_names)

    @defer.inlineCallbacks
    def testAddStepsAfterLastStep(self):
        b = self.build

        steps = self.create_fake_steps(["a", "b", "c"])

        def startStepB(*args, **kw):
            new_steps = self.create_fake_steps(["d", "e"])
            b.addStepsAfterLastStep([FakeStepFactory(s) for s in new_steps])
            return SUCCESS

        steps[1].startStep = startStepB
        b.setStepFactories([FakeStepFactory(s) for s in steps])

        yield b.startBuild(self.workerforbuilder)
        self.assertEqual(b.results, SUCCESS)
        expected_names = ["a", "b", "c", "d", "e"]
        executed_names = [s.name for s in b.executedSteps]
        self.assertEqual(executed_names, expected_names)

    def testStepNamesUnique(self):
        # if the step names are unique they should remain unchanged
        b = self.build

        steps = self.create_fake_steps(["clone", "command", "clean"])
        b.setStepFactories([FakeStepFactory(s) for s in steps])

        b.startBuild(self.workerforbuilder)
        self.assertEqual(b.results, SUCCESS)
        expected_names = ["clone", "command", "clean"]
        executed_names = [s.name for s in b.executedSteps]
        self.assertEqual(executed_names, expected_names)

    def testStepNamesDuplicate(self):
        b = self.build

        steps = self.create_fake_steps(["stage", "stage", "stage"])
        b.setStepFactories([FakeStepFactory(s) for s in steps])

        b.startBuild(self.workerforbuilder)
        self.assertEqual(b.results, SUCCESS)
        expected_names = ["stage", "stage_1", "stage_2"]
        executed_names = [s.name for s in b.executedSteps]
        self.assertEqual(executed_names, expected_names)

    def testStepNamesDuplicateAfterAdd(self):
        b = self.build

        steps = self.create_fake_steps(["a", "b", "c"])

        def startStepB(*args, **kw):
            new_steps = self.create_fake_steps(["c", "c"])
            b.addStepsAfterCurrentStep([FakeStepFactory(s) for s in new_steps])
            return SUCCESS

        steps[1].startStep = startStepB
        b.setStepFactories([FakeStepFactory(s) for s in steps])

        b.startBuild(self.workerforbuilder)
        self.assertEqual(b.results, SUCCESS)
        expected_names = ["a", "b", "c", "c_1", "c_2"]
        executed_names = [s.name for s in b.executedSteps]
        self.assertEqual(executed_names, expected_names)

    @defer.inlineCallbacks
    def testGetUrl(self):
        self.build.number = 3
        url = yield self.build.getUrl()
        self.assertEqual(url, 'http://localhost:8080/#builders/83/builds/3')

    @defer.inlineCallbacks
    def testGetUrlForVirtualBuilder(self):
        # Let's fake a virtual builder
        self.builder._builders['wilma'] = 108
        self.build.setProperty('virtual_builder_name', 'wilma', 'Build')
        self.build.setProperty('virtual_builder_tags', ['_virtual_'])
        self.build.number = 33
        url = yield self.build.getUrl()
        self.assertEqual(url, 'http://localhost:8080/#builders/108/builds/33')

    def test_active_builds_metric(self):
        """
        The number of active builds is increased when a build starts
        and decreased when it finishes.
        """
        b = self.build

        controller, step_factory = makeControllableStepFactory()
        b.setStepFactories([step_factory])

        observer = MetricLogObserver()
        observer.enable()
        self.addCleanup(observer.disable)

        def get_active_builds():
            return observer.asDict()['counters'].get('active_builds', 0)
        self.assertEqual(get_active_builds(), 0)

        b.startBuild(self.workerforbuilder)

        self.assertEqual(get_active_builds(), 1)

        controller.finishStep(SUCCESS)

        self.assertEqual(get_active_builds(), 0)

    def test_active_builds_metric_failure(self):
        """
        The number of active builds is increased when a build starts
        and decreased when it finishes..
        """
        b = self.build

        b.setStepFactories([FailingStepFactory()])

        observer = MetricLogObserver()
        observer.enable()
        self.addCleanup(observer.disable)

        def get_active_builds():
            return observer.asDict()['counters'].get('active_builds', 0)
        self.assertEqual(get_active_builds(), 0)

        b.startBuild(self.workerforbuilder)

        self.flushLoggedErrors(TestException)

        self.assertEqual(get_active_builds(), 0)
Exemple #52
0
 def acquireLocks(res=None):
     retval = Build.acquireLocks(b, res)
     b.lostRemote()
     return retval
Exemple #53
0
class TestBuild(unittest.TestCase):
    def setUp(self):
        r = FakeRequest()
        r.sources = [FakeSource()]
        r.sources[0].changes = [FakeChange()]
        r.sources[0].revision = "12345"

        self.request = r
        self.master = FakeMaster()

        self.master.botmaster = FakeBotMaster(master=self.master)

        self.slave = slave.FakeSlave(self.master)
        self.builder = self.createBuilder()
        self.build = Build([r])
        self.build.master = self.master
        self.build.setBuilder(self.builder)

    def createBuilder(self):
        bldr = Mock()
        bldr.botmaster = self.master.botmaster
        return bldr

    def testRunSuccessfulBuild(self):
        b = self.build

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        b.setStepFactories([FakeStepFactory(step)])

        slavebuilder = Mock()

        b.startBuild(FakeBuildStatus(), None, slavebuilder)

        self.assertEqual(b.result, SUCCESS)
        self.assert_(('startStep', (slavebuilder.remote, ),
                      {}) in step.method_calls)

    def testStopBuild(self):
        b = self.build

        step = Mock()
        step.return_value = step
        b.setStepFactories([FakeStepFactory(step)])

        slavebuilder = Mock()

        def startStep(*args, **kw):
            # Now interrupt the build
            b.stopBuild("stop it")
            return defer.Deferred()

        step.startStep = startStep

        b.startBuild(FakeBuildStatus(), None, slavebuilder)

        self.assertEqual(b.result, EXCEPTION)

        self.assert_(('interrupt', ('stop it', ), {}) in step.method_calls)

    def testAlwaysRunStepStopBuild(self):
        """Test that steps marked with alwaysRun=True still get run even if
        the build is stopped."""

        # Create a build with 2 steps, the first one will get interrupted, and
        # the second one is marked with alwaysRun=True
        b = self.build

        step1 = Mock()
        step1.return_value = step1
        step1.alwaysRun = False
        step2 = Mock()
        step2.return_value = step2
        step2.alwaysRun = True
        b.setStepFactories([
            FakeStepFactory(step1),
            FakeStepFactory(step2),
        ])

        slavebuilder = Mock()

        def startStep1(*args, **kw):
            # Now interrupt the build
            b.stopBuild("stop it")
            return defer.succeed(SUCCESS)

        step1.startStep = startStep1
        step1.stepDone.return_value = False

        step2Started = [False]

        def startStep2(*args, **kw):
            step2Started[0] = True
            return defer.succeed(SUCCESS)

        step2.startStep = startStep2
        step1.stepDone.return_value = False

        d = b.startBuild(FakeBuildStatus(), None, slavebuilder)

        def check(ign):
            self.assertEqual(b.result, EXCEPTION)
            self.assert_(('interrupt', ('stop it', ),
                          {}) in step1.method_calls)
            self.assert_(step2Started[0])

        d.addCallback(check)
        return d

    def testBuildcanStartWithSlavebuilder(self):
        b = self.build

        slavebuilder1 = Mock()
        slavebuilder2 = Mock()

        l = SlaveLock('lock')
        counting_access = l.access('counting')
        real_lock = b.builder.botmaster.getLockByID(l)

        # no locks, so both these pass (call twice to verify there's no state/memory)
        lock_list = [(real_lock, counting_access)]
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))

        slave_lock_1 = real_lock.getLock(slavebuilder1.slave)
        slave_lock_2 = real_lock.getLock(slavebuilder2.slave)

        # then have slavebuilder2 claim its lock:
        slave_lock_2.claim(slavebuilder2, counting_access)
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertFalse(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
        self.assertFalse(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
        slave_lock_2.release(slavebuilder2, counting_access)

        # then have slavebuilder1 claim its lock:
        slave_lock_1.claim(slavebuilder1, counting_access)
        self.assertFalse(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertFalse(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
        self.assertTrue(
            Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
        slave_lock_1.release(slavebuilder1, counting_access)

    def testBuilddirPropType(self):
        import posixpath

        b = self.build

        slavebuilder = Mock()
        b.build_status = Mock()
        b.builder.config.slavebuilddir = 'test'
        slavebuilder.slave.slave_basedir = "/srv/buildbot/slave"
        slavebuilder.slave.path_module = posixpath
        b.getProperties = Mock()
        b.setProperty = Mock()

        b.setupSlaveBuilder(slavebuilder)

        expected_path = '/srv/buildbot/slave/test'

        b.setProperty.assert_has_calls([
            call('workdir', expected_path, 'slave (deprecated)'),
            call('builddir', expected_path, 'slave')
        ],
                                       any_order=True)

    def testBuildLocksAcquired(self):
        b = self.build

        slavebuilder = Mock()

        l = SlaveLock('lock')
        claimCount = [0]
        lock_access = l.access('counting')
        l.access = lambda mode: lock_access
        real_lock = b.builder.botmaster.getLockByID(l).getLock(
            slavebuilder.slave)

        def claim(owner, access):
            claimCount[0] += 1
            return real_lock.old_claim(owner, access)

        real_lock.old_claim = real_lock.claim
        real_lock.claim = claim
        b.setLocks([lock_access])

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        b.setStepFactories([FakeStepFactory(step)])

        b.startBuild(FakeBuildStatus(), None, slavebuilder)

        self.assertEqual(b.result, SUCCESS)
        self.assert_(('startStep', (slavebuilder.remote, ),
                      {}) in step.method_calls)
        self.assertEquals(claimCount[0], 1)

    def testBuildLocksOrder(self):
        """Test that locks are acquired in FIFO order; specifically that
        counting locks cannot jump ahead of exclusive locks"""
        eBuild = self.build

        cBuilder = self.createBuilder()
        cBuild = Build([self.request])
        cBuild.setBuilder(cBuilder)

        eSlavebuilder = Mock()
        cSlavebuilder = Mock()

        slave = eSlavebuilder.slave
        cSlavebuilder.slave = slave

        l = SlaveLock('lock', 2)
        claimLog = []
        realLock = self.master.botmaster.getLockByID(l).getLock(slave)

        def claim(owner, access):
            claimLog.append(owner)
            return realLock.oldClaim(owner, access)

        realLock.oldClaim = realLock.claim
        realLock.claim = claim

        eBuild.setLocks([l.access('exclusive')])
        cBuild.setLocks([l.access('counting')])

        fakeBuild = Mock()
        fakeBuildAccess = l.access('counting')
        realLock.claim(fakeBuild, fakeBuildAccess)

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        eBuild.setStepFactories([FakeStepFactory(step)])
        cBuild.setStepFactories([FakeStepFactory(step)])

        e = eBuild.startBuild(FakeBuildStatus(), None, eSlavebuilder)
        c = cBuild.startBuild(FakeBuildStatus(), None, cSlavebuilder)
        d = defer.DeferredList([e, c])

        realLock.release(fakeBuild, fakeBuildAccess)

        def check(ign):
            self.assertEqual(eBuild.result, SUCCESS)
            self.assertEqual(cBuild.result, SUCCESS)
            self.assertEquals(claimLog, [fakeBuild, eBuild, cBuild])

        d.addCallback(check)
        return d

    def testBuildWaitingForLocks(self):
        b = self.build

        slavebuilder = Mock()

        l = SlaveLock('lock')
        claimCount = [0]
        lock_access = l.access('counting')
        l.access = lambda mode: lock_access
        real_lock = b.builder.botmaster.getLockByID(l).getLock(
            slavebuilder.slave)

        def claim(owner, access):
            claimCount[0] += 1
            return real_lock.old_claim(owner, access)

        real_lock.old_claim = real_lock.claim
        real_lock.claim = claim
        b.setLocks([lock_access])

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        b.setStepFactories([FakeStepFactory(step)])

        real_lock.claim(Mock(), l.access('counting'))

        b.startBuild(FakeBuildStatus(), None, slavebuilder)

        self.assert_(('startStep', (slavebuilder.remote, ),
                      {}) not in step.method_calls)
        self.assertEquals(claimCount[0], 1)
        self.assert_(b.currentStep is None)
        self.assert_(b._acquiringLock is not None)

    def testStopBuildWaitingForLocks(self):
        b = self.build

        slavebuilder = Mock()

        l = SlaveLock('lock')
        lock_access = l.access('counting')
        l.access = lambda mode: lock_access
        real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)
        b.setLocks([lock_access])

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        step.alwaysRun = False
        b.setStepFactories([FakeStepFactory(step)])

        real_lock.claim(Mock(), l.access('counting'))

        def acquireLocks(res=None):
            retval = Build.acquireLocks(b, res)
            b.stopBuild('stop it')
            return retval

        b.acquireLocks = acquireLocks

        b.startBuild(FakeBuildStatus(), None, slavebuilder)

        self.assert_(('startStep', (slavebuilder.remote, ),
                      {}) not in step.method_calls)
        self.assert_(b.currentStep is None)
        self.assertEqual(b.result, EXCEPTION)
        self.assert_(('interrupt', ('stop it', ), {}) not in step.method_calls)

    def testStopBuildWaitingForLocks_lostRemote(self):
        b = self.build

        slavebuilder = Mock()

        l = SlaveLock('lock')
        lock_access = l.access('counting')
        l.access = lambda mode: lock_access
        real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)
        b.setLocks([lock_access])

        step = Mock()
        step.return_value = step
        step.startStep.return_value = SUCCESS
        step.alwaysRun = False
        b.setStepFactories([FakeStepFactory(step)])

        real_lock.claim(Mock(), l.access('counting'))

        def acquireLocks(res=None):
            retval = Build.acquireLocks(b, res)
            b.lostRemote()
            return retval

        b.acquireLocks = acquireLocks

        b.startBuild(FakeBuildStatus(), None, slavebuilder)

        self.assert_(('startStep', (slavebuilder.remote, ),
                      {}) not in step.method_calls)
        self.assert_(b.currentStep is None)
        self.assertEqual(b.result, RETRY)
        self.assert_(('interrupt', ('stop it', ), {}) not in step.method_calls)
        self.build.build_status.setText.assert_called_with(
            ["retry", "lost", "remote"])
        self.build.build_status.setResults.assert_called_with(RETRY)

    def testStopBuildWaitingForStepLocks(self):
        b = self.build

        slavebuilder = Mock()

        l = SlaveLock('lock')
        lock_access = l.access('counting')
        l.access = lambda mode: lock_access
        real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)

        step = LoggingBuildStep(locks=[lock_access])
        b.setStepFactories([FakeStepFactory(step)])

        real_lock.claim(Mock(), l.access('counting'))

        gotLocks = [False]

        def acquireLocks(res=None):
            gotLocks[0] = True
            retval = LoggingBuildStep.acquireLocks(step, res)
            self.assert_(b.currentStep is step)
            b.stopBuild('stop it')
            return retval

        step.acquireLocks = acquireLocks
        step.setStepStatus = Mock()
        step._step_status = Mock()
        step.step_status.addLog().chunkSize = 10
        step.step_status.getLogs.return_value = []

        b.startBuild(FakeBuildStatus(), None, slavebuilder)

        self.assertEqual(gotLocks, [True])
        self.assert_(('stepStarted', (), {}) in step.step_status.method_calls)
        self.assertEqual(b.result, EXCEPTION)

    def testStepDone(self):
        b = self.build
        b.results = [SUCCESS]
        b.result = SUCCESS
        b.remote = Mock()
        step = FakeBuildStep()
        terminate = b.stepDone(SUCCESS, step)
        self.assertEqual(terminate, False)
        self.assertEqual(b.result, SUCCESS)

    def testStepDoneHaltOnFailure(self):
        b = self.build
        b.results = []
        b.result = SUCCESS
        b.remote = Mock()
        step = FakeBuildStep()
        step.haltOnFailure = True
        terminate = b.stepDone(FAILURE, step)
        self.assertEqual(terminate, True)
        self.assertEqual(b.result, FAILURE)

    def testStepDoneHaltOnFailureNoFlunkOnFailure(self):
        b = self.build
        b.results = []
        b.result = SUCCESS
        b.remote = Mock()
        step = FakeBuildStep()
        step.flunkOnFailure = False
        step.haltOnFailure = True
        terminate = b.stepDone(FAILURE, step)
        self.assertEqual(terminate, True)
        self.assertEqual(b.result, SUCCESS)

    def testStepDoneFlunkOnWarningsFlunkOnFailure(self):
        b = self.build
        b.results = []
        b.result = SUCCESS
        b.remote = Mock()
        step = FakeBuildStep()
        step.flunkOnFailure = True
        step.flunkOnWarnings = True
        b.stepDone(WARNINGS, step)
        terminate = b.stepDone(FAILURE, step)
        self.assertEqual(terminate, False)
        self.assertEqual(b.result, FAILURE)

    def testStepDoneNoWarnOnWarnings(self):
        b = self.build
        b.results = [SUCCESS]
        b.result = SUCCESS
        b.remote = Mock()
        step = FakeBuildStep()
        step.warnOnWarnings = False
        terminate = b.stepDone(WARNINGS, step)
        self.assertEqual(terminate, False)
        self.assertEqual(b.result, SUCCESS)

    def testStepDoneWarnings(self):
        b = self.build
        b.results = [SUCCESS]
        b.result = SUCCESS
        b.remote = Mock()
        step = FakeBuildStep()
        terminate = b.stepDone(WARNINGS, step)
        self.assertEqual(terminate, False)
        self.assertEqual(b.result, WARNINGS)

    def testStepDoneFail(self):
        b = self.build
        b.results = [SUCCESS]
        b.result = SUCCESS
        b.remote = Mock()
        step = FakeBuildStep()
        terminate = b.stepDone(FAILURE, step)
        self.assertEqual(terminate, False)
        self.assertEqual(b.result, FAILURE)

    def testStepDoneFailOverridesWarnings(self):
        b = self.build
        b.results = [SUCCESS, WARNINGS]
        b.result = WARNINGS
        b.remote = Mock()
        step = FakeBuildStep()
        terminate = b.stepDone(FAILURE, step)
        self.assertEqual(terminate, False)
        self.assertEqual(b.result, FAILURE)

    def testStepDoneWarnOnFailure(self):
        b = self.build
        b.results = [SUCCESS]
        b.result = SUCCESS
        b.remote = Mock()
        step = FakeBuildStep()
        step.warnOnFailure = True
        step.flunkOnFailure = False
        terminate = b.stepDone(FAILURE, step)
        self.assertEqual(terminate, False)
        self.assertEqual(b.result, WARNINGS)

    def testStepDoneFlunkOnWarnings(self):
        b = self.build
        b.results = [SUCCESS]
        b.result = SUCCESS
        b.remote = Mock()
        step = FakeBuildStep()
        step.flunkOnWarnings = True
        terminate = b.stepDone(WARNINGS, step)
        self.assertEqual(terminate, False)
        self.assertEqual(b.result, FAILURE)

    def testStepDoneHaltOnFailureFlunkOnWarnings(self):
        b = self.build
        b.results = [SUCCESS]
        b.result = SUCCESS
        b.remote = Mock()
        step = FakeBuildStep()
        step.flunkOnWarnings = True
        self.haltOnFailure = True
        terminate = b.stepDone(WARNINGS, step)
        self.assertEqual(terminate, False)
        self.assertEqual(b.result, FAILURE)

    def testStepDoneWarningsDontOverrideFailure(self):
        b = self.build
        b.results = [FAILURE]
        b.result = FAILURE
        b.remote = Mock()
        step = FakeBuildStep()
        terminate = b.stepDone(WARNINGS, step)
        self.assertEqual(terminate, False)
        self.assertEqual(b.result, FAILURE)

    def testStepDoneRetryOverridesAnythingElse(self):
        b = self.build
        b.results = [RETRY]
        b.result = RETRY
        b.remote = Mock()
        step = FakeBuildStep()
        step.alwaysRun = True
        b.stepDone(WARNINGS, step)
        b.stepDone(FAILURE, step)
        b.stepDone(SUCCESS, step)
        terminate = b.stepDone(EXCEPTION, step)
        self.assertEqual(terminate, True)
        self.assertEqual(b.result, RETRY)