~launchpad-pqm/launchpad/devel

11573.3.16 by Jonathan Lange
Add the first attempt at an integration test for the binary package build behaviour.
1
# Copyright 2010 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4
"""Tests for BinaryPackageBuildBehavior."""
5
6
__metaclass__ = type
7
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
8
import gzip
9
import os
11818.1.1 by Julian Edwards
Remove leftover builddmaster.root directory so we don't break test isolation.
10
import shutil
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
11
import tempfile
11583.3.4 by Jonathan Lange
Review changes.
12
import transaction
13
11705.2.16 by Jonathan Lange
And so it goes.
14
from testtools.deferredruntest import (
15
    AsynchronousDeferredRunTest,
16
    )
17
12019.10.2 by Julian Edwards
Fix test busted by the change, which was depending on removed sources.
18
from storm.store import Store
19
11583.3.1 by Jonathan Lange
Bust up buildd-slavescanner.txt and move it into unit tests.
20
from twisted.internet import defer
11573.3.17 by Jonathan Lange
Make the test actually execute properly, but not actually assert anything. Actually.
21
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
22
from zope.component import getUtility
11573.3.16 by Jonathan Lange
Add the first attempt at an integration test for the binary package build behaviour.
23
from zope.security.proxy import removeSecurityProxy
24
11818.1.1 by Julian Edwards
Remove leftover builddmaster.root directory so we don't break test isolation.
25
from canonical.config import config
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
26
from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
11705.2.16 by Jonathan Lange
And so it goes.
27
from canonical.testing.layers import LaunchpadZopelessLayer
11573.3.16 by Jonathan Lange
Add the first attempt at an integration test for the binary package build behaviour.
28
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
29
from lp.buildmaster.enums import (
30
    BuildStatus,
31
    )
32
from lp.buildmaster.tests.mock_slaves import (
33
    AbortedSlave,
34
    AbortingSlave,
35
    BuildingSlave,
36
    OkSlave,
37
    WaitingSlave,
38
    )
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
39
from lp.registry.interfaces.pocket import (
40
    PackagePublishingPocket,
41
    pocketsuffix,
42
    )
43
from lp.registry.interfaces.series import SeriesStatus
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
44
from lp.services.job.interfaces.job import JobStatus
12070.1.4 by Tim Penhey
Move FakeLogger and BufferLogger to lp.services.log.logging and delete the QuietFakeLogger.
45
from lp.services.log.logger import BufferLogger
11573.3.18 by Jonathan Lange
Move the first of the crazy buildd-slavescanner.txt behaviour testing examples
46
from lp.soyuz.adapters.archivedependencies import (
47
    get_sources_list_for_building,
48
    )
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
49
from lp.soyuz.enums import (
50
    ArchivePurpose,
51
    )
11705.2.24 by Jonathan Lange
Clean up a bunch of stuff that I didn't actually need
52
from lp.testing import TestCaseWithFactory
11705.2.16 by Jonathan Lange
And so it goes.
53
54
55
class TestBinaryBuildPackageBehavior(TestCaseWithFactory):
11573.3.18 by Jonathan Lange
Move the first of the crazy buildd-slavescanner.txt behaviour testing examples
56
    """Tests for the BinaryPackageBuildBehavior.
57
58
    In particular, these tests are about how the BinaryPackageBuildBehavior
59
    interacts with the build slave.  We test this by using a test double that
60
    implements the same interface as `BuilderSlave` but instead of actually
61
    making XML-RPC calls, just records any method invocations along with
62
    interesting parameters.
63
    """
11573.3.16 by Jonathan Lange
Add the first attempt at an integration test for the binary package build behaviour.
64
11705.2.16 by Jonathan Lange
And so it goes.
65
    layer = LaunchpadZopelessLayer
66
    run_tests_with = AsynchronousDeferredRunTest
11573.3.16 by Jonathan Lange
Add the first attempt at an integration test for the binary package build behaviour.
67
68
    def setUp(self):
69
        super(TestBinaryBuildPackageBehavior, self).setUp()
70
        self.layer.switchDbUser('testadmin')
71
11583.3.4 by Jonathan Lange
Review changes.
72
    def assertExpectedInteraction(self, ignored, call_log, builder, build,
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
73
                                  chroot, archive, archive_purpose,
74
                                  component=None, extra_urls=None,
75
                                  filemap_names=None):
11583.3.4 by Jonathan Lange
Review changes.
76
        expected = self.makeExpectedInteraction(
77
            builder, build, chroot, archive, archive_purpose, component,
78
            extra_urls, filemap_names)
79
        self.assertEqual(call_log, expected)
80
81
    def makeExpectedInteraction(self, builder, build, chroot, archive,
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
82
                                archive_purpose, component=None,
11583.3.4 by Jonathan Lange
Review changes.
83
                                extra_urls=None, filemap_names=None):
84
        """Build the log of calls that we expect to be made to the slave.
85
11573.3.18 by Jonathan Lange
Move the first of the crazy buildd-slavescanner.txt behaviour testing examples
86
        :param builder: The builder we are using to build the binary package.
87
        :param build: The build being done on the builder.
88
        :param chroot: The `LibraryFileAlias` for the chroot in which we are
89
            building.
90
        :param archive: The `IArchive` into which we are building.
91
        :param archive_purpose: The ArchivePurpose we are sending to the
92
            builder. We specify this separately from the archive because
93
            sometimes the behavior object has to give a different purpose
94
            in order to trick the slave into building correctly.
11583.3.4 by Jonathan Lange
Review changes.
95
        :return: A list of the calls we expect to be made.
11573.3.18 by Jonathan Lange
Move the first of the crazy buildd-slavescanner.txt behaviour testing examples
96
        """
97
        job = removeSecurityProxy(builder.current_build_behavior).buildfarmjob
98
        build_id = job.generateSlaveBuildCookie()
99
        ds_name = build.distro_arch_series.distroseries.name
100
        suite = ds_name + pocketsuffix[build.pocket]
101
        archives = get_sources_list_for_building(
102
            build, build.distro_arch_series,
103
            build.source_package_release.name)
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
104
        arch_indep = build.distro_arch_series.isNominatedArchIndep
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
105
        if component is None:
106
            component = build.current_component.name
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
107
        if filemap_names is None:
108
            filemap_names = []
109
        if extra_urls is None:
110
            extra_urls = []
111
11583.3.4 by Jonathan Lange
Review changes.
112
        upload_logs = [
11583.3.5 by Jonathan Lange
Change the OkSlave to log less about cacheFile & sendFileToSlave,
113
            ('ensurepresent', url, '', '')
11583.3.4 by Jonathan Lange
Review changes.
114
            for url in [chroot.http_url] + extra_urls]
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
115
11583.3.4 by Jonathan Lange
Review changes.
116
        extra_args = {
117
            'arch_indep': arch_indep,
118
            'arch_tag': build.distro_arch_series.architecturetag,
119
            'archive_private': archive.private,
120
            'archive_purpose': archive_purpose.name,
121
            'archives': archives,
122
            'build_debug_symbols': archive.build_debug_symbols,
123
            'ogrecomponent': component,
124
            'suite': suite,
125
            }
126
        build_log = [
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
127
            ('build', build_id, 'binarypackage', chroot.content.sha1,
11583.3.4 by Jonathan Lange
Review changes.
128
             filemap_names, extra_args)]
11981.1.4 by Julian Edwards
Fix another failing test
129
        if builder.virtualized:
130
            result = [('echo', 'ping')] + upload_logs + build_log
131
        else:
132
            result = upload_logs + build_log
133
        return result
11573.3.18 by Jonathan Lange
Move the first of the crazy buildd-slavescanner.txt behaviour testing examples
134
11583.3.1 by Jonathan Lange
Bust up buildd-slavescanner.txt and move it into unit tests.
135
    def startBuild(self, builder, candidate):
136
        builder = removeSecurityProxy(builder)
137
        candidate = removeSecurityProxy(candidate)
138
        return defer.maybeDeferred(
12070.1.4 by Tim Penhey
Move FakeLogger and BufferLogger to lp.services.log.logging and delete the QuietFakeLogger.
139
            builder.startBuild, candidate, BufferLogger())
