예제 #1
0
  def _GetAdditionalInformationForCL(
      self, repo_name, revision, confidences, build, reference_build_key):
    """Gets additional information for a cl.

    Currently additional information contains:
        confidence of the result;
        approaches that found this cl: HEURISTIC, TRY_JOB or both;
        revert_cl_url if the cl has been reverted by Findit.
    """
    additional_info = {}

    cl = WfSuspectedCL.Get(repo_name, revision)
    if not cl:
      return additional_info

    master_name = buildbot.GetMasterNameFromUrl(build.master_url)
    builder_name = build.builder_name
    current_build = build.build_number

    # If the CL is found by a try job, only the first failure will be recorded.
    # So we might need to go to the first failure to get CL information.
    build_info = cl.GetBuildInfo(master_name, builder_name, current_build)
    first_build_info = None if not reference_build_key else cl.GetBuildInfo(
        *build_util.GetBuildInfoFromId(reference_build_key))
    additional_info['confidence'], additional_info['cl_approach'] = (
        suspected_cl_util.GetSuspectedCLConfidenceScoreAndApproach(
            confidences, build_info, first_build_info))

    # Gets the revert_cl_url for the CL if there is one.
    if cl.revert_cl_url:
      additional_info['revert_cl_url'] = cl.revert_cl_url

    return additional_info
예제 #2
0
  def _GetAllSwarmingTasks(self, failure_result_map):
    """Returns all swarming tasks related to one build.

    Args:
      A dict to map each step/test with the key to the build when it failed the
      first time.
      {
          'step1': 'm/b/1',
          'step2': {
              'test1': 'm/b/1',
              'test2': 'm/b/2'
          }
      }

    Returns:
      A dict of swarming tasks like below:
      {
          'step1': {
              'm/b/1': WfSwarmingTask(
                  key=Key('WfBuild', 'm/b/1', 'WfSwarmingTask', 'step1'),...)
          },
          ...
      }
    """
    if not failure_result_map:
      return {}

    swarming_tasks = defaultdict(dict)
    for step_name, step_map in failure_result_map.iteritems():
      if isinstance(step_map, basestring):
        swarming_tasks[step_name][step_map] = (
            WfSwarmingTask.Get(
                *build_util.GetBuildInfoFromId(step_map), step_name=step_name))
      else:
        for task_key in step_map.values():
          if not swarming_tasks[step_name].get(task_key):
            swarming_tasks[step_name][task_key] = (
              WfSwarmingTask.Get(*build_util.GetBuildInfoFromId(task_key),
                                 step_name=step_name))

    return swarming_tasks
예제 #3
0
    def GetListOfTryJobBuilds(builds):
        displayed_builds = {}
        for build_id, build in builds.iteritems():
            if analysis_approach_type.TRY_JOB not in build.get(
                    'approaches', []):
                continue

            build_info = build_util.GetBuildInfoFromId(build_id)
            master_name = build_info[0]
            builder_name = build_info[1]
            build_number = build_info[2]
            if (not displayed_builds.get((master_name, builder_name))
                    or displayed_builds[(master_name, builder_name)][0] >
                    build_number):
                displayed_builds[(master_name,
                                  builder_name)] = (build_number, )

        return [k + v for k, v in displayed_builds.iteritems()]
예제 #4
0
def _PrepareTryJobDataForCompileFailure(analysis):
    try_job_data = {}
    if not (analysis.failure_result_map and  # pragma: no branch.
            constants.COMPILE_STEP_NAME in analysis.failure_result_map):
        return try_job_data  # pragma: no cover.

    referred_build_keys = build_util.GetBuildInfoFromId(
        analysis.failure_result_map[constants.COMPILE_STEP_NAME])
    try_job = WfTryJob.Get(*referred_build_keys)
    if not try_job or not try_job.compile_results:
        return try_job_data  # pragma: no cover.
    result = try_job.compile_results[-1]

    try_job_data['status'] = analysis_status.STATUS_TO_DESCRIPTION.get(
        try_job.status, 'unknown').lower()
    try_job_data['url'] = result.get('url')
    try_job_data['completed'] = try_job.completed
    try_job_data['failed'] = try_job.failed
    try_job_data['culprit'] = result.get('culprit',
                                         {}).get(constants.COMPILE_STEP_NAME)

    return try_job_data
