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)
Пример #3
0
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)
Пример #4
0
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
Пример #5
0
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
Пример #6
0
  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