Exemplo n.º 1
0
    def testNotEveryoneCanRequestNewAnalysisOfFailureOnSupportedMaster(
            self, mock_fn, mocked_ValidateAuthToken):
        mocked_ValidateAuthToken.side_effect = [(True, False)]
        master_name = 'm'
        builder_name = 'b 1'
        build_number = 123
        build_url = buildbot.CreateBuildUrl(master_name, builder_name,
                                            build_number)

        build_info = BuildInfo(master_name, builder_name, build_number)
        build_info.completed = False
        mock_fn.return_value = build_info

        self.mock_current_user(user_email='*****@*****.**', is_admin=False)

        response = self.test_app.post('/failure',
                                      params={
                                          'url': build_url,
                                          'xsrf_token': 'abc'
                                      },
                                      status=302)
        redirect_url = '/waterfall/failure?redirect=1&url=%s' % build_url
        self.assertTrue(
            response.headers.get('Location', '').endswith(redirect_url))

        self.assertEqual(0, len(self.taskqueue_stub.get_filtered_tasks()))
Exemplo n.º 2
0
    def testCannotRerunIncompleteBuild(self, mock_fn):
        master_name = 'm2'
        builder_name = 'b 1'
        build_number = 123
        build_url = buildbot.CreateBuildUrl(master_name, builder_name,
                                            build_number)

        build_info = BuildInfo(master_name, builder_name, build_number)
        build_info.completed = False
        mock_fn.return_value = build_info

        self.mock_current_user(user_email='*****@*****.**', is_admin=True)

        self.assertRaisesRegexp(
            webtest.app.AppError,
            re.compile(
                '.*501 Not Implemented.*Can't rerun an incomplete'
                ' build "%s/%s/%s".*' %
                (master_name, builder_name, build_number),
                re.MULTILINE | re.DOTALL),
            self.test_app.get,
            '/failure',
            params={
                'url': build_url,
                'force': '1'
            })
Exemplo n.º 3
0
    def testCannotRerunIncompleteBuild(self, mock_fn,
                                       mocked_ValidateAuthToken):
        mocked_ValidateAuthToken.side_effect = [(True, False)]
        master_name = 'm'
        builder_name = 'b 1'
        build_number = 123
        build_url = buildbot.CreateBuildUrl(master_name, builder_name,
                                            build_number)

        build_info = BuildInfo(master_name, builder_name, build_number)
        build_info.completed = False
        mock_fn.return_value = build_info

        self.mock_current_user(user_email='*****@*****.**', is_admin=True)

        self.assertRaisesRegexp(
            webtest.app.AppError,
            re.compile(
                '.*501 Not Implemented.*Can't force a rerun for an '
                'incomplete build "%s/%s/%s".*' %
                (master_name, builder_name, build_number),
                re.MULTILINE | re.DOTALL),
            self.test_app.post,
            '/failure',
            params={
                'url': build_url,
                'force': '1',
                'xsrf_token': 'abc'
            })
Exemplo n.º 4
0
  def testAdminCanRequestAnalysisOfFailureOnUnsupportedMaster(self):
    self.mock_current_user(user_email='*****@*****.**', is_admin=True)

    build = WfBuild.Create('m', 'b', 1)
    build.data = '{}'
    self._MockDownloadBuildData(build)

    build_info = BuildInfo('m', 'b', 1)
    build_info.completed = True
    self._MockExtractBuildInfo(build_info)

    requests = []
    self._MockScheduleAnalysisIfNeeded(requests)

    builds = [
        {
            'master_name': 'm',
            'builder_name': 'b',
            'build_number': 1,
            'failed_steps': [],
        },
    ]

    response = self.test_app.post(
        '/trigger-analyses',
        params=json.dumps({'builds': builds}))
    self.assertEquals(200, response.status_int)
    self.assertEqual(1, len(requests))
    self.assertTrue(requests[0][1]['build_completed'])
Exemplo n.º 5
0
  def testTaskQueueCanRequestAnalysis(self):
    build_info = BuildInfo('m', 'b', 1)
    build_info.completed = True
    self._MockGetBuildInfo(build_info)

    requests = []
    self._MockScheduleAnalysisIfNeeded(requests)

    builds = [
        {
            'master_name': 'm',
            'builder_name': 'b',
            'build_number': 1,
            'failed_steps': [],
        },
    ]

    response = self.test_app.post(
        '/process-failure-analysis-requests',
        params=json.dumps({
            'builds': builds
        }),
        headers={'X-AppEngine-QueueName': 'task_queue'},
    )
    self.assertEquals(200, response.status_int)
    self.assertEqual(1, len(requests))
    self.assertTrue(requests[0][1]['build_completed'])
