← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~wgrant/launchpad/antibfjo-4-use into lp:launchpad

 

William Grant has proposed merging lp:~wgrant/launchpad/antibfjo-4-use into lp:launchpad with lp:~wgrant/launchpad/antibfjo-3-branch-deletion as a prerequisite.

Commit message:
Adjust most of the BuildQueue lookup code to use the new BQ.build_farm_job rather than BQ.job.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~wgrant/launchpad/antibfjo-4-use/+merge/195891

IBuildFarmJobOld and its implementations (BuildPackageJob, SourcePackageRecipeBuildJob, TranslationTemplatesBuildJob) are finally being replaced with an FK from BuildQueue to BuildFarmJob. Additionally, the two fields of Job that are used by BuildQueue are being inlined, and the FK to Job dropped, for performance reasons.

This branch adjust about half of the relevant code to use the new columns rather than the old ones. All the old columns are still set.
-- 
https://code.launchpad.net/~wgrant/launchpad/antibfjo-4-use/+merge/195891
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/antibfjo-4-use into lp:launchpad.
=== modified file 'lib/lp/buildmaster/browser/builder.py'
--- lib/lp/buildmaster/browser/builder.py	2013-11-15 06:36:55 +0000
+++ lib/lp/buildmaster/browser/builder.py	2013-11-20 00:22:47 +0000
@@ -160,7 +160,7 @@
             cache = get_property_cache(builder)
             cache.currentjob = queue_builders.get(builder.id, None)
         # Prefetch the jobs' data.
-        BuildQueue.preloadSpecificJobData(queues)
+        BuildQueue.preloadSpecificBuild(queues)
 
         return builders
 

=== modified file 'lib/lp/buildmaster/interfaces/buildqueue.py'
--- lib/lp/buildmaster/interfaces/buildqueue.py	2013-11-20 00:22:47 +0000
+++ lib/lp/buildmaster/interfaces/buildqueue.py	2013-11-20 00:22:47 +0000
@@ -30,7 +30,10 @@
     BuildQueueStatus,
     )
 from lp.buildmaster.interfaces.builder import IBuilder
-from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJob
+from lp.buildmaster.interfaces.buildfarmjob import (
+    IBuildFarmJob,
+    IBuildFarmJobOld,
+    )
 from lp.services.job.interfaces.job import IJob
 from lp.soyuz.interfaces.processor import IProcessor
 
@@ -99,7 +102,10 @@
         """Set this queue item to a 'building' state."""
 
     def suspend():
-        """Suspend this job, removing it from the active queue."""
+        """Suspend this waiting job, removing it from the active queue."""
+
+    def resume():
+        """Resume this suspended job, adding it to the active queue."""
 
     def reset():
         """Reset this job, so it can be re-dispatched."""
@@ -107,9 +113,9 @@
     def cancel():
         """Cancel this job, it will not be re-dispatched."""
 
-    specific_job = Reference(
-        IBuildFarmJob, title=_("Job"),
-        description=_("Data and operations common to all build farm jobs."))
+    specific_old_job = Reference(
+        IBuildFarmJobOld, title=_("Old build farm job"),
+        description=_("Old IBuildQueue <-> IBuildFarmJob link object."))
 
     specific_build = Reference(
         IBuildFarmJob, title=_("Build farm job"),

=== modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
--- lib/lp/buildmaster/model/buildfarmjob.py	2013-11-20 00:22:47 +0000
+++ lib/lp/buildmaster/model/buildfarmjob.py	2013-11-20 00:22:47 +0000
@@ -149,7 +149,8 @@
     @property
     def buildqueue_record(self):
         """See `IBuildFarmJob`."""
-        return None
+        return Store.of(self).find(
+            BuildQueue, _build_farm_job_id=self.build_farm_job_id).one()
 
     @property
     def is_private(self):

=== modified file 'lib/lp/buildmaster/model/buildqueue.py'
--- lib/lp/buildmaster/model/buildqueue.py	2013-11-20 00:22:47 +0000
+++ lib/lp/buildmaster/model/buildqueue.py	2013-11-20 00:22:47 +0000
@@ -28,8 +28,12 @@
     )
 from storm.references import Reference
 from storm.store import Store
-from zope.component import getSiteManager
+from zope.component import (
+    getSiteManager,
+    getUtility,
+    )
 from zope.interface import implements
