~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
Distribution Soyuz
==================

Distributions are built by the Soyuz build system which creates many
objects for the distribution.


    >>> from lp.registry.interfaces.distribution import IDistributionSet
    >>> from lp.registry.interfaces.pocket import PackagePublishingPocket
    >>> from lp.soyuz.enums import PackagePublishingStatus

    >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
    >>> debian = getUtility(IDistributionSet).getByName('debian')

(Create some data that is depended upon by later tests. It was part of a
test "narrative" that was converted to unit tests.... for obvious reasons.)

    >>> from lp.soyuz.tests.ppa import publishToPPA
    >>> publishToPPA(
    ...     person_name='cprov',
    ...     sourcepackage_name='at', sourcepackage_version='0.00',
    ...     binarypackage_version='3.14156',
    ...     distribution_name='ubuntutest',
    ...     distroseries_name='hoary-test',
    ...     publishing_status=PackagePublishingStatus.PUBLISHED)


Handling Personal Package Archives
----------------------------------

`IDistribution` provides a series of methods to lookup PPAs:

 * getAllPPAs
 * searchPPAs
 * getPendingAcceptancePPAs
 * getPendingPublicationPPAs

    >>> from lp.registry.interfaces.person import IPersonSet
    >>> cprov = getUtility(IPersonSet).getByName('cprov')
    >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
    >>> mark = getUtility(IPersonSet).getByName('mark')


Iteration over all PPAs
~~~~~~~~~~~~~~~~~~~~~~~

getAllPPAs method provides all returns, as the suggests, all PPAs for
the distribution in question:

    >>> [archive.owner.name for archive in ubuntu.getAllPPAs()]
    [u'cprov', u'mark', u'no-priv']

    >>> [archive.owner.name for archive in debian.getAllPPAs()]
    []


Searching PPAs
~~~~~~~~~~~~~~

Via searchPPAs, the callsites are able to look for PPA given a string
matching Person.fti or PPA Archive.fti (description content) and also
restrict the result to active/inactive (whether the PPA contains or not
valid publications).

searchPPAs also considers the packages caches available for PPAs, for
further information see doc/package-cache.txt.

There is only one 'active' PPA:

    >>> cprov.archive.getPublishedSources().count()
    4

    >>> mark.archive.getPublishedSources().count()
    1

    >>> no_priv.archive.getPublishedSources().count()
    0

    >>> result = ubuntu.searchPPAs()
    >>> [archive.owner.name for archive in result]
    [u'cprov', u'mark']

PPAs can be reached passing a filter matching (via fti) its description
and its  'contents description' (see package-cache.txt).

    >>> for owner in [cprov, mark, no_priv]:
    ...     print "%s: %s" % (owner.name, owner.archive.description)
    cprov: packages to help my friends.
    mark: packages to help the humanity (you know, ubuntu)
    no-priv: I am not allowed to say, I have no privs.

    >>> result = ubuntu.searchPPAs(text='friend')
    >>> [archive.owner.name for archive in result]
    [u'cprov']

    >>> result = ubuntu.searchPPAs(text='oink')
    >>> [archive.owner.name for archive in result]
    []

    >>> result = ubuntu.searchPPAs(text='packages')
    >>> [archive.owner.name for archive in result]
    [u'cprov', u'mark']

    >>> result = ubuntu.searchPPAs(text='help')
    >>> [archive.owner.name for archive in result]
    [u'cprov', u'mark']

Including 'inactive' PPAs:

    >>> result = ubuntu.searchPPAs(show_inactive=True)
    >>> [archive.owner.name for archive in result]
    [u'cprov', u'mark', u'no-priv']

    >>> result = ubuntu.searchPPAs(text='priv', show_inactive=True)
    >>> [archive.owner.name for archive in result]
    [u'no-priv']

    >>> result = ubuntu.searchPPAs(text='ubuntu', show_inactive=True)
    >>> [archive.owner.name for archive in result]
    [u'mark']

The searchPPAs() method only returns the PPAs of active users.

    >>> from canonical.launchpad.interfaces.account import AccountStatus
    >>> from canonical.launchpad.interfaces.lpstorm import IMasterObject

    >>> login('admin@canonical.com')
    >>> account = IMasterObject(no_priv.account)
    >>> account.status = AccountStatus.SUSPENDED
    >>> transaction.commit()

    >>> result = ubuntu.searchPPAs(text='priv', show_inactive=True)
    >>> [archive for archive in result]
    []

    >>> account.status = AccountStatus.ACTIVE
    >>> transaction.commit()


Retrieving only pending-acceptance PPAs
---------------------------------------

'getPendingAcceptancePPAs' lookup will only return PPA which have
Package Upload (queue) records in ACCEPTED state, it it used in
'process-accepted' in '--ppa' mode to avoid quering all PPAs:

Nothing is pending-acceptance in sampledata:

    >>> ubuntu.getPendingAcceptancePPAs().count()
    0

Create a NEW PackageUpload record for cprov PPA:

    >>> hoary = ubuntu['hoary']
    >>> login('mark@example.com')
    >>> queue = hoary.createQueueEntry(
    ...      pocket=PackagePublishingPocket.RELEASE, archive=cprov.archive,
    ...      changesfilename='foo', changesfilecontent='bar')
    >>> queue.status.name
    'NEW'

Records in NEW do not make cprov PPA pending-acceptance:

    >>> ubuntu.getPendingAcceptancePPAs().count()
    0

