← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/launchpad/archive-enable-recalculate-virt into lp:launchpad

 

Colin Watson has proposed merging lp:~cjwatson/launchpad/archive-enable-recalculate-virt into lp:launchpad.

Commit message:
Recalculate BinaryPackageBuild.virtualized when enabling an archive.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/archive-enable-recalculate-virt/+merge/269371

Recalculate BinaryPackageBuild.virtualized when enabling an archive.

Similar to https://code.launchpad.net/~cjwatson/launchpad/bpb-recalculate-virt/+merge/269323, but this deals with the case of suspended builds in disabled archives.  Unfortunately Storm's Update (and hence .set()) doesn't support FROM, so I had to write the SQL for the !Archive.require_virtualized case by hand and use store.invalidate.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/archive-enable-recalculate-virt into lp:launchpad.
=== modified file 'lib/lp/soyuz/model/archive.py'
--- lib/lp/soyuz/model/archive.py	2015-07-08 16:05:11 +0000
+++ lib/lp/soyuz/model/archive.py	2015-08-27 14:19:30 +0000
@@ -2022,12 +2022,40 @@
                 AND BinaryPackageBuild.status = %s;
             """, params=(status.value, self.id, BuildStatus.NEEDSBUILD.value))
 
+    def _recalculateBuildVirtualization(self):
+        """Update BinaryPackageBuild.virtualized for this archive."""
+        store = Store.of(self)
+        if self.require_virtualized:
+            # We can avoid the Processor join in this case.
+            builds = store.find(
+                BinaryPackageBuild,
+                BinaryPackageBuild.archive == self,
+                BinaryPackageBuild.status == BuildStatus.NEEDSBUILD)
+            builds.set(virtualized=True)
+        else:
+            store.execute("""
+                UPDATE BinaryPackageBuild
+                SET virtualized = NOT Processor.supports_nonvirtualized
+                FROM Processor
+                WHERE
+                    -- insert self.id here
+                    BinaryPackageBuild.archive = %s
+                    AND BinaryPackageBuild.processor = Processor.id
+                    -- Build is in state BuildStatus.NEEDSBUILD (0)
+                    AND BinaryPackageBuild.status = %s;
+                """, params=(self.id, BuildStatus.NEEDSBUILD.value))
+            store.invalidate()
+
     def enable(self):
         """See `IArchive`."""
         assert self._enabled == False, "This archive is already enabled."
         assert self.is_active, "Deleted archives can't be enabled."
         self._enabled = True
         self._setBuildQueueStatuses(BuildQueueStatus.WAITING)
+        # Suspended builds may have the wrong virtualization setting (due to
+        # changes to either Archive.require_virtualized or
+        # Processor.supports_nonvirtualized) and need to be updated.
+        self._recalculateBuildVirtualization()
 
     def disable(self):
         """See `IArchive`."""

=== modified file 'lib/lp/soyuz/tests/test_archive.py'
--- lib/lp/soyuz/tests/test_archive.py	2015-05-19 02:37:36 +0000
+++ lib/lp/soyuz/tests/test_archive.py	2015-08-27 14:19:30 +0000
@@ -343,6 +343,71 @@
         self.assertNoBuildQueuesHaveStatus(archive, BuildQueueStatus.SUSPENDED)
         self.assertTrue(archive.enabled)
 
+    def test_enableArchive_virt_sets_virtualized(self):
+        # Enabling an archive that requires virtualized builds changes all
+        # its pending builds to be virtualized.
+        archive = self.factory.makeArchive(virtualized=False)
+        other_archive = self.factory.makeArchive(virtualized=False)
+        pending_builds = [
+            self.factory.makeBinaryPackageBuild(
+                archive=archive, status=BuildStatus.NEEDSBUILD)
+            for _ in range(2)]
+        completed_build = self.factory.makeBinaryPackageBuild(
+            archive=archive, status=BuildStatus.FULLYBUILT)
+        other_build = self.factory.makeBinaryPackageBuild(
+            archive=other_archive, status=BuildStatus.NEEDSBUILD)
+        for build in pending_builds + [completed_build, other_build]:
+            self.assertFalse(build.virtualized)
+            build.queueBuild()
+        removeSecurityProxy(archive).disable()
+        removeSecurityProxy(archive).require_virtualized = True
+        removeSecurityProxy(archive).enable()
+        # Pending builds in the just-enabled archive are now virtualized.
+        for build in pending_builds:
+            self.assertTrue(build.virtualized)
+        # Completed builds and builds in other archives are untouched.
+        for build in completed_build, other_build:
+            self.assertFalse(build.virtualized)
+
+    def test_enableArchive_nonvirt_sets_virtualized(self):
+        # Enabling an archive that does not require virtualized builds
+        # changes its pending builds to be virtualized or not depending on
+        # whether their processor supports non-virtualized builds.
+        distroseries = self.factory.makeDistroSeries()
+        archive = self.factory.makeArchive(
+            distribution=distroseries.distribution, virtualized=False)
+        other_archive = self.factory.makeArchive(
+            distribution=distroseries.distribution, virtualized=False)
+        procs = [self.factory.makeProcessor() for _ in range(2)]
+        dases = [
+            self.factory.makeDistroArchSeries(
+                distroseries=distroseries, processor=procs[i])
+            for i in range(2)]
+        pending_builds = [
+            self.factory.makeBinaryPackageBuild(
+                distroarchseries=dases[i], archive=archive,
+                status=BuildStatus.NEEDSBUILD, processor=procs[i])
+            for i in range(2)]
+        completed_build = self.factory.makeBinaryPackageBuild(
+            distroarchseries=dases[0], archive=archive,
+            status=BuildStatus.FULLYBUILT, processor=procs[0])
+        other_build = self.factory.makeBinaryPackageBuild(
+            distroarchseries=dases[0], archive=other_archive,
+            status=BuildStatus.NEEDSBUILD, processor=procs[0])
+        for build in pending_builds + [completed_build, other_build]:
+            self.assertFalse(build.virtualized)
+            build.queueBuild()
+        removeSecurityProxy(archive).disable()
+        procs[0].supports_nonvirtualized = False
+        removeSecurityProxy(archive).enable()
+        # Pending builds in the just-enabled archive are now virtualized iff
+        # their processor does not support non-virtualized builds.
+        self.assertTrue(pending_builds[0].virtualized)
+        self.assertFalse(pending_builds[1].virtualized)
+        # Completed builds and builds in other archives are untouched.
+        for build in completed_build, other_build:
+            self.assertFalse(build.virtualized)
+
     def test_enableArchiveAlreadyEnabled(self):
         # Enabling an already enabled Archive should raise an AssertionError.
         archive = self.factory.makeArchive(enabled=True)


Follow ups