+from zope.security.proxy import removeSecurityProxy
 
 from lp.buildmaster.enums import (
     BuildFarmJobType,
@@ -107,7 +111,7 @@
             job_type=job_type, job=job, virtualized=virtualized,
             processor=processor, estimated_duration=estimated_duration,
             lastscore=lastscore)
-        if lastscore is None and self.specific_job is not None:
+        if lastscore is None and self.specific_build is not None:
             self.score()
 
     _build_farm_job_id = Int(name='build_farm_job')
@@ -127,40 +131,40 @@
     processor = ForeignKey(dbName='processor', foreignKey='Processor')
     virtualized = BoolCol(dbName='virtualized')
 
-    @property
+    @cachedproperty
     def specific_build(self):
-        return self.specific_job.build
+        """See `IBuildQueue`."""
+        specific_source = specific_build_farm_job_sources()[self.job_type]
+        return specific_source.getByBuildFarmJob(self._build_farm_job)
+
+    def _clear_specific_build_cache(self):
+        del get_property_cache(self).specific_build
 
     @cachedproperty
-    def specific_job(self):
+    def specific_old_job(self):
         """See `IBuildQueue`."""
         specific_class = specific_job_classes()[self.job_type]
         return specific_class.getByJob(self.job)
 
-    def _clear_specific_job_cache(self):
-        del get_property_cache(self).specific_job
+    def _clear_specific_old_job_cache(self):
+        del get_property_cache(self).specific_old_job
 
     @staticmethod
-    def preloadSpecificJobData(queues):
+    def preloadSpecificBuild(queues):
+        from lp.buildmaster.model.buildfarmjob import BuildFarmJob
+        load_related(BuildFarmJob, queues, ['_build_farm_job_id'])
+        load_related(Job, queues, ['jobID'])
+        bfj_to_bq = dict(
+            (removeSecurityProxy(bq)._build_farm_job, bq)
+            for bq in queues)
         key = attrgetter('job_type')
         for job_type, grouped_queues in groupby(queues, key=key):
-            specific_class = specific_job_classes()[job_type]
-            queue_subset = list(grouped_queues)
-            job_subset = load_related(Job, queue_subset, ['jobID'])
-            # We need to preload the build farm jobs early to avoid
-            # the call to _set_build_farm_job to look up BuildFarmBuildJobs
-            # one by one.
-            specific_class.preloadBuildFarmJobs(job_subset)
-            specific_jobs = list(specific_class.getByJobs(job_subset))
-            if len(specific_jobs) == 0:
-                continue
-            specific_class.preloadJobsData(specific_jobs)
-            specific_jobs_dict = dict(
-                (specific_job.job, specific_job)
-                    for specific_job in specific_jobs)
-            for queue in queue_subset:
-                cache = get_property_cache(queue)
-                cache.specific_job = specific_jobs_dict[queue.job]
+            source = getUtility(ISpecificBuildFarmJobSource, job_type.name)
+            builds = source.getByBuildFarmJobs(
+                [bq._build_farm_job for bq in grouped_queues])
+            for build in builds:
+                bq = bfj_to_bq[removeSecurityProxy(build).build_farm_job]
+                get_property_cache(bq).specific_build = build
 
     @property
     def date_started(self):
@@ -177,17 +181,18 @@
             return self._now() - date_started
 
     def destroySelf(self):
-        """Remove this record and associated job/specific_job."""
+        """Remove this record and associated job/specific_old_job."""
         job = self.job
-        specific_job = self.specific_job
+        specific_old_job = self.specific_old_job
         builder = self.builder
         Store.of(self).remove(self)
-        specific_job.cleanUp()
+        specific_old_job.cleanUp()
         Store.of(self).flush()
         job.destroySelf()
         if builder is not None:
             del get_property_cache(builder).currentjob
-        self._clear_specific_job_cache()
+        self._clear_specific_old_job_cache()
+        self._clear_specific_build_cache()
 
     def manualScore(self, value):
         """See `IBuildQueue`."""
@@ -220,6 +225,14 @@
         self.job.suspend()
         self.status = BuildQueueStatus.SUSPENDED
 
+    def resume(self):
+        """See `IBuildQueue`."""
+        if self.status != BuildQueueStatus.SUSPENDED:
+            raise AssertionError("Only suspended jobs can be resumed.")
+        if self.job is not None:
+            self.job.resume()
+        self.status = BuildQueueStatus.WAITING
+
     def reset(self):
         """See `IBuildQueue`."""
         builder = self.builder