Neither in UNAPPROVED:

    >>> queue.setUnapproved()
    >>> queue.status.name
    'UNAPPROVED'

    >>> ubuntu.getPendingAcceptancePPAs().count()
    0

Only records in ACCEPTED does:

    >>> queue.setAccepted()
    >>> queue.status.name
    'ACCEPTED'

    >>> pending_ppas = ubuntu.getPendingAcceptancePPAs()
    >>> [pending_ppa] = pending_ppas
    >>> pending_ppa.id == cprov.archive.id
    True

Records in DONE also do not trigger pending-acceptance state in PPAs:

    >>> queue.setDone()
    >>> queue.status.name
    'DONE'

    >>> ubuntu.getPendingAcceptancePPAs().count()
    0


Retrieving only pending-acceptance PPAs
---------------------------------------

'getPendingPublicationPPAs'lookup will only return PPA which have
PENDING publishing records, it's used in 'publish-distro' in '--ppa'
mode to avoiding querying all PPAs.

Nothing is pending-publication in sampledata:

    >>> ubuntu.getPendingPublicationPPAs().count()
    0

We can make Celso's PPA pending publication by copying a published
source to another location within the PPA.

    >>> cprov_src = cprov.archive.getPublishedSources().first()

    >>> warty = ubuntu['warty']
    >>> pocket_release = PackagePublishingPocket.RELEASE
    >>> src_pub = cprov_src.copyTo(warty, pocket_release, cprov.archive)
    >>> print src_pub.status.name
    PENDING

    >>> [pending_ppa] = ubuntu.getPendingPublicationPPAs()
    >>> pending_ppa.id == cprov.archive.id
    True

Publishing the record will exclude Celso's PPA from pending-publication
state:

    >>> src_pub.status = PackagePublishingStatus.PUBLISHED

    >>> ubuntu.getPendingPublicationPPAs().count()
    0

We can also make Celso's PPA pending publication by deleting a published
source.

    >>> login("celso.providelo@canonical.com")
    >>> cprov_src.requestDeletion(cprov, 'go away !')
    >>> src_pub = cprov_src

    >>> [pending_ppa] = ubuntu.getPendingPublicationPPAs()
    >>> pending_ppa.id == cprov.archive.id
    True

    >>> login('mark@example.com')
    >>> from canonical.database.constants import UTC_NOW
    >>> src_pub.scheduleddeletiondate = UTC_NOW
    >>> ubuntu.getPendingPublicationPPAs().count()
    0

A binary pending publication also moves a PPA to the pending-publication
state. In order to test this behaviour we will copy some binaries within
Celso's PPA.

    >>> cprov_bin = cprov.archive.getAllPublishedBinaries()[0]
    >>> pending_binaries = cprov_bin.copyTo(
    ...     warty, pocket_release, cprov.archive)

The copied binaries are pending publication, thus Celso's PPA gets
listed in the PPA pending-publication results.

    >>> for pub in pending_binaries:
    ...     print pub.status.name
    PENDING
    PENDING

    >>> [pending_ppa] = ubuntu.getPendingPublicationPPAs()
    >>> pending_ppa.id == cprov.archive.id
    True

Publishing the binaries will exclude Celso's PPA from pending-
publication results:

    >>> for pub in pending_binaries:
    ...     pub.status = PackagePublishingStatus.PUBLISHED

    >>> ubuntu.getPendingPublicationPPAs().count()
    0

A binary deletion will also make Celso's PPA pending publication.

    >>> login("celso.providelo@canonical.com")
    >>> cprov_bin.requestDeletion(cprov, 'go away !')
    >>> bin_pub = cprov_bin

    >>> [pending_ppa] = ubuntu.getPendingPublicationPPAs()
    >>> pending_ppa.id == cprov.archive.id
    True

    >>> login('mark@example.com')
    >>> bin_pub.scheduleddeletiondate = UTC_NOW
    >>> ubuntu.getPendingPublicationPPAs().count()
    0


Distribution Archives
---------------------

`IDistribution.all_distro_archives` returns all archives associated with
the distribution.  This list does not, therefore, include PPAs.

    >>> ubuntutest = getUtility(IDistributionSet)['ubuntutest']
    >>> for archive in ubuntutest.all_distro_archives:
    ...     print archive.purpose.title
    Primary Archive
    Partner Archive

`IDistribution.getArchiveByComponent` retrieves an IArchive given a
component name.  If the component is unknown, None is returned.

    >>> partner_archive = ubuntutest.getArchiveByComponent('partner')
    >>> print partner_archive.displayname
    Partner Archive for Ubuntu Test

    >>> other_archive = ubuntutest.getArchiveByComponent('dodgycomponent')
    >>> print other_archive
    None

Multiple components, specially the debian-compatibility ones points to
the PRIMARY archive. This relationship is established so we can import
their packages in the correct archive.

    >>> main_archive = ubuntutest.getArchiveByComponent('main')
    >>> print main_archive.displayname
    Primary Archive for Ubuntu Test

    >>> non_free_archive = ubuntutest.getArchiveByComponent('non-free')
    >>> print non_free_archive.displayname
    Primary Archive for Ubuntu Test

    >>> contrib_archive = ubuntutest.getArchiveByComponent('contrib')
    >>> print contrib_archive.displayname
    Primary Archive for Ubuntu Test