~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/buildmaster/tests/test_builder.py

[r=allenap, bac, gmb, julian-edwards, wallyworld][bug=905853, 905855,
 906079] In buildmaster,
 always shift into a read-write database transaction access mode before
 updating PackageBuild statuses. Shift into read-write transactions in
 appropriate places in TranslationTemplatesBuildBehavior. Ensure that all
 lp.buildmaster tests to which it is relevant are running with
 BuilddManagerTestFixture.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2009-2010 Canonical Ltd.  This software is licensed under the
 
1
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
2
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
3
 
4
4
"""Test Builder features."""
15
15
    AsynchronousDeferredRunTestForBrokenTwisted,
16
16
    SynchronousDeferredRunTest,
17
17
    )
 
18
import transaction
18
19
from twisted.internet.defer import (
19
20
    CancelledError,
20
21
    DeferredList,
45
46
    )
46
47
from lp.buildmaster.model.buildfarmjobbehavior import IdleBuildBehavior
47
48
from lp.buildmaster.model.buildqueue import BuildQueue
 
49
from lp.buildmaster.testing import BuilddManagerTestFixture
48
50
from lp.buildmaster.tests.mock_slaves import (
49
51
    AbortedSlave,
50
52
    AbortingSlave,
60
62
    TrivialBehavior,
61
63
    WaitingSlave,
62
64
    )
 
65
from lp.registry.interfaces.pocket import PackagePublishingPocket
63
66
from lp.services.config import config
64
67
from lp.services.database.sqlbase import flush_database_updates
65
68
from lp.services.job.interfaces.job import JobStatus
82
85
    TestCaseWithFactory,
83
86
    )
84
87
from lp.testing.fakemethod import FakeMethod
85
 
from lp.testing.layers import (
86
 
    DatabaseFunctionalLayer,
87
 
    LaunchpadZopelessLayer,
88
 
    )
 
88
from lp.testing.layers import LaunchpadZopelessLayer
89
89
 
90
90
 
91
91
class TestBuilderBasics(TestCaseWithFactory):
92
92
    """Basic unit tests for `Builder`."""
93
93
 
94
 
    layer = DatabaseFunctionalLayer
 
94
    layer = LaunchpadZopelessLayer
 
95
 
 
96
    def setUp(self):
 
97
        super(TestBuilderBasics, self).setUp()
 
98
        self.useFixture(BuilddManagerTestFixture())
95
99
 
96
100
    def test_providesInterface(self):
97
101
        # Builder provides IBuilder
98
 
        builder = self.factory.makeBuilder()
 
102
        with BuilddManagerTestFixture.extraSetUp():
 
103
            builder = self.factory.makeBuilder()
99
104
        self.assertProvides(builder, IBuilder)
100
105
 
101
106
    def test_default_values(self):
102
 
        builder = self.factory.makeBuilder()
 
107
        with BuilddManagerTestFixture.extraSetUp():
 
108
            builder = self.factory.makeBuilder()
103
109
        # Make sure the Storm cache gets the values that the database
104
110
        # initializes.
105
111
        flush_database_updates()
 
112
        self.useFixture(BuilddManagerTestFixture())
106
113
        self.assertEqual(0, builder.failure_count)
107
114
 
108
115
    def test_getCurrentBuildFarmJob(self):
109
 
        bq = self.factory.makeSourcePackageRecipeBuildJob(3333)
110
 
        builder = self.factory.makeBuilder()
111
 
        bq.markAsBuilding(builder)
 
116
        with BuilddManagerTestFixture.extraSetUp():
 
117
            bq = self.factory.makeSourcePackageRecipeBuildJob(3333)
 
118
            builder = self.factory.makeBuilder()
 
119
            bq.markAsBuilding(builder)
 
120
        self.useFixture(BuilddManagerTestFixture())
112
121
        self.assertEqual(
113
122
            bq, builder.getCurrentBuildFarmJob().buildqueue_record)
114
123
 
115
124
    def test_getBuildQueue(self):