예제 #5
0
def _GetTryJobResultForCompile(failure_result_map):
    try_job_key = failure_result_map['compile']
    referred_build_keys = build_util.GetBuildInfoFromId(try_job_key)
    culprit_info = defaultdict(lambda: defaultdict(list))

    try_job = WfTryJob.Get(*referred_build_keys)
    if not try_job or try_job.test_results:
        return culprit_info

    try_job_result = (try_job.compile_results[-1]
                      if try_job.compile_results else None)

    compile_try_job = {'try_job_key': try_job_key, 'status': try_job.status}

    if try_job_result:
        if try_job_result.get('url'):
            compile_try_job['try_job_url'] = try_job_result['url']
            compile_try_job['try_job_build_number'] = (_GetTryJobBuildNumber(
                try_job_result['url']))
        if try_job_result.get('culprit', {}).get('compile'):
            compile_try_job['culprit'] = try_job_result['culprit']['compile']

    culprit_info['compile']['try_jobs'].append(compile_try_job)
    return culprit_info
예제 #6
0
 def testGetBuildInfoFromId(self):
     build_id = 'm/b/1'
     self.assertEqual(build_util.GetBuildInfoFromId(build_id),
                      ['m', 'b', '1'])
예제 #7
0
def _GenerateSwarmingTasksData(failure_result_map):
    """Collects info for all related swarming tasks.

  Returns: A dict as below:
      {
          'step1': {
              'swarming_tasks': {
                  'm/b/121': {
                      'task_info': {
                          'status': 'Completed',
                          'task_id': 'task1',
                          'task_url': ('https://chromium-swarm.appspot.com/user'
                                       '/task/task1')
                      },
                      'all_tests': ['test2', 'test3', 'test4'],
                      'reliable_tests': ['test2'],
                      'flaky_tests': ['test3', 'test4']
                  }
              }
          },
          'step2': {
              'swarming_tasks': {
                  'm/b/121': {
                      'task_info': {
                          'status': 'Pending'
                      },
                      'all_tests': ['test1']
                  }
              }
          },
          'step3': {
              'swarming_tasks': {
                  'm/b/121': {
                      'task_info': {
                          'status': 'No swarming rerun found'
                      },
                      'all_tests': ['test1']
                  }
              }
          }
      }
  """

    tasks_info = defaultdict(lambda: defaultdict(lambda: defaultdict(dict)))

    swarming_server = waterfall_config.GetSwarmingSettings()['server_host']

    for step_name, failure in failure_result_map.iteritems():
        step_tasks_info = tasks_info[step_name]['swarming_tasks']

        if isinstance(failure, dict):
            # Only swarming test failures have swarming re-runs.
            swarming_task_keys = set(failure.values())

            for key in swarming_task_keys:
                task_dict = step_tasks_info[key]
                referred_build_keys = build_util.GetBuildInfoFromId(key)
                task = WfSwarmingTask.Get(*referred_build_keys,
                                          step_name=step_name)
                all_tests = _GetAllTestsForASwarmingTask(key, failure)
                task_dict['all_tests'] = all_tests
                if not task:  # In case task got manually removed from data store.
                    task_info = {
                        'status': result_status.NO_SWARMING_TASK_FOUND
                    }
                else:
                    task_info = {'status': task.status}

                    # Get the step name without platform.
                    # This value should have been saved in task.parameters;
                    # in case of no such value saved, split the step_name.
                    task_dict['ref_name'] = (
                        step_name.split()[0] if not task.parameters
                        or not task.parameters.get('ref_name') else
                        task.parameters['ref_name'])

                    if task.task_id:  # Swarming rerun has started.
                        task_info['task_id'] = task.task_id
                        task_info['task_url'] = 'https://%s/user/task/%s' % (
                            swarming_server, task.task_id)
                    if task.classified_tests:
                        # Swarming rerun has completed.
                        # Use its result to get reliable and flaky tests.
                        # If task has not completed, there will be no try job yet,
                        # the result will be grouped in unclassified failures temporarily.
                        reliable_tests = task.classified_tests.get(
                            'reliable_tests', [])
                        task_dict['reliable_tests'] = [
                            test for test in reliable_tests
                            if test in all_tests
                        ]
                        flaky_tests = task.classified_tests.get(
                            'flaky_tests', [])
                        task_dict['flaky_tests'] = [
                            test for test in flaky_tests if test in all_tests
                        ]

                task_dict['task_info'] = task_info
        else:
            step_tasks_info[failure] = {
                'task_info': {
                    'status': result_status.NON_SWARMING_NO_RERUN
                }
            }

    return tasks_info
