~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/soyuz/doc/soyuz-set-of-uploads.txt

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-06-16 12:17:34 UTC
  • mfrom: (13233.1.2 pre-394645)
  • Revision ID: launchpad@pqm.canonical.com-20110616121734-igzzpd482yots7d3
[r=jtv][bug=394645,537335][no-qa] Lint blows but hoover sucks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
= Soyuz Set of Uploads Test =
 
1
Soyuz Set of Uploads Test
 
2
=========================
2
3
 
3
4
This test will:
4
5
 
12
13
  * Cleanup
13
14
 
14
15
 
15
 
== Pre-creating directories ==
 
16
Pre-creating directories
 
17
------------------------
16
18
 
17
19
First, let's create the temporary directory structure where we'll put uploaded
18
20
files in.
19
21
 
20
 
  >>> import os
21
 
  >>> import tempfile
22
 
  >>> temp_dir = tempfile.mkdtemp()
23
 
  >>> incoming_dir = os.path.join(temp_dir, "incoming")
24
 
  >>> accepted_dir = os.path.join(temp_dir, "accepted")
25
 
  >>> rejected_dir = os.path.join(temp_dir, "rejected")
26
 
  >>> failed_dir = os.path.join(temp_dir, "failed")
27
 
  >>> os.mkdir(incoming_dir)
28
 
 
29
 
 
30
 
== A note about error checking ==
 
22
    >>> import os
 
23
    >>> import tempfile
 
24
    >>> temp_dir = tempfile.mkdtemp()
 
25
    >>> incoming_dir = os.path.join(temp_dir, "incoming")
 
26
    >>> accepted_dir = os.path.join(temp_dir, "accepted")
 
27
    >>> rejected_dir = os.path.join(temp_dir, "rejected")
 
28
    >>> failed_dir = os.path.join(temp_dir, "failed")
 
29
    >>> os.mkdir(incoming_dir)
 
30
 
 
31
 
 
32
A note about error checking
 
33
---------------------------
31
34
 
32
35
To be able to process the entire upload and provide the full set of
33
36
errors, we need:
48
51
 about what is available.
49
52
 
50
53
 
51
 
== Processing Uploads ==
 
54
Processing Uploads
 
55
------------------
52
56
 
53
57
Before asking the system to process the upload, we must prepare the
54
58
database and services to receive it. Since we're using
58
62
librarian are running and making sure that the key is attached to the
59
63
relevant launchpad person.
60
64
 
61
 
  >>> from lp.testing.keyserver import KeyServerTac
62
 
  >>> keyserver = KeyServerTac()
63
 
  >>> keyserver.setUp()
 
65
    >>> from lp.testing.keyserver import KeyServerTac
 
66
    >>> keyserver = KeyServerTac()
 
67
    >>> keyserver.setUp()
64
68
 
65
69
Import public keyring into current LPDB.
66
70
 
67
 
  >>> from canonical.launchpad.ftests import import_public_test_keys
68
 
  >>> import_public_test_keys()
 
71
    >>> from canonical.launchpad.ftests import import_public_test_keys
 
72
    >>> import_public_test_keys()
69
73
 
70
74
Having set up that infrastructure we need to prepare a breezy distroseries
71
75
for the ubuntutest distribution.
72
76
 
73
 
  >>> from lp.registry.interfaces.pocket import PackagePublishingPocket
74
 
  >>> from lp.registry.model.distribution import Distribution
75
 
  >>> from lp.soyuz.enums import PackageUploadStatus
76
 
  >>> from lp.soyuz.scripts.initialize_distroseries import (
77
 
  ...     InitializeDistroSeries)
78
 
  >>> from canonical.launchpad.database.librarian import LibraryFileAlias
79
 
  >>> ubuntu = Distribution.byName('ubuntu')
80
 
  >>> breezy_autotest = ubuntu['breezy-autotest']
81
 
  >>> ubuntutest = Distribution.byName('ubuntutest')
82
 
  >>> breezy = ubuntutest.newSeries(
83
 
  ...     'breezy', 'Breezy Badger', 'The Breezy Badger',
84
 
  ...     'Black and White', 'Someone', '5.10', None,
85
 
  ...     breezy_autotest.owner)
86
 
  >>> ids = InitializeDistroSeries(breezy, [breezy_autotest.id])
87
 
  >>> ids.initialize()
88
 
  >>> breezy.changeslist = 'breezy-changes@ubuntu.com'
89
 
  >>> fake_chroot = LibraryFileAlias.get(1)
90
 
  >>> unused = breezy['i386'].addOrUpdateChroot(fake_chroot)
 
77
    >>> from lp.registry.interfaces.pocket import PackagePublishingPocket
 
78
    >>> from lp.registry.model.distribution import Distribution
 
79
    >>> from lp.soyuz.enums import PackageUploadStatus
 
80
    >>> from lp.soyuz.scripts.initialize_distroseries import (
 
81
    ...     InitializeDistroSeries)
 
82
    >>> from canonical.launchpad.database.librarian import LibraryFileAlias
 
83
    >>> ubuntu = Distribution.byName('ubuntu')
 
84
    >>> breezy_autotest = ubuntu['breezy-autotest']
 
85
    >>> ubuntutest = Distribution.byName('ubuntutest')
 
86
    >>> breezy = ubuntutest.newSeries(
 
87
    ...     'breezy', 'Breezy Badger', 'The Breezy Badger',
 
88
    ...     'Black and White', 'Someone', '5.10', None,
 
89
    ...     breezy_autotest.owner)
 
90
    >>> ids = InitializeDistroSeries(breezy, [breezy_autotest.id])
 
91
    >>> ids.initialize()
 
92
    >>> breezy.changeslist = 'breezy-changes@ubuntu.com'
 
93
    >>> fake_chroot = LibraryFileAlias.get(1)
 
94
    >>> unused = breezy['i386'].addOrUpdateChroot(fake_chroot)
91
95
 
92
96
Add disk content for file inherited from ubuntu/breezy-autotest:
93
97
 
94
 
  >>> from canonical.librarian.testing.server import fillLibrarianFile
95
 
  >>> fillLibrarianFile(54)
 
98
    >>> from canonical.librarian.testing.server import fillLibrarianFile
 
99
    >>> fillLibrarianFile(54)
96
100
 
97
101
Now that the infrastructure is ready, we prepare a set of useful methods.
98
102
 
99
103
Firstly, we need a way to copy a test upload into the queue (but skip
100
104
lock files, which have names starting with a dot).
101
105
 
102
 
  >>> from lp.archiveuploader.tests import datadir
103
 
  >>> def punt_upload_into_queue(leaf, distro):
104
 
  ...     inc_dir = os.path.join(incoming_dir, leaf, distro)
105
 
  ...     os.makedirs(inc_dir)
106
 
  ...     for file_leaf in os.listdir(datadir(os.path.join("suite", leaf))):
107
 
  ...         os.system("cp %s %s" % (
108
 
  ...             datadir(os.path.join("suite", leaf, file_leaf)), inc_dir))
 
106
    >>> from lp.archiveuploader.tests import datadir
 
107
    >>> def punt_upload_into_queue(leaf, distro):
 
108
    ...     inc_dir = os.path.join(incoming_dir, leaf, distro)
 
109
    ...     os.makedirs(inc_dir)
 
110
    ...     for file_leaf in os.listdir(datadir(os.path.join("suite", leaf))):
 
111
    ...         os.system("cp %s %s" % (
 
112
    ...             datadir(os.path.join("suite", leaf, file_leaf)), inc_dir))
109
113
 
110
114
We need a way to count the items in a queue directory
111
115
 
112
 
  >>> def count_items(queue):
113
 
  ...     return len(queue)
 
116
    >>> def count_items(queue):
 
117
    ...     return len(queue)
114
118
 
115
119
And then we need a way to process the uploads from the queue
116
120
 
117
 
  >>> import logging
118
 
  >>> from canonical.config import config
119
 
  >>> from lp.services.log.logger import FakeLogger
120
 
  >>> from lp.soyuz.scripts.soyuz_process_upload import (
121
 
  ...     ProcessUpload)
122
 
  >>> from canonical.testing.layers import LaunchpadZopelessLayer
123
 
  >>> def process_uploads(upload_policy, series, loglevel):
124
 
  ...     """Simulate process-upload.py script run.
125
 
  ...
126
 
  ...     :param upload_policy: context in which to consider the upload
127
 
  ...         (equivalent to script's --context option).
128
 
  ...     :param series: distro series to give back from.
129
 
  ...         (equivalent to script's --series option).
130
 
  ...     :param loglevel: logging level (as defined in logging module).  Any
131
 
  ...         log messages below this level will be suppressed.
132
 
  ...     """
133
 
  ...     args = [temp_dir, "-C", upload_policy]
134
 
  ...     if series is not None:
135
 
  ...         args.extend(["-s", series])
136
 
  ...     # Run script under 'uploader' DB user.  The dbuser argument to the
137
 
  ...     # script constructor is ignored, so we must change DB users here.
138
 
  ...     LaunchpadZopelessLayer.txn.commit()
139
 
  ...     LaunchpadZopelessLayer.switchDbUser(config.uploader.dbuser)
140
 
  ...     process = ProcessUpload(
141
 
  ...         'process-upload', dbuser='ignored', test_args=args)
142
 
  ...     process.logger = FakeLogger()
143
 
  ...     if loglevel is not None:
144
 
  ...         process.logger.setLevel(loglevel)
145
 
  ...     process.txn = LaunchpadZopelessLayer.txn
146
 
  ...     process.main()
147
 
  ...     LaunchpadZopelessLayer.switchDbUser('launchpad')
 
121
    >>> import logging
 
122
    >>> from canonical.config import config
 
123
    >>> from lp.services.log.logger import FakeLogger
 
124
    >>> from lp.soyuz.scripts.soyuz_process_upload import (
 
125
    ...     ProcessUpload)
 
126
    >>> from canonical.testing.layers import LaunchpadZopelessLayer
 
127
    >>> def process_uploads(upload_policy, series, loglevel):
 
128
    ...     """Simulate process-upload.py script run.
 
129
    ...
 
130
    ...     :param upload_policy: context in which to consider the upload
 
131
    ...         (equivalent to script's --context option).
 
132
    ...     :param series: distro series to give back from.
 
133
    ...         (equivalent to script's --series option).
 
134
    ...     :param loglevel: logging level (as defined in logging module).
 
135
    ...         Any log messages below this level will be suppressed.
 
136
    ...     """
 
137
    ...     args = [temp_dir, "-C", upload_policy]
 
138
    ...     if series is not None:
 
139
    ...         args.extend(["-s", series])
 
140
    ...     # Run script under 'uploader' DB user.  The dbuser argument to the
 
141
    ...     # script constructor is ignored, so we must change DB users here.
 
142
    ...     LaunchpadZopelessLayer.txn.commit()
 
143
    ...     LaunchpadZopelessLayer.switchDbUser(config.uploader.dbuser)
 
144
    ...     process = ProcessUpload(
 
145
    ...         'process-upload', dbuser='ignored', test_args=args)
 
146
    ...     process.logger = FakeLogger()
 
147
    ...     if loglevel is not None:
 
148
    ...         process.logger.setLevel(loglevel)
 
149
    ...     process.txn = LaunchpadZopelessLayer.txn
 
150
    ...     process.main()
 
151
    ...     LaunchpadZopelessLayer.switchDbUser('launchpad')
148
152
 
149
153
And we need a way to process the accepted queue
150
154
 
151
 
  >>> from zope.component import getUtility
152
 
  >>> from canonical.launchpad.ftests import (
153
 
  ...     login,
154
 
  ...     syncUpdate,
155
 
  ...     )
156
 
  >>> from lp.registry.interfaces.distribution import IDistributionSet
157
 
 
158
 
  >>> login("foo.bar@canonical.com")
159
 
 
160
 
  >>> def process_accepted(distro):
161
 
  ...     distribution = getUtility(IDistributionSet)[distro]
162
 
  ...     for series in distribution.series:
163
 
  ...         items = series.getQueueItems(
164
 
  ...            status=PackageUploadStatus.ACCEPTED)
165
 
  ...         for item in items:
166
 
  ...             item.realiseUpload()
167
 
  ...             syncUpdate(item)
 
155
    >>> from zope.component import getUtility
 
156
    >>> from canonical.launchpad.ftests import (
 
157
    ...     login,
 
158
    ...     syncUpdate,
 
159
    ...     )
 
160
    >>> from lp.registry.interfaces.distribution import IDistributionSet
 
161
 
 
162
    >>> login("foo.bar@canonical.com")
 
163
 
 
164
    >>> def process_accepted(distro):
 
165
    ...     distribution = getUtility(IDistributionSet)[distro]
 
166
    ...     for series in distribution.series:
 
167
    ...         items = series.getQueueItems(
 
168
    ...            status=PackageUploadStatus.ACCEPTED)
 
169
    ...         for item in items:
 
170
    ...             item.realiseUpload()
 
171
    ...             syncUpdate(item)
168
172
 
169
173
 
170
174
If an upload of ours ends up in the NEW queue, we need a way to process
171
175
it into the accepted queue
172
176
 
173
 
  >>> def process_new(distro, series):
174
 
  ...     distribution = getUtility(IDistributionSet)[distro]
175
 
  ...     if series is None:
176
 
  ...         series = "breezy"
177
 
  ...     dr, pocket = distribution.getDistroSeriesAndPocket(series)
178
 
  ...     items = dr.getQueueItems(status=PackageUploadStatus.NEW)
179
 
  ...     for item in items:
180
 
  ...         item.setAccepted()
181
 
  ...         syncUpdate(item)
182
 
  ...     items = dr.getQueueItems(status=PackageUploadStatus.UNAPPROVED)
183
 
  ...     for item in items:
184
 
  ...         item.setAccepted()
185
 
  ...         syncUpdate(item)
 
177
    >>> def process_new(distro, series):
 
178
    ...     distribution = getUtility(IDistributionSet)[distro]
 
179
    ...     if series is None:
 
180
    ...         series = "breezy"
 
181
    ...     dr, pocket = distribution.getDistroSeriesAndPocket(series)
 
182
    ...     items = dr.getQueueItems(status=PackageUploadStatus.NEW)
 
183
    ...     for item in items:
 
184
    ...         item.setAccepted()
 
185
    ...         syncUpdate(item)
 
186
    ...     items = dr.getQueueItems(status=PackageUploadStatus.UNAPPROVED)
 
187
    ...     for item in items:
 
188
    ...         item.setAccepted()
 
189
    ...         syncUpdate(item)
186
190
 
187
191
Finally, as a very simplistic publishing process, we may need to punt any
188
192
given upload into the published state, so here's a very simplistic publisher
189
193
 
190
 
  >>> from lp.soyuz.model.publishing import (
191
 
  ...     SourcePackagePublishingHistory as SPPH,
192
 
  ...     BinaryPackagePublishingHistory as BPPH)
193
 
  >>> from lp.soyuz.enums import PackagePublishingStatus as PPS
194
 
  >>> from canonical.database.constants import UTC_NOW
195
 
  >>> def simple_publish(distro):