Exemplo n.º 6
0
def ExtractBuildInfo(master_name, builder_name, build_number, build_data):
    """Extracts and returns build information as an instance of BuildInfo."""
    build_info = BuildInfo(master_name, builder_name, build_number)
    data_json = json.loads(build_data)
    chromium_revision = GetBuildProperty(data_json.get('properties', []),
                                         'got_revision')
    commit_position_line = GetBuildProperty(data_json.get('properties', []),
                                            'got_revision_cp')
    parent_buildername = GetBuildProperty(data_json.get('properties', []),
                                          'parent_buildername')
    parent_mastername = GetBuildProperty(data_json.get('properties', []),
                                         'parent_mastername')

    build_info.build_start_time = GetBuildStartTime(data_json)
    build_info.build_end_time = GetBuildEndTime(data_json)
    build_info.chromium_revision = chromium_revision
    build_info.commit_position = _GetCommitPosition(commit_position_line)
    build_info.completed = data_json.get('currentStep') is None
    build_info.result = GetBuildResult(data_json)
    build_info.parent_buildername = parent_buildername
    build_info.parent_mastername = parent_mastername

    changes = data_json.get('sourceStamp', {}).get('changes', [])
    for change in changes:
        if change['revision'] not in build_info.blame_list:
            build_info.blame_list.append(change['revision'])

    # Step categories:
    # 1. A step is passed if it is in SUCCESS or WARNINGS status.
    # 2. A step is failed if it is in FAILED status.
    # 3. A step is not passed if it is not in SUCCESS or WARNINGS status. This
    #    category includes steps in statuses: FAILED, SKIPPED, EXCEPTION, RETRY,
    #    CANCELLED, etc.
    steps = data_json.get('steps', [])
    for step_data in steps:
        step_name = step_data['name']

        if not step_data.get('isFinished', False):
            # Skip steps that haven't started yet or are still running.
            continue

        step_result = GetStepResult(step_data)
        if step_result not in (SUCCESS, WARNINGS):
            build_info.not_passed_steps.append(step_name)

        step_logs = step_data.get('logs')
        if step_logs and 'preamble' == step_logs[0][0]:
            # Skip a annotating step like "steps" or "slave_steps", which wraps other
            # steps. A failed annotated step like "content_browsertests" will make
            # the annotating step like "steps" fail too. Such annotating steps have a
            # log with name "preamble".
            continue

        if step_result in (SUCCESS, WARNINGS):
            build_info.passed_steps.append(step_name)
        elif step_result == FAILURE:
            build_info.failed_steps.append(step_name)

    return build_info
Exemplo n.º 7
0
def ExtractBuildInfo(master_name, builder_name, build_number, build_data):
  """Extracts and returns build information as an instance of BuildInfo."""
  build_info = BuildInfo(master_name, builder_name, build_number)

  data_json = json.loads(build_data)
  chromium_revision = GetBuildProperty(
      data_json.get('properties', []), 'got_revision')

  build_info.build_start_time = GetBuildStartTime(data_json)
  build_info.chromium_revision = chromium_revision
  build_info.completed = data_json.get('currentStep') is None
  build_info.result = GetBuildResult(data_json)

  changes = data_json.get('sourceStamp', {}).get('changes', [])
  for change in changes:
    if change['revision'] not in build_info.blame_list:
      build_info.blame_list.append(change['revision'])

  # Step categories:
  # 1. A step is passed if it is in SUCCESS or WARNINGS status.
  # 2. A step is failed if it is in FAILED status.
  # 3. A step is not passed if it is not in SUCCESS or WARNINGS status. This
  #    category includes steps in statuses: FAILED, SKIPPED, EXCEPTION, RETRY,
  #    CANCELLED, etc.
  steps = data_json.get('steps', [])
  for step_data in steps:
    step_name = step_data['name']

    if not step_data.get('isFinished', False):
      # Skip steps that haven't started yet or are still running.
      continue

    step_result = GetStepResult(step_data)
    if step_result not in (SUCCESS, WARNINGS):
      build_info.not_passed_steps.append(step_name)

    step_logs = step_data.get('logs')
    if step_logs and 'preamble' == step_logs[0][0]:
      # Skip a annotating step like "steps" or "slave_steps", which wraps other
      # steps. A failed annotated step like "content_browsertests" will make
      # the annotating step like "steps" fail too. Such annotating steps have a
      # log with name "preamble".
      continue

    if step_result in (SUCCESS, WARNINGS):
      build_info.passed_steps.append(step_name)
    elif step_result == FAILURE:
      build_info.failed_steps.append(step_name)

  return build_info
Exemplo n.º 8
0
    def testAnyoneCanRequestAnalysisOfFailureOnSupportedMaster(self, mock_fn):
        master_name = 'm'
        builder_name = 'b 1'
        build_number = 123
        build_url = buildbot.CreateBuildUrl(master_name, builder_name,
                                            build_number)

        build_info = BuildInfo(master_name, builder_name, build_number)
        build_info.completed = False
        mock_fn.return_value = build_info

        response = self.test_app.get('/failure', params={'url': build_url})
        self.assertEquals(200, response.status_int)

        self.assertEqual(1, len(self.taskqueue_stub.get_filtered_tasks()))
Exemplo n.º 9
0
    def testAdminCanRequestAnalysisOfFailureOnUnsupportedMaster(self, mock_fn):
        master_name = 'm2'
        builder_name = 'b'
        build_number = 123
        build_url = buildbot.CreateBuildUrl(master_name, builder_name,
                                            build_number)

        build_info = BuildInfo(master_name, builder_name, build_number)
        build_info.completed = False
        mock_fn.return_value = build_info

        self.mock_current_user(user_email='*****@*****.**', is_admin=True)

        response = self.test_app.get('/failure', params={'url': build_url})
        self.assertEquals(200, response.status_int)

        self.assertEqual(1, len(self.taskqueue_stub.get_filtered_tasks()))
Exemplo n.º 10
0
    def testWhenBuildDataIsDownloadedSuccessfully(self):
        build_info = BuildInfo('m', 'b', 1)
        build_info.completed = False
        self._MockGetBuildInfo(build_info)

        requests = []
        self._MockScheduleAnalysisIfNeeded(requests)

        builds = [
            {
                'master_name': 'm',
                'builder_name': 'b',
                'build_number': 1,
                'failed_steps': [],
            },
        ]
        process_failure_analysis_requests._TriggerNewAnalysesOnDemand(builds)
        self.assertEqual(1, len(requests))
        self.assertFalse(requests[0][1]['build_completed'])
Exemplo n.º 11
0
  def testWhenBuildDataIsDownloadedSuccessfully(self):
    build = WfBuild.Create('m', 'b', 1)
    build.data = '{}'
    self._MockDownloadBuildData(build)

    build_info = BuildInfo('m', 'b', 1)
    build_info.completed = False
    self._MockExtractBuildInfo(build_info)

    requests = []
    self._MockScheduleAnalysisIfNeeded(requests)

    builds = [
        {
            'master_name': 'm',
            'builder_name': 'b',
            'build_number': 1,
            'failed_steps': [],
        },
    ]
    trigger_analyses._TriggerNewAnalysesOnDemand(builds)
    self.assertEqual(1, len(requests))
    self.assertFalse(requests[0][1]['build_completed'])
Exemplo n.º 12
0
    def testAdminCanRequestAnalysisOfFailureOnUnsupportedMaster(self):
        self.mock_current_user(user_email='*****@*****.**', is_admin=True)

        build_info = BuildInfo('m', 'b', 1)
        build_info.completed = True
        self._MockGetBuildInfo(build_info)

        requests = []
        self._MockScheduleAnalysisIfNeeded(requests)

        builds = [
            {
                'master_name': 'm',
                'builder_name': 'b',
                'build_number': 1,
                'failed_steps': [],
            },
        ]

        response = self.test_app.post('/process-failure-analysis-requests',
                                      params=json.dumps({'builds': builds}))
        self.assertEquals(200, response.status_int)
        self.assertEqual(1, len(requests))
        self.assertTrue(requests[0][1]['build_completed'])
