Skip to content

Commit

Permalink
Fix OSS-fuzz builds status reporting. (#4378) (#4538)
Browse files Browse the repository at this point in the history
There were some hardcoded constants that needed to be updated for the
Google Issue Tracker migration.

We'll also stop adding the 'Project' custom field for now, because it's
hard to propagate custom field values and it's not essential for build
failure issues.

This should hopefully fix
google/oss-fuzz#12536 (comment).

Cherry-pick of #4378

Co-authored-by: Oliver Chang <[email protected]>
  • Loading branch information
jonathanmetzman and oliverchang authored Dec 26, 2024
1 parent 437a1e7 commit 5646228
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 13 deletions.
18 changes: 11 additions & 7 deletions src/clusterfuzz/_internal/cron/oss_fuzz_build_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from clusterfuzz._internal.base import utils
from clusterfuzz._internal.datastore import data_types
from clusterfuzz._internal.issue_management import issue_tracker_policy
from clusterfuzz._internal.issue_management import issue_tracker_utils
from clusterfuzz._internal.metrics import logs

Expand Down Expand Up @@ -135,7 +136,7 @@ def get_build_time(build):
stripped_timestamp.group(0), TIMESTAMP_FORMAT)


def file_bug(issue_tracker, project_name, build_id, ccs, build_type):
def file_bug(issue_tracker, policy, project_name, build_id, ccs, build_type):
"""File a new bug for a build failure."""
logs.info('Filing bug for new build failure (project=%s, build_type=%s, '
'build_id=%s).' % (project_name, build_type, build_id))
Expand All @@ -144,8 +145,7 @@ def file_bug(issue_tracker, project_name, build_id, ccs, build_type):
issue.title = '{project_name}: {build_type} build failure'.format(
project_name=project_name, build_type=build_type.capitalize())
issue.body = _get_issue_body(project_name, build_id, build_type)
issue.status = 'New'
issue.labels.add('Proj-' + project_name)
issue.status = policy.status('new')

for cc in ccs:
issue.ccs.add(cc)
Expand All @@ -154,13 +154,13 @@ def file_bug(issue_tracker, project_name, build_id, ccs, build_type):
return str(issue.id)


def close_bug(issue_tracker, issue_id, project_name):
def close_bug(issue_tracker, policy, issue_id, project_name):
"""Close a build failure bug."""
logs.info('Closing build failure bug (project=%s, issue_id=%s).' %
(project_name, issue_id))

issue = issue_tracker.get_original_issue(issue_id)
issue.status = 'Fixed'
issue.status = policy.status('verified')
issue.save(
new_comment='The latest build has succeeded, closing this issue.',
notify=True)
Expand All @@ -184,6 +184,8 @@ def _close_fixed_builds(projects, build_type):
if not issue_tracker:
raise OssFuzzBuildStatusError('Failed to get issue tracker.')

policy = issue_tracker_policy.get('oss-fuzz')

for project in projects:
project_name = project['name']
builds = project['history']
Expand All @@ -205,7 +207,7 @@ def _close_fixed_builds(projects, build_type):
continue

if build_failure.issue_id is not None:
close_bug(issue_tracker, build_failure.issue_id, project_name)
close_bug(issue_tracker, policy, build_failure.issue_id, project_name)

close_build_failure(build_failure)

Expand All @@ -216,6 +218,8 @@ def _process_failures(projects, build_type):
if not issue_tracker:
raise OssFuzzBuildStatusError('Failed to get issue tracker.')

policy = issue_tracker_policy.get('oss-fuzz')

for project in projects:
project_name = project['name']
builds = project['history']
Expand Down Expand Up @@ -255,7 +259,7 @@ def _process_failures(projects, build_type):
'Project %s is disabled, skipping bug filing.' % project_name)
continue

