13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
1 |
# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
|
8687.15.12
by Karl Fogel
Add the copyright header block to files under lib/lp/archivepublisher/ |
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
3 |
||
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
4 |
"""Tests for domination.py."""
|
3673.6.16
by Malcolm Cleaton
Addressed review comments |
5 |
|
6 |
__metaclass__ = type |
|
7 |
||
13850.2.13
by Jeroen Vermeulen
Reformat imports. |
8 |
import datetime |
13850.2.25
by Jeroen Vermeulen
Test for desired behaviour, and add massive compound test as a catchall for complex bugs. |
9 |
from operator import attrgetter |
14017.2.2
by Jeroen Vermeulen
Satisfy findPublishedSourcePackageNames tests; remove one that is now redundant (also failed because updated badly). |
10 |
|
11 |
import apt_pkg |
|
14017.3.5
by Jeroen Vermeulen
As per review: add query-count test. |
12 |
from testtools.matchers import LessThan |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
13 |
from zope.security.proxy import removeSecurityProxy |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
14 |
|
15 |
from lp.archivepublisher.domination import ( |
|
14220.2.9
by Jeroen Vermeulen
Create arch-specific-publications cache for 2nd-pass binary domination. |
16 |
ArchSpecificPublicationsCache, |
14220.2.6
by Jeroen Vermeulen
Limit 2nd binary-domination pass to packages with arch-indep publications. |
17 |
contains_arch_indep, |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
18 |
Dominator, |
14220.2.4
by Jeroen Vermeulen
Still working on tests. Shorter names for first-pass and second-pass liveness functions. |
19 |
find_live_binary_versions_pass_1, |
20 |
find_live_binary_versions_pass_2, |
|
14220.2.2
by Jeroen Vermeulen
Initial tests of liveness functions; not passing yet. |
21 |
find_live_source_versions, |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
22 |
GeneralizedPublication, |
23 |
STAY_OF_EXECUTION, |
|
24 |
)
|
|
8426.7.1
by Julian Edwards
migrate archivepublisher to the lp tree. |
25 |
from lp.archivepublisher.publishing import Publisher |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
26 |
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. |
27 |
from lp.registry.interfaces.series import SeriesStatus |
14606.3.1
by William Grant
Merge canonical.database into lp.services.database. |
28 |
from lp.services.database.sqlbase import flush_database_updates |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
29 |
from lp.services.log.logger import DevNullLogger |
14198.1.1
by Jeroen Vermeulen
Lint. |
30 |
from lp.soyuz.enums import PackagePublishingStatus |
13850.2.10
by Jeroen Vermeulen
Paving the way for gina source domination. |
31 |
from lp.soyuz.interfaces.publishing import ISourcePackagePublishingHistory |
8294.6.1
by Julian Edwards
First stab at code-reorg. Still got a discrepancy on stuff I assigned to registry but not migrated yet. |
32 |
from lp.soyuz.tests.test_publishing import TestNativePublishingBase |
14017.3.5
by Jeroen Vermeulen
As per review: add query-count test. |
33 |
from lp.testing import ( |
34 |
StormStatementRecorder, |
|
35 |
TestCaseWithFactory, |
|
36 |
)
|
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
37 |
from lp.testing.fakemethod import FakeMethod |
14606.3.1
by William Grant
Merge canonical.database into lp.services.database. |
38 |
from lp.testing.layers import ZopelessDatabaseLayer |
14017.3.5
by Jeroen Vermeulen
As per review: add query-count test. |
39 |
from lp.testing.matchers import HasQueryCount |
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
40 |
|
41 |
||
42 |
class TestDominator(TestNativePublishingBase): |
|
43 |
"""Test Dominator class."""
|
|
44 |
||
7675.757.3
by William Grant
Dominator now excludes DDEBs from the candidate query, and a test has been added to verify that judgeAndDominate works over an archive with both DEBs and DDEBs. |
45 |
def createSourceAndBinaries(self, version, with_debug=False, |
46 |
archive=None): |
|
11116.4.9
by William Grant
Add judgeAndDominate test. |
47 |
"""Create a source and binaries with the given version."""
|
48 |
source = self.getPubSource( |
|
7675.757.3
by William Grant
Dominator now excludes DDEBs from the candidate query, and a test has been added to verify that judgeAndDominate works over an archive with both DEBs and DDEBs. |
49 |
version=version, archive=archive, |
11116.4.9
by William Grant
Add judgeAndDominate test. |
50 |
status=PackagePublishingStatus.PUBLISHED) |
51 |
binaries = self.getPubBinaries( |
|
7675.757.3
by William Grant
Dominator now excludes DDEBs from the candidate query, and a test has been added to verify that judgeAndDominate works over an archive with both DEBs and DDEBs. |
52 |
pub_source=source, with_debug=with_debug, |
11116.4.9
by William Grant
Add judgeAndDominate test. |
53 |
status=PackagePublishingStatus.PUBLISHED) |
54 |
return (source, binaries) |
|
55 |
||
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
56 |
def createSimpleDominationContext(self): |
57 |
"""Create simple domination context.
|
|
58 |
||
59 |
Creates source and binary publications for:
|
|
60 |
||
61 |
* Dominated: foo_1.0 & foo-bin_1.0_i386
|
|
62 |
* Dominant: foo_1.1 & foo-bin_1.1_i386
|
|
63 |
||
7659.7.1
by Julian Edwards
Remove secure publishing records. |
64 |
Return the corresponding publication records as a 4-tuple:
|
5293.2.6
by Celso Providelo
more comments, r=sinzui. |
65 |
|
66 |
(dominant_source, dominant_binary, dominated_source,
|
|
67 |
dominated_binary)
|
|
68 |
||
69 |
Note that as an optimization the binaries list is already unpacked.
|
|
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
70 |
"""
|
11116.4.9
by William Grant
Add judgeAndDominate test. |
71 |
foo_10_source, foo_10_binaries = self.createSourceAndBinaries('1.0') |
72 |
foo_11_source, foo_11_binaries = self.createSourceAndBinaries('1.1') |
|
11116.4.10
by William Grant
Merge checkBinaryPublication and checkSourcePublication; we no longer need to have the refreshing functionality, since S[SB]PPH are dead. |
73 |
return (foo_11_source, foo_11_binaries[0], |
74 |
foo_10_source, foo_10_binaries[0]) |
|
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
75 |
|
11116.4.12
by William Grant
Remove duplicated test code. |
76 |
def dominateAndCheck(self, dominant, dominated, supersededby): |
13850.2.10
by Jeroen Vermeulen
Paving the way for gina source domination. |
77 |
generalization = GeneralizedPublication( |
78 |
is_source=ISourcePackagePublishingHistory.providedBy(dominant)) |
|
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
79 |
dominator = Dominator(self.logger, self.ubuntutest.main_archive) |
80 |
||
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
81 |
pubs = [dominant, dominated] |
82 |
live_versions = [generalization.getPackageVersion(dominant)] |
|
83 |
dominator.dominatePackage(pubs, live_versions, generalization) |
|
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
84 |
flush_database_updates() |
85 |
||
5293.2.6
by Celso Providelo
more comments, r=sinzui. |
86 |
# The dominant version remains correctly published.
|
11116.4.12
by William Grant
Remove duplicated test code. |
87 |
self.checkPublication(dominant, PackagePublishingStatus.PUBLISHED) |
88 |
self.assertTrue(dominant.supersededby is None) |
|
89 |
self.assertTrue(dominant.datesuperseded is None) |
|
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
90 |
|
5293.2.6
by Celso Providelo
more comments, r=sinzui. |
91 |
# The dominated version is correctly dominated.
|
11116.4.12
by William Grant
Remove duplicated test code. |
92 |
self.checkPublication(dominated, PackagePublishingStatus.SUPERSEDED) |
93 |
self.assertEqual(dominated.supersededby, supersededby) |
|
94 |
self.checkPastDate(dominated.datesuperseded) |
|
95 |
||
96 |
def testManualSourceDomination(self): |
|
97 |
"""Test source domination procedure."""
|
|
98 |
[dominant_source, dominant_binary, dominated_source, |
|
99 |
dominated_binary] = self.createSimpleDominationContext() |
|
100 |
||
101 |
self.dominateAndCheck( |
|
102 |
dominant_source, dominated_source, |
|
11116.4.10
by William Grant
Merge checkBinaryPublication and checkSourcePublication; we no longer need to have the refreshing functionality, since S[SB]PPH are dead. |
103 |
dominant_source.sourcepackagerelease) |
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
104 |
|
11116.4.9
by William Grant
Add judgeAndDominate test. |
105 |
def testManualBinaryDomination(self): |
106 |
"""Test binary domination procedure."""
|
|
5293.2.6
by Celso Providelo
more comments, r=sinzui. |
107 |
[dominant_source, dominant, dominated_source, |
108 |
dominated] = self.createSimpleDominationContext() |
|
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
109 |
|
11116.4.12
by William Grant
Remove duplicated test code. |
110 |
self.dominateAndCheck( |
111 |
dominant, dominated, dominant.binarypackagerelease.build) |
|
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
112 |
|
11116.4.9
by William Grant
Add judgeAndDominate test. |
113 |
def testJudgeAndDominate(self): |
114 |
"""Verify that judgeAndDominate correctly dominates everything."""
|
|
115 |
foo_10_source, foo_10_binaries = self.createSourceAndBinaries('1.0') |
|
116 |
foo_11_source, foo_11_binaries = self.createSourceAndBinaries('1.1') |
|
117 |
foo_12_source, foo_12_binaries = self.createSourceAndBinaries('1.2') |
|
118 |
||
119 |
dominator = Dominator(self.logger, foo_10_source.archive) |
|
120 |
dominator.judgeAndDominate( |
|
7675.996.6
by William Grant
Remove stayofexecution from lucilleconfig. I invoke YAGNI and hardcode it to 5 days. |
121 |
foo_10_source.distroseries, foo_10_source.pocket) |
11116.4.9
by William Grant
Add judgeAndDominate test. |
122 |
|
123 |
self.checkPublications( |
|
11116.4.13
by William Grant
Fix lint. |
124 |
[foo_12_source] + foo_12_binaries, |
125 |
PackagePublishingStatus.PUBLISHED) |
|
126 |
self.checkPublications( |
|
127 |
[foo_11_source] + foo_11_binaries, |
|
128 |
PackagePublishingStatus.SUPERSEDED) |
|
129 |
self.checkPublications( |
|
130 |
[foo_10_source] + foo_10_binaries, |
|
131 |
PackagePublishingStatus.SUPERSEDED) |
|
11116.4.9
by William Grant
Add judgeAndDominate test. |
132 |
|
7675.757.3
by William Grant
Dominator now excludes DDEBs from the candidate query, and a test has been added to verify that judgeAndDominate works over an archive with both DEBs and DDEBs. |
133 |
def testJudgeAndDominateWithDDEBs(self): |
134 |
"""Verify that judgeAndDominate ignores DDEBs correctly.
|
|
135 |
||
136 |
DDEBs are superseded by their corresponding DEB publications, so they
|
|
137 |
are forbidden from superseding publications (an attempt would result
|
|
138 |
in an AssertionError), and shouldn't be directly considered for
|
|
139 |
superseding either.
|
|
140 |
"""
|
|
7675.1039.9
by William Grant
Revert test DB user changes. We should grant those users the relevant permission instead. |
141 |
ppa = self.factory.makeArchive() |
7675.757.3
by William Grant
Dominator now excludes DDEBs from the candidate query, and a test has been added to verify that judgeAndDominate works over an archive with both DEBs and DDEBs. |
142 |
foo_10_source, foo_10_binaries = self.createSourceAndBinaries( |
143 |
'1.0', with_debug=True, archive=ppa) |
|
144 |
foo_11_source, foo_11_binaries = self.createSourceAndBinaries( |
|
145 |
'1.1', with_debug=True, archive=ppa) |
|
146 |
foo_12_source, foo_12_binaries = self.createSourceAndBinaries( |
|
147 |
'1.2', with_debug=True, archive=ppa) |
|
148 |
||
149 |
dominator = Dominator(self.logger, ppa) |
|
150 |
dominator.judgeAndDominate( |
|
7675.996.6
by William Grant
Remove stayofexecution from lucilleconfig. I invoke YAGNI and hardcode it to 5 days. |
151 |
foo_10_source.distroseries, foo_10_source.pocket) |
7675.757.3
by William Grant
Dominator now excludes DDEBs from the candidate query, and a test has been added to verify that judgeAndDominate works over an archive with both DEBs and DDEBs. |
152 |
|
153 |
self.checkPublications( |
|
154 |
[foo_12_source] + foo_12_binaries, |
|
155 |
PackagePublishingStatus.PUBLISHED) |
|
156 |
self.checkPublications( |
|
157 |
[foo_11_source] + foo_11_binaries, |
|
158 |
PackagePublishingStatus.SUPERSEDED) |
|
159 |
self.checkPublications( |
|
160 |
[foo_10_source] + foo_10_binaries, |
|
161 |
PackagePublishingStatus.SUPERSEDED) |
|
162 |
||
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
163 |
def test_dominateBinaries_rejects_empty_publication_list(self): |
164 |
"""Domination asserts for non-empty input list."""
|
|
165 |
package = self.factory.makeBinaryPackageName() |
|
166 |
dominator = Dominator(self.logger, self.ubuntutest.main_archive) |
|
14220.2.3
by Jeroen Vermeulen
Most liveness-function tests pass. |
167 |
dominator._sortPackages = FakeMethod({package.name: []}) |
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
168 |
# This isn't a really good exception. It should probably be
|
169 |
# something more indicative of bad input.
|
|
170 |
self.assertRaises( |
|
171 |
AssertionError, |
|
172 |
dominator.dominateBinaries, |
|
173 |
self.factory.makeDistroArchSeries().distroseries, |
|
174 |
self.factory.getAnyPocket()) |
|
175 |
||
176 |
def test_dominateSources_rejects_empty_publication_list(self): |
|
177 |
"""Domination asserts for non-empty input list."""
|
|
178 |
package = self.factory.makeSourcePackageName() |
|
179 |
dominator = Dominator(self.logger, self.ubuntutest.main_archive) |
|
14220.2.3
by Jeroen Vermeulen
Most liveness-function tests pass. |
180 |
dominator._sortPackages = FakeMethod({package.name: []}) |
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
181 |
# This isn't a really good exception. It should probably be
|
182 |
# something more indicative of bad input.
|
|
183 |
self.assertRaises( |
|
184 |
AssertionError, |
|
185 |
dominator.dominateSources, |
|
186 |
self.factory.makeDistroSeries(), self.factory.getAnyPocket()) |
|
11116.4.8
by William Grant
Reorder tests more sanely. |
187 |
|
14090.3.21
by Julian Edwards
re-apply reverted qa-bad changes |
188 |
def test_archall_domination(self): |
189 |
# Arch-all binaries should not be dominated when a new source
|
|
190 |
# version builds an updated arch-all binary, because slower builds
|
|
191 |
# of other architectures will leave the previous version
|
|
192 |
# uninstallable if they depend on the arch-all binary.
|
|
193 |
# See https://bugs.launchpad.net/launchpad/+bug/34086
|
|
194 |
||
195 |
# Set up a source, "foo" which builds "foo-bin" and foo-common
|
|
196 |
# (which is arch-all).
|
|
197 |
foo_10_src = self.getPubSource( |
|
198 |
sourcename="foo", version="1.0", architecturehintlist="i386", |
|
199 |
status=PackagePublishingStatus.PUBLISHED) |
|
200 |
[foo_10_i386_bin] = self.getPubBinaries( |
|
201 |
binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED, |
|
202 |
architecturespecific=True, version="1.0", pub_source=foo_10_src) |
|
203 |
[build] = foo_10_src.getBuilds() |
|
204 |
bpr = self.factory.makeBinaryPackageRelease( |
|
205 |
binarypackagename="foo-common", version="1.0", build=build, |
|
206 |
architecturespecific=False) |
|
207 |
foo_10_all_bins = self.publishBinaryInArchive( |
|
208 |
bpr, self.ubuntutest.main_archive, pocket=foo_10_src.pocket, |
|
209 |
status=PackagePublishingStatus.PUBLISHED) |
|
210 |
||
211 |
# Now, make version 1.1 of foo and add a foo-common but not foo-bin
|
|
212 |
# (imagine that it's not finished building yet).
|
|
213 |
foo_11_src = self.getPubSource( |
|
214 |
sourcename="foo", version="1.1", architecturehintlist="all", |
|
215 |
status=PackagePublishingStatus.PUBLISHED) |
|
14198.1.1
by Jeroen Vermeulen
Lint. |
216 |
# Generate binary publications for architecture "all" (actually,
|
217 |
# one such publication per architecture).
|
|
218 |
self.getPubBinaries( |
|
14090.3.21
by Julian Edwards
re-apply reverted qa-bad changes |
219 |
binaryname="foo-common", status=PackagePublishingStatus.PUBLISHED, |
220 |
architecturespecific=False, version="1.1", pub_source=foo_11_src) |
|
221 |
||
222 |
dominator = Dominator(self.logger, self.ubuntutest.main_archive) |
|
223 |
dominator.judgeAndDominate( |
|
224 |
foo_10_src.distroseries, foo_10_src.pocket) |
|
225 |
||
226 |
# The source will be superseded.
|
|
227 |
self.checkPublication(foo_10_src, PackagePublishingStatus.SUPERSEDED) |
|
228 |
# The arch-specific has no dominant, so it's still published
|
|
229 |
self.checkPublication( |
|
230 |
foo_10_i386_bin, PackagePublishingStatus.PUBLISHED) |
|
231 |
# The arch-indep has a dominant but must not be superseded yet
|
|
232 |
# since the arch-specific is still published.
|
|
233 |
self.checkPublications( |
|
234 |
foo_10_all_bins, PackagePublishingStatus.PUBLISHED) |
|
235 |
||
236 |
# Now creating a newer foo-bin should see those last two
|
|
237 |
# publications superseded.
|
|
238 |
[build2] = foo_11_src.getBuilds() |
|
239 |
foo_11_bin = self.factory.makeBinaryPackageRelease( |
|
240 |
binarypackagename="foo-bin", version="1.1", build=build2, |
|
241 |
architecturespecific=True) |
|
242 |
self.publishBinaryInArchive( |
|
243 |
foo_11_bin, self.ubuntutest.main_archive, |
|
244 |
pocket=foo_10_src.pocket, |
|
245 |
status=PackagePublishingStatus.PUBLISHED) |
|
246 |
dominator.judgeAndDominate( |
|
247 |
foo_10_src.distroseries, foo_10_src.pocket) |
|
248 |
self.checkPublication( |
|
249 |
foo_10_i386_bin, PackagePublishingStatus.SUPERSEDED) |
|
250 |
self.checkPublications( |
|
251 |
foo_10_all_bins, PackagePublishingStatus.SUPERSEDED) |
|
252 |
||
14090.3.22
by Julian Edwards
Add failing tests for new corner cases. |
253 |
def test_any_superseded_by_all(self): |
254 |
# Set up a source, foo, which builds an architecture-dependent
|
|
255 |
# binary, foo-bin.
|
|
256 |
foo_10_src = self.getPubSource( |
|
257 |
sourcename="foo", version="1.0", architecturehintlist="i386", |
|
258 |
status=PackagePublishingStatus.PUBLISHED) |
|
259 |
[foo_10_i386_bin] = self.getPubBinaries( |
|
260 |
binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED, |
|
261 |
architecturespecific=True, version="1.0", pub_source=foo_10_src) |
|
262 |
||
263 |
# Now, make version 1.1 of foo, where foo-bin is now
|
|
264 |
# architecture-independent.
|
|
265 |
foo_11_src = self.getPubSource( |
|
266 |
sourcename="foo", version="1.1", architecturehintlist="all", |
|
267 |
status=PackagePublishingStatus.PUBLISHED) |
|
268 |
[foo_10_all_bin, foo_10_all_bin_2] = self.getPubBinaries( |
|
269 |
binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED, |
|
270 |
architecturespecific=False, version="1.1", pub_source=foo_11_src) |
|
271 |
||
272 |
dominator = Dominator(self.logger, self.ubuntutest.main_archive) |
|
273 |
dominator.judgeAndDominate( |
|
274 |
foo_10_src.distroseries, foo_10_src.pocket) |
|
275 |
||
276 |
# The source will be superseded.
|
|
277 |
self.checkPublication(foo_10_src, PackagePublishingStatus.SUPERSEDED) |
|
278 |
# The arch-specific is superseded by the new arch-indep.
|
|
279 |
self.checkPublication( |
|
280 |
foo_10_i386_bin, PackagePublishingStatus.SUPERSEDED) |
|
281 |
||
282 |
def test_schitzoid_package(self): |
|
283 |
# Test domination of a source that produces an arch-indep and an
|
|
284 |
# arch-all, that then switches both on the next version to the
|
|
285 |
# other arch type.
|
|
286 |
foo_10_src = self.getPubSource( |
|
287 |
sourcename="foo", version="1.0", architecturehintlist="i386", |
|
288 |
status=PackagePublishingStatus.PUBLISHED) |
|
289 |
[foo_10_i386_bin] = self.getPubBinaries( |
|
290 |
binaryname="foo-bin", status=PackagePublishingStatus.PUBLISHED, |
|
291 |
architecturespecific=True, version="1.0", pub_source=foo_10_src) |
|
292 |
[build] = foo_10_src.getBuilds() |
|
293 |
bpr = self.factory.makeBinaryPackageRelease( |
|
294 |
binarypackagename="foo-common", version="1.0", build=build, |
|
295 |
architecturespecific=False) |
|
296 |
foo_10_all_bins = self.publishBinaryInArchive( |
|
297 |
bpr, self.ubuntutest.main_archive, pocket=foo_10_src.pocket, |
|
298 |
status=PackagePublishingStatus.PUBLISHED) |
|
299 |
||
300 |
foo_11_src = self.getPubSource( |
|
301 |
sourcename="foo", version="1.1", architecturehintlist="i386", |
|
302 |
status=PackagePublishingStatus.PUBLISHED) |
|
303 |
[foo_11_i386_bin] = self.getPubBinaries( |
|
304 |
binaryname="foo-common", status=PackagePublishingStatus.PUBLISHED, |
|
305 |
architecturespecific=True, version="1.1", pub_source=foo_11_src) |
|
306 |
[build] = foo_11_src.getBuilds() |
|
307 |
bpr = self.factory.makeBinaryPackageRelease( |
|
308 |
binarypackagename="foo-bin", version="1.1", build=build, |
|
309 |
architecturespecific=False) |
|
14198.1.1
by Jeroen Vermeulen
Lint. |
310 |
# Generate binary publications for architecture "all" (actually,
|
311 |
# one such publication per architecture).
|
|
312 |
self.publishBinaryInArchive( |
|
14090.3.22
by Julian Edwards
Add failing tests for new corner cases. |
313 |
bpr, self.ubuntutest.main_archive, pocket=foo_11_src.pocket, |
314 |
status=PackagePublishingStatus.PUBLISHED) |
|
315 |
||
316 |
dominator = Dominator(self.logger, self.ubuntutest.main_archive) |
|
317 |
dominator.judgeAndDominate(foo_10_src.distroseries, foo_10_src.pocket) |
|
318 |
||
319 |
self.checkPublications(foo_10_all_bins + [foo_10_i386_bin], |
|
320 |
PackagePublishingStatus.SUPERSEDED) |
|
321 |
||
322 |
||
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
323 |
class TestDomination(TestNativePublishingBase): |
324 |
"""Test overall domination procedure."""
|
|
325 |
||
326 |
def testCarefulDomination(self): |
|
327 |
"""Test the careful domination procedure.
|
|
328 |
||
329 |
Check if it works on a development series.
|
|
330 |
A SUPERSEDED, DELETED or OBSOLETE published source should
|
|
331 |
have its scheduleddeletiondate set.
|
|
332 |
"""
|
|
333 |
publisher = Publisher( |
|
334 |
self.logger, self.config, self.disk_pool, |
|
335 |
self.ubuntutest.main_archive) |
|
336 |
||
337 |
superseded_source = self.getPubSource( |
|
338 |
status=PackagePublishingStatus.SUPERSEDED) |
|
339 |
self.assertTrue(superseded_source.scheduleddeletiondate is None) |
|
340 |
deleted_source = self.getPubSource( |
|
341 |
status=PackagePublishingStatus.DELETED) |
|
342 |
self.assertTrue(deleted_source.scheduleddeletiondate is None) |
|
343 |
obsoleted_source = self.getPubSource( |
|
344 |
status=PackagePublishingStatus.OBSOLETE) |
|
345 |
self.assertTrue(obsoleted_source.scheduleddeletiondate is None) |
|
346 |
||
347 |
publisher.B_dominate(True) |
|
348 |
||
349 |
# The publishing records will be scheduled for removal.
|
|
350 |
# DELETED and OBSOLETED publications are set to be deleted
|
|
351 |
# immediately, whereas SUPERSEDED ones get a stay of execution
|
|
352 |
# according to the configuration.
|
|
11116.4.10
by William Grant
Merge checkBinaryPublication and checkSourcePublication; we no longer need to have the refreshing functionality, since S[SB]PPH are dead. |
353 |
self.checkPublication( |
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
354 |
deleted_source, PackagePublishingStatus.DELETED) |
355 |
self.checkPastDate(deleted_source.scheduleddeletiondate) |
|
356 |
||
11116.4.10
by William Grant
Merge checkBinaryPublication and checkSourcePublication; we no longer need to have the refreshing functionality, since S[SB]PPH are dead. |
357 |
self.checkPublication( |
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
358 |
obsoleted_source, PackagePublishingStatus.OBSOLETE) |
359 |
self.checkPastDate(deleted_source.scheduleddeletiondate) |
|
360 |
||
11116.4.10
by William Grant
Merge checkBinaryPublication and checkSourcePublication; we no longer need to have the refreshing functionality, since S[SB]PPH are dead. |
361 |
self.checkPublication( |
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
362 |
superseded_source, PackagePublishingStatus.SUPERSEDED) |
363 |
self.checkPastDate( |
|
364 |
superseded_source.scheduleddeletiondate, |
|
7675.995.1
by William Grant
Hardcode stay of execution to one day. No more lucilleconfig here. |
365 |
lag=datetime.timedelta(days=STAY_OF_EXECUTION)) |
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
366 |
|
11149.5.1
by Jeroen Vermeulen
Test cruft in archivepublisher. |
367 |
|
5293.2.5
by Celso Providelo
applying review comments, r=sinzui. |
368 |
class TestDominationOfObsoletedSeries(TestDomination): |
369 |
"""Replay domination tests upon a OBSOLETED distroseries."""
|
|
370 |
||
371 |
def setUp(self): |
|
372 |
TestDomination.setUp(self) |
|
373 |
self.ubuntutest['breezy-autotest'].status = ( |
|
10054.26.1
by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series. |
374 |
SeriesStatus.OBSOLETE) |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
375 |
|
376 |
||
14220.2.4
by Jeroen Vermeulen
Still working on tests. Shorter names for first-pass and second-pass liveness functions. |
377 |
def remove_security_proxies(proxied_objects): |
378 |
"""Return list of `proxied_objects`, without their proxies.
|
|
379 |
||
380 |
The dominator runs only in scripts, where security proxies don't get
|
|
381 |
in the way. To test realistically for this environment, strip the
|
|
382 |
proxies wherever necessary and do as you will.
|
|
383 |
"""
|
|
384 |
return [removeSecurityProxy(obj) for obj in proxied_objects] |
|
385 |
||
386 |
||
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
387 |
def make_spphs_for_versions(factory, versions): |
388 |
"""Create publication records for each of `versions`.
|
|
389 |
||
14220.1.5
by Jeroen Vermeulen
Extract finding of publications for domination. |
390 |
All these publications will be in the same source package, archive,
|
391 |
distroseries, and pocket. They will all be in Published status.
|
|
392 |
||
393 |
The records are created in the same order in which they are specified.
|
|
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
394 |
Make the order irregular to prove that version ordering is not a
|
395 |
coincidence of object creation order etc.
|
|
396 |
||
397 |
Versions may also be identical; each publication record will still have
|
|
398 |
its own package release.
|
|
399 |
"""
|
|
400 |
spn = factory.makeSourcePackageName() |
|
401 |
distroseries = factory.makeDistroSeries() |
|
402 |
pocket = factory.getAnyPocket() |
|
14220.1.5
by Jeroen Vermeulen
Extract finding of publications for domination. |
403 |
archive = distroseries.main_archive |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
404 |
sprs = [ |
405 |
factory.makeSourcePackageRelease( |
|
406 |
sourcepackagename=spn, version=version) |
|
407 |
for version in versions] |
|
408 |
return [ |
|
409 |
factory.makeSourcePackagePublishingHistory( |
|
410 |
distroseries=distroseries, pocket=pocket, |
|
14220.1.5
by Jeroen Vermeulen
Extract finding of publications for domination. |
411 |
sourcepackagerelease=spr, archive=archive, |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
412 |
status=PackagePublishingStatus.PUBLISHED) |
413 |
for spr in sprs] |
|
414 |
||
415 |
||
14220.1.5
by Jeroen Vermeulen
Extract finding of publications for domination. |
416 |
def make_bpphs_for_versions(factory, versions): |
417 |
"""Create publication records for each of `versions`.
|
|
418 |
||
419 |
All these publications will be in the same binary package, source
|
|
420 |
package, archive, distroarchseries, and pocket. They will all be in
|
|
421 |
Published status.
|
|
422 |
"""
|
|
423 |
bpn = factory.makeBinaryPackageName() |
|
424 |
spn = factory.makeSourcePackageName() |
|
425 |
das = factory.makeDistroArchSeries() |
|
426 |
archive = das.distroseries.main_archive |
|
427 |
pocket = factory.getAnyPocket() |
|
428 |
bprs = [ |
|
14220.2.3
by Jeroen Vermeulen
Most liveness-function tests pass. |
429 |
factory.makeBinaryPackageRelease( |
430 |
binarypackagename=bpn, version=version) |
|
14220.1.5
by Jeroen Vermeulen
Extract finding of publications for domination. |
431 |
for version in versions] |
14220.2.4
by Jeroen Vermeulen
Still working on tests. Shorter names for first-pass and second-pass liveness functions. |
432 |
return remove_security_proxies([ |
14220.1.5
by Jeroen Vermeulen
Extract finding of publications for domination. |
433 |
factory.makeBinaryPackagePublishingHistory( |
434 |
binarypackagerelease=bpr, binarypackagename=bpn, |
|
435 |
distroarchseries=das, pocket=pocket, archive=archive, |
|
436 |
sourcepackagename=spn, status=PackagePublishingStatus.PUBLISHED) |
|
14220.2.4
by Jeroen Vermeulen
Still working on tests. Shorter names for first-pass and second-pass liveness functions. |
437 |
for bpr in bprs]) |
14220.1.5
by Jeroen Vermeulen
Extract finding of publications for domination. |
438 |
|
439 |
||
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
440 |
def list_source_versions(spphs): |
441 |
"""Extract the versions from `spphs` as a list, in the same order."""
|
|
442 |
return [spph.sourcepackagerelease.version for spph in spphs] |
|
443 |
||
444 |
||
13850.2.24
by Jeroen Vermeulen
A newer publication record for a live package versions supersedes older ones for the same versions. |
445 |
def alter_creation_dates(spphs, ages): |
446 |
"""Set `datecreated` on each of `spphs` according to `ages`.
|
|
447 |
||
448 |
:param spphs: Iterable of `SourcePackagePublishingHistory`. Their
|
|
449 |
respective creation dates will be offset by the respective ages found
|
|
450 |
in `ages` (with the two being matched up in the same order).
|
|
451 |
:param ages: Iterable of ages. Must provide the same number of items as
|
|
452 |
`spphs`. Ages are `timedelta` objects that will be subtracted from
|
|
453 |
the creation dates on the respective records in `spph`.
|
|
454 |
"""
|
|
455 |
for spph, age in zip(spphs, ages): |
|
456 |
spph.datecreated -= age |
|
457 |
||
458 |
||
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
459 |
class TestGeneralizedPublication(TestCaseWithFactory): |
460 |
"""Test publication generalization helpers."""
|
|
461 |
||
462 |
layer = ZopelessDatabaseLayer |
|
463 |
||
464 |
def test_getPackageVersion_gets_source_version(self): |
|
465 |
spph = self.factory.makeSourcePackagePublishingHistory() |
|
466 |
self.assertEqual( |
|
467 |
spph.sourcepackagerelease.version, |
|
468 |
GeneralizedPublication(is_source=True).getPackageVersion(spph)) |
|
469 |
||
470 |
def test_getPackageVersion_gets_binary_version(self): |
|
471 |
bpph = self.factory.makeBinaryPackagePublishingHistory() |
|
472 |
self.assertEqual( |
|
473 |
bpph.binarypackagerelease.version, |
|
474 |
GeneralizedPublication(is_source=False).getPackageVersion(bpph)) |
|
475 |
||
476 |
def test_compare_sorts_versions(self): |
|
477 |
versions = [ |
|
478 |
'1.1v2', |
|
479 |
'1.1v1', |
|
480 |
'1.1v3', |
|
481 |
]
|
|
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
482 |
spphs = make_spphs_for_versions(self.factory, versions) |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
483 |
sorted_spphs = sorted(spphs, cmp=GeneralizedPublication().compare) |
484 |
self.assertEqual( |
|
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
485 |
sorted(versions), list_source_versions(sorted_spphs)) |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
486 |
|
487 |
def test_compare_orders_versions_by_debian_rules(self): |
|
488 |
versions = [ |
|
489 |
'1.1.0', |
|
490 |
'1.10', |
|
491 |
'1.1', |
|
492 |
'1.1ubuntu0', |
|
493 |
]
|
|
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
494 |
spphs = make_spphs_for_versions(self.factory, versions) |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
495 |
|
14514.3.1
by Colin Watson
Port to new python-apt API. |
496 |
debian_sorted_versions = sorted(versions, cmp=apt_pkg.version_compare) |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
497 |
|
498 |
# Assumption: in this case, Debian version ordering is not the
|
|
499 |
# same as alphabetical version ordering.
|
|
500 |
self.assertNotEqual(sorted(versions), debian_sorted_versions) |
|
501 |
||
502 |
# The compare method produces the Debian ordering.
|
|
503 |
sorted_spphs = sorted(spphs, cmp=GeneralizedPublication().compare) |
|
504 |
self.assertEqual( |
|
14514.3.1
by Colin Watson
Port to new python-apt API. |
505 |
sorted(versions, cmp=apt_pkg.version_compare), |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
506 |
list_source_versions(sorted_spphs)) |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
507 |
|
508 |
def test_compare_breaks_tie_with_creation_date(self): |
|
509 |
# When two publications are tied for comparison because they are
|
|
510 |
# for the same package release, they are ordered by creation
|
|
511 |
# date.
|
|
512 |
distroseries = self.factory.makeDistroSeries() |
|
513 |
pocket = self.factory.getAnyPocket() |
|
514 |
spr = self.factory.makeSourcePackageRelease() |
|
13850.2.5
by Jeroen Vermeulen
Test GeneralizedPublication. |
515 |
ages = [ |
516 |
datetime.timedelta(2), |
|
517 |
datetime.timedelta(1), |
|
518 |
datetime.timedelta(3), |
|
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
519 |
]
|
520 |
spphs = [ |
|
521 |
self.factory.makeSourcePackagePublishingHistory( |
|
522 |
sourcepackagerelease=spr, distroseries=distroseries, |
|
13850.2.5
by Jeroen Vermeulen
Test GeneralizedPublication. |
523 |
pocket=pocket) |
524 |
for counter in xrange(len(ages))] |
|
13850.2.24
by Jeroen Vermeulen
A newer publication record for a live package versions supersedes older ones for the same versions. |
525 |
alter_creation_dates(spphs, ages) |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
526 |
|
527 |
self.assertEqual( |
|
13850.2.5
by Jeroen Vermeulen
Test GeneralizedPublication. |
528 |
[spphs[2], spphs[0], spphs[1]], |
529 |
sorted(spphs, cmp=GeneralizedPublication().compare)) |
|
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
530 |
|
531 |
def test_compare_breaks_tie_for_releases_with_same_version(self): |
|
532 |
# When two publications are tied for comparison because they
|
|
533 |
# belong to releases with the same version string, they are
|
|
534 |
# ordered by creation date.
|
|
535 |
version = "1.%d" % self.factory.getUniqueInteger() |
|
13850.2.5
by Jeroen Vermeulen
Test GeneralizedPublication. |
536 |
ages = [ |
537 |
datetime.timedelta(2), |
|
538 |
datetime.timedelta(1), |
|
539 |
datetime.timedelta(3), |
|
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
540 |
]
|
541 |
distroseries = self.factory.makeDistroSeries() |
|
542 |
pocket = self.factory.getAnyPocket() |
|
543 |
spphs = [ |
|
544 |
self.factory.makeSourcePackagePublishingHistory( |
|
13850.2.5
by Jeroen Vermeulen
Test GeneralizedPublication. |
545 |
distroseries=distroseries, pocket=pocket, |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
546 |
sourcepackagerelease=self.factory.makeSourcePackageRelease( |
547 |
version=version)) |
|
13850.2.5
by Jeroen Vermeulen
Test GeneralizedPublication. |
548 |
for counter in xrange(len(ages))] |
13850.2.24
by Jeroen Vermeulen
A newer publication record for a live package versions supersedes older ones for the same versions. |
549 |
alter_creation_dates(spphs, ages) |
13850.2.4
by Jeroen Vermeulen
Test GeneralizedPublication. |
550 |
|
551 |
self.assertEqual( |
|
13850.2.5
by Jeroen Vermeulen
Test GeneralizedPublication. |
552 |
[spphs[2], spphs[0], spphs[1]], |
553 |
sorted(spphs, cmp=GeneralizedPublication().compare)) |
|
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
554 |
|
555 |
||
13850.2.25
by Jeroen Vermeulen
Test for desired behaviour, and add massive compound test as a catchall for complex bugs. |
556 |
def jumble(ordered_list): |
13850.2.27
by Jeroen Vermeulen
Typo. |
557 |
"""Jumble the elements of `ordered_list` into a weird order.
|
13850.2.25
by Jeroen Vermeulen
Test for desired behaviour, and add massive compound test as a catchall for complex bugs. |
558 |
|
559 |
Ordering is very important in domination. We jumble some of our lists to
|
|
560 |
insure against "lucky coincidences" that might give our tests the right
|
|
561 |
answers for the wrong reasons.
|
|
562 |
"""
|
|
563 |
even = [ |
|
564 |
item for offset, item in enumerate(ordered_list) if offset % 2 == 0] |
|
565 |
odd = [ |
|
566 |
item for offset, item in enumerate(ordered_list) if offset % 2 != 0] |
|
567 |
return list(reversed(odd)) + even |
|
568 |
||
569 |
||
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
570 |
class TestDominatorMethods(TestCaseWithFactory): |
571 |
||
572 |
layer = ZopelessDatabaseLayer |
|
573 |
||
574 |
def makeDominator(self, publications): |
|
13850.2.17
by Jeroen Vermeulen
Support for new gina domination loop. |
575 |
"""Create a `Dominator` suitable for `publications`."""
|
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
576 |
if len(publications) == 0: |
577 |
archive = self.factory.makeArchive() |
|
578 |
else: |
|
579 |
archive = publications[0].archive |
|
580 |
return Dominator(DevNullLogger(), archive) |
|
581 |
||
582 |
def test_dominatePackage_survives_empty_publications_list(self): |
|
583 |
# Nothing explodes when dominatePackage is called with an empty
|
|
584 |
# packages list.
|
|
585 |
self.makeDominator([]).dominatePackage( |
|
586 |
[], [], GeneralizedPublication(True)) |
|
587 |
# The test is that we get here without error.
|
|
588 |
pass
|
|
589 |
||
590 |
def test_dominatePackage_leaves_live_version_untouched(self): |
|
591 |
# dominatePackage does not supersede live versions.
|
|
592 |
[pub] = make_spphs_for_versions(self.factory, ['3.1']) |
|
593 |
self.makeDominator([pub]).dominatePackage( |
|
594 |
[pub], ['3.1'], GeneralizedPublication(True)) |
|
595 |
self.assertEqual(PackagePublishingStatus.PUBLISHED, pub.status) |
|
596 |
||
597 |
def test_dominatePackage_deletes_dead_version_without_successor(self): |
|
598 |
# dominatePackage marks non-live package versions without
|
|
599 |
# superseding versions as deleted.
|
|
600 |
[pub] = make_spphs_for_versions(self.factory, ['1.1']) |
|
601 |
self.makeDominator([pub]).dominatePackage( |
|
602 |
[pub], [], GeneralizedPublication(True)) |
|
603 |
self.assertEqual(PackagePublishingStatus.DELETED, pub.status) |
|
604 |
||
605 |
def test_dominatePackage_supersedes_older_pub_with_newer_live_pub(self): |
|
606 |
# When marking a package as superseded, dominatePackage
|
|
607 |
# designates a newer live version as the superseding version.
|
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
608 |
generalization = GeneralizedPublication(True) |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
609 |
pubs = make_spphs_for_versions(self.factory, ['1.0', '1.1']) |
610 |
self.makeDominator(pubs).dominatePackage( |
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
611 |
generalization.sortPublications(pubs), ['1.1'], generalization) |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
612 |
self.assertEqual(PackagePublishingStatus.SUPERSEDED, pubs[0].status) |
613 |
self.assertEqual(pubs[1].sourcepackagerelease, pubs[0].supersededby) |
|
614 |
self.assertEqual(PackagePublishingStatus.PUBLISHED, pubs[1].status) |
|
615 |
||
616 |
def test_dominatePackage_only_supersedes_with_live_pub(self): |
|
617 |
# When marking a package as superseded, dominatePackage will
|
|
618 |
# only pick a live version as the superseding one.
|
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
619 |
generalization = GeneralizedPublication(True) |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
620 |
pubs = make_spphs_for_versions( |
621 |
self.factory, ['1.0', '2.0', '3.0', '4.0']) |
|
622 |
self.makeDominator(pubs).dominatePackage( |
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
623 |
generalization.sortPublications(pubs), ['3.0'], generalization) |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
624 |
self.assertEqual([ |
625 |
pubs[2].sourcepackagerelease, |
|
626 |
pubs[2].sourcepackagerelease, |
|
627 |
None, |
|
628 |
None, |
|
629 |
],
|
|
630 |
[pub.supersededby for pub in pubs]) |
|
631 |
||
632 |
def test_dominatePackage_supersedes_with_oldest_newer_live_pub(self): |
|
633 |
# When marking a package as superseded, dominatePackage picks
|
|
634 |
# the oldest of the newer, live versions as the superseding one.
|
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
635 |
generalization = GeneralizedPublication(True) |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
636 |
pubs = make_spphs_for_versions(self.factory, ['2.7', '2.8', '2.9']) |
637 |
self.makeDominator(pubs).dominatePackage( |
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
638 |
generalization.sortPublications(pubs), ['2.8', '2.9'], |
639 |
generalization) |
|
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
640 |
self.assertEqual(pubs[1].sourcepackagerelease, pubs[0].supersededby) |
641 |
||
642 |
def test_dominatePackage_only_supersedes_with_newer_live_pub(self): |
|
643 |
# When marking a package as superseded, dominatePackage only
|
|
644 |
# considers a newer version as the superseding one.
|
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
645 |
generalization = GeneralizedPublication(True) |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
646 |
pubs = make_spphs_for_versions(self.factory, ['0.1', '0.2']) |
647 |
self.makeDominator(pubs).dominatePackage( |
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
648 |
generalization.sortPublications(pubs), ['0.1'], generalization) |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
649 |
self.assertEqual(None, pubs[1].supersededby) |
650 |
self.assertEqual(PackagePublishingStatus.DELETED, pubs[1].status) |
|
651 |
||
13850.2.24
by Jeroen Vermeulen
A newer publication record for a live package versions supersedes older ones for the same versions. |
652 |
def test_dominatePackage_supersedes_replaced_pub_for_live_version(self): |
653 |
# Even if a publication record is for a live version, a newer
|
|
654 |
# one for the same version supersedes it.
|
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
655 |
generalization = GeneralizedPublication(True) |
13850.2.24
by Jeroen Vermeulen
A newer publication record for a live package versions supersedes older ones for the same versions. |
656 |
spr = self.factory.makeSourcePackageRelease() |
657 |
series = self.factory.makeDistroSeries() |
|
658 |
pocket = PackagePublishingPocket.RELEASE |
|
659 |
pubs = [ |
|
660 |
self.factory.makeSourcePackagePublishingHistory( |
|
661 |
archive=series.main_archive, distroseries=series, |
|
662 |
pocket=pocket, status=PackagePublishingStatus.PUBLISHED, |
|
663 |
sourcepackagerelease=spr) |
|
664 |
for counter in xrange(3)] |
|
665 |
alter_creation_dates(pubs, [ |
|
666 |
datetime.timedelta(3), |
|
667 |
datetime.timedelta(2), |
|
668 |
datetime.timedelta(1), |
|
669 |
])
|
|
670 |
||
671 |
self.makeDominator(pubs).dominatePackage( |
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
672 |
generalization.sortPublications(pubs), [spr.version], |
673 |
generalization) |
|
13850.2.24
by Jeroen Vermeulen
A newer publication record for a live package versions supersedes older ones for the same versions. |
674 |
self.assertEqual([ |
675 |
PackagePublishingStatus.SUPERSEDED, |
|
676 |
PackagePublishingStatus.SUPERSEDED, |
|
677 |
PackagePublishingStatus.PUBLISHED, |
|
678 |
],
|
|
679 |
[pub.status for pub in pubs]) |
|
680 |
self.assertEqual( |
|
681 |
[spr, spr, None], [pub.supersededby for pub in pubs]) |
|
682 |
||
14017.3.5
by Jeroen Vermeulen
As per review: add query-count test. |
683 |
def test_dominatePackage_is_efficient(self): |
684 |
# dominatePackage avoids issuing too many queries.
|
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
685 |
generalization = GeneralizedPublication(True) |
14017.3.5
by Jeroen Vermeulen
As per review: add query-count test. |
686 |
versions = ["1.%s" % revision for revision in xrange(5)] |
687 |
pubs = make_spphs_for_versions(self.factory, versions) |
|
688 |
with StormStatementRecorder() as recorder: |
|
689 |
self.makeDominator(pubs).dominatePackage( |
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
690 |
generalization.sortPublications(pubs), versions[2:-1], |
691 |
generalization) |
|
14017.3.5
by Jeroen Vermeulen
As per review: add query-count test. |
692 |
self.assertThat(recorder, HasQueryCount(LessThan(5))) |
693 |
||
13850.2.25
by Jeroen Vermeulen
Test for desired behaviour, and add massive compound test as a catchall for complex bugs. |
694 |
def test_dominatePackage_advanced_scenario(self): |
695 |
# Put dominatePackage through its paces with complex combined
|
|
696 |
# data.
|
|
697 |
# This test should be redundant in theory (which in theory
|
|
698 |
# equates practice but in practice does not). If this fails,
|
|
699 |
# don't just patch up the code or this test. Create unit tests
|
|
700 |
# that specifically cover the difference, then change the code
|
|
701 |
# and/or adapt this test to return to harmony.
|
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
702 |
generalization = GeneralizedPublication(True) |
13850.2.25
by Jeroen Vermeulen
Test for desired behaviour, and add massive compound test as a catchall for complex bugs. |
703 |
series = self.factory.makeDistroSeries() |
704 |
package = self.factory.makeSourcePackageName() |
|
705 |
pocket = PackagePublishingPocket.RELEASE |
|
706 |
||
707 |
versions = ["1.%d" % number for number in xrange(4)] |
|
708 |
||
709 |
# We have one package releases for each version.
|
|
710 |
relevant_releases = dict( |
|
711 |
(version, self.factory.makeSourcePackageRelease( |
|
712 |
sourcepackagename=package, version=version)) |
|
713 |
for version in jumble(versions)) |
|
714 |
||
715 |
# Each of those releases is subsequently published in
|
|
716 |
# different components.
|
|
717 |
components = jumble( |
|
718 |
[self.factory.makeComponent() for version in versions]) |
|
719 |
||
720 |
# Map versions to lists of publications for that version, from
|
|
721 |
# oldest to newest. Each re-publishing into a different
|
|
722 |
# component is meant to supersede publication into the previous
|
|
723 |
# component.
|
|
724 |
pubs_by_version = dict( |
|
725 |
(version, [ |
|
726 |
self.factory.makeSourcePackagePublishingHistory( |
|
727 |
archive=series.main_archive, distroseries=series, |
|
728 |
pocket=pocket, status=PackagePublishingStatus.PUBLISHED, |
|
729 |
sourcepackagerelease=relevant_releases[version], |
|
730 |
component=component) |
|
731 |
for component in components]) |
|
732 |
for version in jumble(versions)) |
|
733 |
||
734 |
ages = jumble( |
|
735 |
[datetime.timedelta(age) for age in xrange(len(versions))]) |
|
736 |
||
737 |
# Actually the "oldest to newest" order on the publications only
|
|
738 |
# applies to their creation dates. Their creation orders are
|
|
739 |
# irrelevant.
|
|
740 |
for pubs_list in pubs_by_version.itervalues(): |
|
741 |
alter_creation_dates(pubs_list, ages) |
|
742 |
pubs_list.sort(key=attrgetter('datecreated')) |
|
743 |
||
744 |
live_versions = ["1.1", "1.2"] |
|
745 |
last_version_alive = sorted(live_versions)[-1] |
|
746 |
||
747 |
all_pubs = sum(pubs_by_version.itervalues(), []) |
|
748 |
Dominator(DevNullLogger(), series.main_archive).dominatePackage( |
|
14220.2.1
by Jeroen Vermeulen
Move special-casing for publication liveness out of domination loop; specialized and slimmed down binary passes. |
749 |
generalization.sortPublications(all_pubs), live_versions, |
750 |
generalization) |
|
13850.2.25
by Jeroen Vermeulen
Test for desired behaviour, and add massive compound test as a catchall for complex bugs. |
751 |
|
752 |
for version in reversed(versions): |
|
753 |
pubs = pubs_by_version[version] |
|
754 |
||
755 |
if version in live_versions: |
|
756 |
# Beware: loop-carried variable. Used locally as well,
|
|
757 |
# but tells later iterations what the highest-versioned
|
|
758 |
# release so far was. This is used in tracking
|
|
759 |
# supersededby links.
|
|
760 |
superseding_release = pubs[-1].sourcepackagerelease |
|
761 |
||
762 |
if version in live_versions: |
|
763 |
# The live versions' latest publications are Published,
|
|
764 |
# their older ones Superseded.
|
|
765 |
expected_status = ( |
|
766 |
[PackagePublishingStatus.SUPERSEDED] * (len(pubs) - 1) + |
|
767 |
[PackagePublishingStatus.PUBLISHED]) |
|
768 |
expected_supersededby = ( |
|
769 |
[superseding_release] * (len(pubs) - 1) + [None]) |
|
770 |
elif version < last_version_alive: |
|
771 |
# The superseded versions older than the last live
|
|
772 |
# version have all been superseded.
|
|
773 |
expected_status = ( |
|
774 |
[PackagePublishingStatus.SUPERSEDED] * len(pubs)) |
|
775 |
expected_supersededby = [superseding_release] * len(pubs) |
|
776 |
else: |
|
777 |
# Versions that are newer than any live release have
|
|
778 |
# been deleted.
|
|
779 |
expected_status = ( |
|
780 |
[PackagePublishingStatus.DELETED] * len(pubs)) |
|
781 |
expected_supersededby = [None] * len(pubs) |
|
782 |
||
783 |
self.assertEqual(expected_status, [pub.status for pub in pubs]) |
|
784 |
self.assertEqual( |
|
785 |
expected_supersededby, [pub.supersededby for pub in pubs]) |
|
786 |
||
14017.3.2
by Jeroen Vermeulen
Rename dominateRemovedSourceVersions; the name is no longer accurate. |
787 |
def test_dominateSourceVersions_dominates_publications(self): |
788 |
# dominateSourceVersions finds the publications for a package
|
|
789 |
# and calls dominatePackage on them.
|
|
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
790 |
pubs = make_spphs_for_versions(self.factory, ['0.1', '0.2', '0.3']) |
791 |
package_name = pubs[0].sourcepackagerelease.sourcepackagename.name |
|
792 |
||
14017.3.2
by Jeroen Vermeulen
Rename dominateRemovedSourceVersions; the name is no longer accurate. |
793 |
self.makeDominator(pubs).dominateSourceVersions( |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
794 |
pubs[0].distroseries, pubs[0].pocket, package_name, ['0.2']) |
795 |
self.assertEqual([ |
|
796 |
PackagePublishingStatus.SUPERSEDED, |
|
797 |
PackagePublishingStatus.PUBLISHED, |
|
798 |
PackagePublishingStatus.DELETED, |
|
799 |
],
|
|
800 |
[pub.status for pub in pubs]) |
|
801 |
self.assertEqual( |
|
802 |
[pubs[1].sourcepackagerelease, None, None], |
|
803 |
[pub.supersededby for pub in pubs]) |
|
804 |
||
14017.3.2
by Jeroen Vermeulen
Rename dominateRemovedSourceVersions; the name is no longer accurate. |
805 |
def test_dominateSourceVersions_ignores_other_pockets(self): |
806 |
# dominateSourceVersions ignores publications in other pockets
|
|
807 |
# than the one specified.
|
|
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
808 |
pubs = make_spphs_for_versions(self.factory, ['2.3', '2.4']) |
809 |
package_name = pubs[0].sourcepackagerelease.sourcepackagename.name |
|
810 |
removeSecurityProxy(pubs[0]).pocket = PackagePublishingPocket.UPDATES |
|
811 |
removeSecurityProxy(pubs[1]).pocket = PackagePublishingPocket.PROPOSED |
|
14017.3.2
by Jeroen Vermeulen
Rename dominateRemovedSourceVersions; the name is no longer accurate. |
812 |
self.makeDominator(pubs).dominateSourceVersions( |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
813 |
pubs[0].distroseries, pubs[0].pocket, package_name, ['2.3']) |
814 |
self.assertEqual(PackagePublishingStatus.PUBLISHED, pubs[1].status) |
|
815 |
||
14017.3.2
by Jeroen Vermeulen
Rename dominateRemovedSourceVersions; the name is no longer accurate. |
816 |
def test_dominateSourceVersions_ignores_other_packages(self): |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
817 |
pubs = make_spphs_for_versions(self.factory, ['1.0', '1.1']) |
818 |
other_package_name = self.factory.makeSourcePackageName().name |
|
14017.3.2
by Jeroen Vermeulen
Rename dominateRemovedSourceVersions; the name is no longer accurate. |
819 |
self.makeDominator(pubs).dominateSourceVersions( |
13850.2.12
by Jeroen Vermeulen
Delete non-live versions without superseding versions. |
820 |
pubs[0].distroseries, pubs[0].pocket, other_package_name, ['1.1']) |
821 |
self.assertEqual(PackagePublishingStatus.PUBLISHED, pubs[0].status) |
|
13850.2.17
by Jeroen Vermeulen
Support for new gina domination loop. |
822 |
|
823 |
def test_findPublishedSourcePackageNames_finds_package(self): |
|
824 |
spph = self.factory.makeSourcePackagePublishingHistory( |
|
825 |
status=PackagePublishingStatus.PUBLISHED) |
|
826 |
dominator = self.makeDominator([spph]) |
|
827 |
self.assertContentEqual( |
|
14017.2.1
by Jeroen Vermeulen
New meaning for findPublishedSourcePackageNames (test change). |
828 |
[(spph.sourcepackagerelease.sourcepackagename.name, 1)], |
13850.2.17
by Jeroen Vermeulen
Support for new gina domination loop. |
829 |
dominator.findPublishedSourcePackageNames( |
830 |
spph.distroseries, spph.pocket)) |
|
831 |
||
832 |
def test_findPublishedSourcePackageNames_ignores_other_states(self): |
|
833 |
series = self.factory.makeDistroSeries() |
|
834 |
pocket = PackagePublishingPocket.RELEASE |
|
835 |
spphs = dict( |
|
836 |
(status, self.factory.makeSourcePackagePublishingHistory( |
|
837 |
distroseries=series, archive=series.main_archive, |
|
838 |
pocket=pocket, status=status)) |
|
839 |
for status in PackagePublishingStatus.items) |
|
840 |
published_spph = spphs[PackagePublishingStatus.PUBLISHED] |
|
841 |
dominator = self.makeDominator(spphs.values()) |
|
842 |
self.assertContentEqual( |
|
14017.2.1
by Jeroen Vermeulen
New meaning for findPublishedSourcePackageNames (test change). |
843 |
[(published_spph.sourcepackagerelease.sourcepackagename.name, 1)], |
13850.2.17
by Jeroen Vermeulen
Support for new gina domination loop. |
844 |
dominator.findPublishedSourcePackageNames(series, pocket)) |
845 |
||
846 |
def test_findPublishedSourcePackageNames_ignores_other_archives(self): |
|
847 |
spph = self.factory.makeSourcePackagePublishingHistory( |
|
848 |
status=PackagePublishingStatus.PUBLISHED) |
|
849 |
dominator = self.makeDominator([spph]) |
|
850 |
dominator.archive = self.factory.makeArchive() |
|
851 |
self.assertContentEqual( |
|
852 |
[],
|
|
853 |
dominator.findPublishedSourcePackageNames( |
|
854 |
spph.distroseries, spph.pocket)) |
|
855 |
||
856 |
def test_findPublishedSourcePackageNames_ignores_other_series(self): |
|
857 |
spph = self.factory.makeSourcePackagePublishingHistory( |
|
858 |
status=PackagePublishingStatus.PUBLISHED) |
|
859 |
distro = spph.distroseries.distribution |
|
860 |
other_series = self.factory.makeDistroSeries(distribution=distro) |
|
861 |
dominator = self.makeDominator([spph]) |
|
862 |
self.assertContentEqual( |
|
863 |
[],
|
|
864 |
dominator.findPublishedSourcePackageNames( |
|
865 |
other_series, spph.pocket)) |
|
866 |
||
867 |
def test_findPublishedSourcePackageNames_ignores_other_pockets(self): |
|
868 |
spph = self.factory.makeSourcePackagePublishingHistory( |
|
869 |
status=PackagePublishingStatus.PUBLISHED, |
|
870 |
pocket=PackagePublishingPocket.RELEASE) |
|
871 |
dominator = self.makeDominator([spph]) |
|
872 |
self.assertContentEqual( |
|
873 |
[],
|
|
874 |
dominator.findPublishedSourcePackageNames( |
|
875 |
spph.distroseries, PackagePublishingPocket.SECURITY)) |
|
876 |
||
14017.2.1
by Jeroen Vermeulen
New meaning for findPublishedSourcePackageNames (test change). |
877 |
def test_findPublishedSourcePackageNames_counts_published_SPPHs(self): |
878 |
series = self.factory.makeDistroSeries() |
|
879 |
pocket = PackagePublishingPocket.RELEASE |
|
880 |
spr = self.factory.makeSourcePackageRelease() |
|
881 |
spphs = [ |
|
882 |
self.factory.makeSourcePackagePublishingHistory( |
|
883 |
distroseries=series, sourcepackagerelease=spr, pocket=pocket, |
|
884 |
status=PackagePublishingStatus.PUBLISHED) |
|
885 |
for counter in xrange(2)] |
|
886 |
dominator = self.makeDominator(spphs) |
|
14017.3.3
by Jeroen Vermeulen
Slightly nicer test assertions. |
887 |
self.assertContentEqual( |
888 |
[(spr.sourcepackagename.name, len(spphs))], |
|
889 |
dominator.findPublishedSourcePackageNames(series, pocket)) |
|
14017.2.1
by Jeroen Vermeulen
New meaning for findPublishedSourcePackageNames (test change). |
890 |
|
891 |
def test_findPublishedSourcePackageNames_counts_no_other_state(self): |
|
892 |
series = self.factory.makeDistroSeries() |
|
893 |
pocket = PackagePublishingPocket.RELEASE |
|
894 |
spr = self.factory.makeSourcePackageRelease() |
|
895 |
spphs = [ |
|
896 |
self.factory.makeSourcePackagePublishingHistory( |
|
897 |
distroseries=series, sourcepackagerelease=spr, pocket=pocket, |
|
898 |
status=status) |
|
899 |
for status in PackagePublishingStatus.items] |
|
900 |
dominator = self.makeDominator(spphs) |
|
14017.3.3
by Jeroen Vermeulen
Slightly nicer test assertions. |
901 |
self.assertContentEqual( |
902 |
[(spr.sourcepackagename.name, 1)], |
|
903 |
dominator.findPublishedSourcePackageNames(series, pocket)) |
|
14017.2.1
by Jeroen Vermeulen
New meaning for findPublishedSourcePackageNames (test change). |
904 |
|
13850.2.17
by Jeroen Vermeulen
Support for new gina domination loop. |
905 |
def test_findPublishedSPPHs_finds_published_SPPH(self): |
906 |
spph = self.factory.makeSourcePackagePublishingHistory( |
|
907 |
status=PackagePublishingStatus.PUBLISHED) |
|
908 |
package_name = spph.sourcepackagerelease.sourcepackagename.name |
|
909 |
dominator = self.makeDominator([spph]) |
|
910 |
self.assertContentEqual( |
|
911 |
[spph], |
|
912 |
dominator.findPublishedSPPHs( |
|
913 |
spph.distroseries, spph.pocket, package_name)) |
|
914 |
||
915 |
def test_findPublishedSPPHs_ignores_other_states(self): |
|
916 |
series = self.factory.makeDistroSeries() |
|
917 |
package = self.factory.makeSourcePackageName() |
|
918 |
pocket = PackagePublishingPocket.RELEASE |
|
919 |
spphs = dict( |
|
920 |
(status, self.factory.makeSourcePackagePublishingHistory( |
|
921 |
distroseries=series, archive=series.main_archive, |
|
922 |
pocket=pocket, status=status, |
|
923 |
sourcepackagerelease=self.factory.makeSourcePackageRelease( |
|
924 |
sourcepackagename=package))) |
|
925 |
for status in PackagePublishingStatus.items) |
|
926 |
dominator = self.makeDominator(spphs.values()) |
|
927 |
self.assertContentEqual( |
|
928 |
[spphs[PackagePublishingStatus.PUBLISHED]], |
|
929 |
dominator.findPublishedSPPHs(series, pocket, package.name)) |
|
930 |
||
931 |
def test_findPublishedSPPHs_ignores_other_archives(self): |
|
932 |
spph = self.factory.makeSourcePackagePublishingHistory( |
|
933 |
status=PackagePublishingStatus.PUBLISHED) |
|
934 |
package = spph.sourcepackagerelease.sourcepackagename |
|
935 |
dominator = self.makeDominator([spph]) |
|
936 |
dominator.archive = self.factory.makeArchive() |
|
937 |
self.assertContentEqual( |
|
938 |
[],
|
|
939 |
dominator.findPublishedSPPHs( |
|
940 |
spph.distroseries, spph.pocket, package.name)) |
|
941 |
||
942 |
def test_findPublishedSPPHs_ignores_other_series(self): |
|
943 |
spph = self.factory.makeSourcePackagePublishingHistory( |
|
944 |
status=PackagePublishingStatus.PUBLISHED) |
|
945 |
distro = spph.distroseries.distribution |
|
946 |
package = spph.sourcepackagerelease.sourcepackagename |
|
947 |
other_series = self.factory.makeDistroSeries(distribution=distro) |
|
948 |
dominator = self.makeDominator([spph]) |
|
949 |
self.assertContentEqual( |
|
950 |
[],
|
|
951 |
dominator.findPublishedSPPHs( |
|
952 |
other_series, spph.pocket, package.name)) |
|
953 |
||
954 |
def test_findPublishedSPPHs_ignores_other_pockets(self): |
|
955 |
spph = self.factory.makeSourcePackagePublishingHistory( |
|
956 |
status=PackagePublishingStatus.PUBLISHED, |
|
957 |
pocket=PackagePublishingPocket.RELEASE) |
|
958 |
package = spph.sourcepackagerelease.sourcepackagename |
|
959 |
dominator = self.makeDominator([spph]) |
|
960 |
self.assertContentEqual( |
|
961 |
[],
|
|
962 |
dominator.findPublishedSPPHs( |
|
963 |
spph.distroseries, PackagePublishingPocket.SECURITY, |
|
964 |
package.name)) |
|
965 |
||
966 |
def test_findPublishedSPPHs_ignores_other_packages(self): |
|
967 |
spph = self.factory.makeSourcePackagePublishingHistory( |
|
968 |
status=PackagePublishingStatus.PUBLISHED) |
|
969 |
other_package = self.factory.makeSourcePackageName() |
|
970 |
dominator = self.makeDominator([spph]) |
|
971 |
self.assertContentEqual( |
|
972 |
[],
|
|
973 |
dominator.findPublishedSPPHs( |
|
974 |
spph.distroseries, spph.pocket, other_package.name)) |
|
14220.1.5
by Jeroen Vermeulen
Extract finding of publications for domination. |
975 |
|
976 |
def test_findBinariesForDomination_finds_published_publications(self): |
|
977 |
bpphs = make_bpphs_for_versions(self.factory, ['1.0', '1.1']) |
|
978 |
dominator = self.makeDominator(bpphs) |
|
979 |
self.assertContentEqual( |
|
980 |
bpphs, dominator.findBinariesForDomination( |
|
981 |
bpphs[0].distroarchseries, bpphs[0].pocket)) |
|
982 |
||
983 |
def test_findBinariesForDomination_skips_single_pub_packages(self): |
|
984 |
# The domination algorithm that uses findBinariesForDomination
|
|
985 |
# always keeps the latest version live. Thus, a single
|
|
986 |
# publication isn't worth dominating. findBinariesForDomination
|
|
987 |
# won't return it.
|
|
988 |
bpphs = make_bpphs_for_versions(self.factory, ['1.0']) |
|
989 |
dominator = self.makeDominator(bpphs) |
|
990 |
self.assertContentEqual( |
|
991 |
[], dominator.findBinariesForDomination( |
|
992 |
bpphs[0].distroarchseries, bpphs[0].pocket)) |
|
993 |
||
994 |
def test_findBinariesForDomination_ignores_other_distroseries(self): |
|
995 |
bpphs = make_bpphs_for_versions(self.factory, ['1.0', '1.1']) |
|
996 |
dominator = self.makeDominator(bpphs) |
|
997 |
das = bpphs[0].distroarchseries |
|
998 |
other_series = self.factory.makeDistroSeries( |
|
999 |
distribution=das.distroseries.distribution) |
|
1000 |
other_das = self.factory.makeDistroArchSeries( |
|
1001 |
distroseries=other_series, architecturetag=das.architecturetag, |
|
1002 |
processorfamily=das.processorfamily) |
|
1003 |
self.assertContentEqual( |
|
1004 |
[], dominator.findBinariesForDomination( |
|
1005 |
other_das, bpphs[0].pocket)) |
|
1006 |
||
1007 |
def test_findBinariesForDomination_ignores_other_architectures(self): |
|
1008 |
bpphs = make_bpphs_for_versions(self.factory, ['1.0', '1.1']) |
|
1009 |
dominator = self.makeDominator(bpphs) |
|
1010 |
other_das = self.factory.makeDistroArchSeries( |
|
1011 |
distroseries=bpphs[0].distroseries) |
|
1012 |
self.assertContentEqual( |
|
1013 |
[], dominator.findBinariesForDomination( |
|
1014 |
other_das, bpphs[0].pocket)) |
|
1015 |
||
1016 |
def test_findBinariesForDomination_ignores_other_archive(self): |
|
1017 |
bpphs = make_bpphs_for_versions(self.factory, ['1.0', '1.1']) |
|
1018 |
dominator = self.makeDominator(bpphs) |
|
1019 |
dominator.archive = self.factory.makeArchive() |
|
1020 |
self.assertContentEqual( |
|
1021 |
[], dominator.findBinariesForDomination( |
|
1022 |
bpphs[0].distroarchseries, bpphs[0].pocket)) |
|
1023 |
||
1024 |
def test_findBinariesForDomination_ignores_other_pocket(self): |
|
1025 |
bpphs = make_bpphs_for_versions(self.factory, ['1.0', '1.1']) |
|
1026 |
dominator = self.makeDominator(bpphs) |
|
1027 |
for bpph in bpphs: |
|
1028 |
removeSecurityProxy(bpph).pocket = PackagePublishingPocket.UPDATES |
|
1029 |
self.assertContentEqual( |
|
1030 |
[], dominator.findBinariesForDomination( |
|
1031 |
bpphs[0].distroarchseries, PackagePublishingPocket.SECURITY)) |
|
1032 |
||
1033 |
def test_findBinariesForDomination_ignores_other_status(self): |
|
1034 |
# If we have one BPPH for each possible status, plus one
|
|
1035 |
# Published one to stop findBinariesForDomination from skipping
|
|
1036 |
# the package, findBinariesForDomination returns only the
|
|
1037 |
# Published ones.
|
|
1038 |
versions = [ |
|
1039 |
'1.%d' % self.factory.getUniqueInteger() |
|
1040 |
for status in PackagePublishingStatus.items] + ['0.9'] |
|
1041 |
bpphs = make_bpphs_for_versions(self.factory, versions) |
|
1042 |
dominator = self.makeDominator(bpphs) |
|
1043 |
||
1044 |
for bpph, status in zip(bpphs, PackagePublishingStatus.items): |
|
1045 |
bpph.status = status |
|
1046 |
||
1047 |
# These are the Published publications. The other ones will all
|
|
1048 |
# be ignored.
|
|
1049 |
published_bpphs = [ |
|
1050 |
bpph
|
|
1051 |
for bpph in bpphs |
|
1052 |
if bpph.status == PackagePublishingStatus.PUBLISHED] |
|
1053 |
||
1054 |
self.assertContentEqual( |
|
1055 |
published_bpphs, |
|
1056 |
dominator.findBinariesForDomination( |
|
1057 |
bpphs[0].distroarchseries, bpphs[0].pocket)) |
|
1058 |
||
1059 |
def test_findSourcesForDomination_finds_published_publications(self): |
|
1060 |
spphs = make_spphs_for_versions(self.factory, ['2.0', '2.1']) |
|
1061 |
dominator = self.makeDominator(spphs) |
|
1062 |
self.assertContentEqual( |
|
1063 |
spphs, dominator.findSourcesForDomination( |
|
1064 |
spphs[0].distroseries, spphs[0].pocket)) |
|
1065 |
||
1066 |
def test_findSourcesForDomination_skips_single_pub_packages(self): |
|
1067 |
# The domination algorithm that uses findSourcesForDomination
|
|
1068 |
# always keeps the latest version live. Thus, a single
|
|
1069 |
# publication isn't worth dominating. findSourcesForDomination
|
|
1070 |
# won't return it.
|
|
1071 |
spphs = make_spphs_for_versions(self.factory, ['2.0']) |
|
1072 |
dominator = self.makeDominator(spphs) |
|
1073 |
self.assertContentEqual( |
|
1074 |
[], dominator.findSourcesForDomination( |
|
1075 |
spphs[0].distroseries, spphs[0].pocket)) |
|
1076 |
||
1077 |
def test_findSourcesForDomination_ignores_other_distroseries(self): |
|
1078 |
spphs = make_spphs_for_versions(self.factory, ['2.0', '2.1']) |
|
1079 |
dominator = self.makeDominator(spphs) |
|
1080 |
other_series = self.factory.makeDistroSeries( |
|
1081 |
distribution=spphs[0].distroseries.distribution) |
|
1082 |
self.assertContentEqual( |
|
1083 |
[], dominator.findSourcesForDomination( |
|
1084 |
other_series, spphs[0].pocket)) |
|
1085 |
||
1086 |
def test_findSourcesForDomination_ignores_other_pocket(self): |
|
1087 |
spphs = make_spphs_for_versions(self.factory, ['2.0', '2.1']) |
|
1088 |
dominator = self.makeDominator(spphs) |
|
1089 |
for spph in spphs: |
|
1090 |
removeSecurityProxy(spph).pocket = PackagePublishingPocket.UPDATES |
|
1091 |
self.assertContentEqual( |
|
1092 |
[], dominator.findSourcesForDomination( |
|
1093 |
spphs[0].distroseries, PackagePublishingPocket.SECURITY)) |
|
1094 |
||
1095 |
def test_findSourcesForDomination_ignores_other_status(self): |
|
1096 |
versions = [ |
|
1097 |
'1.%d' % self.factory.getUniqueInteger() |
|
1098 |
for status in PackagePublishingStatus.items] + ['0.9'] |
|
1099 |
spphs = make_spphs_for_versions(self.factory, versions) |
|
1100 |
dominator = self.makeDominator(spphs) |
|
1101 |
||
1102 |
for spph, status in zip(spphs, PackagePublishingStatus.items): |
|
1103 |
spph.status = status |
|
1104 |
||
1105 |
# These are the Published publications. The other ones will all
|
|
1106 |
# be ignored.
|
|
1107 |
published_spphs = [ |
|
1108 |
spph
|
|
1109 |
for spph in spphs |
|
1110 |
if spph.status == PackagePublishingStatus.PUBLISHED] |
|
1111 |
||
1112 |
self.assertContentEqual( |
|
1113 |
published_spphs, |
|
1114 |
dominator.findSourcesForDomination( |
|
1115 |
spphs[0].distroseries, spphs[0].pocket)) |
|
14220.2.2
by Jeroen Vermeulen
Initial tests of liveness functions; not passing yet. |
1116 |
|
1117 |
||
14220.2.3
by Jeroen Vermeulen
Most liveness-function tests pass. |
1118 |
def make_publications_arch_specific(pubs, arch_specific=True): |
1119 |
"""Set the `architecturespecific` attribute for given SPPHs.
|
|
1120 |
||
1121 |
:param pubs: An iterable of `BinaryPackagePublishingHistory`.
|
|
1122 |
:param arch_specific: Whether the binary package releases published
|
|
1123 |
by `pubs` are to be architecture-specific. If not, they will be
|
|
1124 |
treated as being for the "all" architecture.
|
|
1125 |
"""
|
|
1126 |
for pub in pubs: |
|
1127 |
bpr = removeSecurityProxy(pub).binarypackagerelease |
|
1128 |
bpr.architecturespecific = arch_specific |
|
1129 |
||
1130 |
||
14220.2.2
by Jeroen Vermeulen
Initial tests of liveness functions; not passing yet. |
1131 |
class TestLivenessFunctions(TestCaseWithFactory): |
1132 |
"""Tests for the functions that say which versions are live."""
|
|
1133 |
||
1134 |
layer = ZopelessDatabaseLayer |
|
1135 |
||
1136 |
def test_find_live_source_versions_blesses_latest(self): |
|
14220.3.1
by Jeroen Vermeulen
Review changes. |
1137 |
# find_live_source_versions, assuming that you passed it
|
1138 |
# publications sorted from most current to least current
|
|
1139 |
# version, simply returns the most current version.
|
|
14220.2.5
by Jeroen Vermeulen
Successfully tested the binary-phase-2 arch-all domination reprieve. |
1140 |
spphs = make_spphs_for_versions(self.factory, ['1.2', '1.1', '1.0']) |
1141 |
self.assertEqual(['1.2'], find_live_source_versions(spphs)) |
|
14220.2.2
by Jeroen Vermeulen
Initial tests of liveness functions; not passing yet. |
1142 |
|
14220.2.4
by Jeroen Vermeulen
Still working on tests. Shorter names for first-pass and second-pass liveness functions. |
1143 |
def test_find_live_binary_versions_pass_1_blesses_latest(self): |
14220.3.1
by Jeroen Vermeulen
Review changes. |
1144 |
# find_live_binary_versions_pass_1 always includes the latest
|
1145 |
# version among the input publications in its result.
|
|
14220.2.5
by Jeroen Vermeulen
Successfully tested the binary-phase-2 arch-all domination reprieve. |
1146 |
bpphs = make_bpphs_for_versions(self.factory, ['1.2', '1.1', '1.0']) |
14220.2.3
by Jeroen Vermeulen
Most liveness-function tests pass. |
1147 |
make_publications_arch_specific(bpphs) |
14220.2.5
by Jeroen Vermeulen
Successfully tested the binary-phase-2 arch-all domination reprieve. |
1148 |
self.assertEqual(['1.2'], find_live_binary_versions_pass_1(bpphs)) |
14220.2.2
by Jeroen Vermeulen
Initial tests of liveness functions; not passing yet. |
1149 |
|
14220.2.4
by Jeroen Vermeulen
Still working on tests. Shorter names for first-pass and second-pass liveness functions. |
1150 |
def test_find_live_binary_versions_pass_1_blesses_arch_all(self): |
14220.3.1
by Jeroen Vermeulen
Review changes. |
1151 |
# find_live_binary_versions_pass_1 includes any
|
1152 |
# architecture-independent publications among the input in its
|
|
1153 |
# result.
|
|
14220.2.5
by Jeroen Vermeulen
Successfully tested the binary-phase-2 arch-all domination reprieve. |
1154 |
versions = list(reversed(['1.%d' % version for version in range(3)])) |
14220.2.3
by Jeroen Vermeulen
Most liveness-function tests pass. |
1155 |
bpphs = make_bpphs_for_versions(self.factory, versions) |
1156 |
||
1157 |
# All of these publications are architecture-specific, except
|
|
1158 |
# the last one. This would happen if the binary package had
|
|
1159 |
# just changed from being architecture-specific to being
|
|
1160 |
# architecture-independent.
|
|
1161 |
make_publications_arch_specific(bpphs, True) |
|
1162 |
make_publications_arch_specific(bpphs[-1:], False) |
|
14220.2.2
by Jeroen Vermeulen
Initial tests of liveness functions; not passing yet. |
1163 |
self.assertEqual( |
14220.2.3
by Jeroen Vermeulen
Most liveness-function tests pass. |
1164 |
versions[:1] + versions[-1:], |
14220.2.4
by Jeroen Vermeulen
Still working on tests. Shorter names for first-pass and second-pass liveness functions. |
1165 |
find_live_binary_versions_pass_1(bpphs)) |
14220.2.2
by Jeroen Vermeulen
Initial tests of liveness functions; not passing yet. |
1166 |
|
14220.2.4
by Jeroen Vermeulen
Still working on tests. Shorter names for first-pass and second-pass liveness functions. |
1167 |
def test_find_live_binary_versions_pass_2_blesses_latest(self): |
14220.3.1
by Jeroen Vermeulen
Review changes. |
1168 |
# find_live_binary_versions_pass_2 always includes the latest
|
1169 |
# version among the input publications in its result.
|
|
14220.2.5
by Jeroen Vermeulen
Successfully tested the binary-phase-2 arch-all domination reprieve. |
1170 |
bpphs = make_bpphs_for_versions(self.factory, ['1.2', '1.1', '1.0']) |
14220.2.3
by Jeroen Vermeulen
Most liveness-function tests pass. |
1171 |
make_publications_arch_specific(bpphs, False) |
14220.2.10
by Jeroen Vermeulen
Review afterthought from earlier branch; pass cache to 2nd-pass binary domination liveness function. |
1172 |
cache = ArchSpecificPublicationsCache() |
1173 |
self.assertEqual( |
|
1174 |
['1.2'], find_live_binary_versions_pass_2(bpphs, cache)) |
|
14220.2.2
by Jeroen Vermeulen
Initial tests of liveness functions; not passing yet. |
1175 |
|
14220.2.4
by Jeroen Vermeulen
Still working on tests. Shorter names for first-pass and second-pass liveness functions. |
1176 |
def test_find_live_binary_versions_pass_2_blesses_arch_specific(self): |
14220.3.1
by Jeroen Vermeulen
Review changes. |
1177 |
# find_live_binary_versions_pass_2 includes any
|
1178 |
# architecture-specific publications among the input in its
|
|
1179 |
# result.
|
|
14220.2.5
by Jeroen Vermeulen
Successfully tested the binary-phase-2 arch-all domination reprieve. |
1180 |
versions = list(reversed(['1.%d' % version for version in range(3)])) |
1181 |
bpphs = make_bpphs_for_versions(self.factory, versions) |
|
14220.2.3
by Jeroen Vermeulen
Most liveness-function tests pass. |
1182 |
make_publications_arch_specific(bpphs) |
14220.2.10
by Jeroen Vermeulen
Review afterthought from earlier branch; pass cache to 2nd-pass binary domination liveness function. |
1183 |
cache = ArchSpecificPublicationsCache() |
1184 |
self.assertEqual( |
|
1185 |
versions, find_live_binary_versions_pass_2(bpphs, cache)) |
|
14220.2.3
by Jeroen Vermeulen
Most liveness-function tests pass. |
1186 |
|
14220.2.4
by Jeroen Vermeulen
Still working on tests. Shorter names for first-pass and second-pass liveness functions. |
1187 |
def test_find_live_binary_versions_pass_2_reprieves_arch_all(self): |
14220.2.5
by Jeroen Vermeulen
Successfully tested the binary-phase-2 arch-all domination reprieve. |
1188 |
# An arch-all BPPH for a BPR built by an SPR that also still has
|
1189 |
# active arch-dependent BPPHs gets a reprieve: it can't be
|
|
1190 |
# superseded until those arch-dependent BPPHs have been
|
|
1191 |
# superseded.
|
|
1192 |
bpphs = make_bpphs_for_versions(self.factory, ['1.2', '1.1', '1.0']) |
|
1193 |
make_publications_arch_specific(bpphs, False) |
|
1194 |
dependent = self.factory.makeBinaryPackagePublishingHistory( |
|
1195 |
binarypackagerelease=bpphs[1].binarypackagerelease) |
|
1196 |
make_publications_arch_specific([dependent], True) |
|
14220.2.10
by Jeroen Vermeulen
Review afterthought from earlier branch; pass cache to 2nd-pass binary domination liveness function. |
1197 |
cache = ArchSpecificPublicationsCache() |
14220.2.5
by Jeroen Vermeulen
Successfully tested the binary-phase-2 arch-all domination reprieve. |
1198 |
self.assertEqual( |
14220.2.10
by Jeroen Vermeulen
Review afterthought from earlier branch; pass cache to 2nd-pass binary domination liveness function. |
1199 |
['1.2', '1.1'], find_live_binary_versions_pass_2(bpphs, cache)) |
14220.2.6
by Jeroen Vermeulen
Limit 2nd binary-domination pass to packages with arch-indep publications. |
1200 |
|
1201 |
||
1202 |
class TestDominationHelpers(TestCaseWithFactory): |
|
1203 |
"""Test lightweight helpers for the `Dominator`."""
|
|
1204 |
||
1205 |
layer = ZopelessDatabaseLayer |
|
1206 |
||
1207 |
def test_contains_arch_indep_says_True_for_arch_indep(self): |
|
1208 |
bpphs = [self.factory.makeBinaryPackagePublishingHistory()] |
|
1209 |
make_publications_arch_specific(bpphs, False) |
|
1210 |
self.assertTrue(contains_arch_indep(bpphs)) |
|
1211 |
||
1212 |
def test_contains_arch_indep_says_False_for_arch_specific(self): |
|
1213 |
bpphs = [self.factory.makeBinaryPackagePublishingHistory()] |
|
1214 |
make_publications_arch_specific(bpphs, True) |
|
1215 |
self.assertFalse(contains_arch_indep(bpphs)) |
|
1216 |
||
1217 |
def test_contains_arch_indep_says_True_for_combination(self): |
|
1218 |
bpphs = make_bpphs_for_versions(self.factory, ['1.1', '1.0']) |
|
1219 |
make_publications_arch_specific(bpphs[:1], True) |
|
1220 |
make_publications_arch_specific(bpphs[1:], False) |
|
1221 |
self.assertTrue(contains_arch_indep(bpphs)) |
|
1222 |
||
1223 |
def test_contains_arch_indep_says_False_for_empty_list(self): |
|
1224 |
self.assertFalse(contains_arch_indep([])) |
|
14220.2.9
by Jeroen Vermeulen
Create arch-specific-publications cache for 2nd-pass binary domination. |
1225 |
|
1226 |
||
1227 |
class TestArchSpecificPublicationsCache(TestCaseWithFactory): |
|
1228 |
"""Tests for `ArchSpecificPublicationsCache`."""
|
|
1229 |
||
1230 |
layer = ZopelessDatabaseLayer |
|
1231 |
||
1232 |
def makeCache(self): |
|
1233 |
"""Shorthand: create a ArchSpecificPublicationsCache."""
|
|
1234 |
return ArchSpecificPublicationsCache() |
|
1235 |
||
1236 |
def makeSPR(self): |
|
1237 |
"""Create a `BinaryPackageRelease`."""
|
|
1238 |
# Return an un-proxied SPR. This is script code, so it won't be
|
|
1239 |
# running into them in real life.
|
|
1240 |
return removeSecurityProxy(self.factory.makeSourcePackageRelease()) |
|
1241 |
||
1242 |
def makeBPPH(self, spr=None, arch_specific=True, archive=None, |
|
1243 |
distroseries=None): |
|
1244 |
"""Create a `BinaryPackagePublishingHistory`."""
|
|
1245 |
if spr is None: |
|
1246 |
spr = self.makeSPR() |
|
1247 |
bpb = self.factory.makeBinaryPackageBuild(source_package_release=spr) |
|
1248 |
bpr = self.factory.makeBinaryPackageRelease( |
|
1249 |
build=bpb, architecturespecific=arch_specific) |
|
1250 |
das = self.factory.makeDistroArchSeries(distroseries=distroseries) |
|
1251 |
return removeSecurityProxy( |
|
1252 |
self.factory.makeBinaryPackagePublishingHistory( |
|
1253 |
binarypackagerelease=bpr, archive=archive, |
|
1254 |
distroarchseries=das, pocket=PackagePublishingPocket.UPDATES, |
|
1255 |
status=PackagePublishingStatus.PUBLISHED)) |
|
1256 |
||
1257 |
def test_getKey_is_consistent_and_distinguishing(self): |
|
1258 |
# getKey consistently returns the same key for the same BPPH,
|
|
1259 |
# but different keys for non-matching BPPHs.
|
|
1260 |
bpphs = [ |
|
1261 |
self.factory.makeBinaryPackagePublishingHistory() |
|
1262 |
for counter in range(2)] |
|
1263 |
cache = self.makeCache() |
|
1264 |
self.assertContentEqual( |
|
1265 |
[cache.getKey(bpph) for bpph in bpphs], |
|
1266 |
set(cache.getKey(bpph) for bpph in bpphs * 2)) |
|
1267 |
||
1268 |
def test_hasArchSpecificPublications_is_consistent_and_correct(self): |
|
14220.2.14
by Jeroen Vermeulen
Review changes. |
1269 |
# hasArchSpecificPublications consistently, repeatably returns
|
1270 |
# the same result for the same key. Naturally, different keys
|
|
1271 |
# can still produce different results.
|
|
14220.2.9
by Jeroen Vermeulen
Create arch-specific-publications cache for 2nd-pass binary domination. |
1272 |
spr = self.makeSPR() |
1273 |
dependent = self.makeBPPH(spr, arch_specific=True) |
|
1274 |
bpph1 = self.makeBPPH( |
|
1275 |
spr, arch_specific=False, archive=dependent.archive, |
|
1276 |
distroseries=dependent.distroseries) |
|
1277 |
bpph2 = self.makeBPPH(arch_specific=False) |
|
1278 |
cache = self.makeCache() |
|
1279 |
self.assertEqual( |
|
1280 |
[True, True, False, False], |
|
1281 |
[
|
|
1282 |
cache.hasArchSpecificPublications(bpph1), |
|
1283 |
cache.hasArchSpecificPublications(bpph1), |
|
1284 |
cache.hasArchSpecificPublications(bpph2), |
|
1285 |
cache.hasArchSpecificPublications(bpph2), |
|
1286 |
])
|
|
1287 |
||
1288 |
def test_hasArchSpecificPublications_caches_results(self): |
|
1289 |
# Results are cached, so once the presence of archive-specific
|
|
1290 |
# publications has been looked up in the database, the query is
|
|
1291 |
# not performed again for the same inputs.
|
|
1292 |
spr = self.makeSPR() |
|
1293 |
self.makeBPPH(spr, arch_specific=True) |
|
1294 |
bpph = self.makeBPPH(spr, arch_specific=False) |
|
1295 |
cache = self.makeCache() |
|
1296 |
cache.hasArchSpecificPublications(bpph) |
|
1297 |
spr.getActiveArchSpecificPublications = FakeMethod() |
|
1298 |
cache.hasArchSpecificPublications(bpph) |
|
1299 |
self.assertEqual(0, spr.getActiveArchSpecificPublications.call_count) |