~launchpad-pqm/launchpad/devel

13233.1.1 by Jeroen Vermeulen
Lint.
1
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
8687.15.13 by Karl Fogel
Add the copyright header block to files under lib/lp/archiveuploader/.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
3
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
4
"""Functional tests for uploadprocessor.py."""
3673.6.16 by Malcolm Cleaton
Addressed review comments
5
6
__metaclass__ = type
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
7
__all__ = [
8
    "MockOptions",
10722.3.2 by Steve Kowalik
* Walk every attachment when looking for PGP signatures.
9
    "TestUploadProcessorBase",
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
10
    ]
3673.6.16 by Malcolm Cleaton
Addressed review comments
11
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
12
from email import message_from_string
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
13
import os
14
import shutil
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
15
from StringIO import StringIO
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
16
import tempfile
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
17
14066.2.1 by William Grant
testOopsCreation no longer depends on bad uploads producing OOPSes.
18
from fixtures import MonkeyPatch
11039.2.53 by Jelmer Vernooij
Add extra flush, don't store upload log on success.
19
from storm.locals import Store
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
20
import transaction
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
21
from zope.component import (
22
    getGlobalSiteManager,
23
    getUtility,
24
    )
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
25
from zope.security.proxy import removeSecurityProxy
26
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
27
from canonical.config import config
28
from canonical.database.constants import UTC_NOW
11768.1.2 by Curtis Hovey
Used the deglobber to fix imports in python tests, then formatted them using format-new-and-modified-imports.
29
from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
30
from canonical.launchpad.testing.fakepackager import FakePackager
11666.3.5 by Curtis Hovey
Import layers from canonical.testing.layers.
31
from canonical.testing.layers import LaunchpadZopelessLayer
11270.1.3 by Tim Penhey
Changed NotFoundError imports - gee there were a lot of them.
32
from lp.app.errors import NotFoundError
14158.1.2 by Julian Edwards
Failing test added to check that process() is overriding the ddebs.
33
from lp.archiveuploader.nascentupload import NascentUpload
34
from lp.archiveuploader.nascentuploadfile import DdebBinaryUploadFile
35
from lp.archiveuploader.tests import (
36
    datadir,
37
    getPolicy,
38
    )
11369.1.1 by Guilherme Salgado
Use named adapters for archive upload policies rather than implementing our own global registry of policies.
39
from lp.archiveuploader.uploadpolicy import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
40
    AbstractUploadPolicy,
14158.1.2 by Julian Edwards
Failing test added to check that process() is overriding the ddebs.
41
    ArchiveUploadType,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
42
    findPolicyByName,
43
    IArchiveUploadPolicy,
44
    )
45
from lp.archiveuploader.uploadprocessor import (
12221.13.1 by Aaron Bentley
Start splitting UploadHandler.
46
    BuildUploadHandler,
12221.13.9 by Aaron Bentley
Move build retrieval to the constructor.
47
    CannotGetBuild,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
48
    parse_build_upload_leaf_name,
12221.13.1 by Aaron Bentley
Start splitting UploadHandler.
49
    UploadHandler,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
50
    UploadProcessor,
14066.2.4 by William Grant
Test the silence.
51
    UploadStatusEnum,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
52
    )
11039.2.42 by Jelmer Vernooij
Work with jobs rather than builds.
53
from lp.buildmaster.enums import (
54
    BuildFarmJobType,
55
    BuildStatus,
56
    )
8294.6.5 by Julian Edwards
Fix a bunch of circular imports, but there's still one I can't find.
57
from lp.registry.interfaces.distribution import IDistributionSet
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
58
from lp.registry.interfaces.person import IPersonSet
59
from lp.registry.interfaces.pocket import PackagePublishingPocket
10054.26.1 by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series.
60
from lp.registry.interfaces.series import SeriesStatus
7675.424.13 by William Grant
Test that the 3.0 (quilt) upload with two component tarballs works.
61
from lp.registry.interfaces.sourcepackage import SourcePackageFileType
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
62
from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
63
from lp.registry.model.sourcepackagename import SourcePackageName
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
64
from lp.services.features.testing import FeatureFixture
14158.1.2 by Julian Edwards
Failing test added to check that process() is overriding the ddebs.
65
from lp.services.log.logger import (
66
    BufferLogger,
67
    DevNullLogger,
68
    )
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
69
from lp.services.mail import stub
11411.6.4 by Julian Edwards
move ArchivePermissionType
70
from lp.soyuz.enums import (
71
    ArchivePermissionType,
72
    ArchivePurpose,
11411.6.9 by Julian Edwards
Move PackageUploadStatus and PackageUploadCustomFormat
73
    PackageUploadStatus,
11411.6.11 by Julian Edwards
Move SourcePackageFormat
74
    SourcePackageFormat,
11411.6.4 by Julian Edwards
move ArchivePermissionType
75
    )
11768.1.2 by Curtis Hovey
Used the deglobber to fix imports in python tests, then formatted them using format-new-and-modified-imports.
76
from lp.soyuz.interfaces.archive import IArchiveSet
77
from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
8294.6.8 by Julian Edwards
Section and component are now moved, and gina imports fixed.
78
from lp.soyuz.interfaces.component import IComponentSet
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
79
from lp.soyuz.interfaces.packageset import IPackagesetSet
80
from lp.soyuz.interfaces.publishing import (
81
    IPublishingSet,
82
    PackagePublishingStatus,
83
    )
11768.1.2 by Curtis Hovey
Used the deglobber to fix imports in python tests, then formatted them using format-new-and-modified-imports.
84
from lp.soyuz.interfaces.queue import QueueInconsistentStateError
9849.3.6 by William Grant
Move SourcePackageFormatSelection manipulation methods to the ISourcePackageFormatSelectionSet.
85
from lp.soyuz.interfaces.sourcepackageformat import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
86
    ISourcePackageFormatSelectionSet,
87
    )
88
from lp.soyuz.model.archivepermission import ArchivePermission
89
from lp.soyuz.model.binarypackagename import BinaryPackageName
90
from lp.soyuz.model.binarypackagerelease import BinaryPackageRelease
91
from lp.soyuz.model.component import Component
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
92
from lp.soyuz.model.distroseriesdifferencejob import (
93
    FEATURE_FLAG_ENABLE_MODULE,
94
    )
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
95
from lp.soyuz.model.publishing import (
96
    BinaryPackagePublishingHistory,
97
    SourcePackagePublishingHistory,
98
    )
99
from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
13194.2.1 by Gavin Panella
Change all uses of 'initialise' to 'initialize'.
100
from lp.soyuz.scripts.initialize_distroseries import InitializeDistroSeries
11308.3.7 by Jelmer Vernooij
Merge devel.
101
from lp.testing import (
102
    TestCase,
103
    TestCaseWithFactory,
104
    )
14066.2.5 by William Grant
Review comments.
105
from lp.testing.fakemethod import FakeMethod
14455.2.4 by William Grant
Drop imports from canonical.launchpad.ftests.
106
from lp.testing.gpgkeys import import_public_test_keys
8400.1.3 by Tim Penhey
Move c.l.tests.mail_helpers to lp.testing.
107
from lp.testing.mail_helpers import pop_notifications
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
108
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
109
110
class MockOptions:
3673.6.16 by Malcolm Cleaton
Addressed review comments
111
    """Use in place of an options object, adding more attributes if needed."""
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
112
    keep = False
113
    dryrun = False
114
115
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
116
class BrokenUploadPolicy(AbstractUploadPolicy):
117
    """A broken upload policy, to test error handling."""
118
119
    def __init__(self):
120
        AbstractUploadPolicy.__init__(self)
121
        self.name = "broken"
122
        self.unsigned_changes_ok = True
123
        self.unsigned_dsc_ok = True
124
125
    def checkUpload(self, upload):
126
        """Raise an exception upload processing is not expecting."""
127
        raise Exception("Exception raised by BrokenUploadPolicy for testing.")
128
129
8804.2.1 by Julian Edwards
Make PPA explicit uploaders always get notified of new uploads.
130
class TestUploadProcessorBase(TestCaseWithFactory):
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
131
    """Base class for functional tests over uploadprocessor.py."""
132
    layer = LaunchpadZopelessLayer
133
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
134
    def switchToUploader(self):
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
135
        transaction.commit()
136
        self.layer.switchDbUser("uploader")
137
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
138
    def switchToAdmin(self):
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
139
        transaction.commit()
140
        self.layer.switchDbUser("launchpad_main")
141
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
142
    def setUp(self):
10123.3.6 by Jonathan Lange
Fix archiveuploader, probably.
143
        super(TestUploadProcessorBase, self).setUp()
8804.2.1 by Julian Edwards
Make PPA explicit uploaders always get notified of new uploads.
144
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
145
        self.queue_folder = tempfile.mkdtemp()
11039.2.11 by Jelmer Vernooij
More tests.
146
        self.incoming_folder = os.path.join(self.queue_folder, "incoming")
147
        os.makedirs(self.incoming_folder)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
148
149
        self.test_files_dir = os.path.join(config.root,
8426.7.2 by Julian Edwards
migrate archiveuploader to the lp tree.
150
            "lib/lp/archiveuploader/tests/data/suite")
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
151
152
        import_public_test_keys()
153
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
154
        self.options = MockOptions()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
155
        self.options.base_fsroot = self.queue_folder
11039.3.13 by Jelmer Vernooij
Simplify handling of uploaders.
156
        self.options.builds = False
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
157
        self.options.leafname = None
158
        self.options.distro = "ubuntu"
159
        self.options.distroseries = None
160
        self.options.nomails = False
161
        self.options.context = 'insecure'
162
163
        # common recipients
164
        self.kinnison_recipient = (
165
            "Daniel Silverstone <daniel.silverstone@canonical.com>")
166
        self.name16_recipient = "Foo Bar <foo.bar@canonical.com>"
167
12070.1.30 by Tim Penhey
Another MockLogger killed.
168
        self.log = BufferLogger()
3691.93.17 by Christian Reis
Fix test bustage
169
13697.5.3 by Raphael Badin
Fix test failures.
170
        self.switchToAdmin()
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
171
        self.useFixture(FeatureFixture({
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
172
            FEATURE_FLAG_ENABLE_MODULE: u'on',
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
173
        }))
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
174
        self.switchToUploader()
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
175
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
176
    def tearDown(self):
177
        shutil.rmtree(self.queue_folder)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
178
        self.switchToAdmin()
10123.3.6 by Jonathan Lange
Fix archiveuploader, probably.
179
        super(TestUploadProcessorBase, self).tearDown()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
180
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
181
    def getUploadProcessor(self, txn, builds=None):
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
182
        self.switchToAdmin()
12221.13.14 by Aaron Bentley
Fix lint.
183
        if builds is None:
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
184
            builds = self.options.builds
11768.1.3 by Curtis Hovey
Hushed lint
185
14158.1.5 by Julian Edwards
fix lint
186
        def getUploadPolicy(distro, build):
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
187
            self.options.distro = distro.name
11369.1.3 by Guilherme Salgado
A few tweaks suggested by Julian
188
            policy = findPolicyByName(self.options.context)
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
189
            if builds:
11039.3.13 by Jelmer Vernooij
Simplify handling of uploaders.
190
                policy.distroseries = build.distro_series
191
                policy.pocket = build.pocket
192
                policy.archive = build.archive
11369.1.1 by Guilherme Salgado
Use named adapters for archive upload policies rather than implementing our own global registry of policies.
193
            policy.setOptions(self.options)
194
            return policy
11768.1.3 by Curtis Hovey
Hushed lint
195
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
196
        upload_processor = UploadProcessor(
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
197
            self.options.base_fsroot, self.options.dryrun,
14158.1.5 by Julian Edwards
fix lint
198
            self.options.nomails, builds, self.options.keep, getUploadPolicy,
199
            txn, self.log)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
200
        self.switchToUploader()
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
201
        return upload_processor
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
202
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
203
    def publishPackage(self, packagename, version, source=True, archive=None):
11039.2.13 by Jelmer Vernooij
Fix tests.
204
        """Publish a single package that is currently NEW in the queue."""
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
205
        self.switchToAdmin()
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
206
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
207
        packagename = unicode(packagename)
208
        if version is not None:
209
            version = unicode(version)
210
        queue_items = self.breezy.getPackageUploads(
11039.2.13 by Jelmer Vernooij
Fix tests.
211
            status=PackageUploadStatus.NEW, name=packagename,
212
            version=version, exact_match=True, archive=archive)
213
        self.assertEqual(queue_items.count(), 1)
214
        queue_item = queue_items[0]
215
        queue_item.setAccepted()
216
        if source:
217
            pubrec = queue_item.sources[0].publish(self.log)
218
        else:
219
            pubrec = queue_item.builds[0].publish(self.log)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
220
        self.switchToUploader()
11039.2.13 by Jelmer Vernooij
Fix tests.
221
        return pubrec
222
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
223
    def assertLogContains(self, line):
224
        """Assert if a given line is present in the log messages."""
12070.1.30 by Tim Penhey
Another MockLogger killed.
225
        log_lines = self.log.getLogBuffer()
226
        self.assertTrue(line in log_lines,
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
227
                        "'%s' is not in logged output\n\n%s"
12070.1.30 by Tim Penhey
Another MockLogger killed.
228
                        % (line, log_lines))
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
229
230
    def assertRaisesAndReturnError(self, excClass, callableObj, *args,
231
                                   **kwargs):
232
        """See `TestCase.assertRaises`.
233
234
        Unlike `TestCase.assertRaises`, this method returns the exception
235
        object when it is raised.  Callsites can then easily check the
236
        exception contents.
237
        """
238
        try:
239
            callableObj(*args, **kwargs)
240
        except excClass, error:
241
            return error
242
        else:
243
            if getattr(excClass, '__name__', None) is not None:
244
                excName = excClass.__name__
245
            else:
246
                excName = str(excClass)
247
            raise self.failureException, "%s not raised" % excName
248
7675.424.34 by William Grant
Fix lint.
249
    def setupBreezy(self, name="breezy", permitted_formats=None):
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
250
        """Create a fresh distroseries in ubuntu.
251
13194.2.1 by Gavin Panella
Change all uses of 'initialise' to 'initialize'.
252
        Use *initializeFromParent* procedure to create 'breezy'
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
253
        on ubuntu based on the last 'breezy-autotest'.
254
255
        Also sets 'changeslist' and 'nominatedarchindep' properly and
256
        creates a chroot for breezy-autotest/i386 distroarchseries.
7548.5.4 by Julian Edwards
Resurrection part 4
257
258
        :param name: supply the name of the distroseries if you don't want
259
            it to be called "breezy"
7675.424.34 by William Grant
Fix lint.
260
        :param permitted_formats: list of SourcePackageFormats to allow
261
            in the new distroseries. Only permits '1.0' by default.
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
262
        """
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
263
        self.switchToAdmin()
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
264
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
265
        self.ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
266
        bat = self.ubuntu['breezy-autotest']
6935.4.16 by Edwin Grubbs
Used zopeless to circumvent permissions.
267
        self.breezy = self.ubuntu.newSeries(
7548.5.4 by Julian Edwards
Resurrection part 4
268
            name, 'Breezy Badger',
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
269
            'The Breezy Badger', 'Black and White', 'Someone',
12494.1.98 by Gavin Panella
Fix almost all test failures. Most were due to the extra required argument to the InitialiseDistroSeries constructor.
270
            '5.10', None, bat.owner)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
271
13168.13.30 by Raphael Badin
Setup previous_series properly in tests.
272
        self.breezy.previous_series = bat
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
273
        self.breezy.changeslist = 'breezy-changes@ubuntu.com'
13194.2.1 by Gavin Panella
Change all uses of 'initialise' to 'initialize'.
274
        ids = InitializeDistroSeries(self.breezy, [bat.id])
275
        ids.initialize()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
276
11258.1.10 by Steve Kowalik
* Undo test changes.
277
        fake_chroot = self.addMockFile('fake_chroot.tar.gz')
278
        self.breezy['i386'].addOrUpdateChroot(fake_chroot)
279
7675.424.34 by William Grant
Fix lint.
280
        if permitted_formats is None:
281
            permitted_formats = [SourcePackageFormat.FORMAT_1_0]
282
7675.424.25 by William Grant
Reject uploads involving formats unsupported by the target series.
283
        for format in permitted_formats:
9849.3.6 by William Grant
Move SourcePackageFormatSelection manipulation methods to the ISourcePackageFormatSelectionSet.
284
            if not self.breezy.isSourcePackageFormatPermitted(format):
285
                getUtility(ISourcePackageFormatSelectionSet).add(
286
                    self.breezy, format)
7675.424.25 by William Grant
Reject uploads involving formats unsupported by the target series.
287
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
288
        self.switchToUploader()
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
289
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
290
    def addMockFile(self, filename, content="anything"):
291
        """Return a librarian file."""
292
        return getUtility(ILibraryFileAliasSet).create(
293
            filename, len(content), StringIO(content),
294
            'application/x-gtar')
295
11039.2.11 by Jelmer Vernooij
More tests.
296
    def queueUpload(self, upload_name, relative_path="", test_files_dir=None,
297
            queue_entry=None):
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
298
        """Queue one of our test uploads.
299
11768.1.3 by Curtis Hovey
Hushed lint
300
        upload_name is the name of the test upload directory. If there
11039.2.11 by Jelmer Vernooij
More tests.
301
        is no explicit queue entry name specified, it is also
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
302
        the name of the queue entry directory we create.
303
        relative_path is the path to create inside the upload, eg
304
        ubuntu/~malcc/default. If not specified, defaults to "".
305
306
        Return the path to the upload queue entry directory created.
307
        """
11039.2.11 by Jelmer Vernooij
More tests.
308
        if queue_entry is None:
309
            queue_entry = upload_name
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
310
        target_path = os.path.join(
11039.2.11 by Jelmer Vernooij
More tests.
311
            self.incoming_folder, queue_entry, relative_path)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
312
        if test_files_dir is None:
313
            test_files_dir = self.test_files_dir
314
        upload_dir = os.path.join(test_files_dir, upload_name)
315
        if relative_path:
316
            os.makedirs(os.path.dirname(target_path))
317
        shutil.copytree(upload_dir, target_path)
11039.2.11 by Jelmer Vernooij
More tests.
318
        return os.path.join(self.incoming_folder, queue_entry)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
319
11039.3.7 by Jelmer Vernooij
Eliminate --buildid option, pass around build objects everywhere.
320
    def processUpload(self, processor, upload_dir, build=None):
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
321
        """Process an upload queue entry directory.
322
323
        There is some duplication here with logic in UploadProcessor,
324
        but we need to be able to do this without error handling here,
325
        so that we can debug failing tests effectively.
326
        """
327
        results = []
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
328
        self.assertEqual(processor.builds, build is not None)
12221.13.14 by Aaron Bentley
Fix lint.
329
        handler = UploadHandler.forProcessor(
330
            processor, '.', upload_dir, build)
12221.13.4 by Aaron Bentley
Move locateChangesFiles and orderFilenames to UploadHandler.
331
        changes_files = handler.locateChangesFiles()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
332
        for changes_file in changes_files:
12221.13.11 by Aaron Bentley
remove build parameter from processChangesFile.
333
            result = handler.processChangesFile(changes_file)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
334
            results.append(result)
335
        return results
336
337
    def setupBreezyAndGetUploadProcessor(self, policy=None):
338
        """Setup Breezy and return an upload processor for it."""
339
        self.setupBreezy()
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
340
        self.switchToAdmin()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
341
        self.layer.txn.commit()
342
        if policy is not None:
343
            self.options.context = policy
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
344
        upload_processor = self.getUploadProcessor(self.layer.txn)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
345
        self.switchToUploader()
13697.5.1 by Raphael Badin
Use the right user and set the feature flag to trigger DSDJ creation.
346
        return upload_processor
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
347
348
    def assertEmail(self, contents=None, recipients=None):
349
        """Check last email content and recipients.
350
351
        :param contents: A list of lines; assert that each is in the email.
352
        :param recipients: A list of recipients that must be on the email.
353
                           Supply an empty list if you don't want them
354
                           checked.  Default action is to check that the
355
                           recipient is foo.bar@canonical.com, which is the
356
                           signer on most of the test data uploads.
357
        """
358
        if recipients is None:
359
            recipients = [self.name16_recipient]
360
        if contents is None:
361
            contents = []
362
363
        self.assertEqual(
364
            len(stub.test_emails), 1,
365
            'Unexpected number of emails sent: %s' % len(stub.test_emails))
366
367
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
368
        msg = message_from_string(raw_msg)
7013.1.1 by Muharem Hrnjadovic
merged email-250820 changes into fresh branch
369
        # This is now a MIMEMultipart message.
370
        body = msg.get_payload(0)
371
        body = body.get_payload(decode=True)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
372
373
        # Only check recipients if callsite didn't provide an empty list.
374
        if recipients != []:
375
            clean_recipients = [r.strip() for r in to_addrs]
376
            for recipient in list(recipients):
377
                self.assertTrue(
378
                    recipient in clean_recipients,
379
                    "%s not found in %s" % (recipients, clean_recipients))
380
            self.assertEqual(
381
                len(recipients), len(clean_recipients),
382
                "Email recipients do not match exactly. Expected %s, got %s" %
383
                    (recipients, clean_recipients))
384
385
        subject = "Subject: %s\n" % msg['Subject']
386
        body = subject + body
387
388
        for content in list(contents):
389
            self.assertTrue(
390
                content in body,
391
                "Expect: '%s'\nGot:\n%s" % (content, body))
392
10722.3.3 by Steve Kowalik
Refactor PGPSignatureNotPreserved to pull the changes file from the librarian, as opposed to the checking the notification mail.
393
    def PGPSignatureNotPreserved(self, archive=None):
10542.14.2 by Steve Kowalik
Refactor .testPGPSignatureNotPreserved() from PPATestUploadProcessor to TestUploadProcessorBase, and call it from {PPA,}TestUploadProcessor
394
        """PGP signatures should be removed from .changes files.
395
396
        Email notifications and the librarian file for .changes file should
397
        both have the PGP signature removed.
398
        """
10722.3.3 by Steve Kowalik
Refactor PGPSignatureNotPreserved to pull the changes file from the librarian, as opposed to the checking the notification mail.
399
        bar = archive.getPublishedSources(
400
            name='bar', version="1.0-1", exact_match=True)
10722.3.4 by Steve Kowalik
* Utilise .getChangesFileLFA() instead of .changesFileUrl() when checking for PGP signatures
401
        changes_lfa = getUtility(IPublishingSet).getChangesFileLFA(
12505.4.1 by Robert Collins
Hopefully fix bug 727560 by permitting a much better query plan for folk querying the primary archive.
402
            bar.first().sourcepackagerelease)
10722.3.4 by Steve Kowalik
* Utilise .getChangesFileLFA() instead of .changesFileUrl() when checking for PGP signatures
403
        changes_file = changes_lfa.read()
404
        self.assertTrue(
405
            "Format: " in changes_file, "Does not look like a changes file")
10722.3.3 by Steve Kowalik
Refactor PGPSignatureNotPreserved to pull the changes file from the librarian, as opposed to the checking the notification mail.
406
        self.assertTrue(
407
            "-----BEGIN PGP SIGNED MESSAGE-----" not in changes_file,
408
            "Unexpected PGP header found")
409
        self.assertTrue(
410
            "-----BEGIN PGP SIGNATURE-----" not in changes_file,
411
            "Unexpected start of PGP signature found")
412
        self.assertTrue(
413
            "-----END PGP SIGNATURE-----" not in changes_file,
414
            "Unexpected end of PGP signature found")
10542.14.2 by Steve Kowalik
Refactor .testPGPSignatureNotPreserved() from PPATestUploadProcessor to TestUploadProcessorBase, and call it from {PPA,}TestUploadProcessor
415
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
416
417
class TestUploadProcessor(TestUploadProcessorBase):
418
    """Basic tests on uploadprocessor class.
419
420
    * Check if the rejection message is send even when an unexpected
421
      exception occur when processing the upload.
422
    * Check if known uploads targeted to a FROZEN distroseries
423
      end up in UNAPPROVED queue.
424
425
    This test case is able to setup a fresh distroseries in Ubuntu.
426
    """
427
428
    def _checkPartnerUploadEmailSuccess(self):
429
        """Ensure partner uploads generate the right email."""
430
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
431
        foo_bar = "Foo Bar <foo.bar@canonical.com>"
432
        self.assertEqual([e.strip() for e in to_addrs], [foo_bar])
433
        self.assertTrue(
434
            "rejected" not in raw_msg,
435
            "Expected acceptance email not rejection. Actually Got:\n%s"
436
                % raw_msg)
437
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
438
    def testInstantiate(self):
3691.93.15 by Christian Reis
Fix for bug #54345: archivepublisher module imports monolithically
439
        """UploadProcessor should instantiate"""
13233.1.1 by Jeroen Vermeulen
Lint.
440
        self.getUploadProcessor(None)
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
441
3673.6.16 by Malcolm Cleaton
Addressed review comments
442
    def testLocateDirectories(self):
8322.7.1 by Celso Providelo
Fixing bug #371640 (uploads are processed in the order they happened).
443
        """Return a sorted list of subdirs in a directory.
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
444
3673.6.7 by Malcolm Cleaton
Incorporate peer-review suggestions from dsilvers
445
        We don't test that we block on the lockfile, as this is trivial
446
        code but tricky to test.
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
447
        """
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
448
        testdir = tempfile.mkdtemp()
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
449
        try:
8322.7.1 by Celso Providelo
Fixing bug #371640 (uploads are processed in the order they happened).
450
            os.mkdir("%s/dir3" % testdir)
3673.6.16 by Malcolm Cleaton
Addressed review comments
451
            os.mkdir("%s/dir1" % testdir)
452
            os.mkdir("%s/dir2" % testdir)
453
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
454
            up = self.getUploadProcessor(None)
3673.6.16 by Malcolm Cleaton
Addressed review comments
455
            located_dirs = up.locateDirectories(testdir)
8322.7.1 by Celso Providelo
Fixing bug #371640 (uploads are processed in the order they happened).
456
            self.assertEqual(located_dirs, ['dir1', 'dir2', 'dir3'])
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
457
        finally:
458
            shutil.rmtree(testdir)
459
11039.1.8 by Jelmer Vernooij
Use private method name for test utility function.
460
    def _makeUpload(self, testdir):
11039.1.7 by Jelmer Vernooij
Create convenience function for creating dummy uploads.
461
        """Create a dummy upload for testing the move/remove methods."""
462
        upload = tempfile.mkdtemp(dir=testdir)
463
        distro = upload + ".distro"
464
        f = open(distro, mode="w")
465
        f.write("foo")
466
        f.close()
467
        return upload, distro
468
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
469
    def testMoveUpload(self):
3673.6.16 by Malcolm Cleaton
Addressed review comments
470
        """moveUpload should move the upload directory and .distro file."""
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
471
        testdir = tempfile.mkdtemp()
3673.6.16 by Malcolm Cleaton
Addressed review comments
472
        try:
473
            # Create an upload, a .distro and a target to move it to.
11039.1.8 by Jelmer Vernooij
Use private method name for test utility function.
474
            upload, distro = self._makeUpload(testdir)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
475
            target = tempfile.mkdtemp(dir=testdir)
3673.6.16 by Malcolm Cleaton
Addressed review comments
476
            target_name = os.path.basename(target)
11039.1.7 by Jelmer Vernooij
Create convenience function for creating dummy uploads.
477
            upload_name = os.path.basename(upload)
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
478
3673.6.16 by Malcolm Cleaton
Addressed review comments
479
            # Move it
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
480
            self.options.base_fsroot = testdir
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
481
            up = self.getUploadProcessor(None)
12221.13.6 by Aaron Bentley
move moveProcessedUpload etc to UploadHandler.
482
            handler = UploadHandler(up, '.', upload)
483
            handler.moveUpload(target_name, self.log)
3673.6.16 by Malcolm Cleaton
Addressed review comments
484
485
            # Check it moved
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
486
            self.assertTrue(os.path.exists(os.path.join(target, upload_name)))
487
            self.assertTrue(os.path.exists(os.path.join(
488
                target, upload_name + ".distro")))
489
            self.assertFalse(os.path.exists(upload))
490
            self.assertFalse(os.path.exists(distro))
491
        finally:
492
            shutil.rmtree(testdir)
3691.93.17 by Christian Reis
Fix test bustage
493
11039.1.6 by Jelmer Vernooij
Cherrypick change to move/remove decision for uploads to a separate method.
494
    def testMoveProcessUploadAccepted(self):
495
        testdir = tempfile.mkdtemp()
496
        try:
497
            # Create an upload, a .distro and a target to move it to.
11039.1.8 by Jelmer Vernooij
Use private method name for test utility function.
498
            upload, distro = self._makeUpload(testdir)
11039.1.6 by Jelmer Vernooij
Cherrypick change to move/remove decision for uploads to a separate method.
499
            upload_name = os.path.basename(upload)
500
501
            # Remove it
502
            self.options.base_fsroot = testdir
11039.2.7 by Jelmer Vernooij
Cherrypick existing work.
503
            up = self.getUploadProcessor(None)
12221.13.6 by Aaron Bentley
move moveProcessedUpload etc to UploadHandler.
504
            handler = UploadHandler(up, '.', upload)
505
            handler.moveProcessedUpload("accepted", self.log)
11039.1.6 by Jelmer Vernooij
Cherrypick change to move/remove decision for uploads to a separate method.
506
507
            # Check it was removed, not moved
508
            self.assertFalse(os.path.exists(os.path.join(
11039.1.10 by Jelmer Vernooij
Fix paths, thanks Henning.
509
                testdir, "accepted")))
510
            self.assertFalse(os.path.exists(os.path.join(testdir,
11039.1.6 by Jelmer Vernooij
Cherrypick change to move/remove decision for uploads to a separate method.
511
                "accepted", upload_name + ".distro")))
512
            self.assertFalse(os.path.exists(upload))
513
            self.assertFalse(os.path.exists(distro))
514
        finally:
515
            shutil.rmtree(testdir)
516
517
    def testMoveProcessUploadFailed(self):
11149.4.1 by Jeroen Vermeulen
Test cruft in archiveuploader.
518
        """moveProcessedUpload moves if the result was not successful."""
11039.1.6 by Jelmer Vernooij
Cherrypick change to move/remove decision for uploads to a separate method.
519
        testdir = tempfile.mkdtemp()
520
        try:
521
            # Create an upload, a .distro and a target to move it to.
11039.1.8 by Jelmer Vernooij
Use private method name for test utility function.
522
            upload, distro = self._makeUpload(testdir)
11039.1.6 by Jelmer Vernooij
Cherrypick change to move/remove decision for uploads to a separate method.
523
            upload_name = os.path.basename(upload)
524
525
            # Move it
526
            self.options.base_fsroot = testdir
11039.2.7 by Jelmer Vernooij
Cherrypick existing work.
527
            up = self.getUploadProcessor(None)
12221.13.6 by Aaron Bentley
move moveProcessedUpload etc to UploadHandler.
528
            handler = UploadHandler(up, '.', upload)
529
            handler.moveProcessedUpload("rejected", self.log)
11039.1.6 by Jelmer Vernooij
Cherrypick change to move/remove decision for uploads to a separate method.
530
531
            # Check it moved
11039.1.10 by Jelmer Vernooij
Fix paths, thanks Henning.
532
            self.assertTrue(os.path.exists(os.path.join(testdir,
533
                "rejected", upload_name)))
11039.1.6 by Jelmer Vernooij
Cherrypick change to move/remove decision for uploads to a separate method.
534
            self.assertTrue(os.path.exists(os.path.join(testdir,
535
                "rejected", upload_name + ".distro")))
536
            self.assertFalse(os.path.exists(upload))
537
            self.assertFalse(os.path.exists(distro))
538
        finally:
539
            shutil.rmtree(testdir)
540
11039.1.2 by Jelmer Vernooij
Move removing of uploads into a separate function.
541
    def testRemoveUpload(self):
11149.4.1 by Jeroen Vermeulen
Test cruft in archiveuploader.
542
        """RemoveUpload removes the upload directory and .distro file."""
11039.1.1 by Jelmer Vernooij
Cherrypick simplified fix for 361192.
543
        testdir = tempfile.mkdtemp()
544
        try:
545
            # Create an upload, a .distro and a target to move it to.
11039.1.8 by Jelmer Vernooij
Use private method name for test utility function.
546
            upload, distro = self._makeUpload(testdir)
13233.1.1 by Jeroen Vermeulen
Lint.
547
            os.path.basename(upload)
11039.1.1 by Jelmer Vernooij
Cherrypick simplified fix for 361192.
548
11039.1.3 by Jelmer Vernooij
Cope with upstream changes.
549
            # Remove it
11039.1.1 by Jelmer Vernooij
Cherrypick simplified fix for 361192.
550
            self.options.base_fsroot = testdir
11039.2.7 by Jelmer Vernooij
Cherrypick existing work.
551
            up = self.getUploadProcessor(None)
12221.13.6 by Aaron Bentley
move moveProcessedUpload etc to UploadHandler.
552
            handler = UploadHandler(up, '.', upload)
553
            handler.removeUpload(self.log)
11039.1.1 by Jelmer Vernooij
Cherrypick simplified fix for 361192.
554
11039.1.2 by Jelmer Vernooij
Move removing of uploads into a separate function.
555
            # Check it was removed, not moved
11039.1.1 by Jelmer Vernooij
Cherrypick simplified fix for 361192.
556
            self.assertFalse(os.path.exists(os.path.join(
11039.1.10 by Jelmer Vernooij
Fix paths, thanks Henning.
557
                testdir, "accepted")))
11039.1.1 by Jelmer Vernooij
Cherrypick simplified fix for 361192.
558
            self.assertFalse(os.path.exists(upload))
559
            self.assertFalse(os.path.exists(distro))
560
        finally:
561
            shutil.rmtree(testdir)
562
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
563
    def testRejectionEmailForUnhandledException(self):
564
        """Test there's a rejection email when nascentupload breaks.
565
566
        If a developer makes an upload which finds a bug in nascentupload,
567
        and an unhandled exception occurs, we should try to send a
568
        rejection email. We'll test that this works, in a case where we
569
        will have the right information to send the email before the
570
        error occurs.
571
572
        If we haven't extracted enough information to send a rejection
573
        email when things break, trying to send one will raise a new
574
        exception, and the upload will fail silently as before. We don't
575
        test this case.
576
577
        See bug 35965.
578
        """
11369.1.1 by Guilherme Salgado
Use named adapters for archive upload policies rather than implementing our own global registry of policies.
579
        self.options.context = u'broken'
580
        # Register our broken upload policy.
581
        getGlobalSiteManager().registerUtility(
582
            component=BrokenUploadPolicy, provided=IArchiveUploadPolicy,
583
            name=self.options.context)