116
 
        buildqueueset = getUtility(IBuildQueueSet)
117
 
        active_jobs = buildqueueset.getActiveBuildJobs()
118
 
        [active_job] = active_jobs
119
 
        builder = active_job.builder
 
125
        with BuilddManagerTestFixture.extraSetUp():
 
126
            buildqueueset = getUtility(IBuildQueueSet)
 
127
            active_jobs = buildqueueset.getActiveBuildJobs()
 
128
            [active_job] = active_jobs
 
129
            builder = active_job.builder
120
130
 
121
131
        bq = builder.getBuildQueue()
122
132
        self.assertEqual(active_job, bq)
123
133
 
124
 
        active_job.builder = None
 
134
        with BuilddManagerTestFixture.extraSetUp():
 
135
            active_job.builder = None
 
136
 
125
137
        bq = builder.getBuildQueue()
126
138
        self.assertIs(None, bq)
127
139
 
128
140
    def test_setting_builderok_resets_failure_count(self):
129
 
        builder = removeSecurityProxy(self.factory.makeBuilder())
130
 
        builder.failure_count = 1
131
 
        builder.builderok = False
 
141
        with BuilddManagerTestFixture.extraSetUp():
 
142
            builder = removeSecurityProxy(self.factory.makeBuilder())
 
143
            builder.failure_count = 1
 
144
            builder.builderok = False
 
145
 
132
146
        self.assertEqual(1, builder.failure_count)
133
 
        builder.builderok = True
 
147
 
 
148
        with BuilddManagerTestFixture.extraSetUp():
 
149
            builder.builderok = True
 
150
 
134
151
        self.assertEqual(0, builder.failure_count)
135
152
 
136
153
 
142
159
    def setUp(self):
143
160
        super(TestBuilder, self).setUp()
144
161
        self.slave_helper = self.useFixture(SlaveTestHelpers())
 
162
        self.useFixture(BuilddManagerTestFixture())
145
163
 
146
164
    def test_updateStatus_aborts_lost_and_broken_slave(self):
147
165
        # A slave that's 'lost' should be aborted; when the slave is
152
170
        d = lostbuilding_builder.updateStatus(BufferLogger())
153
171
        def check_slave_status(failure):
154
172
            self.assertIn('abort', slave.call_log)
155
 
            # 'Fault' comes from the LostBuildingBrokenSlave, this is
 
173
            # 'Fault' comes from the LostBuildingBrokenSlave.  This is
156
174
            # just testing that the value is passed through.
157
175
            self.assertIsInstance(failure.value, xmlrpclib.Fault)
158
176
        return d.addBoth(check_slave_status)
159
177
 
160
178
    def test_resumeSlaveHost_nonvirtual(self):
161
 
        builder = self.factory.makeBuilder(virtualized=False)
 
179
        with BuilddManagerTestFixture.extraSetUp():
 
180
            builder = self.factory.makeBuilder(virtualized=False)
162
181
        d = builder.resumeSlaveHost()
163
182
        return assert_fails_with(d, CannotResumeHost)
164
183
 
165
184
    def test_resumeSlaveHost_no_vmhost(self):
166
 
        builder = self.factory.makeBuilder(virtualized=True, vm_host=None)
 
185
        with BuilddManagerTestFixture.extraSetUp():
 
186
            builder = self.factory.makeBuilder(virtualized=True, vm_host=None)
167
187
        d = builder.resumeSlaveHost()
168
188
        return assert_fails_with(d, CannotResumeHost)
169
189
 
174
194
        config.push('reset', reset_config)
175
195
        self.addCleanup(config.pop, 'reset')
176
196
 
177
 
        builder = self.factory.makeBuilder(virtualized=True, vm_host="pop")
 
197
        with BuilddManagerTestFixture.extraSetUp():
 
198
            builder = self.factory.makeBuilder(
 
199
                virtualized=True, vm_host="pop")
178
200
        d = builder.resumeSlaveHost()
179
201
        def got_resume(output):
