Skip to content

Commit 220c1c7

Browse files
Use datastore OssFuzzProject instead of github for cc-groups cronjob (#5166)
The cronjob is getting throttled by the GitHub API when trying to query for the oss-fuzz projects info (probably since the project-setup cron is already heavily querying it). This change uses the `OssFuzzProject` datastore entity, which is synced with oss-fuzz github by the project-setup cron, in order to retrieve all the projects and their CCs. Bug: b/477964128
1 parent 3c3409e commit 220c1c7

File tree

2 files changed

+31
-29
lines changed

2 files changed

+31
-29
lines changed

src/clusterfuzz/_internal/cron/oss_fuzz_cc_groups.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,16 @@
1414
"""Cron to sync OSS-Fuzz projects groups used as CC in the issue tracker."""
1515

1616
from clusterfuzz._internal.base import utils
17-
from clusterfuzz._internal.cron import project_setup
17+
from clusterfuzz._internal.datastore import data_types
18+
from clusterfuzz._internal.datastore import ndb_utils
1819
from clusterfuzz._internal.google_cloud_utils import google_groups
1920
from clusterfuzz._internal.metrics import logs
2021

2122
_CC_GROUP_SUFFIX = '-ccs@oss-fuzz.com'
2223
_CC_GROUP_DESC = 'External CCs in OSS-Fuzz issue tracker for project'
2324

2425

25-
def sync_project_cc_group(project_name, info):
26+
def sync_project_cc_group(project_name: str, ccs: list[str]):
2627
"""Sync the project's google group used for CCing in the issue tracker."""
2728
group_name = f'{project_name}{_CC_GROUP_SUFFIX}'
2829

@@ -54,13 +55,13 @@ def sync_project_cc_group(project_name, info):
5455
logs.warning(f'Failed to allow external members for {group_name}')
5556
return
5657

57-
ccs = set(project_setup.ccs_from_info(info))
58+
ccs_set = set(ccs)
5859

59-
to_add = ccs - group_memberships.keys()
60+
to_add = ccs_set - group_memberships.keys()
6061
for member in to_add:
6162
google_groups.add_member_to_group(group_id, member)
6263

63-
to_delete = group_memberships.keys() - ccs
64+
to_delete = group_memberships.keys() - ccs_set
6465
for member in to_delete:
6566
# Ignore the SA that created the group from members to delete.
6667
if utils.is_service_account(member):
@@ -73,10 +74,11 @@ def sync_project_cc_group(project_name, info):
7374
def main():
7475
"""Sync OSS-Fuzz projects groups used to CC owners in the issue tracker."""
7576
logs.info('OSS-Fuzz CC groups sync started.')
76-
projects = project_setup.get_oss_fuzz_projects()
7777

78-
for project, info in projects:
79-
sync_project_cc_group(project, info)
78+
for project in ndb_utils.get_all_from_model(data_types.OssFuzzProject):
79+
project_name = project.name
80+
ccs = project.ccs
81+
sync_project_cc_group(project_name, ccs)
8082

8183
logs.info('OSS-Fuzz CC groups sync succeeded.')
8284
return True

src/clusterfuzz/_internal/tests/appengine/handlers/cron/oss_fuzz_cc_groups_test.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,17 @@
1616
import unittest
1717

1818
from clusterfuzz._internal.cron import oss_fuzz_cc_groups
19+
from clusterfuzz._internal.datastore import data_types
1920
from clusterfuzz._internal.tests.test_libs import helpers as test_helpers
21+
from clusterfuzz._internal.tests.test_libs import test_utils
2022

2123

24+
@test_utils.with_cloud_emulators('datastore')
2225
class OssFuzzCcGroupsTest(unittest.TestCase):
2326
"""Tests for oss_fuzz_cc_groups."""
2427

2528
def setUp(self):
2629
test_helpers.patch(self, [
27-
'clusterfuzz._internal.cron.project_setup.get_oss_fuzz_projects',
28-
'clusterfuzz._internal.cron.project_setup.ccs_from_info',
2930
'clusterfuzz._internal.google_cloud_utils.google_groups.get_group_id',
3031
'clusterfuzz._internal.google_cloud_utils.google_groups.create_google_group',
3132
'clusterfuzz._internal.google_cloud_utils.google_groups.get_google_group_memberships',
@@ -37,14 +38,12 @@ def setUp(self):
3738

3839
def test_main(self):
3940
"""Test main execution for creating groups and syncing project ccs."""
40-
self.mock.get_oss_fuzz_projects.return_value = [
41-
('project1', {
42-
'info': 1
43-
}),
44-
('project2', {
45-
'info': 2
46-
}),
47-
]
41+
project1 = data_types.OssFuzzProject(
42+
name='project1', ccs=['member2@example.com'])
43+
project2 = data_types.OssFuzzProject(
44+
name='project2', ccs=['member2@example.com', 'member3@example.com'])
45+
project1.put()
46+
project2.put()
4847

4948
# project1 group does not exist, so create it.
5049
# project2 group exists, only sync members.
@@ -55,10 +54,6 @@ def test_main(self):
5554
'member1@example.com': 'membership1',
5655
'member2@example.com': 'membership2',
5756
}
58-
self.mock.ccs_from_info.return_value = [
59-
'member2@example.com',
60-
'member3@example.com',
61-
]
6257
self.mock.is_service_account.return_value = False
6358

6459
self.assertTrue(oss_fuzz_cc_groups.main())
@@ -77,13 +72,14 @@ def test_main(self):
7772

7873
def test_main_exec_for_new_group(self):
7974
"""Test main execution for a newly created group."""
80-
self.mock.get_oss_fuzz_projects.return_value = [('project1', {'info': 1})]
75+
project1 = data_types.OssFuzzProject(
76+
name='project1', ccs=['member2@example.com'])
77+
project1.put()
8178
self.mock.get_group_id.return_value = '1'
8279
self.mock.get_google_group_memberships.return_value = {
8380
'member1@gserviceaccount.com': 'membership1'
8481
}
8582
self.mock.set_oss_fuzz_access_settings.return_value = True
86-
self.mock.ccs_from_info.return_value = ['member2@example.com']
8783
self.mock.is_service_account.return_value = True
8884

8985
self.assertTrue(oss_fuzz_cc_groups.main())
@@ -97,7 +93,9 @@ def test_main_exec_for_new_group(self):
9793

9894
def test_create_fail(self):
9995
"""Test group creation failure."""
100-
self.mock.get_oss_fuzz_projects.return_value = [('project1', {})]
96+
project1 = data_types.OssFuzzProject(
97+
name='project1', ccs=['member2@example.com'])
98+
project1.put()
10199
self.mock.get_group_id.return_value = None
102100
self.mock.create_google_group.return_value = False
103101

@@ -106,21 +104,23 @@ def test_create_fail(self):
106104

107105
def test_get_memberships_fail(self):
108106
"""Test get memberships failure."""
109-
self.mock.get_oss_fuzz_projects.return_value = [('project1', {})]
107+
project1 = data_types.OssFuzzProject(name='project1')
108+
project1.put()
110109
self.mock.get_group_id.return_value = 'group1_id'
111110
self.mock.get_google_group_memberships.return_value = None
112111

113112
self.assertTrue(oss_fuzz_cc_groups.main())
114-
self.mock.ccs_from_info.assert_not_called()
113+
self.mock.add_member_to_group.assert_not_called()
114+
self.mock.delete_google_group_membership.assert_not_called()
115115

116116
def test_skip_sa_deletion(self):
117117
"""Test that service accounts are not deleted from group."""
118-
self.mock.get_oss_fuzz_projects.return_value = [('project1', {})]
118+
project1 = data_types.OssFuzzProject(name='project1')
119+
project1.put()
119120
self.mock.get_group_id.return_value = 'group1_id'
120121
self.mock.get_google_group_memberships.return_value = {
121122
'sa@serviceaccount.com': 'membership_sa',
122123
}
123-
self.mock.ccs_from_info.return_value = []
124124
self.mock.is_service_account.return_value = True
125125

126126
self.assertTrue(oss_fuzz_cc_groups.main())

0 commit comments

Comments
 (0)