584
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
585
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
586
587
        # Upload a package to Breezy.
588
        upload_dir = self.queueUpload("baz_1.0-1")
589
        self.processUpload(uploadprocessor, upload_dir)
590
591
        # Check the mailer stub has a rejection email for Daniel
592
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
7013.1.1 by Muharem Hrnjadovic
merged email-250820 changes into fresh branch
593
        # This is now a MIMEMultipart message.
594
        msg = message_from_string(raw_msg)
595
        body = msg.get_payload(0)
596
        body = body.get_payload(decode=True)
597
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
598
        daniel = "Daniel Silverstone <daniel.silverstone@canonical.com>"
599
        self.assertEqual(to_addrs, [daniel])
600
        self.assertTrue("Unhandled exception processing upload: Exception "
601
                        "raised by BrokenUploadPolicy for testing."
7013.1.1 by Muharem Hrnjadovic
merged email-250820 changes into fresh branch
602
                        in body)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
603
604
    def testUploadToFrozenDistro(self):
605
        """Uploads to a frozen distroseries should work, but be unapproved.
606
607
        The rule for a frozen distroseries is that uploads should still
608
        be permitted, but that the usual rule for auto-accepting uploads
609
        of existing packages should be suspended. New packages will still
610
        go into NEW, but new versions will be UNAPPROVED, rather than
611
        ACCEPTED.
612
613
        To test this, we will upload two versions of the same package,
614
        accepting and publishing the first, and freezing the distroseries
615
        before the second. If all is well, the second upload should go
616
        through ok, but end up in status UNAPPROVED, and with the
617
        appropriate email contents.
618
619
        See bug 58187.
620
        """
621
        # Set up the uploadprocessor with appropriate options and logger
622
        uploadprocessor = self.setupBreezyAndGetUploadProcessor()
623
624
        # Upload a package for Breezy.
625
        upload_dir = self.queueUpload("bar_1.0-1")
626
        self.processUpload(uploadprocessor, upload_dir)
627
628
        # Check it went ok to the NEW queue and all is going well so far.
629
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
630
        foo_bar = "Foo Bar <foo.bar@canonical.com>"
631
        daniel = "Daniel Silverstone <daniel.silverstone@canonical.com>"
14493.1.3 by Jeroen Vermeulen
Fixed some tests that relied on arbitrary ordering (and now failed).
632
        self.assertContentEqual(
633
            [foo_bar, daniel], [e.strip() for e in to_addrs])
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
634
        self.assertTrue(
635
            "NEW" in raw_msg, "Expected email containing 'NEW', got:\n%s"
636
            % raw_msg)
637
638
        # Accept and publish the upload.
639
        # This is required so that the next upload of a later version of
640
        # the same package will work correctly.
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
641
        self.switchToAdmin()
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
642
        queue_items = self.breezy.getPackageUploads(
643
            status=PackageUploadStatus.NEW, name=u"bar",
644
            version=u"1.0-1", exact_match=True)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
645
        self.assertEqual(queue_items.count(), 1)
646
        queue_item = queue_items[0]
647
648
        queue_item.setAccepted()
649
        pubrec = queue_item.sources[0].publish(self.log)
7659.7.1 by Julian Edwards
Remove secure publishing records.
650
        pubrec.status = PackagePublishingStatus.PUBLISHED
651
        pubrec.datepublished = UTC_NOW
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
652
653
        # Make ubuntu/breezy a frozen distro, so a source upload for an
654
        # existing package will be allowed, but unapproved.
10054.26.1 by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series.
655
        self.breezy.status = SeriesStatus.FROZEN
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
656
        self.layer.txn.commit()
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
657
        self.switchToUploader()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
658
659
        # Upload a newer version of bar.
660
        upload_dir = self.queueUpload("bar_1.0-2")
661
        self.processUpload(uploadprocessor, upload_dir)
662
663
        # Verify we get an email talking about awaiting approval.
664
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
665
        daniel = "Daniel Silverstone <daniel.silverstone@canonical.com>"
666
        foo_bar = "Foo Bar <foo.bar@canonical.com>"
14493.1.3 by Jeroen Vermeulen
Fixed some tests that relied on arbitrary ordering (and now failed).
667
        self.assertContentEqual(
668
            [foo_bar, daniel], [e.strip() for e in to_addrs])
7013.1.1 by Muharem Hrnjadovic
merged email-250820 changes into fresh branch
669
        self.assertTrue("Waiting for approval" in raw_msg,
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
670
                        "Expected an 'upload awaits approval' email.\n"
671
                        "Got:\n%s" % raw_msg)
672
673
        # And verify that the queue item is in the unapproved state.
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
674
        queue_items = self.breezy.getPackageUploads(
675
            status=PackageUploadStatus.UNAPPROVED, name=u"bar",
676
            version=u"1.0-2", exact_match=True)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
677
        self.assertEqual(queue_items.count(), 1)
678
        queue_item = queue_items[0]
679
        self.assertEqual(
680
            queue_item.status, PackageUploadStatus.UNAPPROVED,
681
            "Expected queue item to be in UNAPPROVED status.")
682
7675.158.3 by Muharem Hrnjadovic
Graham's review comments
683
    def _checkCopyArchiveUploadToDistro(self, pocket_to_check,
684
                                        status_to_check):
7675.158.1 by Muharem Hrnjadovic
bug fixed.
685
        """Check binary copy archive uploads for given pocket and status.
686
687
        This helper method tests that buildd binary uploads to copy
688
        archives work when the
689
            * destination pocket is `pocket_to_check`
690
            * associated distroseries is in state `status_to_check`.
691
692
        See bug 369512.
693
        """
694
        # Set up the uploadprocessor with appropriate options and logger
695
        uploadprocessor = self.setupBreezyAndGetUploadProcessor()
696
697
        # Upload 'bar-1.0-1' source and binary to ubuntu/breezy.
698
        upload_dir = self.queueUpload("bar_1.0-1")
699
        self.processUpload(uploadprocessor, upload_dir)
11039.2.13 by Jelmer Vernooij
Fix tests.
700
        bar_source_pub = self.publishPackage('bar', '1.0-1')
7675.158.1 by Muharem Hrnjadovic
bug fixed.
701
        [bar_original_build] = bar_source_pub.createMissingBuilds()
702
10395.2.1 by Julian Edwards
Write a failing test.
703
        # Move the source from the accepted queue.
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
704
        [queue_item] = self.breezy.getPackageUploads(
10395.2.1 by Julian Edwards
Write a failing test.
705
            status=PackageUploadStatus.ACCEPTED,
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
706
            version=u"1.0-1",
707
            name=u"bar")
10395.2.1 by Julian Edwards
Write a failing test.
708
        queue_item.setDone()
709
10395.2.4 by Julian Edwards
Add copy archive binary upload overrides.
710
        # Upload and accept a binary for the primary archive source.
711
        shutil.rmtree(upload_dir)
712
        self.options.context = 'buildd'
713
        self.layer.txn.commit()
714
        upload_dir = self.queueUpload("bar_1.0-1_binary")
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
715
        build_uploadprocessor = self.getUploadProcessor(
716
            self.layer.txn, builds=True)
717
        self.processUpload(build_uploadprocessor, upload_dir,
11039.3.7 by Jelmer Vernooij
Eliminate --buildid option, pass around build objects everywhere.
718
            build=bar_original_build)
10395.2.4 by Julian Edwards
Add copy archive binary upload overrides.
719
        self.assertEqual(
720
            uploadprocessor.last_processed_upload.is_rejected, False)
11039.2.13 by Jelmer Vernooij
Fix tests.
721
        bar_bin_pubs = self.publishPackage('bar', '1.0-1', source=False)
10395.2.4 by Julian Edwards
Add copy archive binary upload overrides.
722
        # Mangle its publishing component to "restricted" so we can check
723
        # the copy archive ancestry override later.
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
724
        self.switchToAdmin()
10395.2.4 by Julian Edwards
Add copy archive binary upload overrides.
725
        restricted = getUtility(IComponentSet)["restricted"]
726
        for pub in bar_bin_pubs:
7675.556.1 by Julian Edwards
Fix conflict with devel
727
            pub.component = restricted
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
728
        self.switchToUploader()
10395.2.4 by Julian Edwards
Add copy archive binary upload overrides.
729
7675.158.1 by Muharem Hrnjadovic
bug fixed.
730
        # Create a COPY archive for building in non-virtual builds.
731
        uploader = getUtility(IPersonSet).getByName('name16')
732
        copy_archive = getUtility(IArchiveSet).new(
733
            owner=uploader, purpose=ArchivePurpose.COPY,
734
            distribution=self.ubuntu, name='the-copy-archive')
735
        copy_archive.require_virtualized = False
736
737
        # Copy 'bar-1.0-1' source to the COPY archive.
738
        bar_copied_source = bar_source_pub.copyTo(
739
            bar_source_pub.distroseries, pocket_to_check, copy_archive)
740
        [bar_copied_build] = bar_copied_source.createMissingBuilds()
741
742
        # Make ubuntu/breezy the current distro.
743
        self.breezy.status = status_to_check
744
        self.layer.txn.commit()
745
746
        shutil.rmtree(upload_dir)
747
        self.options.context = 'buildd'
748
        upload_dir = self.queueUpload(
749
            "bar_1.0-1_binary", "%s/ubuntu" % copy_archive.id)
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
750
        self.processUpload(build_uploadprocessor, upload_dir,
11039.3.7 by Jelmer Vernooij
Eliminate --buildid option, pass around build objects everywhere.
751
             build=bar_copied_build)
7675.158.1 by Muharem Hrnjadovic
bug fixed.
752
753
        # Make sure the upload succeeded.
754
        self.assertEqual(
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
755
            build_uploadprocessor.last_processed_upload.is_rejected, False)
7675.158.1 by Muharem Hrnjadovic
bug fixed.
756
10395.2.1 by Julian Edwards
Write a failing test.
757
        # The upload should also be auto-accepted even though there's no
758
        # ancestry.  This means items should go to ACCEPTED and not NEW.
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
759
        queue_items = self.breezy.getPackageUploads(
10395.2.1 by Julian Edwards
Write a failing test.
760
            status=PackageUploadStatus.ACCEPTED,
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
761
            version=u"1.0-1",
762
            name=u"bar",
10395.2.2 by Julian Edwards
Make fix and tweak test so it works
763
            archive=copy_archive)
10395.2.1 by Julian Edwards
Write a failing test.
764
        self.assertEqual(
765
            queue_items.count(), 1,
766
            "Binary upload was not accepted when it should have been.")
767
10395.2.4 by Julian Edwards
Add copy archive binary upload overrides.
768
        # The copy archive binary published component should have been
769
        # inherited from the main archive's.
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
770
        self.switchToAdmin()
10395.2.4 by Julian Edwards
Add copy archive binary upload overrides.
771
        copy_bin_pubs = queue_items[0].realiseUpload()
772
        for pub in copy_bin_pubs:
773
            self.assertEqual(pub.component.name, restricted.name)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
774
        self.switchToUploader()
10395.2.4 by Julian Edwards
Add copy archive binary upload overrides.
775
7675.158.1 by Muharem Hrnjadovic
bug fixed.
776
    def testCopyArchiveUploadToCurrentDistro(self):
777
        """Check binary copy archive uploads to RELEASE pockets.
778
779
        Buildd binary uploads to COPY archives (resulting from successful
780
        builds) should be allowed to go to the RELEASE pocket even though
781
        the distro series has a CURRENT status.
782
783
        See bug 369512.
784
        """
785
        self._checkCopyArchiveUploadToDistro(
10054.26.1 by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series.
786
            PackagePublishingPocket.RELEASE, SeriesStatus.CURRENT)
7675.158.1 by Muharem Hrnjadovic
bug fixed.
787
788
    def testCopyArchiveUploadToSupportedDistro(self):
789
        """Check binary copy archive uploads to RELEASE pockets.
790
791
        Buildd binary uploads to COPY archives (resulting from successful
792
        builds) should be allowed to go to the RELEASE pocket even though
793
        the distro series has a SUPPORTED status.
794
795
        See bug 369512.
796
        """
797
        self._checkCopyArchiveUploadToDistro(
10054.26.1 by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series.
798
            PackagePublishingPocket.RELEASE, SeriesStatus.SUPPORTED)
7675.158.1 by Muharem Hrnjadovic
bug fixed.
799
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
800
    def testDuplicatedBinaryUploadGetsRejected(self):
801
        """The upload processor rejects duplicated binary uploads.
802
803
        Duplicated binary uploads should be rejected, because they can't
804
        be published on disk, since it will be introducing different contents
805
        to the same filename in the archive.
806
807
        Such situation happens when a source gets copied to another suite in
11149.4.1 by Jeroen Vermeulen
Test cruft in archiveuploader.
808
        the same archive. The binary rebuild will have the same
809
        (name, version) of the original binary and will certainly have a
810
        different content (at least, the ar-compressed timestamps) making it
811
        impossible to be published in the archive.
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
812
        """
813
        uploadprocessor = self.setupBreezyAndGetUploadProcessor()
814
815
        # Upload 'bar-1.0-1' source and binary to ubuntu/breezy.
816
        upload_dir = self.queueUpload("bar_1.0-1")
817
        self.processUpload(uploadprocessor, upload_dir)
11039.2.13 by Jelmer Vernooij
Fix tests.
818
        bar_source_pub = self.publishPackage('bar', '1.0-1')
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
819
        [bar_original_build] = bar_source_pub.createMissingBuilds()
820
821
        self.options.context = 'buildd'
822
        upload_dir = self.queueUpload("bar_1.0-1_binary")
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
823
        build_uploadprocessor = self.getUploadProcessor(
824
            self.layer.txn, builds=True)
11039.3.6 by Jelmer Vernooij
Avoid use of UploadOptions.buildid.
825
        self.processUpload(
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
826
            build_uploadprocessor, upload_dir, build=bar_original_build)
11039.2.13 by Jelmer Vernooij
Fix tests.
827
        [bar_binary_pub] = self.publishPackage("bar", "1.0-1", source=False)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
828
829
        # Prepare ubuntu/breezy-autotest to build sources in i386.
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
830
        self.switchToAdmin()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
831
        breezy_autotest = self.ubuntu['breezy-autotest']
832
        breezy_autotest_i386 = breezy_autotest['i386']
833
        breezy_autotest.nominatedarchindep = breezy_autotest_i386
834
        fake_chroot = self.addMockFile('fake_chroot.tar.gz')
835
        breezy_autotest_i386.addOrUpdateChroot(fake_chroot)
836
        self.layer.txn.commit()
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
837
        self.switchToUploader()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
838
12965.2.2 by Julian Edwards
Fix remaining test failures
839
        # Copy 'bar-1.0-1' source from breezy to breezy-autotest and
840
        # create a build there (this would never happen in reality, it
841
        # just suits the purposes of this test).
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
842
        bar_copied_source = bar_source_pub.copyTo(
843
            breezy_autotest, PackagePublishingPocket.RELEASE,
844
            self.ubuntu.main_archive)
12965.2.2 by Julian Edwards
Fix remaining test failures
845
        bar_copied_build = bar_copied_source.sourcepackagerelease.createBuild(
846
            breezy_autotest_i386, PackagePublishingPocket.RELEASE,
847
            self.ubuntu.main_archive)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
848
849
        # Re-upload the same 'bar-1.0-1' binary as if it was rebuilt
850
        # in breezy-autotest context.
851
        shutil.rmtree(upload_dir)
852
        self.options.distroseries = breezy_autotest.name
853
        upload_dir = self.queueUpload("bar_1.0-1_binary")
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
854
        self.processUpload(build_uploadprocessor, upload_dir,
11039.3.7 by Jelmer Vernooij
Eliminate --buildid option, pass around build objects everywhere.
855
            build=bar_copied_build)
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
856
        [duplicated_binary_upload] = breezy_autotest.getPackageUploads(
857
            status=PackageUploadStatus.NEW, name=u'bar',
858
            version=u'1.0-1', exact_match=True)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
859
860
        # The just uploaded binary cannot be accepted because its
861
        # filename 'bar_1.0-1_i386.deb' is already published in the
862
        # archive.
863
        error = self.assertRaisesAndReturnError(
864
            QueueInconsistentStateError,
865
            duplicated_binary_upload.setAccepted)
866
        self.assertEqual(
867
            str(error),
868
            "The following files are already published in Primary "
869
            "Archive for Ubuntu Linux:\nbar_1.0-1_i386.deb")
870
7675.159.2 by Muharem Hrnjadovic
added test
871
    def testBinaryUploadToCopyArchive(self):
7675.159.6 by Muharem Hrnjadovic
Revised branch with working test.
872
        """Copy archive binaries are not checked against the primary archive.
873
874
        When a buildd binary upload to a copy archive is performed the
875
        version should not be checked against the primary archive but
876
        against the copy archive in question.
877
        """
7675.159.2 by Muharem Hrnjadovic
added test
878
        uploadprocessor = self.setupBreezyAndGetUploadProcessor()
879
880
        # Upload 'bar-1.0-1' source and binary to ubuntu/breezy.
881
        upload_dir = self.queueUpload("bar_1.0-1")
882
        self.processUpload(uploadprocessor, upload_dir)
11039.2.13 by Jelmer Vernooij
Fix tests.
883
        bar_source_old = self.publishPackage('bar', '1.0-1')
7675.159.5 by Muharem Hrnjadovic
Working test (from Celso)
884
885
        # Upload 'bar-1.0-1' source and binary to ubuntu/breezy.
886
        upload_dir = self.queueUpload("bar_1.0-2")
887
        self.processUpload(uploadprocessor, upload_dir)
12505.4.1 by Robert Collins
Hopefully fix bug 727560 by permitting a much better query plan for folk querying the primary archive.
888
        bar_source_pub = self.ubuntu.main_archive.getPublishedSources(
889
            name='bar', version='1.0-2', exact_match=True).one()
7675.159.5 by Muharem Hrnjadovic
Working test (from Celso)
890
        [bar_original_build] = bar_source_pub.getBuilds()
7675.159.2 by Muharem Hrnjadovic
added test
891
892
        self.options.context = 'buildd'
7675.159.5 by Muharem Hrnjadovic
Working test (from Celso)
893
        upload_dir = self.queueUpload("bar_1.0-2_binary")
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
894
        build_uploadprocessor = self.getUploadProcessor(
895
            self.layer.txn, builds=True)
896
        self.processUpload(build_uploadprocessor, upload_dir,
11039.3.7 by Jelmer Vernooij
Eliminate --buildid option, pass around build objects everywhere.
897
            build=bar_original_build)
11039.2.13 by Jelmer Vernooij
Fix tests.
898
        [bar_binary_pub] = self.publishPackage("bar", "1.0-2", source=False)
7675.159.2 by Muharem Hrnjadovic
added test
899
7675.159.5 by Muharem Hrnjadovic
Working test (from Celso)
900
        # Create a COPY archive for building in non-virtual builds.
7675.159.2 by Muharem Hrnjadovic
added test
901
        uploader = getUtility(IPersonSet).getByName('name16')
902
        copy_archive = getUtility(IArchiveSet).new(
903
            owner=uploader, purpose=ArchivePurpose.COPY,
904
            distribution=self.ubuntu, name='no-source-uploads')
7675.159.5 by Muharem Hrnjadovic
Working test (from Celso)
905
        copy_archive.require_virtualized = False
7675.159.2 by Muharem Hrnjadovic
added test
906
7675.159.5 by Muharem Hrnjadovic
Working test (from Celso)
907
        # Copy 'bar-1.0-1' source to the COPY archive.
908
        bar_copied_source = bar_source_old.copyTo(
909
            bar_source_pub.distroseries, bar_source_pub.pocket,
7675.159.2 by Muharem Hrnjadovic
added test
910
            copy_archive)
911
        [bar_copied_build] = bar_copied_source.createMissingBuilds()
912
913
        shutil.rmtree(upload_dir)
914
        upload_dir = self.queueUpload(
915
            "bar_1.0-1_binary", "%s/ubuntu" % copy_archive.id)
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
916
        self.processUpload(build_uploadprocessor, upload_dir,
11039.3.7 by Jelmer Vernooij
Eliminate --buildid option, pass around build objects everywhere.
917
            build=bar_copied_build)
7675.159.6 by Muharem Hrnjadovic
Revised branch with working test.
918
7675.159.7 by Muharem Hrnjadovic
Revised test comment
919
        # The binary just uploaded is accepted because it's destined for a
920
        # copy archive and the PRIMARY and the COPY archives are isolated
921
        # from each other.
7675.159.5 by Muharem Hrnjadovic
Working test (from Celso)
922
        self.assertEqual(
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
923
            build_uploadprocessor.last_processed_upload.is_rejected, False)
7675.159.2 by Muharem Hrnjadovic
added test
924
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
925
    def testPartnerArchiveMissingForPartnerUploadFails(self):
926
        """A missing partner archive should produce a rejection email.
927
928
        If the partner archive is missing (i.e. there is a data problem)
929
        when a partner package is uploaded to it, a sensible rejection
930
        error email should be generated.
931
        """
932
        uploadprocessor = self.setupBreezyAndGetUploadProcessor(
933
            policy='anything')
934
935
        # Fudge the partner archive in the sample data temporarily so that
936
        # it's now a PPA instead.
937
        archive = getUtility(IArchiveSet).getByDistroPurpose(
938
            distribution=self.ubuntu, purpose=ArchivePurpose.PARTNER)
939
        removeSecurityProxy(archive).purpose = ArchivePurpose.PPA
940
941
        self.layer.txn.commit()
942
943
        # Upload a package.
944
        upload_dir = self.queueUpload("foocomm_1.0-1")
945
        self.processUpload(uploadprocessor, upload_dir)
946
947
        # Check that it was rejected appropriately.
948
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
949
        self.assertTrue(
950
            "Partner archive for distro '%s' not found" % self.ubuntu.name
951
                in raw_msg)
952
953
    def testMixedPartnerUploadFails(self):
954
        """Uploads with partner and non-partner files are rejected.
955
956
        Test that a package that has partner and non-partner files in it
957
        is rejected.  Partner uploads should be entirely partner.
958
        """
959
        uploadprocessor = self.setupBreezyAndGetUploadProcessor(
960
            policy='anything')
961
962
        # Upload a package for Breezy.
963
        upload_dir = self.queueUpload("foocomm_1.0-1-illegal-component-mix")
964
        self.processUpload(uploadprocessor, upload_dir)
965
966
        # Check that it was rejected.
967
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
968
        foo_bar = "Foo Bar <foo.bar@canonical.com>"
969
        self.assertEqual([e.strip() for e in to_addrs], [foo_bar])
970
        self.assertTrue(
971
            "Cannot mix partner files with non-partner." in raw_msg,
972
            "Expected email containing 'Cannot mix partner files with "
973
            "non-partner.', got:\n%s" % raw_msg)
974
7675.386.6 by Muharem Hrnjadovic
Passes Q/A on Soyuz dogfood.
975
    def testPartnerReusingOrigFromPartner(self):
976
        """Partner uploads reuse 'orig.tar.gz' from the partner archive."""
7675.386.1 by Muharem Hrnjadovic
testPartnerReusingOrigFromUbuntu() reproduces the problem.
977
        # Make the official bar orig.tar.gz available in the system.
978
        uploadprocessor = self.setupBreezyAndGetUploadProcessor(
979
            policy='absolutely-anything')
980
981
        upload_dir = self.queueUpload("foocomm_1.0-1")
982
        self.processUpload(uploadprocessor, upload_dir)
983
984
        self.assertEqual(
985
            uploadprocessor.last_processed_upload.queue_root.status,
986
            PackageUploadStatus.NEW)
987
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
988
        [queue_item] = self.breezy.getPackageUploads(
989
            status=PackageUploadStatus.NEW, name=u"foocomm",
990
            version=u"1.0-1", exact_match=True)
7675.386.1 by Muharem Hrnjadovic
testPartnerReusingOrigFromUbuntu() reproduces the problem.
991
        queue_item.setAccepted()
992
        queue_item.realiseUpload()
993
        self.layer.commit()
994
995
        archive = getUtility(IArchiveSet).getByDistroPurpose(
996
            distribution=self.ubuntu, purpose=ArchivePurpose.PARTNER)
997
        try:
12019.12.1 by William Grant
Eliminate Distribution.getFileByName. There's a perfectly good alternative on Archive.
998
            archive.getFileByName('foocomm_1.0.orig.tar.gz')
7675.386.1 by Muharem Hrnjadovic
testPartnerReusingOrigFromUbuntu() reproduces the problem.
999
        except NotFoundError:
1000
            self.fail('foocomm_1.0.orig.tar.gz is not yet published.')
1001
1002
        # Please note: this upload goes to the Ubuntu main archive.
1003
        upload_dir = self.queueUpload("foocomm_1.0-3")
1004
        self.processUpload(uploadprocessor, upload_dir)
1005
        # Discard the announcement email and check the acceptance message
1006
        # content.
1007
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1008
        msg = message_from_string(raw_msg)
1009
        # This is now a MIMEMultipart message.
1010
        body = msg.get_payload(0)
1011
        body = body.get_payload(decode=True)
7675.386.2 by Muharem Hrnjadovic
Corrected test.
1012
7675.386.5 by Muharem Hrnjadovic
Slightly improved test.
1013
        self.assertEqual(
1014
            '[ubuntu/breezy] foocomm 1.0-3 (Accepted)', msg['Subject'])
7675.386.1 by Muharem Hrnjadovic
testPartnerReusingOrigFromUbuntu() reproduces the problem.
1015
        self.assertFalse(
7675.386.2 by Muharem Hrnjadovic
Corrected test.
1016
            'Unable to find foocomm_1.0.orig.tar.gz in upload or '
1017
            'distribution.' in body,
1018
            'Unable to find foocomm_1.0.orig.tar.gz')
7675.386.1 by Muharem Hrnjadovic
testPartnerReusingOrigFromUbuntu() reproduces the problem.
1019
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1020
    def testPartnerUpload(self):
1021
        """Partner packages should be uploaded to the partner archive.
1022
1023
        Packages that have files in the 'partner' component should be
1024
        uploaded to a separate IArchive that has a purpose of
1025
        ArchivePurpose.PARTNER.
1026
        """
1027
        uploadprocessor = self.setupBreezyAndGetUploadProcessor(
1028
            policy='anything')
1029
1030
        # Upload a package for Breezy.
1031
        upload_dir = self.queueUpload("foocomm_1.0-1")
1032
        self.processUpload(uploadprocessor, upload_dir)
1033
1034
        # Check it went ok to the NEW queue and all is going well so far.
1035
        self._checkPartnerUploadEmailSuccess()
1036
1037
        # Find the sourcepackagerelease and check its component.
1038
        foocomm_name = SourcePackageName.selectOneBy(name="foocomm")
1039
        foocomm_spr = SourcePackageRelease.selectOneBy(
1040
           sourcepackagename=foocomm_name)
1041
        self.assertEqual(foocomm_spr.component.name, 'partner')
1042
1043
        # Check that the right archive was picked.
1044
        self.assertEqual(foocomm_spr.upload_archive.description,
1045
            'Partner archive')
1046
1047
        # Accept and publish the upload.
1048
        partner_archive = getUtility(IArchiveSet).getByDistroPurpose(
1049
            self.ubuntu, ArchivePurpose.PARTNER)
1050
        self.assertTrue(partner_archive)
11039.2.13 by Jelmer Vernooij
Fix tests.
1051
        self.publishPackage("foocomm", "1.0-1", archive=partner_archive)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1052
1053
        # Check the publishing record's archive and component.
1054
        foocomm_spph = SourcePackagePublishingHistory.selectOneBy(
1055
            sourcepackagerelease=foocomm_spr)
1056
        self.assertEqual(foocomm_spph.archive.description,
1057
            'Partner archive')
1058
        self.assertEqual(foocomm_spph.component.name,
1059
            'partner')
1060
1061
        # Fudge a build for foocomm so that it's not in the partner archive.
1062
        # We can then test that uploading a binary package must match the
1063
        # build's archive.
1064
        foocomm_build = foocomm_spr.createBuild(
1065
            self.breezy['i386'], PackagePublishingPocket.RELEASE,
1066
            self.ubuntu.main_archive)
1067
        self.layer.txn.commit()
1068
        upload_dir = self.queueUpload("foocomm_1.0-1_binary")
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
1069
        build_uploadprocessor = self.getUploadProcessor(
1070
            self.layer.txn, builds=True)
11039.3.6 by Jelmer Vernooij
Avoid use of UploadOptions.buildid.
1071
        self.processUpload(
12221.13.10 by Aaron Bentley
Start removing build from processChangesFile.
1072
            build_uploadprocessor, upload_dir, build=foocomm_build)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1073
1074
        contents = [
1075
            "Subject: foocomm_1.0-1_i386.changes rejected",
1076
            "Attempt to upload binaries specifying build 31, "
1077
            "where they don't fit."]
1078
        self.assertEmail(contents)
1079
11039.3.6 by Jelmer Vernooij
Avoid use of UploadOptions.buildid.
1080
        # Reset upload queue directory for a new upload.
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1081
        shutil.rmtree(upload_dir)
1082
1083
        # Now upload a binary package of 'foocomm', letting a new build record
1084
        # with appropriate data be created by the uploadprocessor.
1085
        upload_dir = self.queueUpload("foocomm_1.0-1_binary")
1086
        self.processUpload(uploadprocessor, upload_dir)
1087
1088
        # Find the binarypackagerelease and check its component.
1089
        foocomm_binname = BinaryPackageName.selectOneBy(name="foocomm")
1090
        foocomm_bpr = BinaryPackageRelease.selectOneBy(
1091
            binarypackagename=foocomm_binname)
1092
        self.assertEqual(foocomm_bpr.component.name, 'partner')
1093
1094
        # Publish the upload so we can check the publishing record.
11039.2.13 by Jelmer Vernooij
Fix tests.
1095
        self.publishPackage("foocomm", "1.0-1", source=False)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1096
1097
        # Check the publishing record's archive and component.
1098
        foocomm_bpph = BinaryPackagePublishingHistory.selectOneBy(
1099
            binarypackagerelease=foocomm_bpr)
1100
        self.assertEqual(foocomm_bpph.archive.description,
1101
            'Partner archive')
1102
        self.assertEqual(foocomm_bpph.component.name,
1103
            'partner')
1104
1105
    def testUploadAncestry(self):
1106
        """Check that an upload correctly finds any file ancestors.
1107
1108
        When uploading a package, any previous versions will have
1109
        ancestor files which affects whether this upload is NEW or not.
1110
        In particular, when an upload's archive has been overridden,
1111
        we must make sure that the ancestry check looks in all the
1112
        distro archives.  This can be done by two partner package
1113
        uploads, as partner packages have their archive overridden.
1114
        """
1115
        # Use the 'absolutely-anything' policy which allows unsigned
1116
        # DSC and changes files.
1117
        uploadprocessor = self.setupBreezyAndGetUploadProcessor(
1118
            policy='absolutely-anything')
1119
1120
        # Upload a package for Breezy.
1121
        upload_dir = self.queueUpload("foocomm_1.0-1")
1122
        self.processUpload(uploadprocessor, upload_dir)
1123
1124
        # Check it went ok to the NEW queue and all is going well so far.
1125
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1126
        self.assertTrue(
1127
            "NEW" in raw_msg,
1128
            "Expected email containing 'NEW', got:\n%s"
1129
            % raw_msg)
1130
1131
        # Accept and publish the upload.
1132
        partner_archive = getUtility(IArchiveSet).getByDistroPurpose(
1133
            self.ubuntu, ArchivePurpose.PARTNER)
11039.2.13 by Jelmer Vernooij
Fix tests.
1134
        self.publishPackage("foocomm", "1.0-1", archive=partner_archive)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1135
1136
        # Now do the same thing with a binary package.
1137
        upload_dir = self.queueUpload("foocomm_1.0-1_binary")
1138
        self.processUpload(uploadprocessor, upload_dir)
1139
1140
        # Accept and publish the upload.
11039.2.13 by Jelmer Vernooij
Fix tests.
1141
        self.publishPackage("foocomm", "1.0-1", source=False,
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1142
                             archive=partner_archive)
1143
1144
        # Upload the next source version of the package.
1145
        upload_dir = self.queueUpload("foocomm_1.0-2")
1146
        self.processUpload(uploadprocessor, upload_dir)
1147
1148
        # Check the upload is in the DONE queue since single source uploads
1149
        # with ancestry (previously uploaded) will skip the ACCEPTED state.
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
1150
        queue_items = self.breezy.getPackageUploads(
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1151
            status=PackageUploadStatus.DONE,
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
1152
            version=u"1.0-2",
1153
            name=u"foocomm")
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1154
        self.assertEqual(queue_items.count(), 1)
1155
1156
        # Single source uploads also get their corrsponding builds created
1157
        # at upload-time. 'foocomm' only builds in 'i386', thus only one
1158
        # build gets created.
12505.4.1 by Robert Collins
Hopefully fix bug 727560 by permitting a much better query plan for folk querying the primary archive.
1159
        foocomm_source = partner_archive.getPublishedSources(
1160
            name='foocomm', version='1.0-2').one()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1161
        [build] = foocomm_source.sourcepackagerelease.builds
1162
        self.assertEqual(
1163
            build.title,
1164
            'i386 build of foocomm 1.0-2 in ubuntu breezy RELEASE')
7675.687.121 by Michael Nelson
Ensured archiveuploader tests are passing.
1165
        self.assertEqual(build.status.name, 'NEEDSBUILD')
8322.9.2 by Celso Providelo
fixing test failures.
1166
        self.assertTrue(build.buildqueue_record.lastscore is not None)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1167
1168
        # Upload the next binary version of the package.
1169
        upload_dir = self.queueUpload("foocomm_1.0-2_binary")
1170
        self.processUpload(uploadprocessor, upload_dir)
1171
1172
        # Check that the binary upload was accepted:
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
1173
        queue_items = self.breezy.getPackageUploads(
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1174
            status=PackageUploadStatus.ACCEPTED,
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
1175
            version=u"1.0-2",
1176
            name=u"foocomm")
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1177
        self.assertEqual(queue_items.count(), 1)
1178
1179
    def testPartnerUploadToProposedPocket(self):
1180
        """Upload a partner package to the proposed pocket."""
1181
        self.setupBreezy()
10054.26.1 by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series.
1182
        self.breezy.status = SeriesStatus.CURRENT
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1183
        self.layer.txn.commit()
1184
        self.options.context = 'insecure'
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1185
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1186
1187
        # Upload a package for Breezy.
1188
        upload_dir = self.queueUpload("foocomm_1.0-1_proposed")
1189
        self.processUpload(uploadprocessor, upload_dir)
1190
1191
        self._checkPartnerUploadEmailSuccess()
1192
1193
    def testPartnerUploadToReleasePocketInStableDistroseries(self):
