Merge lp:~allenap/launchpad/dd-initseries-bug-727105-derive-distro-series into lp:launchpad

Proposed by Gavin Panella
Status: Merged
Approved by: Gavin Panella
Approved revision: no longer in the source branch.
Merged at revision: 12705
Proposed branch: lp:~allenap/launchpad/dd-initseries-bug-727105-derive-distro-series
Merge into: lp:launchpad
Prerequisite: lp:~allenap/launchpad/dd-initseries-bug-727105-copy-options
Diff against target: 621 lines (+167/-108)
10 files modified
lib/lp/registry/configure.zcml (+3/-0)
lib/lp/registry/interfaces/distroseries.py (+2/-1)
lib/lp/registry/model/distroseries.py (+4/-3)
lib/lp/registry/tests/test_derivedistroseries.py (+13/-11)
lib/lp/soyuz/model/distributionjob.py (+11/-10)
lib/lp/soyuz/model/initialisedistroseriesjob.py (+27/-12)
lib/lp/soyuz/scripts/initialise_distroseries.py (+14/-5)
lib/lp/soyuz/scripts/tests/test_initialise_distroseries.py (+18/-17)
lib/lp/soyuz/tests/test_initialisedistroseriesjob.py (+56/-38)
scripts/ftpmaster-tools/initialise-from-parent.py (+19/-11)
To merge this branch: bzr merge lp:~allenap/launchpad/dd-initseries-bug-727105-derive-distro-series
Reviewer Review Type Date Requested Status
Gavin Panella (community) Approve
Steve Kowalik (community) code Approve
Review via email: mp+54742@code.launchpad.net

Description of the change

Currently, InitializeDistroSeries() needs the child series'
parent_series property set. However, other parts of the code consider
parent_series to be a marker for when a series has *already* been
initialized.

This branch changes the assumption. The InitialiseDistroSeriesJob now
takes another parameter, parent, that it stores in its metadata, and
InitialiseDistroSeries now also accepts a parent parameter. It is the
latter's responsibility for updating the child's parent_series
property. This also means that failed initializations (aka
derivations) don't leave the series in a limbo state.

IDistroSeries.parent_series is now editable by those with
launchpad.Admin. However, it is exported to the API as read-only, so
it cannot be modified except by internal code.

To post a comment you must log in.
Revision history for this message
Steve Kowalik (stevenk) wrote :

This looks great to me, expect for the error message of "Parent series has already been initialized." It strikes me as ambiguous, since the parent series *has* been initialized, but you mean the child's parent series has already been set.

review: Approve (code)
Revision history for this message
Gavin Panella (allenap) :
review: Approve
Revision history for this message
Gavin Panella (allenap) wrote :

> This looks great to me, expect for the error message of "Parent
> series has already been initialized." It strikes me as ambiguous,
> since the parent series *has* been initialized, but you mean the
> child's parent series has already been set.

Oops, good catch. I've changed it to:

  DistroSeries child-name has been initialized; it derives from
  parent-distro-name/parent-name.

Thanks for the review!

Gavin.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/configure.zcml'
2--- lib/lp/registry/configure.zcml 2011-03-23 16:28:51 +0000
3+++ lib/lp/registry/configure.zcml 2011-03-30 16:11:08 +0000
4@@ -195,6 +195,9 @@
5 permission="launchpad.Edit"
6 interface="lp.registry.interfaces.distroseries.IDistroSeriesEditRestricted"/>
7 <require
8+ permission="launchpad.Admin"
9+ set_attributes="parent_series"/>
10+ <require
11 permission="launchpad.TranslationsAdmin"
12 set_attributes="hide_all_translations defer_translation_imports"/>
13 <require
14
15=== modified file 'lib/lp/registry/interfaces/distroseries.py'
16--- lib/lp/registry/interfaces/distroseries.py 2011-03-30 16:11:05 +0000
17+++ lib/lp/registry/interfaces/distroseries.py 2011-03-30 16:11:08 +0000
18@@ -242,7 +242,8 @@
19 title=_("Parent series"),
20 description=_("The series from which this one was branched."),
21 required=True, schema=Interface, # Really IDistroSeries, see below
22- vocabulary='DistroSeries'))
23+ vocabulary='DistroSeries'),
24+ readonly=True)
25 owner = exported(
26 PublicPersonChoice(title=_("Owner"), vocabulary='ValidOwner'))
27 date_created = exported(
28
29=== modified file 'lib/lp/registry/model/distroseries.py'
30--- lib/lp/registry/model/distroseries.py 2011-03-28 20:54:50 +0000
31+++ lib/lp/registry/model/distroseries.py 2011-03-30 16:11:08 +0000
32@@ -1963,12 +1963,13 @@
33 child = distribution.newSeries(
34 name=name, displayname=displayname, title=title,
35 summary=summary, description=description,
36- version=version, parent_series=self, owner=user)
37+ version=version, parent_series=None, owner=user)
38 IStore(self).add(child)
39 else:
40- if child.parent_series is not self:
41+ if child.parent_series is not None:
42 raise DerivationError(
43- "DistroSeries %s parent series isn't %s" % (
44+ "DistroSeries %s parent series is %s, "
45+ "but it must not be set" % (
46 child.name, self.name))
47 initialise_series = InitialiseDistroSeries(child)
48 try:
49
50=== modified file 'lib/lp/registry/tests/test_derivedistroseries.py'
51--- lib/lp/registry/tests/test_derivedistroseries.py 2011-03-09 09:53:59 +0000
52+++ lib/lp/registry/tests/test_derivedistroseries.py 2011-03-30 16:11:08 +0000
53@@ -6,6 +6,10 @@
54
55 __metaclass__ = type
56
57+from zope.component import getUtility
58+from zope.security.interfaces import Unauthorized
59+from zope.security.proxy import removeSecurityProxy
60+
61 from canonical.testing.layers import LaunchpadFunctionalLayer
62 from lp.registry.interfaces.distroseries import DerivationError
63 from lp.soyuz.interfaces.distributionjob import (
64@@ -17,8 +21,6 @@
65 TestCaseWithFactory,
66 )
67 from lp.testing.sampledata import ADMIN_EMAIL
68-from zope.component import getUtility
69-from zope.security.interfaces import Unauthorized
70
71
72 class TestDeriveDistroSeries(TestCaseWithFactory):
73@@ -29,8 +31,7 @@
74 super(TestDeriveDistroSeries, self).setUp()
75 self.soyuz = self.factory.makeTeam(name='soyuz-team')
76 self.parent = self.factory.makeDistroSeries()
77- self.child = self.factory.makeDistroSeries(
78- parent_series=self.parent)
79+ self.child = self.factory.makeDistroSeries()
80
81 def test_no_permission_to_call(self):
82 login(ADMIN_EMAIL)
83@@ -50,13 +51,15 @@
84 self.parent.deriveDistroSeries, self.soyuz.teamowner,
85 'newdistro')
86
87- def test_parent_is_not_self(self):
88- other = self.factory.makeDistroSeries()
89+ def test_parent_is_not_set(self):
90+ # When parent_series is set it means that the distroseries has already
91+ # been derived, and it is forbidden to derive more than once.
92+ removeSecurityProxy(self.child).parent_series = self.parent
93 self.assertRaisesWithContent(
94 DerivationError,
95- "DistroSeries %s parent series isn't %s" % (
96- self.child.name, other.name),
97- other.deriveDistroSeries, self.soyuz.teamowner,
98+ ("DistroSeries {self.child.name} parent series is "
99+ "{self.parent.name}, but it must not be set").format(self=self),
100+ self.parent.deriveDistroSeries, self.soyuz.teamowner,
101 self.child.name, self.child.distribution)
102
103 def test_create_new_distroseries(self):
104@@ -79,8 +82,7 @@
105 # Make two distroseries with the same name and different
106 # distributions to check that the right distroseries is initialised.
107 self.factory.makeDistroSeries(name='bar')
108- bar = self.factory.makeDistroSeries(
109- name='bar', parent_series=self.parent)
110+ bar = self.factory.makeDistroSeries(name='bar')
111 self.parent.deriveDistroSeries(
112 self.soyuz.teamowner, 'bar', distribution=bar.parent,
113 displayname='Bar', title='The Bar', summary='Bar',
114
115=== modified file 'lib/lp/soyuz/model/distributionjob.py'
116--- lib/lp/soyuz/model/distributionjob.py 2011-03-10 14:05:51 +0000
117+++ lib/lp/soyuz/model/distributionjob.py 2011-03-30 16:11:08 +0000
118@@ -8,27 +8,28 @@
119 "DistributionJobDerived",
120 ]
121
122+from lazr.delegates import delegates
123 import simplejson
124-
125-from storm.locals import And, Int, Reference, Unicode
126-
127+from storm.locals import (
128+ And,
129+ Int,
130+ Reference,
131+ Unicode,
132+ )
133 from zope.interface import implements
134
135 from canonical.database.enumcol import EnumCol
136 from canonical.launchpad.interfaces.lpstorm import IStore
137-
138-from lazr.delegates import delegates
139-
140 from lp.app.errors import NotFoundError
141 from lp.registry.model.distribution import Distribution
142 from lp.registry.model.distroseries import DistroSeries
143+from lp.services.database.stormbase import StormBase
144+from lp.services.job.model.job import Job
145+from lp.services.job.runner import BaseRunnableJob
146 from lp.soyuz.interfaces.distributionjob import (
147 DistributionJobType,
148 IDistributionJob,
149 )
150-from lp.services.job.model.job import Job
151-from lp.services.job.runner import BaseRunnableJob
152-from lp.services.database.stormbase import StormBase
153
154
155 class DistributionJob(StormBase):
156@@ -106,7 +107,7 @@
157
158 def getOopsVars(self):
159 """See `IRunnableJob`."""
160- vars = BaseRunnableJob.getOopsVars(self)
161+ vars = super(DistributionJobDerived, self).getOopsVars()
162 vars.extend([
163 ('distribution_id', self.context.distribution.id),
164 ('distroseries_id', self.context.distroseries.id),
165
166=== modified file 'lib/lp/soyuz/model/initialisedistroseriesjob.py'
167--- lib/lp/soyuz/model/initialisedistroseriesjob.py 2010-10-13 05:04:41 +0000
168+++ lib/lp/soyuz/model/initialisedistroseriesjob.py 2011-03-30 16:11:08 +0000
169@@ -7,10 +7,16 @@
170 "InitialiseDistroSeriesJob",
171 ]
172
173-from zope.interface import classProvides, implements
174-
175-from canonical.launchpad.interfaces.lpstorm import IMasterStore
176-
177+from zope.interface import (
178+ classProvides,
179+ implements,
180+ )
181+
182+from canonical.launchpad.interfaces.lpstorm import (
183+ IMasterStore,
184+ IStore,
185+ )
186+from lp.registry.model.distroseries import DistroSeries
187 from lp.soyuz.interfaces.distributionjob import (
188 DistributionJobType,
189 IInitialiseDistroSeriesJob,
190@@ -20,9 +26,7 @@
191 DistributionJob,
192 DistributionJobDerived,
193 )
194-from lp.soyuz.scripts.initialise_distroseries import (
195- InitialiseDistroSeries,
196- )
197+from lp.soyuz.scripts.initialise_distroseries import InitialiseDistroSeries
198
199
200 class InitialiseDistroSeriesJob(DistributionJobDerived):
201@@ -33,21 +37,26 @@
202 classProvides(IInitialiseDistroSeriesJobSource)
203
204 @classmethod
205- def create(cls, distroseries, arches=(), packagesets=(),
206- rebuild=False):
207+ def create(cls, parent, child, arches=(), packagesets=(), rebuild=False):
208 """See `IInitialiseDistroSeriesJob`."""
209 metadata = {
210+ 'parent': parent.id,
211 'arches': arches,
212 'packagesets': packagesets,
213 'rebuild': rebuild,
214 }
215 job = DistributionJob(
216- distroseries.distribution, distroseries, cls.class_job_type,
217+ child.distribution, child, cls.class_job_type,
218 metadata)
219 IMasterStore(DistributionJob).add(job)
220 return cls(job)
221
222 @property
223+ def parent(self):
224+ return IStore(DistroSeries).get(
225+ DistroSeries, self.metadata["parent"])
226+
227+ @property
228 def arches(self):
229 return tuple(self.metadata['arches'])
230
231@@ -62,7 +71,13 @@
232 def run(self):
233 """See `IRunnableJob`."""
234 ids = InitialiseDistroSeries(
235- self.distroseries, self.arches, self.packagesets,
236- self.rebuild)
237+ self.parent, self.distroseries, self.arches,
238+ self.packagesets, self.rebuild)
239 ids.check()
240 ids.initialise()
241+
242+ def getOopsVars(self):
243+ """See `IRunnableJob`."""
244+ vars = super(InitialiseDistroSeriesJob, self).getOopsVars()
245+ vars.append(('parent_distroseries_id', self.metadata.get("parent")))
246+ return vars
247
248=== modified file 'lib/lp/soyuz/scripts/initialise_distroseries.py'
249--- lib/lp/soyuz/scripts/initialise_distroseries.py 2011-03-29 23:48:03 +0000
250+++ lib/lp/soyuz/scripts/initialise_distroseries.py 2011-03-30 16:11:08 +0000
251@@ -40,7 +40,8 @@
252 Preconditions:
253 The distroseries must exist, and be completly unused, with no source
254 or binary packages existing, as well as no distroarchseries set up.
255- Section and component selections must be empty.
256+ Section and component selections must be empty. It must not have a
257+ parent series.
258
259 Outcome:
260 The distroarchseries set up in the parent series will be copied.
261@@ -60,11 +61,11 @@
262 """
263
264 def __init__(
265- self, distroseries, arches=(), packagesets=(), rebuild=False):
266+ self, parent, distroseries, arches=(), packagesets=(), rebuild=False):
267 # Avoid circular imports
268 from lp.registry.model.distroseries import DistroSeries
269+ self.parent = parent
270 self.distroseries = distroseries
271- self.parent = self.distroseries.parent_series
272 self.arches = arches
273 self.packagesets = [
274 ensure_unicode(packageset) for packageset in packagesets]
275@@ -72,8 +73,12 @@
276 self._store = IMasterStore(DistroSeries)
277
278 def check(self):
279- if self.parent is None:
280- raise InitialisationError("Parent series required.")
281+ if self.distroseries.parent_series is not None:
282+ raise InitialisationError(
283+ ("DistroSeries {child.name} has been initialized; it already "
284+ "derives from {child.parent_series.distribution.name}/"
285+ "{child.parent_series.name}.").format(
286+ child=self.distroseries))
287 self._checkBuilds()
288 self._checkQueue()
289 self._checkSeries()
290@@ -127,10 +132,14 @@
291 raise InitialisationError(error)
292
293 def initialise(self):
294+ self._set_parent()
295 self._copy_architectures()
296 self._copy_packages()
297 self._copy_packagesets()
298
299+ def _set_parent(self):
300+ self.distroseries.parent_series = self.parent
301+
302 def _copy_architectures(self):
303 include = ''
304 if self.arches:
305
306=== modified file 'lib/lp/soyuz/scripts/tests/test_initialise_distroseries.py'
307--- lib/lp/soyuz/scripts/tests/test_initialise_distroseries.py 2011-03-29 23:48:03 +0000
308+++ lib/lp/soyuz/scripts/tests/test_initialise_distroseries.py 2011-03-30 16:11:08 +0000
309@@ -9,6 +9,8 @@
310 import subprocess
311 import sys
312
313+from testtools.content import Content
314+from testtools.content_type import UTF8_TEXT
315 import transaction
316 from zope.component import getUtility
317
318@@ -83,17 +85,11 @@
319 pocket=PackagePublishingPocket.RELEASE,
320 status=PackagePublishingStatus.PUBLISHED)
321
322- def test_failure_with_no_parent_series(self):
323- # Initialising a new distro series requires a parent series to be set
324- ids = InitialiseDistroSeries(self.factory.makeDistroSeries())
325- self.assertRaisesWithContent(
326- InitialisationError, "Parent series required.", ids.check)
327-
328 def test_failure_for_already_released_distroseries(self):
329 # Initialising a distro series that has already been used will error
330- child = self.factory.makeDistroSeries(parent_series=self.parent)
331+ child = self.factory.makeDistroSeries()
332 self.factory.makeDistroArchSeries(distroseries=child)
333- ids = InitialiseDistroSeries(child)
334+ ids = InitialiseDistroSeries(self.parent, child)
335 self.assertRaisesWithContent(
336 InitialisationError,
337 "Can not copy distroarchseries from parent, there are already "
338@@ -105,9 +101,8 @@
339 distroseries=self.parent,
340 pocket=PackagePublishingPocket.RELEASE)
341 source.createMissingBuilds()
342- child = self.factory.makeDistroSeries(
343- parent_series=self.parent)
344- ids = InitialiseDistroSeries(child)
345+ child = self.factory.makeDistroSeries()
346+ ids = InitialiseDistroSeries(self.parent, child)
347 self.assertRaisesWithContent(
348 InitialisationError, "Parent series has pending builds.",
349 ids.check)
350@@ -118,8 +113,8 @@
351 self.parent.createQueueEntry(
352 PackagePublishingPocket.RELEASE,
353 'foo.changes', 'bar', self.parent.main_archive)
354- child = self.factory.makeDistroSeries(parent_series=self.parent)
355- ids = InitialiseDistroSeries(child)
356+ child = self.factory.makeDistroSeries()
357+ ids = InitialiseDistroSeries(self.parent, child)
358 self.assertRaisesWithContent(
359 InitialisationError, "Parent series queues are not empty.",
360 ids.check)
361@@ -160,10 +155,9 @@
362
363 def _full_initialise(self, arches=(), packagesets=(), rebuild=False,
364 distribution=None):
365- child = self.factory.makeDistroSeries(
366- parent_series=self.parent,
367- distribution=distribution)
368- ids = InitialiseDistroSeries(child, arches, packagesets, rebuild)
369+ child = self.factory.makeDistroSeries(distribution=distribution)
370+ ids = InitialiseDistroSeries(
371+ self.parent, child, arches, packagesets, rebuild)
372 ids.check()
373 ids.initialise()
374 return child
375@@ -347,6 +341,11 @@
376 test1.addSources('udev')
377 getUtility(IArchivePermissionSet).newPackagesetUploader(
378 self.parent.main_archive, uploader, test1)
379+ # The child must have a parent series because initialise-from-parent
380+ # expects it; this script supports the old-style derivation of
381+ # distribution series where the parent series is specified at the time
382+ # of adding the series. New-style derivation leaves the specification
383+ # of the parent series until later.
384 child = self.factory.makeDistroSeries(parent_series=self.parent)
385 transaction.commit()
386 ifp = os.path.join(
387@@ -356,6 +355,8 @@
388 [sys.executable, ifp, "-vv", "-d", child.parent.name,
389 child.name], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
390 stdout, stderr = process.communicate()
391+ self.addDetail("stdout", Content(UTF8_TEXT, lambda: stdout))
392+ self.addDetail("stderr", Content(UTF8_TEXT, lambda: stderr))
393 self.assertEqual(process.returncode, 0)
394 self.assertTrue(
395 "DEBUG Committing transaction." in stderr.split('\n'))
396
397=== modified file 'lib/lp/soyuz/tests/test_initialisedistroseriesjob.py'
398--- lib/lp/soyuz/tests/test_initialisedistroseriesjob.py 2010-12-02 16:13:51 +0000
399+++ lib/lp/soyuz/tests/test_initialisedistroseriesjob.py 2011-03-30 16:11:08 +0000
400@@ -13,7 +13,11 @@
401 from zope.security.proxy import removeSecurityProxy
402
403 from canonical.config import config
404-from canonical.testing import LaunchpadZopelessLayer
405+from canonical.database.sqlbase import flush_database_caches
406+from canonical.testing import (
407+ DatabaseFunctionalLayer,
408+ LaunchpadZopelessLayer,
409+ )
410 from lp.buildmaster.enums import BuildStatus
411 from lp.registry.interfaces.pocket import PackagePublishingPocket
412 from lp.soyuz.interfaces.distributionjob import (
413@@ -30,18 +34,23 @@
414 class InitialiseDistroSeriesJobTests(TestCaseWithFactory):
415 """Test case for InitialiseDistroSeriesJob."""
416
417- layer = LaunchpadZopelessLayer
418+ layer = DatabaseFunctionalLayer
419+
420+ @property
421+ def job_source(self):
422+ return getUtility(IInitialiseDistroSeriesJobSource)
423
424 def test_getOopsVars(self):
425+ parent = self.factory.makeDistroSeries()
426 distroseries = self.factory.makeDistroSeries()
427- job = getUtility(IInitialiseDistroSeriesJobSource).create(
428- distroseries)
429+ job = self.job_source.create(parent, distroseries)
430 vars = job.getOopsVars()
431 naked_job = removeSecurityProxy(job)
432 self.assertIn(
433 ('distribution_id', distroseries.distribution.id), vars)
434 self.assertIn(('distroseries_id', distroseries.id), vars)
435 self.assertIn(('distribution_job_id', naked_job.context.id), vars)
436+ self.assertIn(('parent_distroseries_id', parent.id), vars)
437
438 def _getJobs(self):
439 """Return the pending InitialiseDistroSeriesJobs as a list."""
440@@ -53,52 +62,62 @@
441 return len(self._getJobs())
442
443 def test_create_only_creates_one(self):
444+ parent = self.factory.makeDistroSeries()
445 distroseries = self.factory.makeDistroSeries()
446 # If there's already a InitialiseDistroSeriesJob for a
447 # DistroSeries, InitialiseDistroSeriesJob.create() won't create
448 # a new one.
449- getUtility(IInitialiseDistroSeriesJobSource).create(
450- distroseries)
451- transaction.commit()
452-
453- # There will now be one job in the queue.
454- self.assertEqual(1, self._getJobCount())
455-
456- getUtility(IInitialiseDistroSeriesJobSource).create(
457- distroseries)
458-
459- # This is less than ideal
460- self.assertRaises(IntegrityError, self._getJobCount)
461-
462- def test_run(self):
463- """Test that InitialiseDistroSeriesJob.run() actually
464- initialises builds and copies from the parent."""
465- distroseries = self.factory.makeDistroSeries()
466-
467- job = getUtility(IInitialiseDistroSeriesJobSource).create(
468- distroseries)
469-
470- # Since our new distroseries doesn't have a parent set, and the first
471- # thing that run() will execute is checking the distroseries, if it
472- # returns an InitialisationError, then it's good.
473+ self.job_source.create(parent, distroseries)
474+ self.job_source.create(parent, distroseries)
475+ self.assertRaises(IntegrityError, flush_database_caches)
476+
477+ def test_run_with_parent_series_already_set(self):
478+ # InitialisationError is raised if the parent series is already set on
479+ # the child.
480+ parent = self.factory.makeDistroSeries()
481+ distroseries = self.factory.makeDistroSeries(parent_series=parent)
482+ job = self.job_source.create(parent, distroseries)
483+ expected_message = (
484+ "DistroSeries {child.name} has been initialized; it already "
485+ "derives from {parent.distribution.name}/{parent.name}.").format(
486+ parent=parent, child=distroseries)
487 self.assertRaisesWithContent(
488- InitialisationError, "Parent series required.", job.run)
489+ InitialisationError, expected_message, job.run)
490
491 def test_arguments(self):
492 """Test that InitialiseDistroSeriesJob specified with arguments can
493 be gotten out again."""
494+ parent = self.factory.makeDistroSeries()
495 distroseries = self.factory.makeDistroSeries()
496 arches = (u'i386', u'amd64')
497 packagesets = (u'foo', u'bar', u'baz')
498
499- job = getUtility(IInitialiseDistroSeriesJobSource).create(
500- distroseries, arches, packagesets)
501+ job = self.job_source.create(
502+ parent, distroseries, arches, packagesets)
503
504 naked_job = removeSecurityProxy(job)
505 self.assertEqual(naked_job.distroseries, distroseries)
506 self.assertEqual(naked_job.arches, arches)
507 self.assertEqual(naked_job.packagesets, packagesets)
508 self.assertEqual(naked_job.rebuild, False)
509+ self.assertEqual(naked_job.metadata["parent"], parent.id)
510+
511+ def test_parent(self):
512+ parent = self.factory.makeDistroSeries()
513+ distroseries = self.factory.makeDistroSeries()
514+ job = self.job_source.create(parent, distroseries)
515+ naked_job = removeSecurityProxy(job)
516+ self.assertEqual(parent, naked_job.parent)
517+
518+
519+class InitialiseDistroSeriesJobTestsWithPackages(TestCaseWithFactory):
520+ """Test case for InitialiseDistroSeriesJob."""
521+
522+ layer = LaunchpadZopelessLayer
523+
524+ @property
525+ def job_source(self):
526+ return getUtility(IInitialiseDistroSeriesJobSource)
527
528 def _create_child(self):
529 pf = self.factory.makeProcessorFamily()
530@@ -125,16 +144,14 @@
531 distroseries=parent)
532 test1.addSources('udev')
533 parent.updatePackageCount()
534- child = self.factory.makeDistroSeries(parent_series=parent)
535-
536- # Make sure everything hits the database, switching db users
537- # aborts.
538+ child = self.factory.makeDistroSeries()
539+ # Make sure everything hits the database, switching db users aborts.
540 transaction.commit()
541 return parent, child
542
543 def test_job(self):
544 parent, child = self._create_child()
545- job = getUtility(IInitialiseDistroSeriesJobSource).create(child)
546+ job = self.job_source.create(parent, child)
547 self.layer.switchDbUser('initialisedistroseries')
548
549 job.run()
550@@ -145,8 +162,9 @@
551 def test_job_with_arguments(self):
552 parent, child = self._create_child()
553 arch = parent.nominatedarchindep.architecturetag
554- job = getUtility(IInitialiseDistroSeriesJobSource).create(
555- child, packagesets=('test1',), arches=(arch,), rebuild=True)
556+ job = self.job_source.create(
557+ parent, child, packagesets=('test1',), arches=(arch,),
558+ rebuild=True)
559 self.layer.switchDbUser('initialisedistroseries')
560
561 job.run()
562
563=== modified file 'scripts/ftpmaster-tools/initialise-from-parent.py'
564--- scripts/ftpmaster-tools/initialise-from-parent.py 2010-11-08 12:52:43 +0000
565+++ scripts/ftpmaster-tools/initialise-from-parent.py 2011-03-30 16:11:08 +0000
566@@ -5,23 +5,27 @@
567
568 """Initialise a new distroseries from its parent series."""
569
570+from optparse import OptionParser
571+import sys
572+
573 import _pythonpath
574-
575-import sys
576-from optparse import OptionParser
577-
578+from contrib.glock import GlobalLock
579 from zope.component import getUtility
580-from contrib.glock import GlobalLock
581
582 from canonical.config import config
583-from lp.registry.interfaces.distribution import IDistributionSet
584 from canonical.launchpad.scripts import (
585- execute_zcml_for_scripts, logger, logger_options)
586+ execute_zcml_for_scripts,
587+ logger,
588+ logger_options,
589+ )
590 from canonical.lp import initZopeless
591-
592 from lp.app.errors import NotFoundError
593+from lp.registry.interfaces.distribution import IDistributionSet
594 from lp.soyuz.scripts.initialise_distroseries import (
595- InitialisationError, InitialiseDistroSeries)
596+ InitialisationError,
597+ InitialiseDistroSeries,
598+ )
599+
600
601 def main():
602 # Parse command-line arguments
603@@ -77,7 +81,12 @@
604 arches = ()
605 if options.arches is not None:
606 arches = tuple(options.arches.split(','))
607- ids = InitialiseDistroSeries(distroseries, arches)
608+ # InitialiseDistroSeries does not like it if the parent series is
609+ # specified on the child, so we must unset it and pass it in. This is
610+ # a temporary hack until confidence in InitialiseDistroSeriesJob is
611+ # good, at which point this script will be obsolete.
612+ parent, distroseries.parent_series = distroseries.parent_series, None
613+ ids = InitialiseDistroSeries(parent, distroseries, arches)
614 ids.check()
615 log.debug('initialising from parent, copying publishing records.')
616 ids.initialise()
617@@ -99,4 +108,3 @@
618
619 if __name__ == '__main__':
620 sys.exit(main())
621-