Merge lp:~michael.nelson/launchpad/567922-binarypackagebuild-new-table-1 into lp:launchpad/db-devel

Proposed by Michael Nelson
Status: Merged
Approved by: Aaron Bentley
Approved revision: no longer in the source branch.
Merged at revision: 9405
Proposed branch: lp:~michael.nelson/launchpad/567922-binarypackagebuild-new-table-1
Merge into: lp:launchpad/db-devel
Prerequisite: lp:~michael.nelson/launchpad/567922-binarypackagebuild-packagebuild-4
Diff against target: 1092 lines (+252/-243) (has conflicts)
20 files modified
lib/lp/buildmaster/doc/buildfarmjob.txt (+0/-11)
lib/lp/buildmaster/interfaces/buildfarmjob.py (+65/-73)
lib/lp/buildmaster/interfaces/packagebuild.py (+14/-13)
lib/lp/buildmaster/model/buildfarmjob.py (+37/-23)
lib/lp/buildmaster/model/packagebuild.py (+18/-4)
lib/lp/buildmaster/tests/test_buildfarmjob.py (+1/-4)
lib/lp/buildmaster/tests/test_packagebuild.py (+4/-0)
lib/lp/code/configure.zcml (+0/-1)
lib/lp/soyuz/configure.zcml (+0/-2)
lib/lp/soyuz/doc/build.txt (+3/-2)
lib/lp/soyuz/interfaces/binarypackagebuild.py (+28/-11)
lib/lp/soyuz/model/binarypackagebuild.py (+56/-62)
lib/lp/soyuz/model/sourcepackagerelease.py (+12/-10)
lib/lp/soyuz/templates/build-index.pt (+1/-1)
lib/lp/soyuz/templates/builds-list.pt (+2/-2)
lib/lp/soyuz/tests/test_build.py (+7/-13)
lib/lp/soyuz/tests/test_buildpackagejob.py (+0/-4)
lib/lp/translations/configure.zcml (+1/-3)
lib/lp/translations/model/translationtemplatesbuildjob.py (+1/-1)
lib/lp/translations/tests/test_translationtemplatesbuildjob.py (+2/-3)
Text conflict in lib/lp/buildmaster/interfaces/buildbase.py
Text conflict in lib/lp/buildmaster/model/buildbase.py
Text conflict in lib/lp/buildmaster/tests/test_buildbase.py
To merge this branch: bzr merge lp:~michael.nelson/launchpad/567922-binarypackagebuild-new-table-1
Reviewer Review Type Date Requested Status
Aaron Bentley (community) Approve
Review via email: mp+24401@code.launchpad.net

Description of the change

This branch is part of a pipeline for

https://blueprints.edge.launchpad.net/soyuz/+spec/build-generalisation
https://dev.launchpad.net/LEP/GeneralBuildHistories

Overview
========
This branch *finally* starts the work to switch our BinaryPackageBuild class to the new binarypackagebuild table (using the delegated PackageBuild/BuildFarmJob).

Details
=======
It updates the SQLBase _table to BinaryPackageBuild and then deals with the fallout to ensure that the stated interface is still provided.

This branch is dependent on the pending schema patch in a previous branch.

To test
=======

First update the test db schema (required as the db patch still needs to be updated to remove the old build table):
psql launchpad_ftest_template -f database/schema/pending/michaeln-build-generalisation.sql
bin/py database/schema/security.py -d launchpad_ftest_template

And then:
bin/test -vv -m soyuz.tests.test_build$ -t test_providesInterface

The next branch will continue to update the BinaryPackageBuild implementation to get the rest of the tests working.

To post a comment you must log in.
Revision history for this message
Aaron Bentley (abentley) wrote :

distro_series should be defined on IPackageBuild, because it's common to all packages, even though the implementation will differ for ISourcePackageRecipeBuild and IBinaryBuild. If needed, define a property on IPackageBuild that raises NotImplementedError.

diff lines 342-343 need to be re-indented.

I'm also concerned about the split between IPackageBuild and IPackageBuildDerived. It seems like there should only be one interface for things that are "package builds", so please see if you can unify them, or at least make it clear that IPackageBuild only exists to represent the PackageBuild model object.

Revision history for this message
Michael Nelson (michael.nelson) wrote :

On Mon, May 3, 2010 at 5:55 PM, Aaron Bentley <email address hidden> wrote:
> distro_series should be defined on IPackageBuild, because it's common to all packages, even though the implementation will differ for ISourcePackageRecipeBuild and IBinaryBuild.  If needed, define a property on IPackageBuild that raises NotImplementedError.

Thanks - I added it but returned None on PackageBuild (similar to the
other attributes) as raising NotImplementedError for attributes means
that the exception is raised during assertProvides(), or is there a
better way?

>
> diff lines 342-343 need to be re-indented.

Done.

>
> I'm also concerned about the split between IPackageBuild and IPackageBuildDerived.  It seems like there should only be one interface for things that are "package builds", so please see if you can unify them, or at least make it clear that IPackageBuild only exists to represent the PackageBuild model object.

Thanks for taking the extra time to improve the design beyond the
actual review itself! You were spot on... I'd started getting mixed up
while trying to find places to move methods to. I've removed
IPackageBuildDerived (moving handleStatus to IPackageBuild), and
instead created a mixin class PackageBuildHandleStatusMixin which can
be used to provide an implementation on derived classes (ie. this
implementation can be shared between BinaryPackageBuilds and
SPRBuilds, as it is currently with BuildBase).

I've attached the incremental of the above, but if it's ok with you,
I'll also do a second incremental to get rid of IBuildFarmJobDerived
for the same reason you've outlined above.

