Merge lp:~al-maisan/launchpad/ibuilder-api-cleanup-505647 into lp:launchpad

Proposed by Muharem Hrnjadovic
Status: Merged
Merged at revision: not available
Proposed branch: lp:~al-maisan/launchpad/ibuilder-api-cleanup-505647
Merge into: lp:launchpad
Diff against target: 622 lines (+117/-93)
7 files modified
lib/lp/buildmaster/manager.py (+2/-10)
lib/lp/soyuz/doc/buildd-dispatching.txt (+17/-11)
lib/lp/soyuz/doc/buildd-slavescanner.txt (+31/-30)
lib/lp/soyuz/interfaces/builder.py (+8/-18)
lib/lp/soyuz/model/builder.py (+41/-9)
lib/lp/soyuz/scripts/buildd.py (+2/-4)
lib/lp/soyuz/tests/test_builder.py (+16/-11)
To merge this branch: bzr merge lp:~al-maisan/launchpad/ibuilder-api-cleanup-505647
Reviewer Review Type Date Requested Status
Björn Tillenius (community) Approve
Review via email: mp+17122@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Muharem Hrnjadovic (al-maisan) wrote :

Hello there!

This branch cleans up the IBuilder interface and model code related to
candidate job selection.
The findBuildCandidate()/dispatchBuildCandidate() methods are made internal
and a new findAndStartJob() method that hides them is introduced.

Tests to run:

   bin/test -vv -t build

No "make lint" errors.

Revision history for this message
Björn Tillenius (bjornt) wrote :
Download full text (3.7 KiB)

On Mon, Jan 11, 2010 at 03:08:17AM -0000, Muharem Hrnjadovic wrote:
> === modified file 'lib/lp/buildmaster/manager.py'
> --- lib/lp/buildmaster/manager.py 2009-07-26 14:19:49 +0000
> +++ lib/lp/buildmaster/manager.py 2010-01-11 03:08:16 +0000
> @@ -340,17 +340,9 @@
> transaction.commit()
> continue
>
> - candidate = builder.findBuildCandidate()
> - if candidate is None:
> - self.logger.debug(
> - "No build candidates available for builder.")
> - continue
> -
> slave = RecordingSlave(builder.name, builder.url, builder.vm_host)
> - builder.setSlaveForTesting(slave)
> -
> - builder.dispatchBuildCandidate(candidate)
> - if builder.currentjob is not None:
> + candidate = builder.findAndStartJob(buildd_slave=slave)
> + if candidate is not None:
> recording_slaves.append(slave)
> transaction.commit()

Here you changed it to commit when no candidates are found...

> === modified file 'lib/lp/soyuz/scripts/buildd.py'
> --- lib/lp/soyuz/scripts/buildd.py 2009-10-26 18:40:04 +0000
> +++ lib/lp/soyuz/scripts/buildd.py 2010-01-11 03:08:16 +0000
> @@ -201,12 +201,10 @@
> if not builder.is_available:
> self.logger.warn('builder is not available. Ignored.')
> continue
> - candidate = builder.findBuildCandidate()
> +
> + candidate = builder.findAndStartJob()
> if candidate is None:
> - self.logger.debug(
> - "No candidates available for builder.")
> continue
> - builder.dispatchBuildCandidate(candidate)
> self.txn.commit()

... but here you retain the behaviour of not commiting when no candidate
is found. Why was one place changed, but not the other?

> === modified file 'lib/lp/soyuz/tests/test_builder.py'
> --- lib/lp/soyuz/tests/test_builder.py 2009-12-02 15:18:46 +0000
> +++ lib/lp/soyuz/tests/test_builder.py 2010-01-11 03:08:16 +0000

> @@ -34,13 +35,15 @@
> # Create some i386 builders ready to build PPA builds. Two
> # already exist in sampledata so we'll use those first.
> self.builder1 = getUtility(IBuilderSet)['bob']
> - self.builder2 = getUtility(IBuilderSet)['frog']
> + self.frog_builder = removeSecurityProxy(
> + getUtility(IBuilderSet)['frog'])

Why doesn't frog_builder have a security proxy? If it's just to call
private methods, it's better to remove the proxy when you call the
method. If you start passing frog_builder to methods in your tests, you
might get things passing in the tests, while failing in real code.
Better to be safe and only unwrap the objects when you know it's safe.

> self.builder3 = self.factory.makeBuilder(name='builder3')
> - self.builder4 = self.factory.makeBuilder(name='builder4')
> + self.builder4 = removeSecurityProxy(
> + self.factory.makeBuilder(name='builder4'))

Same comment here.

> self.builder5 = self.factory.makeBuilder(name='builder5')
> self.b...

Read more...

review: Needs Information
Revision history for this message
Muharem Hrnjadovic (al-maisan) wrote :
Download full text (4.2 KiB)

Björn Tillenius wrote:
> Review: Needs Information
> On Mon, Jan 11, 2010 at 03:08:17AM -0000, Muharem Hrnjadovic wrote:
>> === modified file 'lib/lp/buildmaster/manager.py'
>> --- lib/lp/buildmaster/manager.py 2009-07-26 14:19:49 +0000
>> +++ lib/lp/buildmaster/manager.py 2010-01-11 03:08:16 +0000
>> @@ -340,17 +340,9 @@
>> transaction.commit()
>> continue
>>
>> - candidate = builder.findBuildCandidate()
>> - if candidate is None:
>> - self.logger.debug(
>> - "No build candidates available for builder.")
>> - continue
>> -
>> slave = RecordingSlave(builder.name, builder.url, builder.vm_host)
>> - builder.setSlaveForTesting(slave)
>> -
>> - builder.dispatchBuildCandidate(candidate)
>> - if builder.currentjob is not None:
>> + candidate = builder.findAndStartJob(buildd_slave=slave)
>> + if candidate is not None:
>> recording_slaves.append(slave)
>> transaction.commit()
>
> Here you changed it to commit when no candidates are found...
Good catch! I have indented the commit() line above to preserve the old
behaviour.

>> === modified file 'lib/lp/soyuz/scripts/buildd.py'
>> --- lib/lp/soyuz/scripts/buildd.py 2009-10-26 18:40:04 +0000
>> +++ lib/lp/soyuz/scripts/buildd.py 2010-01-11 03:08:16 +0000
>> @@ -201,12 +201,10 @@
>> if not builder.is_available:
>> self.logger.warn('builder is not available. Ignored.')
>> continue
>> - candidate = builder.findBuildCandidate()
>> +
>> + candidate = builder.findAndStartJob()
>> if candidate is None:
>> - self.logger.debug(
>> - "No candidates available for builder.")
>> continue
>> - builder.dispatchBuildCandidate(candidate)
>> self.txn.commit()
>
> ... but here you retain the behaviour of not commiting when no candidate
> is found. Why was one place changed, but not the other?
The issue above is fixed now.