1194
        """Partner package upload to release pocket in stable distroseries.
1195
1196
        Uploading a partner package to the release pocket in a stable
1197
        distroseries is allowed.
1198
        """
1199
        self.setupBreezy()
10054.26.1 by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series.
1200
        self.breezy.status = SeriesStatus.CURRENT
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1201
        self.layer.txn.commit()
1202
        self.options.context = 'insecure'
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1203
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1204
1205
        # Upload a package for Breezy.
1206
        upload_dir = self.queueUpload("foocomm_1.0-1")
1207
        self.processUpload(uploadprocessor, upload_dir)
1208
1209
        self._checkPartnerUploadEmailSuccess()
1210
1211
    def _uploadPartnerToNonReleasePocketAndCheckFail(self):
1212
        """Upload partner package to non-release pocket.
1213
1214
        Helper function to upload a partner package to a non-release
1215
        pocket and ensure it fails."""
1216
        # Set up the uploadprocessor with appropriate options and logger.
14104.6.13 by Robert Collins
no more getLastOops for test_uploadprocessor.
1217
        new_index = len(self.oopses)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1218
        self.options.context = 'insecure'
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1219
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1220
1221
        # Upload a package for Breezy.
1222
        upload_dir = self.queueUpload("foocomm_1.0-1_updates")
1223
        self.processUpload(uploadprocessor, upload_dir)
1224
1225
        # Check it is rejected.
1226
        expect_msg = ("Partner uploads must be for the RELEASE or "
1227
                      "PROPOSED pocket.")
1228
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1229
        self.assertTrue(
1230
            expect_msg in raw_msg,
1231
            "Expected email with %s, got:\n%s" % (expect_msg, raw_msg))
1232
10680.3.9 by Jelmer Vernooij
Handle another OOPS.
1233
        # And an oops should be filed for the error.
14104.6.13 by Robert Collins
no more getLastOops for test_uploadprocessor.
1234
        error_report = self.oopses[new_index]
13067.2.16 by William Grant
Fix two archiveuploader tests... signature verification is now done before tagfile parsing, so the error is different.
1235
        expected_explanation = (
1236
            "Verification failed 3 times: ['No data', 'No data', 'No data']")
14104.6.13 by Robert Collins
no more getLastOops for test_uploadprocessor.
1237
        self.assertIn(expected_explanation, error_report['value'])
10680.3.9 by Jelmer Vernooij
Handle another OOPS.
1238
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1239
        # Housekeeping so the next test won't fail.
1240
        shutil.rmtree(upload_dir)
1241
14158.1.5 by Julian Edwards
fix lint
1242
    def disabled_testPartnerUploadToNonReleaseOrProposedPocket(self):
13660.1.15 by Robert Collins
Disable broken test testPartnerUploadToNonReleaseOrProposedPocket.
1243
        # XXX: bug 825486 robertcollins 2011-08-13 this test is broken.
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1244
        """Test partner upload pockets.
1245
1246
        Partner uploads must be targeted to the RELEASE pocket only,
1247
        """
1248
        self.setupBreezy()
1249
1250
        # Check unstable states:
10054.26.1 by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series.
1251
        self.breezy.status = SeriesStatus.DEVELOPMENT
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1252
        self.layer.txn.commit()
1253
        self._uploadPartnerToNonReleasePocketAndCheckFail()
1254
10054.26.1 by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series.
1255
        self.breezy.status = SeriesStatus.EXPERIMENTAL
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1256
        self.layer.txn.commit()
1257
        self._uploadPartnerToNonReleasePocketAndCheckFail()
1258
1259
        # Check stable states:
1260
10054.26.1 by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series.
1261
        self.breezy.status = SeriesStatus.CURRENT
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1262
        self.layer.txn.commit()
1263
        self._uploadPartnerToNonReleasePocketAndCheckFail()
1264
10054.26.1 by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series.
1265
        self.breezy.status = SeriesStatus.SUPPORTED
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1266
        self.layer.txn.commit()
1267
        self._uploadPartnerToNonReleasePocketAndCheckFail()
1268
8233.4.1 by Celso Providelo
Reject uploads for unknown sections or components (latter was missing tests only).
1269
    def testUploadWithUnknownSectionIsRejected(self):
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1270
        uploadprocessor = self.setupBreezyAndGetUploadProcessor()
1271
        upload_dir = self.queueUpload("bar_1.0-1_bad_section")
1272
        self.processUpload(uploadprocessor, upload_dir)
8233.4.1 by Celso Providelo
Reject uploads for unknown sections or components (latter was missing tests only).
1273
        self.assertEqual(
1274
            uploadprocessor.last_processed_upload.rejection_message,
1275
            "bar_1.0-1.dsc: Unknown section 'badsection'\n"
1276
            "bar_1.0.orig.tar.gz: Unknown section 'badsection'\n"
1277
            "bar_1.0-1.diff.gz: Unknown section 'badsection'\n"
1278
            "Further error processing not possible because of a "
1279
            "critical previous error.")
1280
1281
    def testUploadWithUnknownComponentIsRejected(self):
1282
        uploadprocessor = self.setupBreezyAndGetUploadProcessor()
1283
        upload_dir = self.queueUpload("bar_1.0-1_contrib_component")
1284
        self.processUpload(uploadprocessor, upload_dir)
1285
        self.assertEqual(
1286
            uploadprocessor.last_processed_upload.rejection_message,
1287
            "bar_1.0-1.dsc: Unknown component 'contrib'\n"
1288
            "bar_1.0.orig.tar.gz: Unknown component 'contrib'\n"
1289
            "bar_1.0-1.diff.gz: Unknown component 'contrib'\n"
1290
            "Further error processing not possible because of a "
1291
            "critical previous error.")
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1292
8191.1.4 by Muharem Hrnjadovic
made test stricter
1293
    def testSourceUploadToBuilddPath(self):
1294
        """Source uploads to buildd upload paths are not permitted."""
1295
        ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
8191.1.5 by Muharem Hrnjadovic
Celso's review comments
1296
        primary = ubuntu.main_archive
8191.1.2 by Muharem Hrnjadovic
added 2 more tests for source/binary uploads to copy archives.
1297
1298
        uploadprocessor = self.setupBreezyAndGetUploadProcessor()
8191.1.4 by Muharem Hrnjadovic
made test stricter
1299
        upload_dir = self.queueUpload("bar_1.0-1", "%s/ubuntu" % primary.id)
8191.1.2 by Muharem Hrnjadovic
added 2 more tests for source/binary uploads to copy archives.
1300
        self.processUpload(uploadprocessor, upload_dir)
1301
1302
        # Check that the sourceful upload to the copy archive is rejected.
1303
        contents = [
11149.4.1 by Jeroen Vermeulen
Test cruft in archiveuploader.
1304
            "Invalid upload path (1/ubuntu) for this policy (insecure)"]
8191.1.2 by Muharem Hrnjadovic
added 2 more tests for source/binary uploads to copy archives.
1305
        self.assertEmail(contents=contents, recipients=[])
1306
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1307
    # Uploads that are new should have the component overridden
1308
    # such that:
1309
    #   'contrib' -> 'multiverse'
1310
    #   'non-free' -> 'multiverse'
1311
    #   everything else -> 'universe'
1312
    #
1313
    # This is to relieve the archive admins of some work where this is
1314
    # the default action taken anyway.
1315
    #
1316
    # The following three tests check this.
1317
    def checkComponentOverride(self, upload_dir_name,
1318
                               expected_component_name):
1319
        """Helper function to check overridden component names.
1320
8233.4.1 by Celso Providelo
Reject uploads for unknown sections or components (latter was missing tests only).
1321
        Upload a 'bar' package from upload_dir_name, then
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1322
        inspect the package 'bar' in the NEW queue and ensure its
1323
        overridden component matches expected_component_name.
1324
1325
        The original component comes from the source package contained
1326
        in upload_dir_name.
1327
        """
1328
        uploadprocessor = self.setupBreezyAndGetUploadProcessor()
1329
        upload_dir = self.queueUpload(upload_dir_name)
1330
        self.processUpload(uploadprocessor, upload_dir)
1331
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
1332
        queue_items = self.breezy.getPackageUploads(
1333
            status=PackageUploadStatus.NEW, name=u"bar",
1334
            version=u"1.0-1", exact_match=True)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1335
        [queue_item] = queue_items
1336
        self.assertEqual(
1337
            queue_item.sourcepackagerelease.component.name,
1338
            expected_component_name)
1339
1340
    def testUploadContribComponentOverride(self):
1341
        """Test the overriding of the contrib component on uploads."""
1342
        # The component contrib does not exist in the sample data, so
1343
        # add it here.
1344
        Component(name='contrib')
1345
1346
        # Test it.
1347
        self.checkComponentOverride(
1348
            "bar_1.0-1_contrib_component", "multiverse")
1349
1350
    def testUploadNonfreeComponentOverride(self):
1351
        """Test the overriding of the non-free component on uploads."""
1352
        # The component non-free does not exist in the sample data, so
1353
        # add it here.
1354
        Component(name='non-free')
1355
1356
        # Test it.
1357
        self.checkComponentOverride(
1358
            "bar_1.0-1_nonfree_component", "multiverse")
1359
1360
    def testUploadDefaultComponentOverride(self):
1361
        """Test the overriding of the component on uploads.
1362
1363
        Components other than non-free and contrib should override to
1364
        universe.
1365
        """
1366
        self.checkComponentOverride("bar_1.0-1", "universe")
1367
8053.1.3 by Muharem Hrnjadovic
moved the OOPS creation facility into the UploadProcessor class where it belongs.
1368
    def testOopsCreation(self):
14066.2.5 by William Grant
Review comments.
1369
        """Test that an unhandled exception generates an OOPS."""
11039.2.7 by Jelmer Vernooij
Cherrypick existing work.
1370
        self.options.builds = False
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1371
        processor = self.getUploadProcessor(self.layer.txn)
8053.1.3 by Muharem Hrnjadovic
moved the OOPS creation facility into the UploadProcessor class where it belongs.
1372
14066.2.1 by William Grant
testOopsCreation no longer depends on bad uploads producing OOPSes.
1373
        self.queueUpload("foocomm_1.0-1_proposed")
1374
14066.2.5 by William Grant
Review comments.
1375
        # Inject an unhandled exception into the upload processor.
14066.2.1 by William Grant
testOopsCreation no longer depends on bad uploads producing OOPSes.
1376
        class SomeException(Exception):
1377
            pass
1378
        self.useFixture(
1379
            MonkeyPatch(
1380
                'lp.archiveuploader.nascentupload.NascentUpload.'
1381
                'from_changesfile_path',
14066.2.5 by William Grant
Review comments.
1382
                FakeMethod(failure=SomeException("I am an explanation."))))
8053.1.5 by Muharem Hrnjadovic
fixed docstring and superfluous exception in the test code.
1383
8053.1.6 by Muharem Hrnjadovic
simplified test.
1384
        processor.processUploadQueue()
8053.1.3 by Muharem Hrnjadovic
moved the OOPS creation facility into the UploadProcessor class where it belongs.
1385
14104.6.13 by Robert Collins
no more getLastOops for test_uploadprocessor.
1386
        error_report = self.oopses[0]
1387
        self.assertEqual('SomeException', error_report['type'])
1388
        self.assertIn("I am an explanation", error_report['tb_text'])
8053.1.3 by Muharem Hrnjadovic
moved the OOPS creation facility into the UploadProcessor class where it belongs.
1389
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1390
    def testLZMADebUpload(self):
1391
        """Make sure that data files compressed with lzma in Debs work.
1392
11348.1.1 by Colin Watson
Add support for data.tar.xz .deb members.
1393
        Each Deb contains a data.tar.xxx file where xxx is one of gz, bz2,
1394
        lzma or xz.  Here we make sure that lzma works.
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1395
        """
1396
        # Setup the test.
1397
        self.setupBreezy()
1398
        self.layer.txn.commit()
1399
        self.options.context = 'absolutely-anything'
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1400
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1401
1402
        # Upload the source first to enable the binary later:
1403
        upload_dir = self.queueUpload("bar_1.0-1_lzma")
1404
        self.processUpload(uploadprocessor, upload_dir)
1405
        # Make sure it went ok:
1406
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1407
        self.assertTrue(
1408
            "rejected" not in raw_msg,
1409
            "Failed to upload bar source:\n%s" % raw_msg)
11039.2.13 by Jelmer Vernooij
Fix tests.
1410
        self.publishPackage("bar", "1.0-1")
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1411
        # Clear out emails generated during upload.
13233.1.1 by Jeroen Vermeulen
Lint.
1412
        pop_notifications()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1413
8053.2.1 by Julian Edwards
Remove the LZMA pre-depends check for dpkg versions.
1414
        # Upload a binary lzma-compressed package.
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1415
        upload_dir = self.queueUpload("bar_1.0-1_lzma_binary")
1416
        self.processUpload(uploadprocessor, upload_dir)
1417
1418
        # Successful binary uploads won't generate any email.
1419
        if len(stub.test_emails) != 0:
1420
            from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1421
        self.assertEqual(
1422
            len(stub.test_emails), 0,
1423
            "Expected no emails!  Actually got:\n%s" % raw_msg)
1424
1425
        # Check in the queue to see if it really made it:
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
1426
        queue_items = self.breezy.getPackageUploads(
1427
            status=PackageUploadStatus.NEW, name=u"bar",
1428
            version=u"1.0-1", exact_match=True)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1429
        self.assertEqual(
1430
            queue_items.count(), 1,
1431
            "Expected one 'bar' item in the queue, actually got %d."
1432
                % queue_items.count())
1433
11348.1.1 by Colin Watson
Add support for data.tar.xz .deb members.
1434
    def testXZDebUpload(self):
1435
        """Make sure that data files compressed with xz in Debs work.
1436
1437
        Each Deb contains a data.tar.xxx file where xxx is one of gz, bz2,
1438
        lzma or xz.  Here we make sure that xz works.
1439
        """
1440
        # Setup the test.
1441
        self.setupBreezy()
1442
        self.layer.txn.commit()
1443
        self.options.context = 'absolutely-anything'
1444
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
1445
1446
        # Upload the source first to enable the binary later:
1447
        upload_dir = self.queueUpload("bar_1.0-1_xz")
1448
        self.processUpload(uploadprocessor, upload_dir)
1449
        # Make sure it went ok:
1450
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1451
        self.assertTrue(
1452
            "rejected" not in raw_msg,
1453
            "Failed to upload bar source:\n%s" % raw_msg)
1454
        self.publishPackage("bar", "1.0-1")
1455
        # Clear out emails generated during upload.
11348.1.6 by Colin Watson
lint
1456
        pop_notifications()
11348.1.1 by Colin Watson
Add support for data.tar.xz .deb members.
1457
1458
        # Upload a binary xz-compressed package.
1459
        upload_dir = self.queueUpload("bar_1.0-1_xz_binary")
1460
        self.processUpload(uploadprocessor, upload_dir)
1461
1462
        # Successful binary uploads won't generate any email.
1463
        if len(stub.test_emails) != 0:
1464
            from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1465
        self.assertEqual(
1466
            len(stub.test_emails), 0,
1467
            "Expected no emails!  Actually got:\n%s" % raw_msg)
1468
1469
        # Check in the queue to see if it really made it:
11348.1.4 by Colin Watson
Update for getQueueItems removal.
1470
        queue_items = self.breezy.getPackageUploads(
1471
            status=PackageUploadStatus.NEW, name=u"bar",
1472
            version=u"1.0-1", exact_match=True)
11348.1.1 by Colin Watson
Add support for data.tar.xz .deb members.
1473
        self.assertEqual(
1474
            queue_items.count(), 1,
1475
            "Expected one 'bar' item in the queue, actually got %d."
1476
                % queue_items.count())
1477
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1478
    def testUploadResultingInNoBuilds(self):
7264.4.1 by Celso Providelo
Fixing bug #283247, now primary archives can accept source uploads that only build in unsupported architectures. This feature will be used for bootstraping new architectures.
1479
        """Source uploads resulting in no builds.
1480
1481
        Source uploads building only in unsupported architectures are
1482
        accepted in primary archives.
1483
1484
        If a new source upload results in no builds, it can be accepted
1485
        from queue.
1486
1487
        If a auto-accepted source upload results in no builds, like a
1488
        known ubuntu or a PPA upload, it will made its way to the
1489
        repository.
1490
1491
        This scenario usually happens for sources targeted to
1492
        architectures not yet supported in ubuntu, but for which we
1493
        have plans to support soon.
1494
1495
        Once a chroot is available for the architecture being prepared,
1496
        a `queue-builder` run will be required to create the missing
1497
        builds.
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1498
        """
1499
        self.setupBreezy()
1500
1501
        # New 'biscuit' source building in 'm68k' only can't be accepted.
1502
        # The archive-admin will be forced to reject it manually.
1503
        packager = FakePackager(
1504
            'biscuit', '1.0', 'foo.bar@canonical.com-passwordless.sec')
1505
        packager.buildUpstream(suite=self.breezy.name, arch="m68k")
1506
        packager.buildSource()
1507
        upload = packager.uploadSourceVersion(
1508
            '1.0-1', auto_accept=False)
1509
        upload.do_accept(notify=False)
1510
1511
        # Let's commit because acceptFromQueue needs to access the
1512
        # just-uploaded changesfile from librarian.
1513
        self.layer.txn.commit()
1514
13144.1.1 by Steve Kowalik
Drop announce_list from notify() and acceptFromQueue().
1515
        upload.queue_root.acceptFromQueue()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1516
