Merge lp://staging/~al-maisan/launchpad/empty-table-507782 into lp://staging/launchpad/db-devel
- empty-table-507782
- Merge into db-devel
Proposed by
Muharem Hrnjadovic
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp://staging/~al-maisan/launchpad/empty-table-507782 |
Merge into: | lp://staging/launchpad/db-devel |
Diff against target: |
359 lines (+120/-38) 8 files modified
lib/lp/buildmaster/interfaces/buildfarmjob.py (+17/-11) lib/lp/buildmaster/model/builder.py (+3/-9) lib/lp/buildmaster/model/buildfarmjob.py (+1/-1) lib/lp/buildmaster/tests/test_builder.py (+66/-6) lib/lp/soyuz/configure.zcml (+3/-0) lib/lp/soyuz/model/buildpackagejob.py (+5/-5) lib/lp/soyuz/model/sourcepackagerecipebuild.py (+8/-5) lib/lp/testing/factory.py (+17/-1) |
To merge this branch: | bzr merge lp://staging/~al-maisan/launchpad/empty-table-507782 |
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Canonical Launchpad Engineering | Pending | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Muharem Hrnjadovic (al-maisan) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/buildmaster/interfaces/buildfarmjob.py' | |||
2 | --- lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-01-18 00:39:57 +0000 | |||
3 | +++ lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-01-18 01:45:24 +0000 | |||
4 | @@ -165,22 +165,28 @@ | |||
5 | 165 | """ | 165 | """ |
6 | 166 | 166 | ||
7 | 167 | def addCandidateSelectionCriteria(processor, virtualized): | 167 | def addCandidateSelectionCriteria(processor, virtualized): |
16 | 168 | """Provide extra clauses that will refine the candidate job selection. | 168 | """Provide a sub-query to refine the candidate job selection. |
17 | 169 | 169 | ||
18 | 170 | Return a 2-tuple with extra tables and clauses to be used to | 170 | Return a sub-query to narrow down the list of candidate jobs. |
19 | 171 | narrow down the list of candidate jobs. | 171 | The sub-query will become part of an "outer query" and is free to |
20 | 172 | 172 | refer to the `BuildQueue` and `Job` tables already utilized in the | |
21 | 173 | Example: | 173 | latter. |
22 | 174 | (('Build', 'BuildPackageJob'), | 174 | |
23 | 175 | "BuildPackageJob.build = Build.id AND ..") | 175 | Example (please see the `BuildPackageJob` implementation for a |
24 | 176 | complete example): | ||
25 | 177 | |||
26 | 178 | SELECT TRUE | ||
27 | 179 | FROM Archive, Build, BuildPackageJob, DistroArchSeries | ||
28 | 180 | WHERE | ||
29 | 181 | BuildPackageJob.job = Job.id AND | ||
30 | 182 | .. | ||
31 | 176 | 183 | ||
32 | 177 | :param processor: the type of processor that the candidate jobs are | 184 | :param processor: the type of processor that the candidate jobs are |
33 | 178 | expected to run on. | 185 | expected to run on. |
34 | 179 | :param virtualized: whether the candidate jobs are expected to run on | 186 | :param virtualized: whether the candidate jobs are expected to run on |
35 | 180 | the `processor` natively or inside a virtual machine. | 187 | the `processor` natively or inside a virtual machine. |
39 | 181 | :return: an (extra_tables, extra_query) tuple where `extra_tables` is | 188 | :return: a string containing a sub-query that narrows down the list of |
40 | 182 | a collection of tables that need to appear in the FROM clause of | 189 | candidate jobs. |
38 | 183 | the combined query for `extra_query` to work. | ||
41 | 184 | """ | 190 | """ |
42 | 185 | 191 | ||
43 | 186 | def postprocessCandidate(job, logger): | 192 | def postprocessCandidate(job, logger): |
44 | 187 | 193 | ||
45 | === modified file 'lib/lp/buildmaster/model/builder.py' | |||
46 | --- lib/lp/buildmaster/model/builder.py 2010-01-16 05:54:16 +0000 | |||
47 | +++ lib/lp/buildmaster/model/builder.py 2010-01-18 01:45:24 +0000 | |||
48 | @@ -437,7 +437,7 @@ | |||
49 | 437 | def qualify_subquery(job_type, sub_query): | 437 | def qualify_subquery(job_type, sub_query): |
50 | 438 | """Put the sub-query into a job type context.""" | 438 | """Put the sub-query into a job type context.""" |
51 | 439 | qualified_query = """ | 439 | qualified_query = """ |
53 | 440 | ((BuildQueue.job_type != %s) OR (%%s)) | 440 | ((BuildQueue.job_type != %s) OR EXISTS(%%s)) |
54 | 441 | """ % sqlvalues(job_type) | 441 | """ % sqlvalues(job_type) |
55 | 442 | qualified_query %= sub_query | 442 | qualified_query %= sub_query |
56 | 443 | return qualified_query | 443 | return qualified_query |
57 | @@ -445,9 +445,8 @@ | |||
58 | 445 | logger = self._getSlaveScannerLogger() | 445 | logger = self._getSlaveScannerLogger() |
59 | 446 | candidate = None | 446 | candidate = None |
60 | 447 | 447 | ||
61 | 448 | query_tables = set(('buildqueue', 'job')) | ||
62 | 449 | general_query = """ | 448 | general_query = """ |
64 | 450 | SELECT buildqueue.id FROM %%s | 449 | SELECT buildqueue.id FROM buildqueue, job |
65 | 451 | WHERE | 450 | WHERE |
66 | 452 | buildqueue.job = job.id | 451 | buildqueue.job = job.id |
67 | 453 | AND job.status = %s | 452 | AND job.status = %s |
68 | @@ -474,20 +473,15 @@ | |||
69 | 474 | extra_queries = [] | 473 | extra_queries = [] |
70 | 475 | job_classes = specific_job_classes() | 474 | job_classes = specific_job_classes() |
71 | 476 | for job_type, job_class in job_classes.iteritems(): | 475 | for job_type, job_class in job_classes.iteritems(): |
73 | 477 | tables, query = job_class.addCandidateSelectionCriteria( | 476 | query = job_class.addCandidateSelectionCriteria( |
74 | 478 | self.processor, self.virtualized) | 477 | self.processor, self.virtualized) |
75 | 479 | if query == '': | 478 | if query == '': |
76 | 480 | # This job class does not need to refine candidate jobs | 479 | # This job class does not need to refine candidate jobs |
77 | 481 | # further. | 480 | # further. |
78 | 482 | continue | 481 | continue |
79 | 483 | 482 | ||
80 | 484 | # Table names are case-insensitive in SQL. All table names are in | ||
81 | 485 | # lower case in order to avoid duplicates in the FROM clause. | ||
82 | 486 | query_tables = query_tables.union( | ||
83 | 487 | set(table.lower() for table in tables)) | ||
84 | 488 | # The sub-query should only apply to jobs of the right type. | 483 | # The sub-query should only apply to jobs of the right type. |
85 | 489 | extra_queries.append(qualify_subquery(job_type, query)) | 484 | extra_queries.append(qualify_subquery(job_type, query)) |
86 | 490 | general_query = general_query % ', '.join(query_tables) | ||
87 | 491 | query = ' AND '.join([general_query] + extra_queries) + order_clause | 485 | query = ' AND '.join([general_query] + extra_queries) + order_clause |
88 | 492 | 486 | ||
89 | 493 | store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) | 487 | store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) |
90 | 494 | 488 | ||
91 | === modified file 'lib/lp/buildmaster/model/buildfarmjob.py' | |||
92 | --- lib/lp/buildmaster/model/buildfarmjob.py 2010-01-16 07:52:28 +0000 | |||
93 | +++ lib/lp/buildmaster/model/buildfarmjob.py 2010-01-18 01:45:24 +0000 | |||
94 | @@ -62,7 +62,7 @@ | |||
95 | 62 | @staticmethod | 62 | @staticmethod |
96 | 63 | def addCandidateSelectionCriteria(processor, virtualized): | 63 | def addCandidateSelectionCriteria(processor, virtualized): |
97 | 64 | """See `IBuildFarmCandidateJobSelection`.""" | 64 | """See `IBuildFarmCandidateJobSelection`.""" |
99 | 65 | return ([], '') | 65 | return ('') |
100 | 66 | 66 | ||
101 | 67 | @classmethod | 67 | @classmethod |
102 | 68 | def getByJob(cls, job): | 68 | def getByJob(cls, job): |
103 | 69 | 69 | ||
104 | === modified file 'lib/lp/buildmaster/tests/test_builder.py' | |||
105 | --- lib/lp/buildmaster/tests/test_builder.py 2010-01-12 20:26:34 +0000 | |||
106 | +++ lib/lp/buildmaster/tests/test_builder.py 2010-01-18 01:45:24 +0000 | |||
107 | @@ -8,16 +8,22 @@ | |||
108 | 8 | from zope.component import getUtility | 8 | from zope.component import getUtility |
109 | 9 | from zope.security.proxy import removeSecurityProxy | 9 | from zope.security.proxy import removeSecurityProxy |
110 | 10 | 10 | ||
111 | 11 | from canonical.launchpad.webapp.interfaces import ( | ||
112 | 12 | IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR) | ||
113 | 11 | from canonical.testing import LaunchpadZopelessLayer | 13 | from canonical.testing import LaunchpadZopelessLayer |
114 | 14 | from lp.buildmaster.interfaces.builder import IBuilderSet | ||
115 | 15 | from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType | ||
116 | 12 | from lp.buildmaster.interfaces.buildfarmjobbehavior import ( | 16 | from lp.buildmaster.interfaces.buildfarmjobbehavior import ( |
117 | 13 | IBuildFarmJobBehavior) | 17 | IBuildFarmJobBehavior) |
118 | 14 | from lp.buildmaster.model.buildfarmjobbehavior import IdleBuildBehavior | 18 | from lp.buildmaster.model.buildfarmjobbehavior import IdleBuildBehavior |
119 | 15 | from lp.soyuz.interfaces.archive import ArchivePurpose | 19 | from lp.soyuz.interfaces.archive import ArchivePurpose |
120 | 16 | from lp.soyuz.interfaces.build import BuildStatus, IBuildSet | 20 | from lp.soyuz.interfaces.build import BuildStatus, IBuildSet |
121 | 17 | from lp.buildmaster.interfaces.builder import IBuilderSet | ||
122 | 18 | from lp.soyuz.interfaces.publishing import PackagePublishingStatus | 21 | from lp.soyuz.interfaces.publishing import PackagePublishingStatus |
123 | 22 | from lp.soyuz.interfaces.sourcepackagerecipebuild import ( | ||
124 | 23 | ISourcePackageRecipeBuildSource) | ||
125 | 19 | from lp.soyuz.model.binarypackagebuildbehavior import ( | 24 | from lp.soyuz.model.binarypackagebuildbehavior import ( |
126 | 20 | BinaryPackageBuildBehavior) | 25 | BinaryPackageBuildBehavior) |
127 | 26 | from lp.soyuz.model.buildqueue import BuildQueue | ||
128 | 21 | from lp.soyuz.tests.test_publishing import SoyuzTestPublisher | 27 | from lp.soyuz.tests.test_publishing import SoyuzTestPublisher |
129 | 22 | from lp.testing import TestCaseWithFactory | 28 | from lp.testing import TestCaseWithFactory |
130 | 23 | 29 | ||
131 | @@ -194,15 +200,15 @@ | |||
132 | 194 | super(TestFindBuildCandidateDistroArchive, self).setUp() | 200 | super(TestFindBuildCandidateDistroArchive, self).setUp() |
133 | 195 | # Create a primary archive and publish some builds for the | 201 | # Create a primary archive and publish some builds for the |
134 | 196 | # queue. | 202 | # queue. |
136 | 197 | non_ppa = self.factory.makeArchive( | 203 | self.non_ppa = self.factory.makeArchive( |
137 | 198 | name="primary", purpose=ArchivePurpose.PRIMARY) | 204 | name="primary", purpose=ArchivePurpose.PRIMARY) |
138 | 199 | 205 | ||
140 | 200 | gedit_build = self.publisher.getPubSource( | 206 | self.gedit_build = self.publisher.getPubSource( |
141 | 201 | sourcename="gedit", status=PackagePublishingStatus.PUBLISHED, | 207 | sourcename="gedit", status=PackagePublishingStatus.PUBLISHED, |
144 | 202 | archive=non_ppa).createMissingBuilds()[0] | 208 | archive=self.non_ppa).createMissingBuilds()[0] |
145 | 203 | firefox_build = self.publisher.getPubSource( | 209 | self.firefox_build = self.publisher.getPubSource( |
146 | 204 | sourcename="firefox", status=PackagePublishingStatus.PUBLISHED, | 210 | sourcename="firefox", status=PackagePublishingStatus.PUBLISHED, |
148 | 205 | archive=non_ppa).createMissingBuilds()[0] | 211 | archive=self.non_ppa).createMissingBuilds()[0] |
149 | 206 | 212 | ||
150 | 207 | def test_findBuildCandidate_for_non_ppa(self): | 213 | def test_findBuildCandidate_for_non_ppa(self): |
151 | 208 | # Normal archives are not restricted to serial builds per | 214 | # Normal archives are not restricted to serial builds per |
152 | @@ -224,6 +230,60 @@ | |||
153 | 224 | self.failUnlessEqual('primary', build.archive.name) | 230 | self.failUnlessEqual('primary', build.archive.name) |
154 | 225 | self.failUnlessEqual('firefox', build.sourcepackagerelease.name) | 231 | self.failUnlessEqual('firefox', build.sourcepackagerelease.name) |
155 | 226 | 232 | ||
156 | 233 | def test_findBuildCandidate_for_recipe_build(self): | ||
157 | 234 | # Recipe builds with a higher score are selected first. | ||
158 | 235 | # This test is run in a context with mixed recipe and binary builds. | ||
159 | 236 | |||
160 | 237 | self.assertIsNot(self.frog_builder.processor, None) | ||
161 | 238 | self.assertEqual(self.frog_builder.virtualized, True) | ||
162 | 239 | |||
163 | 240 | self.assertEqual(self.gedit_build.buildqueue_record.lastscore, 2505) | ||
164 | 241 | self.assertEqual(self.firefox_build.buildqueue_record.lastscore, 2505) | ||
165 | 242 | |||
166 | 243 | recipe_build_job = self.factory.makeSourcePackageRecipeBuildJob(9999) | ||
167 | 244 | |||
168 | 245 | self.assertEqual(recipe_build_job.lastscore, 9999) | ||
169 | 246 | |||
170 | 247 | next_job = removeSecurityProxy( | ||
171 | 248 | self.frog_builder)._findBuildCandidate() | ||
172 | 249 | |||
173 | 250 | self.failUnlessEqual(recipe_build_job, next_job) | ||
174 | 251 | |||
175 | 252 | |||
176 | 253 | class TestFindRecipeBuildCandidates(TestFindBuildCandidateBase): | ||
177 | 254 | # These tests operate in a "recipe builds only" setting. | ||
178 | 255 | # Please see also bug #507782. | ||
179 | 256 | |||
180 | 257 | def clearBuildQueue(self): | ||
181 | 258 | """Delete all `BuildQueue`, XXXJOb and `Job` instances.""" | ||
182 | 259 | store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) | ||
183 | 260 | for bq in store.find(BuildQueue): | ||
184 | 261 | bq.destroySelf() | ||
185 | 262 | |||
186 | 263 | def setUp(self): | ||
187 | 264 | """Publish some builds for the test archive.""" | ||
188 | 265 | super(TestFindRecipeBuildCandidates, self).setUp() | ||
189 | 266 | # Create a primary archive and publish some builds for the | ||
190 | 267 | # queue. | ||
191 | 268 | self.non_ppa = self.factory.makeArchive( | ||
192 | 269 | name="primary", purpose=ArchivePurpose.PRIMARY) | ||
193 | 270 | |||
194 | 271 | self.clearBuildQueue() | ||
195 | 272 | self.bq1 = self.factory.makeSourcePackageRecipeBuildJob(3333) | ||
196 | 273 | self.bq2 = self.factory.makeSourcePackageRecipeBuildJob(4333) | ||
197 | 274 | |||
198 | 275 | def test_findBuildCandidate_with_highest_score(self): | ||
199 | 276 | # The recipe build with the highest score is selected first. | ||
200 | 277 | # This test is run in a "recipe builds only" context. | ||
201 | 278 | |||
202 | 279 | self.assertIsNot(self.frog_builder.processor, None) | ||
203 | 280 | self.assertEqual(self.frog_builder.virtualized, True) | ||
204 | 281 | |||
205 | 282 | next_job = removeSecurityProxy( | ||
206 | 283 | self.frog_builder)._findBuildCandidate() | ||
207 | 284 | |||
208 | 285 | self.failUnlessEqual(self.bq2, next_job) | ||
209 | 286 | |||
210 | 227 | 287 | ||
211 | 228 | class TestCurrentBuildBehavior(TestCaseWithFactory): | 288 | class TestCurrentBuildBehavior(TestCaseWithFactory): |
212 | 229 | """This test ensures the get/set behavior of IBuilder's | 289 | """This test ensures the get/set behavior of IBuilder's |
213 | 230 | 290 | ||
214 | === modified file 'lib/lp/soyuz/configure.zcml' | |||
215 | --- lib/lp/soyuz/configure.zcml 2010-01-17 05:01:30 +0000 | |||
216 | +++ lib/lp/soyuz/configure.zcml 2010-01-18 01:45:24 +0000 | |||
217 | @@ -962,6 +962,9 @@ | |||
218 | 962 | class="lp.soyuz.model.sourcepackagerecipebuild.SourcePackageRecipeBuildJob"> | 962 | class="lp.soyuz.model.sourcepackagerecipebuild.SourcePackageRecipeBuildJob"> |
219 | 963 | <allow interface="lp.soyuz.interfaces.sourcepackagerecipebuild.ISourcePackageRecipeBuildJob"/> | 963 | <allow interface="lp.soyuz.interfaces.sourcepackagerecipebuild.ISourcePackageRecipeBuildJob"/> |
220 | 964 | </class> | 964 | </class> |
221 | 965 | <utility component="lp.soyuz.model.sourcepackagerecipebuild.SourcePackageRecipeBuildJob" | ||
222 | 966 | name="RECIPEBRANCHBUILD" | ||
223 | 967 | provides="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJob"/> | ||
224 | 965 | 968 | ||
225 | 966 | <securedutility | 969 | <securedutility |
226 | 967 | component="lp.soyuz.model.sourcepackagerecipebuild.SourcePackageRecipeBuildJob" | 970 | component="lp.soyuz.model.sourcepackagerecipebuild.SourcePackageRecipeBuildJob" |
227 | 968 | 971 | ||
228 | === modified file 'lib/lp/soyuz/model/buildpackagejob.py' | |||
229 | --- lib/lp/soyuz/model/buildpackagejob.py 2010-01-16 09:45:58 +0000 | |||
230 | +++ lib/lp/soyuz/model/buildpackagejob.py 2010-01-18 01:45:24 +0000 | |||
231 | @@ -230,9 +230,9 @@ | |||
232 | 230 | PackagePublishingStatus.SUPERSEDED, | 230 | PackagePublishingStatus.SUPERSEDED, |
233 | 231 | PackagePublishingStatus.DELETED, | 231 | PackagePublishingStatus.DELETED, |
234 | 232 | ) | 232 | ) |
238 | 233 | extra_tables = [ | 233 | sub_query = """ |
239 | 234 | 'Archive', 'Build', 'BuildPackageJob', 'DistroArchSeries'] | 234 | SELECT TRUE FROM Archive, Build, BuildPackageJob, DistroArchSeries |
240 | 235 | extra_clauses = """ | 235 | WHERE |
241 | 236 | BuildPackageJob.job = Job.id AND | 236 | BuildPackageJob.job = Job.id AND |
242 | 237 | BuildPackageJob.build = Build.id AND | 237 | BuildPackageJob.build = Build.id AND |
243 | 238 | Build.distroarchseries = DistroArchSeries.id AND | 238 | Build.distroarchseries = DistroArchSeries.id AND |
244 | @@ -269,7 +269,7 @@ | |||
245 | 269 | num_arch_builders = Builder.selectBy( | 269 | num_arch_builders = Builder.selectBy( |
246 | 270 | processor=processor, manual=False, builderok=True).count() | 270 | processor=processor, manual=False, builderok=True).count() |
247 | 271 | if num_arch_builders > 1: | 271 | if num_arch_builders > 1: |
249 | 272 | extra_clauses += """ | 272 | sub_query += """ |
250 | 273 | AND EXISTS (SELECT true | 273 | AND EXISTS (SELECT true |
251 | 274 | WHERE (( | 274 | WHERE (( |
252 | 275 | SELECT COUNT(build2.id) | 275 | SELECT COUNT(build2.id) |
253 | @@ -287,7 +287,7 @@ | |||
254 | 287 | ArchivePurpose.PPA, processor.family, | 287 | ArchivePurpose.PPA, processor.family, |
255 | 288 | BuildStatus.BUILDING, num_arch_builders) | 288 | BuildStatus.BUILDING, num_arch_builders) |
256 | 289 | 289 | ||
258 | 290 | return(extra_tables, extra_clauses) | 290 | return sub_query |
259 | 291 | 291 | ||
260 | 292 | @staticmethod | 292 | @staticmethod |
261 | 293 | def postprocessCandidate(job, logger): | 293 | def postprocessCandidate(job, logger): |
262 | 294 | 294 | ||
263 | === modified file 'lib/lp/soyuz/model/sourcepackagerecipebuild.py' | |||
264 | --- lib/lp/soyuz/model/sourcepackagerecipebuild.py 2010-01-18 00:39:57 +0000 | |||
265 | +++ lib/lp/soyuz/model/sourcepackagerecipebuild.py 2010-01-18 01:45:24 +0000 | |||
266 | @@ -19,8 +19,9 @@ | |||
267 | 19 | from zope.component import getUtility | 19 | from zope.component import getUtility |
268 | 20 | from zope.interface import classProvides, implements | 20 | from zope.interface import classProvides, implements |
269 | 21 | 21 | ||
270 | 22 | from lp.buildmaster.model.buildfarmjob import BuildFarmJob | ||
271 | 23 | from lp.registry.interfaces.pocket import PackagePublishingPocket | ||
272 | 22 | from lp.services.job.model.job import Job | 24 | from lp.services.job.model.job import Job |
273 | 23 | from lp.registry.interfaces.pocket import PackagePublishingPocket | ||
274 | 24 | from lp.soyuz.adapters.archivedependencies import ( | 25 | from lp.soyuz.adapters.archivedependencies import ( |
275 | 25 | default_component_dependency_name,) | 26 | default_component_dependency_name,) |
276 | 26 | from lp.soyuz.interfaces.build import BuildStatus | 27 | from lp.soyuz.interfaces.build import BuildStatus |
277 | @@ -65,7 +66,8 @@ | |||
278 | 65 | distroseries = Reference(distroseries_id, 'DistroSeries.id') | 66 | distroseries = Reference(distroseries_id, 'DistroSeries.id') |
279 | 66 | 67 | ||
280 | 67 | sourcepackagename_id = Int(name='sourcepackagename', allow_none=True) | 68 | sourcepackagename_id = Int(name='sourcepackagename', allow_none=True) |
282 | 68 | sourcepackagename = Reference(sourcepackagename_id, 'SourcePackageName.id') | 69 | sourcepackagename = Reference( |
283 | 70 | sourcepackagename_id, 'SourcePackageName.id') | ||
284 | 69 | 71 | ||
285 | 70 | @property | 72 | @property |
286 | 71 | def pocket(self): | 73 | def pocket(self): |
287 | @@ -101,7 +103,8 @@ | |||
288 | 101 | self.sourcepackagename = sourcepackagename | 103 | self.sourcepackagename = sourcepackagename |
289 | 102 | 104 | ||
290 | 103 | @classmethod | 105 | @classmethod |
292 | 104 | def new(cls, sourcepackage, recipe, requester, archive, date_created=None): | 106 | def new( |
293 | 107 | cls, sourcepackage, recipe, requester, archive, date_created=None): | ||
294 | 105 | """See `ISourcePackageRecipeBuildSource`.""" | 108 | """See `ISourcePackageRecipeBuildSource`.""" |
295 | 106 | store = IMasterStore(SourcePackageRecipeBuild) | 109 | store = IMasterStore(SourcePackageRecipeBuild) |
296 | 107 | if date_created is None: | 110 | if date_created is None: |
297 | @@ -126,7 +129,7 @@ | |||
298 | 126 | return specific_job | 129 | return specific_job |
299 | 127 | 130 | ||
300 | 128 | 131 | ||
302 | 129 | class SourcePackageRecipeBuildJob(Storm): | 132 | class SourcePackageRecipeBuildJob(BuildFarmJob, Storm): |
303 | 130 | 133 | ||
304 | 131 | classProvides(ISourcePackageRecipeBuildJobSource) | 134 | classProvides(ISourcePackageRecipeBuildJobSource) |
305 | 132 | implements(ISourcePackageRecipeBuildJob) | 135 | implements(ISourcePackageRecipeBuildJob) |
306 | @@ -143,7 +146,7 @@ | |||
307 | 143 | source_package_build_id, 'SourcePackageRecipeBuild.id') | 146 | source_package_build_id, 'SourcePackageRecipeBuild.id') |
308 | 144 | 147 | ||
309 | 145 | processor = None | 148 | processor = None |
311 | 146 | virtualized = False | 149 | virtualized = True |
312 | 147 | 150 | ||
313 | 148 | def __init__(self, build, job): | 151 | def __init__(self, build, job): |
314 | 149 | super(SourcePackageRecipeBuildJob, self).__init__() | 152 | super(SourcePackageRecipeBuildJob, self).__init__() |
315 | 150 | 153 | ||
316 | === modified file 'lib/lp/testing/factory.py' | |||
317 | --- lib/lp/testing/factory.py 2010-01-17 23:32:21 +0000 | |||
318 | +++ lib/lp/testing/factory.py 2010-01-18 01:45:24 +0000 | |||
319 | @@ -86,7 +86,8 @@ | |||
320 | 86 | from lp.services.mail.signedmessage import SignedMessage | 86 | from lp.services.mail.signedmessage import SignedMessage |
321 | 87 | from lp.services.worlddata.interfaces.country import ICountrySet | 87 | from lp.services.worlddata.interfaces.country import ICountrySet |
322 | 88 | from canonical.launchpad.webapp.dbpolicy import MasterDatabasePolicy | 88 | from canonical.launchpad.webapp.dbpolicy import MasterDatabasePolicy |
324 | 89 | from canonical.launchpad.webapp.interfaces import IStoreSelector | 89 | from canonical.launchpad.webapp.interfaces import ( |
325 | 90 | IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR) | ||
326 | 90 | from lp.code.enums import ( | 91 | from lp.code.enums import ( |
327 | 91 | BranchMergeProposalStatus, BranchSubscriptionNotificationLevel, | 92 | BranchMergeProposalStatus, BranchSubscriptionNotificationLevel, |
328 | 92 | BranchType, CodeImportMachineState, CodeImportReviewStatus, | 93 | BranchType, CodeImportMachineState, CodeImportReviewStatus, |
329 | @@ -125,8 +126,10 @@ | |||
330 | 125 | from lp.registry.interfaces.ssh import ISSHKeySet, SSHKeyType | 126 | from lp.registry.interfaces.ssh import ISSHKeySet, SSHKeyType |
331 | 126 | from lp.services.worlddata.interfaces.language import ILanguageSet | 127 | from lp.services.worlddata.interfaces.language import ILanguageSet |
332 | 127 | from lp.buildmaster.interfaces.builder import IBuilderSet | 128 | from lp.buildmaster.interfaces.builder import IBuilderSet |
333 | 129 | from lp.buildmaster.interfaces.buildfarmjob import BuildFarmJobType | ||
334 | 128 | from lp.soyuz.interfaces.component import IComponentSet | 130 | from lp.soyuz.interfaces.component import IComponentSet |
335 | 129 | from lp.soyuz.interfaces.packageset import IPackagesetSet | 131 | from lp.soyuz.interfaces.packageset import IPackagesetSet |
336 | 132 | from lp.soyuz.model.buildqueue import BuildQueue | ||
337 | 130 | from lp.testing import run_with_login, time_counter | 133 | from lp.testing import run_with_login, time_counter |
338 | 131 | 134 | ||
339 | 132 | SPACE = ' ' | 135 | SPACE = ' ' |
340 | @@ -1615,6 +1618,19 @@ | |||
341 | 1615 | archive=archive, | 1618 | archive=archive, |
342 | 1616 | requester=requester) | 1619 | requester=requester) |
343 | 1617 | 1620 | ||
344 | 1621 | def makeSourcePackageRecipeBuildJob(self, score=9876): | ||
345 | 1622 | """Create a `SourcePackageRecipeBuildJob` and a `BuildQueue` for | ||
346 | 1623 | testing.""" | ||
347 | 1624 | recipe_build = self.makeSourcePackageRecipeBuild() | ||
348 | 1625 | recipe_build_job = recipe_build.makeJob() | ||
349 | 1626 | |||
350 | 1627 | store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) | ||
351 | 1628 | bq = BuildQueue( | ||
352 | 1629 | job=recipe_build_job.job, lastscore=score, | ||
353 | 1630 | job_type=BuildFarmJobType.RECIPEBRANCHBUILD) | ||
354 | 1631 | store.add(bq) | ||
355 | 1632 | return bq | ||
356 | 1633 | |||
357 | 1618 | def makePOTemplate(self, productseries=None, distroseries=None, | 1634 | def makePOTemplate(self, productseries=None, distroseries=None, |
358 | 1619 | sourcepackagename=None, owner=None, name=None, | 1635 | sourcepackagename=None, owner=None, name=None, |
359 | 1620 | translation_domain=None, path=None): | 1636 | translation_domain=None, path=None): |
This branch fixes (first and foremost) the following bug: source package recipe build jobs are not seen in the absence of binary build jobs. This makes the candidate job selection fail.
Test to run:
bin/test -vv build