196
 
  ...     srcs_to_publish = SPPH.select("""
197
 
  ...         SourcePackagePublishingHistory.distroseries = DistroSeries.id
198
 
  ...     AND DistroSeries.distribution = Distribution.id
199
 
  ...     AND Distribution.name = '%s'
200
 
  ...     AND SourcePackagePublishingHistory.status = 1""" % distro,
201
 
  ...         clauseTables=['DistroSeries', 'Distribution'])
202
 
  ...     bins_to_publish = BPPH.select("""
203
 
  ...         BinaryPackagePublishingHistory.distroarchseries =
204
 
  ...             DistroArchSeries.id
205
 
  ...     AND DistroArchSeries.distroseries = DistroSeries.id
206
 
  ...     AND DistroSeries.distribution = Distribution.id
207
 
  ...     AND Distribution.name = '%s'
208
 
  ...     AND BinaryPackagePublishingHistory.status = 1""" % distro,
209
 
  ...         clauseTables=['DistroArchSeries', 'DistroSeries',
210
 
  ...                       'Distribution'])
211
 
  ...     published_one = False
212
 
  ...     for src in srcs_to_publish:
213
 
  ...         src.status = PPS.PUBLISHED
214
 
  ...         src.datepublished = UTC_NOW
215
 
  ...         syncUpdate(src)
216
 
  ...         published_one = True
217
 
  ...     for bin in bins_to_publish:
218
 
  ...         bin.status = PPS.PUBLISHED
219
 
  ...         bin.datepublished = UTC_NOW
220
 
  ...         syncUpdate(bin)
221
 
  ...         published_one = True
222
 
  ...     return published_one
223
 
 
224
 
 
225
 
We'll be doing a lot of uploads with sanity checks, and expect them to succeed.
226
 
A helper function, simulate_upload does that with all the checking.
227
 
 
228
 
  >>> import shutil
229
 
  >>> from lp.services.mail import stub
230
 
 
231
 
  >>> def simulate_upload(
232
 
  ...     leafname, is_new=False, upload_policy='anything',
233
 
  ...     series=None, distro="ubuntutest", loglevel=logging.WARN):
234
 
  ...     """Process upload(s).  Options are as for process_uploads()."""
235
 
  ...     punt_upload_into_queue(leafname, distro=distro)
236
 
  ...     process_uploads(upload_policy, series, loglevel)
237
 
  ...     # We seem to be leaving a lock file behind here for some reason.
238
 
  ...     # Naturally it doesn't count as an unprocessed incoming file, which
239
 
  ...     # is what we're really looking for.
240
 
  ...     lockfile = os.path.join(incoming_dir, '.lock')
241
 
  ...     if os.access(lockfile, os.F_OK):
242
 
  ...         os.remove(lockfile)
243
 
  ...     assert len(os.listdir(incoming_dir)) == 0, (
244
 
  ...         "Incoming should be empty: %s" % os.listdir(incoming_dir))
245
 
  ...
246
 
  ...     rejected_contents = os.listdir(rejected_dir)
247
 
  ...     if len(rejected_contents) > 0:
248
 
  ...         # Clean up rejected entry
249
 
  ...         shutil.rmtree(os.path.join(rejected_dir, leafname))
250
 
  ...         print "Rejected uploads: %s" % rejected_contents
251
 
  ...         return
252
 
  ...
253
 
  ...     assert len(os.listdir(failed_dir)) == 0, (
254
 
  ...         "Failed upload(s): %s" % os.listdir(failed_dir))
255
 
  ...     if is_new:
256
 
  ...         process_new(distro=distro, series=series)
257
 
  ...     process_accepted(distro=distro)
258
 
  ...     assert simple_publish(distro=distro), (
259
 
  ...             "Should publish at least one item")
260
 
  ...     if loglevel is None or loglevel <= logging.INFO:
261
 
  ...         print "Upload complete."
262
 
 
263
 
  >>> from lp.testing.mail_helpers import pop_notifications
264
 
  >>> def read_email():
265
 
  ...     """Pop all emails from the test mailbox, and summarize them.
266
 
  ...
267
 
  ...     For each message, prints "To:" followed by recipients; "Subject:"
268
 
  ...     followed by subject line; and message body followed by a blank line.
269
 
  ...     """
270
 
  ...     for message in pop_notifications(commit=False):
271
 
  ...         print "To:", message['to']
272
 
  ...         print "Subject:", message['subject']
273
 
  ...         print message.get_payload()[0].as_string()
274
 
  ...         print ''
 
194
    >>> from lp.soyuz.model.publishing import (
 
195
    ...     SourcePackagePublishingHistory as SPPH,
 
196
    ...     BinaryPackagePublishingHistory as BPPH)
 
197
    >>> from lp.soyuz.enums import PackagePublishingStatus as PPS
 
198
    >>> from canonical.database.constants import UTC_NOW
 
199
    >>> def simple_publish(distro):
 
200
    ...     srcs_to_publish = SPPH.select("""
 
201
    ...         SourcePackagePublishingHistory.distroseries = DistroSeries.id
 
202
    ...     AND DistroSeries.distribution = Distribution.id
 
203
    ...     AND Distribution.name = '%s'
 
204
    ...     AND SourcePackagePublishingHistory.status = 1""" % distro,
 
205
    ...         clauseTables=['DistroSeries', 'Distribution'])
 
206
    ...     bins_to_publish = BPPH.select("""
 
207
    ...         BinaryPackagePublishingHistory.distroarchseries =
 
208
    ...             DistroArchSeries.id
 
209
    ...     AND DistroArchSeries.distroseries = DistroSeries.id
 
210
    ...     AND DistroSeries.distribution = Distribution.id
 
211
    ...     AND Distribution.name = '%s'
 
212
    ...     AND BinaryPackagePublishingHistory.status = 1""" % distro,
 
213
    ...         clauseTables=['DistroArchSeries', 'DistroSeries',
 
214
    ...                       'Distribution'])
 
215
    ...     published_one = False
 
216
    ...     for src in srcs_to_publish:
 
217
    ...         src.status = PPS.PUBLISHED
 
218
    ...         src.datepublished = UTC_NOW
 
219
    ...         syncUpdate(src)
 
220
    ...         published_one = True
 
221
    ...     for bin in bins_to_publish:
 
222
    ...         bin.status = PPS.PUBLISHED
 
223
    ...         bin.datepublished = UTC_NOW
 
224
    ...         syncUpdate(bin)
 
225
    ...         published_one = True
 
226
    ...     return published_one
 
227
 
 
228
 
 
229
We'll be doing a lot of uploads with sanity checks, and expect them to
 
230
succeed.  A helper function, simulate_upload does that with all the checking.
 
231
 
 
232
    >>> import shutil
 
233
    >>> from lp.services.mail import stub
 
234
 
 
235
    >>> def simulate_upload(
 
236
    ...     leafname, is_new=False, upload_policy='anything',
 
237
    ...     series=None, distro="ubuntutest", loglevel=logging.WARN):
 
238
    ...     """Process upload(s).  Options are as for process_uploads()."""
 
239
    ...     punt_upload_into_queue(leafname, distro=distro)
 
240
    ...     process_uploads(upload_policy, series, loglevel)
 
241
    ...     # We seem to be leaving a lock file behind here for some reason.
 
242
    ...     # Naturally it doesn't count as an unprocessed incoming file,
 
243
    ...     # which is what we're really looking for.
 
244
    ...     lockfile = os.path.join(incoming_dir, '.lock')
 
245
    ...     if os.access(lockfile, os.F_OK):
 
246
    ...         os.remove(lockfile)
 
247
    ...     assert len(os.listdir(incoming_dir)) == 0, (
 
248
    ...         "Incoming should be empty: %s" % os.listdir(incoming_dir))
 
249
    ...
 