1=== modified file 'lib/lp/buildmaster/interfaces/packagebuild.py'
2--- lib/lp/buildmaster/interfaces/packagebuild.py 2010-04-29 15:20:09 +0000
3+++ lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-04 12:07:35 +0000
4@@ -6,7 +6,6 @@
5 __all__ = [
6 'IPackageBuild',
7 'IPackageBuildSource',
8- 'IPackageBuildDerived',
9 ]
10
11
12@@ -19,6 +18,7 @@
13 from canonical.launchpad.interfaces.librarian import ILibraryFileAlias
14 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJob
15 from lp.registry.interfaces.distribution import IDistribution
16+from lp.registry.interfaces.distroseries import IDistroSeries
17 from lp.registry.interfaces.pocket import PackagePublishingPocket
18 from lp.soyuz.interfaces.archive import IArchive
19
20@@ -76,6 +76,12 @@
21 title=_("Distribution"), required=True,
22 description=_("Shortcut for its distribution.")))
23
24+ distro_series = exported(
25+ Reference(
26+ schema=IDistroSeries,
27+ title=_("Distribution series"), required=True,
28+ description=_("Shortcut for its distribution series.")))
29+
30 def getUploaderCommand(distro_series, upload_leaf, uploader_logfilename):
31 """Get the command to run as the uploader.
32
33@@ -138,6 +144,13 @@
34 upload log.
35 """
36
37+ def handleStatus(status, librarian, slave_status):
38+ """Handle a finished build status from a slave.
39+
40+ :param status: Slave build status string with 'BuildStatus.' stripped.
41+ :param slave_status: A dict as returned by IBuilder.slaveStatus
42+ """
43+
44
45 class IPackageBuildSource(Interface):
46 """A utility of this interface used to create _things_."""
47@@ -149,15 +162,3 @@
48 :param pocket: An item of `PackagePublishingPocket`.
49 :param dependencies: An optional debian-like dependency line.
50 """
51-
52-
53-class IPackageBuildDerived(Interface):
54- """Classes deriving from IPackageBuild inherit the default handleStatus.
55- """
56- def handleStatus(status, librarian, slave_status):
57- """Handle a finished build status from a slave.
58-
59- :param status: Slave build status string with 'BuildStatus.' stripped.
60- :param slave_status: A dict as returned by IBuilder.slaveStatus
61- """
62-
63
64=== modified file 'lib/lp/buildmaster/model/packagebuild.py'
65--- lib/lp/buildmaster/model/packagebuild.py 2010-04-30 16:12:05 +0000
66+++ lib/lp/buildmaster/model/packagebuild.py 2010-05-04 12:07:35 +0000
67@@ -23,7 +23,7 @@
68 from lp.buildmaster.interfaces.buildbase import BuildStatus
69 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
70 from lp.buildmaster.interfaces.packagebuild import (
71- IPackageBuild, IPackageBuildDerived, IPackageBuildSource)
72+ IPackageBuild, IPackageBuildSource)
73 from lp.buildmaster.model.buildbase import BuildBase
74 from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived
75 from lp.registry.interfaces.pocket import PackagePublishingPocket
76@@ -58,7 +58,11 @@
77 build_farm_job = Reference(build_farm_job_id, 'BuildFarmJob.id')
78
79 policy_name = 'buildd'
80+
81+ # The following two properties are part of the IPackageBuild
82+ # interface, but need to be provided by derived classes.
83 distribution = None
84+ distro_series = None
85
86 def __init__(self, build_farm_job, archive, pocket,
87 dependencies=None):
88@@ -150,14 +154,25 @@
89 """See `IPackageBuild`."""
90 raise NotImplementedError
91
92+ def handleStatus(self, status, librarian, slave_status):
93+ """See `IPackageBuild`."""
94+ raise NotImplementedError
95+
96
97 class PackageBuildDerived:
98- """See `IPackageBuildDerived`."""
99- implements(IPackageBuildDerived)
100 delegates(IPackageBuild, context="package_build")
101
102+
103+class PackageBuildStatusHandlerMixin:
104+ """A mixin to provide the common implementation of handleStatus.
105+
106+ This can be used by classes based on PackageBuild to provide
107+ the implementation of handleStatus, ensuring that the methods
108+ called during handleStatus are called on the top-level object
109+ first.
110+ """
111 def handleStatus(self, status, librarian, slave_status):
112- """See `IPackageBuildDerived`."""
113+ """See `IPackageBuild`."""
114 return BuildBase.handleStatus(self, status, librarian, slave_status)
115
116 # The following private handlers currently re-use the BuildBase
117
118=== modified file 'lib/lp/buildmaster/tests/test_packagebuild.py'
119--- lib/lp/buildmaster/tests/test_packagebuild.py 2010-04-30 16:11:03 +0000
120+++ lib/lp/buildmaster/tests/test_packagebuild.py 2010-05-04 12:07:35 +0000
121@@ -89,6 +89,9 @@
122 self.assertRaises(
123 NotImplementedError, self.package_build.verifySuccessfulUpload)
124 self.assertRaises(NotImplementedError, self.package_build.notify)
125+ self.assertRaises(
126+ NotImplementedError, self.package_build.handleStatus,
127+ None, None, None)
128
129 def test_default_values(self):
130 # PackageBuild has a number of default values.
131@@ -96,6 +99,7 @@
132 self.failUnlessEqual(
133 'multiverse', self.package_build.current_component.name)
134 self.failUnlessEqual(None, self.package_build.distribution)
135+ self.failUnlessEqual(None, self.package_build.distro_series)
136
137 def test_log_url(self):
138 # The url of the build log file is determined by the PackageBuild.
139
140=== modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
141--- lib/lp/soyuz/model/binarypackagebuild.py 2010-04-29 08:20:20 +0000
142+++ lib/lp/soyuz/model/binarypackagebuild.py 2010-05-04 09:45:26 +0000
143@@ -199,8 +199,8 @@
144 def was_built(self):
145 """See `IBuild`"""
146 return self.status not in [BuildStatus.NEEDSBUILD,
147- BuildStatus.BUILDING,
148- BuildStatus.SUPERSEDED]
149+ BuildStatus.BUILDING,
150+ BuildStatus.SUPERSEDED]
151
152 @property
153 def arch_tag(self):
Revision history for this message
Michael Nelson (michael.nelson) wrote :

On Tue, May 4, 2010 at 2:14 PM, Michael Nelson
<email address hidden> wrote:
...
> I've attached the incremental of the above, but if it's ok with you,
> I'll also do a second incremental to get rid of IBuildFarmJobDerived
> for the same reason you've outlined above.
>

See attached for the removal of the IBuildFarmJobDerived interface as
above. I also realised while doing this that I don't need the separate
mixin, and have instead provided the shared implementation on the
BuildFarmJobDerived/PackageJobDerived classes directly.

tested with:
bin/test -vv -t test_buildfarmjob -t test_packagebuild -t
test_sourcepackagerecipebuild -t test_translationtemplatesbuildjob

-Michael

1=== modified file 'lib/lp/buildmaster/doc/buildfarmjob.txt'
2--- lib/lp/buildmaster/doc/buildfarmjob.txt 2010-04-28 10:59:12 +0000
3+++ lib/lp/buildmaster/doc/buildfarmjob.txt 2010-05-04 13:42:25 +0000
4@@ -29,17 +29,6 @@
5
6 For more details, please refer to lp.buildmaster.tests.test_buildfarmjob.
7
8-BuildFarmJobDerived
9-===================
10-
11-BuildFarmJobDerived exists to encapsulate the functionality required
12-by classes delegating IBuildFarmJob.
13-
14- >>> from lp.buildmaster.interfaces.buildfarmjob import (
15- ... IBuildFarmJobDerived)
16- >>> verifyObject(IBuildFarmJobDerived, BuildFarmJobDerived())
17- True
18-
19 This class also includes the getByJob() class method used to find the
20 instance of a specific build-farm job implementation associated with a
21 given Job instance which must be called in the context of a concrete
22
23=== modified file 'lib/lp/buildmaster/interfaces/buildfarmjob.py'
24--- lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-04-30 16:11:03 +0000
25+++ lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-05-04 13:42:25 +0000
26@@ -11,7 +11,6 @@
27 'IBuildFarmJob',
28 'IBuildFarmJobOld',
29 'IBuildFarmJobSource',
30- 'IBuildFarmJobDerived',
31 'BuildFarmJobType',
32 ]
33
34@@ -106,6 +105,71 @@
35 def jobAborted():
36 """'Job aborted' life cycle event, handle as appropriate."""
37
38+ def addCandidateSelectionCriteria(processor, virtualized):
39+ """Provide a sub-query to refine the candidate job selection.
40+
41+ Return a sub-query to narrow down the list of candidate jobs.
42+ The sub-query will become part of an "outer query" and is free to
43+ refer to the `BuildQueue` and `Job` tables already utilized in the
44+ latter.
45+
46+ Example (please see the `BuildPackageJob` implementation for a
47+ complete example):
48+
49+ SELECT TRUE
50+ FROM Archive, Build, BuildPackageJob, DistroArchSeries
51+ WHERE
52+ BuildPackageJob.job = Job.id AND
53+ ..
54+
55+ :param processor: the type of processor that the candidate jobs are
56+ expected to run on.
57+ :param virtualized: whether the candidate jobs are expected to run on
58+ the `processor` natively or inside a virtual machine.
59+ :return: a string containing a sub-query that narrows down the list of
60+ candidate jobs.
61+ """
62+
63+ def postprocessCandidate(job, logger):
64+ """True if the candidate job is fine and should be dispatched
65+ to a builder, False otherwise.
66+
67+ :param job: The `BuildQueue` instance to be scrutinized.
68+ :param logger: The logger to use.
69+
70+ :return: True if the candidate job should be dispatched
71+ to a builder, False otherwise.
72+ """
73+
74+ def getByJob(job):
75+ """Get the specific `IBuildFarmJob` for the given `Job`.
76+
77+ Invoked on the specific `IBuildFarmJob`-implementing class that
78+ has an entry associated with `job`.
79+ """
80+
81+ def generateSlaveBuildCookie():
82+ """Produce a cookie for the slave as a token of the job it's doing.
83+
84+ The cookie need not be unique, but should be hard for a
85+ compromised slave to guess.
86+
87+ :return: a hard-to-guess ASCII string that can be reproduced
88+ accurately based on this job's properties.
89+ """
90+
91+ def makeJob():
92+ """Create the specific job relating this with an lp.services.job.
93+
94+ XXX 2010-04-26 michael.nelson bug=567922
95+ Once all *Build classes are using BuildFarmJob we can lose the
96+ 'specific_job' attributes and simply have a reference to the
97+ services job directly on the BuildFarmJob.
98+ """
99+
100+ def cleanUp():
101+ """Job's finished. Delete its supporting data."""
102+
103
104 class IBuildFarmJob(IBuildFarmJobOld):
105 """Operations that jobs for the build farm must implement."""
106@@ -179,78 +243,6 @@
107
108 title = exported(TextLine(title=_("Title"), required=False))
109
110- def makeJob():
111- """Create the specific job relating this with an lp.services.job.
112-
113- XXX 2010-04-26 michael.nelson bug=567922
114- Once all *Build classes are using BuildFarmJob we can lose the
115- 'specific_job' attributes and simply have a reference to the
116- services job directly on the BuildFarmJob.
117- """
118-
119-
120-class IBuildFarmJobDerived(Interface):
121- """Common functionality required by classes delegating IBuildFarmJob.
122-
123- An implementation of this class must setup the necessary delegation.
124- """
125-
126- def getByJob(job):
127- """Get the specific `IBuildFarmJob` for the given `Job`.
128-
129- Invoked on the specific `IBuildFarmJob`-implementing class that
130- has an entry associated with `job`.
131- """
132-
133- def addCandidateSelectionCriteria(processor, virtualized):
134- """Provide a sub-query to refine the candidate job selection.
135-
136- Return a sub-query to narrow down the list of candidate jobs.
137- The sub-query will become part of an "outer query" and is free to
138- refer to the `BuildQueue` and `Job` tables already utilized in the
139- latter.
140-
141- Example (please see the `BuildPackageJob` implementation for a
142- complete example):
143-
144- SELECT TRUE
145- FROM Archive, Build, BuildPackageJob, DistroArchSeries
146- WHERE
147- BuildPackageJob.job = Job.id AND
148- ..
149-
150- :param processor: the type of processor that the candidate jobs are
151- expected to run on.
152- :param virtualized: whether the candidate jobs are expected to run on
153- the `processor` natively or inside a virtual machine.
154- :return: a string containing a sub-query that narrows down the list of
155- candidate jobs.
156- """
157-
158- def postprocessCandidate(job, logger):
159- """True if the candidate job is fine and should be dispatched
160- to a builder, False otherwise.
161-
162- :param job: The `BuildQueue` instance to be scrutinized.
163- :param logger: The logger to use.
164-
165- :return: True if the candidate job should be dispatched
166- to a builder, False otherwise.
167- """
168-
169- def generateSlaveBuildCookie():
170- """Produce a cookie for the slave as a token of the job it's doing.
171-
172- The cookie need not be unique, but should be hard for a
173- compromised slave to guess.
174-
175- :return: a hard-to-guess ASCII string that can be reproduced
176- accurately based on this job's properties.
177- """
178-
179- def cleanUp():
180- """Job's finished. Delete its supporting data."""
181-
182
183 class IBuildFarmJobSource(Interface):
184 """A utility of BuildFarmJob used to create _things_."""
185
186=== modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
187--- lib/lp/buildmaster/model/buildfarmjob.py 2010-04-30 16:12:05 +0000
188+++ lib/lp/buildmaster/model/buildfarmjob.py 2010-05-04 13:42:25 +0000
189@@ -14,7 +14,6 @@
190
191 from lazr.delegates import delegates
192
193-import hashlib
194 import pytz
195
196 from storm.locals import Bool, DateTime, Int, Reference, Storm
197@@ -32,8 +31,8 @@
198
199 from lp.buildmaster.interfaces.buildbase import BuildStatus
200 from lp.buildmaster.interfaces.buildfarmjob import (
201- BuildFarmJobType, IBuildFarmJob, IBuildFarmJobDerived,
202- IBuildFarmJobOld, IBuildFarmJobSource)
203+ BuildFarmJobType, IBuildFarmJob, IBuildFarmJobOld,
204+ IBuildFarmJobSource)
205 from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet
206
207
208@@ -63,6 +62,10 @@
209 """See `IBuildFarmJobOld`."""
210 raise NotImplementedError
211
212+ def getByJob(self):
213+ """See `IBuildFarmJobOld`."""
214+ raise NotImplementedError
215+
216 def jobStarted(self):
217 """See `IBuildFarmJobOld`."""
218 pass
219@@ -75,8 +78,27 @@
220 """See `IBuildFarmJobOld`."""
221 pass
222
223+ @staticmethod
224+ def addCandidateSelectionCriteria(processor, virtualized):
225+ """See `IBuildFarmJobOld`."""
226+ return ('')
227+
228+ @staticmethod
229+ def postprocessCandidate(job, logger):
230+ """See `IBuildFarmJobOld`."""
231+ return True
232+
233+ def cleanUp(self):
234+ """See `IBuildFarmJob`."""
235+ Store.of(self).remove(self)
236+
237+ def generateSlaveBuildCookie(self):
238+ """See `IBuildFarmJobOld`."""
239+ raise NotImplementedError
240+
241
242 class BuildFarmJobOldDerived:
243+ """Setup the delegation and provide some common implementation."""
244 delegates(IBuildFarmJobOld, context='build_farm_job')
245
246 def __init__(self, *args, **kwargs):
247@@ -102,22 +124,12 @@
248
249 @classmethod
250 def getByJob(cls, job):
251- """See `IBuildFarmJobDerived`."""
252+ """See `IBuildFarmJobOld`."""
253 store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
254 return store.find(cls, cls.job == job).one()
255
256- @staticmethod
257- def addCandidateSelectionCriteria(processor, virtualized):
258- """See `IBuildFarmJobDerived`."""
259- return ('')
260-
261- @staticmethod
262- def postprocessCandidate(job, logger):
263- """See `IBuildFarmJobDerived`."""
264- return True
265-
266 def generateSlaveBuildCookie(self):
267- """See `IBuildFarmJobDerived`."""
268+ """See `IBuildFarmJobOld`."""
269 buildqueue = getUtility(IBuildQueueSet).getByJob(self.job)
270
271 if buildqueue.processor is None:
272@@ -136,10 +148,6 @@
273
274 return hashlib.sha1(contents).hexdigest()
275
276- def cleanUp(self):
277- """See `IBuildFarmJob`."""
278- Store.of(self).remove(self)
279-
280
281 class BuildFarmJob(BuildFarmJobOld, Storm):
282 """A base implementation for `IBuildFarmJob` classes."""
283@@ -258,8 +266,16 @@
284 """
285 return None
286
287+ def cleanUp(self):
288+ """See `IBuildFarmJobOld`.
289+
290+ XXX 2010-05-04 michael.nelson bug=570939
291+ This can be removed once IBuildFarmJobOld is no longer used
292+ and services jobs are linked directly to IBuildFarmJob.
293+ """
294+ pass
295+
296
297 class BuildFarmJobDerived:
298- """See `IBuildFarmJobDerived`."""
299- implements(IBuildFarmJobDerived)
300+ implements(IBuildFarmJob)
301 delegates(IBuildFarmJob, context='build_farm_job')
302
303=== modified file 'lib/lp/buildmaster/model/packagebuild.py'
304--- lib/lp/buildmaster/model/packagebuild.py 2010-05-04 12:07:35 +0000
305+++ lib/lp/buildmaster/model/packagebuild.py 2010-05-04 13:47:11 +0000
306@@ -160,17 +160,13 @@
307
308
309 class PackageBuildDerived:
310+ """Setup the delegation for package build.
311+
312+ This class also provides some common implementation for handling
313+ build status.
314+ """
315 delegates(IPackageBuild, context="package_build")
316
317-
318-class PackageBuildStatusHandlerMixin:
319- """A mixin to provide the common implementation of handleStatus.
320-
321- This can be used by classes based on PackageBuild to provide
322- the implementation of handleStatus, ensuring that the methods
323- called during handleStatus are called on the top-level object
324- first.
325- """
326 def handleStatus(self, status, librarian, slave_status):
327 """See `IPackageBuild`."""
328 return BuildBase.handleStatus(self, status, librarian, slave_status)
329
330=== modified file 'lib/lp/code/configure.zcml'
331--- lib/lp/code/configure.zcml 2010-04-30 15:05:53 +0000
332+++ lib/lp/code/configure.zcml 2010-05-04 13:42:25 +0000
333@@ -1024,7 +1024,6 @@
334 <class
335 class="lp.code.model.sourcepackagerecipebuild.SourcePackageRecipeBuildJob">
336 <allow interface="lp.code.interfaces.sourcepackagerecipebuild.ISourcePackageRecipeBuildJob"/>
337- <allow interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/>
338 </class>
339
340 <securedutility
341
342=== modified file 'lib/lp/soyuz/configure.zcml'
343--- lib/lp/soyuz/configure.zcml 2010-04-20 14:30:00 +0000
344+++ lib/lp/soyuz/configure.zcml 2010-05-04 13:42:25 +0000
345@@ -848,8 +848,6 @@
346 class="lp.soyuz.model.buildpackagejob.BuildPackageJob">
347 <allow
348 interface="lp.soyuz.interfaces.buildpackagejob.IBuildPackageJob"/>
349- <allow
350- interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/>
351 </class>
352 <!--
353 The registration below is used to discover all build farm job classes
354
355=== modified file 'lib/lp/soyuz/tests/test_buildpackagejob.py'
356--- lib/lp/soyuz/tests/test_buildpackagejob.py 2010-04-28 13:57:13 +0000
357+++ lib/lp/soyuz/tests/test_buildpackagejob.py 2010-05-04 13:42:25 +0000
358@@ -13,7 +13,6 @@
359
360 from lp.buildmaster.interfaces.buildbase import BuildStatus
361 from lp.buildmaster.interfaces.builder import IBuilderSet
362-from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobDerived
363 from lp.soyuz.interfaces.archive import ArchivePurpose
364 from lp.soyuz.interfaces.buildfarmbuildjob import IBuildFarmBuildJob
365 from lp.soyuz.interfaces.buildpackagejob import IBuildPackageJob
366@@ -235,6 +234,3 @@
367 build_farm_job = bq.specific_job
368 self.assertProvides(build_farm_job, IBuildPackageJob)
369 self.assertProvides(build_farm_job, IBuildFarmBuildJob)
370- self.assertProvides(build_farm_job, IBuildFarmJobDerived)
371-
372-
373
374=== modified file 'lib/lp/translations/configure.zcml'
375--- lib/lp/translations/configure.zcml 2010-04-22 07:33:12 +0000
376+++ lib/lp/translations/configure.zcml 2010-05-04 13:42:25 +0000
377@@ -578,9 +578,7 @@
378 <allow
379 interface="lp.code.interfaces.branchjob.IBranchJob"/>
380 <allow
381- interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJob"/>
382- <allow
383- interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/>
384+ interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobOld"/>
385 </class>
386 <securedutility
387 component="lp.translations.model.translationtemplatesbuildjob.TranslationTemplatesBuildJob"
388
389=== modified file 'lib/lp/translations/model/translationtemplatesbuildjob.py'
390--- lib/lp/translations/model/translationtemplatesbuildjob.py 2010-04-30 16:11:03 +0000
391+++ lib/lp/translations/model/translationtemplatesbuildjob.py 2010-05-04 13:42:25 +0000
392@@ -147,7 +147,7 @@
393
394 @classmethod
395 def getByJob(cls, job):
396- """See `IBuildFarmJobDerived`.
397+ """See `IBuildFarmJob`.
398
399 Overridden here to search via a BranchJob, rather than a Job.
400 """
401
402=== modified file 'lib/lp/translations/tests/test_translationtemplatesbuildjob.py'
403--- lib/lp/translations/tests/test_translationtemplatesbuildjob.py 2010-04-30 16:11:03 +0000
404+++ lib/lp/translations/tests/test_translationtemplatesbuildjob.py 2010-05-04 13:42:25 +0000
405@@ -19,7 +19,7 @@
406 from lp.testing import TestCaseWithFactory
407
408 from lp.buildmaster.interfaces.buildfarmjob import (
409- IBuildFarmJobOld, IBuildFarmJobDerived)
410+ IBuildFarmJobOld)
411 from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet
412 from lp.buildmaster.model.buildqueue import BuildQueue
413 from lp.code.interfaces.branch import IBranchSet
414@@ -54,9 +54,8 @@
415
416 def test_new_TranslationTemplatesBuildJob(self):
417 # TranslationTemplateBuildJob implements IBuildFarmJobOld,
418- # IBuildFarmJobDerived, and IBranchJob.
419+ # and IBranchJob.
420 verifyObject(IBranchJob, self.specific_job)
421- verifyObject(IBuildFarmJobDerived, self.specific_job)
422 verifyObject(IBuildFarmJobOld, self.specific_job)
423
424 # Each of these jobs knows the branch it will operate on.
Revision history for this message
Aaron Bentley (abentley) wrote :