180
202
            self.assertEqual(('parp', ''), output)
186
208
            vm_resume_command: /bin/false"""
187
209
        config.push('reset fail', reset_fail_config)
188
210
        self.addCleanup(config.pop, 'reset fail')
189
 
        builder = self.factory.makeBuilder(virtualized=True, vm_host="pop")
 
211
        with BuilddManagerTestFixture.extraSetUp():
 
212
            builder = self.factory.makeBuilder(
 
213
                virtualized=True, vm_host="pop")
190
214
        d = builder.resumeSlaveHost()
191
215
        return assert_fails_with(d, CannotResumeHost)
192
216
 
196
220
            vm_resume_command: /bin/false"""
197
221
        config.push('reset fail', reset_fail_config)
198
222
        self.addCleanup(config.pop, 'reset fail')
199
 
        builder = self.factory.makeBuilder(virtualized=True, vm_host="pop")
200
 
        builder.builderok = True
 
223
        with BuilddManagerTestFixture.extraSetUp():
 
224
            builder = self.factory.makeBuilder(
 
225
                virtualized=True, vm_host="pop")
 
226
            builder.builderok = True
201
227
        d = builder.handleTimeout(BufferLogger(), 'blah')
202
228
        return assert_fails_with(d, CannotResumeHost)
203
229
 
 
230
    @BuilddManagerTestFixture.extraSetUp
204
231
    def _setupBuilder(self):
205
232
        processor = self.factory.makeProcessor(name="i386")
206
233
        builder = self.factory.makeBuilder(
215
242
        distroseries.nominatedarchindep = das
216
243
        return builder, distroseries, das
217
244
 
 
245
    @BuilddManagerTestFixture.extraSetUp
218
246
    def _setupRecipeBuildAndBuilder(self):
219
247
        # Helper function to make a builder capable of building a
220
248
        # recipe, returning both.
223
251
            distroseries=distroseries)
224
252
        return builder, build
225
253
 
 
254
    @BuilddManagerTestFixture.extraSetUp
226
255
    def _setupBinaryBuildAndBuilder(self):
227
256
        # Helper function to make a builder capable of building a
228
257
        # binary package, returning both.
235
264
        # findAndStartJob finds the next queued job using _findBuildCandidate.
236
265
        # We don't care about the type of build at all.
237
266
        builder, build = self._setupRecipeBuildAndBuilder()
238
 
        candidate = build.queueBuild()
 
267
        with BuilddManagerTestFixture.extraSetUp():
 
268
            candidate = build.queueBuild()
239
269
        # _findBuildCandidate is tested elsewhere, we just make sure that
240
270
        # findAndStartJob delegates to it.