11583.3.1 by Jonathan Lange
Bust up buildd-slavescanner.txt and move it into unit tests.
140
11573.3.18 by Jonathan Lange
Move the first of the crazy buildd-slavescanner.txt behaviour testing examples
141
    def test_non_virtual_ppa_dispatch(self):
142
        # When the BinaryPackageBuildBehavior dispatches PPA builds to
143
        # non-virtual builders, it stores the chroot on the server and
144
        # requests a binary package build, lying to say that the archive
145
        # purpose is "PRIMARY" because this ensures that the package mangling
146
        # tools will run over the built packages.
11573.3.16 by Jonathan Lange
Add the first attempt at an integration test for the binary package build behaviour.
147
        archive = self.factory.makeArchive(virtualized=False)
11573.3.18 by Jonathan Lange
Move the first of the crazy buildd-slavescanner.txt behaviour testing examples
148
        slave = OkSlave()
11573.3.16 by Jonathan Lange
Add the first attempt at an integration test for the binary package build behaviour.
149
        builder = self.factory.makeBuilder(virtualized=False)
150
        builder.setSlaveForTesting(slave)
151
        build = self.factory.makeBinaryPackageBuild(
152
            builder=builder, archive=archive)
153
        lf = self.factory.makeLibraryFileAlias()
11583.3.4 by Jonathan Lange
Review changes.
154
        transaction.commit()
11573.3.16 by Jonathan Lange
Add the first attempt at an integration test for the binary package build behaviour.
155
        build.distro_arch_series.addOrUpdateChroot(lf)
156
        candidate = build.queueBuild()
11583.3.1 by Jonathan Lange
Bust up buildd-slavescanner.txt and move it into unit tests.
157
        d = self.startBuild(builder, candidate)
11573.3.18 by Jonathan Lange
Move the first of the crazy buildd-slavescanner.txt behaviour testing examples
158
        d.addCallback(
11583.3.4 by Jonathan Lange
Review changes.
159
            self.assertExpectedInteraction, slave.call_log,
160
            builder, build, lf, archive, ArchivePurpose.PRIMARY, 'universe')
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
161
        return d
162
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
163
    def test_virtual_ppa_dispatch(self):
164
        # Make sure the builder slave gets reset before a build is
165
        # dispatched to it.
166
        archive = self.factory.makeArchive(virtualized=True)
167
        slave = OkSlave()
168
        builder = self.factory.makeBuilder(
169
            virtualized=True, vm_host="foohost")
170
        builder.setSlaveForTesting(slave)
171
        build = self.factory.makeBinaryPackageBuild(
172
            builder=builder, archive=archive)
173
        lf = self.factory.makeLibraryFileAlias()
174
        transaction.commit()
175
        build.distro_arch_series.addOrUpdateChroot(lf)
176
        candidate = build.queueBuild()
177
        d = self.startBuild(builder, candidate)
178
        def check_build(ignored):
179
            # We expect the first call to the slave to be a resume call,
180
            # followed by the rest of the usual calls we expect.
181
            expected_resume_call = slave.call_log.pop(0)
182
            self.assertEqual('resume', expected_resume_call)
183
            self.assertExpectedInteraction(
184
                ignored, slave.call_log,
185
                builder, build, lf, archive, ArchivePurpose.PPA)
186
        return d.addCallback(check_build)
187
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
188
    def test_partner_dispatch_no_publishing_history(self):
189
        archive = self.factory.makeArchive(
190
            virtualized=False, purpose=ArchivePurpose.PARTNER)
191
        slave = OkSlave()
192
        builder = self.factory.makeBuilder(virtualized=False)
193
        builder.setSlaveForTesting(slave)
194
        build = self.factory.makeBinaryPackageBuild(
195
            builder=builder, archive=archive)
196
        lf = self.factory.makeLibraryFileAlias()
11583.3.4 by Jonathan Lange
Review changes.
197
        transaction.commit()
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
198
        build.distro_arch_series.addOrUpdateChroot(lf)
199
        candidate = build.queueBuild()
11583.3.1 by Jonathan Lange
Bust up buildd-slavescanner.txt and move it into unit tests.
200
        d = self.startBuild(builder, candidate)
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
201
        d.addCallback(
11583.3.4 by Jonathan Lange
Review changes.
202
            self.assertExpectedInteraction, slave.call_log,
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
203
            builder, build, lf, archive, ArchivePurpose.PARTNER)
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
204
        return d