>> === modified file 'lib/lp/soyuz/tests/test_builder.py'
>> --- lib/lp/soyuz/tests/test_builder.py 2009-12-02 15:18:46 +0000
>> +++ lib/lp/soyuz/tests/test_builder.py 2010-01-11 03:08:16 +0000
>
>> @@ -34,13 +35,15 @@
>> # Create some i386 builders ready to build PPA builds. Two
>> # already exist in sampledata so we'll use those first.
>> self.builder1 = getUtility(IBuilderSet)['bob']
>> - self.builder2 = getUtility(IBuilderSet)['frog']
>> + self.frog_builder = removeSecurityProxy(
>> + getUtility(IBuilderSet)['frog'])
>
> Why doesn't frog_builder have a security proxy? If it's just to call
> private methods, it's better to remove the proxy when you call the
> method. If you start passing frog_builder to methods in your tests, you
> might get things passing in the tests, while failing in real code.
> Better to be safe and only unwrap the objects when you know it's safe.
Good point! Revised the code accordingly.

>> self.builder3 = self.factory.makeBuilder(name='builder3')
>> - ...

Read more...

=== modified file 'lib/lp/buildmaster/manager.py'
--- lib/lp/buildmaster/manager.py 2010-01-10 23:59:31 +0000
+++ lib/lp/buildmaster/manager.py 2010-01-11 03:39:35 +0000
@@ -344,7 +344,7 @@
344 candidate = builder.findAndStartJob(buildd_slave=slave)344 candidate = builder.findAndStartJob(buildd_slave=slave)
345 if candidate is not None:345 if candidate is not None:
346 recording_slaves.append(slave)346 recording_slaves.append(slave)
347 transaction.commit()347 transaction.commit()
348348
349 return recording_slaves349 return recording_slaves
350350
351351
=== modified file 'lib/lp/soyuz/tests/test_builder.py'
--- lib/lp/soyuz/tests/test_builder.py 2010-01-11 03:03:19 +0000
+++ lib/lp/soyuz/tests/test_builder.py 2010-01-11 03:43:47 +0000
@@ -35,11 +35,9 @@
35 # Create some i386 builders ready to build PPA builds. Two35 # Create some i386 builders ready to build PPA builds. Two
36 # already exist in sampledata so we'll use those first.36 # already exist in sampledata so we'll use those first.
37 self.builder1 = getUtility(IBuilderSet)['bob']37 self.builder1 = getUtility(IBuilderSet)['bob']
38 self.frog_builder = removeSecurityProxy(38 self.frog_builder = getUtility(IBuilderSet)['frog']
39 getUtility(IBuilderSet)['frog'])
40 self.builder3 = self.factory.makeBuilder(name='builder3')39 self.builder3 = self.factory.makeBuilder(name='builder3')
41 self.builder4 = removeSecurityProxy(40 self.builder4 = self.factory.makeBuilder(name='builder4')
42 self.factory.makeBuilder(name='builder4'))
43 self.builder5 = self.factory.makeBuilder(name='builder5')41 self.builder5 = self.factory.makeBuilder(name='builder5')
44 self.builders = [42 self.builders = [
45 self.builder1,43 self.builder1,
@@ -65,8 +63,7 @@
65 self.publisher.prepareBreezyAutotest()63 self.publisher.prepareBreezyAutotest()
6664
67 self.bob_builder = getUtility(IBuilderSet)['bob']65 self.bob_builder = getUtility(IBuilderSet)['bob']
68 self.frog_builder = removeSecurityProxy(66 self.frog_builder = getUtility(IBuilderSet)['frog']
69 getUtility(IBuilderSet)['frog'])
7067
71 # Disable bob so only frog is available.68 # Disable bob so only frog is available.
72 self.bob_builder.manual = True69 self.bob_builder.manual = True
@@ -85,7 +82,8 @@
85 # there's only one builder available.82 # there's only one builder available.
8683
87 # Asking frog to find a candidate should give us the joesppa build.84 # Asking frog to find a candidate should give us the joesppa build.
88 next_job = self.frog_builder._findBuildCandidate()85 next_job = removeSecurityProxy(
86 self.frog_builder)._findBuildCandidate()
89 build = getUtility(IBuildSet).getByQueueEntry(next_job)87 build = getUtility(IBuildSet).getByQueueEntry(next_job)
90 self.assertEqual('joesppa', build.archive.name)88 self.assertEqual('joesppa', build.archive.name)
9189
@@ -93,7 +91,8 @@
93 # returned.91 # returned.
94 self.bob_builder.builderok = False92 self.bob_builder.builderok = False
95 self.bob_builder.manual = False93 self.bob_builder.manual = False
96 next_job = self.frog_builder._findBuildCandidate()94 next_job = removeSecurityProxy(
95 self.frog_builder)._findBuildCandidate()
97 build = getUtility(IBuildSet).getByQueueEntry(next_job)96 build = getUtility(IBuildSet).getByQueueEntry(next_job)
98 self.assertEqual('joesppa', build.archive.name)97 self.assertEqual('joesppa', build.archive.name)
9998
@@ -166,7 +165,7 @@
166 def test_findBuildCandidate_first_build_started(self):165 def test_findBuildCandidate_first_build_started(self):
167 # A PPA cannot start a build if it would use 80% or more of the166 # A PPA cannot start a build if it would use 80% or more of the
168 # builders.167 # builders.
169 next_job = self.builder4._findBuildCandidate()168 next_job = removeSecurityProxy(self.builder4)._findBuildCandidate()
170 build = getUtility(IBuildSet).getByQueueEntry(next_job)169 build = getUtility(IBuildSet).getByQueueEntry(next_job)
171 self.failIfEqual('joesppa', build.archive.name)170 self.failIfEqual('joesppa', build.archive.name)
172171
@@ -174,7 +173,7 @@
174 # When joe's first ppa build finishes, his fourth i386 build173 # When joe's first ppa build finishes, his fourth i386 build
175 # will be the next build candidate.174 # will be the next build candidate.
176 self.joe_builds[0].buildstate = BuildStatus.FAILEDTOBUILD175 self.joe_builds[0].buildstate = BuildStatus.FAILEDTOBUILD
177 next_job = self.builder4._findBuildCandidate()176 next_job = removeSecurityProxy(self.builder4)._findBuildCandidate()
178 build = getUtility(IBuildSet).getByQueueEntry(next_job)177 build = getUtility(IBuildSet).getByQueueEntry(next_job)
179 self.failUnlessEqual('joesppa', build.archive.name)178 self.failUnlessEqual('joesppa', build.archive.name)
180179
@@ -183,7 +182,7 @@
183 # for the one architecture.182 # for the one architecture.
184 self.ppa_joe.private = True183 self.ppa_joe.private = True
185 self.ppa_joe.buildd_secret = 'sekrit'184 self.ppa_joe.buildd_secret = 'sekrit'
186 next_job = self.builder4._findBuildCandidate()185 next_job = removeSecurityProxy(self.builder4)._findBuildCandidate()
187 build = getUtility(IBuildSet).getByQueueEntry(next_job)186 build = getUtility(IBuildSet).getByQueueEntry(next_job)
188 self.failUnlessEqual('joesppa', build.archive.name)187 self.failUnlessEqual('joesppa', build.archive.name)
189188
@@ -209,7 +208,8 @@
209 # Normal archives are not restricted to serial builds per208 # Normal archives are not restricted to serial builds per
210 # arch.209 # arch.
211210
212 next_job = self.frog_builder._findBuildCandidate()211 next_job = removeSecurityProxy(
212 self.frog_builder)._findBuildCandidate()
213 build = getUtility(IBuildSet).getByQueueEntry(next_job)213 build = getUtility(IBuildSet).getByQueueEntry(next_job)
214 self.failUnlessEqual('primary', build.archive.name)214 self.failUnlessEqual('primary', build.archive.name)
215 self.failUnlessEqual('gedit', build.sourcepackagerelease.name)215 self.failUnlessEqual('gedit', build.sourcepackagerelease.name)
@@ -218,7 +218,8 @@
218 # second non-ppa build for the same archive as the next candidate.218 # second non-ppa build for the same archive as the next candidate.
219 build.buildstate = BuildStatus.BUILDING219 build.buildstate = BuildStatus.BUILDING
220 build.builder = self.frog_builder220 build.builder = self.frog_builder
221 next_job = self.frog_builder._findBuildCandidate()221 next_job = removeSecurityProxy(
222 self.frog_builder)._findBuildCandidate()
222 build = getUtility(IBuildSet).getByQueueEntry(next_job)223 build = getUtility(IBuildSet).getByQueueEntry(next_job)
223 self.failUnlessEqual('primary', build.archive.name)224 self.failUnlessEqual('primary', build.archive.name)
224 self.failUnlessEqual('firefox', build.sourcepackagerelease.name)225 self.failUnlessEqual('firefox', build.sourcepackagerelease.name)
Revision history for this message
Björn Tillenius (bjornt) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/buildmaster/manager.py'
--- lib/lp/buildmaster/manager.py 2009-07-26 14:19:49 +0000
+++ lib/lp/buildmaster/manager.py 2010-01-11 21:56:15 +0000
@@ -340,19 +340,11 @@
340 transaction.commit()340 transaction.commit()
341 continue341 continue
342342
343 candidate = builder.findBuildCandidate()
344 if candidate is None:
345 self.logger.debug(
346 "No build candidates available for builder.")
347 continue
348
349 slave = RecordingSlave(builder.name, builder.url, builder.vm_host)343 slave = RecordingSlave(builder.name, builder.url, builder.vm_host)
350 builder.setSlaveForTesting(slave)344 candidate = builder.findAndStartJob(buildd_slave=slave)
351
352 builder.dispatchBuildCandidate(candidate)
353 if builder.currentjob is not None:345 if builder.currentjob is not None:
354 recording_slaves.append(slave)346 recording_slaves.append(slave)
355 transaction.commit()347 transaction.commit()
356348
357 return recording_slaves349 return recording_slaves
358350
359351
=== modified file 'lib/lp/soyuz/doc/buildd-dispatching.txt'
--- lib/lp/soyuz/doc/buildd-dispatching.txt 2009-11-13 19:34:17 +0000
+++ lib/lp/soyuz/doc/buildd-dispatching.txt 2010-01-11 21:56:15 +0000
@@ -128,7 +128,8 @@
128Now let's check the build candidates which will be considered for the128Now let's check the build candidates which will be considered for the
129builder 'bob':129builder 'bob':
130130
131 >>> job = bob_builder.findBuildCandidate()131 >>> from zope.security.proxy import removeSecurityProxy
132 >>> job = removeSecurityProxy(bob_builder)._findBuildCandidate()
132133
133The single BuildQueue found is a non-virtual pending build:134The single BuildQueue found is a non-virtual pending build:
134135
@@ -157,14 +158,16 @@
157 ... 'foo.dsc', len(content), StringIO(content), 'application/dsc')158 ... 'foo.dsc', len(content), StringIO(content), 'application/dsc')
158159
159 >>> sprf = build.sourcepackagerelease.files[0]160 >>> sprf = build.sourcepackagerelease.files[0]
160 >>> from zope.security.proxy import removeSecurityProxy
161 >>> naked_sprf = removeSecurityProxy(sprf)161 >>> naked_sprf = removeSecurityProxy(sprf)
162 >>> naked_sprf.libraryfile = getUtility(ILibraryFileAliasSet)[alias_id]162 >>> naked_sprf.libraryfile = getUtility(ILibraryFileAliasSet)[alias_id]
163 >>> flush_database_updates()163 >>> flush_database_updates()
164164
165Check the dispatching method itself:165Check the dispatching method itself:
166166
167 >>> bob_builder.dispatchBuildCandidate(job)167 >>> dispatched_job = bob_builder.findAndStartJob()
168 >>> job == dispatched_job
169 True
170
168 >>> flush_database_updates()171 >>> flush_database_updates()
169172
170Verify if the job (BuildQueue) was updated appropriately:173Verify if the job (BuildQueue) was updated appropriately:
@@ -224,7 +227,7 @@
224 >>> bob_builder.vm_host = 'localhost.ppa'227 >>> bob_builder.vm_host = 'localhost.ppa'
225 >>> syncUpdate(bob_builder)228 >>> syncUpdate(bob_builder)
226229
227 >>> job = bob_builder.findBuildCandidate()230 >>> job = removeSecurityProxy(bob_builder)._findBuildCandidate()
228 >>> print job231 >>> print job
229 None232 None
230233
@@ -245,11 +248,11 @@
245 >>> bob_builder.virtualized = True248 >>> bob_builder.virtualized = True
246 >>> syncUpdate(bob_builder)249 >>> syncUpdate(bob_builder)
247250
248 >>> job = bob_builder.findBuildCandidate()251 >>> job = removeSecurityProxy(bob_builder)._findBuildCandidate()
249 >>> ppa_job.id == job.id252 >>> ppa_job.id == job.id
250 True253 True
251254
252For further details regarding IBuilder.findBuildCandidate() please see255For further details regarding IBuilder._findBuildCandidate() please see
253lib/lp/soyuz/tests/test_builder.py.256lib/lp/soyuz/tests/test_builder.py.
254257
255Start buildd-slave to be able to dispatch jobs.258Start buildd-slave to be able to dispatch jobs.
@@ -262,7 +265,7 @@
262265
263 >>> bob_builder.virtualized = False266 >>> bob_builder.virtualized = False
264 >>> flush_database_updates()267 >>> flush_database_updates()
265 >>> bob_builder.dispatchBuildCandidate(ppa_job)268 >>> removeSecurityProxy(bob_builder)._dispatchBuildCandidate(ppa_job)
266 Traceback (most recent call last):269 Traceback (most recent call last):
267 ...270 ...
268 AssertionError: Attempt to build non-virtual item on a virtual builder.271 AssertionError: Attempt to build non-virtual item on a virtual builder.
@@ -273,7 +276,10 @@
273 >>> bob_builder.virtualized = True276 >>> bob_builder.virtualized = True
274 >>> flush_database_updates()277 >>> flush_database_updates()
275278
276 >>> bob_builder.dispatchBuildCandidate(ppa_job)279 >>> dispatched_job = bob_builder.findAndStartJob()
280 >>> ppa_job == dispatched_job
281 True
282
277 >>> flush_database_updates()283 >>> flush_database_updates()
278284
279PPA job is building.285PPA job is building.
@@ -328,7 +334,7 @@
328implementation.334implementation.
329335
330 >>> BuilddSlaveTestSetup().setUp()336 >>> BuilddSlaveTestSetup().setUp()
331 >>> bob_builder.dispatchBuildCandidate(sec_job)337 >>> removeSecurityProxy(bob_builder)._dispatchBuildCandidate(sec_job)
332 Traceback (most recent call last):338 Traceback (most recent call last):
333 ...339 ...
334 AssertionError: Soyuz is not yet capable of building SECURITY uploads.340 AssertionError: Soyuz is not yet capable of building SECURITY uploads.
@@ -336,7 +342,7 @@
336342
337To solve this problem temporarily until we start building security343To solve this problem temporarily until we start building security
338uploads, we will mark builds targeted to the SECURITY pocket as344uploads, we will mark builds targeted to the SECURITY pocket as
339FAILEDTOBUILD during the findBuildCandidate look-up.345FAILEDTOBUILD during the _findBuildCandidate look-up.
340346
341We will also create another build candidate in breezy-autotest/i386 to347We will also create another build candidate in breezy-autotest/i386 to
342check if legitimate pending candidates will remain valid.348check if legitimate pending candidates will remain valid.
@@ -360,7 +366,7 @@
360366
361 >>> new_pub = old_pub.copyTo(367 >>> new_pub = old_pub.copyTo(
362 ... pending_build.distroseries, old_pub.pocket, pending_build.archive)368 ... pending_build.distroseries, old_pub.pocket, pending_build.archive)
363 >>> candidate = bob_builder.findBuildCandidate()369 >>> candidate = removeSecurityProxy(bob_builder)._findBuildCandidate()
364 >>> flush_database_updates()370 >>> flush_database_updates()
365 >>> candidate.id == pending_job.id371 >>> candidate.id == pending_job.id
366 True372 True
367373
=== modified file 'lib/lp/soyuz/doc/buildd-slavescanner.txt'
--- lib/lp/soyuz/doc/buildd-slavescanner.txt 2010-01-05 16:30:29 +0000
+++ lib/lp/soyuz/doc/buildd-slavescanner.txt 2010-01-11 21:56:15 +0000
@@ -754,11 +754,8 @@
754754
755== Build Dispatching ==755== Build Dispatching ==
756756
757Build dispatching can be entirely done via IBuilder content class via757Build dispatching can be entirely done via IBuilder content class
758the following API:758using the findAndStartJob method.
759
760 * findCandidate: returns a suitable BuildQueue candidate
761 * dispatchBuildCandidate: dispatch a build for a given candidate.
762759
763We will use SoyuzTestPublisher to simulate the required context in the760We will use SoyuzTestPublisher to simulate the required context in the
764next tests. Let's initialise it.761next tests. Let's initialise it.
@@ -805,14 +802,14 @@
805superseded source package releases in the queue and marks the802superseded source package releases in the queue and marks the
806corresponding build record as SUPERSEDED.803corresponding build record as SUPERSEDED.
807804
808 >>> old_candidate = a_builder.findBuildCandidate()805 >>> old_candidate = removeSecurityProxy(a_builder)._findBuildCandidate()
809 >>> build = getUtility(IBuildSet).getByQueueEntry(old_candidate)806 >>> build = getUtility(IBuildSet).getByQueueEntry(old_candidate)
810 >>> print build.buildstate.name807 >>> print build.buildstate.name
811 NEEDSBUILD808 NEEDSBUILD
812809
813The 'candidate' is constant until we dispatch it.810The 'candidate' is constant until we dispatch it.
814811
815 >>> new_candidate = a_builder.findBuildCandidate()812 >>> new_candidate = removeSecurityProxy(a_builder)._findBuildCandidate()
816 >>> new_candidate.id == old_candidate.id813 >>> new_candidate.id == old_candidate.id
817 True814 True
818815
@@ -820,7 +817,7 @@
820whether the candidate will still be found.817whether the candidate will still be found.
821818
822 >>> build.archive.enabled = False819 >>> build.archive.enabled = False
823 >>> new_candidate = a_builder.findBuildCandidate()820 >>> new_candidate = removeSecurityProxy(a_builder)._findBuildCandidate()
824 >>> new_candidate is None821 >>> new_candidate is None
825 True822 True
826823
@@ -829,7 +826,7 @@
829candidate will be found again.826candidate will be found again.
830827
831 >>> build.archive.enabled = True828 >>> build.archive.enabled = True
832 >>> new_candidate = a_builder.findBuildCandidate()829 >>> new_candidate = removeSecurityProxy(a_builder)._findBuildCandidate()
833 >>> new_candidate.id == old_candidate.id830 >>> new_candidate.id == old_candidate.id
834 True831 True
835832
@@ -852,7 +849,7 @@
852849
853Now, there we have another build candidate.850Now, there we have another build candidate.
854851
855 >>> new_candidate = a_builder.findBuildCandidate()852 >>> new_candidate = removeSecurityProxy(a_builder)._findBuildCandidate()
856 >>> new_candidate.id != old_candidate.id853 >>> new_candidate.id != old_candidate.id
857 True854 True
858855
@@ -882,9 +879,10 @@
882879
883Let's try to find a new build candidate:880Let's try to find a new build candidate:
884881
885 >>> another_candidate = a_builder.findBuildCandidate()882 >>> another_candidate = removeSecurityProxy(
883 ... a_builder)._findBuildCandidate()
886884
887Since there are no more candidates at all, findBuildCandidate()885Since there are no more candidates at all, _findBuildCandidate()
888returned None:886returned None:
889887
890 >>> print another_candidate888 >>> print another_candidate
@@ -897,7 +895,8 @@
897 >>> commit()895 >>> commit()
898 >>> LaunchpadZopelessLayer.switchDbUser(config.builddmaster.dbuser)896 >>> LaunchpadZopelessLayer.switchDbUser(config.builddmaster.dbuser)
899897
900 >>> another_candidate = a_builder.findBuildCandidate()898 >>> another_candidate = removeSecurityProxy(
899 ... a_builder)._findBuildCandidate()
901 >>> another_candidate.id == new_candidate.id900 >>> another_candidate.id == new_candidate.id
902 True901 True
903902
@@ -921,7 +920,8 @@
921 >>> print build.buildstate.name920 >>> print build.buildstate.name
922 NEEDSBUILD921 NEEDSBUILD
923922
924 >>> another_candidate = a_builder.findBuildCandidate()923 >>> another_candidate = removeSecurityProxy(
924 ... a_builder)._findBuildCandidate()
925 >>> print another_candidate925 >>> print another_candidate
926 None926 None
927927
@@ -954,7 +954,7 @@
954 >>> a_builder.is_available954 >>> a_builder.is_available
955 True955 True
956 >>> candidate = a_build.createBuildQueueEntry()956 >>> candidate = a_build.createBuildQueueEntry()
957 >>> a_builder.dispatchBuildCandidate(candidate)957 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(candidate)
958 ensurepresent called, url=...958 ensurepresent called, url=...
959 ensurepresent called,959 ensurepresent called,
960 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz960 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz
@@ -982,7 +982,7 @@
982 >>> a_builder.is_available982 >>> a_builder.is_available
983 True983 True
984 >>> candidate = a_build.createBuildQueueEntry()984 >>> candidate = a_build.createBuildQueueEntry()
985 >>> a_builder.dispatchBuildCandidate(candidate)985 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(candidate)
986 ensurepresent called, url=...986 ensurepresent called, url=...
987 ensurepresent called,987 ensurepresent called,
988 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz988 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz
@@ -1034,7 +1034,7 @@
1034So, at moment, partner archive is still not relevant for builds in1034So, at moment, partner archive is still not relevant for builds in
1035hoary/i386. It's not passed to the builder.1035hoary/i386. It's not passed to the builder.
10361036
1037 >>> a_builder.dispatchBuildCandidate(candidate)1037 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(candidate)
1038 ensurepresent called, url=...1038 ensurepresent called, url=...
1039 ensurepresent called,1039 ensurepresent called,
1040 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz1040 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz
@@ -1084,7 +1084,8 @@
1084binary in hoary/i386, the partner archive gets included in the builder1084binary in hoary/i386, the partner archive gets included in the builder
1085sources_list.1085sources_list.
10861086
1087 >>> a_builder.dispatchBuildCandidate(partner_candidate)1087 >>> removeSecurityProxy(
1088 ... a_builder)._dispatchBuildCandidate(partner_candidate)
1088 ensurepresent called, url=...1089 ensurepresent called, url=...
1089 ensurepresent called, url=http://localhost:58000/.../foo_666.dsc1090 ensurepresent called, url=http://localhost:58000/.../foo_666.dsc
1090 OkSlave BUILDING1091 OkSlave BUILDING
@@ -1126,7 +1127,7 @@
1126 >>> create_binary_publication_for(1127 >>> create_binary_publication_for(
1127 ... cprov_archive, hoary, PackagePublishingStatus.PUBLISHED)1128 ... cprov_archive, hoary, PackagePublishingStatus.PUBLISHED)
11281129
1129 >>> a_builder.dispatchBuildCandidate(candidate)1130 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(candidate)
1130 ensurepresent called, url=...1131 ensurepresent called, url=...
1131 ensurepresent called,1132 ensurepresent called,
1132 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz1133 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz
@@ -1183,7 +1184,7 @@
11831184
1184This is so that the mangling tools will run over the built packages.1185This is so that the mangling tools will run over the built packages.
11851186
1186 >>> a_builder.dispatchBuildCandidate(candidate)1187 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(candidate)
1187 ensurepresent called, url=...1188 ensurepresent called, url=...
1188 ensurepresent called,1189 ensurepresent called,
1189 url=http://private-ppa.launchpad.dev/cprov/ppa/ubuntu/pool/main/m/mozilla-firefox/firefox_0.9.2.orig.tar.gz1190 url=http://private-ppa.launchpad.dev/cprov/ppa/ubuntu/pool/main/m/mozilla-firefox/firefox_0.9.2.orig.tar.gz
@@ -1223,7 +1224,7 @@
1223 >>> LaunchpadZopelessLayer.switchDbUser(config.builddmaster.dbuser)1224 >>> LaunchpadZopelessLayer.switchDbUser(config.builddmaster.dbuser)
1224 >>> login(ANONYMOUS)1225 >>> login(ANONYMOUS)
12251226
1226 >>> a_builder.dispatchBuildCandidate(candidate)1227 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(candidate)
1227 ensurepresent called, ...1228 ensurepresent called, ...
1228 ...1229 ...
1229 Ogre-component: main1230 Ogre-component: main
@@ -1302,7 +1303,7 @@
1302 >>> setupBuildQueue(candidate, a_builder)1303 >>> setupBuildQueue(candidate, a_builder)
1303 >>> last_stub_mail_count = len(stub.test_emails)1304 >>> last_stub_mail_count = len(stub.test_emails)
13041305
1305 >>> a_builder.dispatchBuildCandidate(candidate)1306 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(candidate)
1306 ensurepresent called, url=...1307 ensurepresent called, url=...
1307 ensurepresent called,1308 ensurepresent called,
1308 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz1309 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz
@@ -1331,7 +1332,7 @@
1331 >>> create_binary_publication_for(1332 >>> create_binary_publication_for(
1332 ... mark_archive, hoary, PackagePublishingStatus.PUBLISHED)1333 ... mark_archive, hoary, PackagePublishingStatus.PUBLISHED)
13331334
1334 >>> a_builder.dispatchBuildCandidate(candidate)1335 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(candidate)
1335 ensurepresent called, url=...1336 ensurepresent called, url=...
1336 ensurepresent called,1337 ensurepresent called,
1337 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz1338 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz
@@ -1376,7 +1377,7 @@
13761377
1377 >>> hoary_i386.distroseries.status.name1378 >>> hoary_i386.distroseries.status.name
1378 'DEVELOPMENT'1379 'DEVELOPMENT'
1379 >>> a_builder.dispatchBuildCandidate(updates_bqItem)1380 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(updates_bqItem)
1380 Traceback (most recent call last):1381 Traceback (most recent call last):
1381 ...1382 ...
1382 AssertionError: i386 build of evolution 1.0 in ubuntu hoary UPDATES (...) can not be built for pocket UPDATES: invalid pocket due to the series status of hoary.1383 AssertionError: i386 build of evolution 1.0 in ubuntu hoary UPDATES (...) can not be built for pocket UPDATES: invalid pocket due to the series status of hoary.
@@ -1401,7 +1402,7 @@
1401 >>> removeSecurityProxy(build).pocket = (1402 >>> removeSecurityProxy(build).pocket = (
1402 ... PackagePublishingPocket.UPDATES)1403 ... PackagePublishingPocket.UPDATES)
1403 >>> last_stub_mail_count = len(stub.test_emails)1404 >>> last_stub_mail_count = len(stub.test_emails)
1404 >>> a_builder.dispatchBuildCandidate(bqItem3)1405 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(bqItem3)
1405 ensurepresent called, url=...1406 ensurepresent called, url=...
1406 ensurepresent called,1407 ensurepresent called,
1407 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz1408 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz
@@ -1423,7 +1424,7 @@
1423 >>> removeSecurityProxy(build).pocket = (1424 >>> removeSecurityProxy(build).pocket = (
1424 ... PackagePublishingPocket.PROPOSED)1425 ... PackagePublishingPocket.PROPOSED)
1425 >>> last_stub_mail_count = len(stub.test_emails)1426 >>> last_stub_mail_count = len(stub.test_emails)
1426 >>> a_builder.dispatchBuildCandidate(bqItem3)1427 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(bqItem3)
1427 ensurepresent called, url=...1428 ensurepresent called, url=...
1428 ensurepresent called,1429 ensurepresent called,
1429 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz1430 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz
@@ -1446,7 +1447,7 @@
1446 >>> removeSecurityProxy(build).pocket = (1447 >>> removeSecurityProxy(build).pocket = (
1447 ... PackagePublishingPocket.BACKPORTS)1448 ... PackagePublishingPocket.BACKPORTS)
1448 >>> last_stub_mail_count = len(stub.test_emails)1449 >>> last_stub_mail_count = len(stub.test_emails)
1449 >>> a_builder.dispatchBuildCandidate(bqItem3)1450 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(bqItem3)
1450 ensurepresent called, url=...1451 ensurepresent called, url=...
1451 ensurepresent called,1452 ensurepresent called,
1452 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz1453 url=http://localhost:58000/3/firefox_0.9.2.orig.tar.gz
@@ -1477,13 +1478,13 @@
1477because Embargoed-Archives and Restricted-UI implementations are not1478because Embargoed-Archives and Restricted-UI implementations are not
1478yet ready.1479yet ready.
14791480
1480 >>> a_builder.dispatchBuildCandidate(bqItem3)1481 >>> removeSecurityProxy(a_builder)._dispatchBuildCandidate(bqItem3)
1481 Traceback (most recent call last):1482 Traceback (most recent call last):
1482 ...1483 ...
1483 AssertionError: Soyuz is not yet capable of building SECURITY uploads.1484 AssertionError: Soyuz is not yet capable of building SECURITY uploads.
14841485
1485Builds for security pocket are marked as FAILEDTOBUILD inside1486Builds for security pocket are marked as FAILEDTOBUILD inside the
1486findBuildCandidate method, see doc/buildd-dispatching.txt1487_findBuildCandidate() method, see doc/buildd-dispatching.txt
14871488
14881489
1489== Builder Status Handler ==1490== Builder Status Handler ==
14901491
=== modified file 'lib/lp/soyuz/interfaces/builder.py'
--- lib/lp/soyuz/interfaces/builder.py 2009-12-03 14:38:48 +0000
+++ lib/lp/soyuz/interfaces/builder.py 2010-01-11 21:56:15 +0000
@@ -242,24 +242,6 @@
242 :return: A librarian file alias.242 :return: A librarian file alias.
243 """243 """
244244
245 def findBuildCandidate():
246 """Return the candidate for building.
247
248 The pending BuildQueue item with the highest score for this builder
249 ProcessorFamily or None if no candidate is available.
250
251 For public PPA builds, subsequent builds for a given ppa and
252 architecture will not be returned until the current build for
253 the ppa and architecture is finished.
254 """
255
256 def dispatchBuildCandidate(candidate):
257 """Dispatch the given job to this builder.
258
259 This method can only be executed in the builddmaster machine, since
260 it will actually issues the XMLRPC call to the buildd-slave.
261 """
262
263 def handleTimeout(logger, error_message):245 def handleTimeout(logger, error_message):
264 """Handle buildd slave communication timeout situations.246 """Handle buildd slave communication timeout situations.
265247
@@ -274,6 +256,14 @@
274 :param error_message: The error message to be used for logging.256 :param error_message: The error message to be used for logging.
275 """257 """
276258
259 def findAndStartJob(buildd_slave=None):
260 """Find a job to run and send it to the buildd slave.
261
262 :param buildd_slave: An optional buildd slave that this builder should
263 talk to.
264 :return: the `IBuildQueue` instance found or None if no job was found.
265 """
266
277267
278class IBuilderSet(Interface):268class IBuilderSet(Interface):
279 """Collections of builders.269 """Collections of builders.
280270
=== modified file 'lib/lp/soyuz/model/builder.py'
--- lib/lp/soyuz/model/builder.py 2009-12-24 06:57:25 +0000
+++ lib/lp/soyuz/model/builder.py 2010-01-11 21:56:15 +0000
@@ -386,9 +386,9 @@
386 return True386 return True
387387
388 # XXX cprov 20071116: It should become part of the public388 # XXX cprov 20071116: It should become part of the public
389 # findBuildCandidate once we start to detect superseded builds389 # _findBuildCandidate once we start to detect superseded builds
390 # at build creation time.390 # at build creation time.
391 def _findBuildCandidate(self):391 def _findBinaryBuildCandidate(self):
392 """Return the highest priority build candidate for this builder.392 """Return the highest priority build candidate for this builder.
393393
394 Returns a pending IBuildQueue record queued for this builder394 Returns a pending IBuildQueue record queued for this builder
@@ -487,10 +487,21 @@
487 logger = logging.getLogger('slave-scanner')487 logger = logging.getLogger('slave-scanner')
488 return logger488 return logger
489489
490 def findBuildCandidate(self):490 def _findBuildCandidate(self):
491 """See `IBuilder`."""491 """Find a candidate job for dispatch to an idle buildd slave.
492
493 The pending BuildQueue item with the highest score for this builder
494 ProcessorFamily or None if no candidate is available.
495
496 For public PPA builds, subsequent builds for a given ppa and
497 architecture will not be returned until the current build for
498 the ppa and architecture is finished.
499
500 :return: A binary build candidate job.
501 """
502
492 logger = self._getSlaveScannerLogger()503 logger = self._getSlaveScannerLogger()
493 candidate = self._findBuildCandidate()504 candidate = self._findBinaryBuildCandidate()
494505
495 # Mark build records targeted to old source versions as SUPERSEDED506 # Mark build records targeted to old source versions as SUPERSEDED
496 # and build records target to SECURITY pocket as FAILEDTOBUILD.507 # and build records target to SECURITY pocket as FAILEDTOBUILD.
@@ -507,7 +518,7 @@
507 % (build.id, candidate.id))518 % (build.id, candidate.id))
508 build.buildstate = BuildStatus.FAILEDTOBUILD519 build.buildstate = BuildStatus.FAILEDTOBUILD
509 candidate.destroySelf()520 candidate.destroySelf()
510 candidate = self._findBuildCandidate()521 candidate = self._findBinaryBuildCandidate()
511 continue522 continue
512523
513 publication = build.current_source_publication524 publication = build.current_source_publication
@@ -520,7 +531,7 @@
520 % (build.id, candidate.id))531 % (build.id, candidate.id))
521 build.buildstate = BuildStatus.SUPERSEDED532 build.buildstate = BuildStatus.SUPERSEDED
522 candidate.destroySelf()533 candidate.destroySelf()
523 candidate = self._findBuildCandidate()534 candidate = self._findBinaryBuildCandidate()
524 continue535 continue
525536
526 return candidate537 return candidate
@@ -528,8 +539,14 @@
528 # No candidate was found.539 # No candidate was found.
529 return None540 return None
530541
531 def dispatchBuildCandidate(self, candidate):542 def _dispatchBuildCandidate(self, candidate):
532 """See `IBuilder`."""543 """Dispatch the pending job to the associated buildd slave.
544
545 This method can only be executed in the builddmaster machine, since
546 it will actually issues the XMLRPC call to the buildd-slave.
547
548 :param candidate: The job to dispatch.
549 """
533 logger = self._getSlaveScannerLogger()550 logger = self._getSlaveScannerLogger()
534 try:551 try:
535 self.startBuild(candidate, logger)552 self.startBuild(candidate, logger)
@@ -563,6 +580,21 @@
563 exc_info=True)580 exc_info=True)
564 self.failbuilder(error_message)581 self.failbuilder(error_message)
565582
583 def findAndStartJob(self, buildd_slave=None):
584 """See IBuilder."""
585 logger = self._getSlaveScannerLogger()
586 candidate = self._findBuildCandidate()
587
588 if candidate is None:
589 logger.debug("No build candidates available for builder.")
590 return None
591
592 if buildd_slave is not None:
593 self.setSlaveForTesting(buildd_slave)
594
595 self._dispatchBuildCandidate(candidate)
596 return candidate
597
566598
567class BuilderSet(object):599class BuilderSet(object):
568 """See IBuilderSet"""600 """See IBuilderSet"""
569601
=== modified file 'lib/lp/soyuz/scripts/buildd.py'
--- lib/lp/soyuz/scripts/buildd.py 2009-10-26 18:40:04 +0000
+++ lib/lp/soyuz/scripts/buildd.py 2010-01-11 21:56:15 +0000
@@ -201,12 +201,10 @@
201 if not builder.is_available:201 if not builder.is_available:
202 self.logger.warn('builder is not available. Ignored.')202 self.logger.warn('builder is not available. Ignored.')
203 continue203 continue
204 candidate = builder.findBuildCandidate()204
205 candidate = builder.findAndStartJob()
205 if candidate is None:206 if candidate is None:
206 self.logger.debug(
207 "No candidates available for builder.")
208 continue207 continue
209 builder.dispatchBuildCandidate(candidate)
210 self.txn.commit()208 self.txn.commit()
211209
212 self.logger.info("Slave Scan Process Finished.")210 self.logger.info("Slave Scan Process Finished.")
213211
=== modified file 'lib/lp/soyuz/tests/test_builder.py'
--- lib/lp/soyuz/tests/test_builder.py 2009-12-02 15:18:46 +0000
+++ lib/lp/soyuz/tests/test_builder.py 2010-01-11 21:56:15 +0000
@@ -6,10 +6,11 @@
6import unittest6import unittest
77
8from zope.component import getUtility8from zope.component import getUtility
9from zope.security.proxy import removeSecurityProxy
910
10from canonical.testing import LaunchpadZopelessLayer11from canonical.testing import LaunchpadZopelessLayer
11from lp.buildmaster.interfaces.buildfarmjobbehavior import (12from lp.buildmaster.interfaces.buildfarmjobbehavior import (
12 BuildBehaviorMismatch, IBuildFarmJobBehavior)13 IBuildFarmJobBehavior)
13from lp.buildmaster.model.buildfarmjobbehavior import IdleBuildBehavior14from lp.buildmaster.model.buildfarmjobbehavior import IdleBuildBehavior
14from lp.soyuz.interfaces.archive import ArchivePurpose15from lp.soyuz.interfaces.archive import ArchivePurpose
15from lp.soyuz.interfaces.build import BuildStatus, IBuildSet16from lp.soyuz.interfaces.build import BuildStatus, IBuildSet
@@ -34,13 +35,13 @@
34 # Create some i386 builders ready to build PPA builds. Two35 # Create some i386 builders ready to build PPA builds. Two
35 # already exist in sampledata so we'll use those first.36 # already exist in sampledata so we'll use those first.
36 self.builder1 = getUtility(IBuilderSet)['bob']37 self.builder1 = getUtility(IBuilderSet)['bob']
37 self.builder2 = getUtility(IBuilderSet)['frog']38 self.frog_builder = getUtility(IBuilderSet)['frog']
38 self.builder3 = self.factory.makeBuilder(name='builder3')39 self.builder3 = self.factory.makeBuilder(name='builder3')
39 self.builder4 = self.factory.makeBuilder(name='builder4')40 self.builder4 = self.factory.makeBuilder(name='builder4')
40 self.builder5 = self.factory.makeBuilder(name='builder5')41 self.builder5 = self.factory.makeBuilder(name='builder5')
41 self.builders = [42 self.builders = [
42 self.builder1,43 self.builder1,
43 self.builder2,44 self.frog_builder,
44 self.builder3,45 self.builder3,
45 self.builder4,46 self.builder4,
46 self.builder5,47 self.builder5,
@@ -81,7 +82,8 @@
81 # there's only one builder available.82 # there's only one builder available.
8283
83 # Asking frog to find a candidate should give us the joesppa build.84 # Asking frog to find a candidate should give us the joesppa build.
84 next_job = self.frog_builder.findBuildCandidate()85 next_job = removeSecurityProxy(
86 self.frog_builder)._findBuildCandidate()
85 build = getUtility(IBuildSet).getByQueueEntry(next_job)87 build = getUtility(IBuildSet).getByQueueEntry(next_job)
86 self.assertEqual('joesppa', build.archive.name)88 self.assertEqual('joesppa', build.archive.name)
8789
@@ -89,7 +91,8 @@
89 # returned.91 # returned.
90 self.bob_builder.builderok = False92 self.bob_builder.builderok = False
91 self.bob_builder.manual = False93 self.bob_builder.manual = False
92 next_job = self.frog_builder.findBuildCandidate()94 next_job = removeSecurityProxy(
95 self.frog_builder)._findBuildCandidate()
93 build = getUtility(IBuildSet).getByQueueEntry(next_job)96 build = getUtility(IBuildSet).getByQueueEntry(next_job)
94 self.assertEqual('joesppa', build.archive.name)97 self.assertEqual('joesppa', build.archive.name)
9598
@@ -162,7 +165,7 @@
162 def test_findBuildCandidate_first_build_started(self):165 def test_findBuildCandidate_first_build_started(self):
163 # A PPA cannot start a build if it would use 80% or more of the166 # A PPA cannot start a build if it would use 80% or more of the
164 # builders.167 # builders.
165 next_job = self.builder4.findBuildCandidate()168 next_job = removeSecurityProxy(self.builder4)._findBuildCandidate()
166 build = getUtility(IBuildSet).getByQueueEntry(next_job)169 build = getUtility(IBuildSet).getByQueueEntry(next_job)
167 self.failIfEqual('joesppa', build.archive.name)170 self.failIfEqual('joesppa', build.archive.name)
168171
@@ -170,7 +173,7 @@
170 # When joe's first ppa build finishes, his fourth i386 build173 # When joe's first ppa build finishes, his fourth i386 build
171 # will be the next build candidate.174 # will be the next build candidate.
172 self.joe_builds[0].buildstate = BuildStatus.FAILEDTOBUILD175 self.joe_builds[0].buildstate = BuildStatus.FAILEDTOBUILD
173 next_job = self.builder4.findBuildCandidate()176 next_job = removeSecurityProxy(self.builder4)._findBuildCandidate()
174 build = getUtility(IBuildSet).getByQueueEntry(next_job)177 build = getUtility(IBuildSet).getByQueueEntry(next_job)
175 self.failUnlessEqual('joesppa', build.archive.name)178 self.failUnlessEqual('joesppa', build.archive.name)
176179
@@ -179,7 +182,7 @@
179 # for the one architecture.182 # for the one architecture.
180 self.ppa_joe.private = True183 self.ppa_joe.private = True
181 self.ppa_joe.buildd_secret = 'sekrit'184 self.ppa_joe.buildd_secret = 'sekrit'
182 next_job = self.builder4.findBuildCandidate()185 next_job = removeSecurityProxy(self.builder4)._findBuildCandidate()
183 build = getUtility(IBuildSet).getByQueueEntry(next_job)186 build = getUtility(IBuildSet).getByQueueEntry(next_job)
184 self.failUnlessEqual('joesppa', build.archive.name)187 self.failUnlessEqual('joesppa', build.archive.name)
185188
@@ -205,7 +208,8 @@
205 # Normal archives are not restricted to serial builds per208 # Normal archives are not restricted to serial builds per
206 # arch.209 # arch.
207210
208 next_job = self.builder2.findBuildCandidate()211 next_job = removeSecurityProxy(
212 self.frog_builder)._findBuildCandidate()
209 build = getUtility(IBuildSet).getByQueueEntry(next_job)213 build = getUtility(IBuildSet).getByQueueEntry(next_job)
210 self.failUnlessEqual('primary', build.archive.name)214 self.failUnlessEqual('primary', build.archive.name)
211 self.failUnlessEqual('gedit', build.sourcepackagerelease.name)215 self.failUnlessEqual('gedit', build.sourcepackagerelease.name)
@@ -213,8 +217,9 @@
213 # Now even if we set the build building, we'll still get the217 # Now even if we set the build building, we'll still get the
214 # second non-ppa build for the same archive as the next candidate.218 # second non-ppa build for the same archive as the next candidate.
215 build.buildstate = BuildStatus.BUILDING219 build.buildstate = BuildStatus.BUILDING
216 build.builder = self.builder2220 build.builder = self.frog_builder
217 next_job = self.builder2.findBuildCandidate()221 next_job = removeSecurityProxy(
222 self.frog_builder)._findBuildCandidate()
218 build = getUtility(IBuildSet).getByQueueEntry(next_job)223 build = getUtility(IBuildSet).getByQueueEntry(next_job)
219 self.failUnlessEqual('primary', build.archive.name)224 self.failUnlessEqual('primary', build.archive.name)
220 self.failUnlessEqual('firefox', build.sourcepackagerelease.name)225 self.failUnlessEqual('firefox', build.sourcepackagerelease.name)