Merge ~ines-almeida/launchpad:fetch-service-expose-build-metadata-url-api into launchpad:master

Proposed by Ines Almeida
Status: Merged
Approved by: Ines Almeida
Approved revision: 4c818aea02eefa9dad2c3939c274ca79bc565199
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~ines-almeida/launchpad:fetch-service-expose-build-metadata-url-api
Merge into: launchpad:master
Prerequisite: ~ines-almeida/launchpad:fetch-service-buildd-manager-end-session
Diff against target: 114 lines (+74/-0)
3 files modified
lib/lp/snappy/interfaces/snapbuild.py (+12/-0)
lib/lp/snappy/model/snapbuild.py (+11/-0)
lib/lp/snappy/tests/test_snapbuild.py (+51/-0)
Reviewer Review Type Date Requested Status
Jürgen Gmach Approve
Review via email: mp+464697@code.launchpad.net

Commit message

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

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) wrote :

Thanks for finishing this!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/snappy/interfaces/snapbuild.py b/lib/lp/snappy/interfaces/snapbuild.py
2index 52019bf..3416200 100644
3--- a/lib/lp/snappy/interfaces/snapbuild.py
4+++ b/lib/lp/snappy/interfaces/snapbuild.py
5@@ -340,6 +340,18 @@ class ISnapBuildView(IPackageBuildView, IPrivacy):
6 _("A dict of data about store upload progress.")
7 )
8
9+ build_metadata_url = exported(
10+ TextLine(
11+ title=_("URL of the build metadata file"),
12+ description=_(
13+ "URL of the metadata file generated by the fetch service, if "
14+ "it exists."
15+ ),
16+ required=False,
17+ readonly=True,
18+ )
19+ )
20+
21 def getFiles():
22 """Retrieve the build's `ISnapFile` records.
23
24diff --git a/lib/lp/snappy/model/snapbuild.py b/lib/lp/snappy/model/snapbuild.py
25index df2e2c2..c7418e6 100644
26--- a/lib/lp/snappy/model/snapbuild.py
27+++ b/lib/lp/snappy/model/snapbuild.py
28@@ -34,6 +34,7 @@ from zope.interface.interfaces import ObjectEvent
29 from zope.security.proxy import removeSecurityProxy
30
31 from lp.app.errors import NotFoundError
32+from lp.buildmaster.builderproxy import BUILD_METADATA_FILENAME_FORMAT
33 from lp.buildmaster.enums import (
34 BuildFarmJobType,
35 BuildQueueStatus,
36@@ -425,6 +426,16 @@ class SnapBuild(PackageBuildMixin, StormBase):
37 def getFileUrls(self):
38 return [self.lfaUrl(lfa) for _, lfa, _ in self.getFiles()]
39
40+ @property
41+ def build_metadata_url(self):
42+ metadata_filename = BUILD_METADATA_FILENAME_FORMAT.format(
43+ build_id=self.build_cookie
44+ )
45+ for url in self.getFileUrls():
46+ if url.endswith(metadata_filename):
47+ return url
48+ return None
49+
50 @cachedproperty
51 def eta(self):
52 """The datetime when the build job is estimated to complete.
53diff --git a/lib/lp/snappy/tests/test_snapbuild.py b/lib/lp/snappy/tests/test_snapbuild.py
54index d8b7758..c60b6ae 100644
55--- a/lib/lp/snappy/tests/test_snapbuild.py
56+++ b/lib/lp/snappy/tests/test_snapbuild.py
57@@ -1009,6 +1009,57 @@ class TestSnapBuildWebservice(TestCaseWithFactory):
58 for file_url in file_urls:
59 self.assertCanOpenRedirectedUrl(browser, file_url)
60
61+ def test_build_metadata_url(self):
62+ # API clients can fetch the metadata from the build, generated by the
63+ # fetch service
64+ db_build = self.factory.makeSnapBuild(requester=self.person)
65+ metadata_filename = f"{db_build.build_cookie}_metadata.json"
66+ with person_logged_in(self.person):
67+ file_1 = self.factory.makeLibraryFileAlias(
68+ content="some_json",
69+ filename="test_file.json",
70+ )
71+ db_build.addFile(file_1)
72+ metadata_file = self.factory.makeLibraryFileAlias(
73+ content="some_json",
74+ filename=metadata_filename,
75+ )
76+ db_build.addFile(metadata_file)
77+ file_2 = self.factory.makeLibraryFileAlias(
78+ content="some_json",
79+ filename="another_test_file.tar",
80+ )
81+ db_build.addFile(file_2)
82+
83+ build_url = api_url(db_build)
84+ logout()
85+
86+ build = self.webservice.get(build_url).jsonBody()
87+ self.assertIsNotNone(build["build_metadata_url"])
88+ self.assertEndsWith(build["build_metadata_url"], metadata_filename)
89+
90+ def test_build_metadata_url_no_metadata_file(self):
91+ # The attribute `build_metadata_url` returns None when metadata file
92+ # does not exist.
93+ db_build = self.factory.makeSnapBuild(requester=self.person)
94+ with person_logged_in(self.person):
95+ file_1 = self.factory.makeLibraryFileAlias(
96+ content="some_json",
97+ filename="test_file.json",
98+ )
99+ db_build.addFile(file_1)
100+ file_2 = self.factory.makeLibraryFileAlias(
101+ content="some_json",
102+ filename="another_test_file.tar",
103+ )
104+ db_build.addFile(file_2)
105+
106+ build_url = api_url(db_build)
107+ logout()
108+
109+ build = self.webservice.get(build_url).jsonBody()
110+ self.assertIsNone(build["build_metadata_url"])
111+
112
113 class TestSnapBuildMacaroonIssuer(MacaroonTestMixin, TestCaseWithFactory):
114 """Test SnapBuild macaroon issuing and verification."""

Subscribers

People subscribed via source and target branches

to status/vote changes: