launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #28284
[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"]])