Merge lp:~cjwatson/launchpad/copy-custom-uploads into lp:launchpad
- copy-custom-uploads
- Merge into devel
| Status: | Merged | ||||
|---|---|---|---|---|---|
| Approved by: | Benji York on 2012-06-25 | ||||
| Approved revision: | no longer in the source branch. | ||||
| Merged at revision: | 15491 | ||||
| Proposed branch: | lp:~cjwatson/launchpad/copy-custom-uploads | ||||
| Merge into: | lp:launchpad | ||||
| Diff against target: |
959 lines (+226/-157) 8 files modified
database/schema/security.cfg (+1/-0) lib/lp/archivepublisher/scripts/publish_ftpmaster.py (+9/-2) lib/lp/soyuz/scripts/custom_uploads_copier.py (+21/-10) lib/lp/soyuz/scripts/packagecopier.py (+17/-1) lib/lp/soyuz/scripts/tests/test_copypackage.py (+126/-128) lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py (+34/-5) lib/lp/testing/factory.py (+11/-7) lib/lp/testing/tests/test_factory.py (+7/-4) |
||||
| To merge this branch: | bzr merge lp:~cjwatson/launchpad/copy-custom-uploads | ||||
| Related bugs: |
|
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Benji York (community) | code | 2012-06-22 | Approve on 2012-06-25 |
| Brad Crittenden (community) | code | 2012-06-22 | Abstain on 2012-06-25 |
|
Review via email:
|
|||
Commit Message
Handle custom files in direct copies (and hence PCJs) by synthesising an upload.
Description of the Change
== Summary ==
One of the last bugs that cause Ubuntu archive administrators to still require access to lp_publish@cocoplum (a horrendously privileged account) is bug 231371: if we upload installer or upgrader images to -proposed, get them past verification, and copy them to -updates, we have to copy the custom files around by hand. At the moment we have a pile of manual instructions in https:/
== Proposed fix ==
A while back, Jeroen wrote CustomUploadsCo
This does make one aspect of direct copies behave a little bit like delayed copies in that they synthesise an upload, and I considered making this case trigger a delayed copy, but consensus seems to be that delayed copies should be removed at the earliest opportunity, and I can't say I disagree. Besides, CustomUploadsCo
== LOC Rationale ==
I got it down to +68 with a bit of judicious tidying up of unit tests. Aside from that, this is part of the general arc of tidying up package copying described in https:/
== Tests ==
bin/test -vvct test_copypackage -t test_custom_
== Demo and Q/A ==
This will involve two publisher runs on dogfood, so it won't be exactly fast, but it shouldn't be difficult. Upload debian-installer to precise-proposed on dogfood, let it build, publish it, then use Archive.copyPackage (or 'sru-release -l dogfood' from lp:ubuntu-archive-tools) to copy it to precise-updates. This should create the appropriate versioned subdirectories and "current" symlinks in dists/precise-
== Lint ==
Just one pre-existing and not very interesting entry:
./lib/lp/
1450: E501 line too long (82 characters)
Preview Diff
| 1 | === modified file 'database/schema/security.cfg' |
| 2 | --- database/schema/security.cfg 2012-06-22 05:36:22 +0000 |
| 3 | +++ database/schema/security.cfg 2012-06-25 16:57:21 +0000 |
| 4 | @@ -1034,6 +1034,7 @@ |
| 5 | public.packageupload = SELECT |
| 6 | public.packageuploadsource = SELECT |
| 7 | public.packageuploadbuild = SELECT |
| 8 | +public.packageuploadcustom = SELECT |
| 9 | public.packaging = SELECT, INSERT |
| 10 | public.person = SELECT |
| 11 | public.pocketchroot = SELECT |
| 12 | |
| 13 | === modified file 'lib/lp/archivepublisher/scripts/publish_ftpmaster.py' |
| 14 | --- lib/lp/archivepublisher/scripts/publish_ftpmaster.py 2012-05-23 00:20:23 +0000 |
| 15 | +++ lib/lp/archivepublisher/scripts/publish_ftpmaster.py 2012-06-25 16:57:21 +0000 |
| 16 | @@ -18,7 +18,10 @@ |
| 17 | from lp.archivepublisher.interfaces.publisherconfig import IPublisherConfigSet |
| 18 | from lp.archivepublisher.publishing import GLOBAL_PUBLISHER_LOCK |
| 19 | from lp.registry.interfaces.distribution import IDistributionSet |
| 20 | -from lp.registry.interfaces.pocket import pocketsuffix |
| 21 | +from lp.registry.interfaces.pocket import ( |
| 22 | + PackagePublishingPocket, |
| 23 | + pocketsuffix, |
| 24 | + ) |
| 25 | from lp.registry.interfaces.series import SeriesStatus |
| 26 | from lp.services.config import config |
| 27 | from lp.services.database.bulk import load_related |
| 28 | @@ -588,7 +591,11 @@ |
| 29 | # This is a fresh series. |
| 30 | have_fresh_series = True |
| 31 | if series.previous_series is not None: |
| 32 | - CustomUploadsCopier(series).copy(series.previous_series) |
| 33 | + copier = CustomUploadsCopier( |
| 34 | + series, PackagePublishingPocket.RELEASE) |
| 35 | + copier.copy( |
| 36 | + series.previous_series, |
| 37 | + PackagePublishingPocket.RELEASE) |
| 38 | self.createIndexes(distribution, suites_needing_indexes) |
| 39 | |
| 40 | return have_fresh_series |
| 41 | |
| 42 | === modified file 'lib/lp/soyuz/scripts/custom_uploads_copier.py' |
| 43 | --- lib/lp/soyuz/scripts/custom_uploads_copier.py 2012-05-30 10:25:43 +0000 |
| 44 | +++ lib/lp/soyuz/scripts/custom_uploads_copier.py 2012-06-25 16:57:21 +0000 |
| 45 | @@ -42,17 +42,20 @@ |
| 46 | PackageUploadCustomFormat.DIST_UPGRADER: DistUpgraderUpload, |
| 47 | } |
| 48 | |
| 49 | - def __init__(self, target_series): |
| 50 | + def __init__(self, target_series, |
| 51 | + target_pocket=PackagePublishingPocket.RELEASE): |
| 52 | self.target_series = target_series |
| 53 | + self.target_pocket = target_pocket |
| 54 | |
| 55 | def isCopyable(self, upload): |
| 56 | """Is `upload` the kind of `PackageUploadCustom` that we can copy?""" |
| 57 | return upload.customformat in self.copyable_types |
| 58 | |
| 59 | - def getCandidateUploads(self, source_series): |
| 60 | + def getCandidateUploads(self, source_series, |
| 61 | + source_pocket=PackagePublishingPocket.RELEASE): |
| 62 | """Find custom uploads that may need copying.""" |
| 63 | uploads = source_series.getPackageUploads( |
| 64 | - custom_type=self.copyable_types.keys()) |
| 65 | + pocket=source_pocket, custom_type=self.copyable_types.keys()) |
| 66 | load_referencing(PackageUploadCustom, uploads, ['packageuploadID']) |
| 67 | customs = sum([list(upload.customfiles) for upload in uploads], []) |
| 68 | customs = filter(self.isCopyable, customs) |
| 69 | @@ -77,15 +80,19 @@ |
| 70 | else: |
| 71 | return (custom_format, series_key) |
| 72 | |
| 73 | - def getLatestUploads(self, source_series): |
| 74 | + def getLatestUploads(self, source_series, |
| 75 | + source_pocket=PackagePublishingPocket.RELEASE): |
| 76 | """Find the latest uploads. |
| 77 | |
| 78 | :param source_series: The `DistroSeries` whose uploads to get. |
| 79 | + :param source_pocket: The `PackagePublishingPocket` to inspect. |
| 80 | :return: A dict containing the latest uploads, indexed by keys as |
| 81 | returned by `getKey`. |
| 82 | """ |
| 83 | + candidate_uploads = self.getCandidateUploads( |
| 84 | + source_series, source_pocket=source_pocket) |
| 85 | latest_uploads = {} |
| 86 | - for upload in self.getCandidateUploads(source_series): |
| 87 | + for upload in candidate_uploads: |
| 88 | key = self.getKey(upload) |
| 89 | if key is not None: |
| 90 | latest_uploads.setdefault(key, upload) |
| 91 | @@ -120,16 +127,20 @@ |
| 92 | if target_archive is None: |
| 93 | return None |
| 94 | package_upload = self.target_series.createQueueEntry( |
| 95 | - PackagePublishingPocket.RELEASE, target_archive, |
| 96 | + self.target_pocket, target_archive, |
| 97 | changes_file_alias=original_upload.packageupload.changesfile) |
| 98 | custom = package_upload.addCustom( |
| 99 | original_upload.libraryfilealias, original_upload.customformat) |
| 100 | package_upload.setAccepted() |
| 101 | return custom |
| 102 | |
| 103 | - def copy(self, source_series): |
| 104 | - """Copy uploads from `source_series`.""" |
| 105 | - target_uploads = self.getLatestUploads(self.target_series) |
| 106 | - for upload in self.getLatestUploads(source_series).itervalues(): |
| 107 | + def copy(self, source_series, |
| 108 | + source_pocket=PackagePublishingPocket.RELEASE): |
| 109 | + """Copy uploads from `source_series`-`source_pocket`.""" |
| 110 | + target_uploads = self.getLatestUploads( |
| 111 | + self.target_series, source_pocket=self.target_pocket) |
| 112 | + source_uploads = self.getLatestUploads( |
| 113 | + source_series, source_pocket=source_pocket) |
| 114 | + for upload in source_uploads.itervalues(): |
| 115 | if not self.isObsolete(upload, target_uploads): |
| 116 | self.copyUpload(upload) |
| 117 | |
| 118 | === modified file 'lib/lp/soyuz/scripts/packagecopier.py' |
| 119 | --- lib/lp/soyuz/scripts/packagecopier.py 2012-06-22 23:55:02 +0000 |
| 120 | +++ lib/lp/soyuz/scripts/packagecopier.py 2012-06-25 16:57:21 +0000 |
| 121 | @@ -49,6 +49,7 @@ |
| 122 | IPackageUploadCustom, |
| 123 | IPackageUploadSet, |
| 124 | ) |
| 125 | +from lp.soyuz.scripts.custom_uploads_copier import CustomUploadsCopier |
| 126 | from lp.soyuz.scripts.ftpmasterbase import ( |
| 127 | SoyuzScript, |
| 128 | SoyuzScriptError, |
| 129 | @@ -731,6 +732,7 @@ |
| 130 | publications. |
| 131 | """ |
| 132 | copies = [] |
| 133 | + custom_files = [] |
| 134 | |
| 135 | # Copy source if it's not yet copied. |
| 136 | source_in_destination = archive.getPublishedSources( |
| 137 | @@ -762,6 +764,8 @@ |
| 138 | copies.append(source_copy) |
| 139 | else: |
| 140 | source_copy = source_in_destination.first() |
| 141 | + if source_copy.packageupload is not None: |
| 142 | + custom_files.extend(source_copy.packageupload.customfiles) |
| 143 | |
| 144 | if include_binaries: |
| 145 | # Copy missing binaries for the matching architectures in the |
| 146 | @@ -771,10 +775,22 @@ |
| 147 | # arch-indep publications. |
| 148 | binary_copies = getUtility(IPublishingSet).copyBinariesTo( |
| 149 | source.getBuiltBinaries(), series, pocket, archive, policy=policy) |
| 150 | - # XXX cjwatson 2012-06-22 bug=231371: Copy custom uploads. |
| 151 | |
| 152 | if binary_copies is not None: |
| 153 | copies.extend(binary_copies) |
| 154 | + binary_uploads = set( |
| 155 | + bpph.binarypackagerelease.build.package_upload |
| 156 | + for bpph in binary_copies) |
| 157 | + for binary_upload in binary_uploads: |
| 158 | + if binary_upload is not None: |
| 159 | + custom_files.extend(binary_upload.customfiles) |
| 160 | + |
| 161 | + if custom_files: |
| 162 | + # Custom uploads aren't modelled as publication history records, so |
| 163 | + # we have to send these through the upload queue. |
| 164 | + custom_copier = CustomUploadsCopier(series, target_pocket=pocket) |
| 165 | + for custom in custom_files: |
| 166 | + custom_copier.copyUpload(custom) |
| 167 | |
| 168 | # Always ensure the needed builds exist in the copy destination |
| 169 | # after copying the binaries. |
| 170 | |
| 171 | === modified file 'lib/lp/soyuz/scripts/tests/test_copypackage.py' |
| 172 | --- lib/lp/soyuz/scripts/tests/test_copypackage.py 2012-06-20 09:19:37 +0000 |
| 173 | +++ lib/lp/soyuz/scripts/tests/test_copypackage.py 2012-06-25 16:57:21 +0000 |
| 174 | @@ -111,11 +111,9 @@ |
| 175 | |
| 176 | Their filename, mimetype and file contents should be the same. |
| 177 | """ |
| 178 | - self.assertEquals( |
| 179 | - old.filename, new.filename, 'Filename mismatch.') |
| 180 | - self.assertEquals( |
| 181 | - old.mimetype, new.mimetype, 'MIME type mismatch.') |
| 182 | - self.assertEquals(old.read(), new.read(), 'Content mismatch.') |
| 183 | + self.assertEqual(old.filename, new.filename, 'Filename mismatch.') |
| 184 | + self.assertEqual(old.mimetype, new.mimetype, 'MIME type mismatch.') |
| 185 | + self.assertEqual(old.read(), new.read(), 'Content mismatch.') |
| 186 | |
| 187 | def assertFileIsReset(self, reuploaded_file): |
| 188 | """Assert the given `ILibraryFileAlias` attributes were reset. |
| 189 | @@ -123,10 +121,10 @@ |
| 190 | The expiration date and the hits counter are reset and the |
| 191 | last access records was on file creation. |
| 192 | """ |
| 193 | - self.assertIs(reuploaded_file.expires, None) |
| 194 | - self.assertEquals( |
| 195 | + self.assertIsNone(reuploaded_file.expires) |
| 196 | + self.assertEqual( |
| 197 | reuploaded_file.last_accessed, reuploaded_file.date_created) |
| 198 | - self.assertEquals(reuploaded_file.hits, 0) |
| 199 | + self.assertEqual(reuploaded_file.hits, 0) |
| 200 | |
| 201 | def testReUploadFileToTheSameContext(self): |
| 202 | # Re-uploading a librarian file to the same privacy/server |
| 203 | @@ -139,7 +137,7 @@ |
| 204 | transaction.commit() |
| 205 | |
| 206 | self.assertIsNot(old, new) |
| 207 | - self.assertEquals( |
| 208 | + self.assertEqual( |
| 209 | old.restricted, new.restricted, 'New file still private.') |
| 210 | self.assertSameContent(old, new) |
| 211 | self.assertFileIsReset(new) |
| 212 | @@ -223,9 +221,8 @@ |
| 213 | |
| 214 | def assertNewFiles(self, new_files, result): |
| 215 | """Check new files created during update_files_privacy.""" |
| 216 | - self.assertEquals( |
| 217 | - sorted([new_file.filename for new_file in new_files]), |
| 218 | - result) |
| 219 | + self.assertEqual( |
| 220 | + sorted([new_file.filename for new_file in new_files]), result) |
| 221 | |
| 222 | def _checkSourceFilesPrivacy(self, pub_record, restricted, |
| 223 | expected_n_files): |
| 224 | @@ -233,20 +230,20 @@ |
| 225 | n_files = 0 |
| 226 | source = pub_record.sourcepackagerelease |
| 227 | for source_file in source.files: |
| 228 | - self.assertEquals( |
| 229 | + self.assertEqual( |
| 230 | source_file.libraryfile.restricted, restricted, |
| 231 | 'Privacy mismatch on %s' % source_file.libraryfile.filename) |
| 232 | n_files += 1 |
| 233 | - self.assertEquals( |
| 234 | + self.assertEqual( |
| 235 | source.upload_changesfile.restricted, restricted, |
| 236 | 'Privacy mismatch on %s' % source.upload_changesfile.filename) |
| 237 | n_files += 1 |
| 238 | for diff in source.package_diffs: |
| 239 | - self.assertEquals( |
| 240 | + self.assertEqual( |
| 241 | diff.diff_content.restricted, restricted, |
| 242 | 'Privacy mismatch on %s' % diff.diff_content.filename) |
| 243 | n_files += 1 |
| 244 | - self.assertEquals( |
| 245 | + self.assertEqual( |
| 246 | n_files, expected_n_files, |
| 247 | 'Expected %d and got %d files' % (expected_n_files, n_files)) |
| 248 | |
| 249 | @@ -335,20 +332,20 @@ |
| 250 | n_files = 0 |
| 251 | binary = pub_record.binarypackagerelease |
| 252 | for binary_file in binary.files: |
| 253 | - self.assertEquals( |
| 254 | + self.assertEqual( |
| 255 | binary_file.libraryfile.restricted, restricted, |
| 256 | 'Privacy mismatch on %s' % binary_file.libraryfile.filename) |
| 257 | n_files += 1 |
| 258 | build = binary.build |
| 259 | - self.assertEquals( |
| 260 | + self.assertEqual( |
| 261 | build.upload_changesfile.restricted, restricted, |
| 262 | 'Privacy mismatch on %s' % build.upload_changesfile.filename) |
| 263 | n_files += 1 |
| 264 | - self.assertEquals( |
| 265 | + self.assertEqual( |
| 266 | build.log.restricted, restricted, |
| 267 | 'Privacy mismatch on %s' % build.log.filename) |
| 268 | n_files += 1 |
| 269 | - self.assertEquals( |
| 270 | + self.assertEqual( |
| 271 | n_files, expected_n_files, |
| 272 | 'Expected %d and got %d files' % (expected_n_files, n_files)) |
| 273 | |
| 274 | @@ -464,18 +461,17 @@ |
| 275 | """ |
| 276 | copy_checker = CopyChecker( |
| 277 | self.archive, include_binaries=False, allow_delayed_copies=delayed) |
| 278 | - self.assertIs( |
| 279 | - None, |
| 280 | + self.assertIsNone( |
| 281 | copy_checker.checkCopy( |
| 282 | self.source, self.series, self.pocket, |
| 283 | check_permissions=False)) |
| 284 | checked_copies = list(copy_checker.getCheckedCopies()) |
| 285 | - self.assertEquals(1, len(checked_copies)) |
| 286 | + self.assertEqual(1, len(checked_copies)) |
| 287 | [checked_copy] = checked_copies |
| 288 | - self.assertEquals( |
| 289 | + self.assertEqual( |
| 290 | BuildSetStatus.NEEDSBUILD, |
| 291 | checked_copy.getStatusSummaryForBuilds()['status']) |
| 292 | - self.assertEquals(delayed, checked_copy.delayed) |
| 293 | + self.assertEqual(delayed, checked_copy.delayed) |
| 294 | |
| 295 | def assertCanCopyBinaries(self, delayed=False): |
| 296 | """Source and binary copy is allowed. |
| 297 | @@ -493,18 +489,17 @@ |
| 298 | """ |
| 299 | copy_checker = CopyChecker( |
| 300 | self.archive, include_binaries=True, allow_delayed_copies=delayed) |
| 301 | - self.assertIs( |
| 302 | - None, |
| 303 | + self.assertIsNone( |
| 304 | copy_checker.checkCopy( |
| 305 | self.source, self.series, self.pocket, |
| 306 | check_permissions=False)) |
| 307 | checked_copies = list(copy_checker.getCheckedCopies()) |
| 308 | - self.assertEquals(1, len(checked_copies)) |
| 309 | + self.assertEqual(1, len(checked_copies)) |
| 310 | [checked_copy] = checked_copies |
| 311 | self.assertTrue( |
| 312 | checked_copy.getStatusSummaryForBuilds()['status'] >= |
| 313 | BuildSetStatus.FULLYBUILT_PENDING) |
| 314 | - self.assertEquals(delayed, checked_copy.delayed) |
| 315 | + self.assertEqual(delayed, checked_copy.delayed) |
| 316 | |
| 317 | def assertCannotCopySourceOnly(self, msg, person=None, |
| 318 | check_permissions=False): |
| 319 | @@ -518,7 +513,7 @@ |
| 320 | copy_checker.checkCopy, self.source, self.series, self.pocket, |
| 321 | person, check_permissions) |
| 322 | checked_copies = list(copy_checker.getCheckedCopies()) |
| 323 | - self.assertEquals(0, len(checked_copies)) |
| 324 | + self.assertEqual(0, len(checked_copies)) |
| 325 | |
| 326 | def assertCannotCopyBinaries(self, msg): |
| 327 | """`CopyChecker.checkCopy()` including binaries raises CannotCopy. |
| 328 | @@ -531,7 +526,7 @@ |
| 329 | copy_checker.checkCopy, self.source, self.series, self.pocket, |
| 330 | None, False) |
| 331 | checked_copies = list(copy_checker.getCheckedCopies()) |
| 332 | - self.assertEquals(0, len(checked_copies)) |
| 333 | + self.assertEqual(0, len(checked_copies)) |
| 334 | |
| 335 | def test_cannot_copy_binaries_from_building(self): |
| 336 | [build] = self.source.createMissingBuilds() |
| 337 | @@ -609,13 +604,12 @@ |
| 338 | with StormStatementRecorder() as recorder: |
| 339 | copy_checker = CopyChecker(self.archive, include_binaries=False) |
| 340 | for source in sources: |
| 341 | - self.assertIs( |
| 342 | - None, |
| 343 | + self.assertIsNone( |
| 344 | copy_checker.checkCopy( |
| 345 | source, self.series, self.pocket, person=person, |
| 346 | check_permissions=check_permissions)) |
| 347 | checked_copies = list(copy_checker.getCheckedCopies()) |
| 348 | - self.assertEquals(nb_of_sources, len(checked_copies)) |
| 349 | + self.assertEqual(nb_of_sources, len(checked_copies)) |
| 350 | return recorder |
| 351 | |
| 352 | def test_queries_copy_check(self): |
| 353 | @@ -834,13 +828,11 @@ |
| 354 | |
| 355 | # At this point copy is allowed with or without binaries. |
| 356 | copy_checker = CopyChecker(archive, include_binaries=False) |
| 357 | - self.assertIs( |
| 358 | - None, |
| 359 | + self.assertIsNone( |
| 360 | copy_checker.checkCopy( |
| 361 | source, series, pocket, check_permissions=False)) |
| 362 | copy_checker = CopyChecker(archive, include_binaries=True) |
| 363 | - self.assertIs( |
| 364 | - None, |
| 365 | + self.assertIsNone( |
| 366 | copy_checker.checkCopy( |
| 367 | source, series, pocket, check_permissions=False)) |
| 368 | |
| 369 | @@ -852,8 +844,8 @@ |
| 370 | |
| 371 | # Now source-only copies are allowed. |
| 372 | copy_checker = CopyChecker(archive, include_binaries=False) |
| 373 | - self.assertIs( |
| 374 | - None, copy_checker.checkCopy( |
| 375 | + self.assertIsNone( |
| 376 | + copy_checker.checkCopy( |
| 377 | source, series, pocket, check_permissions=False)) |
| 378 | |
| 379 | # Copies with binaries are denied. |
| 380 | @@ -990,8 +982,7 @@ |
| 381 | |
| 382 | # The first source-only copy is allowed, thus stored in the |
| 383 | # copy checker inventory. |
| 384 | - self.assertIs( |
| 385 | - None, |
| 386 | + self.assertIsNone( |
| 387 | copy_checker.checkCopy( |
| 388 | source, source.distroseries, source.pocket, |
| 389 | check_permissions=False)) |
| 390 | @@ -1164,7 +1155,7 @@ |
| 391 | self.test_publisher.prepareBreezyAutotest() |
| 392 | |
| 393 | def assertCopied(self, copies, series, arch_tags): |
| 394 | - self.assertEquals( |
| 395 | + self.assertEqual( |
| 396 | [u'foo 666 in %s' % series.name] + |
| 397 | [u'foo-bin 666 in %s %s' % (series.name, arch_tag) |
| 398 | for arch_tag in arch_tags], |
| 399 | @@ -1268,9 +1259,9 @@ |
| 400 | |
| 401 | def assertComponentSectionAndPriority(self, component, source, |
| 402 | destination): |
| 403 | - self.assertEquals(component, destination.component) |
| 404 | - self.assertEquals(source.section, destination.section) |
| 405 | - self.assertEquals(source.priority, destination.priority) |
| 406 | + self.assertEqual(component, destination.component) |
| 407 | + self.assertEqual(source.section, destination.section) |
| 408 | + self.assertEqual(source.priority, destination.priority) |
| 409 | |
| 410 | def test_new_publication_overrides(self): |
| 411 | # When we copy publications, if the destination primary archive has |
| 412 | @@ -1297,7 +1288,7 @@ |
| 413 | [copied_source, copied_bin_i386, copied_bin_hppa] = self.doCopy( |
| 414 | source, target_archive, nobby, source.pocket, True) |
| 415 | universe = getUtility(IComponentSet)['universe'] |
| 416 | - self.assertEquals(universe, copied_source.component) |
| 417 | + self.assertEqual(universe, copied_source.component) |
| 418 | self.assertComponentSectionAndPriority( |
| 419 | universe, bin_i386, copied_bin_i386) |
| 420 | self.assertComponentSectionAndPriority( |
| 421 | @@ -1333,7 +1324,7 @@ |
| 422 | |
| 423 | [copied_source, copied_bin_i386, copied_bin_hppa] = self.doCopy( |
| 424 | source, target_archive, nobby, source.pocket, True) |
| 425 | - self.assertEquals(copied_source.component, existing_source.component) |
| 426 | + self.assertEqual(copied_source.component, existing_source.component) |
| 427 | self.assertComponentSectionAndPriority( |
| 428 | ebin_i386.component, ebin_i386, copied_bin_i386) |
| 429 | self.assertComponentSectionAndPriority( |
| 430 | @@ -1365,7 +1356,7 @@ |
| 431 | |
| 432 | [copied_source, copied_bin_i386, copied_bin_hppa] = self.doCopy( |
| 433 | source, archive, nobby, PackagePublishingPocket.UPDATES, True) |
| 434 | - self.assertEquals(copied_source.component, source.component) |
| 435 | + self.assertEqual(copied_source.component, source.component) |
| 436 | self.assertComponentSectionAndPriority( |
| 437 | bin_i386.component, bin_i386, copied_bin_i386) |
| 438 | self.assertComponentSectionAndPriority( |
| 439 | @@ -1387,7 +1378,7 @@ |
| 440 | [copied_source, copied_bin_i386, copied_bin_hppa] = self.doCopy( |
| 441 | source, target_archive, nobby, source.pocket, True) |
| 442 | main = getUtility(IComponentSet)['main'] |
| 443 | - self.assertEquals(main, copied_source.component) |
| 444 | + self.assertEqual(main, copied_source.component) |
| 445 | self.assertComponentSectionAndPriority( |
| 446 | main, bin_i386, copied_bin_i386) |
| 447 | self.assertComponentSectionAndPriority( |
| 448 | @@ -1444,9 +1435,8 @@ |
| 449 | person=target_archive.owner, check_permissions=False, |
| 450 | send_email=True) |
| 451 | [notification] = pop_notifications() |
| 452 | - self.assertEquals( |
| 453 | - get_ppa_reference(target_archive), |
| 454 | - notification['X-Launchpad-PPA']) |
| 455 | + self.assertEqual( |
| 456 | + get_ppa_reference(target_archive), notification['X-Launchpad-PPA']) |
| 457 | body = notification.get_payload()[0].get_payload() |
| 458 | expected = dedent("""\ |
| 459 | Accepted: |
| 460 | @@ -1483,11 +1473,10 @@ |
| 461 | person=source.sourcepackagerelease.creator, |
| 462 | check_permissions=False, send_email=True) |
| 463 | [notification, announcement] = pop_notifications() |
| 464 | - self.assertEquals( |
| 465 | - 'Foo Bar <foo.bar@canonical.com>', notification['To']) |
| 466 | - self.assertEquals('nobby-changes@example.com', announcement['To']) |
| 467 | + self.assertEqual('Foo Bar <foo.bar@canonical.com>', notification['To']) |
| 468 | + self.assertEqual('nobby-changes@example.com', announcement['To']) |
| 469 | for mail in (notification, announcement): |
| 470 | - self.assertEquals( |
| 471 | + self.assertEqual( |
| 472 | '[ubuntutest/nobby] foo 1.0-2 (Accepted)', mail['Subject']) |
| 473 | expected_text = dedent("""\ |
| 474 | foo (1.0-2) unstable; urgency=3Dlow |
| 475 | @@ -1523,7 +1512,7 @@ |
| 476 | check_permissions=False, send_email=True, |
| 477 | sponsored=sponsored_person) |
| 478 | [notification, announcement] = pop_notifications() |
| 479 | - self.assertEquals( |
| 480 | + self.assertEqual( |
| 481 | 'Sponsored <sponsored@example.com>', announcement['From']) |
| 482 | self.assertEqual(sponsored_person, copied_source.creator) |
| 483 | |
| 484 | @@ -1602,11 +1591,9 @@ |
| 485 | notifications = pop_notifications() |
| 486 | self.assertEqual(1, len(notifications)) |
| 487 | [notification] = notifications |
| 488 | - self.assertEquals( |
| 489 | - 'Foo Bar <foo.bar@canonical.com>', notification['To']) |
| 490 | - self.assertEquals( |
| 491 | - '[ubuntutest/nobby] foo 1.0-2 (Rejected)', |
| 492 | - notification['Subject']) |
| 493 | + self.assertEqual('Foo Bar <foo.bar@canonical.com>', notification['To']) |
| 494 | + self.assertEqual( |
| 495 | + '[ubuntutest/nobby] foo 1.0-2 (Rejected)', notification['Subject']) |
| 496 | expected_text = ( |
| 497 | "Rejected:\n" |
| 498 | "foo 1.0-2 in breezy-autotest (a different source with the same " |
| 499 | @@ -1623,7 +1610,7 @@ |
| 500 | [source], target_archive, nobby, source.pocket, False, |
| 501 | person=target_archive.owner, check_permissions=False, |
| 502 | send_email=False) |
| 503 | - self.assertEquals([], pop_notifications()) |
| 504 | + self.assertEqual([], pop_notifications()) |
| 505 | |
| 506 | def test_copying_unsupported_arch_with_override(self): |
| 507 | # When the copier is passed an unsupported arch with an override |
| 508 | @@ -1659,9 +1646,7 @@ |
| 509 | person=target_archive.owner, check_permissions=False, |
| 510 | send_email=False) |
| 511 | |
| 512 | - self.assertEqual( |
| 513 | - target_archive.owner, |
| 514 | - copied_source.creator) |
| 515 | + self.assertEqual(target_archive.owner, copied_source.creator) |
| 516 | |
| 517 | def test_unsponsored_copy_does_not_set_sponsor(self): |
| 518 | # If the copy is not sponsored, SPPH.sponsor is none |
| 519 | @@ -1673,9 +1658,42 @@ |
| 520 | person=target_archive.owner, check_permissions=False, |
| 521 | send_email=False) |
| 522 | |
| 523 | + self.assertIsNone(copied_source.sponsor) |
| 524 | + |
| 525 | + def test_copy_custom_upload_files(self): |
| 526 | + # Custom upload files are queued for republication when they are |
| 527 | + # copied. |
| 528 | + self.test_publisher.breezy_autotest.status = SeriesStatus.CURRENT |
| 529 | + source = self.test_publisher.getPubSource( |
| 530 | + pocket=PackagePublishingPocket.PROPOSED) |
| 531 | + self.test_publisher.getPubBinaries( |
| 532 | + pocket=PackagePublishingPocket.PROPOSED, pub_source=source) |
| 533 | + [build] = source.getBuilds() |
| 534 | + custom_file = self.factory.makeLibraryFileAlias() |
| 535 | + build.package_upload.addCustom( |
| 536 | + custom_file, PackageUploadCustomFormat.DIST_UPGRADER) |
| 537 | + # Make the new librarian file available. |
| 538 | + self.layer.txn.commit() |
| 539 | + |
| 540 | + self.doCopy( |
| 541 | + source, source.archive, source.distroseries, |
| 542 | + PackagePublishingPocket.UPDATES, include_binaries=True) |
| 543 | + [upload] = source.distroseries.getPackageUploads( |
| 544 | + status=PackageUploadStatus.ACCEPTED, archive=source.archive, |
| 545 | + pocket=PackagePublishingPocket.UPDATES, |
| 546 | + custom_type=PackageUploadCustomFormat.DIST_UPGRADER) |
| 547 | + |
| 548 | + # The upload is targeted to the right publishing context. |
| 549 | + self.assertEqual(source.archive, upload.archive) |
| 550 | + self.assertEqual(source.distroseries, upload.distroseries) |
| 551 | + self.assertEqual(PackagePublishingPocket.UPDATES, upload.pocket) |
| 552 | + |
| 553 | + # It contains only the custom files. |
| 554 | + self.assertEqual([], list(upload.sources)) |
| 555 | + self.assertEqual([], list(upload.builds)) |
| 556 | self.assertEqual( |
| 557 | - copied_source.sponsor, |
| 558 | - None) |
| 559 | + [custom_file], |
| 560 | + [custom.libraryfilealias for custom in upload.customfiles]) |
| 561 | |
| 562 | |
| 563 | class TestDoDelayedCopy(TestCaseWithFactory, BaseDoCopyTests): |
| 564 | @@ -1696,16 +1714,13 @@ |
| 565 | |
| 566 | # Make ubuntutest/breezy-autotest CURRENT so uploads to SECURITY |
| 567 | # pocket can be accepted. |
| 568 | - self.test_publisher.breezy_autotest.status = ( |
| 569 | - SeriesStatus.CURRENT) |
| 570 | + self.test_publisher.breezy_autotest.status = SeriesStatus.CURRENT |
| 571 | |
| 572 | def assertCopied(self, copy, series, arch_tags): |
| 573 | - self.assertEquals( |
| 574 | - copy.sources[0].sourcepackagerelease.title, |
| 575 | - 'foo - 666') |
| 576 | - self.assertEquals( |
| 577 | - sorted(arch_tags), |
| 578 | - sorted([pub.build.arch_tag for pub in copy.builds])) |
| 579 | + self.assertEqual( |
| 580 | + copy.sources[0].sourcepackagerelease.title, 'foo - 666') |
| 581 | + self.assertContentEqual( |
| 582 | + arch_tags, [pub.build.arch_tag for pub in copy.builds]) |
| 583 | |
| 584 | def doCopy(self, source, archive, series, pocket, include_binaries): |
| 585 | return _do_delayed_copy(source, archive, series, pocket, True) |
| 586 | @@ -1758,35 +1773,32 @@ |
| 587 | |
| 588 | # A delayed-copy `IPackageUpload` record is returned. |
| 589 | self.assertTrue(delayed_copy.is_delayed_copy) |
| 590 | - self.assertEquals( |
| 591 | - PackageUploadStatus.ACCEPTED, delayed_copy.status) |
| 592 | + self.assertEqual(PackageUploadStatus.ACCEPTED, delayed_copy.status) |
| 593 | |
| 594 | # The returned object has a more descriptive 'displayname' |
| 595 | # attribute than plain `IPackageUpload` instances. |
| 596 | - self.assertEquals( |
| 597 | + self.assertEqual( |
| 598 | 'Delayed copy of foocomm - ' |
| 599 | '1.0-2 (source, i386, raw-dist-upgrader)', |
| 600 | delayed_copy.displayname) |
| 601 | |
| 602 | # It is targeted to the right publishing context. |
| 603 | - self.assertEquals(self.copy_archive, delayed_copy.archive) |
| 604 | - self.assertEquals(self.copy_series, delayed_copy.distroseries) |
| 605 | - self.assertEquals(self.copy_pocket, delayed_copy.pocket) |
| 606 | + self.assertEqual(self.copy_archive, delayed_copy.archive) |
| 607 | + self.assertEqual(self.copy_series, delayed_copy.distroseries) |
| 608 | + self.assertEqual(self.copy_pocket, delayed_copy.pocket) |
| 609 | |
| 610 | # And it contains the source, build and custom files. |
| 611 | - self.assertEquals( |
| 612 | + self.assertEqual( |
| 613 | [source.sourcepackagerelease], |
| 614 | [pus.sourcepackagerelease for pus in delayed_copy.sources]) |
| 615 | |
| 616 | [build] = source.getBuilds() |
| 617 | - self.assertEquals( |
| 618 | - [build], |
| 619 | - [pub.build for pub in delayed_copy.builds]) |
| 620 | + self.assertEqual([build], [pub.build for pub in delayed_copy.builds]) |
| 621 | |
| 622 | [custom_file] = [ |
| 623 | custom.libraryfilealias |
| 624 | for custom in build.package_upload.customfiles] |
| 625 | - self.assertEquals( |
| 626 | + self.assertEqual( |
| 627 | [custom_file], |
| 628 | [custom.libraryfilealias for custom in delayed_copy.customfiles]) |
| 629 | |
| 630 | @@ -1843,23 +1855,20 @@ |
| 631 | # Setup and execute the delayed copy procedure. This should |
| 632 | # now result in an accepted delayed upload. |
| 633 | delayed_copy = self.do_delayed_copy(source) |
| 634 | - self.assertEquals( |
| 635 | - PackageUploadStatus.ACCEPTED, delayed_copy.status) |
| 636 | + self.assertEqual(PackageUploadStatus.ACCEPTED, delayed_copy.status) |
| 637 | |
| 638 | # And it contains the source, build and custom files. |
| 639 | - self.assertEquals( |
| 640 | + self.assertEqual( |
| 641 | [source.sourcepackagerelease], |
| 642 | [pus.sourcepackagerelease for pus in delayed_copy.sources]) |
| 643 | |
| 644 | [build] = source.getBuilds() |
| 645 | - self.assertEquals( |
| 646 | - [build], |
| 647 | - [pub.build for pub in delayed_copy.builds]) |
| 648 | + self.assertEqual([build], [pub.build for pub in delayed_copy.builds]) |
| 649 | |
| 650 | [custom_file] = [ |
| 651 | custom.libraryfilealias |
| 652 | for custom in build.package_upload.customfiles] |
| 653 | - self.assertEquals( |
| 654 | + self.assertEqual( |
| 655 | [custom_file], |
| 656 | [custom.libraryfilealias for custom in delayed_copy.customfiles]) |
| 657 | |
| 658 | @@ -1915,9 +1924,8 @@ |
| 659 | # archive context. Also after this point, the same delayed-copy |
| 660 | # request will be denied by `CopyChecker`. |
| 661 | [build_hppa, build_i386] = source.getBuilds() |
| 662 | - self.assertEquals( |
| 663 | - [build_i386], |
| 664 | - [pub.build for pub in delayed_copy.builds]) |
| 665 | + self.assertEqual( |
| 666 | + [build_i386], [pub.build for pub in delayed_copy.builds]) |
| 667 | |
| 668 | |
| 669 | class CopyPackageScriptTestCase(unittest.TestCase): |
| 670 | @@ -2068,8 +2076,7 @@ |
| 671 | self.assertEqual(len(copied), size) |
| 672 | |
| 673 | for candidate in copied: |
| 674 | - self.assertEqual( |
| 675 | - candidate.status, PackagePublishingStatus.PENDING) |
| 676 | + self.assertEqual(PackagePublishingStatus.PENDING, candidate.status) |
| 677 | |
| 678 | def excludeOlds(found, old_pending_ids): |
| 679 | return [pub.id for pub in found if pub.id not in old_pending_ids] |
| 680 | @@ -2399,16 +2406,14 @@ |
| 681 | active_warty_architectures = [ |
| 682 | arch.architecturetag for arch in warty.architectures |
| 683 | if arch.getChroot()] |
| 684 | - self.assertEqual( |
| 685 | - active_warty_architectures, ['i386']) |
| 686 | + self.assertEqual(active_warty_architectures, ['i386']) |
| 687 | |
| 688 | # Setup ubuntu/hoary supporting i386 and hppa architetures. |
| 689 | hoary = ubuntu.getSeries('hoary') |
| 690 | test_publisher.addFakeChroots(hoary) |
| 691 | active_hoary_architectures = [ |
| 692 | arch.architecturetag for arch in hoary.architectures] |
| 693 | - self.assertEqual( |
| 694 | - sorted(active_hoary_architectures), ['hppa', 'i386']) |
| 695 | + self.assertEqual(sorted(active_hoary_architectures), ['hppa', 'i386']) |
| 696 | |
| 697 | # We will create an architecture-specific source and its binaries |
| 698 | # for i386 in ubuntu/warty. They will be copied over. |
| 699 | @@ -2500,8 +2505,7 @@ |
| 700 | # architecture (hppa). |
| 701 | [new_build] = copied_source.getBuilds() |
| 702 | self.assertEqual( |
| 703 | - new_build.title, |
| 704 | - 'hppa build of boing 1.0 in ubuntu hoary RELEASE') |
| 705 | + new_build.title, 'hppa build of boing 1.0 in ubuntu hoary RELEASE') |
| 706 | |
| 707 | def testVersionConflictInDifferentPockets(self): |
| 708 | """Copy-package stops copies conflicting in different pocket. |
| 709 | @@ -2626,8 +2630,7 @@ |
| 710 | |
| 711 | [copied_source, original_source] = sources |
| 712 | |
| 713 | - self.assertEqual( |
| 714 | - copied_source.pocket, PackagePublishingPocket.UPDATES) |
| 715 | + self.assertEqual(copied_source.pocket, PackagePublishingPocket.UPDATES) |
| 716 | self.assertEqual( |
| 717 | original_source.pocket, PackagePublishingPocket.SECURITY) |
| 718 | |
| 719 | @@ -2673,8 +2676,7 @@ |
| 720 | copied = copy_helper.mainTask() |
| 721 | |
| 722 | [source_copy, i386_copy] = copied |
| 723 | - self.assertEqual( |
| 724 | - source_copy.displayname, 'lazy-building 1.0 in hoary') |
| 725 | + self.assertEqual(source_copy.displayname, 'lazy-building 1.0 in hoary') |
| 726 | self.assertEqual(i386_copy.displayname, 'lazy-bin 1.0 in hoary i386') |
| 727 | |
| 728 | target_archive = copy_helper.destination.archive |
| 729 | @@ -2735,12 +2737,8 @@ |
| 730 | from_suite='warty', to_suite='hoary', to_ppa='mark') |
| 731 | copied = copy_helper.mainTask() |
| 732 | |
| 733 | - self.assertEqual( |
| 734 | - str(copy_helper.location), |
| 735 | - 'cprov: warty-RELEASE') |
| 736 | - self.assertEqual( |
| 737 | - str(copy_helper.destination), |
| 738 | - 'mark: hoary-RELEASE') |
| 739 | + self.assertEqual('cprov: warty-RELEASE', str(copy_helper.location)) |
| 740 | + self.assertEqual('mark: hoary-RELEASE', str(copy_helper.destination)) |
| 741 | |
| 742 | target_archive = copy_helper.destination.archive |
| 743 | self.checkCopies(copied, target_archive, 2) |
| 744 | @@ -3267,10 +3265,10 @@ |
| 745 | section='misc') |
| 746 | |
| 747 | checker = CopyChecker(warty.main_archive, include_binaries=False) |
| 748 | - self.assertIs( |
| 749 | - None, |
| 750 | - checker.checkCopy(proposed_source, warty, |
| 751 | - PackagePublishingPocket.UPDATES, check_permissions=False)) |
| 752 | + self.assertIsNone( |
| 753 | + checker.checkCopy( |
| 754 | + proposed_source, warty, PackagePublishingPocket.UPDATES, |
| 755 | + check_permissions=False)) |
| 756 | |
| 757 | def testCopySourceWithConflictingFilesInPPAs(self): |
| 758 | """We can copy source if the source files match, both in name and |
| 759 | @@ -3355,10 +3353,10 @@ |
| 760 | self.layer.txn.commit() |
| 761 | |
| 762 | checker = CopyChecker(dest_ppa, include_binaries=False) |
| 763 | - self.assertIs( |
| 764 | - None, |
| 765 | - checker.checkCopy(test2_source, warty, |
| 766 | - PackagePublishingPocket.RELEASE, check_permissions=False)) |
| 767 | + self.assertIsNone( |
| 768 | + checker.checkCopy( |
| 769 | + test2_source, warty, PackagePublishingPocket.RELEASE, |
| 770 | + check_permissions=False)) |
| 771 | |
| 772 | def testCopySourceWithExpiredSourcesInDestination(self): |
| 773 | """We can also copy sources if the destination archive has expired |
| 774 | @@ -3401,7 +3399,7 @@ |
| 775 | switch_dbuser(self.dbuser) |
| 776 | |
| 777 | checker = CopyChecker(dest_ppa, include_binaries=False) |
| 778 | - self.assertIs( |
| 779 | - None, |
| 780 | - checker.checkCopy(test2_source, warty, |
| 781 | - PackagePublishingPocket.RELEASE, check_permissions=False)) |
| 782 | + self.assertIsNone( |
| 783 | + checker.checkCopy( |
| 784 | + test2_source, warty, PackagePublishingPocket.RELEASE, |
| 785 | + check_permissions=False)) |
| 786 | |
| 787 | === modified file 'lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py' |
| 788 | --- lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py 2012-05-30 10:25:43 +0000 |
| 789 | +++ lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py 2012-06-25 16:57:21 +0000 |
| 790 | @@ -6,6 +6,7 @@ |
| 791 | __metaclass__ = type |
| 792 | |
| 793 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
| 794 | +from lp.registry.interfaces.series import SeriesStatus |
| 795 | from lp.soyuz.enums import ( |
| 796 | ArchivePurpose, |
| 797 | PackageUploadCustomFormat, |
| 798 | @@ -108,7 +109,7 @@ |
| 799 | # Alas, PackageUploadCustom relies on the Librarian. |
| 800 | layer = LaunchpadZopelessLayer |
| 801 | |
| 802 | - def makeUpload(self, distroseries=None, |
| 803 | + def makeUpload(self, distroseries=None, pocket=None, |
| 804 | custom_type=PackageUploadCustomFormat.DEBIAN_INSTALLER, |
| 805 | version=None, arch=None): |
| 806 | """Create a `PackageUploadCustom`.""" |
| 807 | @@ -121,7 +122,7 @@ |
| 808 | arch = self.factory.getUniqueString() |
| 809 | filename = "%s.tar.gz" % '_'.join([package_name, version, arch]) |
| 810 | package_upload = self.factory.makeCustomPackageUpload( |
| 811 | - distroseries=distroseries, custom_type=custom_type, |
| 812 | + distroseries=distroseries, pocket=pocket, custom_type=custom_type, |
| 813 | filename=filename) |
| 814 | return package_upload.customfiles[0] |
| 815 | |
| 816 | @@ -213,6 +214,19 @@ |
| 817 | upload.id for upload in copier.getCandidateUploads(source_series)] |
| 818 | self.assertEqual(sorted(candidate_ids, reverse=True), candidate_ids) |
| 819 | |
| 820 | + def test_getCandidateUploads_filters_by_pocket(self): |
| 821 | + # getCandidateUploads ignores uploads for other pockets. |
| 822 | + source_series = self.factory.makeDistroSeries() |
| 823 | + matching_upload = self.makeUpload( |
| 824 | + source_series, pocket=PackagePublishingPocket.PROPOSED) |
| 825 | + nonmatching_upload = self.makeUpload( |
| 826 | + source_series, pocket=PackagePublishingPocket.BACKPORTS) |
| 827 | + copier = CustomUploadsCopier(FakeDistroSeries()) |
| 828 | + candidate_uploads = copier.getCandidateUploads( |
| 829 | + source_series, PackagePublishingPocket.PROPOSED) |
| 830 | + self.assertContentEqual([matching_upload], candidate_uploads) |
| 831 | + self.assertNotIn(nonmatching_upload, candidate_uploads) |
| 832 | + |
| 833 | def test_getKey_includes_format_and_architecture(self): |
| 834 | # The key returned by getKey consists of custom upload type, |
| 835 | # and architecture. |
| 836 | @@ -221,7 +235,7 @@ |
| 837 | # component name as well. |
| 838 | source_series = self.factory.makeDistroSeries() |
| 839 | upload = self.makeUpload( |
| 840 | - source_series, PackageUploadCustomFormat.DIST_UPGRADER, |
| 841 | + source_series, custom_type=PackageUploadCustomFormat.DIST_UPGRADER, |
| 842 | arch='mips') |
| 843 | copier = CustomUploadsCopier(FakeDistroSeries()) |
| 844 | expected_key = ( |
| 845 | @@ -379,8 +393,8 @@ |
| 846 | # copyUpload copies the original upload into the release pocket, |
| 847 | # even though the original is more likely to be in another |
| 848 | # pocket. |
| 849 | - original_upload = self.makeUpload() |
| 850 | - original_upload.packageupload.pocket = PackagePublishingPocket.UPDATES |
| 851 | + original_upload = self.makeUpload( |
| 852 | + pocket=PackagePublishingPocket.UPDATES) |
| 853 | target_series = self.factory.makeDistroSeries() |
| 854 | copier = CustomUploadsCopier(target_series) |
| 855 | copied_upload = copier.copyUpload(original_upload) |
| 856 | @@ -388,6 +402,21 @@ |
| 857 | PackagePublishingPocket.RELEASE, |
| 858 | copied_upload.packageupload.pocket) |
| 859 | |
| 860 | + def test_copyUpload_to_updates_pocket(self): |
| 861 | + # copyUpload copies an upload between pockets in the same series if |
| 862 | + # requested. |
| 863 | + source_series = self.factory.makeDistroSeries( |
| 864 | + status=SeriesStatus.CURRENT) |
| 865 | + original_upload = self.makeUpload( |
| 866 | + distroseries=source_series, |
| 867 | + pocket=PackagePublishingPocket.PROPOSED) |
| 868 | + copier = CustomUploadsCopier( |
| 869 | + source_series, target_pocket=PackagePublishingPocket.UPDATES) |
| 870 | + copied_upload = copier.copyUpload(original_upload) |
| 871 | + self.assertEqual( |
| 872 | + PackagePublishingPocket.UPDATES, |
| 873 | + copied_upload.packageupload.pocket) |
| 874 | + |
| 875 | def test_copyUpload_accepts_upload(self): |
| 876 | # Uploads created by copyUpload are automatically accepted. |
| 877 | original_upload = self.makeUpload() |
| 878 | |
| 879 | === modified file 'lib/lp/testing/factory.py' |
| 880 | --- lib/lp/testing/factory.py 2012-06-11 09:55:13 +0000 |
| 881 | +++ lib/lp/testing/factory.py 2012-06-25 16:57:21 +0000 |
| 882 | @@ -3493,28 +3493,32 @@ |
| 883 | sourcepackagename=sourcepackagename, component=component)) |
| 884 | return upload |
| 885 | |
| 886 | - def makeBuildPackageUpload(self, distroseries=None, |
| 887 | - binarypackagename=None): |
| 888 | + def makeBuildPackageUpload(self, distroseries=None, pocket=None, |
| 889 | + binarypackagename=None, |
| 890 | + source_package_release=None): |
| 891 | """Make a `PackageUpload` with a `PackageUploadBuild` attached.""" |
| 892 | if distroseries is None: |
| 893 | distroseries = self.makeDistroSeries() |
| 894 | upload = self.makePackageUpload( |
| 895 | - distroseries=distroseries, archive=distroseries.main_archive) |
| 896 | - build = self.makeBinaryPackageBuild() |
| 897 | + distroseries=distroseries, archive=distroseries.main_archive, |
| 898 | + pocket=pocket) |
| 899 | + build = self.makeBinaryPackageBuild( |
| 900 | + source_package_release=source_package_release, pocket=pocket) |
| 901 | upload.addBuild(build) |
| 902 | self.makeBinaryPackageRelease( |
| 903 | binarypackagename=binarypackagename, build=build) |
| 904 | return upload |
| 905 | |
| 906 | - def makeCustomPackageUpload(self, distroseries=None, custom_type=None, |
| 907 | - filename=None): |
| 908 | + def makeCustomPackageUpload(self, distroseries=None, pocket=None, |
| 909 | + custom_type=None, filename=None): |
| 910 | """Make a `PackageUpload` with a `PackageUploadCustom` attached.""" |
| 911 | if distroseries is None: |
| 912 | distroseries = self.makeDistroSeries() |
| 913 | if custom_type is None: |
| 914 | custom_type = PackageUploadCustomFormat.DEBIAN_INSTALLER |
| 915 | upload = self.makePackageUpload( |
| 916 | - distroseries=distroseries, archive=distroseries.main_archive) |
| 917 | + distroseries=distroseries, archive=distroseries.main_archive, |
| 918 | + pocket=pocket) |
| 919 | file_alias = self.makeLibraryFileAlias(filename=filename) |
| 920 | upload.addCustom(file_alias, custom_type) |
| 921 | return upload |
| 922 | |
| 923 | === modified file 'lib/lp/testing/tests/test_factory.py' |
| 924 | --- lib/lp/testing/tests/test_factory.py 2012-01-01 02:58:52 +0000 |
| 925 | +++ lib/lp/testing/tests/test_factory.py 2012-06-25 16:57:21 +0000 |
| 926 | @@ -1,4 +1,4 @@ |
| 927 | -# Copyright 2010-2011 Canonical Ltd. This software is licensed under the |
| 928 | +# Copyright 2010-2012 Canonical Ltd. This software is licensed under the |
| 929 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 930 | |
| 931 | """Tests for the Launchpad object factory.""" |
| 932 | @@ -781,10 +781,12 @@ |
| 933 | distroseries = self.factory.makeDistroSeries() |
| 934 | bpn = self.factory.makeBinaryPackageName() |
| 935 | pu = self.factory.makeBuildPackageUpload( |
| 936 | - distroseries=distroseries, binarypackagename=bpn) |
| 937 | + distroseries=distroseries, pocket=PackagePublishingPocket.PROPOSED, |
| 938 | + binarypackagename=bpn) |
| 939 | build = list(pu.builds)[0].build |
| 940 | self.assertEqual(distroseries, pu.distroseries) |
| 941 | self.assertEqual(distroseries.distribution, pu.archive.distribution) |
| 942 | + self.assertEqual(PackagePublishingPocket.PROPOSED, pu.pocket) |
| 943 | release = IStore(distroseries).find( |
| 944 | BinaryPackageRelease, BinaryPackageRelease.build == build).one() |
| 945 | self.assertEqual(bpn, release.binarypackagename) |
| 946 | @@ -803,11 +805,12 @@ |
| 947 | custom_type = PackageUploadCustomFormat.ROSETTA_TRANSLATIONS |
| 948 | filename = self.factory.getUniqueString() |
| 949 | pu = self.factory.makeCustomPackageUpload( |
| 950 | - distroseries=distroseries, custom_type=custom_type, |
| 951 | - filename=filename) |
| 952 | + distroseries=distroseries, pocket=PackagePublishingPocket.PROPOSED, |
| 953 | + custom_type=custom_type, filename=filename) |
| 954 | custom = list(pu.customfiles)[0] |
| 955 | self.assertEqual(distroseries, pu.distroseries) |
| 956 | self.assertEqual(distroseries.distribution, pu.archive.distribution) |
| 957 | + self.assertEqual(PackagePublishingPocket.PROPOSED, pu.pocket) |
| 958 | self.assertEqual(custom_type, custom.customformat) |
| 959 | self.assertEqual(filename, custom.libraryfilealias.filename) |
| 960 |

This branch looks good. The replacing of assertEquals with assertEqual is appreciated.