Exemplo n.º 13
0
def ExtractBuildInfoFromV2Build(master_name, builder_name, build_number, build):
  """Generates BuildInfo using bb v2 build info.

  This conversion is needed to keep Findit v1 running, will be deprecated in
  v2 (TODO: crbug.com/966982).

  Args:
    master_name (str): The name of the master.
    builder_name (str): The name of the builder.
    build_number (int): The build number.
    build (build_pb2.Build): All info about the build.

  Returns:
    (BuildInfo)
  """
  build_info = BuildInfo(master_name, builder_name, build_number)

  input_properties = json_format.MessageToDict(build.input.properties)

  chromium_revision = build.input.gitiles_commit.id
  runtime = input_properties.get('$recipe_engine/runtime') or {}

  build_info.chromium_revision = chromium_revision

  repo_url = git.GetRepoUrlFromV2Build(build)
  build_info.commit_position = git.GetCommitPositionFromRevision(
      build.input.gitiles_commit.id, repo_url=repo_url)

  build_info.build_start_time = build.create_time.ToDatetime()
  build_info.build_end_time = build.end_time.ToDatetime()
  build_info.completed = bool(build_info.build_end_time)
  build_info.result = build.status
  build_info.parent_buildername = input_properties.get('parent_buildername')
  build_info.parent_mastername = input_properties.get('parent_mastername')
  build_info.buildbucket_id = str(build.id)
  build_info.buildbucket_bucket = build.builder.bucket
  build_info.is_luci = runtime.get('is_luci')

  build_info.blame_list = GetBlameListForV2Build(build)

  # Step categories:
  # 1. A step is passed if it is in SUCCESS status.
  # 2. A step is failed if it is in FAILURE status.
  # 3. A step is not passed if it is not in SUCCESS status. This category
  #   includes steps in statuses: FAILURE, INFRA_FAILURE, CANCELED, etc.
  for step in build.steps:
    step_name = step.name
    step_status = step.status

    if step_status in [
        common_pb2.STATUS_UNSPECIFIED, common_pb2.SCHEDULED, common_pb2.STARTED
    ]:
      continue

    if step_status != common_pb2.SUCCESS:
      build_info.not_passed_steps.append(step_name)

    if step_name == 'Failure reason':
      # 'Failure reason' is always red when the build breaks or has exception,
      # but it is not a failed step.
      continue

    if not step.logs:
      # Skip wrapping steps.
      continue

    if step_status == common_pb2.SUCCESS:
      build_info.passed_steps.append(step_name)
    elif step_status == common_pb2.FAILURE:
      build_info.failed_steps.append(step_name)

  return build_info
Exemplo n.º 14
0
    def testGetTryJobResultForCompileFailure(self, mock_fn1, mock_fn2, _):
        master_name = 'm'
        builder_name = 'b'
        build_number = 123

        build = WfBuild.Create(master_name, builder_name, build_number)
        build.build_id = '8000000000000123'
        build.put()
        mock_fn1.return_value = build

        build_info = BuildInfo(master_name, builder_name, build_number)
        build_info.completed = False
        mock_fn2.return_value = build_info

        analysis = WfAnalysis.Create(master_name, builder_name, build_number)
        analysis.result = {
            'failures': [
                {
                    'step_name': 'compile',
                    'first_failure': 122,
                    'last_pass': 121,
                    'suspected_cls': [],
                },
                {
                    'step_name': 'steps',
                },
            ]
        }
        analysis.failure_result_map = {
            'compile': 'm/b/122',
        }
        analysis.status = analysis_status.COMPLETED
        analysis.suspected_cls = [{
            'repo_name': 'chromium',
            'revision': 'rev',
            'commit_position': 122,
            'url': None
        }]
        analysis.put()

        try_job = WfTryJob.Create('m', 'b', 122)
        try_job.status = analysis_status.COMPLETED
        try_job.compile_results = [{
            'url': 'build/url',
            'culprit': {
                'compile': {
                    'revision': 'rev',
                }
            }
        }]
        try_job.put()

        suspected_cl = WfSuspectedCL.Create('chromium', 'rev', 122)
        suspected_cl.builds = {
            'm/b/123': {
                'failure_type':
                failure_type.COMPILE,
                'failures':
                None,
                'status':
                suspected_cl_status.CORRECT,
                'approaches': [
                    analysis_approach_type.HEURISTIC,
                    analysis_approach_type.TRY_JOB
                ],
                'top_score':
                5
            }
        }
        suspected_cl.put()

        expected_try_job_result = {
            'status': 'completed',
            'url': 'build/url',
            'completed': True,
            'culprit': {
                'revision': 'rev',
            },
            'failed': False,
        }

        expected_suspected_cls = [{
            'repo_name':
            'chromium',
            'revision':
            'rev',
            'commit_position':
            122,
            'url':
            None,
            'status':
            suspected_cl_status.CORRECT,
            'confidence':
            self._PercentFormat(
                self.cl_confidences.compile_heuristic_try_job.confidence)
        }]

        build_url = buildbot.CreateBuildUrl('m', 'b', 123)
        response = self.test_app.get('/failure',
                                     params={
                                         'url': build_url,
                                         'format': 'json'
                                     })

        self.assertEquals(200, response.status_int)
        self.assertEqual(expected_try_job_result,
                         response.json_body['try_job'])
        self.assertEqual(expected_suspected_cls,
                         response.json_body['suspected_cls'])