← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:stormify-distributionmirror-queries into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:stormify-distributionmirror-queries into launchpad:master.

Commit message:
Convert DistributionMirror queries to Storm style

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/423313

This prepares the way for converting the corresponding models from SQLObject to Storm syntax.

Converting manual SQL to compiled Storm queries wasn't necessary in every case here, but we generally prefer it where possible, and in some cases the act of doing this exposed some unnecessarily complicated queries: the `DistributionMirror` joins in `DistributionMirror.getSummarizedMirroredSourceSeries` and `DistributionMirror.getSummarizedMirroredArchSeries` weren't needed, and `DistributionMirrorSet.getMirrorsToProbe` can avoid a query in some cases.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-distributionmirror-queries into launchpad:master.
diff --git a/lib/lp/registry/doc/distribution-mirror.txt b/lib/lp/registry/doc/distribution-mirror.txt
index 17f1372..13fc5cf 100644
--- a/lib/lp/registry/doc/distribution-mirror.txt
+++ b/lib/lp/registry/doc/distribution-mirror.txt
@@ -414,11 +414,12 @@ single notification to the distribution's mirror admins.
     >>> print(pretty(sorted(to_addrs)))
     ['mark@xxxxxxxxxxx']
 
-    Now we delete the MirrorProbeRecord we've just created, to make
-    sure this mirror is probed by our prober script.
-    >>> from zope.security.proxy import removeSecurityProxy
-    >>> naked_record = removeSecurityProxy(proberecord)
-    >>> naked_record.destroySelf()
+Now we delete the MirrorProbeRecord we've just created, to make sure this
+mirror is probed by our prober script.
+
+    >>> from lp.services.database.interfaces import IStore
+
+    >>> IStore(proberecord).remove(proberecord)
     >>> transaction.commit()
 
 
@@ -593,6 +594,8 @@ because there were no recent uploads there.
 
 If the mirror has no HTTP base url, we'll use the FTP one.
 
+    >>> from zope.security.proxy import removeSecurityProxy
+
     >>> naked_mirror = removeSecurityProxy(warty_mirror)
     >>> http_url = naked_mirror.distribution_mirror.http_base_url
     >>> naked_mirror.distribution_mirror.http_base_url = None
diff --git a/lib/lp/registry/model/distribution.py b/lib/lp/registry/model/distribution.py
index 3abe8fb..97e51c0 100644
--- a/lib/lp/registry/model/distribution.py
+++ b/lib/lp/registry/model/distribution.py
@@ -1013,7 +1013,8 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
         # balance the load on the mirrors.
         order_by = [Func('random')]
         mirrors = shortlist(
-            DistributionMirror.select(query, orderBy=order_by),
+            IStore(DistributionMirror).find(
+                DistributionMirror, query).order_by(order_by),
             longest_expected=200)
 
         if not mirrors and country is not None:
@@ -1023,7 +1024,8 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
                 DistributionMirror.countryID == Country.q.id,
                 base_query)
             mirrors.extend(shortlist(
-                DistributionMirror.select(query, orderBy=order_by),
+                IStore(DistributionMirror).find(
+                    DistributionMirror, query).order_by(order_by),
                 longest_expected=300))
 
         if mirror_type == MirrorContent.ARCHIVE:
diff --git a/lib/lp/registry/model/distributionmirror.py b/lib/lp/registry/model/distributionmirror.py
index 930d01f..eb6ed3c 100644
--- a/lib/lp/registry/model/distributionmirror.py
+++ b/lib/lp/registry/model/distributionmirror.py
@@ -20,10 +20,19 @@ from datetime import (
 
 import pytz
 from storm.expr import (
+    Cast,
+    Coalesce,
+    LeftJoin,
+    )
+from storm.locals import (
     And,
     Desc,
+    Max,
+    Or,
+    Select,
+    Store,
     )
-from storm.store import Store
+from storm.store import EmptyResultSet
 from zope.interface import implementer
 
 from lp.archivepublisher.diskpool import poolify
@@ -61,10 +70,7 @@ from lp.services.database.constants import UTC_NOW
 from lp.services.database.datetimecol import UtcDateTimeCol
 from lp.services.database.enumcol import DBEnum
 from lp.services.database.interfaces import IStore
-from lp.services.database.sqlbase import (
-    SQLBase,
-    sqlvalues,
-    )
+from lp.services.database.sqlbase import SQLBase
 from lp.services.database.sqlobject import (
     BoolCol,
     ForeignKey,
@@ -162,15 +168,16 @@ class DistributionMirror(SQLBase):
     @property
     def last_probe_record(self):
         """See IDistributionMirror"""
-        return MirrorProbeRecord.selectFirst(
-            MirrorProbeRecord.q.distribution_mirrorID == self.id,
-            orderBy='-date_created')
+        return Store.of(self).find(
+            MirrorProbeRecord, distribution_mirror=self).order_by(
+                MirrorProbeRecord.date_created).last()
 
     @property
     def all_probe_records(self):
         """See IDistributionMirror"""
-        return MirrorProbeRecord.selectBy(
-            distribution_mirror=self, orderBy='-date_created')
+        return Store.of(self).find(
+            MirrorProbeRecord, distribution_mirror=self).order_by(
+                Desc(MirrorProbeRecord.date_created))
 
     @property
     def displayname(self):
@@ -221,7 +228,7 @@ class DistributionMirror(SQLBase):
         """
         assert self.last_probe_record is None, (
             "This mirror has been probed and thus can't be removed.")
-        SQLBase.destroySelf(self)
+        Store.of(self).remove(self)
 
     def verifyTransitionToCountryMirror(self):
         """Verify that a mirror can be set as a country mirror.
@@ -349,7 +356,7 @@ class DistributionMirror(SQLBase):
             if expected_file_count > len(self.cdimage_series):
                 return True
         else:
-            if not (self.source_series or self.arch_series):
+            if self.source_series.is_empty() and self.arch_series.is_empty():
                 return True
         return False
 
@@ -397,11 +404,12 @@ class DistributionMirror(SQLBase):
     def deleteMirrorDistroArchSeries(self, distro_arch_series, pocket,
                                      component):
         """See IDistributionMirror"""
-        mirror = MirrorDistroArchSeries.selectOneBy(
+        mirror = IStore(MirrorDistroArchSeries).find(
+            MirrorDistroArchSeries,
             distribution_mirror=self, distro_arch_series=distro_arch_series,
-            pocket=pocket, component=component)
+            pocket=pocket, component=component).one()
         if mirror is not None:
-            mirror.destroySelf()
+            Store.of(mirror).remove(mirror)
 
     def _getMirrorDistroArchSeries(
         self, distro_arch_series, pocket, component):
@@ -451,17 +459,19 @@ class DistributionMirror(SQLBase):
 
     def deleteMirrorDistroSeriesSource(self, distroseries, pocket, component):
         """See IDistributionMirror"""
-        mirror = MirrorDistroSeriesSource.selectOneBy(
+        mirror = IStore(MirrorDistroSeriesSource).find(
+            MirrorDistroSeriesSource,
             distribution_mirror=self, distroseries=distroseries,
-            pocket=pocket, component=component)
+            pocket=pocket, component=component).one()
         if mirror is not None:
-            mirror.destroySelf()
+            Store.of(mirror).remove(mirror)
 
     def ensureMirrorCDImageSeries(self, distroseries, flavour):
         """See IDistributionMirror"""
-        mirror = MirrorCDImageDistroSeries.selectOneBy(
+        mirror = IStore(MirrorCDImageDistroSeries).find(
+            MirrorCDImageDistroSeries,
             distribution_mirror=self, distroseries=distroseries,
-            flavour=flavour)
+            flavour=flavour).one()
         if mirror is None:
             mirror = MirrorCDImageDistroSeries(
                 distribution_mirror=self, distroseries=distroseries,
@@ -471,72 +481,67 @@ class DistributionMirror(SQLBase):
 
     def deleteMirrorCDImageSeries(self, distroseries, flavour):
         """See IDistributionMirror"""
-        mirror = MirrorCDImageDistroSeries.selectOneBy(
+        mirror = IStore(MirrorCDImageDistroSeries).find(
+            MirrorCDImageDistroSeries,
             distribution_mirror=self, distroseries=distroseries,
-            flavour=flavour)
+            flavour=flavour).one()
         if mirror is not None:
-            mirror.destroySelf()
+            Store.of(mirror).remove(mirror)
         del get_property_cache(self).cdimage_series
 
     def deleteAllMirrorCDImageSeries(self):
         """See IDistributionMirror"""
         for mirror in self.cdimage_series:
-            mirror.destroySelf()
+            Store.of(mirror).remove(mirror)
         del get_property_cache(self).cdimage_series
 
     @property
     def arch_series(self):
         """See IDistributionMirror"""
-        return MirrorDistroArchSeries.selectBy(distribution_mirror=self)
+        return IStore(MirrorDistroArchSeries).find(
+            MirrorDistroArchSeries, distribution_mirror=self)
 
     @cachedproperty
     def cdimage_series(self):
         """See IDistributionMirror"""
-        return list(
-            MirrorCDImageDistroSeries.selectBy(distribution_mirror=self))
+        return list(IStore(MirrorCDImageDistroSeries).find(
+            MirrorCDImageDistroSeries, distribution_mirror=self))
 
     @property
     def source_series(self):
         """See IDistributionMirror"""
-        return MirrorDistroSeriesSource.selectBy(distribution_mirror=self)
+        return IStore(MirrorDistroSeriesSource).find(
+            MirrorDistroSeriesSource, distribution_mirror=self)
 
     def getSummarizedMirroredSourceSeries(self):
         """See IDistributionMirror"""
-        query = """
-            MirrorDistroSeriesSource.id IN (
-              SELECT DISTINCT ON (
-                        MirrorDistroSeriesSource.distribution_mirror,
-                        MirrorDistroSeriesSource.distroseries)
-                     MirrorDistroSeriesSource.id
-              FROM MirrorDistroSeriesSource, DistributionMirror
-              WHERE DistributionMirror.id =
-                         MirrorDistroSeriesSource.distribution_mirror
-                    AND DistributionMirror.id = %(mirrorid)s
-                    AND DistributionMirror.distribution = %(distribution)s
-              ORDER BY MirrorDistroSeriesSource.distribution_mirror,
-                       MirrorDistroSeriesSource.distroseries,
-                       MirrorDistroSeriesSource.freshness DESC)
-            """ % sqlvalues(distribution=self.distribution, mirrorid=self)
-        return MirrorDistroSeriesSource.select(query)
+        return IStore(MirrorDistroSeriesSource).find(
+            MirrorDistroSeriesSource,
+            MirrorDistroSeriesSource.id.is_in(Select(
+                MirrorDistroSeriesSource.id,
+                where=(MirrorDistroSeriesSource.distribution_mirror == self),
+                order_by=(
+                    MirrorDistroSeriesSource.distribution_mirrorID,
+                    MirrorDistroSeriesSource.distroseriesID,
+                    Desc(MirrorDistroSeriesSource.freshness)),
+                distinct=(
+                    MirrorDistroSeriesSource.distribution_mirrorID,
+                    MirrorDistroSeriesSource.distroseriesID))))
 
     def getSummarizedMirroredArchSeries(self):
         """See IDistributionMirror"""
-        query = """
-            MirrorDistroArchSeries.id IN (
-                SELECT DISTINCT ON (
-                        MirrorDistroArchSeries.distribution_mirror,
-                        MirrorDistroArchSeries.distroarchseries)
-                       MirrorDistroArchSeries.id
-                FROM MirrorDistroArchSeries, DistributionMirror
-                WHERE DistributionMirror.id =
-                            MirrorDistroArchSeries.distribution_mirror
-                      AND DistributionMirror.id = %(mirrorid)s
-                      AND DistributionMirror.distribution = %(distribution)s
-                ORDER BY MirrorDistroArchSeries.distribution_mirror,
-                         MirrorDistroArchSeries.distroarchseries,
-                         MirrorDistroArchSeries.freshness DESC)
-            """ % sqlvalues(distribution=self.distribution, mirrorid=self)
-        return MirrorDistroArchSeries.select(query)
+        return IStore(MirrorDistroArchSeries).find(
+            MirrorDistroArchSeries,
+            MirrorDistroArchSeries.id.is_in(Select(
+                MirrorDistroArchSeries.id,
+                where=(MirrorDistroArchSeries.distribution_mirror == self),
+                order_by=(
+                    MirrorDistroArchSeries.distribution_mirrorID,
+                    MirrorDistroArchSeries.distro_arch_seriesID,
+                    Desc(MirrorDistroArchSeries.freshness)),
+                distinct=(
+                    MirrorDistroArchSeries.distribution_mirrorID,
+                    MirrorDistroArchSeries.distro_arch_seriesID))))
 
     def getExpectedPackagesPaths(self):
         """See IDistributionMirror"""
@@ -585,64 +590,70 @@ class DistributionMirrorSet:
 
     def __getitem__(self, mirror_id):
         """See IDistributionMirrorSet"""
-        return DistributionMirror.get(mirror_id)
+        return IStore(DistributionMirror).get(DistributionMirror, mirror_id)
 
     def getMirrorsToProbe(
             self, content_type, ignore_last_probe=False, limit=None):
         """See IDistributionMirrorSet"""
-        query = """
-            SELECT distributionmirror.id, MAX(mirrorproberecord.date_created)
-            FROM distributionmirror
-            LEFT OUTER JOIN mirrorproberecord
-                ON mirrorproberecord.distribution_mirror =
-                    distributionmirror.id
-            WHERE distributionmirror.content = %s
-                AND distributionmirror.official_candidate IS TRUE
-                AND distributionmirror.status = %s
-            GROUP BY distributionmirror.id
-            """ % sqlvalues(content_type, MirrorStatus.OFFICIAL)
+        tables = [
+            DistributionMirror,
+            LeftJoin(
+                MirrorProbeRecord,
+                MirrorProbeRecord.distribution_mirror ==
+                    DistributionMirror.id),
+            ]
+        results = IStore(DistributionMirror).using(*tables).find(
+            (DistributionMirror.id, Max(MirrorProbeRecord.date_created)),
+            DistributionMirror.content == content_type,
+            DistributionMirror.official_candidate,
+            DistributionMirror.status == MirrorStatus.OFFICIAL).group_by(
+                DistributionMirror.id)
 
         if not ignore_last_probe:
-            query += """
-                HAVING MAX(mirrorproberecord.date_created) IS NULL
-                    OR MAX(mirrorproberecord.date_created)
-                        < %s - '%s hours'::interval
-                """ % sqlvalues(UTC_NOW, PROBE_INTERVAL)
+            results = results.having(Or(
+                Max(MirrorProbeRecord.date_created) == None,
+                Max(MirrorProbeRecord.date_created) < (
+                    UTC_NOW -
+                    Cast(timedelta(hours=PROBE_INTERVAL), 'interval'))))
 
-        query += """
-            ORDER BY MAX(COALESCE(
-                mirrorproberecord.date_created, '1970-01-01')) ASC, id"""
+        results = results.order_by(
+            Max(Coalesce(
+                MirrorProbeRecord.date_created, datetime(1970, 1, 1))),
+            DistributionMirror.id)
 
         if limit is not None:
-            query += " LIMIT %d" % limit
+            results = results.config(limit=limit)
 
-        store = IStore(MirrorDistroArchSeries)
-        ids = ", ".join(str(id)
-                        for (id, date_created) in store.execute(query))
-        query = '1 = 2'
-        if ids:
-            query = 'id IN (%s)' % ids
-        return DistributionMirror.select(query)
+        mirror_ids = {mirror_id for mirror_id, _ in results}
+        if not mirror_ids:
+            return EmptyResultSet()
+        return IStore(DistributionMirror).find(
+            DistributionMirror, DistributionMirror.id.is_in(mirror_ids))
 
     def getByName(self, name):
         """See IDistributionMirrorSet"""
-        return DistributionMirror.selectOneBy(name=name)
+        return IStore(DistributionMirror).find(
+            DistributionMirror, name=name).one()
 
     def getByHttpUrl(self, url):
         """See IDistributionMirrorSet"""
-        return DistributionMirror.selectOneBy(http_base_url=url)
+        return IStore(DistributionMirror).find(
+            DistributionMirror, http_base_url=url).one()
 
     def getByHttpsUrl(self, url):
         """See IDistributionMirrorSet"""
-        return DistributionMirror.selectOneBy(https_base_url=url)
+        return IStore(DistributionMirror).find(
+            DistributionMirror, https_base_url=url).one()
 
     def getByFtpUrl(self, url):
         """See IDistributionMirrorSet"""
-        return DistributionMirror.selectOneBy(ftp_base_url=url)
+        return IStore(DistributionMirror).find(
+            DistributionMirror, ftp_base_url=url).one()
 
     def getByRsyncUrl(self, url):
         """See IDistributionMirrorSet"""
-        return DistributionMirror.selectOneBy(rsync_base_url=url)
+        return IStore(DistributionMirror).find(
+            DistributionMirror, rsync_base_url=url).one()
 
 
 class _MirrorSeriesMixIn:
@@ -827,8 +838,10 @@ class MirrorDistroArchSeries(SQLBase, _MirrorSeriesMixIn):
         bpr = publishing_record.binarypackagerelease
         base_url = self.distribution_mirror.base_url
         path = poolify(bpr.sourcepackagename, self.component.name).as_posix()
-        file = BinaryPackageFile.selectOneBy(
-            binarypackagerelease=bpr, filetype=BinaryPackageFileType.DEB)
+        file = IStore(BinaryPackageFile).find(
+            BinaryPackageFile,
+            binarypackagerelease=bpr,
+            filetype=BinaryPackageFileType.DEB).one()
         full_path = 'pool/%s/%s' % (path, file.libraryfile.filename)
         return urlappend(base_url, full_path)
 
@@ -887,8 +900,10 @@ class MirrorDistroSeriesSource(SQLBase, _MirrorSeriesMixIn):
         base_url = self.distribution_mirror.base_url
         sourcename = spr.name
         path = poolify(sourcename, self.component.name)
-        file = SourcePackageReleaseFile.selectOneBy(
-            sourcepackagerelease=spr, filetype=SourcePackageFileType.DSC)
+        file = IStore(SourcePackageReleaseFile).find(
+            SourcePackageReleaseFile,
+            sourcepackagerelease=spr,
+            filetype=SourcePackageFileType.DSC).one()
         full_path = 'pool/%s/%s' % (path, file.libraryfile.filename)
         return urlappend(base_url, full_path)
 
diff --git a/lib/lp/registry/stories/distributionmirror/xx-reassign-distributionmirror.txt b/lib/lp/registry/stories/distributionmirror/xx-reassign-distributionmirror.txt
index bef3699..29749ba 100644
--- a/lib/lp/registry/stories/distributionmirror/xx-reassign-distributionmirror.txt
+++ b/lib/lp/registry/stories/distributionmirror/xx-reassign-distributionmirror.txt
@@ -4,11 +4,17 @@ allow them. -- Guilherme Salgado, 2006-10-27
 
     These are the variables that will be defined in each setup hook once we
     move to a generic test used for all objects that can be reassigned.
-    >>> from lp.registry.model.distributionmirror import DistributionMirror
-    >>> context = DistributionMirror.byName('archive-mirror')
+    >>> from zope.component import getUtility
+    >>> from lp.registry.interfaces.distributionmirror import (
+    ...     IDistributionMirrorSet,
+    ...     )
+    >>> login(ANONYMOUS)
+    >>> context = getUtility(IDistributionMirrorSet).getByName(
+    ...     'archive-mirror')
     >>> owner_attribute_name = 'owner'
     >>> context_url = (
     ...     'http://launchpad.test/ubuntu/+mirror/archive-mirror')
+    >>> logout()
 
 Distribution mirrors can be reassigned by anybody with the launchpad.Edit
 permission on them. Mark is the owner of the archive-mirror.
@@ -80,6 +86,9 @@ account.
     >>> browser.getControl('Change').click()
     >>> browser.url
     'http://launchpad.test/ubuntu/+mirror/archive-mirror'
-    >>> context = DistributionMirror.byName('archive-mirror')
+    >>> login(ANONYMOUS)
+    >>> context = getUtility(IDistributionMirrorSet).getByName(
+    ...     'archive-mirror')
     >>> salgado.id == getattr(context, owner_attribute_name).id
     True
+    >>> logout()
diff --git a/lib/lp/registry/tests/test_distribution.py b/lib/lp/registry/tests/test_distribution.py
index b6d6ad6..ee458ca 100644
--- a/lib/lp/registry/tests/test_distribution.py
+++ b/lib/lp/registry/tests/test_distribution.py
@@ -74,7 +74,6 @@ from lp.registry.interfaces.oopsreferences import IHasOOPSReferences
 from lp.registry.interfaces.person import IPersonSet
 from lp.registry.interfaces.series import SeriesStatus
 from lp.registry.model.distribution import Distribution
-from lp.registry.model.distributionmirror import DistributionMirror
 from lp.registry.tests.test_distroseries import CurrentSourceReleasesMixin
 from lp.services.librarianserver.testing.fake import FakeLibrarian
 from lp.services.propertycache import get_property_cache
@@ -92,6 +91,7 @@ from lp.testing import (
     login,
     login_person,
     person_logged_in,
+    StormStatementRecorder,
     TestCase,
     TestCaseWithFactory,
     )
@@ -1784,24 +1784,11 @@ class TestDistributionWebservice(OCIConfigHelperMixin, TestCaseWithFactory):
 
     def test_getBestMirrorsForCountry_randomizes_results(self):
         """Make sure getBestMirrorsForCountry() randomizes its results."""
-        def my_select(class_, query, *args, **kw):
-            """Fake function with the same signature of SQLBase.select().
-
-            This function ensures the orderBy argument given to it contains
-            the 'random' string in its first item.
-            """
-            self.assertEqual(kw['orderBy'][0].name, 'random')
-            return [1, 2, 3]
-
-        orig_select = DistributionMirror.select
-        DistributionMirror.select = classmethod(my_select)
-        try:
-            login('foo.bar@xxxxxxxxxxxxx')
-            getUtility(
-                IDistributionSet).getByName('ubuntu').getBestMirrorsForCountry(
-                None, MirrorContent.ARCHIVE)
-        finally:
-            DistributionMirror.select = orig_select
+        login("foo.bar@xxxxxxxxxxxxx")
+        ubuntu = getUtility(IDistributionSet).getByName("ubuntu")
+        with StormStatementRecorder() as recorder:
+            ubuntu.getBestMirrorsForCountry(None, MirrorContent.ARCHIVE)
+        self.assertIn("ORDER BY random()", recorder.statements[0])
 
     def test_getBestMirrorsForCountry_appends_main_repo_to_the_end(self):
         """Make sure the main mirror is appended to the list of mirrors for a
diff --git a/lib/lp/registry/tests/test_distributionmirror.py b/lib/lp/registry/tests/test_distributionmirror.py
index ebc4d14..a8df7f5 100644
--- a/lib/lp/registry/tests/test_distributionmirror.py
+++ b/lib/lp/registry/tests/test_distributionmirror.py
@@ -89,8 +89,8 @@ class TestDistributionMirror(TestCaseWithFactory):
         self.assertEqual(0, len(self.cdimage_mirror.cdimage_series))
 
     def test_archive_mirror_without_content_freshness(self):
-        self.assertFalse(self.archive_mirror.source_series)
-        self.assertFalse(self.archive_mirror.arch_series)
+        self.assertTrue(self.archive_mirror.source_series.is_empty())
+        self.assertTrue(self.archive_mirror.arch_series.is_empty())
         self.assertEqual(
             self.archive_mirror.getOverallFreshness(),
             MirrorFreshness.UNKNOWN)
diff --git a/lib/lp/registry/tests/test_distributionmirror_prober.py b/lib/lp/registry/tests/test_distributionmirror_prober.py
index 1decf83..ee2b259 100644
--- a/lib/lp/registry/tests/test_distributionmirror_prober.py
+++ b/lib/lp/registry/tests/test_distributionmirror_prober.py
@@ -14,6 +14,7 @@ from textwrap import dedent
 from fixtures import MockPatchObject
 from lazr.uri import URI
 import responses
+from storm.locals import Store
 from testtools.matchers import (
     ContainsDict,
     Equals,
@@ -38,6 +39,7 @@ from zope.security.proxy import removeSecurityProxy
 
 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
 from lp.registry.interfaces.distributionmirror import (
+    IDistributionMirrorSet,
     MirrorContent,
     MirrorStatus,
     )
@@ -83,7 +85,6 @@ from lp.registry.tests.distributionmirror_http_server import (
 from lp.services.config import config
 from lp.services.daemons.tachandler import TacTestSetup
 from lp.services.database.interfaces import IStore
-from lp.services.database.sqlobject import SQLObjectNotFound
 from lp.services.httpproxy.connect_tunneling import TunnelingAgent
 from lp.services.timeout import default_timeout
 from lp.testing import (
@@ -913,9 +914,9 @@ class TestMirrorCDImageProberCallbacks(TestCaseWithFactory):
         callbacks.ensureOrDeleteMirrorCDImageSeries(not_all_success)
         # If the prober gets at least one 404 status, we need to make sure
         # there's no MirrorCDImageSeries for that series and flavour.
-        self.assertRaises(
-            SQLObjectNotFound, mirror_cdimage_series.get,
-            mirror_cdimage_series.id)
+        self.assertIsNone(
+            Store.of(mirror_cdimage_series).get(
+                type(mirror_cdimage_series), mirror_cdimage_series.id))
 
     def test_expected_failures_are_ignored(self):
         # Any errors included in callbacks.expected_failures are simply
@@ -1037,9 +1038,10 @@ class TestArchiveMirrorProberCallbacks(TestCaseWithFactory):
         # If the prober gets a 404 status, we need to make sure there's no
         # MirrorDistroSeriesSource/MirrorDistroArchSeries referent to
         # that url
-        self.assertRaises(
-            SQLObjectNotFound, mirror_distro_series_source.get,
-            mirror_distro_series_source.id)
+        self.assertIsNone(
+            Store.of(mirror_distro_series_source).get(
+                type(mirror_distro_series_source),
+                mirror_distro_series_source.id))
 
 
 class TestProbeFunctionSemaphores(TestCase):
@@ -1063,7 +1065,8 @@ class TestProbeFunctionSemaphores(TestCase):
         super().tearDown()
 
     def test_MirrorCDImageSeries_records_are_deleted_before_probing(self):
-        mirror = DistributionMirror.byName('releases-mirror2')
+        mirror = getUtility(IDistributionMirrorSet).getByName(
+            'releases-mirror2')
         self.assertNotEqual(0, len(mirror.cdimage_series))
         # Note that calling this function won't actually probe any mirrors; we
         # need to call reactor.run() to actually start the probing.
@@ -1072,16 +1075,22 @@ class TestProbeFunctionSemaphores(TestCase):
         self.assertEqual(0, len(mirror.cdimage_series))
 
     def test_archive_mirror_probe_function(self):
-        mirror1 = DistributionMirror.byName('archive-mirror')
-        mirror2 = DistributionMirror.byName('archive-mirror2')
-        mirror3 = DistributionMirror.byName('canonical-archive')
+        mirror1 = getUtility(IDistributionMirrorSet).getByName(
+            'archive-mirror')
+        mirror2 = getUtility(IDistributionMirrorSet).getByName(
+            'archive-mirror2')
+        mirror3 = getUtility(IDistributionMirrorSet).getByName(
+            'canonical-archive')
         self._test_one_semaphore_for_each_host(
             mirror1, mirror2, mirror3, probe_archive_mirror)
 
     def test_cdimage_mirror_probe_function(self):
-        mirror1 = DistributionMirror.byName('releases-mirror')
-        mirror2 = DistributionMirror.byName('releases-mirror2')
-        mirror3 = DistributionMirror.byName('canonical-releases')
+        mirror1 = getUtility(IDistributionMirrorSet).getByName(
+            'releases-mirror')
+        mirror2 = getUtility(IDistributionMirrorSet).getByName(
+            'releases-mirror2')
+        mirror3 = getUtility(IDistributionMirrorSet).getByName(
+            'canonical-releases')
         with default_timeout(15.0):
             self._test_one_semaphore_for_each_host(
                 mirror1, mirror2, mirror3, probe_cdimage_mirror)