18
18
from twisted.trial import unittest
19
from twisted.python import failure
20
19
from twisted.internet import defer
21
20
from buildbot import config
22
from buildbot.status import master
23
21
from buildbot.test.fake import fakedb, fakemaster
24
22
from buildbot.process import builder, factory
25
from buildbot.db import buildrequests
26
23
from buildbot.util import epoch2datetime
28
class TestBuilderBuildCreation(unittest.TestCase):
31
# a collection of rows that would otherwise clutter up every test
33
fakedb.SourceStampSet(id=21),
34
fakedb.SourceStamp(id=21, sourcestampsetid=21),
35
fakedb.Buildset(id=11, reason='because', sourcestampsetid=21),
38
def makeBuilder(self, patch_random=False, **config_kwargs):
25
class BuilderMixin(object):
26
def makeBuilder(self, name="bldr", patch_random=False, **config_kwargs):
39
27
"""Set up C{self.bldr}"""
40
self.bstatus = mock.Mock()
41
28
self.factory = factory.BuildFactory()
42
29
self.master = fakemaster.make_master()
43
30
# only include the necessary required config, plus user-requested
44
config_args = dict(name="bldr", slavename="slv", builddir="bdir",
31
config_args = dict(name=name, slavename="slv", builddir="bdir",
45
32
slavebuilddir="sbdir", factory=self.factory)
46
33
config_args.update(config_kwargs)
47
builder_config = config.BuilderConfig(**config_args)
48
self.bldr = builder.Builder(builder_config.name, _addServices=False)
34
self.builder_config = config.BuilderConfig(**config_args)
35
self.bldr = builder.Builder(self.builder_config.name, _addServices=False)
49
36
self.master.db = self.db = fakedb.FakeDBConnector(self)
50
37
self.bldr.master = self.master
51
38
self.bldr.botmaster = self.master.botmaster
90
99
@defer.inlineCallbacks
91
def test_stopService_flushes(self):
92
yield self.makeBuilder()
94
# just check that stopService calls this and waits
95
# for the deferred to fire
98
long_d = defer.Deferred()
99
long_d.addCallback(lambda _ : events.append('long_d'))
100
self.bldr.maybeStartBuild = lambda : long_d
102
stop_d = self.bldr.stopService()
103
stop_d.addCallback(lambda _ : events.append('stop_d'))
105
# nothing should have happened yet
106
self.assertEqual(events, [])
108
# finish the maybeStartBuild invocation..
109
long_d.callback(None)
113
# and then check that things happened in the right order
114
self.assertEqual(events, [ 'long_d', 'stop_d' ])
118
def do_test_maybeStartBuild(self, rows=[], exp_claims=[], exp_builds=[],
120
d = self.db.insertTestData(rows)
121
d.addCallback(lambda _ :
122
self.bldr.maybeStartBuild())
124
self.failIf(exp_fail)
125
self.db.buildrequests.assertMyClaims(exp_claims)
126
self.assertBuildsStarted(exp_builds)
133
@defer.inlineCallbacks
134
def test_maybeStartBuild_no_buildreqests(self):
135
yield self.makeBuilder()
136
self.setSlaveBuilders({'test-slave11':1})
137
yield self.do_test_maybeStartBuild(exp_claims=[], exp_builds=[])
139
@defer.inlineCallbacks
140
def test_maybeStartBuild_no_slavebuilders(self):
141
yield self.makeBuilder()
143
fakedb.BuildRequest(id=11, buildsetid=10, buildername="bldr"),
145
yield self.do_test_maybeStartBuild(rows=rows,
146
exp_claims=[], exp_builds=[])
148
@defer.inlineCallbacks
149
def test_maybeStartBuild_limited_by_slaves(self):
150
yield self.makeBuilder(mergeRequests=False)
152
self.setSlaveBuilders({'test-slave1':1})
153
rows = self.base_rows + [
154
fakedb.BuildRequest(id=10, buildsetid=11, buildername="bldr",
155
submitted_at=130000),
156
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr",
157
submitted_at=135000),
159
yield self.do_test_maybeStartBuild(rows=rows,
160
exp_claims=[10], exp_builds=[('test-slave1', [10])])
162
@defer.inlineCallbacks
163
def test_maybeStartBuild_limited_by_available_slaves(self):
164
yield self.makeBuilder(mergeRequests=False)
166
self.setSlaveBuilders({'test-slave1':0, 'test-slave2':1})
167
rows = self.base_rows + [
168
fakedb.BuildRequest(id=10, buildsetid=11, buildername="bldr",
169
submitted_at=130000),
170
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr",
171
submitted_at=135000),
173
yield self.do_test_maybeStartBuild(rows=rows,
174
exp_claims=[10], exp_builds=[('test-slave2', [10])])
176
@defer.inlineCallbacks
177
def test_maybeStartBuild_unlimited(self):
178
yield self.makeBuilder(mergeRequests=False, patch_random=True)
180
self.setSlaveBuilders({'test-slave1':1, 'test-slave2':1})
181
rows = self.base_rows + [
182
fakedb.BuildRequest(id=10, buildsetid=11, buildername="bldr",
183
submitted_at=130000),
184
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr",
185
submitted_at=135000),
187
yield self.do_test_maybeStartBuild(rows=rows,
189
exp_builds=[('test-slave2', [10]), ('test-slave1', [11])])
191
@defer.inlineCallbacks
192
def test_maybeStartBuild_limited_by_requests(self):
193
yield self.makeBuilder(mergeRequests=False, patch_random=True)
195
self.setSlaveBuilders({'test-slave1':1, 'test-slave2':1})
196
rows = self.base_rows + [
197
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr"),
199
yield self.do_test_maybeStartBuild(rows=rows,
200
exp_claims=[11], exp_builds=[('test-slave2', [11])])
202
@defer.inlineCallbacks
203
def test_maybeStartBuild_chooseSlave_None(self):
204
yield self.makeBuilder()
206
self.bldr._chooseSlave = lambda avail : defer.succeed(None)
207
self.setSlaveBuilders({'test-slave1':1, 'test-slave2':1})
208
rows = self.base_rows + [
209
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr"),
211
yield self.do_test_maybeStartBuild(rows=rows,
212
exp_claims=[], exp_builds=[])
214
@defer.inlineCallbacks
215
def test_maybeStartBuild_chooseSlave_bogus(self):
216
yield self.makeBuilder()
218
self.bldr._chooseSlave = lambda avail : defer.succeed(mock.Mock())
219
self.setSlaveBuilders({'test-slave1':1, 'test-slave2':1})
220
rows = self.base_rows + [
221
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr"),
223
yield self.do_test_maybeStartBuild(rows=rows,
224
exp_claims=[], exp_builds=[])
226
@defer.inlineCallbacks
227
def test_maybeStartBuild_chooseSlave_fails(self):
228
yield self.makeBuilder()
230
self.bldr._chooseSlave = lambda avail : defer.fail(RuntimeError("xx"))
231
self.setSlaveBuilders({'test-slave1':1, 'test-slave2':1})
232
rows = self.base_rows + [
233
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr"),
235
yield self.do_test_maybeStartBuild(rows=rows,
236
exp_claims=[], exp_builds=[], exp_fail=RuntimeError)
238
@defer.inlineCallbacks
239
def test_maybeStartBuild_chooseBuild_None(self):
240
yield self.makeBuilder()
242
self.bldr._chooseBuild = lambda reqs : defer.succeed(None)
243
self.setSlaveBuilders({'test-slave1':1, 'test-slave2':1})
244
rows = self.base_rows + [
245
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr"),
247
yield self.do_test_maybeStartBuild(rows=rows,
248
exp_claims=[], exp_builds=[])
250
@defer.inlineCallbacks
251
def test_maybeStartBuild_chooseBuild_bogus(self):
252
yield self.makeBuilder()
254
self.bldr._chooseBuild = lambda reqs : defer.succeed(mock.Mock())
255
self.setSlaveBuilders({'test-slave1':1, 'test-slave2':1})
256
rows = self.base_rows + [
257
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr"),
259
yield self.do_test_maybeStartBuild(rows=rows,
260
exp_claims=[], exp_builds=[])
262
@defer.inlineCallbacks
263
def test_maybeStartBuild_chooseBuild_fails(self):
264
yield self.makeBuilder(patch_random=True)
266
self.bldr._chooseBuild = lambda reqs : defer.fail(RuntimeError("xx"))
267
self.setSlaveBuilders({'test-slave1':1, 'test-slave2':1})
268
rows = self.base_rows + [
269
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr"),
271
yield self.do_test_maybeStartBuild(rows=rows,
272
exp_claims=[], exp_builds=[], exp_fail=RuntimeError)
274
@defer.inlineCallbacks
275
def test_maybeStartBuild_mergeRequests_fails(self):
276
yield self.makeBuilder(patch_random=True)
278
def _mergeRequests(breq, unclaimed_requests, mergeRequests_fn):
279
return defer.fail(RuntimeError("xx"))
280
self.bldr._mergeRequests = _mergeRequests
281
self.setSlaveBuilders({'test-slave1':1, 'test-slave2':1})
282
rows = self.base_rows + [
283
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr"),
285
yield self.do_test_maybeStartBuild(rows=rows,
286
exp_claims=[], exp_builds=[], exp_fail=RuntimeError)
288
@defer.inlineCallbacks
289
def test_maybeStartBuild_claim_race(self):
290
yield self.makeBuilder(patch_random=True)
292
# fake a race condition on the buildrequests table
293
old_claimBuildRequests = self.db.buildrequests.claimBuildRequests
294
def claimBuildRequests(brids):
295
# first, ensure this only happens the first time
296
self.db.buildrequests.claimBuildRequests = old_claimBuildRequests
297
# claim brid 10 for some other master
299
self.db.buildrequests.fakeClaimBuildRequest(10, 136000,
300
objectid=9999) # some other objectid
302
return defer.fail(buildrequests.AlreadyClaimedError())
303
self.db.buildrequests.claimBuildRequests = claimBuildRequests
305
self.setSlaveBuilders({'test-slave1':1, 'test-slave2':1})
306
rows = self.base_rows + [
307
fakedb.BuildRequest(id=10, buildsetid=11, buildername="bldr",
308
submitted_at=130000), # will turn out to be claimed!
309
fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr",
310
submitted_at=135000),
312
yield self.do_test_maybeStartBuild(rows=rows,
313
exp_claims=[11], exp_builds=[('test-slave2', [11])])
315
@defer.inlineCallbacks
316
100
def test_maybeStartBuild_builder_stopped(self):
317
101
yield self.makeBuilder()
322
106
# so we just hope this does not fail
323
107
yield self.bldr.stopService()
324
yield self.bldr.maybeStartBuild()
326
@defer.inlineCallbacks
327
def test_maybeStartBuild_merge_ordering(self):
328
yield self.makeBuilder(patch_random=True)
330
self.setSlaveBuilders({'bldr':1})
332
# based on the build in bug #2249
334
fakedb.SourceStampSet(id=1976),
335
fakedb.SourceStamp(id=1976, sourcestampsetid=1976),
336
fakedb.Buildset(id=1980, reason='scheduler', sourcestampsetid=1976,
337
submitted_at=1332024020.67792),
338
fakedb.BuildRequest(id=42880, buildsetid=1980,
339
submitted_at=1332024020.67792, buildername="bldr"),
341
fakedb.SourceStampSet(id=1977),
342
fakedb.SourceStamp(id=1977, sourcestampsetid=1977),
343
fakedb.Buildset(id=1981, reason='scheduler', sourcestampsetid=1977,
344
submitted_at=1332025495.19141),
345
fakedb.BuildRequest(id=42922, buildsetid=1981,
346
buildername="bldr", submitted_at=1332025495.19141),
348
yield self.do_test_maybeStartBuild(rows=rows,
349
exp_claims=[42880, 42922],
350
exp_builds=[('bldr', [42880, 42922])])
354
def do_test_chooseSlave(self, nextSlave, exp_choice=None, exp_fail=None):
355
slavebuilders = [ mock.Mock(name='sb%d' % i) for i in range(4) ]
357
d = self.makeBuilder(nextSlave=nextSlave)
358
d.addCallback(lambda _ : self.bldr._chooseSlave(slavebuilders))
360
self.assertIdentical(sb, slavebuilders[exp_choice])
363
d.addCallbacks(check, failed)
366
def test_chooseSlave_default(self):
367
self.patch(random, "choice", lambda lst : lst[2])
368
return self.do_test_chooseSlave(None, exp_choice=2)
370
def test_chooseSlave_nextSlave_simple(self):
371
def nextSlave(bldr, lst):
372
self.assertIdentical(bldr, self.bldr)
374
return self.do_test_chooseSlave(nextSlave, exp_choice=1)
376
def test_chooseSlave_nextSlave_deferred(self):
377
def nextSlave(bldr, lst):
378
self.assertIdentical(bldr, self.bldr)
379
return defer.succeed(lst[1])
380
return self.do_test_chooseSlave(nextSlave, exp_choice=1)
382
def test_chooseSlave_nextSlave_exception(self):
383
def nextSlave(bldr, lst):
385
return self.do_test_chooseSlave(nextSlave, exp_fail=RuntimeError)
387
def test_chooseSlave_nextSlave_failure(self):
388
def nextSlave(bldr, lst):
389
return defer.fail(failure.Failure(RuntimeError()))
390
return self.do_test_chooseSlave(nextSlave, exp_fail=RuntimeError)
394
def do_test_chooseBuild(self, nextBuild, exp_choice=None, exp_fail=None):
397
brdict = dict(brobj=mock.Mock(name='br%d' % n))
398
brdict['brobj'].brdict = brdict
400
requests = [ mkrq(i) for i in range(4) ]
402
d = self.makeBuilder(nextBuild=nextBuild)
403
d.addCallback(lambda _ : self.bldr._chooseBuild(requests))
405
self.assertIdentical(sb, requests[exp_choice])
408
d.addCallbacks(check, failed)
411
def test_chooseBuild_default(self):
412
"default chooses the first in the list, which should be the earliest"
413
return self.do_test_chooseBuild(None, exp_choice=0)
415
def test_chooseBuild_nextBuild_simple(self):
416
def nextBuild(bldr, lst):
417
self.assertIdentical(bldr, self.bldr)
419
return self.do_test_chooseBuild(nextBuild, exp_choice=3)
421
def test_chooseBuild_nextBuild_deferred(self):
422
def nextBuild(bldr, lst):
423
self.assertIdentical(bldr, self.bldr)
424
return defer.succeed(lst[2])
425
return self.do_test_chooseBuild(nextBuild, exp_choice=2)
427
def test_chooseBuild_nextBuild_exception(self):
428
def nextBuild(bldr, lst):
430
return self.do_test_chooseBuild(nextBuild, exp_fail=RuntimeError)
432
def test_chooseBuild_nextBuild_failure(self):
433
def nextBuild(bldr, lst):
434
return defer.fail(failure.Failure(RuntimeError()))
435
return self.do_test_chooseBuild(nextBuild, exp_fail=RuntimeError)
437
# _brdictToBuildRequest
439
@defer.inlineCallbacks
440
def test_brdictToBuildRequest(self):
108
started = yield self.bldr.maybeStartBuild(None, [])
109
self.assertEquals(started, False)
114
def _makeMocks(self):
117
buildrequest = mock.Mock()
119
buildrequests = [buildrequest]
120
return slave, buildrequests
122
@defer.inlineCallbacks
123
def test_maybeStartBuild(self):
441
124
yield self.makeBuilder()
443
# set up all of the data required for a BuildRequest object
444
yield self.db.insertTestData([
445
fakedb.SourceStampSet(id=234),
446
fakedb.SourceStamp(id=234,sourcestampsetid=234),
447
fakedb.Buildset(id=30, sourcestampsetid=234, reason='foo',
448
submitted_at=1300305712, results=-1),
449
fakedb.BuildRequest(id=19, buildsetid=30, buildername='bldr',
450
priority=13, submitted_at=1300305712, results=-1),
453
brdict = yield self.db.buildrequests.getBuildRequest(19)
454
br = yield self.bldr._brdictToBuildRequest(brdict)
456
# just check that the BuildRequest looks reasonable -
457
# test_process_buildrequest checks the whole thing
458
self.assertEqual(br.reason, 'foo')
460
# and check that the cross-pointers are correct
461
self.assertIdentical(br.brdict, brdict)
462
self.assertIdentical(brdict['brobj'], br)
464
self.bldr._breakBrdictRefloops([brdict])
466
# _getMergeRequestsFn
126
slave, buildrequests = self._makeMocks()
128
started = yield self.bldr.maybeStartBuild(slave, buildrequests)
129
self.assertEqual(started, True)
130
self.assertBuildsStarted([('slave', [10])])
132
@defer.inlineCallbacks
133
def test_maybeStartBuild_failsToStart(self):
134
yield self.makeBuilder(startBuildsForSucceeds=False)
136
slave, buildrequests = self._makeMocks()
138
started = yield self.bldr.maybeStartBuild(slave, buildrequests)
139
self.assertEqual(started, False)
140
self.assertBuildsStarted([('slave', [10])])
468
142
@defer.inlineCallbacks
469
143
def do_test_getMergeRequestsFn(self, builder_param=None,
509
183
def test_getMergeRequestsFn_builder_function(self):
510
184
self.do_test_getMergeRequestsFn('callable', None, 'callable')
514
@defer.inlineCallbacks
515
def test_mergeRequests(self):
516
yield self.makeBuilder()
518
# set up all of the data required for a BuildRequest object
519
yield self.db.insertTestData([
520
fakedb.SourceStampSet(id=234),
521
fakedb.SourceStamp(id=234, sourcestampsetid=234),
522
fakedb.Buildset(id=30, sourcestampsetid=234, reason='foo',
523
submitted_at=1300305712, results=-1),
524
fakedb.BuildRequest(id=19, buildsetid=30, buildername='bldr',
525
priority=13, submitted_at=1300305712, results=-1),
526
fakedb.BuildRequest(id=20, buildsetid=30, buildername='bldr',
527
priority=13, submitted_at=1300305712, results=-1),
528
fakedb.BuildRequest(id=21, buildsetid=30, buildername='bldr',
529
priority=13, submitted_at=1300305712, results=-1),
532
brdicts = yield defer.gatherResults([
533
self.db.buildrequests.getBuildRequest(id)
534
for id in (19, 20, 21)
537
def mergeRequests_fn(builder, breq, other):
538
# merge evens with evens, odds with odds
539
return breq.id % 2 == other.id % 2
542
odds = yield self.bldr._mergeRequests(brdicts[0],
543
brdicts, mergeRequests_fn)
544
self.assertEqual(odds, [ brdicts[0], brdicts[2] ])
547
evens = yield self.bldr._mergeRequests(brdicts[1],
548
brdicts, mergeRequests_fn)
549
self.assertEqual(evens, [ brdicts[1] ])
551
# check original relative order of requests within brdicts is maintained
552
merged = yield self.bldr._mergeRequests(brdicts[2],
553
brdicts, mergeRequests_fn)
554
self.assertEqual(merged, [brdicts[0], brdicts[2]],
555
'relative order of merged requests was not maintained')
557
@defer.inlineCallbacks
558
def test_mergeRequest_no_other_request(self):
559
""" Test if builder test for codebases in requests """
560
yield self.makeBuilder()
562
# set up all of the data required for a BuildRequest object
563
yield self.db.insertTestData([
564
fakedb.SourceStampSet(id=234),
565
fakedb.SourceStamp(id=234, sourcestampsetid=234, codebase='A'),
566
fakedb.Change(changeid=14, codebase='A'),
567
fakedb.SourceStampChange(sourcestampid=234, changeid=14),
568
fakedb.Buildset(id=30, sourcestampsetid=234, reason='foo',
569
submitted_at=1300305712, results=-1),
570
fakedb.BuildRequest(id=19, buildsetid=30, buildername='bldr',
571
priority=13, submitted_at=1300305712, results=-1),
574
brdicts = yield defer.gatherResults([
575
self.db.buildrequests.getBuildRequest(19)
578
def mergeRequests_fn(builder, breq, other):
582
# check if the request remains the same
583
res = yield self.bldr._mergeRequests(brdicts[0], brdicts,
585
self.assertEqual(res, [ brdicts[0] ])
587
@defer.inlineCallbacks
588
def test_mergeRequests_codebases_equal(self):
589
""" Test if builder test for codebases in requests """
590
yield self.makeBuilder()
592
# set up all of the data required for a BuildRequest object
593
yield self.db.insertTestData([
594
fakedb.SourceStampSet(id=234),
595
fakedb.SourceStamp(id=234, sourcestampsetid=234, codebase='A'),
596
fakedb.Buildset(id=30, sourcestampsetid=234, reason='foo',
597
submitted_at=1300305712, results=-1),
598
fakedb.SourceStampSet(id=235),
599
fakedb.SourceStamp(id=235, sourcestampsetid=235, codebase='A'),
600
fakedb.Buildset(id=31, sourcestampsetid=235, reason='foo',
601
submitted_at=1300305712, results=-1),
602
fakedb.SourceStampSet(id=236),
603
fakedb.SourceStamp(id=236, sourcestampsetid=236, codebase='A'),
604
fakedb.Buildset(id=32, sourcestampsetid=236, reason='foo',
605
submitted_at=1300305712, results=-1),
606
fakedb.BuildRequest(id=19, buildsetid=30, buildername='bldr',
607
priority=13, submitted_at=1300305712, results=-1),
608
fakedb.BuildRequest(id=20, buildsetid=31, buildername='bldr',
609
priority=13, submitted_at=1300305712, results=-1),
610
fakedb.BuildRequest(id=21, buildsetid=32, buildername='bldr',
611
priority=13, submitted_at=1300305712, results=-1),
614
brdicts = yield defer.gatherResults([
615
self.db.buildrequests.getBuildRequest(id)
616
for id in (19, 20, 21)
619
def mergeRequests_fn(builder, breq, other):
620
# Allow all requests to test builder functionality
623
# check if all are merged
624
res = yield self.bldr._mergeRequests(brdicts[0], brdicts,
626
self.assertEqual(res, [ brdicts[0], brdicts[1], brdicts[2] ])
628
@defer.inlineCallbacks
629
def test_mergeRequests_no_merging(self):
630
yield self.makeBuilder()
633
merged = yield self.bldr._mergeRequests(breq, [ breq, breq ], None)
635
self.assertEqual(merged, [breq])
637
@defer.inlineCallbacks
638
def test_mergeRequests_singleton_list(self):
639
yield self.makeBuilder()
642
def is_not_called(*args):
643
self.fail("should not be called")
644
self.bldr._brdictToBuildRequest = is_not_called
646
merged = yield self.bldr._mergeRequests(breq, [ breq ],
649
self.assertEqual(merged, [breq])
686
222
self.assertEqual(claims, [ (set([10,11,12,15]),) ])
688
class TestGetOldestRequestTime(unittest.TestCase):
224
@defer.inlineCallbacks
225
def test_canStartBuild(self):
226
yield self.makeBuilder()
228
# by default, it returns True
229
startable = yield self.bldr.canStartBuild('slave', 100)
230
self.assertEqual(startable, True)
232
startable = yield self.bldr.canStartBuild('slave', 101)
233
self.assertEqual(startable, True)
235
# set a configurable one
237
def canStartBuild(bldr, slave, breq):
238
record.append((bldr, slave, breq))
239
return (slave,breq)==('slave',100)
240
self.bldr.config.canStartBuild = canStartBuild
242
startable = yield self.bldr.canStartBuild('slave', 100)
243
self.assertEqual(startable, True)
244
self.assertEqual(record, [(self.bldr, 'slave', 100)])
246
startable = yield self.bldr.canStartBuild('slave', 101)
247
self.assertEqual(startable, False)
248
self.assertEqual(record, [(self.bldr, 'slave', 100), (self.bldr, 'slave', 101)])
250
# set a configurable one to return Deferred
252
def canStartBuild_deferred(bldr, slave, breq):
253
record.append((bldr, slave, breq))
254
return (slave,breq)==('slave',100)
255
return defer.succeed((slave,breq)==('slave',100))
256
self.bldr.config.canStartBuild = canStartBuild_deferred
258
startable = yield self.bldr.canStartBuild('slave', 100)
259
self.assertEqual(startable, True)
260
self.assertEqual(record, [(self.bldr, 'slave', 100)])
262
startable = yield self.bldr.canStartBuild('slave', 101)
263
self.assertEqual(startable, False)
264
self.assertEqual(record, [(self.bldr, 'slave', 100), (self.bldr, 'slave', 101)])
266
@defer.inlineCallbacks
267
def test_enforceChosenSlave(self):
268
"""enforceChosenSlave rejects and accepts builds"""
269
yield self.makeBuilder()
271
self.bldr.config.canStartBuild = builder.enforceChosenSlave
274
slave.slave.slavename = 'slave5'
278
# no buildslave requested
280
result = yield self.bldr.canStartBuild(slave, breq)
281
self.assertIdentical(True, result)
283
# buildslave requested as the right one
284
breq.properties = { 'slavename': 'slave5' }
285
result = yield self.bldr.canStartBuild(slave, breq)
286
self.assertIdentical(True, result)
288
# buildslave requested as the wrong one
289
breq.properties = { 'slavename': 'slave4' }
290
result = yield self.bldr.canStartBuild(slave, breq)
291
self.assertIdentical(False, result)
293
# buildslave set to non string value gets skipped
294
breq.properties = { 'slavename': 0 }
295
result = yield self.bldr.canStartBuild(slave, breq)
296
self.assertIdentical(True, result)
301
class TestGetOldestRequestTime(BuilderMixin, unittest.TestCase):
691
304
# a collection of rows that would otherwise clutter up every test
745
339
d.addCallback(check)
748
class TestRebuild(unittest.TestCase):
342
class TestRebuild(BuilderMixin, unittest.TestCase):
750
344
def makeBuilder(self, name, sourcestamps):
751
self.bstatus = mock.Mock()
752
bstatus_properties = mock.Mock()
753
bstatus_properties.properties = {}
754
self.bstatus.getProperties.return_value = bstatus_properties
755
self.bstatus.getSourceStamps.return_value = sourcestamps
756
self.factory = factory.BuildFactory()
757
self.master = fakemaster.make_master()
758
# only include the necessary required config
759
builder_config = config.BuilderConfig(
760
name=name, slavename="slv", builddir="bdir",
761
slavebuilddir="sbdir", factory=self.factory)
762
self.bldr = builder.Builder(builder_config.name)
763
self.master.db = self.db = fakedb.FakeDBConnector(self)
764
self.bldr.master = self.master
765
self.master.addBuildset = addBuildset = mock.Mock()
766
addBuildset.return_value = (1, [100])
345
d = BuilderMixin.makeBuilder(self, name=name)
348
self.bstatus = mock.Mock()
349
bstatus_properties = mock.Mock()
350
bstatus_properties.properties = {}
351
self.bstatus.getProperties.return_value = bstatus_properties
352
self.bstatus.getSourceStamps.return_value = sourcestamps
353
self.master.addBuildset = addBuildset = mock.Mock()
354
addBuildset.return_value = (1, [100])
357
@defer.inlineCallbacks
768
358
def do_test_rebuild(self,
769
359
sourcestampsetid,
770
360
nr_of_sourcestamps):