build_failure.issue_id = file_bug(issue_tracker, project_name,
build_failure.issue_id = file_bug(issue_tracker, policy, project_name,
build['build_id'],
oss_fuzz_project.ccs, build_type)
elif (build_failure.consecutive_failures -
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,66 @@

from clusterfuzz._internal.cron import oss_fuzz_build_status
from clusterfuzz._internal.datastore import data_types
from clusterfuzz._internal.issue_management import issue_tracker_policy
from clusterfuzz._internal.issue_management import monorail
from clusterfuzz._internal.issue_management.monorail.issue import Issue
from clusterfuzz._internal.tests.test_libs import helpers as test_helpers
from clusterfuzz._internal.tests.test_libs import test_utils

OSS_FUZZ_POLICY = issue_tracker_policy.IssueTrackerPolicy({
'status': {
'assigned': 'Assigned',
'duplicate': 'Duplicate',
'verified': 'Verified',
'new': 'New',
'wontfix': 'WontFix',
'fixed': 'Fixed'
},
'all': {
'status': 'new',
'labels': ['ClusterFuzz', 'Stability-%SANITIZER%'],
'issue_body_footer':
'When you fix this bug, please\n'
' * mention the fix revision(s).\n'
' * state whether the bug was a short-lived regression or an old '
'bug in any stable releases.\n'
' * add any other useful information.\n'
'This information can help downstream consumers.\n\n'
'If you need to contact the OSS-Fuzz team with a question, '
'concern, or any other feedback, please file an issue at '
'https://github.com/google/oss-fuzz/issues.'
},
'non_security': {
'labels': ['Type-Bug']
},
'labels': {
'ignore': 'ClusterFuzz-Ignore',
'verified': 'ClusterFuzz-Verified',
'security_severity': 'Security_Severity-%SEVERITY%',
'needs_feedback': 'Needs-Feedback',
'invalid_fuzzer': 'ClusterFuzz-Invalid-Fuzzer',
'reported': 'Reported-%YYYY-MM-DD%',
'wrong': 'ClusterFuzz-Wrong',
'fuzz_blocker': 'Fuzz-Blocker',
'reproducible': 'Reproducible',
'auto_cc_from_owners': 'ClusterFuzz-Auto-CC',
'os': 'OS-%PLATFORM%',
'unreproducible': 'Unreproducible',
'restrict_view': 'Restrict-View-Commit'
},
'security': {
'labels': ['Type-Bug-Security']
},
'deadline_policy_message':
'This bug is subject to a 90 day disclosure deadline. If 90 days '
'elapse\n'
'without an upstream patch, then the bug report will automatically\n'
'become visible to the public.',
'existing': {
'labels': ['Stability-%SANITIZER%']
}
})


class MockResponse:
"""Mock url request's response."""
Expand Down Expand Up @@ -67,6 +122,8 @@ def setUp(self):
test_helpers.patch(self, [
'clusterfuzz._internal.base.utils.utcnow',
'handlers.base_handler.Handler.is_cron',
('policy_get',
'clusterfuzz._internal.issue_management.issue_tracker_policy.get'),
'clusterfuzz._internal.issue_management.issue_tracker_utils.get_issue_tracker',
'clusterfuzz._internal.metrics.logs.error',
'requests.get',
Expand All @@ -77,6 +134,7 @@ def setUp(self):

self.itm = IssueTrackerManager('oss-fuzz')
self.mock.get_issue_tracker.return_value = monorail.IssueTracker(self.itm)
self.mock.policy_get.return_value = OSS_FUZZ_POLICY

self.maxDiff = None

Expand Down Expand Up @@ -386,8 +444,6 @@ def _mock_requests_get(url, timeout=None):
'**This bug will be automatically closed within a '
'day once it is fixed.**', issue.body)

self.assertTrue(issue.has_label('Proj-proj2'))

issue = self.itm.issues[2]
self.assertCountEqual(['[email protected]'], issue.cc)
self.assertEqual('New', issue.status)
Expand All @@ -407,8 +463,6 @@ def _mock_requests_get(url, timeout=None):
'**This bug will be automatically closed within a '
'day once it is fixed.**', issue.body)

self.assertTrue(issue.has_label('Proj-proj6'))

def test_recovered_build_failure(self):
"""Test fixed build failures."""
# Use the same status for all build types.
Expand Down Expand Up @@ -436,7 +490,6 @@ def test_recovered_build_failure(self):
issue = Issue()
issue.open = True
issue.add_label('Type-Build-Failure')
issue.add_label('Proj-proj2')
issue.summary = 'Build failure in proj2'
issue.body = 'Build failure'

Expand All @@ -446,7 +499,7 @@ def test_recovered_build_failure(self):
self.assertEqual(0, data_types.OssFuzzBuildFailure.query().count())

issue = self.itm.issues[1]
self.assertEqual('Fixed', issue.status)
self.assertEqual('Verified', issue.status)
self.assertEqual('The latest build has succeeded, closing this issue.',
issue.comment)

Expand Down

0 comments on commit 5646228

Please sign in to comment.