250
    ...     rejected_contents = os.listdir(rejected_dir)
 
251
    ...     if len(rejected_contents) > 0:
 
252
    ...         # Clean up rejected entry
 
253
    ...         shutil.rmtree(os.path.join(rejected_dir, leafname))
 
254
    ...         print "Rejected uploads: %s" % rejected_contents
 
255
    ...         return
 
256
    ...
 
257
    ...     assert len(os.listdir(failed_dir)) == 0, (
 
258
    ...         "Failed upload(s): %s" % os.listdir(failed_dir))
 
259
    ...     if is_new:
 
260
    ...         process_new(distro=distro, series=series)
 
261
    ...     process_accepted(distro=distro)
 
262
    ...     assert simple_publish(distro=distro), (
 
263
    ...             "Should publish at least one item")
 
264
    ...     if loglevel is None or loglevel <= logging.INFO:
 
265
    ...         print "Upload complete."
 
266
 
 
267
    >>> from lp.testing.mail_helpers import pop_notifications
 
268
    >>> def read_email():
 
269
    ...     """Pop all emails from the test mailbox, and summarize them.
 
270
    ...
 
271
    ...     For each message, prints "To:" followed by recipients; "Subject:"
 
272
    ...     followed by subject line; and message body followed by a blank
 
273
    ...     line.
 
274
    ...     """
 
275
    ...     for message in pop_notifications(commit=False):
 
276
    ...         print "To:", message['to']
 
277
    ...         print "Subject:", message['subject']
 
278
    ...         print message.get_payload()[0].as_string()
 
279
    ...         print ''
275
280
 
276
281
The 'bar' package' is an arch-all package. We have four stages to the
277
282
bar test. Each stage should be simple enough. First we have a new
279
284
overridable binary. This tests the simple overriding of both sources
280
285
and arch-independent binaries.
281
286
 
282
 
  >>> simulate_upload('bar_1.0-1', is_new=True, loglevel=logging.INFO)
283
 
  INFO Processing upload
284
 
  ...
285
 
  Upload complete.
286
 
 
287
 
  >>> simulate_upload('bar_1.0-1_binary', is_new=True)
288
 
 
289
 
  >>> simulate_upload('bar_1.0-2')
290
 
 
291
 
  >>> simulate_upload('bar_1.0-2_binary')
 
287
    >>> simulate_upload('bar_1.0-1', is_new=True, loglevel=logging.INFO)
 
288
    INFO Processing upload
 
289
    ...
 
290
    Upload complete.
 
291
 
 
292
    >>> simulate_upload('bar_1.0-1_binary', is_new=True)
 
293
 
 
294
    >>> simulate_upload('bar_1.0-2')
 
295
 
 
296
    >>> simulate_upload('bar_1.0-2_binary')
292
297
 
293
298
Check the rejection of a malicious version of bar package which refers
294
299
to a different 'bar_1.0.orig.tar.gz'.
295
300
 
296
 
  >>> stub.test_emails = []
297
 
  >>> simulate_upload('bar_1.0-3', loglevel=logging.ERROR)
298
 
  Rejected uploads: ['bar_1.0-3']
 
301
    >>> stub.test_emails = []
 
302
    >>> simulate_upload('bar_1.0-3', loglevel=logging.ERROR)
 
303
    Rejected uploads: ['bar_1.0-3']
299
304
 
300
 
  >>> read_email()
301
 
  To:
302
 
      Foo Bar <foo.bar@canonical.com>,
303
 
      Daniel Silverstone <daniel.silverstone@canonical.com>
304
 
  Subject: bar_1.0-3_source.changes rejected
305
 
  ...
 
305
    >>> read_email()
 
306
    To:
 
307
        Foo Bar <foo.bar@canonical.com>,
 
308
        Daniel Silverstone <daniel.silverstone@canonical.com>
 
309
    Subject: bar_1.0-3_source.changes rejected
 
310
    ...
306
311
 
307
312
Force weird behavior with rfc2047 sentences containing '.' on
308
313
bar_1.0-4, which caused bug # 41102.
309
314
 
310
 
  >>> from lp.registry.interfaces.person import IPersonSet
311
 
  >>> name16 = getUtility(IPersonSet).getByName('name16')
312
 
  >>> name16.displayname = "Foo B. Bar"
313
 
  >>> syncUpdate(name16)
 
315
    >>> from lp.registry.interfaces.person import IPersonSet
 
316
    >>> name16 = getUtility(IPersonSet).getByName('name16')
 
317
    >>> name16.displayname = "Foo B. Bar"
 
318
    >>> syncUpdate(name16)
314
319
 
315
320
Check the email recipient for displayname containing special chars,
316
321
'.', must be rfc2047 compliant:
317
322
 
318
 
  >>> simulate_upload('bar_1.0-4')
319
 
  >>> uninteresting_email = stub.test_emails.pop()
320
 
  >>> read_email()
321
 
  To: "Foo B. Bar" <foo.bar@canonical.com>,
322
 
        Celso Providelo <celso.providelo@canonical.com>
323
 
  Subject: [ubuntutest/breezy] bar 1.0-4 (Accepted)
324
 
  Content-Type: text/plain; charset="utf-8"
325
 
  MIME-Version: 1.0
326
 
  Content-Transfer-Encoding: quoted-printable
327
 
  <BLANKLINE>
328
 
  bar (1.0-4) breezy; urgency=3Dlow
329
 
  <BLANKLINE>
330
 
    * Changer using non-preferred email
331
 
  <BLANKLINE>
332
 
  Date: Tue, 25 Apr 2006 10:36:14 -0300
333
 
  Changed-By: Celso R. Providelo <cprov@ubuntu.com>
334
 
  Maintainer: Launchpad team <launchpad@lists.canonical.com>
335
 
  Signed-By: "Foo B. Bar" <foo.bar@canonical.com>
336
 
  http://launchpad.dev/ubuntutest/breezy/+source/bar/1.0-4
337
 
  <BLANKLINE>
338
 
  =3D=3D
339
 
  <BLANKLINE>
340
 
  Announcing to breezy-changes@ubuntu.com
341
 
  <BLANKLINE>
342
 
  Thank you for your contribution to Ubuntu Test.
343
 
  <BLANKLINE>
344
 
  -- =
345
 
  <BLANKLINE>
346
 
  You are receiving this email because you are the uploader, maintainer or
347
 
  signer of the above package.
348
 
  <BLANKLINE>
349
 
  <BLANKLINE>
 
323
    >>> simulate_upload('bar_1.0-4')
 
324
    >>> uninteresting_email = stub.test_emails.pop()
 
325
    >>> read_email()
 
326
    To: "Foo B. Bar" <foo.bar@canonical.com>,
 
327
          Celso Providelo <celso.providelo@canonical.com>
 
328
    Subject: [ubuntutest/breezy] bar 1.0-4 (Accepted)
 
329
    Content-Type: text/plain; charset="utf-8"
 
330
    MIME-Version: 1.0
 
331
    Content-Transfer-Encoding: quoted-printable
 
332
    <BLANKLINE>
 
333
    bar (1.0-4) breezy; urgency=3Dlow
 
334
    <BLANKLINE>
 
335
      * Changer using non-preferred email
 
336
    <BLANKLINE>
 
337
    Date: Tue, 25 Apr 2006 10:36:14 -0300
 
338
    Changed-By: Celso R. Providelo <cprov@ubuntu.com>
 
339
    Maintainer: Launchpad team <launchpad@lists.canonical.com>
 
340
    Signed-By: "Foo B. Bar" <foo.bar@canonical.com>
 
341
    http://launchpad.dev/ubuntutest/breezy/+source/bar/1.0-4
 
342
    <BLANKLINE>
 
343
    =3D=3D
 
344
    <BLANKLINE>
 
345
    Announcing to breezy-changes@ubuntu.com
 
346
    <BLANKLINE>
 
347
    Thank you for your contribution to Ubuntu Test.
 
348
    <BLANKLINE>
 
349
    -- =
 
350
    <BLANKLINE>
 
351
    You are receiving this email because you are the uploader, maintainer or
 
352
    signer of the above package.
 
353
    <BLANKLINE>
 
354
    <BLANKLINE>
350
355
 
351
356
Revert changes:
352
357
 
353
 
  >>> name16.displayname = "Foo Bar"
354
 
  >>> syncUpdate(name16)
 
358
    >>> name16.displayname = "Foo Bar"
 
359
    >>> syncUpdate(name16)
355
360
 
356
361
Check if we forcibly add the changer as recipient for "sync" uploads,
357
362
which contains unsigned changesfile. Ensure it sends email to the
358
363
changer.
359
364
 
360
 
  >>> stub.test_emails = []
 
365
    >>> stub.test_emails = []
361
366
 
362
 
  >>> simulate_upload('bar_1.0-5', upload_policy='sync')
363
 
  >>> read_email()
364
 
  To: Celso Providelo <celso.providelo@canonical.com>
365
 
  Subject: [ubuntutest/breezy] bar 1.0-5 (Accepted)
366
 
  ...
 
367
    >>> simulate_upload('bar_1.0-5', upload_policy='sync')
 
368
    >>> read_email()
 
369
    To: Celso Providelo <celso.providelo@canonical.com>
 
370
    Subject: [ubuntutest/breezy] bar 1.0-5 (Accepted)
 
371
    ...
367
372
 
368
373
 
369
374
Add a new series of bar sourcepackage, rename its binary package to
370
375
'bar-bin', upload the binary and look for a spurious sourcepackagename
371
376
created with the binary package name.
372
377
 
373
 
  >>> simulate_upload('bar_1.0-6', upload_policy='sync')
374
 
  >>> simulate_upload('bar_1.0-6_binary', is_new=True)
375
 
 
376
 
  >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
377
 
  >>> spn_set = getUtility(ISourcePackageNameSet)
378
 
  >>> assert spn_set.queryByName('bar-bin') is None
379
 
 
380
 
 
381
 
== Source Uploads using epochs ==
 
378
    >>> simulate_upload('bar_1.0-6', upload_policy='sync')
 
379
    >>> simulate_upload('bar_1.0-6_binary', is_new=True)
 
380
 
 
381
    >>> from lp.registry.interfaces.sourcepackagename import (
 
382
    ...     ISourcePackageNameSet)
 
383
    >>> spn_set = getUtility(ISourcePackageNameSet)
 
384
    >>> assert spn_set.queryByName('bar-bin') is None
 
385
 
 
386
 
 
387
Source Uploads using epochs
 
388
---------------------------
382
389
 
383
390
As described in Debian Policy
384
391
(http://www.debian.org/doc/debian-policy/ch-controlfields.html)
406
413
Check if upload system interpret epochs properly, inter-epoch versions
407
414
will get compared in this case (see bug #85201):
408
415
 
409
 
  >>> simulate_upload('bar_1.0-7', upload_policy='sync')
410
 
  >>> read_email()
411
 
  To: ...
412
 
  Subject: [ubuntutest/breezy] bar 1.0-6 (Accepted)
413
 
  ...
414
 
 
415
 
  >>> simulate_upload('bar_1.0-8', upload_policy='sync')
416
 
  >>> read_email()
417
 
  To: ...
418
 
  Subject: [ubuntutest/breezy] bar 1:1.0-8 (Accepted)
419
 
  ...
420
 
 
421
 
== Pocket Version Consistency ==
 
416
    >>> simulate_upload('bar_1.0-7', upload_policy='sync')
 
417
    >>> read_email()
 
418
    To: ...
 
419
    Subject: [ubuntutest/breezy] bar 1.0-6 (Accepted)
 
420
    ...
 
421
 
 
422
    >>> simulate_upload('bar_1.0-8', upload_policy='sync')
 
423
    >>> read_email()
 
424
    To: ...
 
425
    Subject: [ubuntutest/breezy] bar 1:1.0-8 (Accepted)
 
426
    ...
 
427
 
 
428
Pocket Version Consistency
 
429
--------------------------
422
430
 
423
431
Check behaviour of upload system for uploads across pockets (see
424
432
bug #34089, #58144 and #83976 for further info)
426
434
Let's start a new package series by uploading foo_1.0-1  source in
427
435
ubututest/breezy-RELEASE:
428
436
 
429
 
  >>> simulate_upload(
430
 
  ...     'foo_1.0-1', upload_policy='sync', is_new=True,
431
 
  ...     loglevel=logging.DEBUG)
432
 
  DEBUG Initializing connection.
433
 
  ...
434
 
  DEBUG Sent a mail:
435
 
  DEBUG   Subject: [ubuntutest/breezy] foo 1.0-1 (New)
436
 
  DEBUG   Sender: Root <root@localhost>
437
 
  DEBUG   Recipients: Daniel Silverstone <daniel.silverstone@canonical.com>
438
 
  DEBUG   Bcc: Root <root@localhost>
439
 
  DEBUG   Body:
440
 
  DEBUG NEW: foo_1.0.orig.tar.gz
441
 
  DEBUG NEW: foo_1.0-1.diff.gz
442
 
  DEBUG NEW: foo_1.0-1.dsc
443
 
  DEBUG
444
 
  DEBUG foo (1.0-1) breezy; urgency=low
445
 
  DEBUG
446
 
  DEBUG   * Initial version
447
 
  DEBUG
448
 
  DEBUG
449
 
  DEBUG Your package contains new components which requires manual editing of
450
 
  DEBUG the override file.  It is ok otherwise, so please be patient.  New
451
 
  DEBUG packages are usually added to the overrides about once a week.
452
 
  DEBUG
453
 
  DEBUG You may have gotten the distroseries wrong.  If so, you may get warnings
454
 
  DEBUG above if files already exist in other distroseries.
455
 
  DEBUG
456
 
  DEBUG --
457
 
  DEBUG You are receiving this email because you are the uploader, maintainer or
458
 
  DEBUG signer of the above package.
459
 
  INFO  Committing the transaction and any mails associated with this upload.
460
 
  ...
461
 
  Upload complete.
 
437
    >>> simulate_upload(
 
438
    ...     'foo_1.0-1', upload_policy='sync', is_new=True,
 
439
    ...     loglevel=logging.DEBUG)
 
440
    DEBUG Initializing connection.
 
441
    ...
 
442
    DEBUG Sent a mail:
 
443
    DEBUG   Subject: [ubuntutest/breezy] foo 1.0-1 (New)
 
444
    DEBUG   Sender: Root <root@localhost>
 
445
    DEBUG   Recipients: Daniel Silverstone <daniel.silverstone@canonical.com>
 
446
    DEBUG   Bcc: Root <root@localhost>
 
447
    DEBUG   Body:
 
448
    DEBUG NEW: foo_1.0.orig.tar.gz
 
449
    DEBUG NEW: foo_1.0-1.diff.gz
 
450
    DEBUG NEW: foo_1.0-1.dsc
 
451
    DEBUG
 
452
    DEBUG foo (1.0-1) breezy; urgency=low
 
453
    DEBUG
 
454
    DEBUG   * Initial version
 
455
    DEBUG
 
456
    DEBUG
 
457
    DEBUG Your package contains new components which requires manual editing
 
458
    of
 
459
    DEBUG the override file.  It is ok otherwise, so please be patient.  New
 
460
    DEBUG packages are usually added to the overrides about once a week.
 
461
    DEBUG
 
462
    DEBUG You may have gotten the distroseries wrong.  If so, you may get
 
463
    warnings
 
464
    DEBUG above if files already exist in other distroseries.
 
465
    DEBUG
 
466
    DEBUG --
 
467
    DEBUG You are receiving this email because you are the uploader,
 
468
    maintainer or
 
469
    DEBUG signer of the above package.
 
470
    INFO  Committing the transaction and any mails associated with this
 
471
    upload.
 
472
    ...
 
473
    Upload complete.
462
474
 
463
475
And its binary:
464
476
 
465
 
  >>> simulate_upload(
466
 
  ...     'foo_1.0-1_i386_binary', upload_policy='anything', is_new=True,
467
 
  ...     loglevel=logging.DEBUG)
468
 
  DEBUG ...
469
 
  DEBUG foo: (binary) NEW
470
 
  ...
471
 
  Upload complete.
 
477
    >>> simulate_upload(
 
478
    ...     'foo_1.0-1_i386_binary', upload_policy='anything', is_new=True,
 
479
    ...     loglevel=logging.DEBUG)
 
480
    DEBUG ...
 
481
    DEBUG foo: (binary) NEW
 
482
    ...
 
483
    Upload complete.
472
484
 
473
485
Set ubuntutest/breezy as the "current series" to activate post-release
474
486
pockets.
475
487
 
476
 
  >>> from lp.registry.interfaces.series import SeriesStatus
477
 
  >>> breezy.status = SeriesStatus.CURRENT
478
 
  >>> LaunchpadZopelessLayer.txn.commit()
 
488
    >>> from lp.registry.interfaces.series import SeriesStatus
 
489
    >>> breezy.status = SeriesStatus.CURRENT
 
490
    >>> LaunchpadZopelessLayer.txn.commit()
479
491
 
480
492
Since we are using 'sync' policy in the following tests the packages
481
493
are auto-approved, however, in the real environment the 'insecure'
484
496
 
485
497
Upload a newer version of source package "foo" to breezy-backports:
486
498
 
487
 
  >>> simulate_upload(
488
 
  ...     'foo_2.9-1', upload_policy='sync', loglevel=logging.DEBUG)
489
 
  DEBUG Initializing connection.
490
 
  ...
491
 
  DEBUG Setting it to ACCEPTED
492
 
  ...
493
 
  Upload complete.
 
499
    >>> simulate_upload(
 
500
    ...     'foo_2.9-1', upload_policy='sync', loglevel=logging.DEBUG)
 
501
    DEBUG Initializing connection.
 
502
    ...
 
503
    DEBUG Setting it to ACCEPTED
 
504
    ...
 
505
    Upload complete.
494
506
 
495
507
 
496
508
In order to verify if the binary ancestry lookup algorithm works we
497
509
will need to build a new DistroArchSeries for powerpc in
498
510
ubuntutest/breezy.
499
511
 
500
 
  >>> from lp.soyuz.model.processor import (
501
 
  ...     ProcessorFamily, Processor)
502
 
  >>> powerpc_pf = ProcessorFamily.selectOneBy(name='powerpc')
503
 
  >>> powerpc_proc = Processor(family=powerpc_pf, name='powerpc',
504
 
  ...                          title='PowerPC G3/G4', description='G3/G4')
505
 
  >>> powerpc_dar = breezy.newArch('powerpc', powerpc_pf, True, breezy.owner)
 
512
    >>> from lp.soyuz.model.processor import (
 
513
    ...     ProcessorFamily, Processor)
 
514
    >>> powerpc_pf = ProcessorFamily.selectOneBy(name='powerpc')
 
515
    >>> powerpc_proc = Processor(family=powerpc_pf, name='powerpc',
 
516
    ...                          title='PowerPC G3/G4', description='G3/G4')
 
517
    >>> powerpc_dar = breezy.newArch(
 
518
    ...     'powerpc', powerpc_pf, True, breezy.owner)
506
519
 
507
520
After having the respective DistroArchSeries in place we will submit a
508
521
binary upload for the last source in BACKPORTS. The ancestry should be
509
522
found in i386/RELEASE, because it's the only one available.
510
523
 
511
 
  >>> simulate_upload(
512
 
  ...     'foo_2.9-1_binary', upload_policy='anything',
513
 
  ...     loglevel=logging.DEBUG)
514
 
  DEBUG ...
515
 
  DEBUG Checking for foo/2.9-1/powerpc binary ancestry
516
 
  DEBUG foo-1.0-1 (binary) exists in i386/RELEASE
517
 
  ...
518
 
  Upload complete.
 
524
    >>> simulate_upload(
 
525
    ...     'foo_2.9-1_binary', upload_policy='anything',
 
526
    ...     loglevel=logging.DEBUG)
 
527
    DEBUG ...
 
528
    DEBUG Checking for foo/2.9-1/powerpc binary ancestry
 
529
    DEBUG foo-1.0-1 (binary) exists in i386/RELEASE
 
530
    ...
 
531
    Upload complete.
519
532
 
520
533
 
521
534
Due the constraints relaxation requested by bug #83976, even having
524
537
it should be rejected by the package reviewer, otherwise people can
525
538
live with this inconsistency.
526
539
 
527
 
  >>> simulate_upload(
528
 
  ...     'foo_2.9-2', upload_policy='sync', loglevel=logging.DEBUG)
529
 
  DEBUG Initializing connection.
530
 
  ...
531
 
  DEBUG Setting it to ACCEPTED
532
 
  ...
533
 
  Upload complete.
 
540
    >>> simulate_upload(
 
541
    ...     'foo_2.9-2', upload_policy='sync', loglevel=logging.DEBUG)
 
542
    DEBUG Initializing connection.
 
543
    ...
 
544
    DEBUG Setting it to ACCEPTED
 
545
    ...
 
546
    Upload complete.
534
547
 
535
548
 
536
549
Same behaviour is expected for a version in SECURITY lower than that
537
550
in PROPOSED:
538
551
 
539
 
  >>> simulate_upload(
540
 
  ...     'foo_2.9-4', upload_policy='sync', loglevel=logging.DEBUG)
541
 
  DEBUG Initializing connection.
542
 
  ...
543
 
  DEBUG Setting it to ACCEPTED
544
 
  ...
545
 
  Upload complete.
 
552
    >>> simulate_upload(
 
553
    ...     'foo_2.9-4', upload_policy='sync', loglevel=logging.DEBUG)
 
554
    DEBUG Initializing connection.
 
555
    ...
 
556
    DEBUG Setting it to ACCEPTED
 
557
    ...
 
558
    Upload complete.
546
559
 
547
 
  >>> simulate_upload(
548
 
  ...     'foo_2.9-3', upload_policy='sync', loglevel=logging.DEBUG)
549
 
  DEBUG Initializing connection.
550
 
  ...
551
 
  DEBUG Setting it to ACCEPTED
552
 
  ...
553
 
  Upload complete.
 
560
    >>> simulate_upload(
 
561
    ...     'foo_2.9-3', upload_policy='sync', loglevel=logging.DEBUG)
 
562
    DEBUG Initializing connection.
 
563
    ...
 
564
    DEBUG Setting it to ACCEPTED
 
565
    ...
 
566
    Upload complete.
554
567
 
555
568
 
556
569
However, the source upload of a smaller version than the one already
557
570
published inside the target pocket should be rejected:
558
571
 
559
 
  >>> simulate_upload(
560
 
  ...     'foo_1.0-3', upload_policy='sync', loglevel=logging.INFO)
561
 
  INFO ...
562
 
  INFO Upload was rejected:
563
 
  INFO foo_1.0-3.dsc: Version older than that in the archive. 1.0-3 <= 2.9-2
564
 
  ...
565
 
  Rejected uploads: ['foo_1.0-3']
 
572
    >>> simulate_upload(
 
573
    ...     'foo_1.0-3', upload_policy='sync', loglevel=logging.INFO)
 
574
    INFO ...
 
575
    INFO Upload was rejected:
 
576
    INFO foo_1.0-3.dsc: Version older than that in the archive. 1.0-3 <= 2.9-2
 
577
    ...
 
578
    Rejected uploads: ['foo_1.0-3']
566
579
 
567
580
Note that the ancestry pointed in the rejection message (2.9-2) is what
568
581
we expect.
570
583
Set ubuntutest/breezy to 'experimental' state again to not affect the
571
584
rest of the test:
572
585
 
573
 
  >>> breezy.status = SeriesStatus.EXPERIMENTAL
574
 
  >>> breezy.syncUpdate()
575
 
 
576
 
 
577
 
== Staged Security Uploads ==
 
586
    >>> breezy.status = SeriesStatus.EXPERIMENTAL
 
587
    >>> breezy.syncUpdate()
 
588
 
 
589
 
 
590
Staged Security Uploads
 
591
-----------------------
578
592
 
579
593
XXX: Salgado, 2010-08-25, bug=624078: This entire section should be removed
580
594
but if you do so publish-distro.py (called further down) will hang.
584
598
allowed a security upload, we need to use a released distroseries,
585
599
eg ubuntu/warty.
586
600
 
587
 
  >>> from lp.soyuz.model.section import (
588
 
  ...     Section, SectionSelection)
589
 
  >>> warty = ubuntu['warty']
590
 
  >>> devel = Section.selectOneBy(name="devel")
591
 
  >>> ss = SectionSelection(distroseries=warty, section=devel)
 
601
    >>> from lp.soyuz.model.section import (
 
602
    ...     Section, SectionSelection)
 
603
    >>> warty = ubuntu['warty']
 
604
    >>> devel = Section.selectOneBy(name="devel")
 
605
    >>> ss = SectionSelection(distroseries=warty, section=devel)
592
606
 
593
 
  >>> simulate_upload(
594
 
  ...     'baz_1.0-1', is_new=True, upload_policy="anything",
595
 
  ...     series="warty-security", distro="ubuntu")
 
607
    >>> simulate_upload(
 
608
    ...     'baz_1.0-1', is_new=True, upload_policy="anything",
 
609
    ...     series="warty-security", distro="ubuntu")
596
610
 
597
611
Check there's a SourcePackageRelease with no build.
598
612
 
599
 
  >>> from lp.buildmaster.enums import BuildStatus
600
 
  >>> from lp.registry.interfaces.pocket import PackagePublishingPocket
601
 
  >>> from lp.registry.model.sourcepackagename import SourcePackageName
602
 
  >>> from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
603
 
  >>> from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
604
 
  >>> spn = SourcePackageName.selectOneBy(name="baz")
605
 
  >>> spr = SourcePackageRelease.selectOneBy(sourcepackagenameID=spn.id)
606
 
  >>> spr_id = spr.id
607
 
  >>> builds = BinaryPackageBuild.selectBy(source_package_release_id=spr_id)
608
 
  >>> len(list(builds))
609
 
  0
 
613
    >>> from lp.buildmaster.enums import BuildStatus
 
614
    >>> from lp.registry.model.sourcepackagename import SourcePackageName
 
615
    >>> from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
 
616
    >>> from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
 
617
    >>> spn = SourcePackageName.selectOneBy(name="baz")
 
618
    >>> spr = SourcePackageRelease.selectOneBy(sourcepackagenameID=spn.id)
 
619
    >>> spr_id = spr.id
 
620
    >>> builds = BinaryPackageBuild.selectBy(source_package_release_id=spr_id)
 
621
    >>> len(list(builds))
 
622
    0
610
623
 
611
624
Manually create a build for this spr in i386.  This simulates the
612
625
buildd-queuebuilder having run inbetween the source and binary uploads.
613
626
 
614
 
  >>> warty_i386 = ubuntu['warty']['i386']
615
 
  >>> main_archive = ubuntu.main_archive
616
 
  >>> build = spr.createBuild(warty_i386, PackagePublishingPocket.SECURITY,
617
 
  ...                         main_archive, status=BuildStatus.NEEDSBUILD)
 
627
    >>> warty_i386 = ubuntu['warty']['i386']
 
628
    >>> main_archive = ubuntu.main_archive
 
629
    >>> build = spr.createBuild(warty_i386, PackagePublishingPocket.SECURITY,
 
630
    ...                         main_archive, status=BuildStatus.NEEDSBUILD)
618
631
 
619
632
Check build created
620
633
 
621
 
  >>> len(list(BinaryPackageBuild.selectBy(source_package_release_id=spr_id)))
622
 
  1
 
634
    >>> len(list(BinaryPackageBuild.selectBy(
 
635
    ...     source_package_release_id=spr_id)))
 
636
    1
623
637
 
624
638
Upload the i386 binary:
625
639
 
626
 
  >>> simulate_upload(
627
 
  ...     'baz_1.0-1_single_binary', is_new=True, upload_policy="anything",
628
 
  ...     distro="ubuntu", series="warty-security")
 
640
    >>> simulate_upload(
 
641
    ...     'baz_1.0-1_single_binary', is_new=True, upload_policy="anything",
 
642
    ...     distro="ubuntu", series="warty-security")
629
643
 
630
644
Should still just have one build, and it should now be FULLYBUILT.
631
645
 
632
 
  >>> from canonical.database.sqlbase import clear_current_connection_cache
633
 
  >>> clear_current_connection_cache()
 
646
    >>> from canonical.database.sqlbase import clear_current_connection_cache
 
647
    >>> clear_current_connection_cache()
634
648
 
635
 
  >>> builds = list(BinaryPackageBuild.selectBy(
636
 
  ...     source_package_release_id=spr_id))
637
 
  >>> len(builds)
638
 
  1
639
 
  >>> builds[0].status == BuildStatus.FULLYBUILT
640
 
  True
 
649
    >>> builds = list(BinaryPackageBuild.selectBy(
 
650
    ...     source_package_release_id=spr_id))
 
651
    >>> len(builds)
 
652
    1
 
653
    >>> builds[0].status == BuildStatus.FULLYBUILT
 
654
    True
641
655
 
642
656
 
643
657
Regression test for bug 54039. Currently must be here, see bug 54158.
654
668
 
655
669
First a couple helpers.
656
670
 
657
 
  >>> import os
658
 
  >>> import stat
659
 
  >>> from canonical.launchpad.ftests.script import run_script
660
 
 
661
 
  >>> def run_publish_distro(careful=False, careful_publishing=False):
662
 
  ...     """Run publish-distro on ubuntutest with given extra args.
663
 
  ...
664
 
  ...     :param careful: turns on all "careful" options to the publish-distro
665
 
  ...         script.  Equivalent to the script's --careful option.
666
 
  ...     :param careful_publishing: passes the --careful-publishing option
667
 
  ...         to the publish-distro script.
668
 
  ...     """
669
 
  ...     args = ["-v", "-d", "ubuntutest"]
670
 
  ...     if careful:
671
 
  ...         args.append("-C")
672
 
  ...     if careful_publishing:
673
 
  ...         args.append("-P")
674
 
  ...     script = os.path.join(config.root, "scripts", "publish-distro.py")
675
 
  ...     result, stdout, stderr = run_script(script, args)
676
 
  ...     print stderr
677
 
  ...     if result != 0:
678
 
  ...         print "Script returned", result
679
 
 
680
 
  >>> def release_file_has_uncompressed_packages(path):
681
 
  ...     """Return whether the release file includes uncompressed Packages."""
682
 
  ...     release_file = open(path)
683
 
  ...     release_contents = release_file.read()
684
 
  ...     release_file.close()
685
 
  ...     target_string = "Packages\n"
686
 
  ...     return release_contents.find(target_string) != -1
 
671
    >>> import os
 
672
    >>> import stat
 
673
    >>> from canonical.launchpad.ftests.script import run_script
 
674
 
 
675
    >>> def run_publish_distro(careful=False, careful_publishing=False):
 
676
    ...     """Run publish-distro on ubuntutest with given extra args.
 
677
    ...
 
678
    ...     :param careful: turns on all "careful" options to the
 
679
    ...         publish-distro script.  Equivalent to the script's --careful
 
680
    ...         option.
 
681
    ...     :param careful_publishing: passes the --careful-publishing option
 
682
    ...         to the publish-distro script.
 
683
    ...     """
 
684
    ...     args = ["-v", "-d", "ubuntutest"]
 
685
    ...     if careful:
 
686
    ...         args.append("-C")
 
687
    ...     if careful_publishing:
 
688
    ...         args.append("-P")
 
689
    ...     script = os.path.join(config.root, "scripts", "publish-distro.py")
 
690
    ...     result, stdout, stderr = run_script(script, args)
 
691
    ...     print stderr
 
692
    ...     if result != 0:
 
693
    ...         print "Script returned", result
 
694
 
 
695
    >>> def release_file_has_uncompressed_packages(path):
 
696
    ...     """Does the release file include uncompressed Packages?"""
 
697
    ...     release_file = open(path)
 
698
    ...     release_contents = release_file.read()
 
699
    ...     release_file.close()
 
700
    ...     target_string = "Packages\n"
 
701
    ...     return release_contents.find(target_string) != -1
687
702
 
688
703
 
689
704
First publish the distro carefully, to get everything in place.
690
705
Before this can happen we need to set up some dummy librarian files for
691
706
files that are published in the sample data.
692
707
 
693
 
  >>> fillLibrarianFile(66)
694
 
  >>> fillLibrarianFile(67)
695
 
  >>> fillLibrarianFile(68)
696
 
  >>> fillLibrarianFile(70)
 
708
    >>> fillLibrarianFile(66)
 
709
    >>> fillLibrarianFile(67)
 
710
    >>> fillLibrarianFile(68)
 
711
    >>> fillLibrarianFile(70)
697
712
 
698
 
  >>> run_publish_distro(careful=True)
699
 
  DEBUG   Initializing zopeless.
700
 
  DEBUG   Distribution: ubuntutest
701
 
  ...
702
 
  DEBUG   Added /var/tmp/archive/ubuntutest/pool/universe/b/bar/bar_1.0-2_i386.deb from library
703
 
  DEBUG   Added /var/tmp/archive/ubuntutest/pool/universe/b/bar/bar_1.0-1_i386.deb from library
704
 
  ...
 
713
    >>> run_publish_distro(careful=True)
 
714
    DEBUG   Initializing zopeless.
 
715
    DEBUG   Distribution: ubuntutest
 
716
    ...
 
717
    DEBUG   Added /var/tmp/archive/ubuntutest/pool/universe/b/bar/bar_1.0-2_i386.deb from library
 
718
    DEBUG   Added /var/tmp/archive/ubuntutest/pool/universe/b/bar/bar_1.0-1_i386.deb from library
 
719
    ...
705
720
 
706
721
 
707
722
Delete the uncompressed Packages and Sources files from the archive folder.
708
723
This simulates what cron.daily does between publishing runs.
709
724
 
710
 
  >>> os.system('find /var/tmp/archive/ubuntutest \\( -name "Packages" '
711
 
  ...           '-o -name "Sources" \\) -exec rm "{}" \\;')
712
 
  0
 
725
    >>> os.system('find /var/tmp/archive/ubuntutest \\( -name "Packages" '
 
726
    ...           '-o -name "Sources" \\) -exec rm "{}" \\;')
 
727
    0
713
728
 
714
729
Record the timestamp of a release file we expect to be rewritten,
715
730
which we'll need later.
716
731
 
717
 
  >>> release_timestamp = os.stat('/var/tmp/archive/ubuntutest/dists/'
718
 
  ...     'breezy/Release')[stat.ST_MTIME]
 
732
    >>> release_timestamp = os.stat('/var/tmp/archive/ubuntutest/dists/'
 
733
    ...     'breezy/Release')[stat.ST_MTIME]
719
734
 
720
735
Re-publish the distribution, with careful publishing only. This will mean
721
736
only pockets into which we've done some publication will have apt-ftparchive
724
739
Check that breezy-autotest is skipped, to ensure that changes to what's
725
740
uploaded in the test above don't break the assumptions of this test.
726
741
 
727
 
  >>> run_publish_distro(careful_publishing=True)
728
 
  DEBUG   Initializing zopeless.
729
 
  DEBUG   Distribution: ubuntutest
730
 
  ...
731
 
  DEBUG   /var/tmp/archive/ubuntutest/pool/universe/b/bar/bar_1.0-2_i386.deb is already in pool with the same content.
732
 
  ...
733
 
  DEBUG   Skipping a-f stanza for breezy-autotest/RELEASE
734
 
  ...
735
 
  DEBUG   Skipping release files for breezy-autotest/RELEASE
736
 
  ...
 
742
    >>> run_publish_distro(careful_publishing=True)
 
743
    DEBUG   Initializing zopeless.
 
744
    DEBUG   Distribution: ubuntutest
 
745
    ...
 
746
    DEBUG   /var/tmp/archive/ubuntutest/pool/universe/b/bar/bar_1.0-2_i386.deb is already in pool with the same content.
 
747
    ...
 
748
    DEBUG   Skipping a-f stanza for breezy-autotest/RELEASE
 
749
    ...
 
750
    DEBUG   Skipping release files for breezy-autotest/RELEASE
 
751
    ...
737
752
 
738
753
Check the breezy-security release file doesn't exhibit bug 54039.
739
754
 
740
 
  >>> release_file_has_uncompressed_packages(
741
 
  ...     '/var/tmp/archive/ubuntutest/dists/breezy-security/Release')
742
 
  True
 
755
    >>> release_file_has_uncompressed_packages(
 
756
    ...     '/var/tmp/archive/ubuntutest/dists/breezy-security/Release')
 
757
    True
743
758
 
744
759
We also need to check the fix for bug 54039 didn't go too far, ie. that
745
760
Release files are still generated for those pockets where they should be.
746
761
So, check the MTIME has changed for hoary-test/Release.
747
762
 
748
 
  >>> new_release_timestamp = os.stat('/var/tmp/archive/ubuntutest/dists/'
749
 
  ...     'breezy/Release')[stat.ST_MTIME]
750
 
 
751
 
  >>> new_release_timestamp == release_timestamp
752
 
  False
753
 
 
 
763
    >>> new_release_timestamp = os.stat('/var/tmp/archive/ubuntutest/dists/'
 
764
    ...     'breezy/Release')[stat.ST_MTIME]
 
765
 
 
766
    >>> new_release_timestamp == release_timestamp
 
767
    False
754
768
 
755
769
 
756
770
Nice! That's enough for now.. let's kill the process and clean
757
771
everything up.
758
772
 
759
 
  >>> shutil.rmtree("/var/tmp/archive/")
760
 
  >>> shutil.rmtree(temp_dir)
761
 
 
762
 
  >>> keyserver.tearDown()
763
 
 
 
773
    >>> shutil.rmtree("/var/tmp/archive/")
 
774
    >>> shutil.rmtree(temp_dir)
 
775
 
 
776
    >>> keyserver.tearDown()