241
271
        removeSecurityProxy(builder)._findBuildCandidate = FakeMethod(
248
278
        # and then starts it.
249
279
        # We don't care about the type of build at all.
250
280
        builder, build = self._setupRecipeBuildAndBuilder()
251
 
        candidate = build.queueBuild()
 
281
        with BuilddManagerTestFixture.extraSetUp():
 
282
            candidate = build.queueBuild()
252
283
        removeSecurityProxy(builder)._findBuildCandidate = FakeMethod(
253
284
            result=candidate)
254
285
        d = builder.findAndStartJob()
261
292
        # We need to send a ping to the builder to work around a bug
262
293
        # where sometimes the first network packet sent is dropped.
263
294
        builder, build = self._setupBinaryBuildAndBuilder()
264
 
        candidate = build.queueBuild()
 
295
        with BuilddManagerTestFixture.extraSetUp():
 
296
            candidate = build.queueBuild()
265
297
        removeSecurityProxy(builder)._findBuildCandidate = FakeMethod(
266
298
            result=candidate)
267
299
        d = builder.findAndStartJob()
274
306
        # Builder.slave is a BuilderSlave that points at the actual Builder.
275
307
        # The Builder is only ever used in scripts that run outside of the
276
308
        # security context.
277
 
        builder = removeSecurityProxy(self.factory.makeBuilder())
 
309
        with BuilddManagerTestFixture.extraSetUp():
 
310
            builder = removeSecurityProxy(self.factory.makeBuilder())
278
311
        self.assertEqual(builder.url, builder.slave.url)
279
312
 
280
313
    def test_recovery_of_aborted_virtual_slave(self):
319
352
        # rescueIfLost does not attempt to abort or clean a builder that is
320
353
        # WAITING.
321
354
        waiting_slave = WaitingSlave()
322
 
        builder = MockBuilder("mock_builder", waiting_slave, TrivialBehavior())
 
355
        builder = MockBuilder(
 
356
            "mock_builder", waiting_slave, TrivialBehavior())
323
357
        d = builder.rescueIfLost()
324
358
        def check_slave_calls(ignored):
325
359
            self.assertNotIn('abort', waiting_slave.call_log)
333
367
        # builder is reset for a new build, and the corrupt build is
334
368
        # discarded.
335
369
        waiting_slave = WaitingSlave()
336
 
        builder = MockBuilder("mock_builder", waiting_slave, CorruptBehavior())
 
370
        builder = MockBuilder(
 
371
            "mock_builder", waiting_slave, CorruptBehavior())
337
372
        d = builder.rescueIfLost()
338
373
        def check_slave_calls(ignored):
339
374
            self.assertNotIn('abort', waiting_slave.call_log)
344
379
        # rescueIfLost does not attempt to abort or clean a builder that is
345
380
        # BUILDING.
346
381
        building_slave = BuildingSlave()
347
 
        builder = MockBuilder("mock_builder", building_slave, TrivialBehavior())
 
382
        builder = MockBuilder(
 
383
            "mock_builder", building_slave, TrivialBehavior())
348
384
        d = builder.rescueIfLost()
349
385
        def check_slave_calls(ignored):
350
386
            self.assertNotIn('abort', building_slave.call_log)
355
391
        # If a slave is BUILDING with a build id we don't recognize, then we
356
392
        # abort the build, thus stopping it in its tracks.
357
393
        building_slave = BuildingSlave()
358
 
        builder = MockBuilder("mock_builder", building_slave, CorruptBehavior())
 
394
        builder = MockBuilder(
 
395
            "mock_builder", building_slave, CorruptBehavior())
359
396
        d = builder.rescueIfLost()
360
397
        def check_slave_calls(ignored):
361
398
            self.assertIn('abort', building_slave.call_log)
368
405
        # too so that we don't traceback when the wrong behaviour tries
369
406
        # to access a non-existent job.
370
407
        builder, build = self._setupBinaryBuildAndBuilder()
371
 
        candidate = build.queueBuild()
372
 
        building_slave = BuildingSlave()
373
 
        builder.setSlaveForTesting(building_slave)
374
 
        candidate.markAsBuilding(builder)
 
408
        with BuilddManagerTestFixture.extraSetUp():
 
409
            candidate = build.queueBuild()
 
410
            building_slave = BuildingSlave()
 
411
            builder.setSlaveForTesting(building_slave)
 
412
            candidate.markAsBuilding(builder)
375
413
 
376
414
        # At this point we should see a valid behaviour on the builder:
377
415
        self.assertFalse(
379
417
                builder.current_build_behavior, IdleBuildBehavior))
380
418
 
381
419
        # Now reset the job and try to rescue the builder.
382
 
        candidate.destroySelf()
383
 
        self.layer.txn.commit()
 
420
        with BuilddManagerTestFixture.extraSetUp():
 
421
            candidate.destroySelf()
384
422
        builder = getUtility(IBuilderSet)[builder.name]
385
423
        d = builder.rescueIfLost()
386
424
        def check_builder(ignored):
400
438
    def setUp(self):
401
439
        super(TestBuilderSlaveStatus, self).setUp()
402
440
        self.slave_helper = self.useFixture(SlaveTestHelpers())
 
441
        self.builder = self.factory.makeBuilder()
 
442
        self.useFixture(BuilddManagerTestFixture())