205
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
206
    def test_dont_dispatch_release_builds(self):
207
        archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
208
        builder = self.factory.makeBuilder()
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
209
        distroseries = self.factory.makeDistroSeries(
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
210
            status=SeriesStatus.CURRENT, distribution=archive.distribution)
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
211
        distro_arch_series = self.factory.makeDistroArchSeries(
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
212
            distroseries=distroseries)
213
        build = self.factory.makeBinaryPackageBuild(
214
            builder=builder, archive=archive,
215
            distroarchseries=distro_arch_series,
216
            pocket=PackagePublishingPocket.RELEASE)
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
217
        lf = self.factory.makeLibraryFileAlias()
11583.3.4 by Jonathan Lange
Review changes.
218
        transaction.commit()
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
219
        build.distro_arch_series.addOrUpdateChroot(lf)
220
        candidate = build.queueBuild()
221
        behavior = candidate.required_build_behavior
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
222
        behavior.setBuilder(builder)
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
223
        e = self.assertRaises(
12070.1.4 by Tim Penhey
Move FakeLogger and BufferLogger to lp.services.log.logging and delete the QuietFakeLogger.
224
            AssertionError, behavior.verifyBuildRequest, BufferLogger())
11583.3.4 by Jonathan Lange
Review changes.
225
        expected_message = (
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
226
            "%s (%s) can not be built for pocket %s: invalid pocket due "
227
            "to the series status of %s." % (
228
                build.title, build.id, build.pocket.name,
11583.3.4 by Jonathan Lange
Review changes.
229
                build.distro_series.name))
230
        self.assertEqual(expected_message, str(e))
11573.3.19 by Jonathan Lange
Move more tests to unit test style.
231
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
232
    def test_dont_dispatch_security_builds(self):
233
        archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY)
234
        builder = self.factory.makeBuilder()
235
        build = self.factory.makeBinaryPackageBuild(
236
            builder=builder, archive=archive,
237
            pocket=PackagePublishingPocket.SECURITY)
238
        lf = self.factory.makeLibraryFileAlias()
11583.3.4 by Jonathan Lange
Review changes.
239
        transaction.commit()
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
240
        build.distro_arch_series.addOrUpdateChroot(lf)
241
        candidate = build.queueBuild()
242
        behavior = candidate.required_build_behavior
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
243
        behavior.setBuilder(builder)
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
244
        e = self.assertRaises(
12070.1.4 by Tim Penhey
Move FakeLogger and BufferLogger to lp.services.log.logging and delete the QuietFakeLogger.
245
            AssertionError, behavior.verifyBuildRequest, BufferLogger())
11573.3.24 by Jonathan Lange
Finish gutting the rest of buildd-slavescanner.
246
        self.assertEqual(
247
            'Soyuz is not yet capable of building SECURITY uploads.',
248
            str(e))
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
249
250
    def test_verifyBuildRequest(self):
251
        # Don't allow a virtual build on a non-virtual builder.
252
        archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
253
        builder = self.factory.makeBuilder(virtualized=False)
254
        build = self.factory.makeBinaryPackageBuild(
255
            builder=builder, archive=archive,
256
            pocket=PackagePublishingPocket.RELEASE)
257
        lf = self.factory.makeLibraryFileAlias()
258
        transaction.commit()
259
        build.distro_arch_series.addOrUpdateChroot(lf)
260
        candidate = build.queueBuild()
261
        behavior = candidate.required_build_behavior
262
        behavior.setBuilder(builder)
263
        e = self.assertRaises(
12070.1.4 by Tim Penhey
Move FakeLogger and BufferLogger to lp.services.log.logging and delete the QuietFakeLogger.
264
            AssertionError, behavior.verifyBuildRequest, BufferLogger())
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
265
        self.assertEqual(
266
            'Attempt to build virtual item on a non-virtual builder.',
267
            str(e))
268
269
11705.2.16 by Jonathan Lange
And so it goes.
270
class TestBinaryBuildPackageBehaviorBuildCollection(TestCaseWithFactory):
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
271
    """Tests for the BinaryPackageBuildBehavior.
272
273
    Using various mock slaves, we check how updateBuild() behaves in
274
    various scenarios.
275
    """
