Merge lp:~jml/launchpad/buildd-deferred-fo-sho into lp:launchpad
- buildd-deferred-fo-sho
- Merge into devel
Proposed by
Jonathan Lange
Status: | Merged |
---|---|
Merged at revision: | 11801 |
Proposed branch: | lp:~jml/launchpad/buildd-deferred-fo-sho |
Merge into: | lp:launchpad |
Prerequisite: | lp:~jml/launchpad/buildd-slavescanner-bustage |
Diff against target: |
770 lines (+307/-160) 7 files modified
lib/lp/buildmaster/manager.py (+25/-19) lib/lp/buildmaster/model/builder.py (+38/-17) lib/lp/buildmaster/tests/test_builder.py (+138/-43) lib/lp/code/model/recipebuilder.py (+30/-27) lib/lp/soyuz/model/binarypackagebuildbehavior.py (+56/-40) lib/lp/soyuz/tests/soyuzbuilddhelpers.py (+8/-4) lib/lp/translations/model/translationtemplatesbuildbehavior.py (+12/-10) |
To merge this branch: | bzr merge lp:~jml/launchpad/buildd-deferred-fo-sho |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Launchpad code reviewers | Pending | ||
Review via email: mp+36188@code.launchpad.net |
Commit message
Description of the change
Use Deferreds.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/buildmaster/manager.py' | |||
2 | --- lib/lp/buildmaster/manager.py 2010-09-20 10:21:32 +0000 | |||
3 | +++ lib/lp/buildmaster/manager.py 2010-09-22 11:33:47 +0000 | |||
4 | @@ -283,15 +283,15 @@ | |||
5 | 283 | """Scan the builder and dispatch to it or deal with failures.""" | 283 | """Scan the builder and dispatch to it or deal with failures.""" |
6 | 284 | self.logger.debug("Scanning builder: %s" % self.builder_name) | 284 | self.logger.debug("Scanning builder: %s" % self.builder_name) |
7 | 285 | 285 | ||
10 | 286 | try: | 286 | d = self.scan() |
11 | 287 | slave = self.scan() | 287 | |
12 | 288 | def got_slave(slave): | ||
13 | 288 | if slave is None: | 289 | if slave is None: |
15 | 289 | self.scheduleNextScanCycle() | 290 | return self.scheduleNextScanCycle() |
16 | 290 | else: | 291 | else: |
21 | 291 | # XXX: Ought to return Deferred. | 292 | return self.resumeAndDispatch(slave) |
22 | 292 | self.resumeAndDispatch(slave) | 293 | |
23 | 293 | except: | 294 | def disaster(error): |
20 | 294 | error = Failure() | ||
24 | 295 | self.logger.info("Scanning failed with: %s\n%s" % | 295 | self.logger.info("Scanning failed with: %s\n%s" % |
25 | 296 | (error.getErrorMessage(), error.getTraceback())) | 296 | (error.getErrorMessage(), error.getTraceback())) |
26 | 297 | 297 | ||
27 | @@ -307,7 +307,11 @@ | |||
28 | 307 | assessFailureCounts(builder, error.getErrorMessage()) | 307 | assessFailureCounts(builder, error.getErrorMessage()) |
29 | 308 | transaction.commit() | 308 | transaction.commit() |
30 | 309 | 309 | ||
32 | 310 | self.scheduleNextScanCycle() | 310 | return self.scheduleNextScanCycle() |
33 | 311 | |||
34 | 312 | d.addCallback(got_slave) | ||
35 | 313 | d.addErrback(disaster) | ||
36 | 314 | return d | ||
37 | 311 | 315 | ||
38 | 312 | @write_transaction | 316 | @write_transaction |
39 | 313 | def scan(self): | 317 | def scan(self): |
40 | @@ -346,7 +350,7 @@ | |||
41 | 346 | if self.builder.manual: | 350 | if self.builder.manual: |
42 | 347 | self.logger.debug( | 351 | self.logger.debug( |
43 | 348 | '%s is in manual mode, not dispatching.' % self.builder.name) | 352 | '%s is in manual mode, not dispatching.' % self.builder.name) |
45 | 349 | return None | 353 | return defer.succeed(None) |
46 | 350 | 354 | ||
47 | 351 | # If the builder is marked unavailable, don't dispatch anything. | 355 | # If the builder is marked unavailable, don't dispatch anything. |
48 | 352 | # Additionaly, because builders can be removed from the pool at | 356 | # Additionaly, because builders can be removed from the pool at |
49 | @@ -362,7 +366,7 @@ | |||
50 | 362 | "job" % self.builder.name) | 366 | "job" % self.builder.name) |
51 | 363 | job.reset() | 367 | job.reset() |
52 | 364 | transaction.commit() | 368 | transaction.commit() |
54 | 365 | return None | 369 | return defer.succeed(None) |
55 | 366 | 370 | ||
56 | 367 | # See if there is a job we can dispatch to the builder slave. | 371 | # See if there is a job we can dispatch to the builder slave. |
57 | 368 | 372 | ||
58 | @@ -374,15 +378,17 @@ | |||
59 | 374 | self.builder.name, self.builder.url, self.builder.vm_host) | 378 | self.builder.name, self.builder.url, self.builder.vm_host) |
60 | 375 | # XXX: Passing buildd_slave=slave overwrites the 'slave' property of | 379 | # XXX: Passing buildd_slave=slave overwrites the 'slave' property of |
61 | 376 | # self.builder. Not sure why this is needed yet. | 380 | # self.builder. Not sure why this is needed yet. |
71 | 377 | self.builder.findAndStartJob(buildd_slave=slave) | 381 | d = self.builder.findAndStartJob(buildd_slave=slave) |
72 | 378 | if self.builder.currentjob is not None: | 382 | def job_started(candidate): |
73 | 379 | # After a successful dispatch we can reset the | 383 | if self.builder.currentjob is not None: |
74 | 380 | # failure_count. | 384 | # After a successful dispatch we can reset the |
75 | 381 | self.builder.resetFailureCount() | 385 | # failure_count. |
76 | 382 | transaction.commit() | 386 | self.builder.resetFailureCount() |
77 | 383 | return slave | 387 | transaction.commit() |
78 | 384 | 388 | return slave | |
79 | 385 | return None | 389 | else: |
80 | 390 | return None | ||
81 | 391 | return d.addCallback(job_started) | ||
82 | 386 | 392 | ||
83 | 387 | def resumeAndDispatch(self, slave): | 393 | def resumeAndDispatch(self, slave): |
84 | 388 | """Chain the resume and dispatching Deferreds.""" | 394 | """Chain the resume and dispatching Deferreds.""" |
85 | 389 | 395 | ||
86 | === modified file 'lib/lp/buildmaster/model/builder.py' | |||
87 | --- lib/lp/buildmaster/model/builder.py 2010-09-22 11:33:46 +0000 | |||
88 | +++ lib/lp/buildmaster/model/builder.py 2010-09-22 11:33:47 +0000 | |||
89 | @@ -34,6 +34,7 @@ | |||
90 | 34 | Count, | 34 | Count, |
91 | 35 | Sum, | 35 | Sum, |
92 | 36 | ) | 36 | ) |
93 | 37 | from twisted.internet import defer | ||
94 | 37 | from zope.component import getUtility | 38 | from zope.component import getUtility |
95 | 38 | from zope.interface import implements | 39 | from zope.interface import implements |
96 | 39 | 40 | ||
97 | @@ -166,8 +167,10 @@ | |||
98 | 166 | return self._server.status() | 167 | return self._server.status() |
99 | 167 | 168 | ||
100 | 168 | def ensurepresent(self, sha1sum, url, username, password): | 169 | def ensurepresent(self, sha1sum, url, username, password): |
101 | 170 | # XXX: Nothing external calls this. Make it private. | ||
102 | 169 | """Attempt to ensure the given file is present.""" | 171 | """Attempt to ensure the given file is present.""" |
104 | 170 | return self._server.ensurepresent(sha1sum, url, username, password) | 172 | return defer.succeed( |
105 | 173 | self._server.ensurepresent(sha1sum, url, username, password)) | ||
106 | 171 | 174 | ||
107 | 172 | def getFile(self, sha_sum): | 175 | def getFile(self, sha_sum): |
108 | 173 | """Construct a file-like object to return the named file.""" | 176 | """Construct a file-like object to return the named file.""" |
109 | @@ -206,13 +209,15 @@ | |||
110 | 206 | logger.debug("Asking builder on %s to ensure it has file %s " | 209 | logger.debug("Asking builder on %s to ensure it has file %s " |
111 | 207 | "(%s, %s)" % (self.urlbase, libraryfilealias.filename, | 210 | "(%s, %s)" % (self.urlbase, libraryfilealias.filename, |
112 | 208 | url, libraryfilealias.content.sha1)) | 211 | url, libraryfilealias.content.sha1)) |
114 | 209 | self.sendFileToSlave(libraryfilealias.content.sha1, url) | 212 | return self.sendFileToSlave(libraryfilealias.content.sha1, url) |
115 | 210 | 213 | ||
116 | 211 | def sendFileToSlave(self, sha1, url, username="", password=""): | 214 | def sendFileToSlave(self, sha1, url, username="", password=""): |
117 | 212 | """Helper to send the file at 'url' with 'sha1' to this builder.""" | 215 | """Helper to send the file at 'url' with 'sha1' to this builder.""" |
121 | 213 | present, info = self.ensurepresent(sha1, url, username, password) | 216 | d = self.ensurepresent(sha1, url, username, password) |
122 | 214 | if not present: | 217 | def check_present((present, info)): |
123 | 215 | raise CannotFetchFile(url, info) | 218 | if not present: |
124 | 219 | raise CannotFetchFile(url, info) | ||
125 | 220 | return d.addCallback(check_present) | ||
126 | 216 | 221 | ||
127 | 217 | def build(self, buildid, builder_type, chroot_sha1, filemap, args): | 222 | def build(self, buildid, builder_type, chroot_sha1, filemap, args): |
128 | 218 | """Build a thing on this build slave. | 223 | """Build a thing on this build slave. |
129 | @@ -469,14 +474,19 @@ | |||
130 | 469 | 474 | ||
131 | 470 | # Do it. | 475 | # Do it. |
132 | 471 | build_queue_item.markAsBuilding(self) | 476 | build_queue_item.markAsBuilding(self) |
138 | 472 | try: | 477 | |
139 | 473 | self.current_build_behavior.dispatchBuildToSlave( | 478 | d = self.current_build_behavior.dispatchBuildToSlave( |
140 | 474 | build_queue_item.id, logger) | 479 | build_queue_item.id, logger) |
141 | 475 | except BuildSlaveFailure, e: | 480 | |
142 | 476 | logger.debug("Disabling builder: %s" % self.url, exc_info=1) | 481 | def eb_slave_failure(failure): |
143 | 482 | failure.trap(BuildSlaveFailure) | ||
144 | 483 | e = failure.value | ||
145 | 477 | self.failBuilder( | 484 | self.failBuilder( |
146 | 478 | "Exception (%s) when setting up to new job" % (e,)) | 485 | "Exception (%s) when setting up to new job" % (e,)) |
148 | 479 | except CannotFetchFile, e: | 486 | |
149 | 487 | def eb_cannot_fetch_file(failure): | ||
150 | 488 | failure.trap(CannotFetchFile) | ||
151 | 489 | e = failure.value | ||
152 | 480 | message = """Slave '%s' (%s) was unable to fetch file. | 490 | message = """Slave '%s' (%s) was unable to fetch file. |
153 | 481 | ****** URL ******** | 491 | ****** URL ******** |
154 | 482 | %s | 492 | %s |
155 | @@ -485,11 +495,19 @@ | |||
156 | 485 | ******************* | 495 | ******************* |
157 | 486 | """ % (self.name, self.url, e.file_url, e.error_information) | 496 | """ % (self.name, self.url, e.file_url, e.error_information) |
158 | 487 | raise BuildDaemonError(message) | 497 | raise BuildDaemonError(message) |
160 | 488 | except socket.error, e: | 498 | |
161 | 499 | def eb_socket_error(failure): | ||
162 | 500 | failure.trap(socket.error) | ||
163 | 501 | e = failure.value | ||
164 | 489 | error_message = "Exception (%s) when setting up new job" % (e,) | 502 | error_message = "Exception (%s) when setting up new job" % (e,) |
165 | 490 | self.handleTimeout(logger, error_message) | 503 | self.handleTimeout(logger, error_message) |
166 | 491 | raise BuildSlaveFailure | 504 | raise BuildSlaveFailure |
167 | 492 | 505 | ||
168 | 506 | d.addErrback(eb_slave_failure) | ||
169 | 507 | d.addErrback(eb_cannot_fetch_file) | ||
170 | 508 | d.addErrback(eb_socket_error) | ||
171 | 509 | return d | ||
172 | 510 | |||
173 | 493 | def failBuilder(self, reason): | 511 | def failBuilder(self, reason): |
174 | 494 | """See IBuilder""" | 512 | """See IBuilder""" |
175 | 495 | # XXX cprov 2007-04-17: ideally we should be able to notify the | 513 | # XXX cprov 2007-04-17: ideally we should be able to notify the |
176 | @@ -682,10 +700,13 @@ | |||
177 | 682 | :param candidate: The job to dispatch. | 700 | :param candidate: The job to dispatch. |
178 | 683 | """ | 701 | """ |
179 | 684 | logger = self._getSlaveScannerLogger() | 702 | logger = self._getSlaveScannerLogger() |
183 | 685 | try: | 703 | d = self.startBuild(candidate, logger) |
184 | 686 | self.startBuild(candidate, logger) | 704 | def warn_on_error(failure): |
185 | 687 | except (BuildSlaveFailure, CannotBuild, BuildBehaviorMismatch), err: | 705 | failure.trap( |
186 | 706 | BuildSlaveFailure, CannotBuild, BuildBehaviorMismatch) | ||
187 | 707 | err = failure.value | ||
188 | 688 | logger.warn('Could not build: %s' % err) | 708 | logger.warn('Could not build: %s' % err) |
189 | 709 | return d.addErrback(warn_on_error) | ||
190 | 689 | 710 | ||
191 | 690 | def handleTimeout(self, logger, error_message): | 711 | def handleTimeout(self, logger, error_message): |
192 | 691 | """See IBuilder.""" | 712 | """See IBuilder.""" |
193 | @@ -726,8 +747,8 @@ | |||
194 | 726 | if buildd_slave is not None: | 747 | if buildd_slave is not None: |
195 | 727 | self.setSlaveForTesting(buildd_slave) | 748 | self.setSlaveForTesting(buildd_slave) |
196 | 728 | 749 | ||
199 | 729 | self._dispatchBuildCandidate(candidate) | 750 | d = self._dispatchBuildCandidate(candidate) |
200 | 730 | return candidate | 751 | return d.addCallback(lambda ignored: candidate) |
201 | 731 | 752 | ||
202 | 732 | def getBuildQueue(self): | 753 | def getBuildQueue(self): |
203 | 733 | """See `IBuilder`.""" | 754 | """See `IBuilder`.""" |
204 | 734 | 755 | ||
205 | === modified file 'lib/lp/buildmaster/tests/test_builder.py' | |||
206 | --- lib/lp/buildmaster/tests/test_builder.py 2010-09-21 16:23:35 +0000 | |||
207 | +++ lib/lp/buildmaster/tests/test_builder.py 2010-09-22 11:33:47 +0000 | |||
208 | @@ -8,8 +8,10 @@ | |||
209 | 8 | import socket | 8 | import socket |
210 | 9 | import xmlrpclib | 9 | import xmlrpclib |
211 | 10 | 10 | ||
214 | 11 | from testtools.content import Content | 11 | import fixtures |
215 | 12 | from testtools.content_type import UTF8_TEXT | 12 | |
216 | 13 | from twisted.trial.unittest import TestCase as TrialTestCase | ||
217 | 14 | from twisted.web.client import getPage | ||
218 | 13 | 15 | ||
219 | 14 | from zope.component import getUtility | 16 | from zope.component import getUtility |
220 | 15 | from zope.security.proxy import removeSecurityProxy | 17 | from zope.security.proxy import removeSecurityProxy |
221 | @@ -24,10 +26,16 @@ | |||
222 | 24 | ) | 26 | ) |
223 | 25 | from canonical.testing.layers import ( | 27 | from canonical.testing.layers import ( |
224 | 26 | DatabaseFunctionalLayer, | 28 | DatabaseFunctionalLayer, |
226 | 27 | LaunchpadZopelessLayer | 29 | LaunchpadZopelessLayer, |
227 | 30 | TwistedLaunchpadZopelessLayer, | ||
228 | 31 | TwistedLayer, | ||
229 | 28 | ) | 32 | ) |
230 | 29 | from lp.buildmaster.enums import BuildStatus | 33 | from lp.buildmaster.enums import BuildStatus |
232 | 30 | from lp.buildmaster.interfaces.builder import IBuilder, IBuilderSet | 34 | from lp.buildmaster.interfaces.builder import ( |
233 | 35 | CannotFetchFile, | ||
234 | 36 | IBuilder, | ||
235 | 37 | IBuilderSet, | ||
236 | 38 | ) | ||
237 | 31 | from lp.buildmaster.interfaces.buildfarmjobbehavior import ( | 39 | from lp.buildmaster.interfaces.buildfarmjobbehavior import ( |
238 | 32 | IBuildFarmJobBehavior, | 40 | IBuildFarmJobBehavior, |
239 | 33 | ) | 41 | ) |
240 | @@ -49,9 +57,12 @@ | |||
241 | 49 | ) | 57 | ) |
242 | 50 | from lp.soyuz.tests.test_publishing import SoyuzTestPublisher | 58 | from lp.soyuz.tests.test_publishing import SoyuzTestPublisher |
243 | 51 | from lp.testing import ( | 59 | from lp.testing import ( |
245 | 52 | TestCase, | 60 | ANONYMOUS, |
246 | 61 | login_as, | ||
247 | 62 | logout, | ||
248 | 53 | TestCaseWithFactory, | 63 | TestCaseWithFactory, |
249 | 54 | ) | 64 | ) |
250 | 65 | from lp.testing.factory import LaunchpadObjectFactory | ||
251 | 55 | from lp.testing.fakemethod import FakeMethod | 66 | from lp.testing.fakemethod import FakeMethod |
252 | 56 | 67 | ||
253 | 57 | 68 | ||
254 | @@ -467,19 +478,11 @@ | |||
255 | 467 | self.builder.current_build_behavior, BinaryPackageBuildBehavior) | 478 | self.builder.current_build_behavior, BinaryPackageBuildBehavior) |
256 | 468 | 479 | ||
257 | 469 | 480 | ||
268 | 470 | class TestSlave(TestCase): | 481 | class SlaveTestHelpers(fixtures.Fixture): |
259 | 471 | """ | ||
260 | 472 | Integration tests for BuilderSlave that verify how it works against a | ||
261 | 473 | real slave server. | ||
262 | 474 | """ | ||
263 | 475 | |||
264 | 476 | # XXX: JonathanLange 2010-09-20 bug=643521: There are also tests for | ||
265 | 477 | # BuilderSlave in buildd-slave.txt and in other places. The tests here | ||
266 | 478 | # ought to become the canonical tests for BuilderSlave vs running buildd | ||
267 | 479 | # XML-RPC server interaction. | ||
269 | 480 | 482 | ||
270 | 481 | # The URL for the XML-RPC service set up by `BuilddSlaveTestSetup`. | 483 | # The URL for the XML-RPC service set up by `BuilddSlaveTestSetup`. |
272 | 482 | TEST_URL = 'http://localhost:8221/rpc/' | 484 | BASE_URL = 'http://localhost:8221' |
273 | 485 | TEST_URL = '%s/rpc/' % (BASE_URL,) | ||
274 | 483 | 486 | ||
275 | 484 | def getServerSlave(self): | 487 | def getServerSlave(self): |
276 | 485 | """Set up a test build slave server. | 488 | """Set up a test build slave server. |
277 | @@ -488,11 +491,14 @@ | |||
278 | 488 | """ | 491 | """ |
279 | 489 | tachandler = BuilddSlaveTestSetup() | 492 | tachandler = BuilddSlaveTestSetup() |
280 | 490 | tachandler.setUp() | 493 | tachandler.setUp() |
286 | 491 | def addLogFile(exc_info): | 494 | # Basically impossible to do this w/ TrialTestCase. But it would be |
287 | 492 | self.addDetail( | 495 | # really nice to keep it. |
288 | 493 | 'xmlrpc-log-file', | 496 | # |
289 | 494 | Content(UTF8_TEXT, lambda: open(tachandler.logfile, 'r').read())) | 497 | # def addLogFile(exc_info): |
290 | 495 | self.addOnException(addLogFile) | 498 | # self.addDetail( |
291 | 499 | # 'xmlrpc-log-file', | ||
292 | 500 | # Content(UTF8_TEXT, lambda: open(tachandler.logfile, 'r').read())) | ||
293 | 501 | # self.addOnException(addLogFile) | ||
294 | 496 | self.addCleanup(tachandler.tearDown) | 502 | self.addCleanup(tachandler.tearDown) |
295 | 497 | return tachandler | 503 | return tachandler |
296 | 498 | 504 | ||
297 | @@ -527,7 +533,7 @@ | |||
298 | 527 | :return: The build id returned by the slave. | 533 | :return: The build id returned by the slave. |
299 | 528 | """ | 534 | """ |
300 | 529 | if build_id is None: | 535 | if build_id is None: |
302 | 530 | build_id = self.getUniqueString() | 536 | build_id = 'random-build-id' |
303 | 531 | tachandler = self.getServerSlave() | 537 | tachandler = self.getServerSlave() |
304 | 532 | chroot_file = 'fake-chroot' | 538 | chroot_file = 'fake-chroot' |
305 | 533 | dsc_file = 'thing' | 539 | dsc_file = 'thing' |
306 | @@ -537,10 +543,30 @@ | |||
307 | 537 | build_id, 'debian', chroot_file, {'.dsc': dsc_file}, | 543 | build_id, 'debian', chroot_file, {'.dsc': dsc_file}, |
308 | 538 | {'ogrecomponent': 'main'}) | 544 | {'ogrecomponent': 'main'}) |
309 | 539 | 545 | ||
310 | 546 | |||
311 | 547 | class TestSlave(TrialTestCase): | ||
312 | 548 | """ | ||
313 | 549 | Integration tests for BuilderSlave that verify how it works against a | ||
314 | 550 | real slave server. | ||
315 | 551 | """ | ||
316 | 552 | |||
317 | 553 | layer = TwistedLayer | ||
318 | 554 | |||
319 | 555 | def setUp(self): | ||
320 | 556 | super(TestSlave, self).setUp() | ||
321 | 557 | self.slave_helper = SlaveTestHelpers() | ||
322 | 558 | self.slave_helper.setUp() | ||
323 | 559 | self.addCleanup(self.slave_helper.cleanUp) | ||
324 | 560 | |||
325 | 561 | # XXX: JonathanLange 2010-09-20 bug=643521: There are also tests for | ||
326 | 562 | # BuilderSlave in buildd-slave.txt and in other places. The tests here | ||
327 | 563 | # ought to become the canonical tests for BuilderSlave vs running buildd | ||
328 | 564 | # XML-RPC server interaction. | ||
329 | 565 | |||
330 | 540 | def test_abort(self): | 566 | def test_abort(self): |
332 | 541 | slave = self.getClientSlave() | 567 | slave = self.slave_helper.getClientSlave() |
333 | 542 | # We need to be in a BUILDING state before we can abort. | 568 | # We need to be in a BUILDING state before we can abort. |
335 | 543 | self.triggerGoodBuild(slave) | 569 | self.slave_helper.triggerGoodBuild(slave) |
336 | 544 | result = slave.abort() | 570 | result = slave.abort() |
337 | 545 | self.assertEqual(result, BuilderStatus.ABORTING) | 571 | self.assertEqual(result, BuilderStatus.ABORTING) |
338 | 546 | 572 | ||
339 | @@ -549,8 +575,8 @@ | |||
340 | 549 | # valid chroot & filemaps works and returns a BuilderStatus of | 575 | # valid chroot & filemaps works and returns a BuilderStatus of |
341 | 550 | # BUILDING. | 576 | # BUILDING. |
342 | 551 | build_id = 'some-id' | 577 | build_id = 'some-id' |
345 | 552 | slave = self.getClientSlave() | 578 | slave = self.slave_helper.getClientSlave() |
346 | 553 | result = self.triggerGoodBuild(slave, build_id) | 579 | result = self.slave_helper.triggerGoodBuild(slave, build_id) |
347 | 554 | self.assertEqual([BuilderStatus.BUILDING, build_id], result) | 580 | self.assertEqual([BuilderStatus.BUILDING, build_id], result) |
348 | 555 | 581 | ||
349 | 556 | def test_clean(self): | 582 | def test_clean(self): |
350 | @@ -564,15 +590,15 @@ | |||
351 | 564 | def test_echo(self): | 590 | def test_echo(self): |
352 | 565 | # Calling 'echo' contacts the server which returns the arguments we | 591 | # Calling 'echo' contacts the server which returns the arguments we |
353 | 566 | # gave it. | 592 | # gave it. |
356 | 567 | self.getServerSlave() | 593 | self.slave_helper.getServerSlave() |
357 | 568 | slave = self.getClientSlave() | 594 | slave = self.slave_helper.getClientSlave() |
358 | 569 | result = slave.echo('foo', 'bar', 42) | 595 | result = slave.echo('foo', 'bar', 42) |
359 | 570 | self.assertEqual(['foo', 'bar', 42], result) | 596 | self.assertEqual(['foo', 'bar', 42], result) |
360 | 571 | 597 | ||
361 | 572 | def test_info(self): | 598 | def test_info(self): |
362 | 573 | # Calling 'info' gets some information about the slave. | 599 | # Calling 'info' gets some information about the slave. |
365 | 574 | self.getServerSlave() | 600 | self.slave_helper.getServerSlave() |
366 | 575 | slave = self.getClientSlave() | 601 | slave = self.slave_helper.getClientSlave() |
367 | 576 | result = slave.info() | 602 | result = slave.info() |
368 | 577 | # We're testing the hard-coded values, since the version is hard-coded | 603 | # We're testing the hard-coded values, since the version is hard-coded |
369 | 578 | # into the remote slave, the supported build managers are hard-coded | 604 | # into the remote slave, the supported build managers are hard-coded |
370 | @@ -588,17 +614,17 @@ | |||
371 | 588 | def test_initial_status(self): | 614 | def test_initial_status(self): |
372 | 589 | # Calling 'status' returns the current status of the slave. The | 615 | # Calling 'status' returns the current status of the slave. The |
373 | 590 | # initial status is IDLE. | 616 | # initial status is IDLE. |
376 | 591 | self.getServerSlave() | 617 | self.slave_helper.getServerSlave() |
377 | 592 | slave = self.getClientSlave() | 618 | slave = self.slave_helper.getClientSlave() |
378 | 593 | status = slave.status() | 619 | status = slave.status() |
379 | 594 | self.assertEqual([BuilderStatus.IDLE, ''], status) | 620 | self.assertEqual([BuilderStatus.IDLE, ''], status) |
380 | 595 | 621 | ||
381 | 596 | def test_status_after_build(self): | 622 | def test_status_after_build(self): |
382 | 597 | # Calling 'status' returns the current status of the slave. After a | 623 | # Calling 'status' returns the current status of the slave. After a |
383 | 598 | # build has been triggered, the status is BUILDING. | 624 | # build has been triggered, the status is BUILDING. |
385 | 599 | slave = self.getClientSlave() | 625 | slave = self.slave_helper.getClientSlave() |
386 | 600 | build_id = 'status-build-id' | 626 | build_id = 'status-build-id' |
388 | 601 | self.triggerGoodBuild(slave, build_id) | 627 | self.slave_helper.triggerGoodBuild(slave, build_id) |
389 | 602 | status = slave.status() | 628 | status = slave.status() |
390 | 603 | self.assertEqual([BuilderStatus.BUILDING, build_id], status[:2]) | 629 | self.assertEqual([BuilderStatus.BUILDING, build_id], status[:2]) |
391 | 604 | [log_file] = status[2:] | 630 | [log_file] = status[2:] |
392 | @@ -606,15 +632,84 @@ | |||
393 | 606 | 632 | ||
394 | 607 | def test_ensurepresent_not_there(self): | 633 | def test_ensurepresent_not_there(self): |
395 | 608 | # ensurepresent checks to see if a file is there. | 634 | # ensurepresent checks to see if a file is there. |
400 | 609 | self.getServerSlave() | 635 | self.slave_helper.getServerSlave() |
401 | 610 | slave = self.getClientSlave() | 636 | slave = self.slave_helper.getClientSlave() |
402 | 611 | result = slave.ensurepresent('blahblah', None, None, None) | 637 | d = slave.ensurepresent('blahblah', None, None, None) |
403 | 612 | self.assertEqual([False, 'No URL'], result) | 638 | d.addCallback(self.assertEqual, [False, 'No URL']) |
404 | 639 | return d | ||
405 | 613 | 640 | ||
406 | 614 | def test_ensurepresent_actually_there(self): | 641 | def test_ensurepresent_actually_there(self): |
407 | 615 | # ensurepresent checks to see if a file is there. | 642 | # ensurepresent checks to see if a file is there. |
413 | 616 | tachandler = self.getServerSlave() | 643 | tachandler = self.slave_helper.getServerSlave() |
414 | 617 | slave = self.getClientSlave() | 644 | slave = self.slave_helper.getClientSlave() |
415 | 618 | self.makeCacheFile(tachandler, 'blahblah') | 645 | self.slave_helper.makeCacheFile(tachandler, 'blahblah') |
416 | 619 | result = slave.ensurepresent('blahblah', None, None, None) | 646 | d = slave.ensurepresent('blahblah', None, None, None) |
417 | 620 | self.assertEqual([True, 'No URL'], result) | 647 | d.addCallback(self.assertEqual, [True, 'No URL']) |
418 | 648 | return d | ||
419 | 649 | |||
420 | 650 | def test_sendFileToSlave_not_there(self): | ||
421 | 651 | self.slave_helper.getServerSlave() | ||
422 | 652 | slave = self.slave_helper.getClientSlave() | ||
423 | 653 | d = slave.sendFileToSlave('blahblah', None, None, None) | ||
424 | 654 | return self.assertFailure(d, CannotFetchFile) | ||
425 | 655 | |||
426 | 656 | def test_sendFileToSlave_actually_there(self): | ||
427 | 657 | tachandler = self.slave_helper.getServerSlave() | ||
428 | 658 | slave = self.slave_helper.getClientSlave() | ||
429 | 659 | self.slave_helper.makeCacheFile(tachandler, 'blahblah') | ||
430 | 660 | d = slave.sendFileToSlave('blahblah', None, None, None) | ||
431 | 661 | def check_present(ignored): | ||
432 | 662 | d = slave.ensurepresent('blahblah', None, None, None) | ||
433 | 663 | return d.addCallback(self.assertEqual, [True, 'No URL']) | ||
434 | 664 | d.addCallback(check_present) | ||
435 | 665 | return d | ||
436 | 666 | |||
437 | 667 | |||
438 | 668 | class TestSlaveWithLibrarian(TrialTestCase): | ||
439 | 669 | """Tests that need more of Launchpad to run.""" | ||
440 | 670 | |||
441 | 671 | layer = TwistedLaunchpadZopelessLayer | ||
442 | 672 | |||
443 | 673 | def setUp(self): | ||
444 | 674 | super(TestSlaveWithLibrarian, self) | ||
445 | 675 | self.slave_helper = SlaveTestHelpers() | ||
446 | 676 | self.slave_helper.setUp() | ||
447 | 677 | self.addCleanup(self.slave_helper.cleanUp) | ||
448 | 678 | self.factory = LaunchpadObjectFactory() | ||
449 | 679 | login_as(ANONYMOUS) | ||
450 | 680 | self.addCleanup(logout) | ||
451 | 681 | |||
452 | 682 | def test_ensurepresent_librarian(self): | ||
453 | 683 | # ensurepresent, when given an http URL for a file will download the | ||
454 | 684 | # file from that URL and report that the file is present, and it was | ||
455 | 685 | # downloaded. | ||
456 | 686 | |||
457 | 687 | # Use the Librarian because it's a "convenient" web server. | ||
458 | 688 | lf = self.factory.makeLibraryFileAlias( | ||
459 | 689 | 'HelloWorld.txt', content="Hello World") | ||
460 | 690 | self.layer.txn.commit() | ||
461 | 691 | self.slave_helper.getServerSlave() | ||
462 | 692 | slave = self.slave_helper.getClientSlave() | ||
463 | 693 | d = slave.ensurepresent( | ||
464 | 694 | lf.content.sha1, lf.http_url, "", "") | ||
465 | 695 | d.addCallback(self.assertEqual, [True, 'Download']) | ||
466 | 696 | return d | ||
467 | 697 | |||
468 | 698 | def test_retrieve_files_from_filecache(self): | ||
469 | 699 | # Files that are present on the slave can be downloaded with a | ||
470 | 700 | # filename made from the sha1 of the content underneath the | ||
471 | 701 | # 'filecache' directory. | ||
472 | 702 | content = "Hello World" | ||
473 | 703 | lf = self.factory.makeLibraryFileAlias( | ||
474 | 704 | 'HelloWorld.txt', content=content) | ||
475 | 705 | self.layer.txn.commit() | ||
476 | 706 | expected_url = '%s/filecache/%s' % ( | ||
477 | 707 | self.slave_helper.BASE_URL, lf.content.sha1) | ||
478 | 708 | self.slave_helper.getServerSlave() | ||
479 | 709 | slave = self.slave_helper.getClientSlave() | ||
480 | 710 | d = slave.ensurepresent( | ||
481 | 711 | lf.content.sha1, lf.http_url, "", "") | ||
482 | 712 | def check_file(ignored): | ||
483 | 713 | d = getPage(expected_url.encode('utf8')) | ||
484 | 714 | return d.addCallback(self.assertEqual, content) | ||
485 | 715 | return d.addCallback(check_file) | ||
486 | 621 | 716 | ||
487 | === modified file 'lib/lp/code/model/recipebuilder.py' | |||
488 | --- lib/lp/code/model/recipebuilder.py 2010-08-20 20:31:18 +0000 | |||
489 | +++ lib/lp/code/model/recipebuilder.py 2010-09-22 11:33:47 +0000 | |||
490 | @@ -122,33 +122,36 @@ | |||
491 | 122 | if chroot is None: | 122 | if chroot is None: |
492 | 123 | raise CannotBuild("Unable to find a chroot for %s" % | 123 | raise CannotBuild("Unable to find a chroot for %s" % |
493 | 124 | distroarchseries.displayname) | 124 | distroarchseries.displayname) |
521 | 125 | self._builder.slave.cacheFile(logger, chroot) | 125 | d = self._builder.slave.cacheFile(logger, chroot) |
522 | 126 | 126 | ||
523 | 127 | # Generate a string which can be used to cross-check when obtaining | 127 | def got_cache_file(ignored): |
524 | 128 | # results so we know we are referring to the right database object in | 128 | # Generate a string which can be used to cross-check when obtaining |
525 | 129 | # subsequent runs. | 129 | # results so we know we are referring to the right database object in |
526 | 130 | buildid = "%s-%s" % (self.build.id, build_queue_id) | 130 | # subsequent runs. |
527 | 131 | cookie = self.buildfarmjob.generateSlaveBuildCookie() | 131 | buildid = "%s-%s" % (self.build.id, build_queue_id) |
528 | 132 | chroot_sha1 = chroot.content.sha1 | 132 | cookie = self.buildfarmjob.generateSlaveBuildCookie() |
529 | 133 | logger.debug( | 133 | chroot_sha1 = chroot.content.sha1 |
530 | 134 | "Initiating build %s on %s" % (buildid, self._builder.url)) | 134 | logger.debug( |
531 | 135 | 135 | "Initiating build %s on %s" % (buildid, self._builder.url)) | |
532 | 136 | args = self._extraBuildArgs(distroarchseries, logger) | 136 | |
533 | 137 | status, info = self._builder.slave.build( | 137 | args = self._extraBuildArgs(distroarchseries, logger) |
534 | 138 | cookie, "sourcepackagerecipe", chroot_sha1, {}, args) | 138 | # XXX: Soon to be async |
535 | 139 | message = """%s (%s): | 139 | status, info = self._builder.slave.build( |
536 | 140 | ***** RESULT ***** | 140 | cookie, "sourcepackagerecipe", chroot_sha1, {}, args) |
537 | 141 | %s | 141 | message = """%s (%s): |
538 | 142 | %s: %s | 142 | ***** RESULT ***** |
539 | 143 | ****************** | 143 | %s |
540 | 144 | """ % ( | 144 | %s: %s |
541 | 145 | self._builder.name, | 145 | ****************** |
542 | 146 | self._builder.url, | 146 | """ % ( |
543 | 147 | args, | 147 | self._builder.name, |
544 | 148 | status, | 148 | self._builder.url, |
545 | 149 | info, | 149 | args, |
546 | 150 | ) | 150 | status, |
547 | 151 | logger.info(message) | 151 | info, |
548 | 152 | ) | ||
549 | 153 | logger.info(message) | ||
550 | 154 | return d.addCallback(got_cache_file) | ||
551 | 152 | 155 | ||
552 | 153 | def verifyBuildRequest(self, logger): | 156 | def verifyBuildRequest(self, logger): |
553 | 154 | """Assert some pre-build checks. | 157 | """Assert some pre-build checks. |
554 | 155 | 158 | ||
555 | === modified file 'lib/lp/soyuz/model/binarypackagebuildbehavior.py' | |||
556 | --- lib/lp/soyuz/model/binarypackagebuildbehavior.py 2010-09-22 11:33:46 +0000 | |||
557 | +++ lib/lp/soyuz/model/binarypackagebuildbehavior.py 2010-09-22 11:33:47 +0000 | |||
558 | @@ -11,6 +11,7 @@ | |||
559 | 11 | 'BinaryPackageBuildBehavior', | 11 | 'BinaryPackageBuildBehavior', |
560 | 12 | ] | 12 | ] |
561 | 13 | 13 | ||
562 | 14 | from twisted.internet import defer | ||
563 | 14 | from zope.interface import implements | 15 | from zope.interface import implements |
564 | 15 | 16 | ||
565 | 16 | from canonical.launchpad.webapp import urlappend | 17 | from canonical.launchpad.webapp import urlappend |
566 | @@ -38,56 +39,66 @@ | |||
567 | 38 | logger.info("startBuild(%s, %s, %s, %s)", self._builder.url, | 39 | logger.info("startBuild(%s, %s, %s, %s)", self._builder.url, |
568 | 39 | spr.name, spr.version, self.build.pocket.title) | 40 | spr.name, spr.version, self.build.pocket.title) |
569 | 40 | 41 | ||
578 | 41 | def dispatchBuildToSlave(self, build_queue_id, logger): | 42 | def _buildFilemapStructure(self, ignored, logger): |
571 | 42 | """See `IBuildFarmJobBehavior`.""" | ||
572 | 43 | |||
573 | 44 | # Start the binary package build on the slave builder. First | ||
574 | 45 | # we send the chroot. | ||
575 | 46 | chroot = self.build.distro_arch_series.getChroot() | ||
576 | 47 | self._builder.slave.cacheFile(logger, chroot) | ||
577 | 48 | |||
579 | 49 | # Build filemap structure with the files required in this build | 43 | # Build filemap structure with the files required in this build |
580 | 50 | # and send them to the slave. | 44 | # and send them to the slave. |
581 | 51 | # If the build is private we tell the slave to get the files from the | 45 | # If the build is private we tell the slave to get the files from the |
582 | 52 | # archive instead of the librarian because the slaves cannot | 46 | # archive instead of the librarian because the slaves cannot |
583 | 53 | # access the restricted librarian. | 47 | # access the restricted librarian. |
584 | 48 | dl = [] | ||
585 | 54 | private = self.build.archive.private | 49 | private = self.build.archive.private |
586 | 55 | if private: | 50 | if private: |
588 | 56 | self._cachePrivateSourceOnSlave(logger) | 51 | dl.extend(self._cachePrivateSourceOnSlave(logger)) |
589 | 57 | filemap = {} | 52 | filemap = {} |
590 | 58 | for source_file in self.build.source_package_release.files: | 53 | for source_file in self.build.source_package_release.files: |
591 | 59 | lfa = source_file.libraryfile | 54 | lfa = source_file.libraryfile |
592 | 60 | filemap[lfa.filename] = lfa.content.sha1 | 55 | filemap[lfa.filename] = lfa.content.sha1 |
593 | 61 | if not private: | 56 | if not private: |
623 | 62 | self._builder.slave.cacheFile(logger, source_file.libraryfile) | 57 | dl.append( |
624 | 63 | 58 | self._builder.slave.cacheFile( | |
625 | 64 | # Generate a string which can be used to cross-check when obtaining | 59 | logger, source_file.libraryfile)) |
626 | 65 | # results so we know we are referring to the right database object in | 60 | d = defer.gatherResults(dl) |
627 | 66 | # subsequent runs. | 61 | return d.addCallback(lambda ignored: filemap) |
628 | 67 | buildid = "%s-%s" % (self.build.id, build_queue_id) | 62 | |
629 | 68 | cookie = self.buildfarmjob.generateSlaveBuildCookie() | 63 | def dispatchBuildToSlave(self, build_queue_id, logger): |
630 | 69 | chroot_sha1 = chroot.content.sha1 | 64 | """See `IBuildFarmJobBehavior`.""" |
631 | 70 | logger.debug( | 65 | |
632 | 71 | "Initiating build %s on %s" % (buildid, self._builder.url)) | 66 | # Start the binary package build on the slave builder. First |
633 | 72 | 67 | # we send the chroot. | |
634 | 73 | args = self._extraBuildArgs(self.build) | 68 | chroot = self.build.distro_arch_series.getChroot() |
635 | 74 | status, info = self._builder.slave.build( | 69 | d = self._builder.slave.cacheFile(logger, chroot) |
636 | 75 | cookie, "binarypackage", chroot_sha1, filemap, args) | 70 | d.addCallback(self._buildFilemapStructure, logger) |
637 | 76 | message = """%s (%s): | 71 | |
638 | 77 | ***** RESULT ***** | 72 | def got_filemap(filemap): |
639 | 78 | %s | 73 | # Generate a string which can be used to cross-check when obtaining |
640 | 79 | %s | 74 | # results so we know we are referring to the right database object in |
641 | 80 | %s: %s | 75 | # subsequent runs. |
642 | 81 | ****************** | 76 | buildid = "%s-%s" % (self.build.id, build_queue_id) |
643 | 82 | """ % ( | 77 | cookie = self.buildfarmjob.generateSlaveBuildCookie() |
644 | 83 | self._builder.name, | 78 | chroot_sha1 = chroot.content.sha1 |
645 | 84 | self._builder.url, | 79 | logger.debug( |
646 | 85 | filemap, | 80 | "Initiating build %s on %s" % (buildid, self._builder.url)) |
647 | 86 | args, | 81 | |
648 | 87 | status, | 82 | args = self._extraBuildArgs(self.build) |
649 | 88 | info, | 83 | status, info = self._builder.slave.build( |
650 | 89 | ) | 84 | cookie, "binarypackage", chroot_sha1, filemap, args) |
651 | 90 | logger.info(message) | 85 | message = """%s (%s): |
652 | 86 | ***** RESULT ***** | ||
653 | 87 | %s | ||
654 | 88 | %s | ||
655 | 89 | %s: %s | ||
656 | 90 | ****************** | ||
657 | 91 | """ % ( | ||
658 | 92 | self._builder.name, | ||
659 | 93 | self._builder.url, | ||
660 | 94 | filemap, | ||
661 | 95 | args, | ||
662 | 96 | status, | ||
663 | 97 | info, | ||
664 | 98 | ) | ||
665 | 99 | logger.info(message) | ||
666 | 100 | |||
667 | 101 | return d.addCallback(got_filemap) | ||
668 | 91 | 102 | ||
669 | 92 | def verifyBuildRequest(self, logger): | 103 | def verifyBuildRequest(self, logger): |
670 | 93 | """Assert some pre-build checks. | 104 | """Assert some pre-build checks. |
671 | @@ -154,6 +165,8 @@ | |||
672 | 154 | """Ask the slave to download source files for a private build. | 165 | """Ask the slave to download source files for a private build. |
673 | 155 | 166 | ||
674 | 156 | :param logger: A logger used for providing debug information. | 167 | :param logger: A logger used for providing debug information. |
675 | 168 | :return: A list of Deferreds, each of which represents a request | ||
676 | 169 | to cache a file. | ||
677 | 157 | """ | 170 | """ |
678 | 158 | # The URL to the file in the archive consists of these parts: | 171 | # The URL to the file in the archive consists of these parts: |
679 | 159 | # archive_url / makePoolPath() / filename | 172 | # archive_url / makePoolPath() / filename |
680 | @@ -165,6 +178,7 @@ | |||
681 | 165 | archive = self.build.archive | 178 | archive = self.build.archive |
682 | 166 | archive_url = archive.archive_url | 179 | archive_url = archive.archive_url |
683 | 167 | component_name = self.build.current_component.name | 180 | component_name = self.build.current_component.name |
684 | 181 | dl = [] | ||
685 | 168 | for source_file in self.build.source_package_release.files: | 182 | for source_file in self.build.source_package_release.files: |
686 | 169 | file_name = source_file.libraryfile.filename | 183 | file_name = source_file.libraryfile.filename |
687 | 170 | sha1 = source_file.libraryfile.content.sha1 | 184 | sha1 = source_file.libraryfile.content.sha1 |
688 | @@ -175,8 +189,10 @@ | |||
689 | 175 | logger.debug("Asking builder on %s to ensure it has file %s " | 189 | logger.debug("Asking builder on %s to ensure it has file %s " |
690 | 176 | "(%s, %s)" % ( | 190 | "(%s, %s)" % ( |
691 | 177 | self._builder.url, file_name, url, sha1)) | 191 | self._builder.url, file_name, url, sha1)) |
694 | 178 | self._builder.slave.sendFileToSlave( | 192 | dl.append( |
695 | 179 | sha1, url, "buildd", archive.buildd_secret) | 193 | self._builder.slave.sendFileToSlave( |
696 | 194 | sha1, url, "buildd", archive.buildd_secret)) | ||
697 | 195 | return dl | ||
698 | 180 | 196 | ||
699 | 181 | def _extraBuildArgs(self, build): | 197 | def _extraBuildArgs(self, build): |
700 | 182 | """ | 198 | """ |
701 | 183 | 199 | ||
702 | === modified file 'lib/lp/soyuz/tests/soyuzbuilddhelpers.py' | |||
703 | --- lib/lp/soyuz/tests/soyuzbuilddhelpers.py 2010-09-22 11:33:46 +0000 | |||
704 | +++ lib/lp/soyuz/tests/soyuzbuilddhelpers.py 2010-09-22 11:33:47 +0000 | |||
705 | @@ -19,6 +19,8 @@ | |||
706 | 19 | from StringIO import StringIO | 19 | from StringIO import StringIO |
707 | 20 | import xmlrpclib | 20 | import xmlrpclib |
708 | 21 | 21 | ||
709 | 22 | from twisted.internet import defer | ||
710 | 23 | |||
711 | 22 | from lp.buildmaster.interfaces.builder import CannotFetchFile | 24 | from lp.buildmaster.interfaces.builder import CannotFetchFile |
712 | 23 | from lp.buildmaster.model.builder import ( | 25 | from lp.buildmaster.model.builder import ( |
713 | 24 | rescueBuilderIfLost, | 26 | rescueBuilderIfLost, |
714 | @@ -99,7 +101,7 @@ | |||
715 | 99 | 101 | ||
716 | 100 | def ensurepresent(self, sha1, url, user=None, password=None): | 102 | def ensurepresent(self, sha1, url, user=None, password=None): |
717 | 101 | self.call_log.append(('ensurepresent', url, user, password)) | 103 | self.call_log.append(('ensurepresent', url, user, password)) |
719 | 102 | return True, None | 104 | return defer.succeed((True, None)) |
720 | 103 | 105 | ||
721 | 104 | def build(self, buildid, buildtype, chroot, filemap, args): | 106 | def build(self, buildid, buildtype, chroot, filemap, args): |
722 | 105 | self.call_log.append( | 107 | self.call_log.append( |
723 | @@ -123,9 +125,11 @@ | |||
724 | 123 | 125 | ||
725 | 124 | def sendFileToSlave(self, sha1, url, username="", password=""): | 126 | def sendFileToSlave(self, sha1, url, username="", password=""): |
726 | 125 | self.call_log.append('sendFileToSlave') | 127 | self.call_log.append('sendFileToSlave') |
730 | 126 | present, info = self.ensurepresent(sha1, url, username, password) | 128 | d = self.ensurepresent(sha1, url, username, password) |
731 | 127 | if not present: | 129 | def check_present((present, info)): |
732 | 128 | raise CannotFetchFile(url, info) | 130 | if not present: |
733 | 131 | raise CannotFetchFile(url, info) | ||
734 | 132 | return d.addCallback(check_present) | ||
735 | 129 | 133 | ||
736 | 130 | def cacheFile(self, logger, libraryfilealias): | 134 | def cacheFile(self, logger, libraryfilealias): |
737 | 131 | self.call_log.append('cacheFile') | 135 | self.call_log.append('cacheFile') |
738 | 132 | 136 | ||
739 | === modified file 'lib/lp/translations/model/translationtemplatesbuildbehavior.py' | |||
740 | --- lib/lp/translations/model/translationtemplatesbuildbehavior.py 2010-08-20 20:31:18 +0000 | |||
741 | +++ lib/lp/translations/model/translationtemplatesbuildbehavior.py 2010-09-22 11:33:47 +0000 | |||
742 | @@ -41,16 +41,18 @@ | |||
743 | 41 | """See `IBuildFarmJobBehavior`.""" | 41 | """See `IBuildFarmJobBehavior`.""" |
744 | 42 | chroot = self._getChroot() | 42 | chroot = self._getChroot() |
745 | 43 | chroot_sha1 = chroot.content.sha1 | 43 | chroot_sha1 = chroot.content.sha1 |
756 | 44 | self._builder.slave.cacheFile(logger, chroot) | 44 | d = self._builder.slave.cacheFile(logger, chroot) |
757 | 45 | cookie = self.buildfarmjob.generateSlaveBuildCookie() | 45 | def got_cache_file(ignored): |
758 | 46 | 46 | cookie = self.buildfarmjob.generateSlaveBuildCookie() | |
759 | 47 | args = {'arch_tag': self._getDistroArchSeries().architecturetag} | 47 | |
760 | 48 | args.update(self.buildfarmjob.metadata) | 48 | args = {'arch_tag': self._getDistroArchSeries().architecturetag} |
761 | 49 | 49 | args.update(self.buildfarmjob.metadata) | |
762 | 50 | filemap = {} | 50 | |
763 | 51 | 51 | filemap = {} | |
764 | 52 | self._builder.slave.build( | 52 | |
765 | 53 | cookie, self.build_type, chroot_sha1, filemap, args) | 53 | return self._builder.slave.build( |
766 | 54 | cookie, self.build_type, chroot_sha1, filemap, args) | ||
767 | 55 | return d.addCallback(got_cache_file) | ||
768 | 54 | 56 | ||
769 | 55 | def _getChroot(self): | 57 | def _getChroot(self): |
770 | 56 | return self._getDistroArchSeries().getChroot() | 58 | return self._getDistroArchSeries().getChroot() |