403
443
 
404
444
    def assertStatus(self, slave, builder_status=None,
405
445
                     build_status=None, logtail=False, filemap=None,
406
446
                     dependencies=None):
407
 
        builder = self.factory.makeBuilder()
408
 
        builder.setSlaveForTesting(slave)
409
 
        d = builder.slaveStatus()
 
447
        self.builder.setSlaveForTesting(slave)
 
448
        d = self.builder.slaveStatus()
410
449
 
411
450
        def got_status(status_dict):
412
451
            expected = {}
451
490
 
452
491
    def test_isAvailable_with_not_builderok(self):
453
492
        # isAvailable() is a wrapper around slaveStatusSentence()
454
 
        builder = self.factory.makeBuilder()
455
 
        builder.builderok = False
456
 
        d = builder.isAvailable()
 
493
        with BuilddManagerTestFixture.extraSetUp():
 
494
            self.builder.builderok = False
 
495
        d = self.builder.isAvailable()
457
496
        return d.addCallback(self.assertFalse)
458
497
 
459
498
    def test_isAvailable_with_slave_fault(self):
460
 
        builder = self.factory.makeBuilder()
461
 
        builder.setSlaveForTesting(BrokenSlave())
462
 
        d = builder.isAvailable()
 
499
        self.builder.setSlaveForTesting(BrokenSlave())
 
500
        d = self.builder.isAvailable()
463
501
        return d.addCallback(self.assertFalse)
464
502
 
465
503
    def test_isAvailable_with_slave_idle(self):
466
 
        builder = self.factory.makeBuilder()
467
 
        builder.setSlaveForTesting(OkSlave())
468
 
        d = builder.isAvailable()
 
504
        self.builder.setSlaveForTesting(OkSlave())
 
505
        d = self.builder.isAvailable()
469
506
        return d.addCallback(self.assertTrue)
470
507
 
471
508
 
499
536
            builder.builderok = True
500
537
            builder.manual = False
501
538
 
 
539
        self.useFixture(BuilddManagerTestFixture())
 
540
 
502
541
 
503
542
class TestFindBuildCandidateGeneralCases(TestFindBuildCandidateBase):
504
543
    # Test usage of findBuildCandidate not specific to any archive type.
507
546
        # IBuilder._findBuildCandidate identifies if there are builds
508
547
        # for superseded source package releases in the queue and marks
509
548
        # the corresponding build record as SUPERSEDED.
510
 
        archive = self.factory.makeArchive()
511
 
        self.publisher.getPubSource(
512
 
            sourcename="gedit", status=PackagePublishingStatus.PUBLISHED,
513
 
            archive=archive).createMissingBuilds()
 
549
        with BuilddManagerTestFixture.extraSetUp():
 
550
            archive = self.factory.makeArchive()
 
551
            self.publisher.getPubSource(
 
552
                sourcename="gedit", status=PackagePublishingStatus.PUBLISHED,
 
553
                archive=archive).createMissingBuilds()
514
554
        old_candidate = removeSecurityProxy(
515
555
            self.frog_builder)._findBuildCandidate()
516
556
 
521
561
 
522
562
        # Now supersede the source package:
523
563
        publication = build.current_source_publication
524
 
        publication.status = PackagePublishingStatus.SUPERSEDED
 
564
        with BuilddManagerTestFixture.extraSetUp():
 
565
            publication.status = PackagePublishingStatus.SUPERSEDED
525
566
 
526
567
        # The candidate returned is now a different one:
527
568
        new_candidate = removeSecurityProxy(
531
572
        # And the old_candidate is superseded:
532
573
        self.assertEqual(BuildStatus.SUPERSEDED, build.status)
533
574
 
 
575
    def test_findBuildCandidate_postprocesses_in_read_write_policy(self):
 
576
        # _findBuildCandidate invokes BuildFarmJob.postprocessCandidate,
 
577
        # which may modify the database.  This happens in a read-write
 
578
        # transaction even if _findBuildCandidate itself runs in a
 
579
        # read-only transaction policy.
 
580
 
 
581
        # PackageBuildJob.postprocessCandidate will attempt to delete
 
582
        # security builds.
 
583
        with BuilddManagerTestFixture.extraSetUp():
 
584
            pub = self.publisher.getPubSource(
 
585
                sourcename="gedit", status=PackagePublishingStatus.PUBLISHED,
 
586
                archive=self.factory.makeArchive(),
 
587
                pocket=PackagePublishingPocket.SECURITY)
 
588
            pub.createMissingBuilds()
 
589
        removeSecurityProxy(self.frog_builder)._findBuildCandidate()
 
590
        # Passes without a "transaction is read-only" error...
 
591
        transaction.commit()
 
592
 
534
593
    def test_acquireBuildCandidate_marks_building(self):
535
594
        # acquireBuildCandidate() should call _findBuildCandidate and
536
595
        # mark the build as building.
537
 
        archive = self.factory.makeArchive()
538
 
        self.publisher.getPubSource(
539
 
            sourcename="gedit", status=PackagePublishingStatus.PUBLISHED,
540
 
            archive=archive).createMissingBuilds()
 
596
        with BuilddManagerTestFixture.extraSetUp():
 
597
            archive = self.factory.makeArchive()
 
598
            self.publisher.getPubSource(
 
599
                sourcename="gedit", status=PackagePublishingStatus.PUBLISHED,
 
600
                archive=archive).createMissingBuilds()
541
601
        candidate = removeSecurityProxy(
542
602
            self.frog_builder).acquireBuildCandidate()
543
603
        self.assertEqual(JobStatus.RUNNING, candidate.job.status)
567
627
            sourcename="gedit", status=PackagePublishingStatus.PUBLISHED,
568
628
            archive=self.ppa_joe).createMissingBuilds()
569
629
 
 
630
        self.useFixture(BuilddManagerTestFixture())
 
631
 
570
632
    def test_findBuildCandidate_first_build_started(self):
571
633
        # The allocation rule for PPA dispatching doesn't apply when
572
634
        # there's only one builder available.
579
641
 
580
642
        # If bob is in a failed state the joesppa build is still
581
643
        # returned.
582
 
        self.bob_builder.builderok = False
583
 
        self.bob_builder.manual = False
 
644
        with BuilddManagerTestFixture.extraSetUp():
 
645
            self.bob_builder.builderok = False
 
646
            self.bob_builder.manual = False
584
647
        next_job = removeSecurityProxy(
585
648
            self.frog_builder)._findBuildCandidate()
586
649
        build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(next_job)
592
655
    ppa_joe_private = False
593
656
    ppa_jim_private = False
594
657
 
 
658
    @BuilddManagerTestFixture.extraSetUp
595
659
    def _setBuildsBuildingForArch(self, builds_list, num_builds,
596
660
                                  archtag="i386"):