276
277
    # XXX: These tests replace part of the old buildd-slavescanner.txt
278
    # It was checking that each call to updateBuild was sending 3 (!)
279
    # emails but this behaviour is so ill-defined and dependent on the
280
    # sample data that I've not replicated that here.  We need to
281
    # examine that behaviour separately somehow, but the old tests gave
282
    # NO clue as to what, exactly, they were testing.
283
11705.2.16 by Jonathan Lange
And so it goes.
284
    layer = LaunchpadZopelessLayer
285
    run_tests_with = AsynchronousDeferredRunTest
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
286
11818.1.2 by Julian Edwards
unfuck stupid blanket cleanup
287
    def _cleanup(self):
288
        if os.path.exists(config.builddmaster.root):
289
            shutil.rmtree(config.builddmaster.root)
290
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
291
    def setUp(self):
292
        super(TestBinaryBuildPackageBehaviorBuildCollection, self).setUp()
293
        self.layer.switchDbUser('testadmin')
294
295
        self.builder = self.factory.makeBuilder()
296
        self.build = self.factory.makeBinaryPackageBuild(
297
            builder=self.builder, pocket=PackagePublishingPocket.RELEASE)
298
        lf = self.factory.makeLibraryFileAlias()
299
        transaction.commit()
300
        self.build.distro_arch_series.addOrUpdateChroot(lf)
301
        self.candidate = self.build.queueBuild()
302
        self.candidate.markAsBuilding(self.builder)
303
        self.behavior = self.candidate.required_build_behavior
304
        self.behavior.setBuilder(self.builder)
11818.1.1 by Julian Edwards
Remove leftover builddmaster.root directory so we don't break test isolation.
305
        # This is required so that uploaded files from the buildd don't
306
        # hang around between test runs.
11818.1.2 by Julian Edwards
unfuck stupid blanket cleanup
307
        self.addCleanup(self._cleanup)
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
308
309
    def assertBuildProperties(self, build):
310
        """Check that a build happened by making sure some of its properties
311
        are set."""
11705.2.16 by Jonathan Lange
And so it goes.
312
        self.assertIsNot(None, build.builder)
313
        self.assertIsNot(None, build.date_finished)
314
        self.assertIsNot(None, build.duration)
315
        self.assertIsNot(None, build.log)
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
316
317
    def test_packagefail_collection(self):
318
        # When a package fails to build, make sure the builder notes are
319
        # stored and the build status is set as failed.
320
        waiting_slave = WaitingSlave('BuildStatus.PACKAGEFAIL')
321
        self.builder.setSlaveForTesting(waiting_slave)
322
323
        def got_update(ignored):
324
            self.assertBuildProperties(self.build)
325
            self.assertEqual(BuildStatus.FAILEDTOBUILD, self.build.status)
326
327
        d = self.builder.updateBuild(self.candidate)
328
        return d.addCallback(got_update)
329
330
    def test_depwait_collection(self):
331
        # Package build was left in dependency wait.
332
        DEPENDENCIES = 'baz (>= 1.0.1)'
333
        waiting_slave = WaitingSlave('BuildStatus.DEPFAIL', DEPENDENCIES)
334
        self.builder.setSlaveForTesting(waiting_slave)
335
336
        def got_update(ignored):
337
            self.assertBuildProperties(self.build)
338
            self.assertEqual(BuildStatus.MANUALDEPWAIT, self.build.status)
339
            self.assertEqual(DEPENDENCIES, self.build.dependencies)
340
341
        d = self.builder.updateBuild(self.candidate)
342
        return d.addCallback(got_update)
343
344
    def test_chrootfail_collection(self):
345
        # There was a chroot problem for this build.
346
        waiting_slave = WaitingSlave('BuildStatus.CHROOTFAIL')
347
        self.builder.setSlaveForTesting(waiting_slave)
348
349
        def got_update(ignored):
350
            self.assertBuildProperties(self.build)
351
            self.assertEqual(BuildStatus.CHROOTWAIT, self.build.status)
352
353
        d = self.builder.updateBuild(self.candidate)
354
        return d.addCallback(got_update)
355
356
    def test_builderfail_collection(self):
357
        # The builder failed after we dispatched the build.
358
        waiting_slave = WaitingSlave('BuildStatus.BUILDERFAIL')
359
        self.builder.setSlaveForTesting(waiting_slave)
360
361
        def got_update(ignored):
362
            self.assertEqual(
363
                "Builder returned BUILDERFAIL when asked for its status",
364
                self.builder.failnotes)
11705.2.16 by Jonathan Lange
And so it goes.
365
            self.assertIs(None, self.candidate.builder)
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
366
            self.assertEqual(BuildStatus.NEEDSBUILD, self.build.status)
367
            job = self.candidate.specific_job.job
368
            self.assertEqual(JobStatus.WAITING, job.status)
369
370
        d = self.builder.updateBuild(self.candidate)
371
        return d.addCallback(got_update)
372
373
    def test_building_collection(self):
374
        # The builder is still building the package.
375
        self.builder.setSlaveForTesting(BuildingSlave())
11705.2.16 by Jonathan Lange
And so it goes.
376
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
377
        def got_update(ignored):
378
            # The fake log is returned from the BuildingSlave() mock.
379
            self.assertEqual("This is a build log", self.candidate.logtail)
380
381
        d = self.builder.updateBuild(self.candidate)
382
        return d.addCallback(got_update)
383
384
    def test_aborted_collection(self):
385
        # The builder aborted the job.
386
        self.builder.setSlaveForTesting(AbortedSlave())
387
388
        def got_update(ignored):
389
            self.assertEqual(BuildStatus.NEEDSBUILD, self.build.status)
390
391
        d = self.builder.updateBuild(self.candidate)
392
        return d.addCallback(got_update)
393
394
    def test_aborting_collection(self):
395
        # The builder is in the process of aborting.
396
        self.builder.setSlaveForTesting(AbortingSlave())
397
398
        def got_update(ignored):
399
            self.assertEqual(
400
                "Waiting for slave process to be terminated",
401
                self.candidate.logtail)
402
403
        d = self.builder.updateBuild(self.candidate)
404
        return d.addCallback(got_update)
405
12019.10.1 by Julian Edwards
Discard builds when they complete if the source is not published.
406
    def test_collection_for_deleted_source(self):
12019.10.3 by Julian Edwards
Review comments from gmb
407
        # If we collected a build for a superseded/deleted source then
408
        # the build should get marked superseded as the build results
409
        # get discarded.
12019.10.1 by Julian Edwards
Discard builds when they complete if the source is not published.
410
        self.builder.setSlaveForTesting(WaitingSlave('BuildStatus.OK'))
411
        spr = removeSecurityProxy(self.build.source_package_release)
412
        pub = self.build.current_source_publication
413
        pub.requestDeletion(spr.creator)
414
415
        def got_update(ignored):
416
            self.assertEqual(
417
                BuildStatus.SUPERSEDED, self.build.status)
418
419
        d = self.builder.updateBuild(self.candidate)
420
        return d.addCallback(got_update)
421
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
422
    def test_uploading_collection(self):
423
        # After a successful build, the status should be UPLOADING.
424
        self.builder.setSlaveForTesting(WaitingSlave('BuildStatus.OK'))
425
426
        def got_update(ignored):
427
            self.assertEqual(self.build.status, BuildStatus.UPLOADING)
428
            # We do not store any upload log information when the binary
429
            # upload processing succeeded.
11705.2.16 by Jonathan Lange
And so it goes.
430
            self.assertIs(None, self.build.upload_log)
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
431
432
        d = self.builder.updateBuild(self.candidate)
433
        return d.addCallback(got_update)
434
435
    def test_givenback_collection(self):
436
        waiting_slave = WaitingSlave('BuildStatus.GIVENBACK')
437
        self.builder.setSlaveForTesting(waiting_slave)
438
        score = self.candidate.lastscore
439
11705.2.16 by Jonathan Lange
And so it goes.
440
        def got_update(ignored):
441
            self.assertIs(None, self.candidate.builder)
442
            self.assertIs(None, self.candidate.date_started)
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
443
            self.assertEqual(score, self.candidate.lastscore)
444
            self.assertEqual(BuildStatus.NEEDSBUILD, self.build.status)
445
            job = self.candidate.specific_job.job
446
            self.assertEqual(JobStatus.WAITING, job.status)
447
448
        d = self.builder.updateBuild(self.candidate)
449
        return d.addCallback(got_update)
450
451
    def test_log_file_collection(self):
452
        self.builder.setSlaveForTesting(WaitingSlave('BuildStatus.OK'))
453
        self.build.status = BuildStatus.FULLYBUILT
454
        old_tmps = sorted(os.listdir('/tmp'))
455
11892.6.5 by Julian Edwards
fix test_binarypackagebuildbehavior when getting log files to test with
456
        def got_log(logfile_lfa_id):
457
            # Grabbing logs should not leave new files in /tmp (bug #172798)
458
            logfile_lfa = getUtility(ILibraryFileAliasSet)[logfile_lfa_id]
459
            new_tmps = sorted(os.listdir('/tmp'))
460
            self.assertEqual(old_tmps, new_tmps)
461
462
            # The new librarian file is stored compressed with a .gz
463
            # extension and text/plain file type for easy viewing in
464
            # browsers, as it decompresses and displays the file inline.
11892.6.19 by Julian Edwards
merge devel
465
            self.assertTrue(
466
                logfile_lfa.filename.endswith('_FULLYBUILT.txt.gz'))
11892.6.5 by Julian Edwards
fix test_binarypackagebuildbehavior when getting log files to test with
467
            self.assertEqual('text/plain', logfile_lfa.mimetype)
468
            self.layer.txn.commit()
469
470
            # LibrarianFileAlias does not implement tell() or seek(), which
471
            # are required by gzip.open(), so we need to read the file out
472
            # of the librarian first.
473
            fd, fname = tempfile.mkstemp()
474
            self.addCleanup(os.remove, fname)
475
            tmp = os.fdopen(fd, 'wb')
476
            tmp.write(logfile_lfa.read())
477
            tmp.close()
478
            uncompressed_file = gzip.open(fname).read()
479
480
            # Now make a temp filename that getFile() can write to.
11892.6.20 by Julian Edwards
Fix test failures due to jml's TestTools changes
481
            fd, tmp_orig_file_name = tempfile.mkstemp()
11892.6.5 by Julian Edwards
fix test_binarypackagebuildbehavior when getting log files to test with
482
            self.addCleanup(os.remove, tmp_orig_file_name)
483
484
            # Check that the original file from the slave matches the
11892.6.14 by Julian Edwards
Some minor review changes
485
            # uncompressed file in the librarian.
11892.6.5 by Julian Edwards
fix test_binarypackagebuildbehavior when getting log files to test with
486
            def got_orig_log(ignored):
487
                orig_file_content = open(tmp_orig_file_name).read()
488
                self.assertEqual(orig_file_content, uncompressed_file)
489
490
            d = removeSecurityProxy(self.builder.slave).getFile(
491
                'buildlog', tmp_orig_file_name)
492
            return d.addCallback(got_orig_log)
493
494
        d = self.build.getLogFromSlave(self.build)
495
        return d.addCallback(got_log)
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
496
497
    def test_private_build_log_storage(self):
498
        # Builds in private archives should have their log uploaded to
499
        # the restricted librarian.
500
        self.builder.setSlaveForTesting(WaitingSlave('BuildStatus.OK'))
501
12019.10.2 by Julian Edwards
Fix test busted by the change, which was depending on removed sources.
502
        # Go behind Storm's back since the field validator on
503
        # Archive.private prevents us from setting it to True with
504
        # existing published sources.
505
        Store.of(self.build).execute("""
506
            UPDATE archive SET private=True,buildd_secret='foo'
507
            WHERE archive.id = %s""" % self.build.archive.id)
508
        Store.of(self.build).invalidate()
11593.3.120 by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug
509
510
        def got_update(ignored):
511
            # Librarian needs a commit.  :(
512
            self.layer.txn.commit()
513
            self.assertTrue(self.build.log.restricted)
514
515
        d = self.builder.updateBuild(self.candidate)
516
        return d.addCallback(got_update)