launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #01150
[Merge] lp:~jml/launchpad/buildd-deferred-fo-sho into lp:launchpad/devel
Jonathan Lange has proposed merging lp:~jml/launchpad/buildd-deferred-fo-sho into lp:launchpad/devel with lp:~jml/launchpad/buildd-slavescanner-bustage as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Use Deferreds.
--
https://code.launchpad.net/~jml/launchpad/buildd-deferred-fo-sho/+merge/36188
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jml/launchpad/buildd-deferred-fo-sho into lp:launchpad/devel.
=== modified file 'lib/lp/buildmaster/manager.py'
--- lib/lp/buildmaster/manager.py 2010-09-20 10:21:32 +0000
+++ lib/lp/buildmaster/manager.py 2010-09-21 18:41:34 +0000
@@ -283,15 +283,15 @@
"""Scan the builder and dispatch to it or deal with failures."""
self.logger.debug("Scanning builder: %s" % self.builder_name)
- try:
- slave = self.scan()
+ d = self.scan()
+
+ def got_slave(slave):
if slave is None:
- self.scheduleNextScanCycle()
+ return self.scheduleNextScanCycle()
else:
- # XXX: Ought to return Deferred.
- self.resumeAndDispatch(slave)
- except:
- error = Failure()
+ return self.resumeAndDispatch(slave)
+
+ def disaster(error):
self.logger.info("Scanning failed with: %s\n%s" %
(error.getErrorMessage(), error.getTraceback()))
@@ -307,7 +307,11 @@
assessFailureCounts(builder, error.getErrorMessage())
transaction.commit()
- self.scheduleNextScanCycle()
+ return self.scheduleNextScanCycle()
+
+ d.addCallback(got_slave)
+ d.addErrback(disaster)
+ return d
@write_transaction
def scan(self):
@@ -346,7 +350,7 @@
if self.builder.manual:
self.logger.debug(
'%s is in manual mode, not dispatching.' % self.builder.name)
- return None
+ return defer.succeed(None)
# If the builder is marked unavailable, don't dispatch anything.
# Additionaly, because builders can be removed from the pool at
@@ -362,7 +366,7 @@
"job" % self.builder.name)
job.reset()
transaction.commit()
- return None
+ return defer.succeed(None)
# See if there is a job we can dispatch to the builder slave.
@@ -374,15 +378,17 @@
self.builder.name, self.builder.url, self.builder.vm_host)
# XXX: Passing buildd_slave=slave overwrites the 'slave' property of
# self.builder. Not sure why this is needed yet.
- self.builder.findAndStartJob(buildd_slave=slave)
- if self.builder.currentjob is not None:
- # After a successful dispatch we can reset the
- # failure_count.
- self.builder.resetFailureCount()
- transaction.commit()
- return slave
-
- return None
+ d = self.builder.findAndStartJob(buildd_slave=slave)
+ def job_started(candidate):
+ if self.builder.currentjob is not None:
+ # After a successful dispatch we can reset the
+ # failure_count.
+ self.builder.resetFailureCount()
+ transaction.commit()
+ return slave
+ else:
+ return None
+ return d.addCallback(job_started)
def resumeAndDispatch(self, slave):
"""Chain the resume and dispatching Deferreds."""
=== modified file 'lib/lp/buildmaster/model/builder.py'
--- lib/lp/buildmaster/model/builder.py 2010-09-21 18:41:33 +0000
+++ lib/lp/buildmaster/model/builder.py 2010-09-21 18:41:34 +0000
@@ -34,6 +34,7 @@
Count,
Sum,
)
+from twisted.internet import defer
from zope.component import getUtility
from zope.interface import implements
@@ -166,8 +167,10 @@
return self._server.status()
def ensurepresent(self, sha1sum, url, username, password):
+ # XXX: Nothing external calls this. Make it private.
"""Attempt to ensure the given file is present."""
- return self._server.ensurepresent(sha1sum, url, username, password)
+ return defer.succeed(
+ self._server.ensurepresent(sha1sum, url, username, password))
def getFile(self, sha_sum):
"""Construct a file-like object to return the named file."""
@@ -206,13 +209,15 @@
logger.debug("Asking builder on %s to ensure it has file %s "
"(%s, %s)" % (self.urlbase, libraryfilealias.filename,
url, libraryfilealias.content.sha1))
- self.sendFileToSlave(libraryfilealias.content.sha1, url)
+ return self.sendFileToSlave(libraryfilealias.content.sha1, url)
def sendFileToSlave(self, sha1, url, username="", password=""):
"""Helper to send the file at 'url' with 'sha1' to this builder."""
- present, info = self.ensurepresent(sha1, url, username, password)
- if not present:
- raise CannotFetchFile(url, info)
+ d = self.ensurepresent(sha1, url, username, password)
+ def check_present((present, info)):
+ if not present:
+ raise CannotFetchFile(url, info)
+ return d.addCallback(check_present)
def build(self, buildid, builder_type, chroot_sha1, filemap, args):
"""Build a thing on this build slave.
@@ -469,14 +474,19 @@
# Do it.
build_queue_item.markAsBuilding(self)
- try:
- self.current_build_behavior.dispatchBuildToSlave(
- build_queue_item.id, logger)
- except BuildSlaveFailure, e:
- logger.debug("Disabling builder: %s" % self.url, exc_info=1)
+
+ d = self.current_build_behavior.dispatchBuildToSlave(
+ build_queue_item.id, logger)
+
+ def eb_slave_failure(failure):
+ failure.trap(BuildSlaveFailure)
+ e = failure.value
self.failBuilder(
"Exception (%s) when setting up to new job" % (e,))
- except CannotFetchFile, e:
+
+ def eb_cannot_fetch_file(failure):
+ failure.trap(CannotFetchFile)
+ e = failure.value
message = """Slave '%s' (%s) was unable to fetch file.
****** URL ********
%s
@@ -485,11 +495,19 @@
*******************
""" % (self.name, self.url, e.file_url, e.error_information)
raise BuildDaemonError(message)
- except socket.error, e:
+
+ def eb_socket_error(failure):
+ failure.trap(socket.error)
+ e = failure.value
error_message = "Exception (%s) when setting up new job" % (e,)
self.handleTimeout(logger, error_message)
raise BuildSlaveFailure
+ d.addErrback(eb_slave_failure)
+ d.addErrback(eb_cannot_fetch_file)
+ d.addErrback(eb_socket_error)
+ return d
+
def failBuilder(self, reason):
"""See IBuilder"""
# XXX cprov 2007-04-17: ideally we should be able to notify the
@@ -682,10 +700,13 @@
:param candidate: The job to dispatch.
"""
logger = self._getSlaveScannerLogger()
- try:
- self.startBuild(candidate, logger)
- except (BuildSlaveFailure, CannotBuild, BuildBehaviorMismatch), err:
+ d = self.startBuild(candidate, logger)
+ def warn_on_error(failure):
+ failure.trap(
+ BuildSlaveFailure, CannotBuild, BuildBehaviorMismatch)
+ err = failure.value
logger.warn('Could not build: %s' % err)
+ return d.addErrback(warn_on_error)
def handleTimeout(self, logger, error_message):
"""See IBuilder."""
@@ -726,8 +747,8 @@
if buildd_slave is not None:
self.setSlaveForTesting(buildd_slave)
- self._dispatchBuildCandidate(candidate)
- return candidate
+ d = self._dispatchBuildCandidate(candidate)
+ return d.addCallback(lambda ignored: candidate)
def getBuildQueue(self):
"""See `IBuilder`."""
=== modified file 'lib/lp/buildmaster/tests/test_builder.py'
--- lib/lp/buildmaster/tests/test_builder.py 2010-09-21 16:23:35 +0000
+++ lib/lp/buildmaster/tests/test_builder.py 2010-09-21 18:41:34 +0000
@@ -8,8 +8,10 @@
import socket
import xmlrpclib
-from testtools.content import Content
-from testtools.content_type import UTF8_TEXT
+import fixtures
+
+from twisted.trial.unittest import TestCase as TrialTestCase
+from twisted.web.client import getPage
from zope.component import getUtility
from zope.security.proxy import removeSecurityProxy
@@ -24,10 +26,16 @@
)
from canonical.testing.layers import (
DatabaseFunctionalLayer,
- LaunchpadZopelessLayer
+ LaunchpadZopelessLayer,
+ TwistedLaunchpadZopelessLayer,
+ TwistedLayer,
)
from lp.buildmaster.enums import BuildStatus
-from lp.buildmaster.interfaces.builder import IBuilder, IBuilderSet
+from lp.buildmaster.interfaces.builder import (
+ CannotFetchFile,
+ IBuilder,
+ IBuilderSet,
+ )
from lp.buildmaster.interfaces.buildfarmjobbehavior import (
IBuildFarmJobBehavior,
)
@@ -49,9 +57,12 @@
)
from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
from lp.testing import (
- TestCase,
+ ANONYMOUS,
+ login_as,
+ logout,
TestCaseWithFactory,
)
+from lp.testing.factory import LaunchpadObjectFactory
from lp.testing.fakemethod import FakeMethod
@@ -467,19 +478,11 @@
self.builder.current_build_behavior, BinaryPackageBuildBehavior)
-class TestSlave(TestCase):
- """
- Integration tests for BuilderSlave that verify how it works against a
- real slave server.
- """
-
- # XXX: JonathanLange 2010-09-20 bug=643521: There are also tests for
- # BuilderSlave in buildd-slave.txt and in other places. The tests here
- # ought to become the canonical tests for BuilderSlave vs running buildd
- # XML-RPC server interaction.
+class SlaveTestHelpers(fixtures.Fixture):
# The URL for the XML-RPC service set up by `BuilddSlaveTestSetup`.
- TEST_URL = 'http://localhost:8221/rpc/'
+ BASE_URL = 'http://localhost:8221'
+ TEST_URL = '%s/rpc/' % (BASE_URL,)
def getServerSlave(self):
"""Set up a test build slave server.
@@ -488,11 +491,14 @@
"""
tachandler = BuilddSlaveTestSetup()
tachandler.setUp()
- def addLogFile(exc_info):
- self.addDetail(
- 'xmlrpc-log-file',
- Content(UTF8_TEXT, lambda: open(tachandler.logfile, 'r').read()))
- self.addOnException(addLogFile)
+ # Basically impossible to do this w/ TrialTestCase. But it would be
+ # really nice to keep it.
+ #
+ # def addLogFile(exc_info):
+ # self.addDetail(
+ # 'xmlrpc-log-file',
+ # Content(UTF8_TEXT, lambda: open(tachandler.logfile, 'r').read()))
+ # self.addOnException(addLogFile)
self.addCleanup(tachandler.tearDown)
return tachandler
@@ -527,7 +533,7 @@
:return: The build id returned by the slave.
"""
if build_id is None:
- build_id = self.getUniqueString()
+ build_id = 'random-build-id'
tachandler = self.getServerSlave()
chroot_file = 'fake-chroot'
dsc_file = 'thing'
@@ -537,10 +543,30 @@
build_id, 'debian', chroot_file, {'.dsc': dsc_file},
{'ogrecomponent': 'main'})
+
+class TestSlave(TrialTestCase):
+ """
+ Integration tests for BuilderSlave that verify how it works against a
+ real slave server.
+ """
+
+ layer = TwistedLayer
+
+ def setUp(self):
+ super(TestSlave, self).setUp()
+ self.slave_helper = SlaveTestHelpers()
+ self.slave_helper.setUp()
+ self.addCleanup(self.slave_helper.cleanUp)
+
+ # XXX: JonathanLange 2010-09-20 bug=643521: There are also tests for
+ # BuilderSlave in buildd-slave.txt and in other places. The tests here
+ # ought to become the canonical tests for BuilderSlave vs running buildd
+ # XML-RPC server interaction.
+
def test_abort(self):
- slave = self.getClientSlave()
+ slave = self.slave_helper.getClientSlave()
# We need to be in a BUILDING state before we can abort.
- self.triggerGoodBuild(slave)
+ self.slave_helper.triggerGoodBuild(slave)
result = slave.abort()
self.assertEqual(result, BuilderStatus.ABORTING)
@@ -549,8 +575,8 @@
# valid chroot & filemaps works and returns a BuilderStatus of
# BUILDING.
build_id = 'some-id'
- slave = self.getClientSlave()
- result = self.triggerGoodBuild(slave, build_id)
+ slave = self.slave_helper.getClientSlave()
+ result = self.slave_helper.triggerGoodBuild(slave, build_id)
self.assertEqual([BuilderStatus.BUILDING, build_id], result)
def test_clean(self):
@@ -564,15 +590,15 @@
def test_echo(self):
# Calling 'echo' contacts the server which returns the arguments we
# gave it.
- self.getServerSlave()
- slave = self.getClientSlave()
+ self.slave_helper.getServerSlave()
+ slave = self.slave_helper.getClientSlave()
result = slave.echo('foo', 'bar', 42)
self.assertEqual(['foo', 'bar', 42], result)
def test_info(self):
# Calling 'info' gets some information about the slave.
- self.getServerSlave()
- slave = self.getClientSlave()
+ self.slave_helper.getServerSlave()
+ slave = self.slave_helper.getClientSlave()
result = slave.info()
# We're testing the hard-coded values, since the version is hard-coded
# into the remote slave, the supported build managers are hard-coded
@@ -588,17 +614,17 @@
def test_initial_status(self):
# Calling 'status' returns the current status of the slave. The
# initial status is IDLE.
- self.getServerSlave()
- slave = self.getClientSlave()
+ self.slave_helper.getServerSlave()
+ slave = self.slave_helper.getClientSlave()
status = slave.status()
self.assertEqual([BuilderStatus.IDLE, ''], status)
def test_status_after_build(self):
# Calling 'status' returns the current status of the slave. After a
# build has been triggered, the status is BUILDING.
- slave = self.getClientSlave()
+ slave = self.slave_helper.getClientSlave()
build_id = 'status-build-id'
- self.triggerGoodBuild(slave, build_id)
+ self.slave_helper.triggerGoodBuild(slave, build_id)
status = slave.status()
self.assertEqual([BuilderStatus.BUILDING, build_id], status[:2])
[log_file] = status[2:]
@@ -606,15 +632,84 @@
def test_ensurepresent_not_there(self):
# ensurepresent checks to see if a file is there.
- self.getServerSlave()
- slave = self.getClientSlave()
- result = slave.ensurepresent('blahblah', None, None, None)
- self.assertEqual([False, 'No URL'], result)
+ self.slave_helper.getServerSlave()
+ slave = self.slave_helper.getClientSlave()
+ d = slave.ensurepresent('blahblah', None, None, None)
+ d.addCallback(self.assertEqual, [False, 'No URL'])
+ return d
def test_ensurepresent_actually_there(self):
# ensurepresent checks to see if a file is there.
- tachandler = self.getServerSlave()
- slave = self.getClientSlave()
- self.makeCacheFile(tachandler, 'blahblah')
- result = slave.ensurepresent('blahblah', None, None, None)
- self.assertEqual([True, 'No URL'], result)
+ tachandler = self.slave_helper.getServerSlave()
+ slave = self.slave_helper.getClientSlave()
+ self.slave_helper.makeCacheFile(tachandler, 'blahblah')
+ d = slave.ensurepresent('blahblah', None, None, None)
+ d.addCallback(self.assertEqual, [True, 'No URL'])
+ return d
+
+ def test_sendFileToSlave_not_there(self):
+ self.slave_helper.getServerSlave()
+ slave = self.slave_helper.getClientSlave()
+ d = slave.sendFileToSlave('blahblah', None, None, None)
+ return self.assertFailure(d, CannotFetchFile)
+
+ def test_sendFileToSlave_actually_there(self):
+ tachandler = self.slave_helper.getServerSlave()
+ slave = self.slave_helper.getClientSlave()
+ self.slave_helper.makeCacheFile(tachandler, 'blahblah')
+ d = slave.sendFileToSlave('blahblah', None, None, None)
+ def check_present(ignored):
+ d = slave.ensurepresent('blahblah', None, None, None)
+ return d.addCallback(self.assertEqual, [True, 'No URL'])
+ d.addCallback(check_present)
+ return d
+
+
+class TestSlaveWithLibrarian(TrialTestCase):
+ """Tests that need more of Launchpad to run."""
+
+ layer = TwistedLaunchpadZopelessLayer
+
+ def setUp(self):
+ super(TestSlaveWithLibrarian, self)
+ self.slave_helper = SlaveTestHelpers()
+ self.slave_helper.setUp()
+ self.addCleanup(self.slave_helper.cleanUp)
+ self.factory = LaunchpadObjectFactory()
+ login_as(ANONYMOUS)
+ self.addCleanup(logout)
+
+ def test_ensurepresent_librarian(self):
+ # ensurepresent, when given an http URL for a file will download the
+ # file from that URL and report that the file is present, and it was
+ # downloaded.
+
+ # Use the Librarian because it's a "convenient" web server.
+ lf = self.factory.makeLibraryFileAlias(
+ 'HelloWorld.txt', content="Hello World")
+ self.layer.txn.commit()
+ self.slave_helper.getServerSlave()
+ slave = self.slave_helper.getClientSlave()
+ d = slave.ensurepresent(
+ lf.content.sha1, lf.http_url, "", "")
+ d.addCallback(self.assertEqual, [True, 'Download'])
+ return d
+
+ def test_retrieve_files_from_filecache(self):
+ # Files that are present on the slave can be downloaded with a
+ # filename made from the sha1 of the content underneath the
+ # 'filecache' directory.
+ content = "Hello World"
+ lf = self.factory.makeLibraryFileAlias(
+ 'HelloWorld.txt', content=content)
+ self.layer.txn.commit()
+ expected_url = '%s/filecache/%s' % (
+ self.slave_helper.BASE_URL, lf.content.sha1)
+ self.slave_helper.getServerSlave()
+ slave = self.slave_helper.getClientSlave()
+ d = slave.ensurepresent(
+ lf.content.sha1, lf.http_url, "", "")
+ def check_file(ignored):
+ d = getPage(expected_url.encode('utf8'))
+ return d.addCallback(self.assertEqual, content)
+ return d.addCallback(check_file)
=== modified file 'lib/lp/code/model/recipebuilder.py'
--- lib/lp/code/model/recipebuilder.py 2010-08-20 20:31:18 +0000
+++ lib/lp/code/model/recipebuilder.py 2010-09-21 18:41:34 +0000
@@ -122,33 +122,36 @@
if chroot is None:
raise CannotBuild("Unable to find a chroot for %s" %
distroarchseries.displayname)
- self._builder.slave.cacheFile(logger, chroot)
-
- # Generate a string which can be used to cross-check when obtaining
- # results so we know we are referring to the right database object in
- # subsequent runs.
- buildid = "%s-%s" % (self.build.id, build_queue_id)
- cookie = self.buildfarmjob.generateSlaveBuildCookie()
- chroot_sha1 = chroot.content.sha1
- logger.debug(
- "Initiating build %s on %s" % (buildid, self._builder.url))
-
- args = self._extraBuildArgs(distroarchseries, logger)
- status, info = self._builder.slave.build(
- cookie, "sourcepackagerecipe", chroot_sha1, {}, args)
- message = """%s (%s):
- ***** RESULT *****
- %s
- %s: %s
- ******************
- """ % (
- self._builder.name,
- self._builder.url,
- args,
- status,
- info,
- )
- logger.info(message)
+ d = self._builder.slave.cacheFile(logger, chroot)
+
+ def got_cache_file(ignored):
+ # Generate a string which can be used to cross-check when obtaining
+ # results so we know we are referring to the right database object in
+ # subsequent runs.
+ buildid = "%s-%s" % (self.build.id, build_queue_id)
+ cookie = self.buildfarmjob.generateSlaveBuildCookie()
+ chroot_sha1 = chroot.content.sha1
+ logger.debug(
+ "Initiating build %s on %s" % (buildid, self._builder.url))
+
+ args = self._extraBuildArgs(distroarchseries, logger)
+ # XXX: Soon to be async
+ status, info = self._builder.slave.build(
+ cookie, "sourcepackagerecipe", chroot_sha1, {}, args)
+ message = """%s (%s):
+ ***** RESULT *****
+ %s
+ %s: %s
+ ******************
+ """ % (
+ self._builder.name,
+ self._builder.url,
+ args,
+ status,
+ info,
+ )
+ logger.info(message)
+ return d.addCallback(got_cache_file)
def verifyBuildRequest(self, logger):
"""Assert some pre-build checks.
=== modified file 'lib/lp/soyuz/model/binarypackagebuildbehavior.py'
--- lib/lp/soyuz/model/binarypackagebuildbehavior.py 2010-09-21 18:41:33 +0000
+++ lib/lp/soyuz/model/binarypackagebuildbehavior.py 2010-09-21 18:41:34 +0000
@@ -11,6 +11,7 @@
'BinaryPackageBuildBehavior',
]
+from twisted.internet import defer
from zope.interface import implements
from canonical.launchpad.webapp import urlappend
@@ -38,56 +39,66 @@
logger.info("startBuild(%s, %s, %s, %s)", self._builder.url,
spr.name, spr.version, self.build.pocket.title)
- def dispatchBuildToSlave(self, build_queue_id, logger):
- """See `IBuildFarmJobBehavior`."""
-
- # Start the binary package build on the slave builder. First
- # we send the chroot.
- chroot = self.build.distro_arch_series.getChroot()
- self._builder.slave.cacheFile(logger, chroot)
-
+ def _buildFilemapStructure(self, ignored, logger):
# Build filemap structure with the files required in this build
# and send them to the slave.
# If the build is private we tell the slave to get the files from the
# archive instead of the librarian because the slaves cannot
# access the restricted librarian.
+ dl = []
private = self.build.archive.private
if private:
- self._cachePrivateSourceOnSlave(logger)
+ dl.extend(self._cachePrivateSourceOnSlave(logger))
filemap = {}
for source_file in self.build.source_package_release.files:
lfa = source_file.libraryfile
filemap[lfa.filename] = lfa.content.sha1
if not private:
- self._builder.slave.cacheFile(logger, source_file.libraryfile)
-
- # Generate a string which can be used to cross-check when obtaining
- # results so we know we are referring to the right database object in
- # subsequent runs.
- buildid = "%s-%s" % (self.build.id, build_queue_id)
- cookie = self.buildfarmjob.generateSlaveBuildCookie()
- chroot_sha1 = chroot.content.sha1
- logger.debug(
- "Initiating build %s on %s" % (buildid, self._builder.url))
-
- args = self._extraBuildArgs(self.build)
- status, info = self._builder.slave.build(
- cookie, "binarypackage", chroot_sha1, filemap, args)
- message = """%s (%s):
- ***** RESULT *****
- %s
- %s
- %s: %s
- ******************
- """ % (
- self._builder.name,
- self._builder.url,
- filemap,
- args,
- status,
- info,
- )
- logger.info(message)
+ dl.append(
+ self._builder.slave.cacheFile(
+ logger, source_file.libraryfile))
+ d = defer.gatherResults(dl)
+ return d.addCallback(lambda ignored: filemap)
+
+ def dispatchBuildToSlave(self, build_queue_id, logger):
+ """See `IBuildFarmJobBehavior`."""
+
+ # Start the binary package build on the slave builder. First
+ # we send the chroot.
+ chroot = self.build.distro_arch_series.getChroot()
+ d = self._builder.slave.cacheFile(logger, chroot)
+ d.addCallback(self._buildFilemapStructure, logger)
+
+ def got_filemap(filemap):
+ # Generate a string which can be used to cross-check when obtaining
+ # results so we know we are referring to the right database object in
+ # subsequent runs.
+ buildid = "%s-%s" % (self.build.id, build_queue_id)
+ cookie = self.buildfarmjob.generateSlaveBuildCookie()
+ chroot_sha1 = chroot.content.sha1
+ logger.debug(
+ "Initiating build %s on %s" % (buildid, self._builder.url))
+
+ args = self._extraBuildArgs(self.build)
+ status, info = self._builder.slave.build(
+ cookie, "binarypackage", chroot_sha1, filemap, args)
+ message = """%s (%s):
+ ***** RESULT *****
+ %s
+ %s
+ %s: %s
+ ******************
+ """ % (
+ self._builder.name,
+ self._builder.url,
+ filemap,
+ args,
+ status,
+ info,
+ )
+ logger.info(message)
+
+ return d.addCallback(got_filemap)
def verifyBuildRequest(self, logger):
"""Assert some pre-build checks.
@@ -154,6 +165,8 @@
"""Ask the slave to download source files for a private build.
:param logger: A logger used for providing debug information.
+ :return: A list of Deferreds, each of which represents a request
+ to cache a file.
"""
# The URL to the file in the archive consists of these parts:
# archive_url / makePoolPath() / filename
@@ -165,6 +178,7 @@
archive = self.build.archive
archive_url = archive.archive_url
component_name = self.build.current_component.name
+ dl = []
for source_file in self.build.source_package_release.files:
file_name = source_file.libraryfile.filename
sha1 = source_file.libraryfile.content.sha1
@@ -175,8 +189,10 @@
logger.debug("Asking builder on %s to ensure it has file %s "
"(%s, %s)" % (
self._builder.url, file_name, url, sha1))
- self._builder.slave.sendFileToSlave(
- sha1, url, "buildd", archive.buildd_secret)
+ dl.append(
+ self._builder.slave.sendFileToSlave(
+ sha1, url, "buildd", archive.buildd_secret))
+ return dl
def _extraBuildArgs(self, build):
"""
=== modified file 'lib/lp/soyuz/tests/soyuzbuilddhelpers.py'
--- lib/lp/soyuz/tests/soyuzbuilddhelpers.py 2010-09-21 18:41:33 +0000
+++ lib/lp/soyuz/tests/soyuzbuilddhelpers.py 2010-09-21 18:41:34 +0000
@@ -19,6 +19,8 @@
from StringIO import StringIO
import xmlrpclib
+from twisted.internet import defer
+
from lp.buildmaster.interfaces.builder import CannotFetchFile
from lp.buildmaster.model.builder import (
rescueBuilderIfLost,
@@ -101,7 +103,7 @@
def ensurepresent(self, sha1, url, user=None, password=None):
self.call_log.append(('ensurepresent', url, user, password))
- return True, None
+ return defer.succeed((True, None))
def build(self, buildid, buildtype, chroot, filemap, args):
self.call_log.append(
@@ -125,9 +127,11 @@
def sendFileToSlave(self, sha1, url, username="", password=""):
self.call_log.append('sendFileToSlave')
- present, info = self.ensurepresent(sha1, url, username, password)
- if not present:
- raise CannotFetchFile(url, info)
+ d = self.ensurepresent(sha1, url, username, password)
+ def check_present((present, info)):
+ if not present:
+ raise CannotFetchFile(url, info)
+ return d.addCallback(check_present)
def cacheFile(self, logger, libraryfilealias):
self.call_log.append('cacheFile')
=== modified file 'lib/lp/testing/tests/test_factory.py'
--- lib/lp/testing/tests/test_factory.py 2010-09-21 18:41:33 +0000
+++ lib/lp/testing/tests/test_factory.py 2010-09-21 18:41:34 +0000
@@ -113,14 +113,6 @@
status=BuildStatus.FULLYBUILT)
self.assertEqual(BuildStatus.FULLYBUILT, bpb.status)
-<<<<<<< TREE
- def test_makeBinaryPackageBuild_can_be_queued(self):
- build = self.factory.makeBinaryPackageBuild()
- # Just check that makeBinaryPackageBuild returns a build that can be
- # queued.
- build.queueBuild()
-
-=======
def test_makeBinaryPackageBuild_uses_pocket(self):
bpb = self.factory.makeBinaryPackageBuild(
pocket=PackagePublishingPocket.UPDATES)
@@ -132,7 +124,6 @@
# queued.
build.queueBuild()
->>>>>>> MERGE-SOURCE
# makeBinaryPackageName
def test_makeBinaryPackageName_returns_proxied_IBinaryPackageName(self):
binarypackagename = self.factory.makeBinaryPackageName()
=== modified file 'lib/lp/translations/model/translationtemplatesbuildbehavior.py'
--- lib/lp/translations/model/translationtemplatesbuildbehavior.py 2010-08-20 20:31:18 +0000
+++ lib/lp/translations/model/translationtemplatesbuildbehavior.py 2010-09-21 18:41:34 +0000
@@ -41,16 +41,18 @@
"""See `IBuildFarmJobBehavior`."""
chroot = self._getChroot()
chroot_sha1 = chroot.content.sha1
- self._builder.slave.cacheFile(logger, chroot)
- cookie = self.buildfarmjob.generateSlaveBuildCookie()
-
- args = {'arch_tag': self._getDistroArchSeries().architecturetag}
- args.update(self.buildfarmjob.metadata)
-
- filemap = {}
-
- self._builder.slave.build(
- cookie, self.build_type, chroot_sha1, filemap, args)
+ d = self._builder.slave.cacheFile(logger, chroot)
+ def got_cache_file(ignored):
+ cookie = self.buildfarmjob.generateSlaveBuildCookie()
+
+ args = {'arch_tag': self._getDistroArchSeries().architecturetag}
+ args.update(self.buildfarmjob.metadata)
+
+ filemap = {}
+
+ return self._builder.slave.build(
+ cookie, self.build_type, chroot_sha1, filemap, args)
+ return d.addCallback(got_cache_file)
def _getChroot(self):
return self._getDistroArchSeries().getChroot()
Follow ups