=== modified file 'lib/lp/buildmaster/tests/test_buildqueue.py'
--- lib/lp/buildmaster/tests/test_buildqueue.py	2013-11-14 10:52:25 +0000
+++ lib/lp/buildmaster/tests/test_buildqueue.py	2013-11-20 00:22:47 +0000
@@ -88,17 +88,16 @@
         super(TestBuildCancellation, self).setUp()
         self.builder = self.factory.makeBuilder()
 
-    def assertCancelled(self, build, buildqueue):
+    def assertCancelled(self, build, bq):
         self.assertEqual(BuildStatus.CANCELLED, build.status)
-        self.assertIs(None, buildqueue.specific_job)
-        self.assertRaises(SQLObjectNotFound, BuildQueue.get, buildqueue.id)
+        self.assertIs(None, bq.specific_old_job)
+        self.assertRaises(SQLObjectNotFound, BuildQueue.get, bq.id)
 
     def test_binarypackagebuild_cancel(self):
         build = self.factory.makeBinaryPackageBuild()
         bq = build.queueBuild()
         bq.markAsBuilding(self.builder)
         bq.cancel()
-
         self.assertCancelled(build, bq)
 
     def test_recipebuild_cancel(self):
@@ -106,7 +105,6 @@
         bq = build.queueBuild()
         bq.markAsBuilding(self.builder)
         bq.cancel()
-
         self.assertCancelled(build, bq)
 
 
@@ -177,10 +175,10 @@
 
         # The 'specific_job' object associated with this `BuildQueue`
         # instance is of type `BuildPackageJob`.
-        self.assertTrue(bq.specific_job is not None)
+        self.assertTrue(bq.specific_old_job is not None)
         self.assertEqual(
-            BuildPackageJob, bq.specific_job.__class__,
-            "The 'specific_job' object associated with this `BuildQueue` "
+            BuildPackageJob, bq.specific_old_job.__class__,
+            "The 'specific_old_job' object associated with this `BuildQueue` "
             "instance is of type `BuildPackageJob`")
 
     def test_OtherTypeClasses(self):

=== modified file 'lib/lp/buildmaster/tests/test_manager.py'
--- lib/lp/buildmaster/tests/test_manager.py	2013-11-20 00:22:47 +0000
+++ lib/lp/buildmaster/tests/test_manager.py	2013-11-20 00:22:47 +0000
@@ -364,8 +364,8 @@
         builder = getUtility(IBuilderSet)[scanner.builder_name]
 
         builder.failure_count = builder_count
-        naked_job = removeSecurityProxy(builder.currentjob.specific_job)
-        naked_job.build.failure_count = job_count
+        naked_build = removeSecurityProxy(builder.currentjob.specific_build)
+        naked_build.failure_count = job_count
         # The _scanFailed() calls abort, so make sure our existing
         # failure counts are persisted.
         transaction.commit()

=== modified file 'lib/lp/code/model/sourcepackagerecipebuild.py'
--- lib/lp/code/model/sourcepackagerecipebuild.py	2013-11-12 07:39:51 +0000
+++ lib/lp/code/model/sourcepackagerecipebuild.py	2013-11-20 00:22:47 +0000
@@ -45,7 +45,6 @@
     BuildFarmJobOld,
     SpecificBuildFarmJobSourceMixin,
     )
-from lp.buildmaster.model.buildqueue import BuildQueue
 from lp.buildmaster.model.packagebuild import PackageBuildMixin
 from lp.code.errors import (
     BuildAlreadyPending,
@@ -180,16 +179,6 @@
         return str(self.manifest.getRecipe())
 
     @property
-    def buildqueue_record(self):
-        """See `IBuildFarmJob`."""
-        store = Store.of(self)
-        results = store.find(
-            BuildQueue,
-            SourcePackageRecipeBuildJob.job == BuildQueue.jobID,
-            SourcePackageRecipeBuildJob.build == self.id)
-        return results.one()
-
-    @property
     def source_package_release(self):
         """See `ISourcePackageRecipeBuild`."""
         return Store.of(self).find(
@@ -279,24 +268,15 @@
                     builds.append(build)
         return builds
 
-    def _unqueueBuild(self):
-        """Remove the build's queue and job."""
-        store = Store.of(self)
-        if self.buildqueue_record is not None:
-            job = self.buildqueue_record.job
-            store.remove(self.buildqueue_record)
-            store.find(
-                SourcePackageRecipeBuildJob,
-                SourcePackageRecipeBuildJob.build == self.id).remove()
-            store.remove(job)
-
     def cancelBuild(self):
         """See `ISourcePackageRecipeBuild.`"""
-        self._unqueueBuild()
         self.updateStatus(BuildStatus.SUPERSEDED)
+        if self.buildqueue_record is not None:
+            self.buildqueue_record.destroySelf()
 
     def destroySelf(self):
-        self._unqueueBuild()
+        if self.buildqueue_record is not None:
+            self.buildqueue_record.destroySelf()
         store = Store.of(self)
         releases = store.find(
             SourcePackageRelease,

=== modified file 'lib/lp/code/model/tests/test_sourcepackagerecipe.py'
--- lib/lp/code/model/tests/test_sourcepackagerecipe.py	2013-11-14 07:36:26 +0000
+++ lib/lp/code/model/tests/test_sourcepackagerecipe.py	2013-11-20 00:22:47 +0000
@@ -346,7 +346,10 @@
         job = build_job.job
         self.assertProvides(job, IJob)
         self.assertEquals(job.status, JobStatus.WAITING)
-        build_queue = store.find(BuildQueue, BuildQueue.job == job.id).one()
+        build_queue = store.find(
+            BuildQueue,
+            BuildQueue._build_farm_job_id ==
+                removeSecurityProxy(build).build_farm_job_id).one()
         self.assertProvides(build_queue, IBuildQueue)
         self.assertTrue(build_queue.virtualized)
 

=== modified file 'lib/lp/code/model/tests/test_sourcepackagerecipebuild.py'
--- lib/lp/code/model/tests/test_sourcepackagerecipebuild.py	2013-11-20 00:22:47 +0000
+++ lib/lp/code/model/tests/test_sourcepackagerecipebuild.py	2013-11-20 00:22:47 +0000
@@ -105,7 +105,8 @@
         self.assertProvides(bq, IBuildQueue)
         self.assertEqual(
             spb.build_farm_job, removeSecurityProxy(bq)._build_farm_job)
-        self.assertProvides(bq.specific_job, ISourcePackageRecipeBuildJob)
+        self.assertEqual(spb, bq.specific_build)
+        self.assertProvides(bq.specific_old_job, ISourcePackageRecipeBuildJob)
         self.assertEqual(True, bq.virtualized)
 
         # The processor for SourcePackageRecipeBuilds should not be None.

=== modified file 'lib/lp/registry/model/sourcepackage.py'
--- lib/lp/registry/model/sourcepackage.py	2013-06-20 05:50:00 +0000
+++ lib/lp/registry/model/sourcepackage.py	2013-11-20 00:22:47 +0000
@@ -642,11 +642,10 @@
             BuildStatus.UPLOADING,
             ]:
             orderBy = ["-BuildQueue.lastscore"]
-            clauseTables.append('BuildPackageJob')
+            clauseTables.append('BuildQueue')
             condition_clauses.append(
-                'BuildPackageJob.build = BinaryPackageBuild.id')
-            clauseTables.append('BuildQueue')
-            condition_clauses.append('BuildQueue.job = BuildPackageJob.job')
+                'BuildQueue.build_farm_job = '
+                'BinaryPackageBuild.build_farm_job')
         elif build_state == BuildStatus.SUPERSEDED or build_state is None:
             orderBy = [Desc("BinaryPackageBuild.date_created")]
         else:

=== modified file 'lib/lp/soyuz/browser/build.py'
--- lib/lp/soyuz/browser/build.py	2013-03-27 03:37:42 +0000
+++ lib/lp/soyuz/browser/build.py	2013-11-20 00:22:47 +0000
@@ -478,15 +478,15 @@
         build.id for build in builds if IBinaryPackageBuild.providedBy(build)]
     results = getUtility(IBinaryPackageBuildSet).getQueueEntriesForBuildIDs(
         build_ids)
-    for (buildqueue, _builder, build_job) in results:
-        # Get the build's id, 'buildqueue', 'sourcepackagerelease' and
-        # 'buildlog' (from the result set) respectively.
-        prefetched_data[build_job.build.id] = buildqueue
+    for (buildqueue, _builder) in results:
+        prefetched_data[
+            removeSecurityProxy(buildqueue)._build_farm_job_id] = buildqueue
 
     complete_builds = []
     for build in builds:
         if IBinaryPackageBuild.providedBy(build):
-            buildqueue = prefetched_data.get(build.id)
+            buildqueue = prefetched_data.get(
+                removeSecurityProxy(build).build_farm_job_id)
             complete_builds.append(CompleteBuild(build, buildqueue))
         else:
             complete_builds.append(build)

=== modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
--- lib/lp/soyuz/model/binarypackagebuild.py	2013-11-14 07:56:46 +0000
+++ lib/lp/soyuz/model/binarypackagebuild.py	2013-11-20 00:22:47 +0000
@@ -38,6 +38,7 @@
 from storm.zope import IResultSet
 from zope.component import getUtility
 from zope.interface import implements
+from zope.security.proxy import removeSecurityProxy
 
 from lp.app.browser.tales import DurationFormatterAPI
 from lp.app.errors import NotFoundError
@@ -207,16 +208,6 @@
     source_package_name = Reference(
         source_package_name_id, 'SourcePackageName.id')
 
-    @property
-    def buildqueue_record(self):
-        """See `IBuild`."""
-        store = Store.of(self)
-        results = store.find(
-            BuildQueue,
-            BuildPackageJob.job == BuildQueue.jobID,
-            BuildPackageJob.build == self.id)
-        return results.one()
-
     def _getLatestPublication(self):
         from lp.soyuz.model.publishing import SourcePackagePublishingHistory
         store = Store.of(self)
@@ -1119,10 +1110,10 @@
             BuildStatus.UPLOADING]:
             order_by = [Desc(BuildQueue.lastscore), BinaryPackageBuild.id]
             order_by_table = BuildQueue
-            clauseTables.extend([BuildQueue, BuildPackageJob])
-            condition_clauses.extend([
-                BuildPackageJob.build_id == BinaryPackageBuild.id,
-                BuildPackageJob.job_id == BuildQueue.jobID])
+            clauseTables.append(BuildQueue)
+            condition_clauses.append(
+                BuildQueue._build_farm_job_id ==
+                    BinaryPackageBuild.build_farm_job_id)
         elif status == BuildStatus.SUPERSEDED or status is None:
             order_by = [Desc(BinaryPackageBuild.id)]
         else:
@@ -1270,26 +1261,24 @@
 
     def getByQueueEntry(self, queue_entry):
         """See `IBinaryPackageBuildSet`."""
+        bfj_id = removeSecurityProxy(queue_entry)._build_farm_job_id
         return IStore(BinaryPackageBuild).find(
-            BinaryPackageBuild,
-            BuildPackageJob.build == BinaryPackageBuild.id,
-            BuildPackageJob.job == BuildQueue.jobID,
-            BuildQueue.job == queue_entry.job).one()
+            BinaryPackageBuild, build_farm_job_id=bfj_id).one()
 
     def getQueueEntriesForBuildIDs(self, build_ids):
         """See `IBinaryPackageBuildSet`."""
         origin = (
-            BuildPackageJob,
-            Join(BuildQueue, BuildPackageJob.job == BuildQueue.jobID),
+            BuildQueue,
             Join(
                 BinaryPackageBuild,
-                BuildPackageJob.build == BinaryPackageBuild.id),
+                BuildQueue._build_farm_job_id ==
+                    BinaryPackageBuild.build_farm_job_id),
             LeftJoin(
                 Builder,
                 BuildQueue.builderID == Builder.id),
             )
         return IStore(BinaryPackageBuild).using(*origin).find(
-            (BuildQueue, Builder, BuildPackageJob),
+            (BuildQueue, Builder),
             BinaryPackageBuild.id.is_in(build_ids))
 
     @staticmethod
@@ -1301,11 +1290,9 @@
             PackagePublishingStatus.DELETED,
             )
         return """
-            SELECT TRUE FROM Archive, BinaryPackageBuild, BuildPackageJob,
-                             DistroArchSeries
+            SELECT TRUE FROM Archive, BinaryPackageBuild, DistroArchSeries
             WHERE
-            BuildPackageJob.job = Job.id AND
-            BuildPackageJob.build = BinaryPackageBuild.id AND
+            BinaryPackageBuild.build_farm_job = BuildQueue.build_farm_job AND
             BinaryPackageBuild.distro_arch_series =
                 DistroArchSeries.id AND
             BinaryPackageBuild.archive = Archive.id AND

=== modified file 'lib/lp/soyuz/stories/soyuz/xx-build-record.txt'
--- lib/lp/soyuz/stories/soyuz/xx-build-record.txt	2013-09-27 04:13:23 +0000
+++ lib/lp/soyuz/stories/soyuz/xx-build-record.txt	2013-11-20 00:22:47 +0000
@@ -81,7 +81,7 @@
 question.
 
     >>> login('foo.bar@xxxxxxxxxxxxx')
-    >>> build.buildqueue_record.job.suspend()
+    >>> build.buildqueue_record.suspend()
     >>> logout()
     >>> anon_browser.open(build_url)
     >>> print extract_text(find_main_content(anon_browser.contents))
@@ -101,7 +101,7 @@
 Re-enable the build in order to avoid subsequent test breakage.
 
     >>> login('foo.bar@xxxxxxxxxxxxx')
-    >>> build.buildqueue_record.job.resume()
+    >>> build.buildqueue_record.resume()
     >>> logout()
     >>> anon_browser.open(build_url)
 

=== modified file 'lib/lp/soyuz/tests/test_archive.py'
--- lib/lp/soyuz/tests/test_archive.py	2013-11-20 00:22:47 +0000
+++ lib/lp/soyuz/tests/test_archive.py	2013-11-20 00:22:47 +0000
@@ -323,10 +323,10 @@
         # Return the count for archive build jobs with the given status.
         query = """
             SELECT COUNT(BuildQueue.id)
-            FROM BinaryPackageBuild, BuildPackageJob, BuildQueue
+            FROM BinaryPackageBuild, BuildQueue
             WHERE
-                BuildPackageJob.build = BinaryPackageBuild.id
-                AND BuildPackageJob.job = BuildQueue.job
+                BinaryPackageBuild.build_farm_job =
+                    BuildQueue.build_farm_job
                 AND BinaryPackageBuild.archive = %s
                 AND BinaryPackageBuild.status = %s
                 AND BuildQueue.status = %s;

=== modified file 'lib/lp/soyuz/tests/test_binarypackagebuild.py'
--- lib/lp/soyuz/tests/test_binarypackagebuild.py	2013-11-20 00:22:47 +0000
+++ lib/lp/soyuz/tests/test_binarypackagebuild.py	2013-11-20 00:22:47 +0000
@@ -83,7 +83,8 @@
         self.assertProvides(bq, IBuildQueue)
         self.assertEqual(
             self.build.build_farm_job, removeSecurityProxy(bq)._build_farm_job)
-        self.assertProvides(bq.specific_job, IBuildPackageJob)
+        self.assertEqual(self.build, bq.specific_build)
+        self.assertProvides(bq.specific_old_job, IBuildPackageJob)
         self.assertEqual(self.build.is_virtualized, bq.virtualized)
         self.assertIsNotNone(bq.processor)
         self.assertEqual(bq, self.build.buildqueue_record)

=== modified file 'lib/lp/soyuz/tests/test_binarypackagebuildbehavior.py'
--- lib/lp/soyuz/tests/test_binarypackagebuildbehavior.py	2013-11-12 06:03:14 +0000
+++ lib/lp/soyuz/tests/test_binarypackagebuildbehavior.py	2013-11-20 00:22:47 +0000
@@ -18,7 +18,10 @@
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
 
-from lp.buildmaster.enums import BuildStatus
+from lp.buildmaster.enums import (
+    BuildQueueStatus,
+    BuildStatus,
+    )
 from lp.buildmaster.interactor import (
     BuilderInteractor,
     extract_vitals_from_db,
@@ -391,8 +394,8 @@
                 self.builder.failnotes)
             self.assertIs(None, self.candidate.builder)
             self.assertEqual(BuildStatus.NEEDSBUILD, self.build.status)
-            job = self.candidate.specific_job.job
-            self.assertEqual(JobStatus.WAITING, job.status)
+            self.assertEqual(BuildQueueStatus.WAITING, self.candidate.status)
+            self.assertEqual(JobStatus.WAITING, self.candidate.job.status)
 
         d = self.updateBuild(
             self.candidate, WaitingSlave('BuildStatus.BUILDERFAIL'))
@@ -451,8 +454,8 @@
             self.assertIs(None, self.candidate.date_started)
             self.assertEqual(score, self.candidate.lastscore)
             self.assertEqual(BuildStatus.NEEDSBUILD, self.build.status)
-            job = self.candidate.specific_job.job
-            self.assertEqual(JobStatus.WAITING, job.status)
+            self.assertEqual(BuildQueueStatus.WAITING, self.candidate.status)
+            self.assertEqual(JobStatus.WAITING, self.candidate.job.status)
 
         d = self.updateBuild(
             self.candidate, WaitingSlave('BuildStatus.GIVENBACK'))

=== modified file 'lib/lp/soyuz/tests/test_buildpackagejob.py'
--- lib/lp/soyuz/tests/test_buildpackagejob.py	2013-11-15 06:04:17 +0000
+++ lib/lp/soyuz/tests/test_buildpackagejob.py	2013-11-20 00:22:47 +0000
@@ -174,5 +174,5 @@
     def test_providesInterfaces(self):
         # Ensure that a BuildPackageJob generates an appropriate cookie.
         build, bq = find_job(self, 'gcc', '386')
-        build_farm_job = bq.specific_job
+        build_farm_job = bq.specific_old_job
         self.assertProvides(build_farm_job, IBuildPackageJob)

=== modified file 'lib/lp/translations/model/translationtemplatesbuildbehavior.py'
--- lib/lp/translations/model/translationtemplatesbuildbehavior.py	2013-11-12 06:03:14 +0000
+++ lib/lp/translations/model/translationtemplatesbuildbehavior.py	2013-11-20 00:22:47 +0000
@@ -133,7 +133,7 @@
         logger.info(
             "Processing finished %s build %s (%s) from builder %s" % (
             status, self.getBuildCookie(),
-            queue_item.specific_job.branch.bzr_identity,
+            queue_item.specific_build.branch.bzr_identity,
             queue_item.builder.name))
 
         if status == 'OK':
@@ -161,7 +161,7 @@
                         logger.debug(
                             "Uploading translation templates tarball.")
                         self._uploadTarball(
-                            queue_item.specific_job.branch, tarball, logger)
+                            queue_item.specific_build.branch, tarball, logger)
                         logger.debug("Upload complete.")
                 finally:
                     self.build.updateStatus(BuildStatus.FULLYBUILT)

=== modified file 'lib/lp/translations/tests/test_translationtemplatesbuild.py'
--- lib/lp/translations/tests/test_translationtemplatesbuild.py	2013-11-20 00:22:47 +0000
+++ lib/lp/translations/tests/test_translationtemplatesbuild.py	2013-11-20 00:22:47 +0000
@@ -123,7 +123,7 @@
     def test_queueBuild(self):
         build = self.factory.makeTranslationTemplatesBuild()
         bq = build.queueBuild()
-        self.assertEqual(build, bq.specific_job.build)
+        self.assertEqual(build, bq.specific_old_job.build)
         self.assertEqual(build, bq.specific_build)
         self.assertEqual(
             build.build_farm_job, removeSecurityProxy(bq)._build_farm_job)
@@ -132,7 +132,7 @@
             ubuntu.currentseries.nominatedarchindep.processor, bq.processor)
 
         # A job is created with the branch URL in its metadata.
-        metadata = removeSecurityProxy(bq.specific_job).metadata
+        metadata = removeSecurityProxy(bq.specific_old_job).metadata
         self.assertIn('branch_url', metadata)
         url = metadata['branch_url']
         head = 'http://'

=== modified file 'lib/lp/translations/tests/test_translationtemplatesbuildbehavior.py'
--- lib/lp/translations/tests/test_translationtemplatesbuildbehavior.py	2013-11-14 09:46:03 +0000
+++ lib/lp/translations/tests/test_translationtemplatesbuildbehavior.py	2013-11-20 00:22:47 +0000
@@ -42,13 +42,13 @@
 class FakeBuildQueue:
     """Pretend `BuildQueue`."""
 
-    def __init__(self, behavior, bfjo):
+    def __init__(self, behavior):
         """Pretend to be a BuildQueue item for the given build behavior.
 
         Copies its builder from the behavior object.
         """
         self.builder = behavior._builder
-        self.specific_job = bfjo
+        self.specific_build = behavior.build
         self.date_started = datetime.datetime.now(pytz.UTC)
         self.destroySelf = FakeMethod()
 
@@ -56,8 +56,7 @@
 class MakeBehaviorMixin(object):
     """Provide common test methods."""
 