예제 #8
0
def _GetCulpritInfoForTryJobResultForTest(try_job_key, culprits_info):
    referred_build_keys = build_util.GetBuildInfoFromId(try_job_key)
    try_job = WfTryJob.Get(*referred_build_keys)

    if not try_job or try_job.compile_results:
        return

    try_job_result = try_job.test_results[-1] if try_job.test_results else None

    for step_try_jobs in culprits_info.values():
        # If try job found different culprits for each test, split tests by culprit.
        additional_tests_culprit_info = []

        for try_job_info in step_try_jobs['try_jobs']:
            if (try_job_key != try_job_info['try_job_key']
                    or try_job_info.get('status')):
                # Conditions that try_job_info has status are:
                # If there is no swarming task, there won't be try job;
                # If the swarming task is not completed yet, there won't be try job yet;
                # If there are flaky tests found, those tests will be marked as flaky,
                # and no try job for them will be triggered.
                continue

            try_job_info['status'] = try_job.status
            if try_job_result:
                # Needs to use ref_name to match step_name in try job.
                ref_name = try_job_info['ref_name']
                # Saves try job information.
                if try_job_result.get('url'):  # pragma: no cover
                    try_job_info['try_job_url'] = try_job_result['url']
                    try_job_info['try_job_build_number'] = (
                        _GetTryJobBuildNumber(try_job_result['url']))

                if (try_job_result.get('culprit')
                        and try_job_result['culprit'].get(ref_name)):
                    # Saves try job culprits information.

                    # Uses culprits to group tests.
                    culprit_tests_map = _OrganizeTryJobResultByCulprits(
                        try_job_result['culprit'][ref_name])

                    ungrouped_tests = try_job_info.get('tests', [])
                    list_of_culprits = []
                    for culprit_info in culprit_tests_map.values():
                        failed_tests = culprit_info['failed_tests']
                        list_of_culprits.append(culprit_info)
                        # Gets tests that haven't been grouped.
                        ungrouped_tests = list(
                            set(ungrouped_tests) ^ set(failed_tests))
                        if not ungrouped_tests:
                            # All tests have been grouped.
                            break

                    index_start = 1
                    if ungrouped_tests:
                        # There are tests don't have try job culprits.
                        # Group these tests together.
                        # Save them in current try_job_info.
                        try_job_info['tests'] = ungrouped_tests
                        try_job_info['culprit'] = {}
                        # Saves all the tests that have culprits later.
                        index_start = 0
                    else:
                        # Saves the first culprit in current try_job_info.
                        # Saves all the other culprits later.
                        try_job_info['culprit'] = {
                            'revision':
                            list_of_culprits[0]['revision'],
                            'commit_position':
                            list_of_culprits[0]['commit_position'],
                            'review_url':
                            list_of_culprits[0].get(
                                'url',
                                list_of_culprits[0].get('review_url', None))
                        }
                        try_job_info['tests'] = list_of_culprits[0][
                            'failed_tests']

                    for n in xrange(index_start, len(list_of_culprits)):
                        # Appends the rest of test groups to step_try_jobs['try_jobs'].
                        iterate_culprit = list_of_culprits[n]
                        tmp_try_job_info = copy.deepcopy(try_job_info)
                        tmp_try_job_info['culprit'] = {
                            'revision':
                            iterate_culprit['revision'],
                            'commit_position':
                            iterate_culprit['commit_position'],
                            'review_url':
                            iterate_culprit.get(
                                'url', iterate_culprit.get('review_url', None))
                        }
                        tmp_try_job_info['tests'] = iterate_culprit[
                            'failed_tests']
                        additional_tests_culprit_info.append(tmp_try_job_info)

        if additional_tests_culprit_info:
            step_try_jobs['try_jobs'].extend(additional_tests_culprit_info)
예제 #9
0
    test_results = []
    compile_results = []

    while more:
        analyses, cursor, more = WfAnalysis.query(
            ndb.AND(WfAnalysis.build_start_time >= start,
                    WfAnalysis.build_start_time < end)).fetch_page(
                        100, start_cursor=cursor)

        for analysis in analyses:
            if not analysis.completed or not analysis.result:
                continue

            build_key = analysis.key.pairs()[0][1]
            master_name, builder_name, build_number = build_util.GetBuildInfoFromId(
                build_key)
            build_number = int(build_number)

            try_job = WfTryJob.Get(master_name, builder_name, build_number)

            for failure in analysis.result.get('failures', {}):

                result = None
                step_name = failure['step_name']
                culprits = _GetTestTryJobCulprit(try_job, step_name)
                if failure.get('tests'):
                    for test in failure['tests']:
                        if test['first_failure'] != build_number:
                            # Not first time failure.
                            continue