Merge ~ilasc/launchpad:top50-repos-for-repack into launchpad:master

Proposed by Ioana Lasc
Status: Merged
Approved by: Ioana Lasc
Approved revision: 680b60bcf2665d26ca795abc787335fee5d64bab
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~ilasc/launchpad:top50-repos-for-repack
Merge into: launchpad:master
Diff against target: 99 lines (+66/-0)
3 files modified
lib/lp/code/interfaces/gitrepository.py (+12/-0)
lib/lp/code/model/gitrepository.py (+16/-0)
lib/lp/code/model/tests/test_gitrepository.py (+38/-0)
Reviewer Review Type Date Requested Status
Cristian Gonzalez (community) Approve
Review via email: mp+402973@code.launchpad.net

Commit message

Add a getTop50RepositoriesForRepack endpoint

To post a comment you must log in.
Revision history for this message
Cristian Gonzalez (cristiangsp) wrote :

I have suggested a couple of tweaks but open for debate!

review: Needs Information
Revision history for this message
Ioana Lasc (ilasc) wrote :

Thanks Cristian, no debate, agreed with the comments and adjusted accordingly.
MP ready for review.

Revision history for this message
Cristian Gonzalez (cristiangsp) wrote :

Some little comments about comments added :P

Revision history for this message
Ioana Lasc (ilasc) wrote :

Comments about comments addressed :-) Thanks Cristian!

Revision history for this message
Cristian Gonzalez (cristiangsp) wrote :

Awesome job! Thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/code/interfaces/gitrepository.py b/lib/lp/code/interfaces/gitrepository.py
2index dbd7870..5771d11 100644
3--- a/lib/lp/code/interfaces/gitrepository.py
4+++ b/lib/lp/code/interfaces/gitrepository.py
5@@ -1223,6 +1223,18 @@ class IGitRepositorySet(Interface):
6 Projects that do not have default repositories are omitted.
7 """
8
9+ @operation_parameters(limit=Int())
10+ @export_read_operation()
11+ @operation_for_version("devel")
12+ def getRepositoriesForRepack(limit=50):
13+ """Get the top badly packed repositories.
14+
15+ :param limit: The number of badly packed repositories
16+ that the endpoint should return - it is 50 by default.
17+
18+ :return: A list of the worst badly packed repositories.
19+ """
20+
21
22 class IGitRepositoryDelta(Interface):
23 """The quantitative changes made to a Git repository that was edited or
24diff --git a/lib/lp/code/model/gitrepository.py b/lib/lp/code/model/gitrepository.py
25index 58c298c..d0ac773 100644
26--- a/lib/lp/code/model/gitrepository.py
27+++ b/lib/lp/code/model/gitrepository.py
28@@ -1996,6 +1996,22 @@ class GitRepositorySet:
29 return {
30 repository.project_id: repository for repository in repositories}
31
32+ def getRepositoriesForRepack(self, limit=50):
33+ """See `IGitRepositorySet`."""
34+ repos = IStore(GitRepository).find(
35+ GitRepository,
36+ Or(
37+ GitRepository.loose_object_count >=
38+ config.codehosting.loose_objects_threshold,
39+ GitRepository.pack_count >=
40+ config.codehosting.packs_threshold,
41+ ),
42+ GitRepository.status == GitRepositoryStatus.AVAILABLE,
43+ ).order_by(
44+ Desc(GitRepository.loose_object_count)).config(limit=limit)
45+
46+ return list(repos)
47+
48
49 @implementer(IMacaroonIssuer)
50 class GitRepositoryMacaroonIssuer(MacaroonIssuerBase):
51diff --git a/lib/lp/code/model/tests/test_gitrepository.py b/lib/lp/code/model/tests/test_gitrepository.py
52index a0d0baa..ff79c65 100644
53--- a/lib/lp/code/model/tests/test_gitrepository.py
54+++ b/lib/lp/code/model/tests/test_gitrepository.py
55@@ -4069,6 +4069,44 @@ class TestGitRepositoryWebservice(TestCaseWithFactory):
56 def test_getRepositories_personal(self):
57 self.assertGetRepositoriesWorks(self.factory.makePerson())
58
59+ def test_getRepositoriesForRepack(self):
60+ person = self.factory.makePerson()
61+ webservice = webservice_for_person(
62+ person, permission=OAuthPermission.WRITE_PUBLIC)
63+ webservice.default_api_version = "devel"
64+ response = webservice.named_get(
65+ "/+git", "getRepositoriesForRepack", limit=3)
66+ self.assertEqual(200, response.status)
67+ self.assertEqual([], response.jsonBody())
68+ with person_logged_in(person):
69+ repo = []
70+ for i in range(5):
71+ repo.append(self.factory.makeGitRepository())
72+ for i in range(3):
73+ removeSecurityProxy(repo[i]).loose_object_count = 7000 + i
74+ removeSecurityProxy(repo[i]).pack_count = 43
75+
76+ # We have a total of 3 candidates now
77+ response = webservice.named_get(
78+ "/+git", "getRepositoriesForRepack", limit=10)
79+ self.assertEqual(200, response.status)
80+ self.assertContentEqual(
81+ [7002, 7001, 7000],
82+ [entry['loose_object_count']
83+ for entry in response.jsonBody()])
84+
85+ # When we have 5 repack candidates but limit at 4
86+ # we should only get back 4 repos from the query.
87+ removeSecurityProxy(repo[3]).loose_object_count = 7003
88+ removeSecurityProxy(repo[4]).loose_object_count = 7004
89+ response = webservice.named_get(
90+ "/+git", "getRepositoriesForRepack", limit=4)
91+ self.assertEqual(200, response.status)
92+ self.assertContentEqual(
93+ [7004, 7003, 7002, 7001],
94+ [entry['loose_object_count']
95+ for entry in response.jsonBody()])
96+
97 def test_getNumberRepositoriesForRepack(self):
98 person = self.factory.makePerson()
99 webservice = webservice_for_person(

Subscribers

People subscribed via source and target branches

to status/vote changes: