Merge ~cjwatson/launchpad:built-using-guard-deletion into launchpad:master
- Git
- lp:~cjwatson/launchpad
- built-using-guard-deletion
- Merge into master
Status: | Needs review | ||||
---|---|---|---|---|---|
Proposed branch: | ~cjwatson/launchpad:built-using-guard-deletion | ||||
Merge into: | launchpad:master | ||||
Prerequisite: | ~cjwatson/launchpad:built-using-ui | ||||
Diff against target: |
393 lines (+293/-1) 5 files modified
lib/lp/soyuz/interfaces/binarysourcereference.py (+15/-0) lib/lp/soyuz/model/binarysourcereference.py (+29/-1) lib/lp/soyuz/model/publishing.py (+54/-0) lib/lp/soyuz/tests/test_binarysourcereference.py (+100/-0) lib/lp/soyuz/tests/test_publishing.py (+95/-0) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Launchpad code reviewers | Pending | ||
Review via email: mp+381239@code.launchpad.net |
Commit message
Guard removal of sources referenced by Built-Using
Description of the change
Prevent SourcePackagePu
This isn't necessarily complete: in particular, it can miss references from other pockets, and in any case it might race with a build still in progress. The intent of this is not to ensure integrity, but to avoid some easily-detectable mistakes that could cause confusion.
- c0c4aa2... by Colin Watson
-
Expand deletion guard to other pockets
It now checks all pockets that could legitimately depend on the one from
which the publication is being deleted. - 06ccc3e... by Colin Watson
-
Simplify tests using createFromSourc
ePackageRelease s
Unmerged commits
- 06ccc3e... by Colin Watson
-
Simplify tests using createFromSourc
ePackageRelease s - c0c4aa2... by Colin Watson
-
Expand deletion guard to other pockets
It now checks all pockets that could legitimately depend on the one from
which the publication is being deleted. - d7fbcfd... by Colin Watson
-
Guard removal of sources referenced by Built-Using
Prevent SourcePackagePu
blishingHistory .requestDeletio n from deleting
source publications that have Built-Using references from active binary
publications in the same archive and suite.This isn't necessarily complete: in particular, it can miss references
from other pockets, and in any case it might race with a build still in
progress. The intent of this is not to ensure integrity, but to avoid
some easily-detectable mistakes that could cause confusion.LP: #1868558
Preview Diff
1 | diff --git a/lib/lp/soyuz/interfaces/binarysourcereference.py b/lib/lp/soyuz/interfaces/binarysourcereference.py | |||
2 | index dc21765..e625cf9 100644 | |||
3 | --- a/lib/lp/soyuz/interfaces/binarysourcereference.py | |||
4 | +++ b/lib/lp/soyuz/interfaces/binarysourcereference.py | |||
5 | @@ -84,3 +84,18 @@ class IBinarySourceReferenceSet(Interface): | |||
6 | 84 | :param reference_type: A `BinarySourceReferenceType` to search for. | 84 | :param reference_type: A `BinarySourceReferenceType` to search for. |
7 | 85 | :return: A `ResultSet` of matching `IBinarySourceReference`s. | 85 | :return: A `ResultSet` of matching `IBinarySourceReference`s. |
8 | 86 | """ | 86 | """ |
9 | 87 | |||
10 | 88 | def findPublished(archive, distroseries, pockets, reference_type, | ||
11 | 89 | source_package_releases=None): | ||
12 | 90 | """Find references corresponding to published binary publications. | ||
13 | 91 | |||
14 | 92 | :param archive: An `IArchive` to search for binary publications. | ||
15 | 93 | :param distroseries: An `IDistroSeries` to search for binary | ||
16 | 94 | publications. | ||
17 | 95 | :param pocket: A collection of `PackagePublishingPocket`s to search | ||
18 | 96 | for binary publications. | ||
19 | 97 | :param reference_type: A `BinarySourceReferenceType` to search for. | ||
20 | 98 | :param source_package_releases: If not None, only return references | ||
21 | 99 | pointing to any of this sequence of `ISourcePackageRelease`s. | ||
22 | 100 | :return: A `ResultSet` of matching `IBinarySourceReference`s. | ||
23 | 101 | """ | ||
24 | diff --git a/lib/lp/soyuz/model/binarysourcereference.py b/lib/lp/soyuz/model/binarysourcereference.py | |||
25 | index adcfb6f..ca3563b 100644 | |||
26 | --- a/lib/lp/soyuz/model/binarysourcereference.py | |||
27 | +++ b/lib/lp/soyuz/model/binarysourcereference.py | |||
28 | @@ -25,12 +25,17 @@ from lp.services.database.enumcol import DBEnum | |||
29 | 25 | from lp.services.database.interfaces import IStore | 25 | from lp.services.database.interfaces import IStore |
30 | 26 | from lp.services.database.stormbase import StormBase | 26 | from lp.services.database.stormbase import StormBase |
31 | 27 | from lp.soyuz.adapters.archivedependencies import pocket_dependencies | 27 | from lp.soyuz.adapters.archivedependencies import pocket_dependencies |
33 | 28 | from lp.soyuz.enums import BinarySourceReferenceType | 28 | from lp.soyuz.enums import ( |
34 | 29 | BinarySourceReferenceType, | ||
35 | 30 | PackagePublishingStatus, | ||
36 | 31 | ) | ||
37 | 29 | from lp.soyuz.interfaces.binarysourcereference import ( | 32 | from lp.soyuz.interfaces.binarysourcereference import ( |
38 | 30 | IBinarySourceReference, | 33 | IBinarySourceReference, |
39 | 31 | IBinarySourceReferenceSet, | 34 | IBinarySourceReferenceSet, |
40 | 32 | UnparsableBuiltUsing, | 35 | UnparsableBuiltUsing, |
41 | 33 | ) | 36 | ) |
42 | 37 | from lp.soyuz.model.distroarchseries import DistroArchSeries | ||
43 | 38 | from lp.soyuz.model.publishing import BinaryPackagePublishingHistory | ||
44 | 34 | 39 | ||
45 | 35 | 40 | ||
46 | 36 | @implementer(IBinarySourceReference) | 41 | @implementer(IBinarySourceReference) |
47 | @@ -147,3 +152,26 @@ class BinarySourceReferenceSet: | |||
48 | 147 | BinarySourceReference, | 152 | BinarySourceReference, |
49 | 148 | BinarySourceReference.binary_package_release == bpr, | 153 | BinarySourceReference.binary_package_release == bpr, |
50 | 149 | BinarySourceReference.reference_type == reference_type) | 154 | BinarySourceReference.reference_type == reference_type) |
51 | 155 | |||
52 | 156 | @classmethod | ||
53 | 157 | def findPublished(cls, archive, distroseries, pockets, reference_type, | ||
54 | 158 | source_package_releases=None): | ||
55 | 159 | """See `IBinarySourceReferenceSet`.""" | ||
56 | 160 | clauses = [ | ||
57 | 161 | BinarySourceReference.binary_package_release_id == | ||
58 | 162 | BinaryPackagePublishingHistory.binarypackagereleaseID, | ||
59 | 163 | BinarySourceReference.reference_type == reference_type, | ||
60 | 164 | BinaryPackagePublishingHistory.status == | ||
61 | 165 | PackagePublishingStatus.PUBLISHED, | ||
62 | 166 | BinaryPackagePublishingHistory.archive == archive, | ||
63 | 167 | BinaryPackagePublishingHistory.distroarchseries == | ||
64 | 168 | DistroArchSeries.id, | ||
65 | 169 | BinaryPackagePublishingHistory.pocket.is_in(pockets), | ||
66 | 170 | DistroArchSeries.distroseries == distroseries, | ||
67 | 171 | ] | ||
68 | 172 | if source_package_releases is not None: | ||
69 | 173 | clauses.append( | ||
70 | 174 | BinarySourceReference.source_package_release_id.is_in( | ||
71 | 175 | spr.id for spr in source_package_releases)) | ||
72 | 176 | return IStore(BinarySourceReference).find( | ||
73 | 177 | BinarySourceReference, *clauses).config(distinct=True) | ||
74 | diff --git a/lib/lp/soyuz/model/publishing.py b/lib/lp/soyuz/model/publishing.py | |||
75 | index fafd7f9..3c7ce7d 100644 | |||
76 | --- a/lib/lp/soyuz/model/publishing.py | |||
77 | +++ b/lib/lp/soyuz/model/publishing.py | |||
78 | @@ -76,9 +76,11 @@ from lp.services.webapp.errorlog import ( | |||
79 | 76 | ScriptRequest, | 76 | ScriptRequest, |
80 | 77 | ) | 77 | ) |
81 | 78 | from lp.services.worlddata.model.country import Country | 78 | from lp.services.worlddata.model.country import Country |
82 | 79 | from lp.soyuz.adapters.archivedependencies import pocket_dependencies | ||
83 | 79 | from lp.soyuz.adapters.proxiedsourcefiles import ProxiedSourceLibraryFileAlias | 80 | from lp.soyuz.adapters.proxiedsourcefiles import ProxiedSourceLibraryFileAlias |
84 | 80 | from lp.soyuz.enums import ( | 81 | from lp.soyuz.enums import ( |
85 | 81 | BinaryPackageFormat, | 82 | BinaryPackageFormat, |
86 | 83 | BinarySourceReferenceType, | ||
87 | 82 | PackagePublishingPriority, | 84 | PackagePublishingPriority, |
88 | 83 | PackagePublishingStatus, | 85 | PackagePublishingStatus, |
89 | 84 | PackageUploadStatus, | 86 | PackageUploadStatus, |
90 | @@ -87,6 +89,9 @@ from lp.soyuz.interfaces.binarypackagebuild import ( | |||
91 | 87 | BuildSetStatus, | 89 | BuildSetStatus, |
92 | 88 | IBinaryPackageBuildSet, | 90 | IBinaryPackageBuildSet, |
93 | 89 | ) | 91 | ) |
94 | 92 | from lp.soyuz.interfaces.binarysourcereference import ( | ||
95 | 93 | IBinarySourceReferenceSet, | ||
96 | 94 | ) | ||
97 | 90 | from lp.soyuz.interfaces.component import IComponentSet | 95 | from lp.soyuz.interfaces.component import IComponentSet |
98 | 91 | from lp.soyuz.interfaces.distributionjob import ( | 96 | from lp.soyuz.interfaces.distributionjob import ( |
99 | 92 | IDistroSeriesDifferenceJobSource, | 97 | IDistroSeriesDifferenceJobSource, |
100 | @@ -603,6 +608,25 @@ class SourcePackagePublishingHistory(SQLBase, ArchivePublisherBase): | |||
101 | 603 | "Cannot delete publications from suite '%s'" % | 608 | "Cannot delete publications from suite '%s'" % |
102 | 604 | self.distroseries.getSuite(self.pocket)) | 609 | self.distroseries.getSuite(self.pocket)) |
103 | 605 | 610 | ||
104 | 611 | # Check for active Built-Using references to this source package | ||
105 | 612 | # from any pockets in this archive and series that could | ||
106 | 613 | # legitimately refer to it. This isn't necessarily complete: it's | ||
107 | 614 | # there to avoid confusing consequences of mistakes, not to ensure | ||
108 | 615 | # integrity. (The dominator will reinstate a source publication if | ||
109 | 616 | # necessary.) | ||
110 | 617 | reverse_pockets = { | ||
111 | 618 | source_pocket | ||
112 | 619 | for source_pocket, expanded_pockets in pocket_dependencies.items() | ||
113 | 620 | if self.pocket in expanded_pockets} | ||
114 | 621 | bsrs = getUtility(IBinarySourceReferenceSet).findPublished( | ||
115 | 622 | self.archive, self.distroseries, reverse_pockets, | ||
116 | 623 | BinarySourceReferenceType.BUILT_USING, | ||
117 | 624 | source_package_releases=[self.sourcepackagerelease]) | ||
118 | 625 | if not bsrs.is_empty(): | ||
119 | 626 | raise DeletionError( | ||
120 | 627 | "Cannot delete source publication with a Built-Using " | ||
121 | 628 | "reference from an active binary publication.") | ||
122 | 629 | |||
123 | 606 | self.setDeleted(removed_by, removal_comment) | 630 | self.setDeleted(removed_by, removal_comment) |
124 | 607 | if self.archive.is_main: | 631 | if self.archive.is_main: |
125 | 608 | dsd_job_source = getUtility(IDistroSeriesDifferenceJobSource) | 632 | dsd_job_source = getUtility(IDistroSeriesDifferenceJobSource) |
126 | @@ -1712,6 +1736,36 @@ class PublishingSet: | |||
127 | 1712 | "Cannot delete publications from suite '%s'" % | 1736 | "Cannot delete publications from suite '%s'" % |
128 | 1713 | distroseries.getSuite(pocket)) | 1737 | distroseries.getSuite(pocket)) |
129 | 1714 | 1738 | ||
130 | 1739 | # Check for active Built-Using references to these source packages | ||
131 | 1740 | # from any pockets in this archive and series that could | ||
132 | 1741 | # legitimately refer to them. This isn't necessarily complete: it's | ||
133 | 1742 | # there to avoid confusing consequences of mistakes, not to ensure | ||
134 | 1743 | # integrity. (The dominator will reinstate a source publication if | ||
135 | 1744 | # necessary.) | ||
136 | 1745 | if sources: | ||
137 | 1746 | # XXX cjwatson 2020-03-24: In theory we could consolidate this | ||
138 | 1747 | # into one query, but it's complex and probably not worth it. | ||
139 | 1748 | sprs_by_location = defaultdict(list) | ||
140 | 1749 | for spph in sources: | ||
141 | 1750 | sprs_by_location[ | ||
142 | 1751 | (spph.archive, spph.distroseries, spph.pocket)].append( | ||
143 | 1752 | spph.sourcepackagerelease) | ||
144 | 1753 | for (archive, distroseries, pocket), sprs in ( | ||
145 | 1754 | sprs_by_location.items()): | ||
146 | 1755 | reverse_pockets = { | ||
147 | 1756 | source_pocket | ||
148 | 1757 | for source_pocket, expanded_pockets | ||
149 | 1758 | in pocket_dependencies.items() | ||
150 | 1759 | if pocket in expanded_pockets} | ||
151 | 1760 | bsrs = getUtility(IBinarySourceReferenceSet).findPublished( | ||
152 | 1761 | archive, distroseries, reverse_pockets, | ||
153 | 1762 | BinarySourceReferenceType.BUILT_USING, | ||
154 | 1763 | source_package_releases=sprs) | ||
155 | 1764 | if not bsrs.is_empty(): | ||
156 | 1765 | raise DeletionError( | ||
157 | 1766 | "Cannot delete source publication with a Built-Using " | ||
158 | 1767 | "reference from an active binary publication.") | ||
159 | 1768 | |||
160 | 1715 | spph_ids = [spph.id for spph in sources] | 1769 | spph_ids = [spph.id for spph in sources] |
161 | 1716 | self.setMultipleDeleted( | 1770 | self.setMultipleDeleted( |
162 | 1717 | SourcePackagePublishingHistory, spph_ids, removed_by, | 1771 | SourcePackagePublishingHistory, spph_ids, removed_by, |
163 | diff --git a/lib/lp/soyuz/tests/test_binarysourcereference.py b/lib/lp/soyuz/tests/test_binarysourcereference.py | |||
164 | index f682de8..0c4db7f 100644 | |||
165 | --- a/lib/lp/soyuz/tests/test_binarysourcereference.py | |||
166 | +++ b/lib/lp/soyuz/tests/test_binarysourcereference.py | |||
167 | @@ -20,6 +20,7 @@ from lp.registry.interfaces.pocket import PackagePublishingPocket | |||
168 | 20 | from lp.soyuz.enums import ( | 20 | from lp.soyuz.enums import ( |
169 | 21 | ArchivePurpose, | 21 | ArchivePurpose, |
170 | 22 | BinarySourceReferenceType, | 22 | BinarySourceReferenceType, |
171 | 23 | PackagePublishingStatus, | ||
172 | 23 | ) | 24 | ) |
173 | 24 | from lp.soyuz.interfaces.binarysourcereference import ( | 25 | from lp.soyuz.interfaces.binarysourcereference import ( |
174 | 25 | IBinarySourceReferenceSet, | 26 | IBinarySourceReferenceSet, |
175 | @@ -206,3 +207,102 @@ class TestBinarySourceReference(TestCaseWithFactory): | |||
176 | 206 | [], | 207 | [], |
177 | 207 | self.reference_set.findByBinaryPackageRelease( | 208 | self.reference_set.findByBinaryPackageRelease( |
178 | 208 | other_bpr, BinarySourceReferenceType.BUILT_USING)) | 209 | other_bpr, BinarySourceReferenceType.BUILT_USING)) |
179 | 210 | |||
180 | 211 | def test_findPublished_empty(self): | ||
181 | 212 | archive = self.factory.makeArchive() | ||
182 | 213 | self.assertContentEqual( | ||
183 | 214 | [], | ||
184 | 215 | self.reference_set.findPublished( | ||
185 | 216 | archive, archive.distribution.currentseries, | ||
186 | 217 | {PackagePublishingPocket.RELEASE}, | ||
187 | 218 | BinarySourceReferenceType.BUILT_USING)) | ||
188 | 219 | |||
189 | 220 | def test_findPublished(self): | ||
190 | 221 | # findPublished finds references corresponding to published binary | ||
191 | 222 | # publications. | ||
192 | 223 | das = self.factory.makeDistroArchSeries() | ||
193 | 224 | archive = das.main_archive | ||
194 | 225 | bpphs = [ | ||
195 | 226 | self.factory.makeBinaryPackagePublishingHistory( | ||
196 | 227 | archive=archive, distroarchseries=das, pocket=pocket, | ||
197 | 228 | status=PackagePublishingStatus.PUBLISHED) | ||
198 | 229 | for pocket in ( | ||
199 | 230 | PackagePublishingPocket.RELEASE, | ||
200 | 231 | PackagePublishingPocket.PROPOSED)] | ||
201 | 232 | all_sprs = [] | ||
202 | 233 | bsrs = [] | ||
203 | 234 | for bpph in bpphs: | ||
204 | 235 | spphs = [ | ||
205 | 236 | self.factory.makeSourcePackagePublishingHistory( | ||
206 | 237 | archive=bpph.archive, distroseries=bpph.distroseries, | ||
207 | 238 | pocket=bpph.pocket) | ||
208 | 239 | for _ in range(2)] | ||
209 | 240 | sprs = [spph.sourcepackagerelease for spph in spphs] | ||
210 | 241 | all_sprs.extend(sprs) | ||
211 | 242 | bsrs.extend(self.reference_set.createFromSourcePackageReleases( | ||
212 | 243 | bpph.binarypackagerelease, sprs, | ||
213 | 244 | BinarySourceReferenceType.BUILT_USING)) | ||
214 | 245 | |||
215 | 246 | # Create a few more BPPHs with slight mismatches to ensure that | ||
216 | 247 | # findPublished matches correctly. | ||
217 | 248 | other_bpphs = [] | ||
218 | 249 | other_bpphs.append(self.factory.makeBinaryPackagePublishingHistory( | ||
219 | 250 | archive=archive, pocket=PackagePublishingPocket.RELEASE, | ||
220 | 251 | status=PackagePublishingStatus.PUBLISHED)) | ||
221 | 252 | other_bpphs.append(self.factory.makeBinaryPackagePublishingHistory( | ||
222 | 253 | archive=self.factory.makeArchive( | ||
223 | 254 | distribution=das.distroseries.distribution), | ||
224 | 255 | distroarchseries=das, pocket=PackagePublishingPocket.RELEASE, | ||
225 | 256 | status=PackagePublishingStatus.PUBLISHED)) | ||
226 | 257 | other_bpphs.append(self.factory.makeBinaryPackagePublishingHistory( | ||
227 | 258 | archive=archive, distroarchseries=das, | ||
228 | 259 | pocket=PackagePublishingPocket.UPDATES, | ||
229 | 260 | status=PackagePublishingStatus.PUBLISHED)) | ||
230 | 261 | other_bpphs.append(self.factory.makeBinaryPackagePublishingHistory( | ||
231 | 262 | archive=archive, distroarchseries=das, | ||
232 | 263 | pocket=PackagePublishingPocket.RELEASE, | ||
233 | 264 | status=PackagePublishingStatus.SUPERSEDED)) | ||
234 | 265 | for bpph in other_bpphs: | ||
235 | 266 | spr = self.factory.makeSourcePackagePublishingHistory( | ||
236 | 267 | archive=bpph.archive, distroseries=bpph.distroseries, | ||
237 | 268 | pocket=bpph.pocket).sourcepackagerelease | ||
238 | 269 | self.reference_set.createFromSourcePackageReleases( | ||
239 | 270 | bpph.binarypackagerelease, [spr], | ||
240 | 271 | BinarySourceReferenceType.BUILT_USING) | ||
241 | 272 | |||
242 | 273 | self.assertThat( | ||
243 | 274 | self.reference_set.findPublished( | ||
244 | 275 | archive, das.distroseries, {PackagePublishingPocket.RELEASE}, | ||
245 | 276 | BinarySourceReferenceType.BUILT_USING), | ||
246 | 277 | MatchesSetwise(*( | ||
247 | 278 | MatchesStructure.byEquality( | ||
248 | 279 | binary_package_release=bsr.binary_package_release, | ||
249 | 280 | source_package_release=bsr.source_package_release, | ||
250 | 281 | reference_type=BinarySourceReferenceType.BUILT_USING) | ||
251 | 282 | for bsr in bsrs[:2]))) | ||
252 | 283 | self.assertThat( | ||
253 | 284 | self.reference_set.findPublished( | ||
254 | 285 | archive, das.distroseries, | ||
255 | 286 | {PackagePublishingPocket.RELEASE, | ||
256 | 287 | PackagePublishingPocket.PROPOSED}, | ||
257 | 288 | BinarySourceReferenceType.BUILT_USING), | ||
258 | 289 | MatchesSetwise(*( | ||
259 | 290 | MatchesStructure.byEquality( | ||
260 | 291 | binary_package_release=bsr.binary_package_release, | ||
261 | 292 | source_package_release=bsr.source_package_release, | ||
262 | 293 | reference_type=BinarySourceReferenceType.BUILT_USING) | ||
263 | 294 | for bsr in bsrs))) | ||
264 | 295 | self.assertThat( | ||
265 | 296 | self.reference_set.findPublished( | ||
266 | 297 | archive, das.distroseries, | ||
267 | 298 | {PackagePublishingPocket.RELEASE, | ||
268 | 299 | PackagePublishingPocket.PROPOSED}, | ||
269 | 300 | BinarySourceReferenceType.BUILT_USING, | ||
270 | 301 | source_package_releases=[ | ||
271 | 302 | bsr.source_package_release for bsr in [bsrs[0], bsrs[2]]]), | ||
272 | 303 | MatchesSetwise(*( | ||
273 | 304 | MatchesStructure.byEquality( | ||
274 | 305 | binary_package_release=bsr.binary_package_release, | ||
275 | 306 | source_package_release=bsr.source_package_release, | ||
276 | 307 | reference_type=BinarySourceReferenceType.BUILT_USING) | ||
277 | 308 | for bsr in [bsrs[0], bsrs[2]]))) | ||
278 | diff --git a/lib/lp/soyuz/tests/test_publishing.py b/lib/lp/soyuz/tests/test_publishing.py | |||
279 | index cd7d1ea..43d9b91 100644 | |||
280 | --- a/lib/lp/soyuz/tests/test_publishing.py | |||
281 | +++ b/lib/lp/soyuz/tests/test_publishing.py | |||
282 | @@ -38,9 +38,13 @@ from lp.services.log.logger import DevNullLogger | |||
283 | 38 | from lp.soyuz.enums import ( | 38 | from lp.soyuz.enums import ( |
284 | 39 | ArchivePurpose, | 39 | ArchivePurpose, |
285 | 40 | BinaryPackageFormat, | 40 | BinaryPackageFormat, |
286 | 41 | BinarySourceReferenceType, | ||
287 | 41 | PackageUploadStatus, | 42 | PackageUploadStatus, |
288 | 42 | ) | 43 | ) |
289 | 43 | from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet | 44 | from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet |
290 | 45 | from lp.soyuz.interfaces.binarysourcereference import ( | ||
291 | 46 | IBinarySourceReferenceSet, | ||
292 | 47 | ) | ||
293 | 44 | from lp.soyuz.interfaces.component import IComponentSet | 48 | from lp.soyuz.interfaces.component import IComponentSet |
294 | 45 | from lp.soyuz.interfaces.publishing import ( | 49 | from lp.soyuz.interfaces.publishing import ( |
295 | 46 | active_publishing_status, | 50 | active_publishing_status, |
296 | @@ -984,6 +988,97 @@ class TestPublishingSetLite(TestCaseWithFactory): | |||
297 | 984 | self.assertRaisesWithContent( | 988 | self.assertRaisesWithContent( |
298 | 985 | DeletionError, message, pub.api_requestDeletion, self.person) | 989 | DeletionError, message, pub.api_requestDeletion, self.person) |
299 | 986 | 990 | ||
300 | 991 | def test_requestDeletion_singular_disallows_active_built_using_refs(self): | ||
301 | 992 | # The singular version of requestDeletion checks that there are no | ||
302 | 993 | # active Built-Using references to the source package being deleted. | ||
303 | 994 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
304 | 995 | distroseries = self.factory.makeDistroSeries( | ||
305 | 996 | distribution=archive.distribution) | ||
306 | 997 | das = self.factory.makeDistroArchSeries(distroseries=distroseries) | ||
307 | 998 | bpphs = [ | ||
308 | 999 | self.factory.makeBinaryPackagePublishingHistory( | ||
309 | 1000 | archive=archive, distroarchseries=das, pocket=pocket, | ||
310 | 1001 | status=PackagePublishingStatus.PUBLISHED) | ||
311 | 1002 | for pocket in ( | ||
312 | 1003 | PackagePublishingPocket.RELEASE, | ||
313 | 1004 | PackagePublishingPocket.PROPOSED)] | ||
314 | 1005 | spph = self.factory.makeSourcePackagePublishingHistory( | ||
315 | 1006 | archive=archive, distroseries=distroseries, pocket=bpphs[0].pocket, | ||
316 | 1007 | status=PackagePublishingStatus.PUBLISHED) | ||
317 | 1008 | bsr_set = getUtility(IBinarySourceReferenceSet) | ||
318 | 1009 | for bpph in bpphs: | ||
319 | 1010 | spr = spph.sourcepackagerelease | ||
320 | 1011 | bsr_set.createFromSourcePackageReleases( | ||
321 | 1012 | bpph.binarypackagerelease, [spr], | ||
322 | 1013 | BinarySourceReferenceType.BUILT_USING) | ||
323 | 1014 | |||
324 | 1015 | # As long as the referring binary publications are active, deletion | ||
325 | 1016 | # is disallowed. | ||
326 | 1017 | message = ( | ||
327 | 1018 | "Cannot delete source publication with a Built-Using reference " | ||
328 | 1019 | "from an active binary publication.") | ||
329 | 1020 | self.assertRaisesWithContent( | ||
330 | 1021 | DeletionError, message, spph.requestDeletion, self.person) | ||
331 | 1022 | self.assertRaisesWithContent( | ||
332 | 1023 | DeletionError, message, spph.api_requestDeletion, self.person) | ||
333 | 1024 | bpphs[0].requestDeletion(self.person) | ||
334 | 1025 | self.assertRaisesWithContent( | ||
335 | 1026 | DeletionError, message, spph.requestDeletion, self.person) | ||
336 | 1027 | self.assertRaisesWithContent( | ||
337 | 1028 | DeletionError, message, spph.api_requestDeletion, self.person) | ||
338 | 1029 | bpphs[1].requestDeletion(self.person) | ||
339 | 1030 | |||
340 | 1031 | # Now that all the referring binary publications are deleted, we | ||
341 | 1032 | # allow deleting the source publication. | ||
342 | 1033 | spph.requestDeletion(self.person) | ||
343 | 1034 | |||
344 | 1035 | def test_requestDeletion_bulk_disallows_active_built_using_refs(self): | ||
345 | 1036 | # The bulk version of requestDeletion checks that there are no | ||
346 | 1037 | # active Built-Using references to the source packages being | ||
347 | 1038 | # deleted. | ||
348 | 1039 | archive = self.factory.makeArchive(purpose=ArchivePurpose.PRIMARY) | ||
349 | 1040 | distroseries = self.factory.makeDistroSeries( | ||
350 | 1041 | distribution=archive.distribution) | ||
351 | 1042 | das = self.factory.makeDistroArchSeries(distroseries=distroseries) | ||
352 | 1043 | bpphs = [ | ||
353 | 1044 | self.factory.makeBinaryPackagePublishingHistory( | ||
354 | 1045 | archive=archive, distroarchseries=das, pocket=pocket, | ||
355 | 1046 | status=PackagePublishingStatus.PUBLISHED) | ||
356 | 1047 | for pocket in ( | ||
357 | 1048 | PackagePublishingPocket.RELEASE, | ||
358 | 1049 | PackagePublishingPocket.PROPOSED)] | ||
359 | 1050 | spphs = [ | ||
360 | 1051 | self.factory.makeSourcePackagePublishingHistory( | ||
361 | 1052 | archive=archive, distroseries=distroseries, | ||
362 | 1053 | pocket=PackagePublishingPocket.RELEASE, | ||
363 | 1054 | status=PackagePublishingStatus.PUBLISHED) | ||
364 | 1055 | for bpph in bpphs] | ||
365 | 1056 | bsr_set = getUtility(IBinarySourceReferenceSet) | ||
366 | 1057 | for bpph in bpphs: | ||
367 | 1058 | for spph in spphs: | ||
368 | 1059 | spr = spph.sourcepackagerelease | ||
369 | 1060 | bsr_set.createFromSourcePackageReleases( | ||
370 | 1061 | bpph.binarypackagerelease, [spr], | ||
371 | 1062 | BinarySourceReferenceType.BUILT_USING) | ||
372 | 1063 | |||
373 | 1064 | # As long as the referring binary publications are active, deletion | ||
374 | 1065 | # is disallowed. | ||
375 | 1066 | message = ( | ||
376 | 1067 | "Cannot delete source publication with a Built-Using reference " | ||
377 | 1068 | "from an active binary publication.") | ||
378 | 1069 | self.assertRaisesWithContent( | ||
379 | 1070 | DeletionError, message, | ||
380 | 1071 | getUtility(IPublishingSet).requestDeletion, spphs, self.person) | ||
381 | 1072 | bpphs[0].requestDeletion(self.person) | ||
382 | 1073 | self.assertRaisesWithContent( | ||
383 | 1074 | DeletionError, message, | ||
384 | 1075 | getUtility(IPublishingSet).requestDeletion, spphs, self.person) | ||
385 | 1076 | bpphs[1].requestDeletion(self.person) | ||
386 | 1077 | |||
387 | 1078 | # Now that all the referring binary publications are deleted, we | ||
388 | 1079 | # allow deleting the source publications. | ||
389 | 1080 | getUtility(IPublishingSet).requestDeletion(spphs, self.person) | ||
390 | 1081 | |||
391 | 987 | def test_requestDeletion_marks_debug_as_deleted(self): | 1082 | def test_requestDeletion_marks_debug_as_deleted(self): |
392 | 988 | matching_bpph, debug_matching_bpph = ( | 1083 | matching_bpph, debug_matching_bpph = ( |
393 | 989 | self.factory.makeBinaryPackagePublishingHistory( | 1084 | self.factory.makeBinaryPackagePublishingHistory( |