Ines Almeida has proposed merging 
~ines-almeida/launchpad:fetch-service-expose-build-metadata-url-api into 
launchpad:master with 
~ines-almeida/launchpad:fetch-service-buildd-manager-end-session as a 
prerequisite.

Commit message:
Expose the URL to download the metadata file of the fetch service via API

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~ines-almeida/launchpad/+git/launchpad/+merge/464697
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of 
~ines-almeida/launchpad:fetch-service-expose-build-metadata-url-api into 
launchpad:master.
diff --git a/lib/lp/snappy/interfaces/snapbuild.py b/lib/lp/snappy/interfaces/snapbuild.py
index 52019bf..3416200 100644
--- a/lib/lp/snappy/interfaces/snapbuild.py
+++ b/lib/lp/snappy/interfaces/snapbuild.py
@@ -340,6 +340,18 @@ class ISnapBuildView(IPackageBuildView, IPrivacy):
         _("A dict of data about store upload progress.")
     )
 
+    build_metadata_url = exported(
+        TextLine(
+            title=_("URL of the build metadata file"),
+            description=_(
+                "URL of the metadata file generated by the fetch service, if "
+                "it exists."
+            ),
+            required=False,
+            readonly=True,
+        )
+    )
+
     def getFiles():
         """Retrieve the build's `ISnapFile` records.
 
diff --git a/lib/lp/snappy/model/snapbuild.py b/lib/lp/snappy/model/snapbuild.py
index df2e2c2..c7418e6 100644
--- a/lib/lp/snappy/model/snapbuild.py
+++ b/lib/lp/snappy/model/snapbuild.py
@@ -34,6 +34,7 @@ from zope.interface.interfaces import ObjectEvent
 from zope.security.proxy import removeSecurityProxy
 
 from lp.app.errors import NotFoundError
+from lp.buildmaster.builderproxy import BUILD_METADATA_FILENAME_FORMAT
 from lp.buildmaster.enums import (
     BuildFarmJobType,
     BuildQueueStatus,
@@ -425,6 +426,16 @@ class SnapBuild(PackageBuildMixin, StormBase):
     def getFileUrls(self):
         return [self.lfaUrl(lfa) for _, lfa, _ in self.getFiles()]
 
+    @property
+    def build_metadata_url(self):
+        metadata_filename = BUILD_METADATA_FILENAME_FORMAT.format(
+            build_id=self.build_cookie
+        )
+        for url in self.getFileUrls():
+            if url.endswith(metadata_filename):
+                return url
+        return None
+
     @cachedproperty
     def eta(self):
         """The datetime when the build job is estimated to complete.
diff --git a/lib/lp/snappy/tests/test_snapbuild.py b/lib/lp/snappy/tests/test_snapbuild.py
index d8b7758..c60b6ae 100644
--- a/lib/lp/snappy/tests/test_snapbuild.py
+++ b/lib/lp/snappy/tests/test_snapbuild.py
@@ -1009,6 +1009,57 @@ class TestSnapBuildWebservice(TestCaseWithFactory):
         for file_url in file_urls:
             self.assertCanOpenRedirectedUrl(browser, file_url)
 
+    def test_build_metadata_url(self):
+        # API clients can fetch the metadata from the build, generated by the
+        # fetch service
+        db_build = self.factory.makeSnapBuild(requester=self.person)
+        metadata_filename = f"{db_build.build_cookie}_metadata.json"
+        with person_logged_in(self.person):
+            file_1 = self.factory.makeLibraryFileAlias(
+                content="some_json",
+                filename="test_file.json",
+            )
+            db_build.addFile(file_1)
+            metadata_file = self.factory.makeLibraryFileAlias(
+                content="some_json",
+                filename=metadata_filename,
+            )
+            db_build.addFile(metadata_file)
+            file_2 = self.factory.makeLibraryFileAlias(
+                content="some_json",
+                filename="another_test_file.tar",
+            )
+            db_build.addFile(file_2)
+
+        build_url = api_url(db_build)
+        logout()
+
+        build = self.webservice.get(build_url).jsonBody()
+        self.assertIsNotNone(build["build_metadata_url"])
+        self.assertEndsWith(build["build_metadata_url"], metadata_filename)
+
+    def test_build_metadata_url_no_metadata_file(self):
+        # The attribute `build_metadata_url` returns None when metadata file
+        # does not exist.
+        db_build = self.factory.makeSnapBuild(requester=self.person)
+        with person_logged_in(self.person):
+            file_1 = self.factory.makeLibraryFileAlias(
+                content="some_json",
+                filename="test_file.json",
+            )
+            db_build.addFile(file_1)
+            file_2 = self.factory.makeLibraryFileAlias(
+                content="some_json",
+                filename="another_test_file.tar",
+            )
+            db_build.addFile(file_2)
+
+        build_url = api_url(db_build)
+        logout()
+
+        build = self.webservice.get(build_url).jsonBody()
+        self.assertIsNone(build["build_metadata_url"])
+
 
 class TestSnapBuildMacaroonIssuer(MacaroonTestMixin, TestCaseWithFactory):
     """Test SnapBuild macaroon issuing and verification."""
_______________________________________________
Mailing list: https://launchpad.net/~launchpad-reviewers
Post to     : launchpad-reviewers@lists.launchpad.net
Unsubscribe : https://launchpad.net/~launchpad-reviewers
More help   : https://help.launchpad.net/ListHelp

Reply via email to