-    def makeBehavior(self, branch=None, use_fake_chroot=True, want_bfjo=False,
-                     **kwargs):
+    def makeBehavior(self, branch=None, use_fake_chroot=True, **kwargs):
         """Create a TranslationTemplatesBuildBehavior.
 
         Anything that might communicate with build slaves and such
@@ -71,11 +70,7 @@
             lf = self.factory.makeLibraryFileAlias()
             self.layer.txn.commit()
             behavior._getChroot = lambda: lf
-        if want_bfjo:
-            bq = build.queueBuild()
-            return behavior, bq.specific_job
-        else:
-            return behavior
+        return behavior
 
     def makeProductSeriesWithBranchForTranslation(self):
         productseries = self.factory.makeProductSeries()
@@ -106,20 +101,19 @@
 
     def test_dispatchBuildToSlave_no_chroot_fails(self):
         # dispatchBuildToSlave will fail if the chroot does not exist.
-        behavior, buildqueue_item = self.makeBehavior(
-            use_fake_chroot=False, want_bfjo=True)
+        behavior = self.makeBehavior(use_fake_chroot=False)
         switch_dbuser(config.builddmaster.dbuser)
         self.assertRaises(
-            CannotBuild, behavior.dispatchBuildToSlave, buildqueue_item,
+            CannotBuild, behavior.dispatchBuildToSlave, None,
             logging)
 
     def test_dispatchBuildToSlave(self):
         # dispatchBuildToSlave ultimately causes the slave's build
         # method to be invoked.  The slave receives the URL of the
         # branch it should build from.
-        behavior, buildqueue_item = self.makeBehavior(want_bfjo=True)
+        behavior = self.makeBehavior()
         switch_dbuser(config.builddmaster.dbuser)
-        d = behavior.dispatchBuildToSlave(buildqueue_item, logging)
+        d = behavior.dispatchBuildToSlave(FakeBuildQueue(behavior), logging)
 
         def got_dispatch((status, info)):
             # call_log lives on the mock WaitingSlave and tells us what
@@ -155,8 +149,8 @@
         self.assertEqual(fake_chroot_file, chroot)
 
     def test_readTarball(self):
-        behavior, bfjo = self.makeBehavior(want_bfjo=True)
-        buildqueue = FakeBuildQueue(behavior, bfjo)
+        behavior = self.makeBehavior()
+        buildqueue = FakeBuildQueue(behavior)
         path = behavior.templates_tarball_path
         # Poke the file we're expecting into the mock slave.
         behavior._slave.valid_file_hashes.append(path)
@@ -175,10 +169,10 @@
 
     def test_handleStatus_OK(self):
         # Hopefully, a build will succeed and produce a tarball.
-        behavior, bfjo = self.makeBehavior(
-            filemap={'translation-templates.tar.gz': 'foo'}, want_bfjo=True)
+        behavior = self.makeBehavior(
+            filemap={'translation-templates.tar.gz': 'foo'})
         behavior._uploadTarball = FakeMethod()
-        queue_item = FakeBuildQueue(behavior, bfjo)
+        queue_item = FakeBuildQueue(behavior)
         slave = behavior._slave
 
         d = behavior.dispatchBuildToSlave(queue_item, logging)
@@ -214,10 +208,9 @@
 
     def test_handleStatus_failed(self):
         # Builds may also fail (and produce no tarball).
-        behavior, bfjo = self.makeBehavior(
-            state='BuildStatus.FAILEDTOBUILD', want_bfjo=True)
+        behavior = self.makeBehavior(state='BuildStatus.FAILEDTOBUILD')
         behavior._uploadTarball = FakeMethod()
-        queue_item = FakeBuildQueue(behavior, bfjo)
+        queue_item = FakeBuildQueue(behavior)
         slave = behavior._slave
         d = behavior.dispatchBuildToSlave(queue_item, logging)
 
@@ -248,9 +241,9 @@
     def test_handleStatus_notarball(self):
         # Even if the build status is "OK," absence of a tarball will
         # not faze the Behavior class.
-        behavior, bfjo = self.makeBehavior(want_bfjo=True)
+        behavior = self.makeBehavior()
         behavior._uploadTarball = FakeMethod()
-        queue_item = FakeBuildQueue(behavior, bfjo)
+        queue_item = FakeBuildQueue(behavior)
         slave = behavior._slave
         d = behavior.dispatchBuildToSlave(queue_item, logging)
 
@@ -278,10 +271,9 @@
     def test_handleStatus_uploads(self):
         productseries = self.makeProductSeriesWithBranchForTranslation()
         branch = productseries.branch
-        behavior, bfjo = self.makeBehavior(
-            branch=branch, filemap={'translation-templates.tar.gz': 'foo'},
-            want_bfjo=True)
-        queue_item = FakeBuildQueue(behavior, bfjo)
+        behavior = self.makeBehavior(
+            branch=branch, filemap={'translation-templates.tar.gz': 'foo'})
+        queue_item = FakeBuildQueue(behavior)
         slave = behavior._slave
 
         d = behavior.dispatchBuildToSlave(queue_item, logging)


Follow ups