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)
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)
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)
class TestSetupProperties_SingleSource(TestReactorMixin, unittest.TestCase): """ Test that the property values, based on the available requests, are initialized properly """ def setUp(self): self.setup_test_reactor() self.props = {} self.r = FakeRequest() self.r.sources = [] self.r.sources.append(FakeSource()) self.r.sources[0].changes = [FakeChange()] self.r.sources[0].repository = "http://svn-repo-A" self.r.sources[0].codebase = "A" self.r.sources[0].branch = "develop" self.r.sources[0].revision = "12345" self.build = Build([self.r]) self.build.setStepFactories([]) self.builder = FakeBuilder(fakemaster.make_master(self, wantData=True)) self.build.setBuilder(self.builder) # 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_properties_codebase(self): Build.setupBuildProperties(self.build.getProperties(), [self.r], self.r.sources) codebase = self.props["Build"]["codebase"] self.assertEqual(codebase, "A") def test_properties_repository(self): Build.setupBuildProperties(self.build.getProperties(), [self.r], self.r.sources) repository = self.props["Build"]["repository"] self.assertEqual(repository, "http://svn-repo-A") def test_properties_revision(self): Build.setupBuildProperties(self.build.getProperties(), [self.r], self.r.sources) revision = self.props["Build"]["revision"] self.assertEqual(revision, "12345") def test_properties_branch(self): Build.setupBuildProperties(self.build.getProperties(), [self.r], self.r.sources) branch = self.props["Build"]["branch"] self.assertEqual(branch, "develop") def test_property_project(self): Build.setupBuildProperties(self.build.getProperties(), [self.r], self.r.sources) project = self.props["Build"]["project"] self.assertEqual(project, '')
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): 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 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")
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 = 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_properties_codebase(self): self.build.setupOwnProperties() codebase = self.props["Build"]["codebase"] self.assertEqual(codebase, "A") def test_properties_repository(self): self.build.setupOwnProperties() repository = self.props["Build"]["repository"] self.assertEqual(repository, "http://svn-repo-A") def test_properties_revision(self): self.build.setupOwnProperties() revision = self.props["Build"]["revision"] self.assertEqual(revision, "12345") def test_properties_branch(self): self.build.setupOwnProperties() branch = self.props["Build"]["branch"] self.assertEqual(branch, "develop") def test_property_project(self): self.build.setupOwnProperties() project = self.props["Build"]["project"] self.assertEqual(project, '')
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, '')
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 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 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, NOT_REBUILT) self.assertEqual(cBuild.result, NOT_REBUILT) self.assertEquals(claimLog, [fakeBuild, eBuild, cBuild]) d.addCallback(check) return d
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 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])
class TestStepLocks(unittest.TestCase): def setUp(self): r = FakeRequest() self.request = r self.master = FakeMaster() self.master.maybeStartBuildsForSlave = lambda slave: True self.build = Build([r]) self.builder = Mock() self.builder.botmaster = self.master.botmaster self.build.setBuilder(self.builder) self.build_status = FakeBuildStatus() self.step_status = Mock() self.step_status.finished = None self.build_status.addStepWithName = lambda x, y: self.step_status def test_acquire_build_Lock_step(self): b = self.build slavebuilder = Mock() l = SlaveLock("slave_builds", maxCount=1) self.assertEqual(len(b.locks), 0) step = artifact.AcquireBuildLocks(locks=[l.access('exclusive')]) b.setStepFactories([FakeStepFactory(step)]) b.startBuild(self.build_status, None, slavebuilder) b.currentStep.start() self.assertEqual(len(b.locks), 1) self.assertTrue(b.locks[0][0].owners[0][0], step) def test_release_build_Lock_step(self): b = self.build slavebuilder = Mock() l = SlaveLock("slave_builds", maxCount=1) step = artifact.AcquireBuildLocks(locks=[l.access('exclusive')]) step2 = artifact.ReleaseBuildLocks() b.setStepFactories([FakeStepFactory(step), FakeStepFactory(step2)]) self.assertEqual(len(b.locks), 0) b.startBuild(self.build_status, None, slavebuilder) b.currentStep.start() self.assertTrue(b.locks[0][0].owners[0][0], step) b.currentStep.start() self.assertEqual(len(b.locks[0][0].owners), 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.builder.botmaster.master.config.globalFactory = {} 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 self.assertTrue(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")
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
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_propkey(self): self.build_status.has_propkey.return_value = True self.assertTrue(self.build.has_propkey('p')) # has_propkey 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")
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
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"])
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.setupOwnProperties() self.assertNotIn("codebase", self.props["Build"]) self.assertNotIn("revision", self.props["Build"]) self.assertNotIn("branch", self.props["Build"]) self.assertNotIn("project", self.props["Build"]) self.assertNotIn("repository", self.props["Build"])
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)
class TestSetupProperties_MultipleSources(TestReactorMixin, unittest.TestCase): """ Test that the property values, based on the available requests, are initialized properly """ def setUp(self): self.setUpTestReactor() self.props = {} self.r = FakeRequest() self.r.sources = [] self.r.sources.append(FakeSource()) self.r.sources[0].changes = [FakeChange()] self.r.sources[0].repository = "http://svn-repo-A" self.r.sources[0].codebase = "A" self.r.sources[0].branch = "develop" self.r.sources[0].revision = "12345" self.r.sources.append(FakeSource()) self.r.sources[1].changes = [FakeChange()] self.r.sources[1].repository = "http://svn-repo-B" self.r.sources[1].codebase = "B" self.r.sources[1].revision = "34567" self.build = Build([self.r]) self.build.setStepFactories([]) self.builder = FakeBuilder(fakemaster.make_master(self, wantData=True)) self.build.setBuilder(self.builder) # 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): Build.setupBuildProperties(self.build.getProperties(), [self.r], self.r.sources) self.assertNotIn("codebase", self.props["Build"]) self.assertNotIn("revision", self.props["Build"]) self.assertNotIn("branch", self.props["Build"]) self.assertNotIn("project", self.props["Build"]) self.assertNotIn("repository", self.props["Build"])
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 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)
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.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 def testRunSuccessfulBuild(self): b = self.build step = FakeBuildStep() b.setStepFactories([FakeStepFactory(step)]) b.startBuild(FakeBuildStatus(), 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(FakeBuildStatus(), self.workerforbuilder) self.assertEqual(b.results, CANCELLED) self.assertIn('stop it', step.interrupted) def testBuildRetryWhenWorkerPrepareReturnFalse(self): b = self.build step = FakeBuildStep() b.setStepFactories([FakeStepFactory(step)]) self.workerforbuilder.prepare = lambda _: False b.startBuild(FakeBuildStatus(), self.workerforbuilder) self.assertEqual(b.results, RETRY) def testBuildCancelledWhenWorkerPrepareReturnFalseBecauseBuildStop(self): b = self.build step = FakeBuildStep() b.setStepFactories([FakeStepFactory(step)]) d = defer.Deferred() self.workerforbuilder.prepare = lambda _: d b.startBuild(FakeBuildStatus(), self.workerforbuilder) b.stopBuild('Cancel Build', CANCELLED) d.callback(False) self.assertEqual(b.results, CANCELLED) def testBuildRetryWhenWorkerPrepareReturnFalseBecauseBuildStop(self): b = self.build step = FakeBuildStep() b.setStepFactories([FakeStepFactory(step)]) d = defer.Deferred() self.workerforbuilder.prepare = lambda _: d b.startBuild(FakeBuildStatus(), self.workerforbuilder) b.stopBuild('Cancel Build', RETRY) d.callback(False) self.assertEqual(b.results, RETRY) 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 d = b.startBuild(FakeBuildStatus(), self.workerforbuilder) def check(ign): self.assertEqual(b.results, CANCELLED) self.assertIn('stop it', step1.interrupted) self.assertTrue(step2Started[0]) d.addCallback(check) return d def testBuildcanStartWithWorkerForBuilder(self): b = self.build workerforbuilder1 = Mock() workerforbuilder2 = Mock() lock = WorkerLock('lock') counting_access = lock.access('counting') real_lock = b.builder.botmaster.getLockByID(lock) # no locks, so both these pass (call twice to verify there's no # state/memory) lock_list = [(real_lock, counting_access)] self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder2)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder2)) worker_lock_1 = real_lock.getLock(workerforbuilder1.worker) worker_lock_2 = real_lock.getLock(workerforbuilder2.worker) # then have workerforbuilder2 claim its lock: worker_lock_2.claim(workerforbuilder2, counting_access) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertFalse( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder2)) self.assertFalse( Build.canStartWithWorkerForBuilder(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.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertFalse( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder2)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder2)) worker_lock_1.release(workerforbuilder1, counting_access) def testBuilddirPropType(self): import posixpath b = self.build b.build_status = Mock() 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) def testBuildLocksAcquired(self): b = self.build lock = WorkerLock('lock') claimCount = [0] lock_access = lock.access('counting') lock.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(lock) \ .getLock(self.workerforbuilder.worker) 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 = FakeBuildStep() b.setStepFactories([FakeStepFactory(step)]) b.startBuild(FakeBuildStatus(), self.workerforbuilder) self.assertEqual(b.results, SUCCESS) self.assertEqual(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 = 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 lock = WorkerLock('lock', 2) claimLog = [] realLock = self.master.botmaster.getLockByID(lock).getLock(self.worker) def claim(owner, access): claimLog.append(owner) return realLock.oldClaim(owner, access) realLock.oldClaim = realLock.claim realLock.claim = claim eBuild.setLocks([lock.access('exclusive')]) 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(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 testBuildWaitingForLocks(self): b = self.build lock = WorkerLock('lock') claimCount = [0] lock_access = lock.access('counting') lock.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(lock) \ .getLock(self.workerforbuilder.worker) 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 = FakeBuildStep() b.setStepFactories([FakeStepFactory(step)]) real_lock.claim(Mock(), lock.access('counting')) b.startBuild(FakeBuildStatus(), self.workerforbuilder) self.assertEqual(claimCount[0], 1) self.assertTrue(b.currentStep is None) self.assertTrue(b._acquiringLock is not None) def testStopBuildWaitingForLocks(self): b = self.build lock = WorkerLock('lock') lock_access = lock.access('counting') lock.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(lock) \ .getLock(self.workerforbuilder.worker) 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(FakeBuildStatus(), self.workerforbuilder) self.assertTrue(b.currentStep is None) self.assertEqual(b.results, CANCELLED) def testStopBuildWaitingForLocks_lostRemote(self): b = self.build lock = WorkerLock('lock') lock_access = lock.access('counting') lock.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(lock) \ .getLock(self.workerforbuilder.worker) 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(FakeBuildStatus(), self.workerforbuilder) self.assertTrue(b.currentStep is None) self.assertEqual(b.results, RETRY) self.build.build_status.setText.assert_called_with( ["retry", "lost", "connection"]) self.build.build_status.setResults.assert_called_with(RETRY) def testStopBuildWaitingForStepLocks(self): b = self.build lock = WorkerLock('lock') lock_access = lock.access('counting') lock.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(lock) \ .getLock(self.workerforbuilder.worker) step = LoggingBuildStep(locks=[lock_access]) b.setStepFactories([FakeStepFactory(step)]) real_lock.claim(Mock(), lock.access('counting')) gotLocks = [False] def acquireLocks(res=None): gotLocks[0] = True retval = LoggingBuildStep.acquireLocks(step, res) self.assertTrue(b.currentStep is step) b.stopBuild('stop it') return retval step.acquireLocks = acquireLocks b.startBuild(FakeBuildStatus(), 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) @defer.inlineCallbacks def testflushProperties(self): b = self.build b.build_status = FakeBuildStatus() b.setProperty("foo", "bar", "test") b.buildid = 43 result = 'SUCCESS' res = yield b._flushProperties(result) self.assertEqual(res, result) self.assertEqual(self.master.data.updates.properties, [(43, u'foo', 'bar', u'test')]) 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 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]) b.startBuild(FakeBuildStatus(), 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) 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]) b.startBuild(FakeBuildStatus(), 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(FakeBuildStatus(), 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(FakeBuildStatus(), 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(FakeBuildStatus(), self.workerforbuilder) self.assertEqual(b.results, SUCCESS) expected_names = ["a", "b", "c_1", "c_2", "c"] 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.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(FakeBuildStatus(), 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(FakeBuildStatus(), self.workerforbuilder) self.flushLoggedErrors(TestException) self.assertEqual(get_active_builds(), 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): @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 test_getProperty(self): self.build.getProperty('x') self.properties.getProperty.assert_called_with('x', None) def test_getProperty_default(self): self.build.getProperty('x', 'nox') self.properties.getProperty.assert_called_with('x', 'nox') def test_setProperty(self): self.build.setProperty('n', 'v', 's') self.properties.setProperty.assert_called_with('n', 'v', 's', runtime=True) def test_hasProperty(self): self.properties.hasProperty.return_value = True self.assertTrue(self.build.hasProperty('p')) self.properties.hasProperty.assert_called_with('p') def test_has_key(self): self.properties.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.properties.hasProperty.assert_called_with('p') def test_render(self): self.build.render("xyz") self.properties.render.assert_called_with("xyz") def test_getWorkerName_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.workerforbuilder = 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 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)
class TestBuild(unittest.TestCase): def setUp(self): r = FakeRequest() self.build = Build([r]) self.builder = Mock() self.builder.botmaster = FakeMaster() self.build.setBuilder(self.builder) def testRunSuccessfulBuild(self): b = self.build step = Mock() step.return_value = step step.startStep.return_value = SUCCESS b.setStepFactories([(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([(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([ (step1, {}), (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 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) 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(FakeBuildStatus(), None, slavebuilder) self.assertEqual(b.result, SUCCESS) self.assert_( ('startStep', (slavebuilder.remote,), {}) in step.method_calls) self.assertEquals(claimCount[0], 1) 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) 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(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([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(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([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.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]) 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(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)
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)
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)
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.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 def testRunSuccessfulBuild(self): b = self.build step = FakeBuildStep() b.setStepFactories([FakeStepFactory(step)]) b.startBuild(FakeBuildStatus(), 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(FakeBuildStatus(), self.workerforbuilder) self.assertEqual(b.results, CANCELLED) self.assertIn('stop it', step.interrupted) 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 d = b.startBuild(FakeBuildStatus(), self.workerforbuilder) def check(ign): self.assertEqual(b.results, CANCELLED) self.assertIn('stop it', step1.interrupted) self.assertTrue(step2Started[0]) d.addCallback(check) return d def testBuildcanStartWithWorkerForBuilder(self): b = self.build workerforbuilder1 = Mock() workerforbuilder2 = Mock() lock = WorkerLock('lock') counting_access = lock.access('counting') real_lock = b.builder.botmaster.getLockByID(lock) # no locks, so both these pass (call twice to verify there's no # state/memory) lock_list = [(real_lock, counting_access)] self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder2)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder2)) worker_lock_1 = real_lock.getLock(workerforbuilder1.worker) worker_lock_2 = real_lock.getLock(workerforbuilder2.worker) # then have workerforbuilder2 claim its lock: worker_lock_2.claim(workerforbuilder2, counting_access) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertFalse( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder2)) self.assertFalse( Build.canStartWithWorkerForBuilder(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.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertFalse( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder1)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder2)) self.assertTrue( Build.canStartWithWorkerForBuilder(lock_list, workerforbuilder2)) worker_lock_1.release(workerforbuilder1, counting_access) def testBuilddirPropType(self): import posixpath b = self.build b.build_status = Mock() 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.setupWorkerForBuilder(self.workerforbuilder) expected_path = '/srv/buildbot/worker/test' b.setProperty.assert_has_calls( [call('builddir', expected_path, 'worker')], any_order=True) def testBuildLocksAcquired(self): b = self.build lock = WorkerLock('lock') claimCount = [0] lock_access = lock.access('counting') lock.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(lock) \ .getLock(self.workerforbuilder.worker) 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 = FakeBuildStep() b.setStepFactories([FakeStepFactory(step)]) b.startBuild(FakeBuildStatus(), self.workerforbuilder) self.assertEqual(b.results, SUCCESS) self.assertEqual(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 = 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 lock = WorkerLock('lock', 2) claimLog = [] realLock = self.master.botmaster.getLockByID(lock).getLock(self.worker) def claim(owner, access): claimLog.append(owner) return realLock.oldClaim(owner, access) realLock.oldClaim = realLock.claim realLock.claim = claim eBuild.setLocks([lock.access('exclusive')]) 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(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 testBuildWaitingForLocks(self): b = self.build lock = WorkerLock('lock') claimCount = [0] lock_access = lock.access('counting') lock.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(lock) \ .getLock(self.workerforbuilder.worker) 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 = FakeBuildStep() b.setStepFactories([FakeStepFactory(step)]) real_lock.claim(Mock(), lock.access('counting')) b.startBuild(FakeBuildStatus(), self.workerforbuilder) self.assertEqual(claimCount[0], 1) self.assertTrue(b.currentStep is None) self.assertTrue(b._acquiringLock is not None) def testStopBuildWaitingForLocks(self): b = self.build lock = WorkerLock('lock') lock_access = lock.access('counting') lock.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(lock) \ .getLock(self.workerforbuilder.worker) 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(FakeBuildStatus(), self.workerforbuilder) self.assertTrue(b.currentStep is None) self.assertEqual(b.results, CANCELLED) def testStopBuildWaitingForLocks_lostRemote(self): b = self.build lock = WorkerLock('lock') lock_access = lock.access('counting') lock.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(lock) \ .getLock(self.workerforbuilder.worker) 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(FakeBuildStatus(), self.workerforbuilder) self.assertTrue(b.currentStep is None) self.assertEqual(b.results, RETRY) self.build.build_status.setText.assert_called_with( ["retry", "lost", "connection"]) self.build.build_status.setResults.assert_called_with(RETRY) def testStopBuildWaitingForStepLocks(self): b = self.build lock = WorkerLock('lock') lock_access = lock.access('counting') lock.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(lock) \ .getLock(self.workerforbuilder.worker) step = LoggingBuildStep(locks=[lock_access]) b.setStepFactories([FakeStepFactory(step)]) real_lock.claim(Mock(), lock.access('counting')) gotLocks = [False] def acquireLocks(res=None): gotLocks[0] = True retval = LoggingBuildStep.acquireLocks(step, res) self.assertTrue(b.currentStep is step) b.stopBuild('stop it') return retval step.acquireLocks = acquireLocks b.startBuild(FakeBuildStatus(), 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) @defer.inlineCallbacks def testflushProperties(self): b = self.build b.build_status = FakeBuildStatus() b.setProperty("foo", "bar", "test") b.buildid = 43 result = 'SUCCESS' res = yield b._flushProperties(result) self.assertEqual(res, result) self.assertEqual(self.master.data.updates.properties, [(43, u'foo', 'bar', u'test')]) 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 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]) b.startBuild(FakeBuildStatus(), 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) 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]) b.startBuild(FakeBuildStatus(), 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(FakeBuildStatus(), 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(FakeBuildStatus(), 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(FakeBuildStatus(), self.workerforbuilder) self.assertEqual(b.results, SUCCESS) expected_names = ["a", "b", "c_1", "c_2", "c"] 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') 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(FakeBuildStatus(), 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(FakeBuildStatus(), self.workerforbuilder) self.flushLoggedErrors(TestException) self.assertEqual(get_active_builds(), 0)
class TestBuild(unittest.TestCase): def setUp(self): r = FakeRequest() self.build = Build([r]) self.builder = Mock() self.builder.botmaster = FakeMaster() self.build.setBuilder(self.builder) def testRunSuccessfulBuild(self): b = self.build step = Mock() step.return_value = step step.startStep.return_value = SUCCESS b.setStepFactories([(step, {})]) slavebuilder = Mock() b.startBuild(FakeBuildStatus(), None, slavebuilder) self.assertEqual(b.result, SUCCESS) self.assert_( ('startStep', (b.remote,), {}) in step.method_calls) def testStopBuild(self): b = self.build step = Mock() step.return_value = step b.setStepFactories([(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([ (step1, {}), (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 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) 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(FakeBuildStatus(), None, slavebuilder) self.assertEqual(b.result, SUCCESS) self.assert_( ('startStep', (b.remote,), {}) in step.method_calls) self.assertEquals(claimCount[0], 1) 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) 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(FakeBuildStatus(), 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) 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([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(FakeBuildStatus(), 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) 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]) 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(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)
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.make_master(wantData=True, testcase=self) self.slave = slave.FakeSlave(self.master) self.slave.attached(None) self.builder = FakeBuilder(self.master) self.build = Build([r]) self.build.conn = fakeprotocol.FakeConnection(self.master, self.slave) self.slavebuilder = Mock(name='slavebuilder') self.slavebuilder.slave = self.slave self.build.setBuilder(self.builder) def testRunSuccessfulBuild(self): b = self.build step = Mock() step.return_value = step step.startStep.return_value = SUCCESS b.setStepFactories([FakeStepFactory(step)]) b.startBuild(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(b.results, SUCCESS) self.assert_(('startStep', (self.slavebuilder.slave.conn,), {}) in step.method_calls) def testStopBuild(self): b = self.build step = Mock() step.return_value = step b.setStepFactories([FakeStepFactory(step)]) def startStep(*args, **kw): # Now interrupt the build b.stopBuild("stop it") return defer.Deferred() step.startStep = startStep b.startBuild(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(b.results, CANCELLED) 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), ]) 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, self.slavebuilder) def check(ign): self.assertEqual(b.results, CANCELLED) 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 b.build_status = Mock() b.builder.config.slavebuilddir = 'test' self.slavebuilder.slave.slave_basedir = "/srv/buildbot/slave" self.slavebuilder.slave.path_module = posixpath b.getProperties = Mock() b.setProperty = Mock() b.setupSlaveBuilder(self.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 l = SlaveLock('lock') claimCount = [0] lock_access = l.access('counting') l.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(l) \ .getLock(self.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, self.slavebuilder) self.assertEqual(b.results, SUCCESS) self.assertIn(('startStep', (self.slavebuilder.slave.conn,), {}), 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 = FakeBuilder(self.master) cBuild = Build([self.request]) cBuild.setBuilder(cBuilder) eSlavebuilder = Mock() cSlavebuilder = Mock() eSlavebuilder.slave = self.slave cSlavebuilder.slave = self.slave l = SlaveLock('lock', 2) claimLog = [] realLock = self.master.botmaster.getLockByID(l).getLock(self.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.results, SUCCESS) self.assertEqual(cBuild.results, SUCCESS) self.assertEquals(claimLog, [fakeBuild, eBuild, cBuild]) d.addCallback(check) return d def testBuildWaitingForLocks(self): b = self.build l = SlaveLock('lock') claimCount = [0] lock_access = l.access('counting') l.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(l) \ .getLock(self.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, self.slavebuilder) self.assert_(('startStep', (self.slavebuilder.slave.conn,), {}) 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 l = SlaveLock('lock') lock_access = l.access('counting') l.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(l) \ .getLock(self.slavebuilder.slave) 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, self.slavebuilder) self.assert_(('startStep', (self.slavebuilder.slave.conn,), {}) not in step.method_calls) self.assert_(b.currentStep is None) self.assertEqual(b.results, CANCELLED) self.assert_(('interrupt', ('stop it',), {}) not in step.method_calls) def testStopBuildWaitingForLocks_lostRemote(self): b = self.build l = SlaveLock('lock') lock_access = l.access('counting') l.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(l) \ .getLock(self.slavebuilder.slave) 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, self.slavebuilder) self.assert_(('startStep', (self.slavebuilder.slave.conn,), {}) not in step.method_calls) self.assert_(b.currentStep is None) self.assertEqual(b.results, RETRY) self.assert_(('interrupt', ('stop it',), {}) not in step.method_calls) self.build.build_status.setText.assert_called_with(["retry", "lost", "connection"]) self.build.build_status.setResults.assert_called_with(RETRY) def testStopBuildWaitingForStepLocks(self): b = self.build l = SlaveLock('lock') lock_access = l.access('counting') l.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(l) \ .getLock(self.slavebuilder.slave) 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 b.startBuild(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(gotLocks, [True]) self.assertEqual(b.results, CANCELLED) def testStepDone(self): b = self.build b.results = [SUCCESS] b.results = SUCCESS step = FakeBuildStep() terminate = b.stepDone(SUCCESS, step) self.assertEqual(terminate, False) self.assertEqual(b.results, SUCCESS) def testStepDoneHaltOnFailure(self): b = self.build b.results = [] b.results = SUCCESS step = FakeBuildStep() step.haltOnFailure = True terminate = b.stepDone(FAILURE, step) self.assertEqual(terminate, True) self.assertEqual(b.results, FAILURE) def testStepDoneHaltOnFailureNoFlunkOnFailure(self): b = self.build b.results = [] b.results = SUCCESS step = FakeBuildStep() step.flunkOnFailure = False step.haltOnFailure = True terminate = b.stepDone(FAILURE, step) self.assertEqual(terminate, True) self.assertEqual(b.results, SUCCESS) def testStepDoneFlunkOnWarningsFlunkOnFailure(self): b = self.build b.results = [] b.results = SUCCESS step = FakeBuildStep() step.flunkOnFailure = True step.flunkOnWarnings = True b.stepDone(WARNINGS, step) terminate = b.stepDone(FAILURE, step) self.assertEqual(terminate, False) self.assertEqual(b.results, FAILURE) def testStepDoneNoWarnOnWarnings(self): b = self.build b.results = [SUCCESS] b.results = SUCCESS step = FakeBuildStep() step.warnOnWarnings = False terminate = b.stepDone(WARNINGS, step) self.assertEqual(terminate, False) self.assertEqual(b.results, SUCCESS) def testStepDoneWarnings(self): b = self.build b.results = [SUCCESS] b.results = SUCCESS step = FakeBuildStep() terminate = b.stepDone(WARNINGS, step) self.assertEqual(terminate, False) self.assertEqual(b.results, WARNINGS) def testStepDoneFail(self): b = self.build b.results = [SUCCESS] b.results = SUCCESS step = FakeBuildStep() terminate = b.stepDone(FAILURE, step) self.assertEqual(terminate, False) self.assertEqual(b.results, FAILURE) def testStepDoneFailOverridesWarnings(self): b = self.build b.results = [SUCCESS, WARNINGS] b.results = WARNINGS step = FakeBuildStep() terminate = b.stepDone(FAILURE, step) self.assertEqual(terminate, False) self.assertEqual(b.results, FAILURE) def testStepDoneWarnOnFailure(self): b = self.build b.results = [SUCCESS] b.results = SUCCESS step = FakeBuildStep() step.warnOnFailure = True step.flunkOnFailure = False terminate = b.stepDone(FAILURE, step) self.assertEqual(terminate, False) self.assertEqual(b.results, WARNINGS) def testStepDoneFlunkOnWarnings(self): b = self.build b.results = [SUCCESS] b.results = SUCCESS step = FakeBuildStep() step.flunkOnWarnings = True terminate = b.stepDone(WARNINGS, step) self.assertEqual(terminate, False) self.assertEqual(b.results, FAILURE) def testStepDoneHaltOnFailureFlunkOnWarnings(self): b = self.build b.results = [SUCCESS] b.results = SUCCESS step = FakeBuildStep() step.flunkOnWarnings = True self.haltOnFailure = True terminate = b.stepDone(WARNINGS, step) self.assertEqual(terminate, False) self.assertEqual(b.results, FAILURE) def testStepDoneWarningsDontOverrideFailure(self): b = self.build b.results = [FAILURE] b.results = FAILURE step = FakeBuildStep() terminate = b.stepDone(WARNINGS, step) self.assertEqual(terminate, False) self.assertEqual(b.results, FAILURE) def testStepDoneRetryOverridesAnythingElse(self): b = self.build b.results = [RETRY] 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.assertEqual(terminate, True) 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) @defer.inlineCallbacks def testflushProperties(self): b = self.build b.build_status = FakeBuildStatus() b.setProperty("foo", "bar", "test") b.buildid = 43 result = 'SUCCESS' res = yield b._flushProperties(result) self.assertEquals(res, result) self.assertEqual(self.master.data.updates.properties, [(43, u'foo', 'bar', u'test')]) def create_mock_steps(self, names): steps = [] def create_mock_step(name): step = Mock() step.return_value = step step.startStep.return_value = SUCCESS step.name = name return step for name in names: step = create_mock_step(name) steps.append(step) return steps def testAddStepsAfterCurrentStep(self): b = self.build steps = self.create_mock_steps(["a", "b", "c"]) def startStepB(*args, **kw): new_steps = self.create_mock_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]) b.startBuild(FakeBuildStatus(), None, self.slavebuilder) 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) def testAddStepsAfterLastStep(self): b = self.build steps = self.create_mock_steps(["a", "b", "c"]) def startStepB(*args, **kw): new_steps = self.create_mock_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]) b.startBuild(FakeBuildStatus(), None, self.slavebuilder) 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_mock_steps(["clone", "command", "clean"]) b.setStepFactories([FakeStepFactory(s) for s in steps]) b.startBuild(FakeBuildStatus(), None, self.slavebuilder) 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_mock_steps(["stage", "stage", "stage"]) b.setStepFactories([FakeStepFactory(s) for s in steps]) b.startBuild(FakeBuildStatus(), None, self.slavebuilder) 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_mock_steps(["a", "b", "c"]) def startStepB(*args, **kw): new_steps = self.create_mock_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(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(b.results, SUCCESS) expected_names = ["a", "b", "c_1", "c_2", "c"] executed_names = [s.name for s in b.executedSteps] self.assertEqual(executed_names, expected_names)
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.make_master(wantData=True, testcase=self) self.master.botmaster = FakeBotMaster(master=self.master) self.slave = slave.FakeSlave(self.master) self.slave.attached(None) self.builder = FakeBuilder(self.master) self.build = Build([r]) self.build.conn = fakeprotocol.FakeConnection(self.master, self.slave) self.slavebuilder = Mock(name="slavebuilder") self.slavebuilder.slave = self.slave self.build.setBuilder(self.builder) def testRunSuccessfulBuild(self): b = self.build step = Mock() step.return_value = step step.startStep.return_value = SUCCESS b.setStepFactories([FakeStepFactory(step)]) b.startBuild(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(b.result, SUCCESS) self.assert_(("startStep", (self.slavebuilder.slave.conn,), {}) in step.method_calls) def testStopBuild(self): b = self.build step = Mock() step.return_value = step b.setStepFactories([FakeStepFactory(step)]) def startStep(*args, **kw): # Now interrupt the build b.stopBuild("stop it") return defer.Deferred() step.startStep = startStep b.startBuild(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(b.result, CANCELLED) 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)]) 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, self.slavebuilder) def check(ign): self.assertEqual(b.result, CANCELLED) 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 b.build_status = Mock() b.builder.config.slavebuilddir = "test" self.slavebuilder.slave.slave_basedir = "/srv/buildbot/slave" self.slavebuilder.slave.path_module = posixpath b.getProperties = Mock() b.setProperty = Mock() b.setupSlaveBuilder(self.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 l = SlaveLock("lock") claimCount = [0] lock_access = l.access("counting") l.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(l).getLock(self.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, self.slavebuilder) self.assertEqual(b.result, SUCCESS) self.assertIn(("startStep", (self.slavebuilder.slave.conn,), {}), 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 = FakeBuilder(self.master) cBuild = Build([self.request]) cBuild.setBuilder(cBuilder) eSlavebuilder = Mock() cSlavebuilder = Mock() eSlavebuilder.slave = self.slave cSlavebuilder.slave = self.slave l = SlaveLock("lock", 2) claimLog = [] realLock = self.master.botmaster.getLockByID(l).getLock(self.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 l = SlaveLock("lock") claimCount = [0] lock_access = l.access("counting") l.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(l).getLock(self.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, self.slavebuilder) self.assert_(("startStep", (self.slavebuilder.slave.conn,), {}) 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 l = SlaveLock("lock") lock_access = l.access("counting") l.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(l).getLock(self.slavebuilder.slave) 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, self.slavebuilder) self.assert_(("startStep", (self.slavebuilder.slave.conn,), {}) not in step.method_calls) self.assert_(b.currentStep is None) self.assertEqual(b.result, CANCELLED) self.assert_(("interrupt", ("stop it",), {}) not in step.method_calls) def testStopBuildWaitingForLocks_lostRemote(self): b = self.build l = SlaveLock("lock") lock_access = l.access("counting") l.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(l).getLock(self.slavebuilder.slave) 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, self.slavebuilder) self.assert_(("startStep", (self.slavebuilder.slave.conn,), {}) 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", "connection"]) self.build.build_status.setResults.assert_called_with(RETRY) def testStopBuildWaitingForStepLocks(self): b = self.build l = SlaveLock("lock") lock_access = l.access("counting") l.access = lambda mode: lock_access real_lock = b.builder.botmaster.getLockByID(l).getLock(self.slavebuilder.slave) 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 b.startBuild(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(gotLocks, [True]) self.assertEqual(b.result, CANCELLED) def testStepDone(self): b = self.build b.results = [SUCCESS] b.result = SUCCESS 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 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 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 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 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 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 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 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 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 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 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 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 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 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) @defer.inlineCallbacks def testflushProperties(self): b = self.build class FakeBuildStatus(Mock): implements(interfaces.IProperties) b.build_status = FakeBuildStatus() class Properties(Mock): def asList(self): return [(u"p", 5, u"fake"), (u"p2", ["abc", 9], u"mock")] b.master.data.updates.setBuildProperty = Mock() b.build_status.getProperties.return_value = Properties() b.buildid = 42 result = "SUCCESS" res = yield b._flushProperties(result) self.assertEquals(res, result) b.master.data.updates.setBuildProperty.assert_has_calls( [call(42, u"p", 5, u"fake"), call(42, u"p2", ["abc", 9], u"mock")] ) def create_mock_steps(self, names): steps = [] def create_mock_step(name): step = Mock() step.return_value = step step.startStep.return_value = SUCCESS step.name = name return step for name in names: step = create_mock_step(name) steps.append(step) return steps def testAddStepsAfterCurrentStep(self): b = self.build steps = self.create_mock_steps(["a", "b", "c"]) def startStepB(*args, **kw): new_steps = self.create_mock_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]) b.startBuild(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(b.result, SUCCESS) expected_names = ["a", "b", "d", "e", "c"] executed_names = [s.name for s in b.executedSteps] self.assertEqual(executed_names, expected_names) def testAddStepsAfterLastStep(self): b = self.build steps = self.create_mock_steps(["a", "b", "c"]) def startStepB(*args, **kw): new_steps = self.create_mock_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]) b.startBuild(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(b.result, 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_mock_steps(["clone", "command", "clean"]) b.setStepFactories([FakeStepFactory(s) for s in steps]) b.startBuild(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(b.result, 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_mock_steps(["stage", "stage", "stage"]) b.setStepFactories([FakeStepFactory(s) for s in steps]) b.startBuild(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(b.result, 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_mock_steps(["a", "b", "c"]) def startStepB(*args, **kw): new_steps = self.create_mock_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(FakeBuildStatus(), None, self.slavebuilder) self.assertEqual(b.result, SUCCESS) expected_names = ["a", "b", "c_1", "c_2", "c"] executed_names = [s.name for s in b.executedSteps] self.assertEqual(executed_names, expected_names)
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)
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): @implementer(interfaces.IProperties) class FakeProperties(Mock): pass 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 test_getProperty(self): self.build.getProperty('x') self.properties.getProperty.assert_called_with('x', None) def test_getProperty_default(self): self.build.getProperty('x', 'nox') self.properties.getProperty.assert_called_with('x', 'nox') def test_setProperty(self): self.build.setProperty('n', 'v', 's') self.properties.setProperty.assert_called_with('n', 'v', 's', runtime=True) def test_hasProperty(self): self.properties.hasProperty.return_value = True self.assertTrue(self.build.hasProperty('p')) self.properties.hasProperty.assert_called_with('p') def test_has_key(self): self.properties.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.properties.hasProperty.assert_called_with('p') def test_render(self): self.build.render("xyz") self.properties.render.assert_called_with("xyz") def test_getWorkerName_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.workerforbuilder = 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 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)
class TestBuildProperties(TestReactorMixin, 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): self.setUpTestReactor() @implementer(interfaces.IProperties) class FakeProperties(Mock): pass FakeProperties.render = Mock(side_effect=lambda x: x) FakeProperties.asList = Mock(side_effect=lambda: []) class FakeBuildStatus(Mock): pass r = FakeRequest() r.sources = [FakeSource()] r.sources[0].changes = [FakeChange()] r.sources[0].revision = "12345" self.master = fakemaster.make_master(self, wantData=True) 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(self, wantData=True)) self.build.setBuilder(self.builder) self.properties = self.build.properties = FakeProperties() self.build_status = FakeBuildStatus() self.build.startBuild(self.build_status, self.workerforbuilder) def test_getProperty(self): self.build.getProperty('x') self.properties.getProperty.assert_called_with('x', None) def test_getProperty_default(self): self.build.getProperty('x', 'nox') self.properties.getProperty.assert_called_with('x', 'nox') def test_setProperty(self): self.build.setProperty('n', 'v', 's') self.properties.setProperty.assert_called_with('n', 'v', 's', runtime=True) def test_hasProperty(self): self.properties.hasProperty.return_value = True self.assertTrue(self.build.hasProperty('p')) self.properties.hasProperty.assert_called_with('p') def test_has_key(self): self.properties.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.properties.hasProperty.assert_called_with('p') def test_render(self): self.build.render("xyz") self.properties.render.assert_called_with("xyz")