예제 #1
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):
        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")
예제 #2
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):
        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")
예제 #3
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")
예제 #4
0
class TestBuildProperties(unittest.TestCase):

    """
    Test that a Build has the necessary L{IProperties} methods, and that they
    properly delegate to the C{build_status} attribute - so really just a test
    of the L{IProperties} adapter.
    """

    def setUp(self):
        r = FakeRequest()
        r.sources = [FakeSource()]
        r.sources[0].changes = [FakeChange()]
        r.sources[0].revision = "12345"
        self.build = Build([r])
        self.build.setStepFactories([])
        self.builder = Mock()
        self.build.setBuilder(self.builder)
        self.build_status = FakeBuildStatus()
        self.build.startBuild(self.build_status, None, Mock())

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

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

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

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

    def test_has_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")
예제 #5
0
class TestBuild(unittest.TestCase):

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

        self.request = r
        self.master = fakemaster.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)
예제 #6
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)
예제 #7
0
class TestBuild(TestReactorMixin, unittest.TestCase):

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

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

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

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

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

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

    def testRunSuccessfulBuild(self):
        b = self.build

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

        b.startBuild(self.workerforbuilder)

        self.assertEqual(b.results, SUCCESS)

    def testStopBuild(self):
        b = self.build

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

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

        b.startBuild(self.workerforbuilder)

        self.assertEqual(b.results, CANCELLED)

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

    def test_build_retry_when_worker_substantiate_returns_false(self):
        b = self.build

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

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

    def test_build_cancelled_when_worker_substantiate_returns_false_due_to_cancel(self):
        b = self.build

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

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

    def test_build_retry_when_worker_substantiate_returns_false_due_to_cancel(self):
        b = self.build

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

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

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

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

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

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

        step2Started = [False]

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

        yield b.startBuild(self.workerforbuilder)

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

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

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

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

        step1.startStep = startStep

        yield b.startBuild(self.workerforbuilder)

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

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

        workerforbuilder1 = Mock()
        workerforbuilder2 = Mock()

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

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

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

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

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

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

    def testBuilddirPropType(self):

        b = self.build

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

        b.setupWorkerBuildirProperty(self.workerforbuilder)

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

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

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

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

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

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

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

        b.startBuild(self.workerforbuilder)

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

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

        eWorker = Mock()
        cWorker = Mock()

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

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

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

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

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

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

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

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

        realLock.release(fakeBuild, fakeBuildAccess)

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

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

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

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

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

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

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

        b.startBuild(self.workerforbuilder)

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

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

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

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

        yield b.setLocks([lock_access])

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

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

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

        b.startBuild(self.workerforbuilder)

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

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

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

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

        yield b.setLocks([lock_access])

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

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

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

        b.startBuild(self.workerforbuilder)

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

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

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

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

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

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

        gotLocks = [False]

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

        b.startBuild(self.workerforbuilder)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def test_getSummaryStatistic(self):
        b = self.build

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def testStepNamesDuplicate(self):
        b = self.build

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

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

    def testStepNamesDuplicateAfterAdd(self):
        b = self.build

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

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

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

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

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

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

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

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

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

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

        b.startBuild(self.workerforbuilder)

        self.assertEqual(get_active_builds(), 1)

        controller.finishStep(SUCCESS)

        self.assertEqual(get_active_builds(), 0)

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

        b.setStepFactories([FailingStepFactory()])

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

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

        b.startBuild(self.workerforbuilder)

        self.flushLoggedErrors(TestException)

        self.assertEqual(get_active_builds(), 0)
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)
예제 #9
0
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")