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

Proposed by Michael Nelson
Status: Merged
Approved by: Michael Nelson
Approved revision: no longer in the source branch.
Merged at revision: 9405
Proposed branch: lp:~michael.nelson/launchpad/567922-binarypackagebuild-new-table-2
Merge into: lp:launchpad/db-devel
Prerequisite: lp:~michael.nelson/launchpad/567922-binarypackagebuild-new-table-1
Diff against target: 756 lines (+188/-86) (has conflicts)
17 files modified
lib/lp/buildmaster/interfaces/buildbase.py (+7/-1)
lib/lp/buildmaster/interfaces/packagebuild.py (+7/-0)
lib/lp/buildmaster/model/buildbase.py (+6/-5)
lib/lp/buildmaster/model/buildfarmjob.py (+1/-1)
lib/lp/buildmaster/model/packagebuild.py (+11/-4)
lib/lp/code/model/sourcepackagerecipe.py (+1/-1)
lib/lp/code/tests/test_sourcepackagerecipebuild.py (+1/-1)
lib/lp/soyuz/interfaces/binarypackagebuild.py (+2/-1)
lib/lp/soyuz/model/binarypackagebuild.py (+48/-29)
lib/lp/soyuz/model/buildfarmbuildjob.py (+50/-0)
lib/lp/soyuz/model/buildpackagejob.py (+7/-7)
lib/lp/soyuz/model/publishing.py (+1/-1)
lib/lp/soyuz/model/sourcepackagerelease.py (+15/-8)
lib/lp/soyuz/tests/test_binarypackagebuild.py (+11/-9)
lib/lp/soyuz/tests/test_hasbuildrecords.py (+3/-1)
lib/lp/soyuz/tests/test_publishing.py (+14/-14)
lib/lp/soyuz/tests/test_publishing_models.py (+3/-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-2
Reviewer Review Type Date Requested Status
Brad Crittenden (community) code Approve
Review via email: mp+24688@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 continues the work to switch our BinaryPackageBuild class to the new binarypackagebuild table (using the delegated PackageBuild/BuildFarmJob).

Details
=======
Renames test_build to test_binarypackagebuild, adds BinaryPackageBuild.queueBuild (converting it temporarily to a static method so the implementation can be shared with BuildBase until BuildBase is later deleted), and basically renames lots of attributes to get the tests below to pass.

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 test_binarypackagebuild -t test_getBuildsForBuilder -t test_getBuildsForArchive -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
Michael Nelson (michael.nelson) wrote :

Diff here: http://pastebin.ubuntu.com/427743/ (in case the scanner is still catching up).

Revision history for this message
Brad Crittenden (bac) wrote :

Hi Michael,

Man I know you're going to be happy to get these changes all wrapped
up. Thanks for doing a very tedious series of branches.

I'm glad to see soyuzvariablenames expanded. thank_you.

--bac

> === modified file 'lib/lp/buildmaster/interfaces/packagebuild.py'
> --- lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-04 12:07:35 +0000
> +++ lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-04 15:29:42 +0000
> @@ -151,6 +151,13 @@
> :param slave_status: A dict as returned by IBuilder.slaveStatus
> """
>
> + def queueBuild(suspended=False):
> + """Create a BuildQueue entry for this build.
> +
> + :param suspended: Whether the associated `Job` instance should be
> + created in a suspended state.
> + """

So interface method specifications leave off the 'self' argument but
as a staticmethod there is no self, so the first argument 'build' is
dropped? That's no good.

>
> class IPackageBuildSource(Interface):
> """A utility of this interface used to create _things_."""

> === modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
> --- lib/lp/buildmaster/model/buildfarmjob.py 2010-05-04 13:42:25 +0000
> +++ lib/lp/buildmaster/model/buildfarmjob.py 2010-05-04 15:29:42 +0000
> @@ -189,7 +189,7 @@
> def __init__(self, job_type, status=BuildStatus.NEEDSBUILD,
> processor=None, virtualized=None):
> super(BuildFarmJob, self).__init__()
> - self.job_type, self.status, self.process, self.virtualized = (
> + self.job_type, self.status, self.processor, self.virtualized = (
> job_type,
> status,
> processor,

> === modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
> --- lib/lp/soyuz/model/binarypackagebuild.py 2010-05-04 09:45:26 +0000
> +++ lib/lp/soyuz/model/binarypackagebuild.py 2010-05-04 15:29:42 +0000

> @@ -778,7 +791,7 @@
>
> # This code MUST match the logic in the Build security adapter,
> # otherwise users are likely to get 403 errors, or worse.

If it MUST match then perhaps it should be refactored and shared?
(Not a requirement for this branch.)

> === renamed file 'lib/lp/soyuz/tests/test_build.py' => 'lib/lp/soyuz/tests/test_binarypackagebuild.py'
> --- lib/lp/soyuz/tests/test_build.py 2010-04-29 08:28:30 +0000
> +++ lib/lp/soyuz/tests/test_binarypackagebuild.py 2010-05-04 15:29:42 +0000
> @@ -7,6 +7,7 @@
>
> from storm.store import Store
> from zope.component import getUtility
> +from zope.security.proxy import removeSecurityProxy
>
> from canonical.database.constants import UTC_NOW
> from canonical.testing import LaunchpadZopelessLayer
> @@ -81,7 +82,7 @@
>
> [depwait_build] = depwait_source.createMissingBuilds()
> depwait_build.buildstate = BuildStatus.MANUALDEPWAIT
> - depwait_build.dependencies = 'dep-bin'
> + depwait_build.dependencies = u'dep-bin'

Why did you need to convert these strings to unicode?

review: Approve (code)
Revision history for this message
Michael Nelson (michael.nelson) wrote :
Download full text (5.4 KiB)

On Tue, May 4, 2010 at 7:52 PM, Brad Crittenden <email address hidden> wrote:
> Review: Approve code
> Hi Michael,
>
> Man I know you're going to be happy to get these changes all wrapped
> up.  Thanks for doing a very tedious series of branches.
>
> I'm glad to see soyuzvariablenames expanded.  thank_you.
>
> --bac

Thanks for the review bac, a few comments below.

>
>
>> === modified file 'lib/lp/buildmaster/interfaces/packagebuild.py'
>> --- lib/lp/buildmaster/interfaces/packagebuild.py     2010-05-04 12:07:35 +0000
>> +++ lib/lp/buildmaster/interfaces/packagebuild.py     2010-05-04 15:29:42 +0000
>> @@ -151,6 +151,13 @@
>>          :param slave_status: A dict as returned by IBuilder.slaveStatus
>>          """
>>
>> +    def queueBuild(suspended=False):
>> +        """Create a BuildQueue entry for this build.
>> +
>> +        :param suspended: Whether the associated `Job` instance should be
>> +            created in a suspended state.
>> +        """
>
> So interface method specifications leave off the 'self' argument but
> as a staticmethod there is no self, so the first argument 'build' is
> dropped?  That's no good.

It's not a static method on PackageBuild... the
PackageBuild.queueBuild() method calls BuildBase.queueBuild() which is
a static method (so the implementation can be shared in the transition
by old BuildBase-based classes and the new PackageBuild classes).

Let me know if that was obvious to you and there is still something
you'd like to see changed?

>
>>
>>  class IPackageBuildSource(Interface):
>>      """A utility of this interface used to create _things_."""
>
>> === modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
>> --- lib/lp/buildmaster/model/buildfarmjob.py  2010-05-04 13:42:25 +0000
>> +++ lib/lp/buildmaster/model/buildfarmjob.py  2010-05-04 15:29:42 +0000
>> @@ -189,7 +189,7 @@
>>      def __init__(self, job_type, status=BuildStatus.NEEDSBUILD,
>>                   processor=None, virtualized=None):
>>          super(BuildFarmJob, self).__init__()
>> -        self.job_type, self.status, self.process, self.virtualized = (
>> +        self.job_type, self.status, self.processor, self.virtualized = (
>>              job_type,
>>              status,
>>              processor,
>
>> === modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
>> --- lib/lp/soyuz/model/binarypackagebuild.py  2010-05-04 09:45:26 +0000
>> +++ lib/lp/soyuz/model/binarypackagebuild.py  2010-05-04 15:29:42 +0000
>
>> @@ -778,7 +791,7 @@
>>
>>          # This code MUST match the logic in the Build security adapter,
>>          # otherwise users are likely to get 403 errors, or worse.
>
> If it MUST match then perhaps it should be refactored and shared?
> (Not a requirement for this branch.)

Yeah, I thought the same thing when I moved that comment.

>
>> === renamed file 'lib/lp/soyuz/tests/test_build.py' => 'lib/lp/soyuz/tests/test_binarypackagebuild.py'
>> --- lib/lp/soyuz/tests/test_build.py  2010-04-29 08:28:30 +0000
>> +++ lib/lp/soyuz/tests/test_binarypackagebuild.py     2010-05-04 15:29:42 +0000
>> @@ -7,6 +7,7 @@
>>
>>  from storm.store import Store
>>  from zope.component import getUtility
>> +from zope.security.proxy import r...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/buildmaster/interfaces/buildbase.py'
2--- lib/lp/buildmaster/interfaces/buildbase.py 2010-05-05 15:51:54 +0000
3+++ lib/lp/buildmaster/interfaces/buildbase.py 2010-05-05 15:51:57 +0000
4@@ -20,6 +20,7 @@
5 from lazr.restful.fields import Reference
6
7 from lp.buildmaster.interfaces.builder import IBuilder
8+from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType
9 from lp.buildmaster.interfaces.buildqueue import IBuildQueue
10 from lp.registry.interfaces.distribution import IDistribution
11 from lp.registry.interfaces.pocket import PackagePublishingPocket
12@@ -117,6 +118,11 @@
13 # can be removed once all *Build classes inherit from
14 # IBuildFarmJob/IPackageBuild.
15
16+ build_farm_job_type = Choice(
17+ title=_("Job type"), required=True, readonly=True,
18+ vocabulary=BuildFarmJobType,
19+ description=_("The specific type of job."))
20+
21 # XXX: wgrant 2010-01-20 bug=507712: Most of these attribute names
22 # are bad.
23 datecreated = exported(
24@@ -241,7 +247,7 @@
25 Invoke getFileFromSlave method with 'buildlog' identifier.
26 """
27
28- def queueBuild(suspended=False):
29+ def queueBuild(build, suspended=False):
30 """Create a BuildQueue entry for this build.
31
32 :param suspended: Whether the associated `Job` instance should be
33
34=== modified file 'lib/lp/buildmaster/interfaces/packagebuild.py'
35--- lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-05 15:51:54 +0000
36+++ lib/lp/buildmaster/interfaces/packagebuild.py 2010-05-05 15:51:57 +0000
37@@ -151,6 +151,13 @@
38 :param slave_status: A dict as returned by IBuilder.slaveStatus
39 """
40
41+ def queueBuild(suspended=False):
42+ """Create a BuildQueue entry for this build.
43+
44+ :param suspended: Whether the associated `Job` instance should be
45+ created in a suspended state.
46+ """
47+
48
49 class IPackageBuildSource(Interface):
50 """A utility of this interface used to create _things_."""
51
52=== modified file 'lib/lp/buildmaster/model/buildbase.py'
53--- lib/lp/buildmaster/model/buildbase.py 2010-05-05 15:51:54 +0000
54+++ lib/lp/buildmaster/model/buildbase.py 2010-05-05 15:51:57 +0000
55@@ -495,20 +495,21 @@
56 library_file = self.createUploadLog(self, content)
57 self.upload_log = library_file
58
59- def queueBuild(self, suspended=False):
60+ @staticmethod
61+ def queueBuild(build, suspended=False):
62 """See `IBuildBase`"""
63- specific_job = self.makeJob()
64+ specific_job = build.makeJob()
65
66 # This build queue job is to be created in a suspended state.
67 if suspended:
68 specific_job.job.suspend()
69
70- duration_estimate = self.estimateDuration()
71+ duration_estimate = build.estimateDuration()
72 queue_entry = BuildQueue(
73 estimated_duration=duration_estimate,
74- job_type=self.build_farm_job_type,
75+ job_type=build.build_farm_job_type,
76 job=specific_job.job, processor=specific_job.processor,
77 virtualized=specific_job.virtualized)
78- Store.of(self).add(queue_entry)
79+ Store.of(build).add(queue_entry)
80 return queue_entry
81
82
83=== modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
84--- lib/lp/buildmaster/model/buildfarmjob.py 2010-05-05 15:51:54 +0000
85+++ lib/lp/buildmaster/model/buildfarmjob.py 2010-05-05 15:51:57 +0000
86@@ -189,7 +189,7 @@
87 def __init__(self, job_type, status=BuildStatus.NEEDSBUILD,
88 processor=None, virtualized=None):
89 super(BuildFarmJob, self).__init__()
90- self.job_type, self.status, self.process, self.virtualized = (
91+ self.job_type, self.status, self.processor, self.virtualized = (
92 job_type,
93 status,
94 processor,
95
96=== modified file 'lib/lp/buildmaster/model/packagebuild.py'
97--- lib/lp/buildmaster/model/packagebuild.py 2010-05-05 15:51:54 +0000
98+++ lib/lp/buildmaster/model/packagebuild.py 2010-05-05 15:51:57 +0000
99@@ -122,9 +122,10 @@
100 return BuildBase.getUploaderCommand(
101 package_build, distro_series, upload_leaf, upload_logfilename)
102
103- def getLogFromSlave(self):
104+ @staticmethod
105+ def getLogFromSlave(package_build):
106 """See `IPackageBuild`."""
107- return BuildBase.getLogFromSlave(self)
108+ return BuildBase.getLogFromSlave(package_build)
109
110 @staticmethod
111 def getUploadLogContent(root, leaf):
112@@ -135,9 +136,11 @@
113 """See `IPackageBuild`."""
114 raise NotImplementedError
115
116- def storeBuildInfo(self, librarian, slave_status):
117+ @staticmethod
118+ def storeBuildInfo(package_build, librarian, slave_status):
119 """See `IPackageBuild`."""
120- return BuildBase.storeBuildInfo(self, librarian, slave_status)
121+ return BuildBase.storeBuildInfo(package_build, librarian,
122+ slave_status)
123
124 def verifySuccessfulUpload(self):
125 """See `IPackageBuild`."""
126@@ -167,6 +170,10 @@
127 """
128 delegates(IPackageBuild, context="package_build")
129
130+ def queueBuild(self, suspended=False):
131+ """See `IPackageBuild`."""
132+ return BuildBase.queueBuild(self, suspended=False)
133+
134 def handleStatus(self, status, librarian, slave_status):
135 """See `IPackageBuild`."""
136 return BuildBase.handleStatus(self, status, librarian, slave_status)
137
138=== modified file 'lib/lp/code/model/sourcepackagerecipe.py'
139--- lib/lp/code/model/sourcepackagerecipe.py 2010-04-30 12:33:16 +0000
140+++ lib/lp/code/model/sourcepackagerecipe.py 2010-05-05 15:51:57 +0000
141@@ -163,7 +163,7 @@
142 self.sourcepackagename)
143 build = getUtility(ISourcePackageRecipeBuildSource).new(sourcepackage,
144 self, requester, archive)
145- build.queueBuild()
146+ build.queueBuild(build)
147 return build
148
149 def getBuilds(self, pending=False):
150
151=== modified file 'lib/lp/code/tests/test_sourcepackagerecipebuild.py'
152--- lib/lp/code/tests/test_sourcepackagerecipebuild.py 2010-04-20 05:07:52 +0000
153+++ lib/lp/code/tests/test_sourcepackagerecipebuild.py 2010-05-05 15:51:57 +0000
154@@ -58,7 +58,7 @@
155
156 def test_queueBuild(self):
157 spb = self.makeSourcePackageRecipeBuild()
158- bq = spb.queueBuild()
159+ bq = spb.queueBuild(spb)
160 self.assertProvides(bq, IBuildQueue)
161 self.assertProvides(bq.specific_job, ISourcePackageRecipeBuildJob)
162 self.assertEqual(True, bq.virtualized)
163
164=== modified file 'lib/lp/soyuz/interfaces/binarypackagebuild.py'
165--- lib/lp/soyuz/interfaces/binarypackagebuild.py 2010-05-05 15:51:54 +0000
166+++ lib/lp/soyuz/interfaces/binarypackagebuild.py 2010-05-05 15:51:57 +0000
167@@ -21,7 +21,8 @@
168
169 from canonical.launchpad import _
170 from lp.buildmaster.interfaces.buildbase import BuildStatus
171-from lp.buildmaster.interfaces.packagebuild import IPackageBuild
172+from lp.buildmaster.interfaces.packagebuild import (
173+ IPackageBuild)
174 from lp.soyuz.interfaces.processor import IProcessor
175 from lp.soyuz.interfaces.publishing import (
176 ISourcePackagePublishingHistory)
177
178=== modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
179--- lib/lp/soyuz/model/binarypackagebuild.py 2010-05-05 15:51:54 +0000
180+++ lib/lp/soyuz/model/binarypackagebuild.py 2010-05-05 15:51:57 +0000
181@@ -45,9 +45,11 @@
182 from lp.buildmaster.interfaces.buildbase import BuildStatus
183 from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType
184 from lp.buildmaster.interfaces.packagebuild import (
185- IPackageBuild, IPackageBuildSource)
186+ IPackageBuildSource)
187+from lp.buildmaster.model.buildfarmjob import BuildFarmJob
188 from lp.buildmaster.model.buildqueue import BuildQueue
189-from lp.buildmaster.model.packagebuild import PackageBuildDerived
190+from lp.buildmaster.model.packagebuild import (
191+ PackageBuild, PackageBuildDerived)
192 from lp.services.job.model.job import Job
193 from lp.soyuz.adapters.archivedependencies import get_components_for_building
194 from lp.soyuz.interfaces.archive import ArchivePurpose
195@@ -66,7 +68,6 @@
196
197 class BinaryPackageBuild(PackageBuildDerived, SQLBase):
198 implements(IBinaryPackageBuild)
199- delegates(IPackageBuild, context="package_build")
200 _table = 'BinaryPackageBuild'
201 _defaultOrder = 'id'
202
203@@ -355,7 +356,7 @@
204 name, version, relation = self._parseDependencyToken(token)
205
206 dep_candidate = self.archive.findDepCandidateByName(
207- self.distroarchseries, name)
208+ self.distro_arch_series, name)
209
210 if not dep_candidate:
211 return False
212@@ -404,7 +405,7 @@
213 if not self._isDependencySatisfied(token)]
214
215 # Update dependencies line
216- self.dependencies = ", ".join(remaining_deps)
217+ self.dependencies = u", ".join(remaining_deps)
218
219 def __getitem__(self, name):
220 return self.getBinaryPackageRelease(name)
221@@ -447,30 +448,35 @@
222 # and get the (successfully built) build records for this
223 # package.
224 completed_builds = BinaryPackageBuild.select("""
225- Build.sourcepackagerelease = SourcePackageRelease.id AND
226- Build.id != %s AND
227- Build.buildduration IS NOT NULL AND
228+ BinaryPackageBuild.source_package_release = SourcePackageRelease.id AND
229+ BinaryPackageBuild.id != %s AND
230+ BinaryPackageBuild.distro_arch_series = %s AND
231 SourcePackageRelease.sourcepackagename = SourcePackageName.id AND
232 SourcePackageName.name = %s AND
233- distroarchseries = %s AND
234- archive IN %s AND
235- buildstate = %s
236- """ % sqlvalues(self, self.sourcepackagerelease.name,
237- self.distroarchseries, archives,
238+ BinaryPackageBuild.package_build = PackageBuild.id AND
239+ PackageBuild.archive IN %s AND
240+ PackageBuild.build_farm_job = BuildFarmJob.id AND
241+ BuildFarmJob.date_finished IS NOT NULL AND
242+ BuildFarmJob.status = %s
243+ """ % sqlvalues(self, self.distro_arch_series,
244+ self.source_package_release.name, archives,
245 BuildStatus.FULLYBUILT),
246- orderBy=['-datebuilt', '-id'],
247- clauseTables=['SourcePackageName', 'SourcePackageRelease'])
248+ orderBy=['-BuildFarmJob.date_finished', '-id'],
249+ clauseTables=['PackageBuild', 'BuildFarmJob', 'SourcePackageName',
250+ 'SourcePackageRelease'])
251
252 if completed_builds.count() > 0:
253 # Historic build data exists, use the most recent value.
254 most_recent_build = completed_builds[0]
255- estimated_duration = most_recent_build.buildduration
256+ date_finished = most_recent_build.date_finished
257+ date_started = most_recent_build.date_started
258+ estimated_duration = date_finished - date_started
259 else:
260 # Estimate the build duration based on package size if no
261 # historic build data exists.
262
263 # Get the package size in KB.
264- package_size = self.sourcepackagerelease.getPackageSize()
265+ package_size = self.source_package_release.getPackageSize()
266
267 if package_size > 0:
268 # Analysis of previous build data shows that a build rate
269@@ -739,19 +745,25 @@
270 query clause if present.
271 """
272
273+ # Ensure the underlying buildfarmjob and package build tables
274+ # are included.
275+ queries.append('BinaryPackageBuild.package_build = PackageBuild.id')
276+ queries.append('PackageBuild.build_farm_job = BuildFarmJob.id')
277+ tables.extend(['PackageBuild', 'BuildFarmJob'])
278+
279 # Add query clause that filters on build state if the latter is
280 # provided.
281 if status is not None:
282- queries.append('Build.buildstate=%s' % sqlvalues(status))
283+ queries.append('BuildFarmJob.status=%s' % sqlvalues(status))
284
285 # Add query clause that filters on pocket if the latter is provided.
286 if pocket:
287- queries.append('Build.pocket=%s' % sqlvalues(pocket))
288+ queries.append('PackageBuild.pocket=%s' % sqlvalues(pocket))
289
290 # Add query clause that filters on architecture tag if provided.
291 if arch_tag is not None:
292 queries.append('''
293- Build.distroarchseries = DistroArchSeries.id AND
294+ BinaryPackageBuild.distro_arch_series = DistroArchSeries.id AND
295 DistroArchSeries.architecturetag = %s
296 ''' % sqlvalues(arch_tag))
297 tables.extend(['DistroArchSeries'])
298@@ -760,7 +772,8 @@
299 # latter is provided.
300 if name is not None:
301 queries.append('''
302- Build.sourcepackagerelease = SourcePackageRelease.id AND
303+ BinaryPackageBuild.source_package_release =
304+ SourcePackageRelease.id AND
305 SourcePackageRelease.sourcepackagename = SourcePackageName.id
306 AND SourcepackageName.name LIKE '%%' || %s || '%%'
307 ''' % quote_like(name))
308@@ -778,7 +791,7 @@
309
310 # This code MUST match the logic in the Build security adapter,
311 # otherwise users are likely to get 403 errors, or worse.
312- queries.append("Archive.id = Build.archive")
313+ queries.append("Archive.id = PackageBuild.archive")
314 clauseTables.append('Archive')
315 if user is not None:
316 if not user.inTeam(getUtility(ILaunchpadCelebrities).admin):
317@@ -796,7 +809,7 @@
318
319 return BinaryPackageBuild.select(
320 " AND ".join(queries), clauseTables=clauseTables,
321- orderBy=["-Build.datebuilt", "id"])
322+ orderBy=["-BuildFarmJob.date_finished", "id"])
323
324 def getBuildsForArchive(self, archive, status=None, name=None,
325 pocket=None, arch_tag=None):
326@@ -812,9 +825,9 @@
327 # * FULLYBUILT & FAILURES by -datebuilt
328 # It should present the builds in a more natural order.
329 if status == BuildStatus.SUPERSEDED or status is None:
330- orderBy = ["-Build.datecreated"]
331+ orderBy = ["-BuildFarmJob.date_created"]
332 else:
333- orderBy = ["-Build.datebuilt"]
334+ orderBy = ["-BuildFarmJob.date_finished"]
335 # All orders fallback to id if the primary order doesn't succeed
336 orderBy.append("id")
337
338@@ -1021,24 +1034,30 @@
339 origin = (
340 BinaryPackageBuild,
341 LeftJoin(
342+ PackageBuild,
343+ BinaryPackageBuild.package_build == PackageBuild.id),
344+ LeftJoin(
345+ BuildFarmJob,
346+ PackageBuild.build_farm_job == BuildFarmJob.id),
347+ LeftJoin(
348 SourcePackageRelease,
349 (SourcePackageRelease.id ==
350- BinaryPackageBuild.sourcepackagereleaseID)),
351+ BinaryPackageBuild.source_package_releaseID)),
352 LeftJoin(
353 SourcePackageName,
354 SourcePackageName.id
355 == SourcePackageRelease.sourcepackagenameID),
356 LeftJoin(LibraryFileAlias,
357- LibraryFileAlias.id == BinaryPackageBuild.buildlogID),
358+ LibraryFileAlias.id == BuildFarmJob.log_id),
359 LeftJoin(LibraryFileContent,
360 LibraryFileContent.id == LibraryFileAlias.contentID),
361 LeftJoin(
362 Builder,
363- Builder.id == BinaryPackageBuild.builderID),
364+ Builder.id == BuildFarmJob.builder_id),
365 )
366 result_set = store.using(*origin).find(
367 (SourcePackageRelease, LibraryFileAlias, SourcePackageName,
368- LibraryFileContent, Builder),
369+ LibraryFileContent, Builder, PackageBuild, BuildFarmJob),
370 In(BinaryPackageBuild.id, build_ids))
371
372 # Force query execution so that the ancillary data gets fetched
373
374=== added file 'lib/lp/soyuz/model/buildfarmbuildjob.py'
375--- lib/lp/soyuz/model/buildfarmbuildjob.py 1970-01-01 00:00:00 +0000
376+++ lib/lp/soyuz/model/buildfarmbuildjob.py 2010-05-05 15:51:57 +0000
377@@ -0,0 +1,50 @@
378+# Copyright 2010 Canonical Ltd. This software is licensed under the
379+# GNU Affero General Public License version 3 (see the file LICENSE).
380+
381+__metaclass__ = type
382+__all__ = [
383+ 'BuildFarmBuildJob',
384+ ]
385+
386+
387+from zope.interface import implements
388+
389+from canonical.database.constants import UTC_NOW
390+
391+from lp.buildmaster.interfaces.buildbase import BuildStatus
392+from lp.buildmaster.model.buildfarmjob import BuildFarmJobOld
393+from lp.soyuz.interfaces.buildfarmbuildjob import IBuildFarmBuildJob
394+
395+
396+class BuildFarmBuildJob(BuildFarmJobOld):
397+ """See `IBuildFaramBuildJob`."""
398+ implements(IBuildFarmBuildJob)
399+ def __init__(self, build):
400+ """Store the build for this package build farm job.
401+
402+ XXX 2010-04-12 michael.nelson bug=536700
403+ The build param will no longer be necessary once BuildFarmJob is
404+ itself a concrete class. This class (PackageBuildFarmJob)
405+ will also be renamed PackageBuild and turned into a concrete class.
406+ """
407+ super(BuildFarmBuildJob, self).__init__()
408+ self.build = build
409+
410+ def getTitle(self):
411+ """See `IBuildFarmJob`."""
412+ return self.build.title
413+
414+ def jobStarted(self):
415+ """See `IBuildFarmJob`."""
416+ self.build.buildstate = BuildStatus.BUILDING
417+ # The build started, set the start time if not set already.
418+ if self.build.date_first_dispatched is None:
419+ self.build.date_first_dispatched = UTC_NOW
420+
421+ def jobReset(self):
422+ """See `IBuildFarmJob`."""
423+ self.build.buildstate = BuildStatus.NEEDSBUILD
424+
425+ def jobAborted(self):
426+ """See `IBuildFarmJob`."""
427+ self.build.buildstate = BuildStatus.NEEDSBUILD
428
429=== modified file 'lib/lp/soyuz/model/buildpackagejob.py'
430--- lib/lp/soyuz/model/buildpackagejob.py 2010-05-05 15:51:54 +0000
431+++ lib/lp/soyuz/model/buildpackagejob.py 2010-05-05 15:51:57 +0000
432@@ -101,13 +101,13 @@
433 # Please note: the score for language packs is to be zero because
434 # they unduly delay the building of packages in the main component
435 # otherwise.
436- if self.build.sourcepackagerelease.section.name == 'translations':
437+ if self.build.source_package_release.section.name == 'translations':
438 pass
439 elif self.build.archive.purpose == ArchivePurpose.COPY:
440 score = rebuild_archive_score
441 else:
442 # Calculates the urgency-related part of the score.
443- urgency = score_urgency[self.build.sourcepackagerelease.urgency]
444+ urgency = score_urgency[self.build.source_package_release.urgency]
445 score += urgency
446
447 # Calculates the pocket-related part of the score.
448@@ -140,13 +140,13 @@
449
450 def getLogFileName(self):
451 """See `IBuildPackageJob`."""
452- sourcename = self.build.sourcepackagerelease.name
453- version = self.build.sourcepackagerelease.version
454+ sourcename = self.build.source_package_release.name
455+ version = self.build.source_package_release.version
456 # we rely on previous storage of current buildstate
457 # in the state handling methods.
458- state = self.build.buildstate.name
459+ state = self.build.status.name
460
461- dar = self.build.distroarchseries
462+ dar = self.build.distro_arch_series
463 distroname = dar.distroseries.distribution.name
464 distroseriesname = dar.distroseries.name
465 archname = dar.architecturetag
466@@ -163,7 +163,7 @@
467
468 def getName(self):
469 """See `IBuildPackageJob`."""
470- return self.build.sourcepackagerelease.name
471+ return self.build.source_package_release.name
472
473 @property
474 def processor(self):
475
476=== modified file 'lib/lp/soyuz/model/publishing.py'
477--- lib/lp/soyuz/model/publishing.py 2010-04-22 08:47:32 +0000
478+++ lib/lp/soyuz/model/publishing.py 2010-05-05 15:51:57 +0000
479@@ -568,7 +568,7 @@
480 return None
481
482 build = self.sourcepackagerelease.createBuild(
483- distroarchseries=arch, archive=self.archive, pocket=self.pocket)
484+ distro_arch_series=arch, archive=self.archive, pocket=self.pocket)
485 # Create the builds in suspended mode for disabled archives.
486 build_queue = build.queueBuild(suspended=not self.archive.enabled)
487 build_queue.score()
488
489=== modified file 'lib/lp/soyuz/model/sourcepackagerelease.py'
490--- lib/lp/soyuz/model/sourcepackagerelease.py 2010-05-05 15:51:54 +0000
491+++ lib/lp/soyuz/model/sourcepackagerelease.py 2010-05-05 15:51:57 +0000
492@@ -347,9 +347,9 @@
493 'DistroArchSeries']
494
495 query = """
496- Build.sourcepackagerelease = %s AND
497- BinaryPackageRelease.build = Build.id AND
498- DistroArchSeries.id = Build.distroarchseries AND
499+ BinaryPackageBuild.source_package_release = %s AND
500+ BinaryPackageRelease.build = BinaryPackageBuild.id AND
501+ DistroArchSeries.id = BinaryPackageBuild.distro_arch_series AND
502 DistroArchSeries.architecturetag = %s AND
503 BinaryPackagePublishingHistory.binarypackagerelease =
504 BinaryPackageRelease.id AND
505@@ -360,7 +360,7 @@
506
507 select_results = BinaryPackageBuild.select(
508 query, clauseTables=clauseTables, distinct=True,
509- orderBy='-Build.id')
510+ orderBy='-BinaryPackageBuild.id')
511
512 # XXX cprov 20080216: this if/elif/else block could be avoided or,
513 # at least, simplified if SelectOne accepts 'distinct' argument.
514@@ -386,7 +386,11 @@
515 # inheritance tree. See bellow.
516 pass
517
518- queries = ["Build.sourcepackagerelease = %s" % sqlvalues(self)]
519+ queries = [
520+ "BinaryPackageBuild.package_build = PackageBuild.id AND "
521+ "PackageBuild.build_farm_job = BuildFarmJob.id AND "
522+ "BinaryPackageBuild.source_package_release = %s" % (
523+ sqlvalues(self))]
524
525 # Find out all the possible parent DistroArchSeries
526 # a build could be issued (then inherited).
527@@ -417,7 +421,8 @@
528 architectures = [
529 architecture.id for architecture in parent_architectures]
530 queries.append(
531- "Build.distroarchseries IN %s" % sqlvalues(architectures))
532+ "BinaryPackageBuild.distro_arch_series IN %s" % (
533+ sqlvalues(architectures)))
534
535 # Follow archive inheritance across distribution offical archives,
536 # for example:
537@@ -436,13 +441,15 @@
538 archives = [archive.id, ]
539
540 queries.append(
541- "Build.archive IN %s" % sqlvalues(archives))
542+ "PackageBuild.archive IN %s" % sqlvalues(archives))
543
544 # Query only the last build record for this sourcerelease
545 # across all possible locations.
546 query = " AND ".join(queries)
547
548- return BinaryPackageBuild.selectFirst(query, orderBy=['-datecreated'])
549+ return BinaryPackageBuild.selectFirst(
550+ query, clauseTables=['BuildFarmJob', 'PackageBuild'],
551+ orderBy=['-BuildFarmJob.date_created'])
552
553 def override(self, component=None, section=None, urgency=None):
554 """See ISourcePackageRelease."""
555
556=== renamed file 'lib/lp/soyuz/tests/test_build.py' => 'lib/lp/soyuz/tests/test_binarypackagebuild.py'
557--- lib/lp/soyuz/tests/test_build.py 2010-05-05 15:51:54 +0000
558+++ lib/lp/soyuz/tests/test_binarypackagebuild.py 2010-05-05 15:51:57 +0000
559@@ -7,6 +7,7 @@
560
561 from storm.store import Store
562 from zope.component import getUtility
563+from zope.security.proxy import removeSecurityProxy
564
565 from canonical.database.constants import UTC_NOW
566 from canonical.testing import LaunchpadZopelessLayer
567@@ -81,7 +82,7 @@
568
569 [depwait_build] = depwait_source.createMissingBuilds()
570 depwait_build.buildstate = BuildStatus.MANUALDEPWAIT
571- depwait_build.dependencies = 'dep-bin'
572+ depwait_build.dependencies = u'dep-bin'
573
574 return depwait_build
575
576@@ -159,10 +160,11 @@
577 # valid ubuntu component.
578 depwait_build = self._setupSimpleDepwaitContext()
579
580+ spr = depwait_build.source_package_release
581 depwait_build.current_source_publication.requestDeletion(
582- depwait_build.sourcepackagerelease.creator)
583+ spr.creator)
584 contrib = getUtility(IComponentSet).new('contrib')
585- depwait_build.sourcepackagerelease.component = contrib
586+ removeSecurityProxy(spr).component = contrib
587
588 depwait_build.updateDependencies()
589 self.assertEquals(depwait_build.dependencies, '')
590@@ -218,7 +220,8 @@
591 # Results can be filtered by architecture tag.
592 i386_builds = self.builds[:]
593 hppa_build = i386_builds.pop()
594- hppa_build.distroarchseries = self.publisher.distroseries['hppa']
595+ removeSecurityProxy(hppa_build).distro_arch_series = (
596+ self.publisher.distroseries['hppa'])
597
598 builds = self.build_set.getBuildsForArchive(self.archive,
599 arch_tag="i386")
600@@ -256,7 +259,8 @@
601 # Results can be filtered by architecture tag.
602 i386_builds = self.builds[:]
603 hppa_build = i386_builds.pop()
604- hppa_build.distroarchseries = self.publisher.distroseries['hppa']
605+ removeSecurityProxy(hppa_build).distro_arch_series = (
606+ self.publisher.distroseries['hppa'])
607
608 builds = self.build_set.getBuildsForBuilder(self.builder.id,
609 arch_tag="i386")
610@@ -296,13 +300,11 @@
611 # Set something just to make sure that storeBuildInfo actually
612 # empties it.
613 self.build.dependencies = u'something'
614-
615 self.build.storeBuildInfo(self.build, None, {})
616- self.assertIsNot(None, self.build.buildlog)
617+ self.assertIsNot(None, self.build.log)
618 self.assertEqual(self.builder, self.build.builder)
619 self.assertIs(None, self.build.dependencies)
620- self.assertIsNot(None, self.build.datebuilt)
621- self.assertIsNot(None, self.build.buildduration)
622+ self.assertIsNot(None, self.build.date_finished)
623
624
625 def test_suite():
626
627=== modified file 'lib/lp/soyuz/tests/test_hasbuildrecords.py'
628--- lib/lp/soyuz/tests/test_hasbuildrecords.py 2010-01-11 23:43:59 +0000
629+++ lib/lp/soyuz/tests/test_hasbuildrecords.py 2010-05-05 15:51:57 +0000
630@@ -13,7 +13,9 @@
631 from lp.buildmaster.interfaces.builder import IBuilderSet
632 from lp.soyuz.interfaces.buildrecords import IHasBuildRecords
633 from lp.soyuz.model.processor import ProcessorFamilySet
634-from lp.soyuz.tests.test_build import BaseTestCaseWithThreeBuilds
635+from lp.soyuz.tests.test_binarypackagebuild import (
636+ BaseTestCaseWithThreeBuilds)
637+
638
639 class TestHasBuildRecordsInterface(BaseTestCaseWithThreeBuilds):
640 """Tests the implementation of IHasBuildRecords by the
641
642=== modified file 'lib/lp/soyuz/tests/test_publishing.py'
643--- lib/lp/soyuz/tests/test_publishing.py 2010-03-17 00:47:49 +0000
644+++ lib/lp/soyuz/tests/test_publishing.py 2010-05-05 15:51:57 +0000
645@@ -317,8 +317,8 @@
646 replaces=None, provides=None, pre_depends=None, enhances=None,
647 breaks=None, format=BinaryPackageFormat.DEB):
648 """Return the corresponding `BinaryPackageRelease`."""
649- sourcepackagerelease = build.sourcepackagerelease
650- distroarchseries = build.distroarchseries
651+ sourcepackagerelease = build.source_package_release
652+ distroarchseries = build.distro_arch_series
653 architecturespecific = (
654 not sourcepackagerelease.architecturehintlist == 'all')
655
656@@ -367,11 +367,11 @@
657 build.buildduration = datetime.timedelta(minutes=5)
658 buildlog_filename = 'buildlog_%s-%s-%s.%s_%s_%s.txt.gz' % (
659 build.distribution.name,
660- build.distroseries.name,
661- build.distroarchseries.architecturetag,
662- build.sourcepackagerelease.name,
663- build.sourcepackagerelease.version,
664- build.buildstate.name)
665+ build.distro_series.name,
666+ build.distro_arch_series.architecturetag,
667+ build.source_package_release.name,
668+ build.source_package_release.version,
669+ build.status.name)
670 build.buildlog = self.addMockFile(
671 buildlog_filename, filecontent='Built!',
672 restricted=build.archive.private)
673@@ -384,7 +384,7 @@
674 pocket=PackagePublishingPocket.RELEASE,
675 scheduleddeletiondate=None, dateremoved=None):
676 """Return the corresponding BinaryPackagePublishingHistory."""
677- distroarchseries = binarypackagerelease.build.distroarchseries
678+ distroarchseries = binarypackagerelease.build.distro_arch_series
679
680 # Publish the binary.
681 if binarypackagerelease.architecturespecific:
682@@ -898,7 +898,7 @@
683 self.addFakeChroots(self.distroseries)
684
685 def getPubSource(self, architecturehintlist):
686- """Return a mock source package publishing record for the archive
687+ """Return a mock source package publishing record for the archive
688 and architecture used in this testcase.
689
690 :param architecturehintlist: Architecture hint list (e.g. "i386 amd64")
691@@ -922,13 +922,13 @@
692 def test__getAllowedArchitectures_restricted_override(self):
693 """Test _getAllowedArchitectures honors overrides of restricted archs.
694
695- Restricted architectures should only be allowed if there is
696+ Restricted architectures should only be allowed if there is
697 an explicit ArchiveArch association with the archive.
698 """
699 available_archs = [self.sparc_distroarch, self.avr_distroarch]
700 getUtility(IArchiveArchSet).new(self.archive, self.avr_family)
701 pubrec = self.getPubSource(architecturehintlist='any')
702- self.assertEquals([self.sparc_distroarch, self.avr_distroarch],
703+ self.assertEquals([self.sparc_distroarch, self.avr_distroarch],
704 pubrec._getAllowedArchitectures(available_archs))
705
706 def test_createMissingBuilds_restricts_any(self):
707@@ -941,7 +941,7 @@
708 self.assertEquals(self.sparc_distroarch, builds[0].distroarchseries)
709
710 def test_createMissingBuilds_restricts_explicitlist(self):
711- """createMissingBuilds() should limit builds targeted at a
712+ """createMissingBuilds() should limit builds targeted at a
713 variety of architectures architecture to those allowed for the archive.
714 """
715 pubrec = self.getPubSource(architecturehintlist='sparc i386 avr')
716@@ -951,7 +951,7 @@
717
718 def test_createMissingBuilds_restricts_all(self):
719 """createMissingBuilds() should limit builds targeted at 'all'
720- architectures to the nominated independent architecture,
721+ architectures to the nominated independent architecture,
722 if that is allowed for the archive.
723 """
724 pubrec = self.getPubSource(architecturehintlist='all')
725@@ -961,7 +961,7 @@
726
727 def test_createMissingBuilds_restrict_override(self):
728 """createMissingBuilds() should limit builds targeted at 'any'
729- architecture to architectures that are unrestricted or
730+ architecture to architectures that are unrestricted or
731 explicitly associated with the archive.
732 """
733 getUtility(IArchiveArchSet).new(self.archive, self.avr_family)
734
735=== modified file 'lib/lp/soyuz/tests/test_publishing_models.py'
736--- lib/lp/soyuz/tests/test_publishing_models.py 2010-03-06 04:57:40 +0000
737+++ lib/lp/soyuz/tests/test_publishing_models.py 2010-05-05 15:51:57 +0000
738@@ -13,7 +13,7 @@
739 from lp.buildmaster.interfaces.buildbase import BuildStatus
740 from lp.soyuz.interfaces.publishing import (IPublishingSet,
741 PackagePublishingStatus)
742-from lp.soyuz.tests.test_build import BaseTestCaseWithThreeBuilds
743+from lp.soyuz.tests.test_binarypackagebuild import BaseTestCaseWithThreeBuilds
744
745
746 class TestPublishingSet(BaseTestCaseWithThreeBuilds):
747@@ -83,8 +83,8 @@
748 for hist in self.sources)
749 urls = [lfa.http_url for lfa in lfas]
750 self.assertEqual(urls, [
751- 'http://localhost:58000/94/gedit_666_source.changes',
752- 'http://localhost:58000/96/firefox_666_source.changes',
753+ 'http://localhost:58000/94/gedit_666_source.changes',
754+ 'http://localhost:58000/96/firefox_666_source.changes',
755 'http://localhost:58000/98/getting-things-gnome_666_source.changes'
756 ])
757

Subscribers

People subscribed via source and target branches

to status/vote changes: