Merge lp:~cjwatson/launchpad/snap-delete-with-build-requests into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18815
Proposed branch: lp:~cjwatson/launchpad/snap-delete-with-build-requests
Merge into: lp:launchpad
Diff against target: 119 lines (+66/-4)
2 files modified
lib/lp/snappy/model/snap.py (+6/-4)
lib/lp/snappy/tests/test_snap.py (+60/-0)
To merge this branch: bzr merge lp:~cjwatson/launchpad/snap-delete-with-build-requests
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+358440@code.launchpad.net

Commit message

Delete associated build requests when deleting a snap.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/snappy/model/snap.py'
--- lib/lp/snappy/model/snap.py 2018-10-09 09:25:19 +0000
+++ lib/lp/snappy/model/snap.py 2018-11-07 15:02:24 +0000
@@ -50,10 +50,7 @@
50 DateTimeFormatterAPI,50 DateTimeFormatterAPI,
51 )51 )
52from lp.app.enums import PRIVATE_INFORMATION_TYPES52from lp.app.enums import PRIVATE_INFORMATION_TYPES
53from lp.app.errors import (53from lp.app.errors import IncompatibleArguments
54 IncompatibleArguments,
55 NotFoundError,
56 )
57from lp.app.interfaces.security import IAuthorization54from lp.app.interfaces.security import IAuthorization
58from lp.buildmaster.enums import BuildStatus55from lp.buildmaster.enums import BuildStatus
59from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet56from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet
@@ -117,6 +114,7 @@
117 )114 )
118from lp.services.features import getFeatureFlag115from lp.services.features import getFeatureFlag
119from lp.services.job.interfaces.job import JobStatus116from lp.services.job.interfaces.job import JobStatus
117from lp.services.job.model.job import Job
120from lp.services.librarian.model import (118from lp.services.librarian.model import (
121 LibraryFileAlias,119 LibraryFileAlias,
122 LibraryFileContent,120 LibraryFileContent,
@@ -162,6 +160,7 @@
162from lp.snappy.interfaces.snappyseries import ISnappyDistroSeriesSet160from lp.snappy.interfaces.snappyseries import ISnappyDistroSeriesSet
163from lp.snappy.interfaces.snapstoreclient import ISnapStoreClient161from lp.snappy.interfaces.snapstoreclient import ISnapStoreClient
164from lp.snappy.model.snapbuild import SnapBuild162from lp.snappy.model.snapbuild import SnapBuild
163from lp.snappy.model.snapjob import SnapJob
165from lp.soyuz.interfaces.archive import ArchiveDisabled164from lp.soyuz.interfaces.archive import ArchiveDisabled
166from lp.soyuz.model.archive import (165from lp.soyuz.model.archive import (
167 Archive,166 Archive,
@@ -879,6 +878,9 @@
879 SnapBuild.snap = ?878 SnapBuild.snap = ?
880 """, (self.id,))879 """, (self.id,))
881 store.find(SnapBuild, SnapBuild.snap == self).remove()880 store.find(SnapBuild, SnapBuild.snap == self).remove()
881 affected_jobs = Select(
882 [SnapJob.job_id], And(SnapJob.job == Job.id, SnapJob.snap == self))
883 store.find(Job, Job.id.is_in(affected_jobs)).remove()
882 getUtility(IWebhookSet).delete(self.webhooks)884 getUtility(IWebhookSet).delete(self.webhooks)
883 store.remove(self)885 store.remove(self)
884 store.find(886 store.find(
885887
=== modified file 'lib/lp/snappy/tests/test_snap.py'
--- lib/lp/snappy/tests/test_snap.py 2018-10-09 09:25:19 +0000
+++ lib/lp/snappy/tests/test_snap.py 2018-11-07 15:02:24 +0000
@@ -111,6 +111,7 @@
111from lp.snappy.model.snap import SnapSet111from lp.snappy.model.snap import SnapSet
112from lp.snappy.model.snapbuild import SnapFile112from lp.snappy.model.snapbuild import SnapFile
113from lp.snappy.model.snapbuildjob import SnapBuildJob113from lp.snappy.model.snapbuildjob import SnapBuildJob
114from lp.snappy.model.snapjob import SnapJob
114from lp.testing import (115from lp.testing import (
115 admin_logged_in,116 admin_logged_in,
116 ANONYMOUS,117 ANONYMOUS,
@@ -961,6 +962,65 @@
961 other_build, getUtility(ISnapBuildSet).getByID(other_build.id))962 other_build, getUtility(ISnapBuildSet).getByID(other_build.id))
962 self.assertIsNotNone(other_build.buildqueue_record)963 self.assertIsNotNone(other_build.buildqueue_record)
963964
965 def test_delete_with_build_requests(self):
966 # A snap package with build requests can be deleted.
967 owner = self.factory.makePerson()
968 distroseries = self.factory.makeDistroSeries()
969 processor = self.factory.makeProcessor(supports_virtualized=True)
970 das = self.factory.makeDistroArchSeries(
971 distroseries=distroseries, architecturetag=processor.name,
972 processor=processor)
973 das.addOrUpdateChroot(
974 self.factory.makeLibraryFileAlias(
975 filename="fake_chroot.tar.gz", db_only=True))
976 self.useFixture(GitHostingFixture(blob=dedent("""\
977 architectures:
978 - build-on: %s
979 """ % processor.name)))
980 [git_ref] = self.factory.makeGitRefs()
981 condemned_snap = self.factory.makeSnap(
982 registrant=owner, owner=owner, distroseries=distroseries,
983 name="condemned", git_ref=git_ref)
984 other_snap = self.factory.makeSnap(
985 registrant=owner, owner=owner, distroseries=distroseries,
986 git_ref=git_ref)
987 self.assertTrue(getUtility(ISnapSet).exists(owner, "condemned"))
988 with person_logged_in(owner):
989 requests = []
990 jobs = []
991 for snap in (condemned_snap, other_snap):
992 requests.append(snap.requestBuilds(
993 owner, distroseries.main_archive,
994 PackagePublishingPocket.UPDATES))
995 jobs.append(removeSecurityProxy(requests[-1])._job)
996 with dbuser(config.ISnapRequestBuildsJobSource.dbuser):
997 JobRunner(jobs).runAll()
998 for job in jobs:
999 self.assertEqual(JobStatus.COMPLETED, job.job.status)
1000 for request in requests:
1001 self.assertNotEqual([], request.builds)
1002 store = Store.of(condemned_snap)
1003 store.flush()
1004 job_ids = [job.job_id for job in jobs]
1005 build_ids = [
1006 [build.id for build in request.builds] for request in requests]
1007 with person_logged_in(condemned_snap.owner):
1008 condemned_snap.destroySelf()
1009 flush_database_caches()
1010 # The deleted snap, its build requests, and its builds are gone.
1011 self.assertFalse(getUtility(ISnapSet).exists(owner, "condemned"))
1012 self.assertIsNone(store.get(SnapJob, job_ids[0]))
1013 for build_id in build_ids[0]:
1014 self.assertIsNone(getUtility(ISnapBuildSet).getByID(build_id))
1015 # Unrelated build requests and builds are still present.
1016 self.assertEqual(
1017 removeSecurityProxy(jobs[1]).context,
1018 store.get(SnapJob, job_ids[1]))
1019 other_builds = [
1020 getUtility(ISnapBuildSet).getByID(build_id)
1021 for build_id in build_ids[1]]
1022 self.assertEqual(list(requests[1].builds), other_builds)
1023
964 def test_related_webhooks_deleted(self):1024 def test_related_webhooks_deleted(self):
965 owner = self.factory.makePerson()1025 owner = self.factory.makePerson()
966 snap = self.factory.makeSnap(registrant=owner, owner=owner)1026 snap = self.factory.makeSnap(registrant=owner, owner=owner)