597
661
        """Helper function.
609
673
    def setUp(self):
610
674
        """Publish some builds for the test archive."""
611
675
        super(TestFindBuildCandidatePPABase, self).setUp()
 
676
        self.extraSetUp()
612
677
 
 
678
    @BuilddManagerTestFixture.extraSetUp
 
679
    def extraSetUp(self):
613
680
        # Create two PPAs and add some builds to each.
614
681
        self.ppa_joe = self.factory.makeArchive(
615
682
            name="joesppa", private=self.ppa_joe_private)
670
737
    def test_findBuildCandidate_first_build_finished(self):
671
738
        # When joe's first ppa build finishes, his fourth i386 build
672
739
        # will be the next build candidate.
673
 
        self.joe_builds[0].status = BuildStatus.FAILEDTOBUILD
 
740
        with BuilddManagerTestFixture.extraSetUp():
 
741
            self.joe_builds[0].status = BuildStatus.FAILEDTOBUILD
674
742
        next_job = removeSecurityProxy(self.builder4)._findBuildCandidate()
675
743
        build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(next_job)
676
744
        self.failUnlessEqual('joesppa', build.archive.name)
678
746
    def test_findBuildCandidate_with_disabled_archive(self):
679
747
        # Disabled archives should not be considered for dispatching
680
748
        # builds.
681
 
        disabled_job = removeSecurityProxy(self.builder4)._findBuildCandidate()
682
 
        build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(
683
 
            disabled_job)
684
 
        build.archive.disable()
 
749
        disabled_job = removeSecurityProxy(
 
750
            self.builder4)._findBuildCandidate()
 
751
        with BuilddManagerTestFixture.extraSetUp():
 
752
            build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(
 
753
                disabled_job)
 
754
            build.archive.disable()
685
755
        next_job = removeSecurityProxy(self.builder4)._findBuildCandidate()
686
756
        self.assertNotEqual(disabled_job, next_job)
687
757
 
701
771
        # dispatched because the builder has to fetch the source files
702
772
        # from the (password protected) repo area, not the librarian.
703
773
        pub = build.current_source_publication
704
 
        pub.status = PackagePublishingStatus.PENDING
 
774
        with BuilddManagerTestFixture.extraSetUp():
 
775
            pub.status = PackagePublishingStatus.PENDING
705
776
        candidate = removeSecurityProxy(self.builder4)._findBuildCandidate()
706
777
        self.assertNotEqual(next_job.id, candidate.id)
707
778
 
711
782
    def setUp(self):
712
783
        """Publish some builds for the test archive."""
713
784
        super(TestFindBuildCandidateDistroArchive, self).setUp()
 
785
        self.extraSetUp()
 
786
 
 
787
    @BuilddManagerTestFixture.extraSetUp
 
788
    def extraSetUp(self):
714
789
        # Create a primary archive and publish some builds for the
715
790
        # queue.
716
791
        self.non_ppa = self.factory.makeArchive(
726
801
    def test_findBuildCandidate_for_non_ppa(self):
727
802
        # Normal archives are not restricted to serial builds per
728
803
        # arch.
729
 
 
730
804
        next_job = removeSecurityProxy(
731
805
            self.frog_builder)._findBuildCandidate()
732
806
        build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(next_job)
735
809
 
736
810
        # Now even if we set the build building, we'll still get the
737
811
        # second non-ppa build for the same archive as the next candidate.
738
 
        build.status = BuildStatus.BUILDING
739
 
        build.builder = self.frog_builder
 
812
        with BuilddManagerTestFixture.extraSetUp():
 
813
            build.status = BuildStatus.BUILDING
 
814
            build.builder = self.frog_builder
740
815
        next_job = removeSecurityProxy(
741
816
            self.frog_builder)._findBuildCandidate()
742
817
        build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(next_job)
753
828
        self.assertEqual(self.gedit_build.buildqueue_record.lastscore, 2505)
754
829
        self.assertEqual(self.firefox_build.buildqueue_record.lastscore, 2505)
755
830
 
756
 
        recipe_build_job = self.factory.makeSourcePackageRecipeBuildJob(9999)
 
831
        with BuilddManagerTestFixture.extraSetUp():
 
832
            recipe_build_job = (
 
833
                self.factory.makeSourcePackageRecipeBuildJob(9999))
757
834
 
758
835
        self.assertEqual(recipe_build_job.lastscore, 9999)
759
836
 
767
844
    # These tests operate in a "recipe builds only" setting.
768
845
    # Please see also bug #507782.
769
846
 
 
847
    @BuilddManagerTestFixture.extraSetUp
770
848
    def clearBuildQueue(self):
771
849
        """Delete all `BuildQueue`, XXXJOb and `Job` instances."""
772
850
        store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
776
854
    def setUp(self):
777
855
        """Publish some builds for the test archive."""
778
856
        super(TestFindRecipeBuildCandidates, self).setUp()
 
857
        self.extraSetUp()
 
858
 
 
859
    @BuilddManagerTestFixture.extraSetUp
 
860
    def extraSetUp(self):
779
861
        # Create a primary archive and publish some builds for the
780
862
        # queue.
781
863
        self.non_ppa = self.factory.makeArchive(
821
903
 
822
904
        self.buildfarmjob = self.build.buildqueue_record.specific_job
823
905
 
 
906
        self.useFixture(BuilddManagerTestFixture())
 
907
 
824
908
    def test_idle_behavior_when_no_current_build(self):
825
909
        """We return an idle behavior when there is no behavior specified
