Merge lp:~cjwatson/launchpad/archive-dependencies-unittest into lp:launchpad
- archive-dependencies-unittest
- Merge into devel
Proposed by
Colin Watson
Status: | Merged |
---|---|
Merged at revision: | 18378 |
Proposed branch: | lp:~cjwatson/launchpad/archive-dependencies-unittest |
Merge into: | lp:launchpad |
Diff against target: |
1256 lines (+541/-643) 5 files modified
lib/lp/soyuz/adapters/tests/test_archivedependencies.py (+517/-0) lib/lp/soyuz/doc/archive-dependencies.txt (+0/-637) lib/lp/soyuz/interfaces/archive.py (+2/-2) lib/lp/soyuz/tests/test_archive.py (+14/-1) lib/lp/testing/factory.py (+8/-3) |
To merge this branch: | bzr merge lp:~cjwatson/launchpad/archive-dependencies-unittest |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
William Grant | code | Approve | |
Review via email: mp+323129@code.launchpad.net |
Commit message
Convert archive-
Description of the change
I needed to do this to make it less painful to change get_sources_
To post a comment you must log in.
Revision history for this message
William Grant (wgrant) : | # |
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'lib/lp/soyuz/adapters/tests/test_archivedependencies.py' |
2 | --- lib/lp/soyuz/adapters/tests/test_archivedependencies.py 1970-01-01 00:00:00 +0000 |
3 | +++ lib/lp/soyuz/adapters/tests/test_archivedependencies.py 2017-04-25 11:47:06 +0000 |
4 | @@ -0,0 +1,517 @@ |
5 | +# Copyright 2017 Canonical Ltd. This software is licensed under the |
6 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
7 | + |
8 | +"""Test archive dependencies.""" |
9 | + |
10 | +from __future__ import absolute_import, print_function, unicode_literals |
11 | + |
12 | +__metaclass__ = type |
13 | + |
14 | +from testtools.matchers import StartsWith |
15 | +import transaction |
16 | +from zope.component import getUtility |
17 | + |
18 | +from lp.registry.interfaces.distribution import IDistributionSet |
19 | +from lp.registry.interfaces.pocket import PackagePublishingPocket |
20 | +from lp.services.log.logger import BufferLogger |
21 | +from lp.soyuz.adapters.archivedependencies import ( |
22 | + default_component_dependency_name, |
23 | + default_pocket_dependency, |
24 | + get_components_for_context, |
25 | + get_primary_current_component, |
26 | + get_sources_list_for_building, |
27 | + pocket_dependencies, |
28 | + ) |
29 | +from lp.soyuz.enums import PackagePublishingStatus |
30 | +from lp.soyuz.interfaces.archive import IArchive |
31 | +from lp.soyuz.interfaces.component import IComponentSet |
32 | +from lp.soyuz.tests.test_publishing import SoyuzTestPublisher |
33 | +from lp.testing import TestCaseWithFactory |
34 | +from lp.testing.layers import ( |
35 | + LaunchpadZopelessLayer, |
36 | + ZopelessDatabaseLayer, |
37 | + ) |
38 | + |
39 | + |
40 | +class TestOgreModel(TestCaseWithFactory): |
41 | + """Test ogre-model component handling. |
42 | + |
43 | + The Ubuntu "ogre model" (cf. Shrek) ensures that build-dependencies are |
44 | + consistent with the component in which the source is published. |
45 | + """ |
46 | + |
47 | + layer = ZopelessDatabaseLayer |
48 | + |
49 | + def setUpComponents(self, distroseries, component_names): |
50 | + for component_name in component_names: |
51 | + component = getUtility(IComponentSet)[component_name] |
52 | + self.factory.makeComponentSelection(distroseries, component) |
53 | + |
54 | + def assertComponentMap(self, expected, distroseries, pocket): |
55 | + for component_name, expected_components in expected.items(): |
56 | + component = getUtility(IComponentSet)[component_name] |
57 | + self.assertEqual( |
58 | + expected_components, |
59 | + get_components_for_context(component, distroseries, pocket)) |
60 | + |
61 | + def test_strict_supported_component_dependencies(self): |
62 | + # In strict-supported-component-dependencies mode, a source |
63 | + # published in main is only allowed to build-depend on binaries also |
64 | + # published in main, while a source published in universe is allowed |
65 | + # to build-depend on main and universe. |
66 | + distroseries = self.factory.makeDistroSeries() |
67 | + expected = { |
68 | + "main": ["main"], |
69 | + "restricted": ["main", "restricted"], |
70 | + "universe": ["main", "universe"], |
71 | + "multiverse": ["main", "restricted", "universe", "multiverse"], |
72 | + "partner": ["partner"], |
73 | + } |
74 | + self.setUpComponents(distroseries, expected.keys()) |
75 | + self.assertComponentMap( |
76 | + expected, distroseries, PackagePublishingPocket.RELEASE) |
77 | + |
78 | + def test_lax_supported_component_dependencies(self): |
79 | + # In lax-supported-component-dependencies mode, source packages in |
80 | + # "supported" components (main and restricted) may additionally |
81 | + # build-depend on binary packages in "unsupported" components |
82 | + # (universe and multiverse). |
83 | + distroseries = self.factory.makeDistroSeries() |
84 | + distroseries.strict_supported_component_dependencies = False |
85 | + expected = { |
86 | + "main": ["main", "universe"], |
87 | + "restricted": ["main", "restricted", "universe", "multiverse"], |
88 | + "universe": ["main", "universe"], |
89 | + "multiverse": ["main", "restricted", "universe", "multiverse"], |
90 | + "partner": ["partner"], |
91 | + } |
92 | + self.setUpComponents(distroseries, expected.keys()) |
93 | + self.assertComponentMap( |
94 | + expected, distroseries, PackagePublishingPocket.RELEASE) |
95 | + |
96 | + def test_backports(self): |
97 | + # Source packages in the BACKPORTS pocket are allowed to |
98 | + # build-depend on binary packages in any component. This avoids |
99 | + # having to make potentially-invasive changes to accommodate |
100 | + # backporting to stable series. |
101 | + distroseries = self.factory.makeDistroSeries() |
102 | + expected = { |
103 | + "main": ["main", "restricted", "universe", "multiverse"], |
104 | + "restricted": ["main", "restricted", "universe", "multiverse"], |
105 | + "universe": ["main", "restricted", "universe", "multiverse"], |
106 | + "multiverse": ["main", "restricted", "universe", "multiverse"], |
107 | + "partner": ["main", "restricted", "universe", "multiverse"], |
108 | + } |
109 | + self.setUpComponents(distroseries, expected.keys()) |
110 | + self.assertComponentMap( |
111 | + expected, distroseries, PackagePublishingPocket.BACKPORTS) |
112 | + |
113 | + |
114 | +class TestSourcesList(TestCaseWithFactory): |
115 | + """Test sources.list contents for building, and related mechanisms.""" |
116 | + |
117 | + layer = LaunchpadZopelessLayer |
118 | + |
119 | + ubuntu_components = [ |
120 | + "main", "restricted", "universe", "multiverse", "partner"] |
121 | + |
122 | + def setUp(self): |
123 | + super(TestSourcesList, self).setUp() |
124 | + self.publisher = SoyuzTestPublisher() |
125 | + self.ubuntu = getUtility(IDistributionSet).getByName("ubuntu") |
126 | + self.hoary = self.ubuntu.getSeries("hoary") |
127 | + self.publisher.addFakeChroots(self.hoary) |
128 | + self.publisher.setUpDefaultDistroSeries(self.hoary) |
129 | + for component_name in self.ubuntu_components: |
130 | + component = getUtility(IComponentSet)[component_name] |
131 | + if component not in self.hoary.components: |
132 | + self.factory.makeComponentSelection(self.hoary, component) |
133 | + |
134 | + def test_defaults(self): |
135 | + # Non-primary archives by default use the Release, Security and |
136 | + # Updates pockets from the primary archive, and all its available |
137 | + # components. |
138 | + self.assertEqual( |
139 | + PackagePublishingPocket.UPDATES, default_pocket_dependency) |
140 | + self.assertEqual("multiverse", default_component_dependency_name) |
141 | + self.assertEqual( |
142 | + (PackagePublishingPocket.RELEASE, |
143 | + PackagePublishingPocket.SECURITY, |
144 | + PackagePublishingPocket.UPDATES), |
145 | + pocket_dependencies[default_pocket_dependency]) |
146 | + |
147 | + def makeArchive(self, publish_binary=False, **kwargs): |
148 | + archive = self.factory.makeArchive(distribution=self.ubuntu, **kwargs) |
149 | + if publish_binary: |
150 | + self.publisher.getPubBinaries( |
151 | + archive=archive, status=PackagePublishingStatus.PUBLISHED) |
152 | + return archive |
153 | + |
154 | + def makeBuild(self, **kwargs): |
155 | + pub_source = self.publisher.getPubSource(**kwargs) |
156 | + [build] = pub_source.createMissingBuilds() |
157 | + return build |
158 | + |
159 | + def assertPrimaryCurrentComponent(self, expected, build): |
160 | + self.assertEqual( |
161 | + expected, |
162 | + get_primary_current_component( |
163 | + build.archive, build.distro_series, |
164 | + build.source_package_release.name).name) |
165 | + |
166 | + def assertSourcesList(self, expected, build, **kwargs): |
167 | + expected_lines = [] |
168 | + for archive_or_prefix, suffixes in expected: |
169 | + if IArchive.providedBy(archive_or_prefix): |
170 | + prefix = "deb %s " % archive_or_prefix.archive_url |
171 | + else: |
172 | + prefix = archive_or_prefix + " " |
173 | + expected_lines.extend([prefix + suffix for suffix in suffixes]) |
174 | + sources_list = get_sources_list_for_building( |
175 | + build, build.distro_arch_series, build.source_package_release.name, |
176 | + **kwargs) |
177 | + self.assertEqual(expected_lines, sources_list) |
178 | + |
179 | + def test_ppa_with_no_binaries(self): |
180 | + # If there are no published binaries in a PPA, only its primary |
181 | + # archive dependencies need to be considered. |
182 | + ppa = self.makeArchive() |
183 | + build = self.makeBuild(archive=ppa) |
184 | + self.assertEqual( |
185 | + 0, ppa.getAllPublishedBinaries( |
186 | + distroarchseries=build.distro_arch_series, |
187 | + status=PackagePublishingStatus.PUBLISHED).count()) |
188 | + self.assertSourcesList( |
189 | + [(self.ubuntu.main_archive, [ |
190 | + "hoary main restricted universe multiverse", |
191 | + "hoary-security main restricted universe multiverse", |
192 | + "hoary-updates main restricted universe multiverse", |
193 | + ]), |
194 | + ], build) |
195 | + |
196 | + def test_ppa_with_binaries(self): |
197 | + # If there are binaries published in a PPA, then the PPA is |
198 | + # considered as well as its primary dependencies. |
199 | + ppa = self.makeArchive(publish_binary=True) |
200 | + build = self.makeBuild(archive=ppa) |
201 | + self.assertSourcesList( |
202 | + [(ppa, ["hoary main"]), |
203 | + (self.ubuntu.main_archive, [ |
204 | + "hoary main restricted universe multiverse", |
205 | + "hoary-security main restricted universe multiverse", |
206 | + "hoary-updates main restricted universe multiverse", |
207 | + ]), |
208 | + ], build) |
209 | + |
210 | + def test_dependent_ppa_with_no_binaries(self): |
211 | + # A depended-upon PPA is not considered if it has no published |
212 | + # binaries. |
213 | + lower_ppa = self.makeArchive() |
214 | + upper_ppa = self.makeArchive(publish_binary=True) |
215 | + upper_ppa.addArchiveDependency( |
216 | + lower_ppa, PackagePublishingPocket.RELEASE, |
217 | + getUtility(IComponentSet)["main"]) |
218 | + build = self.makeBuild(archive=upper_ppa) |
219 | + self.assertSourcesList( |
220 | + [(upper_ppa, ["hoary main"]), |
221 | + (self.ubuntu.main_archive, [ |
222 | + "hoary main restricted universe multiverse", |
223 | + "hoary-security main restricted universe multiverse", |
224 | + "hoary-updates main restricted universe multiverse", |
225 | + ]), |
226 | + ], build) |
227 | + |
228 | + def test_dependent_ppa_with_binaries(self): |
229 | + # A depended-upon PPA is considered if it has published binaries. |
230 | + lower_ppa = self.makeArchive(publish_binary=True) |
231 | + upper_ppa = self.makeArchive(publish_binary=True) |
232 | + upper_ppa.addArchiveDependency( |
233 | + lower_ppa, PackagePublishingPocket.RELEASE, |
234 | + getUtility(IComponentSet)["main"]) |
235 | + build = self.makeBuild(archive=upper_ppa) |
236 | + self.assertSourcesList( |
237 | + [(upper_ppa, ["hoary main"]), |
238 | + (lower_ppa, ["hoary main"]), |
239 | + (self.ubuntu.main_archive, [ |
240 | + "hoary main restricted universe multiverse", |
241 | + "hoary-security main restricted universe multiverse", |
242 | + "hoary-updates main restricted universe multiverse", |
243 | + ]), |
244 | + ], build) |
245 | + |
246 | + def test_lax_supported_component_dependencies(self): |
247 | + # Dependencies for series with |
248 | + # strict_supported_component_dependencies=False are reasonable. |
249 | + # PPAs only have the "main" component. |
250 | + lower_ppa = self.makeArchive(publish_binary=True) |
251 | + upper_ppa = self.makeArchive(publish_binary=True) |
252 | + upper_ppa.addArchiveDependency( |
253 | + lower_ppa, PackagePublishingPocket.RELEASE, |
254 | + getUtility(IComponentSet)["main"]) |
255 | + upper_ppa.addArchiveDependency( |
256 | + self.ubuntu.main_archive, PackagePublishingPocket.UPDATES, |
257 | + getUtility(IComponentSet)["restricted"]) |
258 | + build = self.makeBuild(archive=upper_ppa) |
259 | + self.assertSourcesList( |
260 | + [(upper_ppa, ["hoary main"]), |
261 | + (lower_ppa, ["hoary main"]), |
262 | + (self.ubuntu.main_archive, [ |
263 | + "hoary main restricted", |
264 | + "hoary-security main restricted", |
265 | + "hoary-updates main restricted", |
266 | + ]), |
267 | + ], build) |
268 | + self.hoary.strict_supported_component_dependencies = False |
269 | + transaction.commit() |
270 | + self.assertSourcesList( |
271 | + [(upper_ppa, ["hoary main"]), |
272 | + (lower_ppa, ["hoary main"]), |
273 | + (self.ubuntu.main_archive, [ |
274 | + "hoary main restricted universe multiverse", |
275 | + "hoary-security main restricted universe multiverse", |
276 | + "hoary-updates main restricted universe multiverse", |
277 | + ]), |
278 | + ], build) |
279 | + |
280 | + def test_no_op_primary_archive_dependency(self): |
281 | + # Overriding the default primary archive dependencies with exactly |
282 | + # the same values has no effect. |
283 | + ppa = self.makeArchive() |
284 | + ppa.addArchiveDependency( |
285 | + self.ubuntu.main_archive, PackagePublishingPocket.UPDATES, |
286 | + getUtility(IComponentSet)["multiverse"]) |
287 | + build = self.makeBuild(archive=ppa) |
288 | + self.assertSourcesList( |
289 | + [(self.ubuntu.main_archive, [ |
290 | + "hoary main restricted universe multiverse", |
291 | + "hoary-security main restricted universe multiverse", |
292 | + "hoary-updates main restricted universe multiverse", |
293 | + ]), |
294 | + ], build) |
295 | + |
296 | + def test_primary_archive_dependency_security(self): |
297 | + # The primary archive dependency can be modified to behave as an |
298 | + # embargoed archive that builds security updates. This is done by |
299 | + # setting the SECURITY pocket dependencies (RELEASE and SECURITY) |
300 | + # and following the component dependencies of the component where |
301 | + # the source was last published in the primary archive. |
302 | + ppa = self.makeArchive() |
303 | + ppa.addArchiveDependency( |
304 | + self.ubuntu.main_archive, PackagePublishingPocket.SECURITY) |
305 | + build = self.makeBuild(archive=ppa) |
306 | + self.assertPrimaryCurrentComponent("universe", build) |
307 | + self.assertSourcesList( |
308 | + [(self.ubuntu.main_archive, [ |
309 | + "hoary main universe", |
310 | + "hoary-security main universe", |
311 | + ]), |
312 | + ], build) |
313 | + self.publisher.getPubSource( |
314 | + sourcename="with-ancestry", version="1.0", |
315 | + archive=self.ubuntu.main_archive) |
316 | + [build_with_ancestry] = self.publisher.getPubSource( |
317 | + sourcename="with-ancestry", version="1.1", |
318 | + archive=ppa).createMissingBuilds() |
319 | + self.assertPrimaryCurrentComponent("main", build_with_ancestry) |
320 | + self.assertSourcesList( |
321 | + [(self.ubuntu.main_archive, [ |
322 | + "hoary main", |
323 | + "hoary-security main", |
324 | + ]), |
325 | + ], build_with_ancestry) |
326 | + |
327 | + def test_primary_archive_dependency_release(self): |
328 | + # The primary archive dependency can be modified to behave as a |
329 | + # pristine build environment based only on what was included in the |
330 | + # original release of the corresponding series. |
331 | + ppa = self.makeArchive() |
332 | + ppa.addArchiveDependency( |
333 | + self.ubuntu.main_archive, PackagePublishingPocket.RELEASE, |
334 | + getUtility(IComponentSet)["restricted"]) |
335 | + build = self.makeBuild(archive=ppa) |
336 | + self.assertSourcesList( |
337 | + [(self.ubuntu.main_archive, ["hoary main restricted"])], build) |
338 | + |
339 | + def test_primary_archive_dependency_proposed(self): |
340 | + # The primary archive dependency can be modified to extend the build |
341 | + # environment for PROPOSED. |
342 | + ppa = self.makeArchive() |
343 | + ppa.addArchiveDependency( |
344 | + self.ubuntu.main_archive, PackagePublishingPocket.PROPOSED, |
345 | + getUtility(IComponentSet)["multiverse"]) |
346 | + build = self.makeBuild(archive=ppa) |
347 | + self.assertSourcesList( |
348 | + [(self.ubuntu.main_archive, [ |
349 | + "hoary main restricted universe multiverse", |
350 | + "hoary-security main restricted universe multiverse", |
351 | + "hoary-updates main restricted universe multiverse", |
352 | + "hoary-proposed main restricted universe multiverse", |
353 | + ]), |
354 | + ], build) |
355 | + |
356 | + def test_primary_archive_dependency_backports(self): |
357 | + # The primary archive dependency can be modified to extend the build |
358 | + # environment for PROPOSED. |
359 | + ppa = self.makeArchive() |
360 | + ppa.addArchiveDependency( |
361 | + self.ubuntu.main_archive, PackagePublishingPocket.BACKPORTS, |
362 | + getUtility(IComponentSet)["multiverse"]) |
363 | + build = self.makeBuild(archive=ppa) |
364 | + self.assertSourcesList( |
365 | + [(self.ubuntu.main_archive, [ |
366 | + "hoary main restricted universe multiverse", |
367 | + "hoary-security main restricted universe multiverse", |
368 | + "hoary-updates main restricted universe multiverse", |
369 | + "hoary-backports main restricted universe multiverse", |
370 | + ]), |
371 | + ], build) |
372 | + |
373 | + def test_partner(self): |
374 | + # Similarly to what happens with PPA builds, partner builds may |
375 | + # depend on any component in the primary archive. This behaviour |
376 | + # allows scenarios where partner packages may use other |
377 | + # restricted/non-free applications from multiverse, and also other |
378 | + # partner applications. |
379 | + primary, partner = self.ubuntu.all_distro_archives |
380 | + self.publisher.getPubBinaries( |
381 | + archive=partner, component="partner", |
382 | + status=PackagePublishingStatus.PUBLISHED) |
383 | + build = self.makeBuild(archive=partner, component="partner") |
384 | + self.assertSourcesList( |
385 | + [(partner, ["hoary partner"]), |
386 | + (primary, [ |
387 | + "hoary main restricted universe multiverse", |
388 | + "hoary-security main restricted universe multiverse", |
389 | + "hoary-updates main restricted universe multiverse", |
390 | + ]), |
391 | + ], build) |
392 | + |
393 | + def test_partner_proposed(self): |
394 | + # The partner archive's PROPOSED pocket builds against itself, but |
395 | + # still uses the default UPDATES dependency for the primary archive |
396 | + # unless overridden by ArchiveDependency. |
397 | + primary, partner = self.ubuntu.all_distro_archives |
398 | + self.publisher.getPubBinaries( |
399 | + archive=partner, component="partner", |
400 | + status=PackagePublishingStatus.PUBLISHED) |
401 | + self.publisher.getPubBinaries( |
402 | + archive=partner, component="partner", |
403 | + status=PackagePublishingStatus.PUBLISHED, |
404 | + pocket=PackagePublishingPocket.PROPOSED) |
405 | + build = self.makeBuild( |
406 | + archive=partner, component="partner", |
407 | + pocket=PackagePublishingPocket.PROPOSED) |
408 | + self.assertSourcesList( |
409 | + [(partner, [ |
410 | + "hoary partner", |
411 | + "hoary-proposed partner", |
412 | + ]), |
413 | + (primary, [ |
414 | + "hoary main restricted universe multiverse", |
415 | + "hoary-security main restricted universe multiverse", |
416 | + "hoary-updates main restricted universe multiverse", |
417 | + ]), |
418 | + ], build) |
419 | + |
420 | + def test_archive_external_dependencies(self): |
421 | + # An archive can be manually given additional external dependencies. |
422 | + # If present, "%(series)s" is replaced with the series name for the |
423 | + # build being dispatched. |
424 | + ppa = self.makeArchive(publish_binary=True) |
425 | + ppa.external_dependencies = ( |
426 | + "deb http://user:pass@repository zoing everything\n" |
427 | + "deb http://user:pass@repository %(series)s public private\n" |
428 | + "deb http://user:pass@repository %(series)s-extra public") |
429 | + build = self.makeBuild(archive=ppa) |
430 | + self.assertSourcesList( |
431 | + [(ppa, ["hoary main"]), |
432 | + ("deb http://user:pass@repository", [ |
433 | + "zoing everything", |
434 | + "hoary public private", |
435 | + "hoary-extra public", |
436 | + ]), |
437 | + (self.ubuntu.main_archive, [ |
438 | + "hoary main restricted universe multiverse", |
439 | + "hoary-security main restricted universe multiverse", |
440 | + "hoary-updates main restricted universe multiverse", |
441 | + ]), |
442 | + ], build) |
443 | + |
444 | + def test_build_external_dependencies(self): |
445 | + # A single build can be manually given additional external |
446 | + # dependencies. |
447 | + ppa = self.makeArchive(publish_binary=True) |
448 | + build = self.makeBuild(archive=ppa) |
449 | + build.api_external_dependencies = ( |
450 | + "deb http://user:pass@repository foo bar") |
451 | + self.assertSourcesList( |
452 | + [(ppa, ["hoary main"]), |
453 | + ("deb http://user:pass@repository", ["foo bar"]), |
454 | + (self.ubuntu.main_archive, [ |
455 | + "hoary main restricted universe multiverse", |
456 | + "hoary-security main restricted universe multiverse", |
457 | + "hoary-updates main restricted universe multiverse", |
458 | + ]), |
459 | + ], build) |
460 | + |
461 | + def test_build_tools(self): |
462 | + # We can force an extra build tools line to be added to |
463 | + # sources.list, which is useful for specialised build types. |
464 | + ppa = self.makeArchive(publish_binary=True) |
465 | + build = self.makeBuild(archive=ppa) |
466 | + self.assertSourcesList( |
467 | + [(ppa, ["hoary main"]), |
468 | + ("deb http://example.org", ["hoary main"]), |
469 | + (self.ubuntu.main_archive, [ |
470 | + "hoary main restricted universe multiverse", |
471 | + "hoary-security main restricted universe multiverse", |
472 | + "hoary-updates main restricted universe multiverse", |
473 | + ]), |
474 | + ], build, tools_source="deb http://example.org %(series)s main") |
475 | + |
476 | + def test_build_tools_bad_formatting(self): |
477 | + # If tools_source is badly formatted, we log the error but don't |
478 | + # blow up. (Note the missing "s" at the end of "%(series)".) |
479 | + ppa = self.makeArchive(publish_binary=True) |
480 | + build = self.makeBuild(archive=ppa) |
481 | + logger = BufferLogger() |
482 | + self.assertSourcesList( |
483 | + [(ppa, ["hoary main"]), |
484 | + (self.ubuntu.main_archive, [ |
485 | + "hoary main restricted universe multiverse", |
486 | + "hoary-security main restricted universe multiverse", |
487 | + "hoary-updates main restricted universe multiverse", |
488 | + ]), |
489 | + ], |
490 | + build, tools_source="deb http://example.org %(series) main", |
491 | + logger=logger) |
492 | + self.assertThat(logger.getLogBuffer(), StartsWith( |
493 | + "ERROR Exception processing build tools sources.list entry:\n")) |
494 | + |
495 | + def test_overlay(self): |
496 | + # An overlay distroseries is a derived distribution which works like |
497 | + # a PPA. This means that the parent's details gets added to the |
498 | + # sources.list passed to the builders. |
499 | + depdistro = self.factory.makeDistribution( |
500 | + "depdistro", publish_base_url="http://archive.launchpad.dev/") |
501 | + depseries = self.factory.makeDistroSeries( |
502 | + distribution=depdistro, name="depseries") |
503 | + self.factory.makeDistroArchSeries( |
504 | + distroseries=depseries, architecturetag="i386") |
505 | + self.publisher.addFakeChroots(depseries) |
506 | + for component_name in self.ubuntu_components: |
507 | + component = getUtility(IComponentSet)[component_name] |
508 | + self.factory.makeComponentSelection(depseries, component) |
509 | + self.factory.makeDistroSeriesParent( |
510 | + derived_series=self.hoary, parent_series=depseries, |
511 | + initialized=True, is_overlay=True, |
512 | + pocket=PackagePublishingPocket.SECURITY, |
513 | + component=getUtility(IComponentSet)["universe"]) |
514 | + build = self.makeBuild() |
515 | + self.assertSourcesList( |
516 | + [(self.ubuntu.main_archive, ["hoary main"]), |
517 | + (depdistro.main_archive, [ |
518 | + "depseries main universe", |
519 | + "depseries-security main universe", |
520 | + ]), |
521 | + ], build) |
522 | |
523 | === removed file 'lib/lp/soyuz/doc/archive-dependencies.txt' |
524 | --- lib/lp/soyuz/doc/archive-dependencies.txt 2016-04-07 00:04:42 +0000 |
525 | +++ lib/lp/soyuz/doc/archive-dependencies.txt 1970-01-01 00:00:00 +0000 |
526 | @@ -1,637 +0,0 @@ |
527 | -= Archive dependencies = |
528 | - |
529 | -`ArchiveDependencies` class models archive dependencies mechanics and |
530 | -is used to provided the contents of 'sources_list' file used to build |
531 | -sources in the given IBuildQueue context. |
532 | - |
533 | - |
534 | -== Testing scenario setup == |
535 | - |
536 | -We use `SoyuzTestPublisher` to generate a source publications and |
537 | -build candidates for ubuntu/hoary. |
538 | - |
539 | - >>> from lp.registry.interfaces.distribution import IDistributionSet |
540 | - >>> from lp.soyuz.interfaces.component import IComponentSet |
541 | - >>> from lp.soyuz.tests.test_publishing import SoyuzTestPublisher |
542 | - >>> from lp.testing import login |
543 | - |
544 | - >>> login('foo.bar@canonical.com') |
545 | - |
546 | - >>> test_publisher = SoyuzTestPublisher() |
547 | - |
548 | - >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu') |
549 | - >>> hoary = ubuntu.getSeries('hoary') |
550 | - |
551 | - >>> test_publisher.addFakeChroots(hoary) |
552 | - >>> _ = test_publisher.setUpDefaultDistroSeries(hoary) |
553 | - |
554 | - >>> ubuntu_components = [ |
555 | - ... 'main', 'restricted', 'universe', 'multiverse', 'partner'] |
556 | - >>> for component_name in ubuntu_components: |
557 | - ... component = getUtility(IComponentSet)[component_name] |
558 | - ... if component not in hoary.components: |
559 | - ... _ = factory.makeComponentSelection(hoary, component) |
560 | - |
561 | - |
562 | -== Static dependency maps == |
563 | - |
564 | -`pocket_dependencies` contains a static map of the default ubuntu |
565 | -pocket dependencies. |
566 | - |
567 | - >>> from lp.soyuz.adapters.archivedependencies import pocket_dependencies |
568 | - |
569 | - >>> def show_pocket_deps(): |
570 | - ... print "Pocket | Dependencies" |
571 | - ... print "----------+---------------" |
572 | - ... for (key, value) in sorted(pocket_dependencies.items()): |
573 | - ... print "%7s |" % (key.name,), |
574 | - ... for pocket in value: |
575 | - ... print pocket.name, |
576 | |
577 | - |
578 | - >>> show_pocket_deps() |
579 | - Pocket | Dependencies |
580 | - ----------+--------------- |
581 | - RELEASE | RELEASE |
582 | - SECURITY | RELEASE SECURITY |
583 | - UPDATES | RELEASE SECURITY UPDATES |
584 | - PROPOSED | RELEASE SECURITY UPDATES PROPOSED |
585 | - BACKPORTS | RELEASE SECURITY UPDATES BACKPORTS |
586 | - |
587 | - |
588 | -== 'Ogre' components == |
589 | - |
590 | -The ubuntu 'ogre-model' ensures that build dependencies are |
591 | -consistently spread according to the source target component, i.e. a |
592 | -source published in 'main' component is only allowed to depend on |
593 | -binaries also published in 'main', on the other hand a source |
594 | -published in 'universe' is allowed to depend on binaries published in |
595 | -'main' and 'universe' components. |
596 | - |
597 | -A proper name for this "model" would be 'cross-component-dependency'. |
598 | - |
599 | - >>> from lp.services.database.sqlbase import flush_database_caches |
600 | - |
601 | - >>> from zope.security.proxy import removeSecurityProxy |
602 | - >>> from lp.registry.interfaces.pocket import ( |
603 | - ... PackagePublishingPocket) |
604 | - >>> from lp.soyuz.adapters.archivedependencies import ( |
605 | - ... get_components_for_context) |
606 | - >>> from lp.soyuz.enums import ArchivePurpose |
607 | - |
608 | - >>> def testOgreComponents(build): |
609 | - ... print " Component | Ogre-Model" |
610 | - ... print "-----------+---------------" |
611 | - ... for component in ubuntu_components: |
612 | - ... component = getUtility(IComponentSet)[component] |
613 | - ... npub = removeSecurityProxy(build.current_source_publication) |
614 | - ... npub.component = component |
615 | - ... flush_database_caches() |
616 | - ... components_term = " ".join(get_components_for_context( |
617 | - ... build.current_component, build.distro_series, |
618 | - ... build.pocket)) |
619 | - ... print '%10s | %s' % (build.current_component.name, |
620 | - ... components_term) |
621 | - |
622 | - >>> archive = factory.makeArchive( |
623 | - ... distribution=ubuntu, purpose=ArchivePurpose.PRIMARY) |
624 | - >>> ogre_build = factory.makeBinaryPackageBuild( |
625 | - ... distroarchseries=hoary.architectures[0], archive=archive, |
626 | - ... pocket=PackagePublishingPocket.RELEASE) |
627 | - >>> testOgreComponents(ogre_build) |
628 | - Component | Ogre-Model |
629 | - -----------+--------------- |
630 | - main | main |
631 | - restricted | main restricted |
632 | - universe | main universe |
633 | - multiverse | main restricted universe multiverse |
634 | - partner | partner |
635 | - |
636 | -Series with strict_supported_component_dependencies=False additionally allow |
637 | -source packages in 'supported' components (main and restricted) to |
638 | -build-depend on binary packages in 'unsupported' components (universe and |
639 | -multiverse). |
640 | - |
641 | - >>> from lp.buildmaster.interfaces.processor import IProcessorSet |
642 | - |
643 | - >>> lax_distroseries = factory.makeDistroSeries( |
644 | - ... distribution=archive.distribution, name='lax') |
645 | - >>> lax_distroseries.strict_supported_component_dependencies = False |
646 | - >>> lax_distroarchseries = factory.makeDistroArchSeries( |
647 | - ... distroseries=lax_distroseries, architecturetag='i386', |
648 | - ... processor=getUtility(IProcessorSet).getByName('386')) |
649 | - >>> test_publisher.addFakeChroots(lax_distroseries) |
650 | - >>> for component_name in ubuntu_components: |
651 | - ... component = getUtility(IComponentSet)[component_name] |
652 | - ... _ = factory.makeComponentSelection(lax_distroseries, component) |
653 | - >>> lax_ogre_build = factory.makeBinaryPackageBuild( |
654 | - ... distroarchseries=lax_distroarchseries, archive=archive, |
655 | - ... pocket=PackagePublishingPocket.RELEASE) |
656 | - >>> testOgreComponents(lax_ogre_build) |
657 | - Component | Ogre-Model |
658 | - -----------+--------------- |
659 | - main | main universe |
660 | - restricted | main restricted universe multiverse |
661 | - universe | main universe |
662 | - multiverse | main restricted universe multiverse |
663 | - partner | partner |
664 | - |
665 | -As fixed for bug #198936, builds for the BACKPORTS pocket are allowed |
666 | -to use any component available, independently of the component they |
667 | -are currently published. This special-case is important because it |
668 | -avoids changes to accommodate the backported source in the already |
669 | -released series. |
670 | - |
671 | -Ultimately, it means that a build targeted to the BACKPORTS pocket |
672 | -will behave as if it were published in the multiverse component, |
673 | -despite the component it is actually published in. |
674 | - |
675 | - >>> back_build = factory.makeBinaryPackageBuild( |
676 | - ... distroarchseries=hoary.architectures[0], |
677 | - ... archive=archive, pocket=PackagePublishingPocket.BACKPORTS) |
678 | - >>> testOgreComponents(back_build) |
679 | - Component | Ogre-Model |
680 | - -----------+--------------- |
681 | - main | main restricted universe multiverse |
682 | - restricted | main restricted universe multiverse |
683 | - universe | main restricted universe multiverse |
684 | - multiverse | main restricted universe multiverse |
685 | - partner | main restricted universe multiverse |
686 | - |
687 | - |
688 | -== Sources.list contents for building == |
689 | - |
690 | -We will use Celso's PPA for testing these mechanisms. |
691 | - |
692 | - >>> from lp.registry.interfaces.person import IPersonSet |
693 | - >>> cprov = getUtility(IPersonSet).getByName('cprov') |
694 | - >>> print cprov.archive.displayname |
695 | - PPA for Celso Providelo |
696 | - |
697 | -Non-primary archives by default use primary Release, Security and Updates |
698 | -pockets and all its available components. |
699 | - |
700 | - >>> from lp.soyuz.adapters.archivedependencies import ( |
701 | - ... default_component_dependency_name, default_pocket_dependency) |
702 | - |
703 | - >>> print default_pocket_dependency |
704 | - Updates |
705 | - |
706 | - >>> print default_component_dependency_name |
707 | - multiverse |
708 | - |
709 | -The default values get applied to their corresponding dependency maps |
710 | -and then will expand to distinct values that will be used to produce |
711 | -the building 'sources_list' contents. |
712 | - |
713 | - >>> for pocket in pocket_dependencies[default_pocket_dependency]: |
714 | - ... print pocket |
715 | - Release |
716 | - Security |
717 | - Updates |
718 | - |
719 | - >>> for component_name in get_components_for_context( |
720 | - ... getUtility(IComponentSet)[default_component_dependency_name], |
721 | - ... hoary, pocket): |
722 | - ... print component_name |
723 | - main |
724 | - restricted |
725 | - universe |
726 | - multiverse |
727 | - |
728 | -We will create a testing source publication and probe its build |
729 | -environment. |
730 | - |
731 | - >>> pub_source = test_publisher.getPubSource( |
732 | - ... version='1.1', archive=cprov.archive) |
733 | - >>> [a_build] = pub_source.createMissingBuilds() |
734 | - |
735 | -Now we can verify if get_sources_list_for_building() method returns the |
736 | -expected content for building the just-created source. |
737 | - |
738 | - >>> from lp.soyuz.adapters.archivedependencies import ( |
739 | - ... get_sources_list_for_building) |
740 | - |
741 | - >>> def print_building_sources_list(candidate): |
742 | - ... sources_list = get_sources_list_for_building( |
743 | - ... candidate, candidate.distro_arch_series, |
744 | - ... candidate.source_package_release.name) |
745 | - ... for line in sources_list: |
746 | - ... print line |
747 | - |
748 | -Note that only the default ubuntu dependencies for a public PPA will be |
749 | -considered when building the source candidate. That's because there is |
750 | -no binary published in Celso's PPA hoary/i386, so there is |
751 | -no need to request the builder to load its archive indexes. |
752 | - |
753 | - >>> from lp.soyuz.enums import PackagePublishingStatus |
754 | - |
755 | - >>> cprov.archive.getAllPublishedBinaries( |
756 | - ... distroarchseries=a_build.distro_arch_series, |
757 | - ... status=PackagePublishingStatus.PUBLISHED).count() |
758 | - 0 |
759 | - |
760 | - >>> print_building_sources_list(a_build) |
761 | - deb http://archive.launchpad.dev/ubuntu hoary |
762 | - main restricted universe multiverse |
763 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
764 | - main restricted universe multiverse |
765 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
766 | - main restricted universe multiverse |
767 | - |
768 | -Once we publish a test binary in Celso's PPA hoary/i386, |
769 | -this archive becomes relevant for building, and thus listed in the |
770 | -returned 'sources_list' content. |
771 | - |
772 | - >>> pub_binaries = test_publisher.getPubBinaries( |
773 | - ... binaryname='dep-bin', archive=cprov.archive, |
774 | - ... status=PackagePublishingStatus.PUBLISHED) |
775 | - |
776 | - >>> print_building_sources_list(a_build) |
777 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
778 | - deb http://archive.launchpad.dev/ubuntu hoary |
779 | - main restricted universe multiverse |
780 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
781 | - main restricted universe multiverse |
782 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
783 | - main restricted universe multiverse |
784 | - |
785 | -Similarly, unpopulated PPA dependencies are *not* listed in the building |
786 | -'sources_list'. |
787 | - |
788 | - >>> mark = getUtility(IPersonSet).getByName('mark') |
789 | - >>> archive_dependency = cprov.archive.addArchiveDependency( |
790 | - ... mark.archive, PackagePublishingPocket.RELEASE, |
791 | - ... getUtility(IComponentSet)['main']) |
792 | - >>> print_building_sources_list(a_build) |
793 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
794 | - deb http://archive.launchpad.dev/ubuntu hoary |
795 | - main restricted universe multiverse |
796 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
797 | - main restricted universe multiverse |
798 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
799 | - main restricted universe multiverse |
800 | - |
801 | -But *populated* PPA dependencies *are* listed in the building 'sources_list'. |
802 | - |
803 | - >>> pub_binaries = test_publisher.getPubBinaries( |
804 | - ... binaryname='dep-bin', archive=mark.archive, |
805 | - ... status=PackagePublishingStatus.PUBLISHED) |
806 | - >>> print_building_sources_list(a_build) |
807 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
808 | - deb http://ppa.launchpad.dev/mark/ppa/ubuntu hoary main |
809 | - deb http://archive.launchpad.dev/ubuntu hoary |
810 | - main restricted universe multiverse |
811 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
812 | - main restricted universe multiverse |
813 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
814 | - main restricted universe multiverse |
815 | - |
816 | -Dependencies for series with strict_supported_component_dependencies=False |
817 | -are reasonable too. PPAs only have the 'main' component. |
818 | - |
819 | - >>> lax_pub_source = test_publisher.getPubSource( |
820 | - ... version='1.2', distroseries=lax_distroseries, |
821 | - ... archive=cprov.archive) |
822 | - >>> [lax_build] = lax_pub_source.createMissingBuilds() |
823 | - >>> _ = test_publisher.getPubBinaries( |
824 | - ... binaryname='dep-bin', distroseries=lax_distroseries, |
825 | - ... archive=cprov.archive, status=PackagePublishingStatus.PUBLISHED) |
826 | - >>> _ = test_publisher.getPubBinaries( |
827 | - ... binaryname='dep-bin', distroseries=lax_distroseries, |
828 | - ... archive=mark.archive, status=PackagePublishingStatus.PUBLISHED) |
829 | - >>> print_building_sources_list(lax_build) |
830 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu lax main |
831 | - deb http://ppa.launchpad.dev/mark/ppa/ubuntu lax main |
832 | - deb http://archive.launchpad.dev/ubuntu lax |
833 | - main restricted universe multiverse |
834 | - deb http://archive.launchpad.dev/ubuntu lax-security |
835 | - main restricted universe multiverse |
836 | - deb http://archive.launchpad.dev/ubuntu lax-updates |
837 | - main restricted universe multiverse |
838 | - |
839 | - >>> cprov.archive.removeArchiveDependency(mark.archive) |
840 | - |
841 | -What when we supply invalid dependencies, an exception is raised. |
842 | - |
843 | - >>> cprov.archive.external_dependencies = ( |
844 | - ... "Malformed format string here --> %(series)") |
845 | - Traceback (most recent call last): |
846 | - InvalidExternalDependencies: (InvalidExternalDependencies(...), |
847 | - "Invalid external dependencies:\nMalformed format string here |
848 | - --> %(series): Must start with 'deb'\nMalformed format string here |
849 | - --> %(series): Invalid URL\n") |
850 | - |
851 | - |
852 | -== Overriding default primary archive dependencies == |
853 | - |
854 | -Despite being private or public, default primary archive dependencies |
855 | -can be overridden by simply creating a `ArchiveDependency`record |
856 | -targeted to the primary archive. |
857 | - |
858 | -The 'pocket' and 'component' dependency attributes can be adjusted to |
859 | -produce the desired build behaviour. |
860 | - |
861 | -By default, public PPAs depend on all of the pocket dependencies of |
862 | -UPDATES, and all of the primary archive's 'multiverse' component |
863 | -dependencies. |
864 | - |
865 | - >>> print_building_sources_list(a_build) |
866 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
867 | - deb http://archive.launchpad.dev/ubuntu hoary |
868 | - main restricted universe multiverse |
869 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
870 | - main restricted universe multiverse |
871 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
872 | - main restricted universe multiverse |
873 | - |
874 | -The default build behaviour will remain unchanged when we override the |
875 | -default primary archive dependencies with exactly the same values. |
876 | - |
877 | - >>> default_dependency = cprov.archive.addArchiveDependency( |
878 | - ... ubuntu.main_archive, PackagePublishingPocket.UPDATES, |
879 | - ... getUtility(IComponentSet)['multiverse']) |
880 | - |
881 | - >>> print_building_sources_list(a_build) |
882 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
883 | - deb http://archive.launchpad.dev/ubuntu hoary |
884 | - main restricted universe multiverse |
885 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
886 | - main restricted universe multiverse |
887 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
888 | - main restricted universe multiverse |
889 | - |
890 | - >>> cprov.archive.removeArchiveDependency(ubuntu.main_archive) |
891 | - |
892 | -The dependency can be modified to behave as an embargoed archive that |
893 | -builds security updates. This is done by setting the SECURITY pocket |
894 | -dependencies (RELEASE and SECURITY) and following the component |
895 | -dependencies of the component where the source was last published in |
896 | -the primary archive. |
897 | - |
898 | - >>> security_dependency = cprov.archive.addArchiveDependency( |
899 | - ... ubuntu.main_archive, PackagePublishingPocket.SECURITY) |
900 | - |
901 | - >>> from lp.soyuz.adapters.archivedependencies import ( |
902 | - ... get_primary_current_component) |
903 | - |
904 | - >>> print get_primary_current_component(a_build.archive, |
905 | - ... a_build.distro_series, a_build.source_package_release.name).name |
906 | - universe |
907 | - |
908 | - >>> print_building_sources_list(a_build) |
909 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
910 | - deb http://archive.launchpad.dev/ubuntu hoary |
911 | - main universe |
912 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
913 | - main universe |
914 | - |
915 | - >>> _ = test_publisher.getPubSource( |
916 | - ... sourcename='with-ancestry', version='1.0', |
917 | - ... archive=ubuntu.main_archive) |
918 | - >>> [build_with_ancestry] = test_publisher.getPubSource( |
919 | - ... sourcename='with-ancestry', version='1.1', |
920 | - ... archive=cprov.archive).createMissingBuilds() |
921 | - >>> print get_primary_current_component( |
922 | - ... build_with_ancestry.archive, build_with_ancestry.distro_series, |
923 | - ... build_with_ancestry.source_package_release.name).name |
924 | - main |
925 | - >>> print_building_sources_list(build_with_ancestry) |
926 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
927 | - deb http://archive.launchpad.dev/ubuntu hoary main |
928 | - deb http://archive.launchpad.dev/ubuntu hoary-security main |
929 | - |
930 | - >>> cprov.archive.removeArchiveDependency(ubuntu.main_archive) |
931 | - |
932 | -It's also possible to modify the PPA to act as a super-free and |
933 | -pristine build environment based only on what was included in the |
934 | -original ubuntu release. |
935 | - |
936 | - >>> release_dependency = cprov.archive.addArchiveDependency( |
937 | - ... ubuntu.main_archive, PackagePublishingPocket.RELEASE, |
938 | - ... getUtility(IComponentSet)['restricted']) |
939 | - |
940 | - >>> print_building_sources_list(a_build) |
941 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
942 | - deb http://archive.launchpad.dev/ubuntu hoary main restricted |
943 | - |
944 | - >>> cprov.archive.removeArchiveDependency(ubuntu.main_archive) |
945 | - |
946 | -The PPA can also be configured to extend the ubuntu PROPOSED build |
947 | -environment. |
948 | - |
949 | - >>> proposed_dependency = cprov.archive.addArchiveDependency( |
950 | - ... ubuntu.main_archive, PackagePublishingPocket.PROPOSED, |
951 | - ... getUtility(IComponentSet)['multiverse']) |
952 | - |
953 | - >>> print_building_sources_list(a_build) |
954 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
955 | - deb http://archive.launchpad.dev/ubuntu hoary |
956 | - main restricted universe multiverse |
957 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
958 | - main restricted universe multiverse |
959 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
960 | - main restricted universe multiverse |
961 | - deb http://archive.launchpad.dev/ubuntu hoary-proposed |
962 | - main restricted universe multiverse |
963 | - |
964 | - >>> cprov.archive.removeArchiveDependency(ubuntu.main_archive) |
965 | - |
966 | -Similarly an extension of the BACKPORTS environment can be set. |
967 | - |
968 | - >>> backports_dependency = cprov.archive.addArchiveDependency( |
969 | - ... ubuntu.main_archive, PackagePublishingPocket.BACKPORTS, |
970 | - ... getUtility(IComponentSet)['multiverse']) |
971 | - |
972 | - >>> print_building_sources_list(a_build) |
973 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
974 | - deb http://archive.launchpad.dev/ubuntu hoary |
975 | - main restricted universe multiverse |
976 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
977 | - main restricted universe multiverse |
978 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
979 | - main restricted universe multiverse |
980 | - deb http://archive.launchpad.dev/ubuntu hoary-backports |
981 | - main restricted universe multiverse |
982 | - |
983 | - >>> cprov.archive.removeArchiveDependency(ubuntu.main_archive) |
984 | - |
985 | - |
986 | -== Partner archive builds == |
987 | - |
988 | -Similarly to what happens with PPA builds, PARTNER builds may depend |
989 | -on any Ubuntu component in the PRIMARY archive. This behaviour allows |
990 | -scenarios where partner packages may use other restricted/non-free |
991 | -applications from 'multiverse', for instance 'sun-java', and also |
992 | -other partner applications by default. |
993 | - |
994 | - # Populate the ubuntutest PARTNER archive with one built and one |
995 | - # pending build source. |
996 | - >>> primary, partner = ubuntu.all_distro_archives |
997 | - >>> unused_source = test_publisher.getPubSource( |
998 | - ... archive=partner, component='partner') |
999 | - >>> unused = test_publisher.getPubBinaries( |
1000 | - ... pub_source=unused_source, |
1001 | - ... status=PackagePublishingStatus.PUBLISHED) |
1002 | - >>> pub_source = test_publisher.getPubSource( |
1003 | - ... version='1.2', archive=partner, component='partner') |
1004 | - >>> [partner_build] = pub_source.createMissingBuilds() |
1005 | - |
1006 | - >>> print_building_sources_list(partner_build) |
1007 | - deb http://archive.launchpad.dev/ubuntu-partner hoary partner |
1008 | - deb http://archive.launchpad.dev/ubuntu hoary |
1009 | - main restricted universe multiverse |
1010 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
1011 | - main restricted universe multiverse |
1012 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
1013 | - main restricted universe multiverse |
1014 | - |
1015 | -PARTNER's PROPOSED pocket builds against itself, but still uses the |
1016 | -default UPDATES dependency for PRIMARY unless overridden by |
1017 | -ArchiveDependency. |
1018 | - |
1019 | - >>> proposed_source = test_publisher.getPubSource( |
1020 | - ... version='1.2', archive=partner, component='partner', |
1021 | - ... pocket=PackagePublishingPocket.PROPOSED) |
1022 | - >>> unused = test_publisher.getPubBinaries( |
1023 | - ... archive=partner, distroseries=proposed_source.distroseries, |
1024 | - ... pocket=PackagePublishingPocket.PROPOSED, |
1025 | - ... status=PackagePublishingStatus.PUBLISHED) |
1026 | - >>> [partner_proposed_build] = proposed_source.createMissingBuilds() |
1027 | - |
1028 | - >>> print_building_sources_list(partner_proposed_build) |
1029 | - deb http://archive.launchpad.dev/ubuntu-partner hoary partner |
1030 | - deb http://archive.launchpad.dev/ubuntu-partner hoary-proposed partner |
1031 | - deb http://archive.launchpad.dev/ubuntu hoary |
1032 | - main restricted universe multiverse |
1033 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
1034 | - main restricted universe multiverse |
1035 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
1036 | - main restricted universe multiverse |
1037 | - |
1038 | -== External build dependencies == |
1039 | - |
1040 | -Via an administrator change, any PPA hosted in launchpad can be |
1041 | -assigned to one or more 'external' build dependencies additionally to |
1042 | -the internal ones. |
1043 | - |
1044 | -There is a column on IArchive called 'external_dependencies' which can be set |
1045 | -for any hosted PPA. It is a string listing the comma-separated external |
1046 | -dependencies in the debian sources_list format. |
1047 | - |
1048 | - deb http[s]://[user:pass@]<host>[/path] %(series)s[-pocket] [components] |
1049 | - |
1050 | -The '%(series)s' part is optional and will be replaced on-the-fly with |
1051 | -the series name for the build record being dispatched. |
1052 | - |
1053 | -We will create some dependencies for Celso's PPA. |
1054 | - |
1055 | - >>> cprov.archive.external_dependencies = ( |
1056 | - ... "deb http://user:pass@repository zoing everything\n" |
1057 | - ... "deb http://user:pass@repository %(series)s public private\n" |
1058 | - ... "deb http://user:pass@repository %(series)s-extra public") |
1059 | - |
1060 | -Now builds in Celso's PPA will use the external dependencies. |
1061 | - |
1062 | - >>> print_building_sources_list(a_build) |
1063 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
1064 | - deb http://user:pass@repository zoing everything |
1065 | - deb http://user:pass@repository hoary public private |
1066 | - deb http://user:pass@repository hoary-extra public |
1067 | - deb http://archive.launchpad.dev/ubuntu hoary |
1068 | - main restricted universe multiverse |
1069 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
1070 | - main restricted universe multiverse |
1071 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
1072 | - main restricted universe multiverse |
1073 | - |
1074 | - >>> cprov.archive.external_dependencies = None |
1075 | - |
1076 | -We can also set external dependencies for a single build. |
1077 | - |
1078 | - >>> a_build.api_external_dependencies = ( |
1079 | - ... u"deb http://user:pass@repository foo bar") |
1080 | - >>> print_building_sources_list(a_build) |
1081 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
1082 | - deb http://user:pass@repository foo bar |
1083 | - deb http://archive.launchpad.dev/ubuntu hoary |
1084 | - main restricted universe multiverse |
1085 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
1086 | - main restricted universe multiverse |
1087 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
1088 | - main restricted universe multiverse |
1089 | - >>> a_build.api_external_dependencies = None |
1090 | - |
1091 | - |
1092 | -== Build tools sources.list entries == |
1093 | - |
1094 | -We can force an extra build tools line to be added to the sources.list, |
1095 | -which is useful for specialised build types. |
1096 | - |
1097 | - >>> for line in get_sources_list_for_building( |
1098 | - ... a_build, a_build.distro_arch_series, |
1099 | - ... a_build.source_package_release.name, |
1100 | - ... tools_source="deb http://example.org %(series)s main"): |
1101 | - ... print line |
1102 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
1103 | - deb http://example.org hoary main |
1104 | - deb http://archive.launchpad.dev/ubuntu hoary |
1105 | - main restricted universe multiverse |
1106 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
1107 | - main restricted universe multiverse |
1108 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
1109 | - main restricted universe multiverse |
1110 | - |
1111 | -If tools_source is badly formatted, we log the error but don't blow up. |
1112 | -(Note the missing "s" at the end of "%(series)".) |
1113 | - |
1114 | - >>> from lp.services.log.logger import BufferLogger |
1115 | - >>> logger = BufferLogger() |
1116 | - >>> for line in get_sources_list_for_building( |
1117 | - ... a_build, a_build.distro_arch_series, |
1118 | - ... a_build.source_package_release.name, |
1119 | - ... tools_source="deb http://example.org %(series) main", |
1120 | - ... logger=logger): |
1121 | - ... print line |
1122 | - deb http://ppa.launchpad.dev/cprov/ppa/ubuntu hoary main |
1123 | - deb http://archive.launchpad.dev/ubuntu hoary |
1124 | - main restricted universe multiverse |
1125 | - deb http://archive.launchpad.dev/ubuntu hoary-security |
1126 | - main restricted universe multiverse |
1127 | - deb http://archive.launchpad.dev/ubuntu hoary-updates |
1128 | - main restricted universe multiverse |
1129 | - >>> print logger.getLogBuffer() |
1130 | - ERROR Exception processing build tools sources.list entry: |
1131 | - ... |
1132 | - |
1133 | - |
1134 | -== Overlays == |
1135 | - |
1136 | -An overlay distroseries is a derived distribution which works like a PPA. |
1137 | -This means that the parent's details gets added to the sources.list passed to |
1138 | -the builders. |
1139 | - |
1140 | - >>> depdistro = factory.makeDistribution('depdistro', |
1141 | - ... publish_base_url=u'http://archive.launchpad.dev/') |
1142 | - >>> depseries = factory.makeDistroSeries( |
1143 | - ... name='depseries', distribution=depdistro) |
1144 | - >>> deparchseries = factory.makeDistroArchSeries( |
1145 | - ... distroseries = depseries, architecturetag = 'i386') |
1146 | - >>> test_publisher.addFakeChroots(depseries) |
1147 | - >>> for component_name in ubuntu_components: |
1148 | - ... component = getUtility(IComponentSet)[component_name] |
1149 | - ... _ = factory.makeComponentSelection(depseries, component) |
1150 | - >>> universe_component = getUtility(IComponentSet)['universe'] |
1151 | - >>> dsp = factory.makeDistroSeriesParent( |
1152 | - ... derived_series=hoary, parent_series=depseries, |
1153 | - ... initialized=True, is_overlay=True, |
1154 | - ... pocket=PackagePublishingPocket.SECURITY, |
1155 | - ... component=universe_component) |
1156 | - >>> pub_source = test_publisher.getPubSource( |
1157 | - ... version='1.1', archive=hoary.main_archive) |
1158 | - >>> [hoary_build] = pub_source.createMissingBuilds() |
1159 | - >>> print_building_sources_list(hoary_build) |
1160 | - deb http://archive.launchpad.dev/ubuntu hoary main |
1161 | - deb http://archive.launchpad.dev/depdistro depseries main universe |
1162 | - deb http://archive.launchpad.dev/depdistro depseries-security |
1163 | - main universe |
1164 | |
1165 | === modified file 'lib/lp/soyuz/interfaces/archive.py' |
1166 | --- lib/lp/soyuz/interfaces/archive.py 2016-11-14 19:55:07 +0000 |
1167 | +++ lib/lp/soyuz/interfaces/archive.py 2017-04-25 11:47:06 +0000 |
1168 | @@ -1,4 +1,4 @@ |
1169 | -# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
1170 | +# Copyright 2009-2017 Canonical Ltd. This software is licensed under the |
1171 | # GNU Affero General Public License version 3 (see the file LICENSE). |
1172 | |
1173 | """Archive interfaces.""" |
1174 | @@ -306,7 +306,7 @@ |
1175 | |
1176 | def __init__(self, errors): |
1177 | error_msg = 'Invalid external dependencies:\n%s\n' % '\n'.join(errors) |
1178 | - super(Exception, self).__init__(self, error_msg) |
1179 | + super(Exception, self).__init__(error_msg) |
1180 | self.errors = errors |
1181 | |
1182 | |
1183 | |
1184 | === modified file 'lib/lp/soyuz/tests/test_archive.py' |
1185 | --- lib/lp/soyuz/tests/test_archive.py 2016-11-07 16:42:23 +0000 |
1186 | +++ lib/lp/soyuz/tests/test_archive.py 2017-04-25 11:47:06 +0000 |
1187 | @@ -1,4 +1,4 @@ |
1188 | -# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
1189 | +# Copyright 2009-2017 Canonical Ltd. This software is licensed under the |
1190 | # GNU Affero General Public License version 3 (see the file LICENSE). |
1191 | |
1192 | """Test Archive features.""" |
1193 | @@ -78,6 +78,7 @@ |
1194 | DuplicateTokenName, |
1195 | IArchiveSet, |
1196 | InsufficientUploadRights, |
1197 | + InvalidExternalDependencies, |
1198 | InvalidPocketForPartnerArchive, |
1199 | InvalidPocketForPPA, |
1200 | NAMED_AUTH_TOKEN_FEATURE_FLAG, |
1201 | @@ -1767,6 +1768,18 @@ |
1202 | "person-name-.*/dependency/ubuntu distroseries-.* main") |
1203 | self.assertThat(sources_list[0], matches) |
1204 | |
1205 | + def test_invalid_external_dependencies(self): |
1206 | + """Trying to set invalid external dependencies raises an exception.""" |
1207 | + ppa = self.factory.makeArchive() |
1208 | + self.assertRaisesWithContent( |
1209 | + InvalidExternalDependencies, |
1210 | + "Invalid external dependencies:\n" |
1211 | + "Malformed format string here --> %(series): " |
1212 | + "Must start with 'deb'\n" |
1213 | + "Malformed format string here --> %(series): Invalid URL\n", |
1214 | + setattr, ppa, "external_dependencies", |
1215 | + "Malformed format string here --> %(series)") |
1216 | + |
1217 | |
1218 | class TestFindDepCandidates(TestCaseWithFactory): |
1219 | """Tests for Archive.findDepCandidates.""" |
1220 | |
1221 | === modified file 'lib/lp/testing/factory.py' |
1222 | --- lib/lp/testing/factory.py 2016-12-02 12:04:11 +0000 |
1223 | +++ lib/lp/testing/factory.py 2017-04-25 11:47:06 +0000 |
1224 | @@ -2,7 +2,7 @@ |
1225 | # NOTE: The first line above must stay first; do not move the copyright |
1226 | # notice to the top. See http://www.python.org/dev/peps/pep-0263/. |
1227 | # |
1228 | -# Copyright 2009-2016 Canonical Ltd. This software is licensed under the |
1229 | +# Copyright 2009-2017 Canonical Ltd. This software is licensed under the |
1230 | # GNU Affero General Public License version 3 (see the file LICENSE). |
1231 | |
1232 | """Testing infrastructure for the Launchpad application. |
1233 | @@ -268,7 +268,10 @@ |
1234 | ) |
1235 | from lp.services.oauth.interfaces import IOAuthConsumerSet |
1236 | from lp.services.openid.model.openididentifier import OpenIdIdentifier |
1237 | -from lp.services.propertycache import clear_property_cache |
1238 | +from lp.services.propertycache import ( |
1239 | + clear_property_cache, |
1240 | + get_property_cache, |
1241 | + ) |
1242 | from lp.services.temporaryblobstorage.interfaces import ( |
1243 | ITemporaryStorageManager, |
1244 | ) |
1245 | @@ -2832,8 +2835,10 @@ |
1246 | if not IComponent.providedBy(component): |
1247 | component = self.makeComponent(component) |
1248 | |
1249 | - return ComponentSelection( |
1250 | + selection = ComponentSelection( |
1251 | distroseries=distroseries, component=component) |
1252 | + del get_property_cache(distroseries).components |
1253 | + return selection |
1254 | |
1255 | def makeArchive(self, distribution=None, owner=None, name=None, |
1256 | purpose=None, enabled=True, private=False, |