Looks like a good improvement.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/buildmaster/doc/buildfarmjob.txt'
2--- lib/lp/buildmaster/doc/buildfarmjob.txt 2010-05-05 15:51:38 +0000
3+++ lib/lp/buildmaster/doc/buildfarmjob.txt 2010-05-05 15:51:40 +0000
4@@ -29,17 +29,6 @@
5
6 For more details, please refer to lp.buildmaster.tests.test_buildfarmjob.
7
8-BuildFarmJobDerived
9-===================
10-
11-BuildFarmJobDerived exists to encapsulate the functionality required
12-by classes delegating IBuildFarmJob.
13-
14- >>> from lp.buildmaster.interfaces.buildfarmjob import (
15- ... IBuildFarmJobDerived)
16- >>> verifyObject(IBuildFarmJobDerived, BuildFarmJobDerived())
17- True
18-
19 This class also includes the getByJob() class method used to find the
20 instance of a specific build-farm job implementation associated with a
21 given Job instance which must be called in the context of a concrete
22
23=== modified file 'lib/lp/buildmaster/interfaces/buildfarmjob.py'
24--- lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-05-05 15:51:38 +0000
25+++ lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-05-05 15:51:40 +0000
26@@ -11,7 +11,6 @@
27 'IBuildFarmJob',
28 'IBuildFarmJobOld',
29 'IBuildFarmJobSource',
30- 'IBuildFarmJobDerived',
31 'BuildFarmJobType',
32 ]
33
34@@ -106,6 +105,71 @@
35 def jobAborted():
36 """'Job aborted' life cycle event, handle as appropriate."""
37
38+ def addCandidateSelectionCriteria(processor, virtualized):
39+ """Provide a sub-query to refine the candidate job selection.
40+
41+ Return a sub-query to narrow down the list of candidate jobs.
42+ The sub-query will become part of an "outer query" and is free to
43+ refer to the `BuildQueue` and `Job` tables already utilized in the
44+ latter.
45+
46+ Example (please see the `BuildPackageJob` implementation for a
47+ complete example):
48+
49+ SELECT TRUE
50+ FROM Archive, Build, BuildPackageJob, DistroArchSeries
51+ WHERE
52+ BuildPackageJob.job = Job.id AND
53+ ..
54+
55+ :param processor: the type of processor that the candidate jobs are
56+ expected to run on.
57+ :param virtualized: whether the candidate jobs are expected to run on
58+ the `processor` natively or inside a virtual machine.
59+ :return: a string containing a sub-query that narrows down the list of
60+ candidate jobs.
61+ """
62+
63+ def postprocessCandidate(job, logger):
64+ """True if the candidate job is fine and should be dispatched
65+ to a builder, False otherwise.
66+
67+ :param job: The `BuildQueue` instance to be scrutinized.
68+ :param logger: The logger to use.
69+
70+ :return: True if the candidate job should be dispatched
71+ to a builder, False otherwise.
72+ """
73+
74+ def getByJob(job):
75+ """Get the specific `IBuildFarmJob` for the given `Job`.
76+
77+ Invoked on the specific `IBuildFarmJob`-implementing class that
78+ has an entry associated with `job`.
79+ """
80+
81+ def generateSlaveBuildCookie():
82+ """Produce a cookie for the slave as a token of the job it's doing.
83+
84+ The cookie need not be unique, but should be hard for a
85+ compromised slave to guess.
86+
87+ :return: a hard-to-guess ASCII string that can be reproduced
88+ accurately based on this job's properties.
89+ """
90+
91+ def makeJob():
92+ """Create the specific job relating this with an lp.services.job.
93+
94+ XXX 2010-04-26 michael.nelson bug=567922
95+ Once all *Build classes are using BuildFarmJob we can lose the
96+ 'specific_job' attributes and simply have a reference to the
97+ services job directly on the BuildFarmJob.
98+ """
99+
100+ def cleanUp():
101+ """Job's finished. Delete its supporting data."""
102+
103
104 class IBuildFarmJob(IBuildFarmJobOld):
105 """Operations that jobs for the build farm must implement."""
106@@ -179,78 +243,6 @@
107
108 title = exported(TextLine(title=_("Title"), required=False))
109
110- def makeJob():
111- """Create the specific job relating this with an lp.services.job.
112-
113- XXX 2010-04-26 michael.nelson bug=567922
114- Once all *Build classes are using BuildFarmJob we can lose the
115- 'specific_job' attributes and simply have a reference to the
116- services job directly on the BuildFarmJob.
117- """
118-
119-
120-class IBuildFarmJobDerived(Interface):
121- """Common functionality required by classes delegating IBuildFarmJob.
122-
123- An implementation of this class must setup the necessary delegation.
124- """
125-
126- def getByJob(job):
127- """Get the specific `IBuildFarmJob` for the given `Job`.
128-
129- Invoked on the specific `IBuildFarmJob`-implementing class that
130- has an entry associated with `job`.
131- """
132-
133- def addCandidateSelectionCriteria(processor, virtualized):
134- """Provide a sub-query to refine the candidate job selection.
135-
136- Return a sub-query to narrow down the list of candidate jobs.
137- The sub-query will become part of an "outer query" and is free to
138- refer to the `BuildQueue` and `Job` tables already utilized in the
139- latter.
140-
141- Example (please see the `BuildPackageJob` implementation for a
142- complete example):
143-
144- SELECT TRUE
145- FROM Archive, Build, BuildPackageJob, DistroArchSeries
146- WHERE
147- BuildPackageJob.job = Job.id AND
148- ..
149-
150- :param processor: the type of processor that the candidate jobs are
151- expected to run on.
152- :param virtualized: whether the candidate jobs are expected to run on
153- the `processor` natively or inside a virtual machine.
154- :return: a string containing a sub-query that narrows down the list of
155- candidate jobs.
156- """
157-
158- def postprocessCandidate(job, logger):
159- """True if the candidate job is fine and should be dispatched
160- to a builder, False otherwise.
161-
162- :param job: The `BuildQueue` instance to be scrutinized.
163- :param logger: The logger to use.
164-
165- :return: True if the candidate job should be dispatched
166- to a builder, False otherwise.
167- """
168-
169- def generateSlaveBuildCookie():
170- """Produce a cookie for the slave as a token of the job it's doing.
171-
172- The cookie need not be unique, but should be hard for a
173- compromised slave to guess.
174-
175- :return: a hard-to-guess ASCII string that can be reproduced
176- accurately based on this job's properties.
177- """
178-
179- def cleanUp():
180- """Job's finished. Delete its supporting data."""
181-
182
183 class IBuildFarmJobSource(Interface):
184 """A utility of BuildFarmJob used to create _things_."""
185
186=== modified file 'lib/lp/buildmaster/interfaces/packagebuild.py'
187--- lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-05 15:51:38 +0000
188+++ lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-05 15:51:40 +0000
189@@ -6,7 +6,6 @@
190 __all__ = [
191 'IPackageBuild',
192 'IPackageBuildSource',
193- 'IPackageBuildDerived',
194 ]
195
196
197@@ -19,6 +18,7 @@
198 from canonical.launchpad.interfaces.librarian import ILibraryFileAlias
199 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJob
200 from lp.registry.interfaces.distribution import IDistribution
201+from lp.registry.interfaces.distroseries import IDistroSeries
202 from lp.registry.interfaces.pocket import PackagePublishingPocket
203 from lp.soyuz.interfaces.archive import IArchive
204
205@@ -76,6 +76,12 @@
206 title=_("Distribution"), required=True,
207 description=_("Shortcut for its distribution.")))
208
209+ distro_series = exported(
210+ Reference(
211+ schema=IDistroSeries,
212+ title=_("Distribution series"), required=True,
213+ description=_("Shortcut for its distribution series.")))
214+
215 def getUploaderCommand(distro_series, upload_leaf, uploader_logfilename):
216 """Get the command to run as the uploader.
217
218@@ -138,6 +144,13 @@
219 upload log.
220 """
221
222+ def handleStatus(status, librarian, slave_status):
223+ """Handle a finished build status from a slave.
224+
225+ :param status: Slave build status string with 'BuildStatus.' stripped.
226+ :param slave_status: A dict as returned by IBuilder.slaveStatus
227+ """
228+
229
230 class IPackageBuildSource(Interface):
231 """A utility of this interface used to create _things_."""
232@@ -149,15 +162,3 @@
233 :param pocket: An item of `PackagePublishingPocket`.
234 :param dependencies: An optional debian-like dependency line.
235 """
236-
237-
238-class IPackageBuildDerived(Interface):
239- """Classes deriving from IPackageBuild inherit the default handleStatus.
240- """
241- def handleStatus(status, librarian, slave_status):
242- """Handle a finished build status from a slave.
243-
244- :param status: Slave build status string with 'BuildStatus.' stripped.
245- :param slave_status: A dict as returned by IBuilder.slaveStatus
246- """
247-
248
249=== modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
250--- lib/lp/buildmaster/model/buildfarmjob.py 2010-05-05 15:51:38 +0000
251+++ lib/lp/buildmaster/model/buildfarmjob.py 2010-05-05 15:51:40 +0000
252@@ -14,7 +14,6 @@
253
254 from lazr.delegates import delegates
255
256-import hashlib
257 import pytz
258
259 from storm.locals import Bool, DateTime, Int, Reference, Storm
260@@ -32,8 +31,8 @@
261
262 from lp.buildmaster.interfaces.buildbase import BuildStatus
263 from lp.buildmaster.interfaces.buildfarmjob import (
264- BuildFarmJobType, IBuildFarmJob, IBuildFarmJobDerived,
265- IBuildFarmJobOld, IBuildFarmJobSource)
266+ BuildFarmJobType, IBuildFarmJob, IBuildFarmJobOld,
267+ IBuildFarmJobSource)
268 from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet
269
270
271@@ -63,6 +62,10 @@
272 """See `IBuildFarmJobOld`."""
273 raise NotImplementedError
274
275+ def getByJob(self):
276+ """See `IBuildFarmJobOld`."""
277+ raise NotImplementedError
278+
279 def jobStarted(self):
280 """See `IBuildFarmJobOld`."""
281 pass
282@@ -75,8 +78,27 @@
283 """See `IBuildFarmJobOld`."""
284 pass
285
286+ @staticmethod
287+ def addCandidateSelectionCriteria(processor, virtualized):
288+ """See `IBuildFarmJobOld`."""
289+ return ('')
290+
291+ @staticmethod
292+ def postprocessCandidate(job, logger):
293+ """See `IBuildFarmJobOld`."""
294+ return True
295+
296+ def cleanUp(self):
297+ """See `IBuildFarmJob`."""
298+ Store.of(self).remove(self)
299+
300+ def generateSlaveBuildCookie(self):
301+ """See `IBuildFarmJobOld`."""
302+ raise NotImplementedError
303+
304
305 class BuildFarmJobOldDerived:
306+ """Setup the delegation and provide some common implementation."""
307 delegates(IBuildFarmJobOld, context='build_farm_job')
308
309 def __init__(self, *args, **kwargs):
310@@ -102,22 +124,12 @@
311
312 @classmethod
313 def getByJob(cls, job):
314- """See `IBuildFarmJobDerived`."""
315+ """See `IBuildFarmJobOld`."""
316 store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
317 return store.find(cls, cls.job == job).one()
318
319- @staticmethod
320- def addCandidateSelectionCriteria(processor, virtualized):
321- """See `IBuildFarmJobDerived`."""
322- return ('')
323-
324- @staticmethod
325- def postprocessCandidate(job, logger):
326- """See `IBuildFarmJobDerived`."""
327- return True
328-
329 def generateSlaveBuildCookie(self):
330- """See `IBuildFarmJobDerived`."""
331+ """See `IBuildFarmJobOld`."""
332 buildqueue = getUtility(IBuildQueueSet).getByJob(self.job)
333
334 if buildqueue.processor is None:
335@@ -136,10 +148,6 @@
336
337 return hashlib.sha1(contents).hexdigest()
338
339- def cleanUp(self):
340- """See `IBuildFarmJob`."""
341- Store.of(self).remove(self)
342-
343
344 class BuildFarmJob(BuildFarmJobOld, Storm):
345 """A base implementation for `IBuildFarmJob` classes."""
346@@ -238,8 +246,6 @@
347 @property
348 def buildqueue_record(self):
349 """See `IBuildFarmJob`."""
350- # Need to update the db schema for buildpackagejob before
351- # this can be implemented here.
352 return None
353
354 @property
355@@ -260,8 +266,16 @@
356 """
357 return None
358
359+ def cleanUp(self):
360+ """See `IBuildFarmJobOld`.
361+
362+ XXX 2010-05-04 michael.nelson bug=570939
363+ This can be removed once IBuildFarmJobOld is no longer used
364+ and services jobs are linked directly to IBuildFarmJob.
365+ """
366+ pass
367+
368
369 class BuildFarmJobDerived:
370- """See `IBuildFarmJobDerived`."""
371- implements(IBuildFarmJobDerived)
372+ implements(IBuildFarmJob)
373 delegates(IBuildFarmJob, context='build_farm_job')
374
375=== modified file 'lib/lp/buildmaster/model/packagebuild.py'
376--- lib/lp/buildmaster/model/packagebuild.py 2010-05-05 15:51:38 +0000
377+++ lib/lp/buildmaster/model/packagebuild.py 2010-05-05 15:51:40 +0000
378@@ -8,6 +8,8 @@
379 ]
380
381
382+from lazr.delegates import delegates
383+
384 from storm.locals import Int, Reference, Storm, Unicode
385
386 from zope.component import getUtility
387@@ -21,7 +23,7 @@
388 from lp.buildmaster.interfaces.buildbase import BuildStatus
389 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
390 from lp.buildmaster.interfaces.packagebuild import (
391- IPackageBuild, IPackageBuildDerived, IPackageBuildSource)
392+ IPackageBuild, IPackageBuildSource)
393 from lp.buildmaster.model.buildbase import BuildBase
394 from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived
395 from lp.registry.interfaces.pocket import PackagePublishingPocket
396@@ -56,7 +58,11 @@
397 build_farm_job = Reference(build_farm_job_id, 'BuildFarmJob.id')
398
399 policy_name = 'buildd'
400+
401+ # The following two properties are part of the IPackageBuild
402+ # interface, but need to be provided by derived classes.
403 distribution = None
404+ distro_series = None
405
406 def __init__(self, build_farm_job, archive, pocket,
407 dependencies=None):
408@@ -148,13 +154,21 @@
409 """See `IPackageBuild`."""
410 raise NotImplementedError
411
412+ def handleStatus(self, status, librarian, slave_status):
413+ """See `IPackageBuild`."""
414+ raise NotImplementedError
415+
416
417 class PackageBuildDerived:
418- """See `IPackageBuildDerived`."""
419- implements(IPackageBuildDerived)
420+ """Setup the delegation for package build.
421+
422+ This class also provides some common implementation for handling
423+ build status.
424+ """
425+ delegates(IPackageBuild, context="package_build")
426
427 def handleStatus(self, status, librarian, slave_status):
428- """See `IPackageBuildDerived`."""
429+ """See `IPackageBuild`."""
430 return BuildBase.handleStatus(self, status, librarian, slave_status)
431
432 # The following private handlers currently re-use the BuildBase
433
434=== modified file 'lib/lp/buildmaster/tests/test_buildfarmjob.py'
435--- lib/lp/buildmaster/tests/test_buildfarmjob.py 2010-05-05 15:51:38 +0000
436+++ lib/lp/buildmaster/tests/test_buildfarmjob.py 2010-05-05 15:51:40 +0000
437@@ -68,6 +68,7 @@
438 self.assertEqual(None, self.build_farm_job.builder)
439 self.assertEqual(None, self.build_farm_job.log)
440 self.assertEqual(None, self.build_farm_job.log_url)
441+ self.assertEqual(None, self.build_farm_job.buildqueue_record)
442
443 def test_unimplemented_methods(self):
444 # A build farm job leaves the implementation of various
445@@ -111,10 +112,6 @@
446 self.build_farm_job.job_type.title,
447 self.build_farm_job.title)
448
449- def test_buildqueue_record(self):
450- self.failUnless(
451- False, "Update schema and move buildqueue_record implementation")
452-
453
454 def test_suite():
455 return unittest.TestLoader().loadTestsFromName(__name__)
456
457=== modified file 'lib/lp/buildmaster/tests/test_packagebuild.py'
458--- lib/lp/buildmaster/tests/test_packagebuild.py 2010-05-05 15:51:38 +0000
459+++ lib/lp/buildmaster/tests/test_packagebuild.py 2010-05-05 15:51:40 +0000
460@@ -89,6 +89,9 @@
461 self.assertRaises(
462 NotImplementedError, self.package_build.verifySuccessfulUpload)
463 self.assertRaises(NotImplementedError, self.package_build.notify)
464+ self.assertRaises(
465+ NotImplementedError, self.package_build.handleStatus,
466+ None, None, None)
467
468 def test_default_values(self):
469 # PackageBuild has a number of default values.
470@@ -96,6 +99,7 @@
471 self.failUnlessEqual(
472 'multiverse', self.package_build.current_component.name)
473 self.failUnlessEqual(None, self.package_build.distribution)
474+ self.failUnlessEqual(None, self.package_build.distro_series)
475
476 def test_log_url(self):
477 # The url of the build log file is determined by the PackageBuild.
478
479=== modified file 'lib/lp/code/configure.zcml'
480--- lib/lp/code/configure.zcml 2010-04-29 13:24:30 +0000
481+++ lib/lp/code/configure.zcml 2010-05-05 15:51:40 +0000
482@@ -1024,7 +1024,6 @@
483 <class
484 class="lp.code.model.sourcepackagerecipebuild.SourcePackageRecipeBuildJob">
485 <allow interface="lp.code.interfaces.sourcepackagerecipebuild.ISourcePackageRecipeBuildJob"/>
486- <allow interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/>
487 </class>
488
489 <securedutility
490
491=== modified file 'lib/lp/soyuz/configure.zcml'
492--- lib/lp/soyuz/configure.zcml 2010-04-20 14:30:00 +0000
493+++ lib/lp/soyuz/configure.zcml 2010-05-05 15:51:40 +0000
494@@ -848,8 +848,6 @@
495 class="lp.soyuz.model.buildpackagejob.BuildPackageJob">
496 <allow
497 interface="lp.soyuz.interfaces.buildpackagejob.IBuildPackageJob"/>
498- <allow
499- interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/>
500 </class>
501 <!--
502 The registration below is used to discover all build farm job classes
503
504=== modified file 'lib/lp/soyuz/doc/build.txt'
505--- lib/lp/soyuz/doc/build.txt 2010-04-14 17:34:35 +0000
506+++ lib/lp/soyuz/doc/build.txt 2010-05-05 15:51:40 +0000
507@@ -72,7 +72,7 @@
508 >>> firefox_build.was_built
509 True
510
511- >>> firefox_build.calculated_buildstart
512+ >>> firefox_build.date_started
513 datetime.datetime(...)
514
515 >>> firefox_build.datebuilt
516@@ -895,6 +895,7 @@
517
518 Build records inserted by gina don't provide calculated_buildstart
519 value, since they miss fields used in its calculation.
520+TODO: check and update this based on the new model.
521
522 >>> gina_build = getUtility(IBinaryPackageBuildSet).getByBuildID(10)
523 >>> gina_build.title
524@@ -908,7 +909,7 @@
525 this method is protected by an assertion on valid buildduration and
526 datebuilt, it makes the diagnosis of problems in current DB easier.
527
528- >>> gina_build.calculated_buildstart
529+ >>> gina_build.date_started
530 Traceback (most recent call last):
531 ...
532 AssertionError: value is not suitable for this build record (10)
533
534=== modified file 'lib/lp/soyuz/interfaces/binarypackagebuild.py'
535--- lib/lp/soyuz/interfaces/binarypackagebuild.py 2010-04-12 13:17:34 +0000
536+++ lib/lp/soyuz/interfaces/binarypackagebuild.py 2010-05-05 15:51:40 +0000
537@@ -16,11 +16,12 @@
538 ]
539
540 from zope.interface import Interface, Attribute
541-from zope.schema import Bool, Int, Object, Text
542+from zope.schema import Bool, Int, Text
543 from lazr.enum import EnumeratedType, Item
544
545 from canonical.launchpad import _
546-from lp.buildmaster.interfaces.buildbase import IBuildBase
547+from lp.buildmaster.interfaces.buildbase import BuildStatus
548+from lp.buildmaster.interfaces.packagebuild import IPackageBuild
549 from lp.soyuz.interfaces.processor import IProcessor
550 from lp.soyuz.interfaces.publishing import (
551 ISourcePackagePublishingHistory)
552@@ -38,21 +39,26 @@
553 _message_prefix = "Cannot rescore build"
554
555
556-class IBinaryPackageBuildView(IBuildBase):
557+class IBinaryPackageBuildView(IPackageBuild):
558 """A Build interface for items requiring launchpad.View."""
559 id = Int(title=_('ID'), required=True, readonly=True)
560
561- processor = Object(
562+ package_build = Reference(
563+ title=_('Package build'), schema=IPackageBuild, required=True,
564+ readonly=True, description=_('The base package build'))
565+
566+ # Overridden from IBuildFarmJob to ensure required is True.
567+ processor = Reference(
568 title=_("Processor"), schema=IProcessor,
569 required=True, readonly=True,
570 description=_("The Processor where this build should be built."))
571
572- sourcepackagerelease = Object(
573+ source_package_release = Reference(
574 title=_('Source'), schema=ISourcePackageRelease,
575 required=True, readonly=True,
576 description=_("The SourcePackageRelease requested to build."))
577
578- distroarchseries = Object(
579+ distro_arch_series = Reference(
580 title=_("Architecture"),
581 # Really IDistroArchSeries
582 schema=Interface,
583@@ -67,7 +73,7 @@
584 required=False, readonly=True,
585 description=_("The current source publication for this build.")))
586
587- distroseries = Attribute("Direct parent needed by CanonicalURL")
588+ distro_series = Attribute("Direct parent needed by CanonicalURL")
589 was_built = Attribute("Whether or not modified by the builddfarm.")
590 arch_tag = exported(
591 Text(title=_("Architecture tag"), required=False))
592@@ -93,10 +99,6 @@
593 description=_(
594 "Whether or not this build record can be retried.")))
595
596- calculated_buildstart = Attribute(
597- "Emulates a buildstart timestamp by calculating it from "
598- "datebuilt - buildduration.")
599-
600 is_virtualized = Attribute(
601 "Whether or not this build requires a virtual build host or not.")
602
603@@ -213,6 +215,21 @@
604 class IBinaryPackageBuildSet(Interface):
605 """Interface for BinaryPackageBuildSet"""
606
607+ def new(distro_arch_series, source_package_release, processor,
608+ archive, pocket, status=BuildStatus.NEEDSBUILD,
609+ date_created=None):
610+ """Create a new `IBinaryPackageBuild`.
611+
612+ :param distro_arch_series: An `IDistroArchSeries`.
613+ :param source_package_release: An `ISourcePackageRelease`.
614+ :param processor: An `IProcessor`.
615+ :param archive: An `IArchive` in which context the build is built.
616+ :param pocket: An item of `PackagePublishingPocket`.
617+ :param status: A `BuildStatus` item indicating the builds status.
618+ :param date_created: An optional datetime to ensure multiple builds
619+ in the same transaction don't all get the same UTC_NOW.
620+ """
621+
622 def getBuildBySRAndArchtag(sourcepackagereleaseID, archtag):
623 """Return a build for a SourcePackageRelease and an ArchTag"""
624
625
626=== modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
627--- lib/lp/soyuz/model/binarypackagebuild.py 2010-04-15 13:48:46 +0000
628+++ lib/lp/soyuz/model/binarypackagebuild.py 2010-05-05 15:51:40 +0000
629@@ -11,6 +11,10 @@
630 import logging
631 import operator
632
633+from lazr.delegates import delegates
634+
635+from storm.locals import Int, Reference
636+
637 from zope.interface import implements
638 from zope.component import getUtility
639 from zope.security.proxy import removeSecurityProxy
640@@ -18,13 +22,10 @@
641 Desc, In, Join, LeftJoin)
642 from storm.store import Store
643 from sqlobject import (
644- StringCol, ForeignKey, IntervalCol, SQLObjectNotFound)
645+ ForeignKey, SQLObjectNotFound)
646 from sqlobject.sqlbuilder import AND, IN
647
648 from canonical.config import config
649-from canonical.database.constants import UTC_NOW
650-from canonical.database.datetimecol import UtcDateTimeCol
651-from canonical.database.enumcol import EnumCol
652 from canonical.database.sqlbase import quote_like, SQLBase, sqlvalues
653 from canonical.launchpad.components.decoratedresultset import (
654 DecoratedResultSet)
655@@ -43,16 +44,16 @@
656 from lp.archivepublisher.utils import get_ppa_reference
657 from lp.buildmaster.interfaces.buildbase import BuildStatus
658 from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType
659-from lp.buildmaster.model.buildbase import BuildBase
660+from lp.buildmaster.interfaces.packagebuild import (
661+ IPackageBuild, IPackageBuildSource)
662 from lp.buildmaster.model.buildqueue import BuildQueue
663-from lp.registry.interfaces.pocket import PackagePublishingPocket
664+from lp.buildmaster.model.packagebuild import PackageBuildDerived
665 from lp.services.job.model.job import Job
666 from lp.soyuz.adapters.archivedependencies import get_components_for_building
667 from lp.soyuz.interfaces.archive import ArchivePurpose
668 from lp.soyuz.interfaces.binarypackagebuild import (
669 BuildSetStatus, CannotBeRescored, IBinaryPackageBuild,
670 IBinaryPackageBuildSet)
671-from lp.buildmaster.interfaces.buildbase import IBuildBase
672 from lp.soyuz.interfaces.publishing import active_publishing_status
673 from lp.soyuz.model.binarypackagerelease import BinaryPackageRelease
674 from lp.buildmaster.model.builder import Builder
675@@ -63,37 +64,21 @@
676 PackageUpload, PackageUploadBuild)
677
678
679-class BinaryPackageBuild(BuildBase, SQLBase):
680- implements(IBuildBase, IBinaryPackageBuild)
681- _table = 'Build'
682+class BinaryPackageBuild(PackageBuildDerived, SQLBase):
683+ implements(IBinaryPackageBuild)
684+ delegates(IPackageBuild, context="package_build")
685+ _table = 'BinaryPackageBuild'
686 _defaultOrder = 'id'
687
688 build_farm_job_type = BuildFarmJobType.PACKAGEBUILD
689
690- datecreated = UtcDateTimeCol(dbName='datecreated', default=UTC_NOW)
691- processor = ForeignKey(dbName='processor', foreignKey='Processor',
692- notNull=True)
693- distroarchseries = ForeignKey(dbName='distroarchseries',
694+ package_build_id = Int(name='package_build', allow_none=False)
695+ package_build = Reference(package_build_id, 'PackageBuild.id')
696+
697+ distro_arch_series = ForeignKey(dbName='distro_arch_series',
698 foreignKey='DistroArchSeries', notNull=True)
699- buildstate = EnumCol(dbName='buildstate', notNull=True,
700- schema=BuildStatus)
701- sourcepackagerelease = ForeignKey(dbName='sourcepackagerelease',
702+ source_package_release = ForeignKey(dbName='source_package_release',
703 foreignKey='SourcePackageRelease', notNull=True)
704- datebuilt = UtcDateTimeCol(dbName='datebuilt', default=None)
705- buildduration = IntervalCol(dbName='buildduration', default=None)
706- buildlog = ForeignKey(dbName='buildlog', foreignKey='LibraryFileAlias',
707- default=None)
708- builder = ForeignKey(dbName='builder', foreignKey='Builder',
709- default=None)
710- pocket = EnumCol(dbName='pocket', schema=PackagePublishingPocket,
711- notNull=True)
712- dependencies = StringCol(dbName='dependencies', default=None)
713- archive = ForeignKey(foreignKey='Archive', dbName='archive', notNull=True)
714-
715- date_first_dispatched = UtcDateTimeCol(dbName='date_first_dispatched')
716-
717- upload_log = ForeignKey(
718- dbName='upload_log', foreignKey='LibraryFileAlias', default=None)
719
720 @property
721 def buildqueue_record(self):
722@@ -110,9 +95,9 @@
723 results = store.find(
724 SourcePackagePublishingHistory,
725 SourcePackagePublishingHistory.archive == self.archive,
726- SourcePackagePublishingHistory.distroseries == self.distroseries,
727+ SourcePackagePublishingHistory.distroseries == self.distro_series,
728 SourcePackagePublishingHistory.sourcepackagerelease ==
729- self.sourcepackagerelease)
730+ self.source_package_release)
731 return results.order_by(
732 Desc(SourcePackagePublishingHistory.id)).first()
733
734@@ -130,7 +115,7 @@
735 #assert latest_publication is not None, (
736 # 'Build %d lacks a corresponding source publication.' % self.id)
737 if latest_publication is None:
738- return self.sourcepackagerelease.component
739+ return self.source_package_release.component
740
741 return latest_publication.component
742
743@@ -173,7 +158,7 @@
744 (PackageUpload, LibraryFileAlias, LibraryFileContent),
745 PackageUploadBuild.build == self,
746 PackageUpload.archive == self.archive,
747- PackageUpload.distroseries == self.distroseries)
748+ PackageUpload.distroseries == self.distro_series)
749
750 # Return the unique `PackageUpload` record that corresponds to the
751 # upload of the result of this `Build`, load the `LibraryFileAlias`
752@@ -182,14 +167,14 @@
753 return DecoratedResultSet(results, operator.itemgetter(0)).one()
754
755 @property
756- def distroseries(self):
757+ def distro_series(self):
758 """See `IBuild`"""
759- return self.distroarchseries.distroseries
760+ return self.distro_arch_series.distroseries
761
762 @property
763 def distribution(self):
764 """See `IBuild`"""
765- return self.distroarchseries.distroseries.distribution
766+ return self.distro_series.distribution
767
768 @property
769 def is_virtualized(self):
770@@ -205,22 +190,22 @@
771 def title(self):
772 """See `IBuild`"""
773 return '%s build of %s %s in %s %s %s' % (
774- self.distroarchseries.architecturetag,
775- self.sourcepackagerelease.name,
776- self.sourcepackagerelease.version,
777- self.distribution.name, self.distroseries.name, self.pocket.name)
778+ self.distro_arch_series.architecturetag,
779+ self.source_package_release.name,
780+ self.source_package_release.version,
781+ self.distribution.name, self.distro_series.name, self.pocket.name)
782
783 @property
784 def was_built(self):
785 """See `IBuild`"""
786- return self.buildstate not in [BuildStatus.NEEDSBUILD,
787- BuildStatus.BUILDING,
788- BuildStatus.SUPERSEDED]
789+ return self.status not in [BuildStatus.NEEDSBUILD,
790+ BuildStatus.BUILDING,
791+ BuildStatus.SUPERSEDED]
792
793 @property
794 def arch_tag(self):
795 """See `IBuild`."""
796- return self.distroarchseries.architecturetag
797+ return self.distro_arch_series.architecturetag
798
799 @property
800 def distributionsourcepackagerelease(self):
801@@ -230,8 +215,8 @@
802 DistributionSourcePackageRelease)
803
804 return DistributionSourcePackageRelease(
805- distribution=self.distroarchseries.distroseries.distribution,
806- sourcepackagerelease=self.sourcepackagerelease)
807+ distribution=self.distribution,
808+ sourcepackagerelease=self.source_package_release)
809
810 @property
811 def binarypackages(self):
812@@ -251,7 +236,7 @@
813 from canonical.launchpad.database import (
814 DistroArchSeriesBinaryPackageRelease)
815 return [DistroArchSeriesBinaryPackageRelease(
816- self.distroarchseries, bp)
817+ self.distro_arch_series, bp)
818 for bp in self.binarypackages]
819
820 @property
821@@ -260,12 +245,12 @@
822 # First check that the slave scanner would pick up the build record
823 # if we reset it. PPA and Partner builds are always ok.
824 if (self.archive.purpose == ArchivePurpose.PRIMARY and
825- not self.distroseries.canUploadToPocket(self.pocket)):
826+ not self.distro_series.canUploadToPocket(self.pocket)):
827 # The slave scanner would not pick this up, so it cannot be
828 # re-tried.
829 return False
830
831- failed_buildstates = [
832+ failed_statuses = [
833 BuildStatus.FAILEDTOBUILD,
834 BuildStatus.MANUALDEPWAIT,
835 BuildStatus.CHROOTWAIT,
836@@ -274,20 +259,12 @@
837
838 # If the build is currently in any of the failed states,
839 # it may be retried.
840- return self.buildstate in failed_buildstates
841+ return self.status in failed_statuses
842
843 @property
844 def can_be_rescored(self):
845 """See `IBuild`."""
846- return self.buildstate is BuildStatus.NEEDSBUILD
847-
848- @property
849- def calculated_buildstart(self):
850- """See `IBuild`."""
851- assert self.datebuilt and self.buildduration, (
852- "value is not suitable for this build record (%d)"
853- % self.id)
854- return self.datebuilt - self.buildduration
855+ return self.status is BuildStatus.NEEDSBUILD
856
857 def retry(self):
858 """See `IBuild`."""
859@@ -695,6 +672,23 @@
860 class BinaryPackageBuildSet:
861 implements(IBinaryPackageBuildSet)
862
863+ def new(self, distro_arch_series, source_package_release, processor,
864+ archive, pocket, status=BuildStatus.NEEDSBUILD,
865+ date_created=None):
866+ """See `IBinaryPackageBuildSet`."""
867+ # Create the PackageBuild to which the new BinaryPackageBuild
868+ # will delegate.
869+ package_build = getUtility(IPackageBuildSource).new(
870+ BinaryPackageBuild.build_farm_job_type,
871+ archive.require_virtualized, archive, pocket, processor,
872+ status) #, date_created)
873+
874+ binary_package_build = BinaryPackageBuild(
875+ package_build=package_build,
876+ distro_arch_series=distro_arch_series,
877+ source_package_release=source_package_release)
878+ return binary_package_build
879+
880 def getBuildBySRAndArchtag(self, sourcepackagereleaseID, archtag):
881 """See `IBinaryPackageBuildSet`"""
882 clauseTables = ['DistroArchSeries']
883
884=== modified file 'lib/lp/soyuz/model/sourcepackagerelease.py'
885--- lib/lp/soyuz/model/sourcepackagerelease.py 2010-04-12 08:29:02 +0000
886+++ lib/lp/soyuz/model/sourcepackagerelease.py 2010-05-05 15:51:40 +0000
887@@ -41,6 +41,7 @@
888 from lp.registry.interfaces.sourcepackage import (
889 SourcePackageType, SourcePackageUrgency)
890 from lp.soyuz.interfaces.archive import IArchiveSet, MAIN_ARCHIVE_PURPOSES
891+from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet
892 from lp.soyuz.interfaces.packagediff import (
893 PackageDiffAlreadyRequested, PackageDiffStatus)
894 from lp.soyuz.interfaces.publishing import PackagePublishingStatus
895@@ -310,12 +311,12 @@
896 else:
897 return 0.0
898
899- def createBuild(self, distroarchseries, pocket, archive, processor=None,
900+ def createBuild(self, distro_arch_series, pocket, archive, processor=None,
901 status=None):
902 """See ISourcePackageRelease."""
903 # Guess a processor if one is not provided
904 if processor is None:
905- pf = distroarchseries.processorfamily
906+ pf = distro_arch_series.processorfamily
907 # We guess at the first processor in the family
908 processor = shortlist(pf.processors)[0]
909
910@@ -325,15 +326,16 @@
911 # Force the current timestamp instead of the default
912 # UTC_NOW for the transaction, avoid several row with
913 # same datecreated.
914- datecreated = datetime.datetime.now(pytz.timezone('UTC'))
915+ date_created = datetime.datetime.now(pytz.timezone('UTC'))
916
917- return BinaryPackageBuild(distroarchseries=distroarchseries,
918- sourcepackagerelease=self,
919- processor=processor,
920- buildstate=status,
921- datecreated=datecreated,
922- pocket=pocket,
923- archive=archive)
924+ return getUtility(IBinaryPackageBuildSet).new(
925+ distro_arch_series=distro_arch_series,
926+ source_package_release=self,
927+ processor=processor,
928+ status=status,
929+ date_created=date_created,
930+ pocket=pocket,
931+ archive=archive)
932
933 def getBuildByArch(self, distroarchseries, archive):
934 """See ISourcePackageRelease."""
935
936=== modified file 'lib/lp/soyuz/templates/build-index.pt'
937--- lib/lp/soyuz/templates/build-index.pt 2010-02-24 13:39:16 +0000
938+++ lib/lp/soyuz/templates/build-index.pt 2010-05-05 15:51:40 +0000
939@@ -169,7 +169,7 @@
940 <tal:built condition="context/was_built">
941 <li tal:condition="context/buildduration">
942 Started <span
943- tal:define="start context/calculated_buildstart"
944+ tal:define="start context/date_started"
945 tal:attributes="title start/fmt:datetime"
946 tal:content="start/fmt:displaydate">2008-01-01</span>
947 </li>
948
949=== modified file 'lib/lp/soyuz/templates/builds-list.pt'
950--- lib/lp/soyuz/templates/builds-list.pt 2009-11-12 15:12:12 +0000
951+++ lib/lp/soyuz/templates/builds-list.pt 2010-05-05 15:51:40 +0000
952@@ -59,9 +59,9 @@
953 <tal:soyuz_record condition="build/buildduration">
954 <span
955 tal:attributes="
956- title build/calculated_buildstart/fmt:datetime"
957+ title build/date_started/fmt:datetime"
958 tal:content="
959- build/calculated_buildstart/fmt:displaydate" />
960+ build/date_started/fmt:displaydate" />
961 </tal:soyuz_record>
962 <tal:gina_record condition="not: build/buildduration">
963 <i>at an unknown time</i>
964
965=== modified file 'lib/lp/soyuz/tests/test_build.py'
966--- lib/lp/soyuz/tests/test_build.py 2010-05-05 15:51:38 +0000
967+++ lib/lp/soyuz/tests/test_build.py 2010-05-05 15:51:40 +0000
968@@ -3,8 +3,6 @@
969
970 """Test Build features."""
971
972-from datetime import datetime, timedelta
973-import pytz
974 import unittest
975
976 from storm.store import Store
977@@ -13,9 +11,10 @@
978 from canonical.database.constants import UTC_NOW
979 from canonical.testing import LaunchpadZopelessLayer
980 from lp.services.job.model.job import Job
981-from lp.buildmaster.interfaces.buildbase import BuildStatus, IBuildBase
982+from lp.buildmaster.interfaces.buildbase import BuildStatus
983 from lp.buildmaster.interfaces.builder import IBuilderSet
984 from lp.buildmaster.interfaces.buildqueue import IBuildQueue
985+from lp.buildmaster.interfaces.packagebuild import IPackageBuild
986 from lp.buildmaster.model.buildqueue import BuildQueue
987 from lp.soyuz.interfaces.binarypackagebuild import (
988 IBinaryPackageBuild, IBinaryPackageBuildSet)
989@@ -41,19 +40,13 @@
990 spr_only=True, sourcename="gedit",
991 status=PackagePublishingStatus.PUBLISHED)
992 self.build = gedit_spr.createBuild(
993- distroarchseries=publisher.distroseries['i386'],
994+ distro_arch_series=publisher.distroseries['i386'],
995 archive=gedit_spr.upload_archive,
996 pocket=gedit_spr.package_upload.pocket)
997
998 def test_providesInterfaces(self):
999- # Build provides IBuildBase and IBuild.
1000-
1001- # The IBinaryPackageBuild.calculated_buildstart property asserts
1002- # that both datebuilt and buildduration are set.
1003- self.build.datebuilt = datetime.now(pytz.UTC)
1004- self.build.buildduration = timedelta(0, 1)
1005-
1006- self.assertProvides(self.build, IBuildBase)
1007+ # Build provides IPackageBuild and IBuild.
1008+ self.assertProvides(self.build, IPackageBuild)
1009 self.assertProvides(self.build, IBinaryPackageBuild)
1010
1011 def test_queueBuild(self):
1012@@ -290,7 +283,8 @@
1013
1014 def testDependencies(self):
1015 """Verify that storeBuildInfo sets any dependencies."""
1016- self.build.storeBuildInfo(self.build, None, {'dependencies': 'somepackage'})
1017+ self.build.storeBuildInfo(
1018+ self.build, None, {'dependencies': 'somepackage'})
1019 self.assertIsNot(None, self.build.buildlog)
1020 self.assertEqual(self.builder, self.build.builder)
1021 self.assertEqual(u'somepackage', self.build.dependencies)
1022
1023=== modified file 'lib/lp/soyuz/tests/test_buildpackagejob.py'
1024--- lib/lp/soyuz/tests/test_buildpackagejob.py 2010-05-05 15:51:38 +0000
1025+++ lib/lp/soyuz/tests/test_buildpackagejob.py 2010-05-05 15:51:40 +0000
1026@@ -13,7 +13,6 @@
1027
1028 from lp.buildmaster.interfaces.buildbase import BuildStatus
1029 from lp.buildmaster.interfaces.builder import IBuilderSet
1030-from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobDerived
1031 from lp.soyuz.interfaces.archive import ArchivePurpose
1032 from lp.soyuz.interfaces.buildfarmbuildjob import IBuildFarmBuildJob
1033 from lp.soyuz.interfaces.buildpackagejob import IBuildPackageJob
1034@@ -235,6 +234,3 @@
1035 build_farm_job = bq.specific_job
1036 self.assertProvides(build_farm_job, IBuildPackageJob)
1037 self.assertProvides(build_farm_job, IBuildFarmBuildJob)
1038- self.assertProvides(build_farm_job, IBuildFarmJobDerived)
1039-
1040-
1041
1042=== modified file 'lib/lp/translations/configure.zcml'
1043--- lib/lp/translations/configure.zcml 2010-04-22 07:33:12 +0000
1044+++ lib/lp/translations/configure.zcml 2010-05-05 15:51:40 +0000
1045@@ -578,9 +578,7 @@
1046 <allow
1047 interface="lp.code.interfaces.branchjob.IBranchJob"/>
1048 <allow
1049- interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJob"/>
1050- <allow
1051- interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobDerived"/>
1052+ interface="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJobOld"/>
1053 </class>
1054 <securedutility
1055 component="lp.translations.model.translationtemplatesbuildjob.TranslationTemplatesBuildJob"
1056
1057=== modified file 'lib/lp/translations/model/translationtemplatesbuildjob.py'
1058--- lib/lp/translations/model/translationtemplatesbuildjob.py 2010-05-05 15:51:38 +0000
1059+++ lib/lp/translations/model/translationtemplatesbuildjob.py 2010-05-05 15:51:40 +0000
1060@@ -147,7 +147,7 @@
1061
1062 @classmethod
1063 def getByJob(cls, job):
1064- """See `IBuildFarmJobDerived`.
1065+ """See `IBuildFarmJob`.
1066
1067 Overridden here to search via a BranchJob, rather than a Job.
1068 """
1069
1070=== modified file 'lib/lp/translations/tests/test_translationtemplatesbuildjob.py'
1071--- lib/lp/translations/tests/test_translationtemplatesbuildjob.py 2010-05-05 15:51:38 +0000
1072+++ lib/lp/translations/tests/test_translationtemplatesbuildjob.py 2010-05-05 15:51:40 +0000
1073@@ -19,7 +19,7 @@
1074 from lp.testing import TestCaseWithFactory
1075
1076 from lp.buildmaster.interfaces.buildfarmjob import (
1077- IBuildFarmJobOld, IBuildFarmJobDerived)
1078+ IBuildFarmJobOld)
1079 from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet
1080 from lp.buildmaster.model.buildqueue import BuildQueue
1081 from lp.code.interfaces.branch import IBranchSet
1082@@ -54,9 +54,8 @@
1083
1084 def test_new_TranslationTemplatesBuildJob(self):
1085 # TranslationTemplateBuildJob implements IBuildFarmJobOld,
1086- # IBuildFarmJobDerived, and IBranchJob.
1087+ # and IBranchJob.
1088 verifyObject(IBranchJob, self.specific_job)
1089- verifyObject(IBuildFarmJobDerived, self.specific_job)
1090 verifyObject(IBuildFarmJobOld, self.specific_job)
1091
1092 # Each of these jobs knows the branch it will operate on.

Subscribers

People subscribed via source and target branches

to status/vote changes: