← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~ilasc/launchpad:distribution-mirror-apis into launchpad:master

 

Ioana Lasc has proposed merging ~ilasc/launchpad:distribution-mirror-apis into launchpad:master.

Commit message:
Expose base_url and getBestMirrorsForCountry over API

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~ilasc/launchpad/+git/launchpad/+merge/418173
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~ilasc/launchpad:distribution-mirror-apis into launchpad:master.
diff --git a/lib/lp/app/browser/launchpad.py b/lib/lp/app/browser/launchpad.py
index 110a34a..48167cb 100644
--- a/lib/lp/app/browser/launchpad.py
+++ b/lib/lp/app/browser/launchpad.py
@@ -111,6 +111,7 @@ from lp.registry.enums import VCSType
 from lp.registry.interfaces.announcement import IAnnouncementSet
 from lp.registry.interfaces.codeofconduct import ICodeOfConductSet
 from lp.registry.interfaces.distribution import IDistributionSet
+from lp.registry.interfaces.distributionmirror import IDistributionMirrorSet
 from lp.registry.interfaces.karma import IKarmaActionSet
 from lp.registry.interfaces.nameblacklist import INameBlacklistSet
 from lp.registry.interfaces.person import IPersonSet
@@ -862,6 +863,7 @@ class LaunchpadRootNavigation(Navigation):
         'codeofconduct': ICodeOfConductSet,
         '+countries': ICountrySet,
         'distros': IDistributionSet,
+        'distribution_mirrors': IDistributionMirrorSet,
         '+git': IGitRepositorySet,
         'karmaaction': IKarmaActionSet,
         '+imports': ITranslationImportQueue,
diff --git a/lib/lp/registry/interfaces/distributionmirror.py b/lib/lp/registry/interfaces/distributionmirror.py
index 0910046..c0a0933 100644
--- a/lib/lp/registry/interfaces/distributionmirror.py
+++ b/lib/lp/registry/interfaces/distributionmirror.py
@@ -26,7 +26,9 @@ from lazr.restful.declarations import (
     exported,
     exported_as_webservice_entry,
     mutator_for,
+    operation_for_version,
     operation_parameters,
+    operation_returns_collection_of,
     )
 from lazr.restful.fields import (
     Reference,
@@ -422,7 +424,9 @@ class IDistributionMirror(Interface):
         'The freshness of this mirror\'s archive mirrors')
     source_mirror_freshness = Attribute(
         'The freshness of this mirror\'s source mirrors')
-    base_url = Attribute('The HTTP or FTP base URL of this mirror')
+    base_url = exported(TextLine(
+        title=_('Base URL'), required=False, readonly=False,
+        description=_("The HTTP or FTP base URL of this mirror")))
     date_created = exported(Datetime(
         title=_('Date Created'), required=True, readonly=True,
         description=_("The date on which this mirror was registered.")))
@@ -606,6 +610,7 @@ class UnableToFetchCDImageFileList(Exception):
     """Couldn't fetch the file list needed for probing cdimage mirrors."""
 
 
+@exported_as_webservice_entry('distribution_mirrors', as_of='devel')
 class IDistributionMirrorSet(Interface):
     """The set of DistributionMirrors"""
 
@@ -628,6 +633,12 @@ class IDistributionMirrorSet(Interface):
         ago.
         """
 
+    @operation_parameters(
+        country=copy_field(IDistributionMirror['country'], required=True),
+        mirror_type=copy_field(IDistributionMirror['content'], required=True))
+    @operation_returns_collection_of(IDistributionMirror)
+    @export_read_operation()
+    @operation_for_version('devel')
     def getBestMirrorsForCountry(country, mirror_type):
         """Return the best mirrors to be used by someone in the given country.
 
diff --git a/lib/lp/registry/interfaces/webservice.py b/lib/lp/registry/interfaces/webservice.py
index c27edda..473c19e 100644
--- a/lib/lp/registry/interfaces/webservice.py
+++ b/lib/lp/registry/interfaces/webservice.py
@@ -8,6 +8,7 @@ __all__ = [
     'ICommercialSubscription',
     'IDistribution',
     'IDistributionMirror',
+    'IDistributionMirrorSet',
     'IDistributionSet',
     'IDistributionSourcePackage',
     'IDistroSeries',
@@ -54,7 +55,10 @@ from lp.registry.interfaces.distribution import (
     IDistribution,
     IDistributionSet,
     )
-from lp.registry.interfaces.distributionmirror import IDistributionMirror
+from lp.registry.interfaces.distributionmirror import (
+    IDistributionMirror,
+    IDistributionMirrorSet,
+    )
 from lp.registry.interfaces.distributionsourcepackage import (
     IDistributionSourcePackage,
     )
diff --git a/lib/lp/registry/tests/test_distributionmirror.py b/lib/lp/registry/tests/test_distributionmirror.py
index e638311..78b3607 100644
--- a/lib/lp/registry/tests/test_distributionmirror.py
+++ b/lib/lp/registry/tests/test_distributionmirror.py
@@ -12,20 +12,29 @@ from lp.registry.interfaces.distributionmirror import (
     IDistributionMirrorSet,
     MirrorContent,
     MirrorFreshness,
+    MirrorSpeed,
     MirrorStatus,
     )
+from lp.registry.interfaces.person import IPersonSet
 from lp.registry.interfaces.pocket import PackagePublishingPocket
 from lp.registry.model.distributionmirror import DistributionMirror
 from lp.services.database.sqlbase import flush_database_updates
 from lp.services.mail import stub
+from lp.services.webapp.interfaces import OAuthPermission
 from lp.services.worlddata.interfaces.country import ICountrySet
 from lp.testing import (
+    api_url,
     login,
     login_as,
+    person_logged_in,
     TestCase,
     TestCaseWithFactory,
     )
-from lp.testing.layers import LaunchpadFunctionalLayer
+from lp.testing.layers import (
+    DatabaseFunctionalLayer,
+    LaunchpadFunctionalLayer,
+    )
+from lp.testing.pages import webservice_for_person
 
 
 class TestDistributionMirror(TestCaseWithFactory):
@@ -242,6 +251,44 @@ class TestDistributionMirror(TestCaseWithFactory):
             MirrorStatus.PENDING_REVIEW, self.archive_mirror.status)
 
 
+class TestDistributionMirrorWebservice(TestCaseWithFactory):
+    """Test the IDistributionMirror API.
+
+    Some tests already exist in distribution-mirror.txt.
+    """
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super().setUp()
+        self.person = self.factory.makePerson(
+            displayname="Test Person")
+        self.webservice = webservice_for_person(
+            self.person, permission=OAuthPermission.WRITE_PUBLIC,
+            default_api_version="devel")
+
+    def test_distribution_mirror_http_base_url(self):
+        distroset = getUtility(IDistributionSet)
+        with person_logged_in(self.person):
+            ubuntu = distroset.get(1)
+            owner = getUtility(IPersonSet).getByName('name16')
+            speed = MirrorSpeed.S2M
+            brazil = getUtility(ICountrySet)['BR']
+            content = MirrorContent.ARCHIVE
+            http_base_url = 'http://foo.bar.com/pub'
+            whiteboard = "This mirror is based deep in the Amazon rainforest."
+            new_mirror = ubuntu.newMirror(owner, speed, brazil, content,
+                                          http_base_url=http_base_url,
+                                          whiteboard=whiteboard)
+            mirror_url = api_url(new_mirror)
+            expected_url = new_mirror.base_url
+        response = self.webservice.get(
+            mirror_url)
+        self.assertEqual(200, response.status, response.body)
+
+        search_body = response.jsonBody()
+        self.assertEqual(expected_url, search_body["base_url"])
+
+
 class TestDistributionMirrorSet(TestCase):
     layer = LaunchpadFunctionalLayer
 
@@ -282,3 +329,40 @@ class TestDistributionMirrorSet(TestCase):
             france, MirrorContent.RELEASE)
         self.assertTrue(len(mirrors) > 1, "Not enough mirrors")
         self.assertEqual(main_mirror, mirrors[-1])
+
+
+class TestDistributionMirrorSetWebservice(TestCaseWithFactory):
+    """Test the IDistributionMirrorSet APIs.
+
+    Some tests already exist in xx-distribution-mirror.txt.
+    """
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super().setUp()
+        self.person = self.factory.makePerson(
+            displayname="Test Person")
+        self.webservice = webservice_for_person(
+            self.person, permission=OAuthPermission.WRITE_PUBLIC,
+            default_api_version="devel")
+
+    def test_getBestMirrorsForCountry_webservice(self):
+        with person_logged_in(self.person):
+            france = getUtility(ICountrySet)['FR']
+            mirrors = getUtility(
+                IDistributionMirrorSet).getBestMirrorsForCountry(
+                france, MirrorContent.ARCHIVE)
+            base_urls = []
+            for mirror in mirrors:
+                base_urls.append(mirror.base_url)
+
+        response = self.webservice.named_get(
+            '/distribution_mirrors', 'getBestMirrorsForCountry',
+            country='%s' % api_url(france),
+            mirror_type='%s' % MirrorContent.ARCHIVE,
+            api_version='devel')
+
+        self.assertEqual(200, response.status)
+        self.assertContentEqual(
+            base_urls,
+            [entry["base_url"] for entry in response.jsonBody()["entries"]])