1517
        # 'biscuit_1.0-2' building on i386 get accepted and published.
1518
        packager.buildVersion('1.0-2', suite=self.breezy.name, arch="i386")
1519
        packager.buildSource()
1520
        biscuit_pub = packager.uploadSourceVersion('1.0-2')
1521
        self.assertEqual(biscuit_pub.status, PackagePublishingStatus.PENDING)
1522
7264.4.1 by Celso Providelo
Fixing bug #283247, now primary archives can accept source uploads that only build in unsupported architectures. This feature will be used for bootstraping new architectures.
1523
        # A auto-accepted version building only in m68k, which also doesn't
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1524
        # exist in breezy gets rejected yet in upload time (meaning, the
1525
        # uploader will receive a rejection email).
1526
        packager.buildVersion('1.0-3', suite=self.breezy.name, arch="m68k")
1527
        packager.buildSource()
1528
        upload = packager.uploadSourceVersion('1.0-3', auto_accept=False)
1529
7264.4.1 by Celso Providelo
Fixing bug #283247, now primary archives can accept source uploads that only build in unsupported architectures. This feature will be used for bootstraping new architectures.
1530
        upload.storeObjectsInDatabase()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1531
1532
    def testPackageUploadPermissions(self):
1533
        """Test package-specific upload permissions.
7264.4.1 by Celso Providelo
Fixing bug #283247, now primary archives can accept source uploads that only build in unsupported architectures. This feature will be used for bootstraping new architectures.
1534
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1535
        Someone who has upload permissions to a component, but also
1536
        has permission to a specific package in a different component
1537
        should be able to upload that package. (Bug #250618)
1538
        """
1539
        self.setupBreezy()
1540
        # Remove our favourite uploader from the team that has
1541
        # permissions to all components at upload time.
1542
        uploader = getUtility(IPersonSet).getByName('name16')
1543
        distro_team = getUtility(IPersonSet).getByName('ubuntu-team')
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1544
        self.switchToAdmin()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1545
        uploader.leave(distro_team)
1546
1547
        # Now give name16 specific permissions to "restricted" only.
1548
        restricted = getUtility(IComponentSet)["restricted"]
1549
        ArchivePermission(
1550
            archive=self.ubuntu.main_archive,
1551
            permission=ArchivePermissionType.UPLOAD, person=uploader,
1552
            component=restricted)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1553
        self.switchToUploader()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1554
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1555
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1556
1557
        # Upload the first version and accept it to make it known in
1558
        # Ubuntu.  The uploader has rights to upload NEW packages to
1559
        # components that he does not have direct rights to.
1560
        upload_dir = self.queueUpload("bar_1.0-1")
1561
        self.processUpload(uploadprocessor, upload_dir)
13233.1.1 by Jeroen Vermeulen
Lint.
1562
        self.publishPackage('bar', '1.0-1')
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1563
        # Clear out emails generated during upload.
13233.1.1 by Jeroen Vermeulen
Lint.
1564
        pop_notifications()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1565
1566
        # Now upload the next version.
1567
        upload_dir = self.queueUpload("bar_1.0-2")
1568
        self.processUpload(uploadprocessor, upload_dir)
1569
1570
        # Make sure it failed.
1571
        self.assertEqual(
1572
            uploadprocessor.last_processed_upload.rejection_message,
7675.296.47 by Jonathan Lange
Use the extracted version of the ACL verifier. Change a couple of expected
1573
            u"Signer is not permitted to upload to the component 'universe'.")
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1574
1575
        # Now add permission to upload "bar" for name16.
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1576
        self.switchToAdmin()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1577
        bar_package = getUtility(ISourcePackageNameSet).queryByName("bar")
1578
        ArchivePermission(
1579
            archive=self.ubuntu.main_archive,
1580
            permission=ArchivePermissionType.UPLOAD, person=uploader,
1581
            sourcepackagename=bar_package)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1582
        self.switchToUploader()
6973.2.1 by Julian Edwards
Move tests from ftests to tests for archiveuploader
1583
1584
        # Upload the package again.
1585
        self.processUpload(uploadprocessor, upload_dir)
1586
1587
        # Check that it worked,
1588
        status = uploadprocessor.last_processed_upload.queue_root.status
1589
        self.assertEqual(
1590
            status, PackageUploadStatus.DONE,
1591
            "Expected NEW status, got %s" % status.value)
1592
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1593
    def testPackagesetUploadPermissions(self):
1594
        """Test package set based upload permissions."""
1595
        self.setupBreezy()
1596
        # Remove our favourite uploader from the team that has
1597
        # permissions to all components at upload time.
1598
        uploader = getUtility(IPersonSet).getByName('name16')
1599
        distro_team = getUtility(IPersonSet).getByName('ubuntu-team')
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1600
        self.switchToAdmin()
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1601
        uploader.leave(distro_team)
1602
1603
        # Now give name16 specific permissions to "restricted" only.
1604
        restricted = getUtility(IComponentSet)["restricted"]
1605
        ArchivePermission(
1606
            archive=self.ubuntu.main_archive,
1607
            permission=ArchivePermissionType.UPLOAD, person=uploader,
1608
            component=restricted)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1609
        self.switchToUploader()
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1610
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1611
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1612
1613
        # Upload the first version and accept it to make it known in
1614
        # Ubuntu.  The uploader has rights to upload NEW packages to
1615
        # components that he does not have direct rights to.
1616
        upload_dir = self.queueUpload("bar_1.0-1")
1617
        self.processUpload(uploadprocessor, upload_dir)
13233.1.1 by Jeroen Vermeulen
Lint.
1618
        self.publishPackage('bar', '1.0-1')
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1619
        # Clear out emails generated during upload.
13233.1.1 by Jeroen Vermeulen
Lint.
1620
        pop_notifications()
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1621
1622
        # Now upload the next version.
1623
        upload_dir = self.queueUpload("bar_1.0-2")
1624
        self.processUpload(uploadprocessor, upload_dir)
1625
1626
        # Make sure it failed.
1627
        self.assertEqual(
1628
            uploadprocessor.last_processed_upload.rejection_message,
7675.296.47 by Jonathan Lange
Use the extracted version of the ACL verifier. Change a couple of expected
1629
            "Signer is not permitted to upload to the component 'universe'.")
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1630
1631
        # Now put in place a package set, add 'bar' to it and define a
1632
        # permission for the former.
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1633
        self.switchToAdmin()
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1634
        bar_package = getUtility(ISourcePackageNameSet).queryByName("bar")
1635
        ap_set = getUtility(IArchivePermissionSet)
1636
        ps_set = getUtility(IPackagesetSet)
1637
        foo_ps = ps_set.new(
7675.384.2 by Muharem Hrnjadovic
Upload test works as well.
1638
            u'foo-pkg-set', u'Packages that require special care.', uploader,
1639
            distroseries=self.ubuntu['grumpy'])
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1640
        self.layer.txn.commit()
1641
11149.4.1 by Jeroen Vermeulen
Test cruft in archiveuploader.
1642
        foo_ps.add((bar_package, ))
8823.1.5 by Muharem Hrnjadovic
fixed upload processor test
1643
        ap_set.newPackagesetUploader(
1644
            self.ubuntu.main_archive, uploader, foo_ps)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1645
        self.switchToUploader()
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1646
1647
        # The uploader now does have a package set based upload permissions
7675.384.2 by Muharem Hrnjadovic
Upload test works as well.
1648
        # to 'bar' in 'grumpy' but not in 'breezy'.
1649
        self.assertTrue(
1650
            ap_set.isSourceUploadAllowed(
1651
                self.ubuntu.main_archive, 'bar', uploader,
1652
                self.ubuntu['grumpy']))
1653
        self.assertFalse(
1654
            ap_set.isSourceUploadAllowed(
1655
                self.ubuntu.main_archive, 'bar', uploader, self.breezy))
1656
1657
        # Upload the package again.
1658
        self.processUpload(uploadprocessor, upload_dir)
1659
1660
        # Check that it failed (permissions were granted for wrong series).
1661
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1662
        msg = message_from_string(raw_msg)
1663
        self.assertEqual(
1664
            msg['Subject'], 'bar_1.0-2_source.changes rejected')
1665
1666
        # Grant the permissions in the proper series.
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1667
        self.switchToAdmin()
7675.384.2 by Muharem Hrnjadovic
Upload test works as well.
1668
        breezy_ps = ps_set.new(
1669
            u'foo-pkg-set-breezy', u'Packages that require special care.',
1670
            uploader, distroseries=self.breezy)
11149.4.1 by Jeroen Vermeulen
Test cruft in archiveuploader.
1671
        breezy_ps.add((bar_package, ))
7675.384.2 by Muharem Hrnjadovic
Upload test works as well.
1672
        ap_set.newPackagesetUploader(
1673
            self.ubuntu.main_archive, uploader, breezy_ps)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1674
        self.switchToUploader()
7675.384.3 by Muharem Hrnjadovic
Minor fixes.
1675
        # The uploader now does have a package set based upload permission
7675.384.2 by Muharem Hrnjadovic
Upload test works as well.
1676
        # to 'bar' in 'breezy'.
1677
        self.assertTrue(
1678
            ap_set.isSourceUploadAllowed(
1679
                self.ubuntu.main_archive, 'bar', uploader, self.breezy))
1680
        # Upload the package again.
1681
        self.processUpload(uploadprocessor, upload_dir)
1682
        # Check that it worked.
7675.140.10 by Muharem Hrnjadovic
Revised the nascent upload tests.
1683
        status = uploadprocessor.last_processed_upload.queue_root.status
1684
        self.assertEqual(
1685
            status, PackageUploadStatus.DONE,
1686
            "Expected DONE status, got %s" % status.value)
1687
8632.3.1 by Celso Providelo
Remove obsolete tests and include a extended upload_path error reporter.
1688
    def testUploadPathErrorIntendedForHumans(self):
1689
        # Distribution upload path errors are augmented with a hint
1690
        # to fix the current dput/dupload configuration.
1691
        # This information gets included in the rejection email along
1692
        # with pointer to the Soyuz questions in Launchpad and the
1693
        # reason why the message was sent to the current recipients.
1694
        self.setupBreezy()
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1695
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
8632.3.1 by Celso Providelo
Remove obsolete tests and include a extended upload_path error reporter.
1696
1697
        upload_dir = self.queueUpload("bar_1.0-1", "boing")
1698
        self.processUpload(uploadprocessor, upload_dir)
8632.3.3 by Celso Providelo
applying review comments, r=mrevell.
1699
        rejection_message = (
8632.3.1 by Celso Providelo
Remove obsolete tests and include a extended upload_path error reporter.
1700
            uploadprocessor.last_processed_upload.rejection_message)
8632.3.3 by Celso Providelo
applying review comments, r=mrevell.
1701
        self.assertEqual(
1702
            ["Launchpad failed to process the upload path 'boing':",
1703
             '',
1704
             "Could not find distribution 'boing'.",
1705
             '',
1706
             'It is likely that you have a configuration problem with '
1707
                'dput/dupload.',
1708
             'Please update your dput/dupload configuration and then '
1709
                're-upload.',
1710
             '',
1711
             'Further error processing not possible because of a critical '
1712
                'previous error.',
1713
             ],
1714
            rejection_message.splitlines())
8632.3.1 by Celso Providelo
Remove obsolete tests and include a extended upload_path error reporter.
1715
1716
        contents = [
1717
            "Subject: bar_1.0-1_source.changes rejected",
1718
            "Could not find distribution 'boing'",
1719
            "If you don't understand why your files were rejected",
1720
            "http://answers.launchpad.net/soyuz",
1721
            "You are receiving this email because you are the "
1722
               "uploader, maintainer or",
1723
            "signer of the above package.",
1724
            ]
1725
        recipients = [
1726
            'Foo Bar <foo.bar@canonical.com>',
1727
            'Daniel Silverstone <daniel.silverstone@canonical.com>',
1728
            ]
1729
        self.assertEmail(contents, recipients=recipients)
1730
7675.424.25 by William Grant
Reject uploads involving formats unsupported by the target series.
1731
    def test30QuiltUploadToUnsupportingSeriesIsRejected(self):
1732
        """Ensure that uploads to series without format support are rejected.
1733
1734
        Series can restrict the source formats that they accept. Uploads
1735
        should be rejected if an unsupported format is uploaded.
1736
        """
1737
        self.setupBreezy()
1738
        self.layer.txn.commit()
1739
        self.options.context = 'absolutely-anything'
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1740
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
7675.424.25 by William Grant
Reject uploads involving formats unsupported by the target series.
1741
1742
        # Upload the source.
1743
        upload_dir = self.queueUpload("bar_1.0-1_3.0-quilt")
1744
        self.processUpload(uploadprocessor, upload_dir)
1745
        # Make sure it was rejected.
1746
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1747
        self.assertTrue(
1748
            "bar_1.0-1.dsc: format '3.0 (quilt)' is not permitted in "
1749
            "breezy." in raw_msg,
1750
            "Source was not rejected properly:\n%s" % raw_msg)
1751
7675.424.13 by William Grant
Test that the 3.0 (quilt) upload with two component tarballs works.
1752
    def test30QuiltUpload(self):
1753
        """Ensure that 3.0 (quilt) uploads work properly. """
7675.424.28 by William Grant
s/SourceFormatSelection/SourcePackageFormatSelection/, and make it use an enum instead.
1754
        self.setupBreezy(
1755
            permitted_formats=[SourcePackageFormat.FORMAT_3_0_QUILT])
7675.424.13 by William Grant
Test that the 3.0 (quilt) upload with two component tarballs works.
1756
        self.layer.txn.commit()
1757
        self.options.context = 'absolutely-anything'
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1758
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
7675.424.13 by William Grant
Test that the 3.0 (quilt) upload with two component tarballs works.
1759
1760
        # Upload the source.
1761
        upload_dir = self.queueUpload("bar_1.0-1_3.0-quilt")
1762
        self.processUpload(uploadprocessor, upload_dir)
1763
        # Make sure it went ok:
1764
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1765
        self.assertTrue(
1766
            "rejected" not in raw_msg,
1767
            "Failed to upload bar source:\n%s" % raw_msg)
11039.2.13 by Jelmer Vernooij
Fix tests.
1768
        spph = self.publishPackage("bar", "1.0-1")
7675.424.13 by William Grant
Test that the 3.0 (quilt) upload with two component tarballs works.
1769
1770
        self.assertEquals(
1771
            sorted((sprf.libraryfile.filename, sprf.filetype)
1772
                   for sprf in spph.sourcepackagerelease.files),
1773
            [('bar_1.0-1.debian.tar.bz2',
1774
              SourcePackageFileType.DEBIAN_TARBALL),
1775
             ('bar_1.0-1.dsc',
1776
              SourcePackageFileType.DSC),
7675.424.18 by William Grant
Drop lzma support, as dak has done.
1777
             ('bar_1.0.orig-comp1.tar.gz',
7675.424.13 by William Grant
Test that the 3.0 (quilt) upload with two component tarballs works.
1778
              SourcePackageFileType.COMPONENT_ORIG_TARBALL),
1779
             ('bar_1.0.orig-comp2.tar.bz2',
1780
              SourcePackageFileType.COMPONENT_ORIG_TARBALL),
12632.3.3 by William Grant
Fix test30QuiltUpload.
1781
             ('bar_1.0.orig-comp3.tar.xz',
1782
              SourcePackageFileType.COMPONENT_ORIG_TARBALL),
7675.424.13 by William Grant
Test that the 3.0 (quilt) upload with two component tarballs works.
1783
             ('bar_1.0.orig.tar.gz',
1784
              SourcePackageFileType.ORIG_TARBALL)])
1785
7675.424.20 by William Grant
Allow duplicated component origs to be uploaded.
1786
    def test30QuiltUploadWithSameComponentOrig(self):
7675.424.34 by William Grant
Fix lint.
1787
        """Ensure that 3.0 (quilt) uploads with shared component origs work.
1788
        """
7675.424.28 by William Grant
s/SourceFormatSelection/SourcePackageFormatSelection/, and make it use an enum instead.
1789
        self.setupBreezy(
1790
            permitted_formats=[SourcePackageFormat.FORMAT_3_0_QUILT])
7675.424.20 by William Grant
Allow duplicated component origs to be uploaded.
1791
        self.layer.txn.commit()
1792
        self.options.context = 'absolutely-anything'
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1793
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
7675.424.20 by William Grant
Allow duplicated component origs to be uploaded.
1794
1795
        # Upload the first source.
1796
        upload_dir = self.queueUpload("bar_1.0-1_3.0-quilt")
1797
        self.processUpload(uploadprocessor, upload_dir)
1798
        # Make sure it went ok:
1799
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1800
        self.assertTrue(
1801
            "rejected" not in raw_msg,
1802
            "Failed to upload bar source:\n%s" % raw_msg)
13233.1.1 by Jeroen Vermeulen
Lint.
1803
        self.publishPackage("bar", "1.0-1")
7675.424.20 by William Grant
Allow duplicated component origs to be uploaded.
1804
1805
        # Upload another source sharing the same (component) orig.
1806
        upload_dir = self.queueUpload("bar_1.0-2_3.0-quilt_without_orig")
1807
        self.assertEquals(
1808
            self.processUpload(uploadprocessor, upload_dir), ['accepted'])
1809
1810
        queue_item = uploadprocessor.last_processed_upload.queue_root
1811
        self.assertEquals(
1812
            sorted((sprf.libraryfile.filename, sprf.filetype) for sprf
1813
                   in queue_item.sources[0].sourcepackagerelease.files),
1814
            [('bar_1.0-2.debian.tar.bz2',
1815
              SourcePackageFileType.DEBIAN_TARBALL),
1816
             ('bar_1.0-2.dsc',
1817
              SourcePackageFileType.DSC),
1818
             ('bar_1.0.orig-comp1.tar.gz',
1819
              SourcePackageFileType.COMPONENT_ORIG_TARBALL),
1820
             ('bar_1.0.orig-comp2.tar.bz2',
1821
              SourcePackageFileType.COMPONENT_ORIG_TARBALL),
1822
             ('bar_1.0.orig.tar.gz',
1823
              SourcePackageFileType.ORIG_TARBALL)])
1824
7675.424.14 by William Grant
Add a 3.0 (native) source and test.
1825
    def test30NativeUpload(self):
1826
        """Ensure that 3.0 (native) uploads work properly. """
7675.424.28 by William Grant
s/SourceFormatSelection/SourcePackageFormatSelection/, and make it use an enum instead.
1827
        self.setupBreezy(
1828
            permitted_formats=[SourcePackageFormat.FORMAT_3_0_NATIVE])
7675.424.14 by William Grant
Add a 3.0 (native) source and test.
1829
        self.layer.txn.commit()
1830
        self.options.context = 'absolutely-anything'
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1831
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
7675.424.14 by William Grant
Add a 3.0 (native) source and test.
1832
1833
        # Upload the source.
1834
        upload_dir = self.queueUpload("bar_1.0_3.0-native")
1835
        self.processUpload(uploadprocessor, upload_dir)
1836
        # Make sure it went ok:
1837
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1838
        self.assertTrue(
1839
            "rejected" not in raw_msg,
1840
            "Failed to upload bar source:\n%s" % raw_msg)
11039.2.13 by Jelmer Vernooij
Fix tests.
1841
        spph = self.publishPackage("bar", "1.0")
7675.424.14 by William Grant
Add a 3.0 (native) source and test.
1842
1843
        self.assertEquals(
1844
            sorted((sprf.libraryfile.filename, sprf.filetype)
1845
                   for sprf in spph.sourcepackagerelease.files),
1846
            [('bar_1.0.dsc',
1847
              SourcePackageFileType.DSC),
1848
             ('bar_1.0.tar.bz2',
1849
              SourcePackageFileType.NATIVE_TARBALL)])
1850
7675.424.19 by William Grant
Reject 1.0 source uploads containing bzip2ed files.
1851
    def test10Bzip2UploadIsRejected(self):
1852
        """Ensure that 1.0 sources with bzip2 compression are rejected."""
1853
        self.setupBreezy()
1854
        self.layer.txn.commit()
1855
        self.options.context = 'absolutely-anything'
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1856
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
7675.424.19 by William Grant
Reject 1.0 source uploads containing bzip2ed files.
1857
1858
        # Upload the source.
1859
        upload_dir = self.queueUpload("bar_1.0-1_1.0-bzip2")
1860
        self.processUpload(uploadprocessor, upload_dir)
1861
        # Make sure it was rejected.
1862
        from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1863
        self.assertTrue(
1864
            "bar_1.0-1.dsc: is format 1.0 but uses bzip2 compression."
1865
            in raw_msg,
1866
            "Source was not rejected properly:\n%s" % raw_msg)
1867
10286.1.2 by Michael Nelson
Added test ensuring that the CannotUploadToPocket exception is printed in the email correctly (the actual fix landed in a previous branch).
1868
    def testUploadToWrongPocketIsRejected(self):
10286.1.4 by Michael Nelson
Updated test comment after review suggestion.
1869
        # Uploads to the wrong pocket are rejected.
10286.1.2 by Michael Nelson
Added test ensuring that the CannotUploadToPocket exception is printed in the email correctly (the actual fix landed in a previous branch).
1870
        self.setupBreezy()
1871
        breezy = self.ubuntu['breezy']
1872
        breezy.status = SeriesStatus.CURRENT
7675.815.1 by Jelmer Vernooij
Reintroduce in-process loading of uploadprocessor from buildd-manager.
1873
        uploadprocessor = self.getUploadProcessor(self.layer.txn)
10286.1.2 by Michael Nelson
Added test ensuring that the CannotUploadToPocket exception is printed in the email correctly (the actual fix landed in a previous branch).
1874
1875
        upload_dir = self.queueUpload("bar_1.0-1")
1876
        self.processUpload(uploadprocessor, upload_dir)
1877
        rejection_message = (
1878
            uploadprocessor.last_processed_upload.rejection_message)
1879
        self.assertEqual(
1880
            "Not permitted to upload to the RELEASE pocket in a series in "
1881
            "the 'CURRENT' state.",
1882
            rejection_message)
1883
1884
        contents = [
1885
            "Subject: bar_1.0-1_source.changes rejected",
1886
            "Not permitted to upload to the RELEASE pocket in a series "
1887
            "in the 'CURRENT' state.",
1888
            "If you don't understand why your files were rejected",
1889
            "http://answers.launchpad.net/soyuz",
1890
            "You are receiving this email because you are the "
1891
               "uploader, maintainer or",
1892
            "signer of the above package.",
1893
            ]
1894
        recipients = [
1895
            'Foo Bar <foo.bar@canonical.com>',
1896
            'Daniel Silverstone <daniel.silverstone@canonical.com>',
1897
            ]
1898
        self.assertEmail(contents, recipients=recipients)
3673.6.1 by Malcolm Cleaton
Tidying process-upload script and tests
1899
10542.14.2 by Steve Kowalik
Refactor .testPGPSignatureNotPreserved() from PPATestUploadProcessor to TestUploadProcessorBase, and call it from {PPA,}TestUploadProcessor
1900
    def testPGPSignatureNotPreserved(self):
1901
        """PGP signatures should be removed from .changes files.
1902
1903
        Email notifications and the librarian file for the .changes file
1904
        should both have the PGP signature removed.
1905
        """
10722.3.2 by Steve Kowalik
* Walk every attachment when looking for PGP signatures.
1906
        uploadprocessor = self.setupBreezyAndGetUploadProcessor(
11149.4.1 by Jeroen Vermeulen
Test cruft in archiveuploader.
1907
        policy='insecure')
10722.3.2 by Steve Kowalik
* Walk every attachment when looking for PGP signatures.
1908
        upload_dir = self.queueUpload("bar_1.0-1")
1909
        self.processUpload(uploadprocessor, upload_dir)
1910
        # ACCEPT the upload
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
1911
        queue_items = self.breezy.getPackageUploads(
1912
            status=PackageUploadStatus.NEW, name=u"bar",
1913
            version=u"1.0-1", exact_match=True)
10722.3.2 by Steve Kowalik
* Walk every attachment when looking for PGP signatures.
1914
        self.assertEqual(queue_items.count(), 1)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1915
        self.switchToAdmin()
10722.3.2 by Steve Kowalik
* Walk every attachment when looking for PGP signatures.
1916
        queue_item = queue_items[0]
1917
        queue_item.setAccepted()
1918
        pubrec = queue_item.sources[0].publish(self.log)
1919
        pubrec.status = PackagePublishingStatus.PUBLISHED
1920
        pubrec.datepublished = UTC_NOW
10722.3.3 by Steve Kowalik
Refactor PGPSignatureNotPreserved to pull the changes file from the librarian, as opposed to the checking the notification mail.
1921
        queue_item.setDone()
1922
        self.PGPSignatureNotPreserved(archive=self.breezy.main_archive)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
1923
        self.switchToUploader()
11039.2.10 by Jelmer Vernooij
Add more tests.
1924
14066.2.4 by William Grant
Test the silence.
1925
    def test_unsigned_upload_is_silently_rejected(self):
14066.2.5 by William Grant
Review comments.
1926
        # Unsigned uploads are rejected without OOPS or email.
14066.2.4 by William Grant
Test the silence.
1927
        uploadprocessor = self.setupBreezyAndGetUploadProcessor()
1928
        upload_dir = self.queueUpload("netapplet_1.0-1")
1929
1930
        [result] = self.processUpload(uploadprocessor, upload_dir)
1931
1932
        self.assertEqual(UploadStatusEnum.REJECTED, result)
1933
        self.assertLogContains(
14066.2.6 by William Grant
Increase log level to INFO, and include the path.
1934
            "INFO Failed to parse changes file")
14066.2.4 by William Grant
Test the silence.
1935
        self.assertEqual(len(stub.test_emails), 0)
14104.6.13 by Robert Collins
no more getLastOops for test_uploadprocessor.
1936
        self.assertEqual([], self.oopses)
14066.2.4 by William Grant
Test the silence.
1937
14158.1.2 by Julian Edwards
Failing test added to check that process() is overriding the ddebs.
1938
    def test_ddeb_upload_overrides(self):
1939
        # DDEBs should always be overridden to the same values as their
1940
        # counterpart DEB's.
1941
        policy = getPolicy(
1942
            name="sync", distro="ubuntu", distroseries="hoary")
1943
        policy.accepted_type = ArchiveUploadType.BINARY_ONLY
1944
        uploader = NascentUpload.from_changesfile_path(
1945
            datadir("suite/debug_1.0-1/debug_1.0-1_i386.changes"),
1946
            policy, DevNullLogger())
1947
        uploader.process()
1948
1949
        # The package data on disk that we just uploaded has a different
1950
        # priority setting between the deb and the ddeb. We can now assert
1951
        # that the process() method above overrode the ddeb.
1952
        for uploaded_file in uploader.changes.files:
1953
            if isinstance(uploaded_file, DdebBinaryUploadFile):
1954
                ddeb = uploaded_file
1955
            else:
1956
                deb = uploaded_file
1957
14158.1.4 by Julian Edwards
make the test more robust by checking for exactly the right priority name
1958
        self.assertEqual("optional", ddeb.priority_name)
14158.1.2 by Julian Edwards
Failing test added to check that process() is overriding the ddebs.
1959
        self.assertEqual(deb.priority_name, ddeb.priority_name)
1960
11039.2.13 by Jelmer Vernooij
Fix tests.
1961
1962
class TestBuildUploadProcessor(TestUploadProcessorBase):
1963
    """Test that processing build uploads works."""
1964
1965
    def setUp(self):
1966
        super(TestBuildUploadProcessor, self).setUp()
1967
        self.uploadprocessor = self.setupBreezyAndGetUploadProcessor()
1968
12221.13.1 by Aaron Bentley
Start splitting UploadHandler.
1969
1970
class TestUploadHandler(TestUploadProcessorBase):
1971
12221.13.15 by Aaron Bentley
Cleanup.
1972
    def setUp(self):
1973
        super(TestUploadHandler, self).setUp()
1974
        self.uploadprocessor = self.setupBreezyAndGetUploadProcessor()
1975
11039.2.13 by Jelmer Vernooij
Fix tests.
1976
    def testInvalidLeafName(self):
11039.2.32 by Jelmer Vernooij
Some test fixes.
1977
        # Directories with invalid leaf names should be skipped,
1978
        # and a warning logged.
11039.2.43 by Jelmer Vernooij
Fix tests.
1979
        upload_dir = self.queueUpload("bar_1.0-1", queue_entry="bar")
12221.13.9 by Aaron Bentley
Move build retrieval to the constructor.
1980
        e = self.assertRaises(
1981
            CannotGetBuild, BuildUploadHandler, self.uploadprocessor,
1982
            upload_dir, "bar")
1983
        self.assertIn(
12221.13.14 by Aaron Bentley
Fix lint.
1984
            'Unable to extract build id from leaf name bar, skipping.',
1985
            str(e))
11039.2.10 by Jelmer Vernooij
Add more tests.
1986
11039.2.13 by Jelmer Vernooij
Fix tests.
1987
    def testNoBuildEntry(self):
11039.2.40 by Jelmer Vernooij
Review feedback from Brad (fix comment typo).
1988
        # Directories with that refer to a nonexistent build
11039.2.32 by Jelmer Vernooij
Some test fixes.
1989
        # should be skipped and a warning logged.
11039.2.42 by Jelmer Vernooij
Work with jobs rather than builds.
1990
        cookie = "%s-%d" % (BuildFarmJobType.PACKAGEBUILD.name, 42)
1991
        upload_dir = self.queueUpload("bar_1.0-1", queue_entry=cookie)
12221.13.9 by Aaron Bentley
Move build retrieval to the constructor.
1992
        e = self.assertRaises(
1993
            CannotGetBuild,
1994
            BuildUploadHandler, self.uploadprocessor, upload_dir, cookie)
1995
        self.assertIn(
12961.1.8 by William Grant
package upload leaf names no longer include the BuildFarmJob ID.
1996
            "Unable to find PACKAGEBUILD with id 42. Skipping.", str(e))
11039.2.11 by Jelmer Vernooij
More tests.
1997
11039.3.4 by Jelmer Vernooij
Add test for failed sprbs
1998
    def testBinaryPackageBuild_fail(self):
11039.2.32 by Jelmer Vernooij
Some test fixes.
1999
        # If the upload directory is empty, the upload
2000
        # will fail.
2001
11039.2.13 by Jelmer Vernooij
Fix tests.
2002
        # Upload a source package
2003
        upload_dir = self.queueUpload("bar_1.0-1")
2004
        self.processUpload(self.uploadprocessor, upload_dir)
2005
        source_pub = self.publishPackage('bar', '1.0-1')
2006
        [build] = source_pub.createMissingBuilds()
2007
2008
        # Move the source from the accepted queue.
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2009
        self.switchToAdmin()
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
2010
        [queue_item] = self.breezy.getPackageUploads(
11039.2.13 by Jelmer Vernooij
Fix tests.
2011
            status=PackageUploadStatus.ACCEPTED,
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
2012
            version=u"1.0-1", name=u"bar")
11039.2.13 by Jelmer Vernooij
Fix tests.
2013
        queue_item.setDone()
2014
11039.2.43 by Jelmer Vernooij
Fix tests.
2015
        builder = self.factory.makeBuilder()
2016
        build.buildqueue_record.markAsBuilding(builder)
2017
        build.builder = build.buildqueue_record.builder
11039.2.13 by Jelmer Vernooij
Fix tests.
2018
11039.2.38 by Jelmer Vernooij
Use correct package build id.
2019
        build.status = BuildStatus.UPLOADING
12177.2.2 by Julian Edwards
Fix test failures
2020
        build.date_finished = UTC_NOW
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2021
        self.switchToUploader()
11039.2.38 by Jelmer Vernooij
Use correct package build id.
2022
11039.2.13 by Jelmer Vernooij
Fix tests.
2023
        # Upload and accept a binary for the primary archive source.
2024
        shutil.rmtree(upload_dir)
11039.3.2 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds uploading.
2025
2026
        # Commit so the build cookie has the right ids.
11039.2.13 by Jelmer Vernooij
Fix tests.
2027
        self.layer.txn.commit()
11039.2.42 by Jelmer Vernooij
Work with jobs rather than builds.
2028
        leaf_name = build.getUploadDirLeaf(build.getBuildCookie())
11039.2.13 by Jelmer Vernooij
Fix tests.
2029
        os.mkdir(os.path.join(self.incoming_folder, leaf_name))
2030
        self.options.context = 'buildd'
2031
        self.options.builds = True
12221.13.1 by Aaron Bentley
Start splitting UploadHandler.
2032
        BuildUploadHandler(self.uploadprocessor, self.incoming_folder,
2033
            leaf_name).process()
11039.2.43 by Jelmer Vernooij
Fix tests.
2034
        self.assertEquals(1, len(self.oopses))
11039.2.38 by Jelmer Vernooij
Use correct package build id.
2035
        self.assertEquals(
2036
            BuildStatus.FAILEDTOUPLOAD, build.status)
11039.2.43 by Jelmer Vernooij
Fix tests.
2037
        self.assertEquals(builder, build.builder)
2038
        self.assertIsNot(None, build.duration)
11039.2.13 by Jelmer Vernooij
Fix tests.
2039
        log_contents = build.upload_log.read()
12070.1.43 by Tim Penhey
Fix test failures.
2040
        self.assertTrue('ERROR Exception while processing upload '
11039.2.13 by Jelmer Vernooij
Fix tests.
2041
            in log_contents)
12070.1.43 by Tim Penhey
Fix test failures.
2042
        self.assertFalse('DEBUG Moving upload directory '
11039.2.13 by Jelmer Vernooij
Fix tests.
2043
            in log_contents)
2044
11039.3.2 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds uploading.
2045
    def testBinaryPackageBuilds(self):
11039.2.32 by Jelmer Vernooij
Some test fixes.
2046
        # Properly uploaded binaries should result in the
2047
        # build status changing to FULLYBUILT.
11039.2.13 by Jelmer Vernooij
Fix tests.
2048
        # Upload a source package
2049
        upload_dir = self.queueUpload("bar_1.0-1")
2050
        self.processUpload(self.uploadprocessor, upload_dir)
2051
        source_pub = self.publishPackage('bar', '1.0-1')
2052
        [build] = source_pub.createMissingBuilds()
2053
2054
        # Move the source from the accepted queue.
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2055
        self.switchToAdmin()
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
2056
        [queue_item] = self.breezy.getPackageUploads(
11039.2.13 by Jelmer Vernooij
Fix tests.
2057
            status=PackageUploadStatus.ACCEPTED,
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
2058
            version=u"1.0-1", name=u"bar")
11039.2.13 by Jelmer Vernooij
Fix tests.
2059
        queue_item.setDone()
2060
11039.2.42 by Jelmer Vernooij
Work with jobs rather than builds.
2061
        build.buildqueue_record.markAsBuilding(self.factory.makeBuilder())
11039.2.38 by Jelmer Vernooij
Use correct package build id.
2062
        build.status = BuildStatus.UPLOADING
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2063
        self.switchToUploader()
11039.2.38 by Jelmer Vernooij
Use correct package build id.
2064
11039.2.11 by Jelmer Vernooij
More tests.
2065
        # Upload and accept a binary for the primary archive source.
2066
        shutil.rmtree(upload_dir)
11039.3.2 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds uploading.
2067
2068
        # Commit so the build cookie has the right ids.
11039.2.11 by Jelmer Vernooij
More tests.
2069
        self.layer.txn.commit()
11039.2.42 by Jelmer Vernooij
Work with jobs rather than builds.
2070
        leaf_name = build.getUploadDirLeaf(build.getBuildCookie())
11039.2.11 by Jelmer Vernooij
More tests.
2071
        upload_dir = self.queueUpload("bar_1.0-1_binary",
2072
                queue_entry=leaf_name)
2073
        self.options.context = 'buildd'
11039.2.12 by Jelmer Vernooij
Fix policy use.
2074
        self.options.builds = True
11039.2.43 by Jelmer Vernooij
Fix tests.
2075
        last_stub_mail_count = len(stub.test_emails)
12221.13.1 by Aaron Bentley
Start splitting UploadHandler.
2076
        BuildUploadHandler(self.uploadprocessor, self.incoming_folder,
2077
            leaf_name).process()
11039.2.13 by Jelmer Vernooij
Fix tests.
2078
        self.layer.txn.commit()
11039.2.43 by Jelmer Vernooij
Fix tests.
2079
        # No emails are sent on success
2080
        self.assertEquals(len(stub.test_emails), last_stub_mail_count)
11039.2.13 by Jelmer Vernooij
Fix tests.
2081
        self.assertEquals(BuildStatus.FULLYBUILT, build.status)
11039.2.53 by Jelmer Vernooij
Add extra flush, don't store upload log on success.
2082
        # Upon full build the upload log is unset.
2083
        self.assertIs(None, build.upload_log)
7675.862.2 by Jelmer Vernooij
Cherrypick second part of asynchronous buildd manager.
2084
12221.13.17 by Aaron Bentley
Fix success emails.
2085
    def doSuccessRecipeBuild(self):
11039.3.2 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds uploading.
2086
        # Upload a source package
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2087
        self.switchToAdmin()
11039.3.18 by Jelmer Vernooij
Fix sprb test.
2088
        archive = self.factory.makeArchive()
2089
        archive.require_virtualized = False
11039.3.3 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds.
2090
        build = self.factory.makeSourcePackageRecipeBuild(sourcename=u"bar",
11768.1.3 by Curtis Hovey
Hushed lint
2091
            distroseries=self.breezy, archive=archive,
2092
            requester=archive.owner)
11039.3.18 by Jelmer Vernooij
Fix sprb test.
2093
        self.assertEquals(archive.owner, build.requester)
13233.1.1 by Jeroen Vermeulen
Lint.
2094
        self.factory.makeSourcePackageRecipeBuildJob(recipe_build=build)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2095
        self.switchToUploader()
11039.3.2 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds uploading.
2096
        # Commit so the build cookie has the right ids.
2097
        self.layer.txn.commit()
2098
        leaf_name = build.getUploadDirLeaf(build.getBuildCookie())
11039.3.18 by Jelmer Vernooij
Fix sprb test.
2099
        relative_path = "~%s/%s/%s/%s" % (
2100
            archive.owner.name, archive.name, self.breezy.distribution.name,
2101
            self.breezy.name)
13233.1.1 by Jeroen Vermeulen
Lint.
2102
        self.queueUpload(
11039.3.18 by Jelmer Vernooij
Fix sprb test.
2103
            "bar_1.0-1", queue_entry=leaf_name, relative_path=relative_path)
11039.3.2 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds uploading.
2104
        self.options.context = 'buildd'
2105
        self.options.builds = True
11039.3.3 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds.
2106
        build.jobStarted()
2107
        # Commit so date_started is recorded and doesn't cause constraint
2108
        # violations later.
11039.3.2 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds uploading.
2109
        build.status = BuildStatus.UPLOADING
12177.2.2 by Julian Edwards
Fix test failures
2110
        build.date_finished = UTC_NOW
11039.2.53 by Jelmer Vernooij
Add extra flush, don't store upload log on success.
2111
        Store.of(build).flush()
12221.13.1 by Aaron Bentley
Start splitting UploadHandler.
2112
        BuildUploadHandler(self.uploadprocessor, self.incoming_folder,
2113
            leaf_name).process()
11039.3.2 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds uploading.
2114
        self.layer.txn.commit()
12221.13.17 by Aaron Bentley
Fix success emails.
2115
        return build
11039.3.2 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds uploading.
2116
12221.13.17 by Aaron Bentley
Fix success emails.
2117
    def testSourcePackageRecipeBuild(self):
2118
        # Properly uploaded source packages should result in the
2119
        # build status changing to FULLYBUILT.
2120
        build = self.doSuccessRecipeBuild()
11039.2.53 by Jelmer Vernooij
Add extra flush, don't store upload log on success.
2121
        self.assertEquals(BuildStatus.FULLYBUILT, build.status)
11039.3.3 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds.
2122
        self.assertEquals(None, build.builder)
2123
        self.assertIsNot(None, build.duration)
11039.2.53 by Jelmer Vernooij
Add extra flush, don't store upload log on success.
2124
        # Upon full build the upload log is unset.
2125
        self.assertIs(None, build.upload_log)
11039.3.2 by Jelmer Vernooij
Add test for sourcepackagerecipebuilds uploading.
2126
12221.13.17 by Aaron Bentley
Fix success emails.
2127
    def testSourcePackageRecipeBuild_success_mail(self):
13001.7.5 by mbp at canonical
Update one more test for mail from sprb success
2128
        """Source package recipe build success does not cause mail.
13233.1.1 by Jeroen Vermeulen
Lint.
2129
13001.7.5 by mbp at canonical
Update one more test for mail from sprb success
2130
        See bug 778437.
2131
        """
12221.13.17 by Aaron Bentley
Fix success emails.
2132
        self.doSuccessRecipeBuild()
13001.7.5 by mbp at canonical
Update one more test for mail from sprb success
2133
        self.assertEquals(len(pop_notifications()), 0, pop_notifications)
12221.13.17 by Aaron Bentley
Fix success emails.
2134
12221.13.19 by Aaron Bentley
Test failure emails and fix upload log links.
2135
    def doFailureRecipeBuild(self):
11039.3.4 by Jelmer Vernooij
Add test for failed sprbs
2136
        # A source package recipe build will fail if no files are present.
2137
2138
        # Upload a source package
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2139
        self.switchToAdmin()
11039.2.52 by Jelmer Vernooij
merge popen 2 branch
2140
        archive = self.factory.makeArchive()
2141
        archive.require_virtualized = False
11039.3.4 by Jelmer Vernooij
Add test for failed sprbs
2142
        build = self.factory.makeSourcePackageRecipeBuild(sourcename=u"bar",
11039.2.52 by Jelmer Vernooij
merge popen 2 branch
2143
            distroseries=self.breezy, archive=archive)
13233.1.1 by Jeroen Vermeulen
Lint.
2144
        self.factory.makeSourcePackageRecipeBuildJob(recipe_build=build)
11039.3.4 by Jelmer Vernooij
Add test for failed sprbs
2145
        # Commit so the build cookie has the right ids.
11039.2.53 by Jelmer Vernooij
Add extra flush, don't store upload log on success.
2146
        Store.of(build).flush()
11039.3.4 by Jelmer Vernooij
Add test for failed sprbs
2147
        leaf_name = build.getUploadDirLeaf(build.getBuildCookie())
2148
        os.mkdir(os.path.join(self.incoming_folder, leaf_name))
2149
        self.options.context = 'buildd'
2150
        self.options.builds = True
2151
        build.jobStarted()
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2152
        self.switchToUploader()
11039.3.4 by Jelmer Vernooij
Add test for failed sprbs
2153
        # Commit so date_started is recorded and doesn't cause constraint
2154
        # violations later.
11039.2.53 by Jelmer Vernooij
Add extra flush, don't store upload log on success.
2155
        Store.of(build).flush()
11039.3.4 by Jelmer Vernooij
Add test for failed sprbs
2156
        build.status = BuildStatus.UPLOADING
12177.2.2 by Julian Edwards
Fix test failures
2157
        build.date_finished = UTC_NOW
12221.13.1 by Aaron Bentley
Start splitting UploadHandler.
2158
        BuildUploadHandler(self.uploadprocessor, self.incoming_folder,
2159
            leaf_name).process()
11039.3.4 by Jelmer Vernooij
Add test for failed sprbs
2160
        self.layer.txn.commit()
12221.13.19 by Aaron Bentley
Test failure emails and fix upload log links.
2161
        return build
2162
2163
    def testSourcePackageRecipeBuild_fail(self):
2164
        build = self.doFailureRecipeBuild()
11039.3.4 by Jelmer Vernooij
Add test for failed sprbs
2165
        self.assertEquals(BuildStatus.FAILEDTOUPLOAD, build.status)
2166
        self.assertEquals(None, build.builder)
2167
        self.assertIsNot(None, build.duration)
11039.2.53 by Jelmer Vernooij
Add extra flush, don't store upload log on success.
2168
        self.assertIsNot(None, build.upload_log)
11039.3.4 by Jelmer Vernooij
Add test for failed sprbs
2169
12221.13.19 by Aaron Bentley
Test failure emails and fix upload log links.
2170
    def testSourcePackageRecipeBuild_fail_mail(self):
12221.13.26 by Aaron Bentley
Update from review.
2171
        # Failures should generate a message that includes the upload log URL.
12221.13.19 by Aaron Bentley
Test failure emails and fix upload log links.
2172
        self.doFailureRecipeBuild()
2173
        (mail,) = pop_notifications()
2174
        subject = mail['Subject'].replace('\n\t', ' ')
2175
        self.assertIn('Failed to upload', subject)
2176
        body = mail.get_payload(decode=True)
2177
        self.assertIn('Upload Log: http', body)
2178
12289.6.1 by Ian Booth
Handle deleted recipes in recipe builds
2179
    def doDeletedRecipeBuild(self):
2180
        # A source package recipe build will fail if the recipe is deleted.
2181
2182
        # Upload a source package
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2183
        self.switchToAdmin()
12289.6.1 by Ian Booth
Handle deleted recipes in recipe builds
2184
        archive = self.factory.makeArchive()
2185
        archive.require_virtualized = False
2186
        build = self.factory.makeSourcePackageRecipeBuild(sourcename=u"bar",
2187
            distroseries=self.breezy, archive=archive)
13233.1.1 by Jeroen Vermeulen
Lint.
2188
        self.factory.makeSourcePackageRecipeBuildJob(recipe_build=build)
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2189
        self.switchToUploader()
12289.6.1 by Ian Booth
Handle deleted recipes in recipe builds
2190
        # Commit so the build cookie has the right ids.
2191
        Store.of(build).flush()
2192
        leaf_name = build.getUploadDirLeaf(build.getBuildCookie())
2193
        os.mkdir(os.path.join(self.incoming_folder, leaf_name))
2194
        self.options.context = 'buildd'
2195
        self.options.builds = True
2196
        build.jobStarted()
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2197
        self.switchToAdmin()
12289.6.1 by Ian Booth
Handle deleted recipes in recipe builds
2198
        build.recipe.destroySelf()
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2199
        self.switchToUploader()
12289.6.1 by Ian Booth
Handle deleted recipes in recipe builds
2200
        # Commit so date_started is recorded and doesn't cause constraint
2201
        # violations later.
2202
        Store.of(build).flush()
2203
        build.status = BuildStatus.UPLOADING
2204
        build.date_finished = UTC_NOW
2205
        BuildUploadHandler(self.uploadprocessor, self.incoming_folder,
2206
            leaf_name).process()
2207
        self.layer.txn.commit()
2208
        return build
2209
2210
    def testSourcePackageRecipeBuild_deleted_recipe(self):
2211
        build = self.doDeletedRecipeBuild()
2212
        self.assertEquals(BuildStatus.FAILEDTOUPLOAD, build.status)
2213
        self.assertEquals(None, build.builder)
2214
        self.assertIsNot(None, build.duration)
2215
        self.assertIs(None, build.upload_log)
2216
12042.2.1 by Jelmer Vernooij
Ensure that builds with an unknown status are kept in incoming/.
2217
    def testBuildWithInvalidStatus(self):
2218
        # Builds with an invalid (non-UPLOADING) status should trigger
2219
        # a warning but be left alone.
2220
        upload_dir = self.queueUpload("bar_1.0-1")
2221
        self.processUpload(self.uploadprocessor, upload_dir)
2222
        source_pub = self.publishPackage('bar', '1.0-1')
2223
        [build] = source_pub.createMissingBuilds()
2224
2225
        # Move the source from the accepted queue.
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2226
        self.switchToAdmin()
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
2227
        [queue_item] = self.breezy.getPackageUploads(
12042.2.1 by Jelmer Vernooij
Ensure that builds with an unknown status are kept in incoming/.
2228
            status=PackageUploadStatus.ACCEPTED,
13233.2.4 by Jeroen Vermeulen
Kill getQueueItems.
2229
            version=u"1.0-1", name=u"bar")
12042.2.1 by Jelmer Vernooij
Ensure that builds with an unknown status are kept in incoming/.
2230
        queue_item.setDone()
2231
2232
        build.buildqueue_record.markAsBuilding(self.factory.makeBuilder())
2233
        build.status = BuildStatus.BUILDING
13697.5.2 by Raphael Badin
Fix imports, rename useUploader and useMainUser.
2234
        self.switchToUploader()
12042.2.1 by Jelmer Vernooij
Ensure that builds with an unknown status are kept in incoming/.
2235
2236
        shutil.rmtree(upload_dir)
2237
2238
        # Commit so the build cookie has the right ids.
2239
        self.layer.txn.commit()
2240
        leaf_name = build.getUploadDirLeaf(build.getBuildCookie())
12042.2.4 by Jelmer Vernooij
Fix formatting.
2241
        upload_dir = self.queueUpload(
2242
            "bar_1.0-1_binary", queue_entry=leaf_name)
12042.2.1 by Jelmer Vernooij
Ensure that builds with an unknown status are kept in incoming/.
2243
        self.options.context = 'buildd'
2244
        self.options.builds = True
13233.1.1 by Jeroen Vermeulen
Lint.
2245
        len(stub.test_emails)
12221.13.1 by Aaron Bentley
Start splitting UploadHandler.
2246
        BuildUploadHandler(self.uploadprocessor, self.incoming_folder,
2247
            leaf_name).process()
12042.2.1 by Jelmer Vernooij
Ensure that builds with an unknown status are kept in incoming/.
2248
        self.layer.txn.commit()
2249
        # The build status is not changed
12042.2.4 by Jelmer Vernooij
Fix formatting.
2250
        self.assertTrue(
2251
            os.path.exists(os.path.join(self.incoming_folder, leaf_name)))
12042.2.1 by Jelmer Vernooij
Ensure that builds with an unknown status are kept in incoming/.
2252
        self.assertEquals(BuildStatus.BUILDING, build.status)
2253
        self.assertLogContains(
2254
            "Expected build status to be 'UPLOADING', was BUILDING. "
2255
            "Ignoring.")
2256
12221.13.4 by Aaron Bentley
Move locateChangesFiles and orderFilenames to UploadHandler.
2257
    def testOrderFilenames(self):
2258
        """orderFilenames sorts _source.changes ahead of other files."""
2259
        self.assertEqual(["d_source.changes", "a", "b", "c"],
2260
            UploadHandler.orderFilenames(["b", "a", "d_source.changes", "c"]))
2261
2262
    def testLocateChangesFiles(self):
2263
        """locateChangesFiles should return the .changes files in a folder.
2264
2265
        'source' changesfiles come first. Files that are not named as
2266
        changesfiles are ignored.
2267
        """
2268
        testdir = tempfile.mkdtemp()
2269
        try:
2270
            open("%s/1.changes" % testdir, "w").close()
2271
            open("%s/2_source.changes" % testdir, "w").close()
2272
            open("%s/3.not_changes" % testdir, "w").close()
2273
2274
            up = self.getUploadProcessor(None)
2275
            handler = UploadHandler(up, '.', testdir)
2276
            located_files = handler.locateChangesFiles()
2277
            self.assertEqual(
2278
                located_files, ["2_source.changes", "1.changes"])
2279
        finally:
2280
            shutil.rmtree(testdir)
2281
11039.2.10 by Jelmer Vernooij
Add more tests.
2282
2283
class ParseBuildUploadLeafNameTests(TestCase):
2284
    """Tests for parse_build_upload_leaf_name."""
2285
2286
    def test_valid(self):
11039.2.20 by Jelmer Vernooij
Fix parsing of buildd names.
2287
        self.assertEquals(
12961.1.9 by William Grant
Fix tests.
2288
            ('PACKAGEBUILD', 60),
2289
            parse_build_upload_leaf_name("20100812-PACKAGEBUILD-60"))
11039.2.42 by Jelmer Vernooij
Work with jobs rather than builds.
2290
2291
    def test_invalid_jobid(self):
2292
        self.assertRaises(
11768.1.3 by Curtis Hovey
Hushed lint
2293
            ValueError, parse_build_upload_leaf_name,
2294
            "aaba-a42-PACKAGEBUILD-abc")