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
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
|
DistroSeries view classes
=========================
Let's use ubuntu/hoary for these tests.
>>> from lp.registry.interfaces.distribution import IDistributionSet
>>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
>>> hoary = ubuntu.getSeries('hoary')
Administering distroseries
--------------------------
The +admin view allows administrators to change a series. It provides a
label, page_title, and cancel_url
>>> view = create_initialized_view(hoary, name='+admin')
>>> print view.label
Administer The Hoary Hedgehog Release
>>> print view.page_title
Administer The Hoary Hedgehog Release
>>> print view.cancel_url
http://launchpad.dev/ubuntu/hoary
We will use a function to print the details related with the
distroseries being tested.
>>> def administrate_distroseries(distroseries, form):
... view = create_initialized_view(hoary, name='+admin', form=form)
... print '%d errors' % len(view.errors)
... for error in view.errors:
... try:
... name, title, message = error
... except ValueError:
... title, message = error
... print '%s: %s' % (title, message)
... print 'Name:', distroseries.name
... print 'Version:', distroseries.version
... print 'Changeslist:', distroseries.changeslist
... print 'Status:', distroseries.status.name
>>> form = {
... 'field.actions.change': 'Change',
... 'field.name': 'hoary',
... 'field.version': '5.04',
... 'field.changeslist': 'hoary-changes@ubuntu.com',
... 'field.status': 'DEVELOPMENT',
... }
>>> login('foo.bar@canonical.com')
>>> administrate_distroseries(hoary, form)
0 errors
Name: hoary
Version: 5.04
Changeslist: hoary-changes@ubuntu.com
Status: DEVELOPMENT
The distroseries 'changeslist' field only accept valid email addresses.
>>> form['field.changeslist'] = ''
>>> administrate_distroseries(hoary, form)
1 errors
E-mail changes to:
Name: hoary
Version: 5.04
Changeslist: hoary-changes@ubuntu.com
Status: DEVELOPMENT
>>> form['field.changeslist'] = 'bRoKen_AdDreSs'
>>> administrate_distroseries(hoary, form)
1 errors
E-mail changes to: Invalid email 'bRoKen_AdDreSs'.
Name: hoary
Version: 5.04
Changeslist: hoary-changes@ubuntu.com
Status: DEVELOPMENT
>>> form['field.changeslist'] = 'foo@bar.com'
>>> administrate_distroseries(hoary, form)
0 errors
Name: hoary
Version: 5.04
Changeslist: foo@bar.com
Status: DEVELOPMENT
When the distroseries is released, i.e. when it goes from an unstable
status (FUTURE, EXPERIMENTAL, DEVELOPMENT, FROZEN) to CURRENT, its
'datereleased' field is set.
>>> print hoary.datereleased
None
>>> form['field.status'] = 'CURRENT'
>>> administrate_distroseries(hoary, form)
0 errors
Name: hoary
Version: 5.04
Changeslist: foo@bar.com
Status: CURRENT
>>> initial_datereleased = hoary.datereleased
>>> initial_datereleased is not None
True
Let's commit the current DB status, so errors can be triggered and
will not rollback the changes done until here.
>>> import transaction
>>> transaction.commit()
A stable distroseries cannot be made unstable again.
>>> form['field.status'] = 'EXPERIMENTAL'
>>> administrate_distroseries(hoary, form)
1 errors
Invalid value: token 'EXPERIMENTAL' not found in vocabulary
Name: hoary
Version: 5.04
Changeslist: foo@bar.com
Status: CURRENT
The 'datereleased' value is only set once, even if the distroseries is
modified to SUPPORTED or OBSOLETE and then set back to CURRENT its
initial value remains.
>>> form['field.status'] = 'SUPPORTED'
>>> administrate_distroseries(hoary, form)
0 errors
Name: hoary
Version: 5.04
Changeslist: foo@bar.com
Status: SUPPORTED
>>> hoary.datereleased == initial_datereleased
True
>>> form['field.status'] = 'CURRENT'
>>> administrate_distroseries(hoary, form)
0 errors
Name: hoary
Version: 5.04
Changeslist: foo@bar.com
Status: CURRENT
>>> hoary.datereleased == initial_datereleased
True
Editing distro series
---------------------
The distroseries edit view allows the editor to change series. The form
uses the displayname, title, and description fields.
>>> driver = factory.makePerson(name='ubuntu-driver')
>>> hoary.driver = driver
>>> login_person(driver)
>>> view = create_initialized_view(hoary, '+edit')
>>> print view.label
Edit The Hoary Hedgehog Release details
>>> print view.page_title
Edit The Hoary Hedgehog Release details
>>> print view.cancel_url
http://launchpad.dev/ubuntu/hoary
>>> [field.__name__ for field in view.form_fields]
['displayname', 'title', 'summary', 'description']
Admins can see the status field for full functionality distributions.
>>> login('admin@canonical.com')
>>> view = create_initialized_view(hoary, '+edit')
>>> [field.__name__ for field in view.form_fields]
['displayname', 'title', 'summary', 'description', 'status']
Series that belong to derivative distributions also contain the status field.
>>> youbuntu = factory.makeDistribution(name='youbuntu')
>>> yo_series = factory.makeDistroSeries(name='melon')
>>> yo_series.title = 'Melon'
>>> youbuntu.full_functionality
False
>>> yo_driver = factory.makePerson(name='yo-driver')
>>> youbuntu.driver = yo_driver
>>> login_person(yo_driver)
>>> view = create_initialized_view(yo_series, '+edit')
>>> print view.label
Edit Melon details
>>> [field.__name__ for field in view.form_fields]
['displayname', 'title', 'summary', 'description', 'status']
>>> print view.widgets.get('status')._getFormValue().title
Active Development
Creating distro series
----------------------
A distroseries is created using the distroseries view.
>>> login('foo.bar@canonical.com')
>>> view = create_view(ubuntu, '+addseries')
>>> print view.page_title
Add a series
>>> print view.label
Add a series
>>> print view.cancel_url
http://launchpad.dev/ubuntu
>>> print view.next_url
None
>>> view.field_names
['name', 'version', 'displayname', 'summary']
A distroseries is created whent the required field are submitted.
>>> form = {
... 'field.name': 'sane',
... 'field.displayname': 'Sane Name',
... 'field.summary': 'A stable series to introduce fnord.',
... 'field.version': '2009.06',
... 'field.actions.create': 'Create Series',
... }
>>> view = create_initialized_view(ubuntu, '+addseries', form=form)
>>> view.errors
[]
>>> sane_distroseries = ubuntu.getSeries('sane')
>>> print sane_distroseries.name
sane
# Save this series to test name and version constraints.
>>> transaction.commit()
Administrators can create series, but normal users cannot.
>>> from canonical.launchpad.webapp.authorization import check_permission
>>> check_permission('launchpad.Driver', view)
True
>>> login('no-priv@canonical.com')
>>> check_permission('launchpad.Driver', view)
False
Drivers can create distro series
--------------------------------
Users who are appointed as drivers of a distribution can create a series.
Most distributions are an `IDerivativeDistribution`.
>>> login_person(yo_driver)
>>> view = create_view(youbuntu, name='+addseries')
>>> check_permission('launchpad.Moderate', view)
True
>>> yo_form = dict(form)
>>> yo_form['field.name'] = 'island'
>>> yo_form['field.displayname'] = 'Island'
>>> view = create_initialized_view(
... youbuntu, name='+addseries', form=yo_form, principal=yo_driver)
>>> view.errors
[]
>>> yo_series = youbuntu.getSeries('island')
>>> print yo_series.displayname
Island
Ubuntu is an exception. It's drivers cannot create series because Ubuntu
is an `IBaseDistribution`.
>>> ubuntu.full_functionality
True
>>> login_person(ubuntu.owner.teamowner)
>>> ubuntu.driver = yo_driver
>>> login_person(yo_driver)
>>> view = create_view(youbuntu, name='+addseries')
>>> check_permission('launchpad.Edit', view)
False
Drivers editing distro series
.............................
The series driver (release manager) can edit a series if the series belongs
to a `IDerivativeDistribution`.
>>> print yo_series.driver.name
yo-driver
>>> login_person(yo_driver)
>>> view = create_view(yo_series, name='+edit')
>>> check_permission('launchpad.Edit', view)
True
>>> yo_form = dict(form)
>>> del yo_form['field.actions.create']
>>> yo_form['field.displayname'] = 'Mountain'
>>> yo_form['field.summary'] = 'Mountain summary'
>>> yo_form['field.actions.change'] = 'Change'
>>> view = create_initialized_view(
... yo_series, name='+edit', form=yo_form, principal=yo_driver)
>>> view.errors
[]
>>> print yo_series.displayname
Mountain
Drivers of an `IBaseDistribution` such as Ubuntu cannot edit a series.
>>> login_person(ubuntu.owner.teamowner)
>>> hoary.driver = yo_driver
>>> login_person(yo_driver)
>>> view = create_view(hoary, name='+edit')
>>> check_permission('launchpad.Edit', view)
False
Distroseries name
-----------------
The distroseries name is unique.
>>> login('foo.bar@canonical.com')
>>> form['field.name'] = 'sane'
>>> form['field.version'] = '2009.07'
>>> view = create_initialized_view(ubuntu, '+addseries', form=form)
>>> for error in view.errors:
... print error[2]
sane is already in use by another series.
The distroseries name cannot contain spaces.
>>> form['field.name'] = 'insane name'
>>> view = create_initialized_view(ubuntu, '+addseries', form=form)
>>> for error in view.errors:
... print error[2]
Invalid name 'insane name'...
Distroseries version
--------------------
Versions cannot contain spaces.
>>> form['field.name'] = '6-06-series'
>>> form['field.version'] = '6.06 LTS'
>>> view = create_initialized_view(ubuntu, '+addseries', form=form)
>>> for error in view.errors:
... print error[2]
6.06 LTS is not a valid version
The distroseries version must be a valid debversion.
>>> form['field.version'] = 'Hardy-6.06-LTS'
>>> view = create_initialized_view(ubuntu, '+addseries', form=form)
>>> for error in view.errors:
... print error[2]
'Hardy-6.06-LTS': Could not parse version...
The distroseries version is unique to a distribution. Version '2009.06'
cannot be reused by another Ubuntu series.
>>> print sane_distroseries.version
2009.06
>>> form['field.name'] = 'experimental'
>>> form['field.version'] = '2009.06'
>>> view = create_initialized_view(ubuntu, '+addseries', form=form)
>>> for error in view.errors:
... print error[2]
2009.06 is already in use by another version in this distribution.
But version '2009.06' can be used by another distribution.
>>> other_distro = factory.makeDistribution(name='other-distro')
>>> view = create_initialized_view(other_distro, '+addseries', form=form)
>>> view.errors
[]
>>> experimental_distroseries = other_distro.getSeries('experimental')
>>> print experimental_distroseries.version
2009.06
|