~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
     DOCTESTS SUCK! PLEASE DO NOT ADD TO THIS DOCTEST, SEE
     lib/lp/soyuz/tests/test_sourcepackagerelease.py instead and consider
     migrating tests from here to there.


= Creating & Looking for Build records =

ISourcePackageRelease has the ability to create Build records,
however it needs external support to treat architecturehintlist and
Package-architecture-specific (P-a-s) information, see further
information in buildd-queuebuilder.txt.

ISourcePackageRelease also provides a 'getBuildByArch' method which
allows the application to lookup for Build records in a given
DistroArchSeries and Archive.

To demonstrate this we need to define some variables.

    >>> from zope.component import getUtility
    >>> from lp.services.librarian.interfaces import ILibraryFileAliasSet
    >>> from lp.registry.interfaces.distribution import IDistributionSet

    >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
    >>> hoary = ubuntu.getSeries('hoary')

Retrieve hoary/i386 and hoary/hppa `DistroArchSeries.

    >>> hoary_i386 = hoary['i386']
    >>> hoary_hppa = hoary['hppa']

    >>> fake_chroot = getUtility(ILibraryFileAliasSet)[1]
    >>> trash = hoary_i386.addOrUpdateChroot(fake_chroot)
    >>> trash = hoary_hppa.addOrUpdateChroot(fake_chroot)

    >>> from lp.registry.interfaces.person import IPersonSet
    >>> cprov = getUtility(IPersonSet).getByName('cprov')

    >>> from lp.registry.interfaces.pocket import (
    ...    PackagePublishingPocket)
    >>> pocket_release = PackagePublishingPocket.RELEASE

The base method createBuild() is able to create a build to a given
distro_arch_series, pocket and archive.

Build.status, by default is set to NEEDSBUILD, but you can
optionally provide another status.

    >>> hoary_evo_source = hoary.getSourcePackage('evolution')
    >>> evo_release = hoary_evo_source['1.0'].sourcepackagerelease

    >>> from lp.buildmaster.enums import BuildStatus
    >>> evo_build_i386 = evo_release.createBuild(
    ...     hoary_i386, pocket_release, ubuntu.main_archive,
    ...     status=BuildStatus.FULLYBUILT)

    >>> print evo_build_i386.status.name
    FULLYBUILT

    >>> evo_build_i386.distro_arch_series.architecturetag
    u'i386'

    >>> print evo_build_i386.archive.displayname
    Primary Archive for Ubuntu Linux

The build record can be retrieved via getBuildByArch on hoary/i386
architecture.

    >>> test_build_i386 = evo_release.getBuildByArch(
    ...     hoary_i386, ubuntu.main_archive)
    >>> test_build_i386 == evo_build_i386
    True

However a hoary/hppa build is not available.

    >>> test_build_hppa = evo_release.getBuildByArch(
    ...     hoary_hppa, ubuntu.main_archive)
    >>> print test_build_hppa
    None


== Sources inherited during distroseries initialization ==

We will copy the evolution source to ubuntu/breezy-autotest as if it
was inherited in the initialization.

    >>> breezy_autotest = ubuntu.getSeries('breezy-autotest')
    >>> breezy_autotest_i386 = breezy_autotest['i386']

    >>> print breezy_autotest.previous_series.title
    The Hoary Hedgehog Release

    >>> hoary_evo_release = hoary_evo_source['1.0']
    >>> copied_pub = hoary_evo_release.current_published.copyTo(
    ...     breezy_autotest, pocket_release, breezy_autotest.main_archive)

    >>> breezy_autotest_evo_source = breezy_autotest.getSourcePackage(
    ...     'evolution')
    >>> breezy_autotest_evo_release = breezy_autotest_evo_source['1.0']
    >>> evo_release == breezy_autotest_evo_release.sourcepackagerelease
    True

Since evolution source was already built on ubuntu/hoary/i386, the
parent series, it should be found by a build lookup happening on
ubuntu/breezy-autotest/i386.

In practical terms it means that another build is not necessary in
this context.

    >>> breezy_autotest_build = evo_release.getBuildByArch(
    ...     breezy_autotest_i386, ubuntu.main_archive)
    >>> print breezy_autotest_build.title
    i386 build of evolution 1.0 in ubuntu hoary RELEASE


== Sources with architecture-independent and specific binaries ==

Even if the source package builds an architecture-independent package,
no Build record will be returned by getBuildByArch() if arch-specific
binary packages were not built (see bug #65712 for further
information).

In order to be independent of the sampledata we will use the
SoyuzTestPublisher helper to create fake but complete publication for
this test.

    >>> from lp.soyuz.enums import (
    ...    PackagePublishingStatus)
    >>> from lp.soyuz.tests.test_publishing import (
    ...     SoyuzTestPublisher)

    >>> test_publisher = SoyuzTestPublisher()

    >>> name16 = getUtility(IPersonSet).getByName('name16')
    >>> test_publisher.person = name16

Let's create and publish a source which produces an
architecture-independent binary.

    >>> foo_pub_src = test_publisher.getPubSource(
    ...     version="1.0", architecturehintlist='all',
    ...     distroseries=hoary, archive=ubuntu.main_archive,
    ...     status=PackagePublishingStatus.PUBLISHED)

    >>> foo_pub_binaries = test_publisher.getPubBinaries(
    ...     distroseries=hoary, pub_source=foo_pub_src,
    ...     status=PackagePublishingStatus.PUBLISHED)

The build record for foo in hoary/i386 was created.

    >>> test_build_i386 = foo_pub_src.sourcepackagerelease.getBuildByArch(
    ...     hoary_i386, ubuntu.main_archive)
    >>> print test_build_i386.title
    i386 build of foo 1.0 in ubuntu hoary RELEASE

And despite of having a architecture-independent binary published in
hoary hppa, the build lookup in this architecture returns None, i.e,
the build doesn't exist.

    >>> for pub in foo_pub_binaries:
    ...     print pub.displayname
    foo-bin 1.0 in hoary i386
    foo-bin 1.0 in hoary hppa

    >>> test_build_hppa = foo_pub_src.sourcepackagerelease.getBuildByArch(
    ...     hoary_hppa, ubuntu.main_archive)
    >>> print test_build_hppa
    None


== Sources copied from PRIMARY to PPAs ==

Sources published (uploaded or copied) to the PPA do not share builds
with the distribution main archive (PRIMARY/PARTNER). They should have
a build record representing the building context for the specific PPA
where they are published.

Let's start by copying a PRIMARY archive source to Celso's PPA.

    >>> copy = hoary_evo_source['1.0'].current_published.copyTo(
    ...    hoary, pocket_release, cprov.archive)

No suitable build will be found for it.

    >>> test_build_i386_ppa = copy.sourcepackagerelease.getBuildByArch(
    ...     hoary_i386, cprov.archive)
    >>> print test_build_i386_ppa
    None

Then we can create a build record representing the intent to build
the copied source using the current PPA context. The PPA build context
is a merge between the PRIMARY archive context and the differences
introduced by the PPA itself, like new package or new dependency
versions, so the resulted binary will be influenced by the PPA
contents at the time it was built.

    >>> evo_build_i386_ppa = copy.sourcepackagerelease.createBuild(
    ...     hoary_i386, pocket_release, cprov.archive)

    >>> evo_build_i386_ppa.status.name
    'NEEDSBUILD'

    >>> print evo_build_i386_ppa.archive.displayname
    PPA for Celso Providelo

The copied source build lookup in the PPA returns the build created in
the PPA context, not the PRIMARY archive one.

    >>> test_build_i386_ppa = copy.sourcepackagerelease.getBuildByArch(
    ...     hoary_i386, cprov.archive)
    >>> test_build_i386_ppa == evo_build_i386_ppa
    True

As expected, the hoary/hppa build is still missing in both archives.

    >>> test_build_hppa_ppa = copy.sourcepackagerelease.getBuildByArch(
    ...     hoary_hppa, cprov.archive)
    >>> print test_build_hppa_ppa
    None

When we create a hoary/hppa build in the PPA context, it will continue
to be missing in the PRIMARY archive context.

    >>> evo_build_hppa_ppa = copy.sourcepackagerelease.createBuild(
    ...     hoary_hppa, pocket_release, cprov.archive)

    >>> test_build_hppa_ppa = copy.sourcepackagerelease.getBuildByArch(
    ...     hoary_hppa, cprov.archive)

    >>> print test_build_hppa_ppa.title
    hppa build of evolution 1.0 in ubuntu hoary RELEASE

    >>> test_build_hppa = evo_release.getBuildByArch(
    ...     hoary_hppa, ubuntu.main_archive)
    >>> print test_build_hppa
    None


== Build lookup for sources & binaries copied across PPAs ==

Launchpad also allows copies from published sources including
corresponding binaries from PRIMARY archive to PPA or from one PPA to
another.

We will create a foo_1.0 source, build and i386 binary published in
hoary PRIMARY archive.

    >>> foo_pub_src = test_publisher.getPubSource(
    ...     version="0.1", architecturehintlist='i386',
    ...     distroseries=hoary, archive=ubuntu.main_archive,
    ...     status=PackagePublishingStatus.PUBLISHED)

    >>> foo_pub_binaries = test_publisher.getPubBinaries(
    ...     distroseries=hoary, pub_source=foo_pub_src,
    ...     status=PackagePublishingStatus.PUBLISHED)

    >>> foo_source_release = foo_pub_src.sourcepackagerelease
    >>> build_primary = foo_source_release.getBuildByArch(
    ...     hoary_i386, ubuntu.main_archive)

    >>> print build_primary.title
    i386 build of foo 0.1 in ubuntu hoary RELEASE

    >>> print build_primary.archive.displayname
    Primary Archive for Ubuntu Linux

Then we can copy source and binary from PRIMARY archive to Celso's PPA:

    >>> cprov_src = foo_pub_src.copyTo(
    ...    hoary, pocket_release, cprov.archive)
    >>> [cprov_bin] = foo_pub_binaries[0].copyTo(
    ...    hoary, pocket_release, cprov.archive)
    >>> cprov_src.status = PackagePublishingStatus.PUBLISHED
    >>> cprov_bin.status = PackagePublishingStatus.PUBLISHED
    >>> from lp.services.database.sqlbase import flush_database_updates
    >>> flush_database_updates()

A build record is clearly not required here, since both, source and
binary got copied from PRIMARY archive, thus the system is able to
identify this situation and locate the original build. See the
bug #181736 report for previous mistakes in this area.

    >>> cprov_spr = cprov_src.sourcepackagerelease
    >>> cprov_build = cprov_spr.getBuildByArch(
    ...     hoary_i386, cprov.archive)

    >>> print cprov_build.title
    i386 build of foo 0.1 in ubuntu hoary RELEASE

    >>> print cprov_build.archive.displayname
    Primary Archive for Ubuntu Linux

Another possible situation is when the user wants to rebuild the
same source published in hoary to another suite, let's say
breezy-autotest in his PPA.

    >>> cprov_foo_src = cprov.archive.getPublishedSources(name='foo').first()

    >>> breezy_autotest = ubuntu.getSeries('breezy-autotest')
    >>> copy = cprov_foo_src.copyTo(
    ...    breezy_autotest, pocket_release, cprov.archive)
    >>> copy.status = PackagePublishingStatus.PUBLISHED
    >>> flush_database_updates()

When only the source is copied we do want to rebuild, so it's correct
when the build lookup returns None.

    >>> copied_release = copy.sourcepackagerelease
    >>> breezy_autotest_i386 = breezy_autotest['i386']
    >>> copied_build_candidate = copied_release.getBuildByArch(
    ...     breezy_autotest_i386, cprov.archive)
    >>> print copied_build_candidate
    None

It's even possible to copy source and binaries from hoary to warty
suite in Celso's PPA.

    >>> cprov_foo_src = cprov.archive.getPublishedSources(
    ...    name='foo', distroseries=hoary).first()
    >>> cprov_foo_bin = cprov_foo_src.getPublishedBinaries()[0]

    >>> warty = ubuntu.getSeries('warty')
    >>> copied_source = cprov_foo_src.copyTo(
    ...    warty, pocket_release, cprov.archive)
    >>> [copied_binary] = cprov_foo_bin.copyTo(
    ...    warty, pocket_release, cprov.archive)
    >>> copied_source.status = PackagePublishingStatus.PUBLISHED
    >>> copied_binary.status = PackagePublishingStatus.PUBLISHED
    >>> flush_database_updates()

In this case the system is also able to locate the original build by
following the build path of the corresponding published binaries.

    >>> copied_source_release = copied_source.sourcepackagerelease
    >>> warty_i386 = warty['i386']
    >>> copied_build_candidate = copied_source_release.getBuildByArch(
    ...     warty_i386, cprov.archive)

    >>> print copied_build_candidate.title
    i386 build of foo 0.1 in ubuntu hoary RELEASE

    >>> print copied_build_candidate.archive.displayname
    Primary Archive for Ubuntu Linux

Now we can also copy the hoary source and its binary from Celso's PPA
to Mark Shuttleworth's PPA.

    >>> cprov_foo_src = cprov.archive.getPublishedSources(
    ...    name='foo', distroseries=hoary).first()
    >>> cprov_foo_bin = cprov_foo_src.getPublishedBinaries()[0]

    >>> mark = getUtility(IPersonSet).getByName('mark')
    >>> mark_src = cprov_foo_src.copyTo(
    ...    hoary, pocket_release, mark.archive)
    >>> [mark_bin] = cprov_foo_bin.copyTo(
    ...    hoary, pocket_release, mark.archive)
    >>> mark_src.status = PackagePublishingStatus.PUBLISHED
    >>> mark_bin.status = PackagePublishingStatus.PUBLISHED
    >>> flush_database_updates()

The published binaries build path is followed again to find the
original build that happened in the primary archive.

    >>> mark_spr = mark_src.sourcepackagerelease
    >>> mark_build = mark_spr.getBuildByArch(
    ...     hoary_i386, mark.archive)

    >>> print mark_build.title
    i386 build of foo 0.1 in ubuntu hoary RELEASE

    >>> print mark_build.archive.displayname
    Primary Archive for Ubuntu Linux