def test_reminder(self): """Test reminders.""" # Return the same status for all build types. self.mock.get.return_value = MockResponse( json.dumps({ 'successes': [], 'failures': [ { 'name': 'proj0', 'finish_time': '2018-02-01T00:00:00.000000Z', 'build_id': 'proj0-id', }, { 'name': 'proj1', 'finish_time': '2018-02-01T00:00:00.000000Z', 'build_id': 'proj0-id', }, ], })) data_types.OssFuzzProject(id='proj0', name='proj0', ccs=['*****@*****.**']).put() data_types.OssFuzzBuildFailure( id='proj0', project_name='proj0', last_checked_timestamp=datetime.datetime(2018, 1, 31), issue_id='1', consecutive_failures=4, build_type='fuzzing').put() data_types.OssFuzzProject(id='proj1', name='proj1', ccs=['*****@*****.**']).put() data_types.OssFuzzBuildFailure( id='proj1', project_name='proj1', last_checked_timestamp=datetime.datetime(2018, 1, 31), issue_id='2', consecutive_failures=3, build_type='fuzzing').put() self.itm.issues[1] = Issue() self.itm.issues[2] = Issue() self.app.get('/build-status') self.assertEqual( 'Friendly reminder that the the build is still failing.\n' 'Please try to fix this failure to ensure that fuzzing remains ' 'productive.\n' 'Latest build log: https://oss-fuzz-build-logs.storage.googleapis.com/' 'log-proj0-id.txt\n', self.itm.issues[1].comment) self.assertEqual('', self.itm.issues[2].comment)
def test_recovered_build_failure(self): """Test fixed build failures.""" # Use the same status for all build types. self.mock.get.return_value = MockResponse( json.dumps({ 'successes': [ { 'name': 'proj0', 'finish_time': '2018-02-01T00:00:00.000000Z', 'build_id': 'proj0-id', }, ], 'failures': [], })) data_types.OssFuzzBuildFailure( id='proj0', project_name='proj0', last_checked_timestamp=datetime.datetime(2018, 1, 31), issue_id='1', consecutive_failures=2, build_type='fuzzing').put() 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' self.itm.issues[1] = issue self.app.get('/build-status') self.assertEqual(0, data_types.OssFuzzBuildFailure.query().count()) issue = self.itm.issues[1] self.assertFalse(issue.open) self.assertEqual('Verified', issue.status) self.assertEqual('The latest build has succeeded, closing this issue.', issue.comment)
def file_bug(itm, project_name, build_id, ccs, build_type): """File a new bug for a build failure.""" logs.log('Filing bug for new build failure (project=%s, build_type=%s, ' 'build_id=%s).' % (project_name, build_type, build_id)) issue = Issue() issue.itm = itm issue.summary = '%s: Build failure' % project_name issue.body = _get_issue_body(project_name, build_id, build_type) issue.status = 'New' issue.add_label('Type-Build-Failure') issue.add_label('Proj-' + project_name) for cc in ccs: issue.add_cc(cc) issue.save() return str(issue.id)
def file_issue(testcase, itm, security_severity=None, user_email=None, additional_ccs=None): """File an issue for the given test case.""" issue = Issue() issue.summary = data_handler.get_issue_summary(testcase) issue.body = data_handler.get_issue_description( testcase, reporter=user_email, show_reporter=True) # Labels applied by default across all issue trackers. issue.status = 'New' issue.add_label('ClusterFuzz') # Add label on memory tool used. add_memory_tool_label_if_needed(issue, testcase) # Add reproducibility flag label. if testcase.one_time_crasher_flag: issue.add_label('Unreproducible') else: issue.add_label('Reproducible') # Add security severity flag label. add_security_severity_label_if_needed(issue, testcase, security_severity) # Get view restriction rules for the job. issue_restrictions = data_handler.get_value_from_job_definition( testcase.job_type, 'ISSUE_VIEW_RESTRICTIONS', 'security') should_restrict_issue = ( issue_restrictions == 'all' or (issue_restrictions == 'security' and testcase.security_flag)) # Chromium-specific labels. if itm.project_name == 'chromium': # A different status system is used on the chromium tracker. Since we # have already reproduced the crash, we skip the Unconfirmed status. issue.status = 'Untriaged' # Add OS label. if environment.is_chromeos_job(testcase.job_type): # ChromeOS fuzzers run on Linux platform, so use correct OS-Chrome for # tracking. issue.add_label('OS-Chrome') elif testcase.platform_id: os_label = 'OS-%s' % ((testcase.platform_id.split(':')[0]).capitalize()) issue.add_label(os_label) # Add view restrictions for internal job types. add_view_restrictions_if_needed(issue, testcase) if testcase.security_flag: # Apply labels specific to security bugs. issue.add_label('Restrict-View-SecurityTeam') issue.add_label('Type-Bug-Security') # Add reward labels if this is from an external fuzzer contribution. fuzzer = data_types.Fuzzer.query( data_types.Fuzzer.name == testcase.fuzzer_name).get() if fuzzer and fuzzer.external_contribution: issue.add_label('reward-topanel') issue.add_label('External-Fuzzer-Contribution') data_handler.update_issue_impact_labels(testcase, issue) else: # Apply labels for functional (non-security) bugs. if utils.sub_string_exists_in(NON_CRASH_TYPES, testcase.crash_type): # Non-crashing test cases shouldn't be assigned Pri-1. issue.add_label('Pri-2') issue.add_label('Type-Bug') else: # Default functional bug labels. issue.add_label('Pri-1') issue.add_label('Stability-Crash') issue.add_label('Type-Bug') # AOSP-specific labels. elif itm.project_name == 'android': if testcase.security_flag: # Security bug labels. issue.add_cc('*****@*****.**') issue.add_label('Type-Security') issue.add_label('Restrict-View-Commit') else: # Functional bug labels. issue.add_label('Type-Defect') # OSS-Fuzz specific labels. elif itm.project_name == 'oss-fuzz': if testcase.security_flag: # Security bug labels. issue.add_label('Type-Bug-Security') else: # Functional bug labels. issue.add_label('Type-Bug') if should_restrict_issue: issue.add_label('Restrict-View-Commit') # Add additional labels from the job definition and fuzzer. additional_labels = data_handler.get_additional_values_for_variable( 'AUTOMATIC_LABELS', testcase.job_type, testcase.fuzzer_name) for label in additional_labels: issue.add_label(label) # Add additional components from the job definition and fuzzer. automatic_components = data_handler.get_additional_values_for_variable( 'AUTOMATIC_COMPONENTS', testcase.job_type, testcase.fuzzer_name) for component in automatic_components: issue.add_component(component) # Add additional ccs from the job definition and fuzzer. ccs = data_handler.get_additional_values_for_variable( 'AUTOMATIC_CCS', testcase.job_type, testcase.fuzzer_name) # For externally contributed fuzzers, potentially cc the author. # Use fully qualified fuzzer name if one is available. fully_qualified_fuzzer_name = ( testcase.overridden_fuzzer_name or testcase.fuzzer_name) ccs += external_users.cc_users_for_fuzzer(fully_qualified_fuzzer_name, testcase.security_flag) ccs += external_users.cc_users_for_job(testcase.job_type, testcase.security_flag) # Add the user as a cc if requested, and any default ccs for this job. # Check for additional ccs or labels from the job definition. if additional_ccs: ccs += [cc for cc in additional_ccs if cc not in ccs] # For user uploads, we assume the uploader is interested in the issue. if testcase.uploader_email and testcase.uploader_email not in ccs: ccs.append(testcase.uploader_email) if itm.project_name == 'oss-fuzz' and ccs: # Add a reported label for deadline tracking. issue.add_label(reported_label()) if issue.has_label_matching('Restrict-View-Commit'): issue.body += '\n\n' + DEADLINE_NOTE issue.body += '\n\n' + FIX_NOTE issue.body += '\n\n' + QUESTIONS_NOTE for cc in ccs: issue.add_cc(cc) # Add additional labels from testcase metadata. metadata_labels = utils.parse_delimited( testcase.get_metadata('issue_labels', ''), delimiter=',', strip=True, remove_empty=True) for label in metadata_labels: issue.add_label(label) issue.itm = itm issue.reporter = user_email issue.save() # Update the testcase with this newly created issue. testcase.bug_information = str(issue.id) testcase.put() data_handler.update_group_bug(testcase.group_id) return issue.id
def create_generic_issue(created_days_ago=28): """Returns a simple issue object for use in tests.""" issue = Issue() issue.cc = ['*****@*****.**'] issue.comment = '' issue.comments = [] issue.components = ['Test>Component'] issue.labels = ['TestLabel', 'Pri-1', 'OS-Windows'] issue.open = True issue.owner = '*****@*****.**' issue.status = 'Assigned' issue.id = 1 issue.itm = create_issue_tracker_manager() # Test issue was created 1 week before the current (mocked) time. issue.created = CURRENT_TIME - datetime.timedelta(days=created_days_ago) return issue
def get_original_issue(self, issue_id): """Get original issue.""" issue = Issue() issue.open = True issue.itm = self issue.id = issue_id if issue_id == 1337: issue.add_cc('*****@*****.**') issue.add_label('Restrict-View-Commit') elif issue_id == 1338: issue.add_cc('*****@*****.**') issue.add_cc('*****@*****.**') elif issue_id == 1340: issue.add_label('reported-2015-01-01') return issue