826
910
        nor a current build.
841
925
        """The current behavior is set automatically from the current job."""
842
926
        # Set the builder attribute on the buildqueue record so that our
843
927
        # builder will think it has a current build.
844
 
        self.build.buildqueue_record.builder = self.builder
 
928
        with BuilddManagerTestFixture.extraSetUp():
 
929
            self.build.buildqueue_record.builder = self.builder
845
930
 
846
931
        self.assertIsInstance(
847
932
            self.builder.current_build_behavior, BinaryPackageBuildBehavior)
1134
1219
        super(TestSlaveWithLibrarian, self).setUp()
1135
1220
        self.slave_helper = self.useFixture(SlaveTestHelpers())
1136
1221
 
 
1222
        self.useFixture(BuilddManagerTestFixture())
 
1223
 
1137
1224
    def test_ensurepresent_librarian(self):
1138
1225
        # ensurepresent, when given an http URL for a file will download the
1139
1226
        # file from that URL and report that the file is present, and it was
1140
1227
        # downloaded.
1141
1228
 
1142
1229
        # Use the Librarian because it's a "convenient" web server.
1143
 
        lf = self.factory.makeLibraryFileAlias(
1144
 
            'HelloWorld.txt', content="Hello World")
1145
 
        self.layer.txn.commit()
 
1230
        with BuilddManagerTestFixture.extraSetUp():
 
1231
            lf = self.factory.makeLibraryFileAlias(
 
1232
                'HelloWorld.txt', content="Hello World")
1146
1233
        self.slave_helper.getServerSlave()
1147
1234
        slave = self.slave_helper.getClientSlave()
1148
1235
        d = slave.ensurepresent(
1155
1242
        # filename made from the sha1 of the content underneath the
1156
1243
        # 'filecache' directory.
1157
1244
        content = "Hello World"
1158
 
        lf = self.factory.makeLibraryFileAlias(
1159
 
            'HelloWorld.txt', content=content)
1160
 
        self.layer.txn.commit()
 
1245
        with BuilddManagerTestFixture.extraSetUp():
 
1246
            lf = self.factory.makeLibraryFileAlias(
 
1247
                'HelloWorld.txt', content=content)
1161
1248
        expected_url = '%s/filecache/%s' % (
1162
1249
            self.slave_helper.BASE_URL, lf.content.sha1)
1163
1250
        self.slave_helper.getServerSlave()
1183
1270
        def got_files(ignored):
1184
1271
            # Called back when getFiles finishes.  Make sure all the
1185
1272
            # content is as expected.
1186
 
            got_contents = []
1187
1273
            for sha1 in filemap:
1188
1274
                local_file = filemap[sha1]
1189
1275
                file = open(local_file)
1199
1285
        dl = []
1200
1286
        for content in contents:
1201
1287
            filename = content + '.txt'
1202
 
            lf = self.factory.makeLibraryFileAlias(filename, content=content)
 
1288
            with BuilddManagerTestFixture.extraSetUp():
 
1289
                lf = self.factory.makeLibraryFileAlias(
 
1290
                    filename, content=content)
1203
1291
            content_map[lf.content.sha1] = content
1204
1292
            fd, filemap[lf.content.sha1] = tempfile.mkstemp()
1205
1293
            self.addCleanup(os.remove, filemap[lf.content.sha1])
1206
 
            self.layer.txn.commit()
1207
1294
            d = slave.ensurepresent(lf.content.sha1, lf.http_url, "", "")
1208
1295
            dl.append(d)
1209
1296