示例#1
0
def _UpdateSwarmingTaskEntity(master_name,
                              builder_name,
                              build_number,
                              step_name,
                              status=None,
                              task_id=None,
                              error=None,
                              classified_test_results=None,
                              parameters=None,
                              canonical_step_name=None,
                              created_ts=None,
                              started_ts=None,
                              completed_ts=None):
    task = WfSwarmingTask.Get(master_name, builder_name, build_number,
                              step_name)
    assert task
    task.status = status or task.status
    task.task_id = task_id or task.task_id
    task.error = error.ToSerializable() if error else task.error
    task.classified_test_results = task.GetClassifiedTestResults(
        classified_test_results or {}) or task.classified_test_results
    task.parameters = task.parameters or {}
    task.parameters.update(parameters or {})
    task.canonical_step_name = canonical_step_name or task.canonical_step_name
    task.created_time = task.created_time or time_util.DatetimeFromString(
        created_ts)
    task.started_time = task.started_time or time_util.DatetimeFromString(
        started_ts)
    task.completed_time = task.completed_time or time_util.DatetimeFromString(
        completed_ts)
    task.put()
示例#2
0
    def testOnSwarmingTaskCompleted(self, mock_mon, *_):
        master_name = 'm'
        builder_name = 'b'
        build_number = 13
        step_name = 's'
        WfSwarmingTask.Create(master_name, builder_name, build_number,
                              step_name).put()

        data = {
            'state': constants.STATE_COMPLETED,
            'created_ts': '2015-07-30T18:11:16.743220',
            'started_ts': '2015-07-30T18:12:16.743220',
            'completed_ts': '2015-07-30T18:15:16.743220'
        }

        test_swarming.OnSwarmingTaskCompleted(master_name, builder_name,
                                              build_number, step_name, data,
                                              'output_json')

        swarming_task = WfSwarmingTask.Get(master_name, builder_name,
                                           build_number, step_name)
        self.assertEqual({}, swarming_task.tests_statuses)
        self.assertEqual(analysis_status.COMPLETED, swarming_task.status)
        self.assertEqual(datetime.datetime(2015, 7, 30, 18, 11, 16, 743220),
                         swarming_task.created_time)
        self.assertEqual(datetime.datetime(2015, 7, 30, 18, 12, 16, 743220),
                         swarming_task.started_time)
        self.assertEqual(datetime.datetime(2015, 7, 30, 18, 15, 16, 743220),
                         swarming_task.completed_time)
        mock_mon.assert_called_once_with(master_name, builder_name,
                                         build_number, step_name,
                                         analysis_status.COMPLETED,
                                         analysis_approach_type.SWARMING)
def _GetHardTimeoutSeconds(master_name, builder_name, reference_build_number,
                           step_name, iterations_to_rerun):
    flake_settings = waterfall_config.GetCheckFlakeSettings()
    flake_swarming_settings = flake_settings.get('swarming_rerun', {})
    reference_task = WfSwarmingTask.Get(master_name, builder_name,
                                        reference_build_number, step_name)

    if _CanEstimateExecutionTimeFromReferenceSwarmingTask(reference_task):
        delta = reference_task.completed_time - reference_task.started_time
        execution_time = delta.total_seconds()
        number_of_tests = len(reference_task.tests_statuses)
        number_of_iterations = reference_task.parameters['iterations_to_rerun']
        time_per_test_per_iteration = (
            execution_time / (number_of_iterations * number_of_tests))
        estimated_execution_time = (time_per_test_per_iteration *
                                    iterations_to_rerun)
    else:
        # Use default settings if the reference task is unavailable or malformed.
        estimated_execution_time = flake_swarming_settings.get(
            'default_per_iteration_timeout_seconds', 60) * iterations_to_rerun

    # To account for variance and pending time, use a factor of 2x estimated
    # execution time.
    estimated_time_needed = estimated_execution_time * 2

    return min(max(estimated_time_needed, _ONE_HOUR_IN_SECONDS),
               _MAX_TIMEOUT_SECONDS)
    def testProcessSwarmingTaskResultPipelineTaskNotRunning(self):

        task = WfSwarmingTask.Create(self.master_name, self.builder_name,
                                     self.build_number, self.step_name)
        task.task_id = 'task_id2'
        task.put()

        pipeline = ProcessSwarmingTaskResultPipeline()
        pipeline.start_test()
        pipeline.run(self.master_name, self.builder_name, self.build_number,
                     self.step_name)
        pipeline.callback(callback_params=pipeline.last_params)
        # Reload from ID to get all internal properties in sync.
        pipeline = ProcessSwarmingTaskResultPipeline.from_id(
            pipeline.pipeline_id)
        step_name, task_info = pipeline.outputs.default.value

        self.assertEqual(self.step_name, step_name)
        self.assertIsNone(task_info[0])
        self.assertEqual([], task_info[1])

        task = WfSwarmingTask.Get(self.master_name, self.builder_name,
                                  self.build_number, self.step_name)

        self.assertEqual(analysis_status.ERROR, task.status)
        self.assertEqual({}, task.tests_statuses)
        self.assertEqual({}, task.classified_tests)
    def testProcessSwarmingTaskResultPipelineSerializedCallback(self, _):
        # End to end test.
        task = WfSwarmingTask.Create(self.master_name, self.builder_name,
                                     self.build_number, self.step_name)
        task.task_id = 'task_id1'
        task.put()

        pipeline = ProcessSwarmingTaskResultPipeline()
        pipeline.start_test()
        pipeline.run(self.master_name, self.builder_name, self.build_number,
                     self.step_name)
        pipeline.callback(callback_params=json.dumps(pipeline.last_params))
        # Reload from ID to get all internal properties in sync.
        pipeline = ProcessSwarmingTaskResultPipeline.from_id(
            pipeline.pipeline_id)
        pipeline.finalized()
        step_name, task_info = pipeline.outputs.default.value

        self.assertEqual(self.step_name, step_name)
        self.assertEqual('abc_tests', task_info[0])
        self.assertEqual(_EXPECTED_CLASSIFIED_TESTS['reliable_tests'],
                         task_info[1])

        task = WfSwarmingTask.Get(self.master_name, self.builder_name,
                                  self.build_number, self.step_name)

        self.assertEqual(analysis_status.COMPLETED, task.status)
        self.assertEqual(_EXPECTED_TESTS_STATUS, task.tests_statuses)
        self.assertEqual(_EXPECTED_CLASSIFIED_TESTS, task.classified_tests)
        self.assertEqual(datetime.datetime(2016, 2, 10, 18, 32, 6, 538220),
                         task.created_time)
        self.assertEqual(datetime.datetime(2016, 2, 10, 18, 32, 9, 90550),
                         task.started_time)
        self.assertEqual(datetime.datetime(2016, 2, 10, 18, 33, 9),
                         task.completed_time)
示例#6
0
 def MockedSleep(*_):
     swarming_task = WfSwarmingTask.Get(master_name, builder_name,
                                        build_number, step_name)
     self.assertEqual(analysis_status.PENDING, swarming_task.status)
     swarming_task.status = analysis_status.RUNNING
     swarming_task.task_id = 'task_id'
     swarming_task.put()
示例#7
0
    def testOnSwarmingTaskTimeout(self, mock_mon, _):
        master_name = 'm'
        builder_name = 'b'
        build_number = 16
        step_name = 's'
        swarming_task = WfSwarmingTask.Create(master_name, builder_name,
                                              build_number, step_name)
        swarming_task.put()
        parameters = RunSwarmingTaskParameters(build_key=BuildKey(
            master_name=master_name,
            builder_name=builder_name,
            build_number=build_number),
                                               step_name=step_name,
                                               tests=['tests'])
        test_swarming.OnSwarmingTaskTimeout(parameters, 'task_id')

        swarming_task = WfSwarmingTask.Get(master_name, builder_name,
                                           build_number, step_name)
        self.assertEqual(analysis_status.ERROR, swarming_task.status)
        self.assertEqual(
            {
                'code': swarming_task_error.RUNNER_TIMEOUT,
                'message': 'Runner to run swarming task timed out'
            }, swarming_task.error)
        mock_mon.assert_called_once_with(master_name, builder_name,
                                         build_number, step_name,
                                         analysis_status.ERROR,
                                         analysis_approach_type.SWARMING)
示例#8
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(
                    *BaseBuildModel.GetBuildInfoFromBuildKey(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(
                                *BaseBuildModel.GetBuildInfoFromBuildKey(
                                    task_key),
                                step_name=step_name))

        return swarming_tasks
示例#9
0
    def testOnSwarmingTaskErrorShouldNotCompletePipeline(self, mock_mon):
        master_name = 'm'
        builder_name = 'b'
        build_number = 12
        step_name = 's'
        WfSwarmingTask.Create(master_name, builder_name, build_number,
                              step_name).put()
        error = {'code': 1, 'message': 'error'}
        test_swarming.OnSwarmingTaskError(
            master_name, builder_name, build_number, step_name,
            SwarmingTaskError.FromSerializable(error), False)

        swarming_task = WfSwarmingTask.Get(master_name, builder_name,
                                           build_number, step_name)
        self.assertEqual(error, swarming_task.error)
        self.assertEqual(analysis_status.PENDING, swarming_task.status)
        self.assertFalse(mock_mon.called)
  def run(self, master_name, builder_name, build_number):
    """Triggers flake analyses for flaky tests found by build failure analysis.

    Args:
      master_name (str): The master name.
      builder_name (str): The builder name.
      build_number (str): The build number.
    """

    analysis = WfAnalysis.Get(master_name, builder_name, build_number)

    if not analysis or not analysis.failure_result_map:  # pragma: no cover
      return

    for step in analysis.failure_result_map.iterkeys():
      task = WfSwarmingTask.Get(
          master_name, builder_name, build_number, step)

      if not task:  # pragma: no cover
        continue

      flaky_tests = task.classified_tests.get('flaky_tests', [])

      if not flaky_tests:  # pragma: no cover
        continue

      # Trigger a master flake analysis on each detected flaky test.
      # TODO lijeffrey): rerun all tests once typical load is determined to be
      # within reasonable limits. For experimentation with automatic flakiness
      # checking, only run 1 test per anaysis to avoid excessive load on the
      # swarming server in case there are too many flaky tests per analysis for
      # now.
      test_name = flaky_tests[0]
      request = FlakeAnalysisRequest.Create(test_name, False, None)
      request.AddBuildStep(
          master_name, builder_name, build_number, step,
          time_util.GetUTCNow())
      scheduled = flake_analysis_service.ScheduleAnalysisForFlake(
          request, '*****@*****.**', False,
          triggering_sources.FINDIT_PIPELINE)

      if scheduled:  # pragma: no branch
        logging.info('%s/%s/%s has %s flaky tests.',
                     master_name, builder_name, build_number, len(flaky_tests))
        logging.info('A flake analysis has been triggered for %s', test_name)
示例#11
0
def NeedANewSwarmingTask(master_name, builder_name, build_number, step_name,
                         force):
    """Checks if a WfSwarmingTask for the given params exists, or creates it."""
    swarming_task = WfSwarmingTask.Get(master_name, builder_name, build_number,
                                       step_name)

    if not swarming_task:
        swarming_task = WfSwarmingTask.Create(master_name, builder_name,
                                              build_number, step_name)
        swarming_task.status = analysis_status.PENDING
        swarming_task.put()
        return True, swarming_task.key.urlsafe()

    if force:
        swarming_task.Reset()
        swarming_task.put()
        return True, swarming_task.key.urlsafe()

    # TODO(http://crbug.com/585676): Rerun the Swarming task if it runs into
    # unexpected infra errors.
    return False, swarming_task.key.urlsafe()
示例#12
0
def GetReliableTests(master_name, builder_name, build_number, failure_info):
    task_results = {}
    for step_name, step_failure in failure_info['failed_steps'].iteritems():
        if not ci_test_failure.AnyTestHasFirstTimeFailure(
                step_failure.get('tests', {}), build_number):
            continue
        task = WfSwarmingTask.Get(master_name, builder_name, build_number,
                                  step_name)

        if not task or not task.classified_tests:
            logging.error('No result for swarming task %s/%s/%s/%s' %
                          (master_name, builder_name, build_number, step_name))
            continue

        if not task.reliable_tests:
            continue

        task_results[task.canonical_step_name
                     or step_name] = task.reliable_tests

    return task_results
示例#13
0
    def testOnSwarmingTaskErrorShouldCompletePipeline(self, mock_mon):
        master_name = 'm'
        builder_name = 'b'
        build_number = 11
        step_name = 's'
        WfSwarmingTask.Create(master_name, builder_name, build_number,
                              step_name).put()
        error = {'code': 1, 'message': 'error'}
        self.assertFalse(
            test_swarming.OnSwarmingTaskError(
                master_name, builder_name, build_number, step_name,
                SwarmingTaskError.FromSerializable(error)))

        swarming_task = WfSwarmingTask.Get(master_name, builder_name,
                                           build_number, step_name)
        self.assertEqual(error, swarming_task.error)
        self.assertEqual(analysis_status.ERROR, swarming_task.status)
        mock_mon.assert_called_once_with(master_name, builder_name,
                                         build_number, step_name,
                                         analysis_status.ERROR,
                                         analysis_approach_type.SWARMING)
示例#14
0
    def testTriggerANewSwarmingTask(self):
        def MockedDownloadSwarmingTaskData(*_):
            return [{'task_id': '1'}, {'task_id': '2'}]

        self.mock(swarming_util, 'ListSwarmingTasksDataByTags',
                  MockedDownloadSwarmingTaskData)

        def MockedGetSwarmingTaskRequest(ref_task_id, *_):
            self.assertEqual('1', ref_task_id)
            return SwarmingTaskRequest.Deserialize({
                'expiration_secs':
                3600,
                'name':
                'ref_task_request',
                'parent_task_id':
                'pti',
                'priority':
                25,
                'properties': {
                    'command':
                    'cmd',
                    'dimensions': [{
                        'key': 'k',
                        'value': 'v'
                    }],
                    'env': [
                        {
                            'key': 'a',
                            'value': '1'
                        },
                        {
                            'key': 'GTEST_SHARD_INDEX',
                            'value': '1'
                        },
                        {
                            'key': 'GTEST_TOTAL_SHARDS',
                            'value': '5'
                        },
                    ],
                    'execution_timeout_secs':
                    3600,
                    'extra_args': [
                        '--flag=value',
                        '--gtest_filter=d.f',
                        '--test-launcher-filter-file=path/to/filter/file',
                    ],
                    'grace_period_secs':
                    30,
                    'idempotent':
                    True,
                    'inputs_ref': {
                        'a': 1
                    },
                    'io_timeout_secs':
                    1200,
                },
                'tags': ['master:a', 'buildername:b', 'name:a_tests'],
                'user':
                '******',
            })

        self.mock(swarming_util, 'GetSwarmingTaskRequest',
                  MockedGetSwarmingTaskRequest)

        new_request_json = {}

        def MockedTriggerSwarmingTask(new_request, *_):
            new_request_json.update(new_request.Serialize())
            return 'new_task_id', None

        self.mock(swarming_util, 'TriggerSwarmingTask',
                  MockedTriggerSwarmingTask)

        def MockedGetSwarmingTaskName(*_):
            return 'new_task_name'

        self.mock(TriggerBaseSwarmingTaskPipeline, '_GetSwarmingTaskName',
                  MockedGetSwarmingTaskName)

        master_name = 'm'
        builder_name = 'b'
        build_number = 234
        step_name = 'a_tests on platform'
        tests = ['a.b', 'a.c']

        expected_new_request_json = {
            'expiration_secs':
            3600,
            'name':
            'new_task_name',
            'parent_task_id':
            '',
            'priority':
            25,
            'properties': {
                'command':
                'cmd',
                'dimensions': [{
                    'key': 'k',
                    'value': 'v'
                }],
                'env': [
                    {
                        'key': 'a',
                        'value': '1'
                    },
                ],
                'execution_timeout_secs':
                3600,
                'extra_args': [
                    '--flag=value',
                    '--gtest_filter=a.b:a.c',
                    '--gtest_repeat=10',
                    '--test-launcher-retry-limit=0',
                    '--gtest_also_run_disabled_tests',
                ],
                'grace_period_secs':
                30,
                'idempotent':
                False,
                'inputs_ref': {
                    'a': 1
                },
                'io_timeout_secs':
                1200,
            },
            'tags': [
                'ref_master:%s' % master_name,
                'ref_buildername:%s' % builder_name,
                'ref_buildnumber:%s' % build_number,
                'ref_stepname:%s' % step_name,
                'ref_task_id:1',
                'ref_name:a_tests',
                'purpose:identify-flake',
            ],
            'user':
            '',
            'pubsub_auth_token':
            'https://goo.gl/yYhr29',
            'pubsub_topic':
            'projects/findit-for-me/topics/swarm',
            'pubsub_userdata':
            '{"Message-Type": "SwarmingTaskStatusChange"}',
        }

        pipeline = TriggerSwarmingTaskPipeline()
        new_task_id = pipeline.run(master_name, builder_name, build_number,
                                   step_name, tests)
        self.assertEqual('new_task_id', new_task_id)
        self.assertEqual(expected_new_request_json, new_request_json)

        swarming_task = WfSwarmingTask.Get(master_name, builder_name,
                                           build_number, step_name)
        self.assertIsNotNone(swarming_task)
        self.assertEqual('new_task_id', swarming_task.task_id)
        self.assertEqual(tests, swarming_task.parameters['tests'])
        self.assertEqual(
            waterfall_config.GetSwarmingSettings()['iterations_to_rerun'],
            swarming_task.parameters['iterations_to_rerun'])
    def testProcessSwarmingTaskResultPipeline(self):
        # End to end test.
        self.mock(swarming_util, 'GetSwarmingTaskFailureLog',
                  self._MockedGetSwarmingTaskFailureLog)

        task = WfSwarmingTask.Create(self.master_name, self.builder_name,
                                     self.build_number, self.step_name)
        task.task_id = 'task_id1'
        task.put()

        analysis = WfAnalysis.Create(self.master_name, self.builder_name,
                                     self.build_number)
        analysis.result = {
            'failures': [
                {
                    'step_name': 'another_step1'
                },
                {
                    'tests': [
                        {
                            'last_pass': self.build_number,
                            'first_failure': self.build_number,
                            'suspected_cls': [],
                            'test_name': 'TestSuite1.test1'
                        },
                        {
                            'last_pass': self.build_number,
                            'first_failure': self.build_number,
                            'suspected_cls': [],
                            'test_name': 'TestSuite1.test2'
                        },
                        {
                            'last_pass': self.build_number,
                            'first_failure': self.build_number,
                            'suspected_cls': [],
                            'test_name': 'TestSuite1.test3'
                        },
                    ],
                    'step_name':
                    self.step_name
                },
                {
                    'step_name': 'another_step2'
                },
            ]
        }
        analysis.put()

        pipeline = ProcessSwarmingTaskResultPipeline()
        pipeline.start_test()
        pipeline.run(self.master_name, self.builder_name, self.build_number,
                     self.step_name)
        pipeline.callback(callback_params=pipeline.last_params)
        # Reload from ID to get all internal properties in sync.
        pipeline = ProcessSwarmingTaskResultPipeline.from_id(
            pipeline.pipeline_id)
        step_name, task_info = pipeline.outputs.default.value

        self.assertEqual(self.step_name, step_name)
        self.assertEqual('abc_tests', task_info[0])
        self.assertEqual(
            base_test._EXPECTED_CLASSIFIED_TESTS['reliable_tests'],
            task_info[1])

        task = WfSwarmingTask.Get(self.master_name, self.builder_name,
                                  self.build_number, self.step_name)
        self.assertEqual(analysis_status.COMPLETED, task.status)
        self.assertEqual(base_test._EXPECTED_TESTS_STATUS, task.tests_statuses)
        self.assertEqual(base_test._EXPECTED_CLASSIFIED_TESTS,
                         task.classified_tests)
        self.assertEqual(datetime.datetime(2016, 2, 10, 18, 32, 6, 538220),
                         task.created_time)
        self.assertEqual(datetime.datetime(2016, 2, 10, 18, 32, 9, 90550),
                         task.started_time)
        self.assertEqual(datetime.datetime(2016, 2, 10, 18, 33, 9),
                         task.completed_time)
def _CheckIfTestFlaky(master_name, builder, build, step, checked_test_name):
  task = WfSwarmingTask.Get(master_name, builder, build, step)
  if task and task.classified_tests:
    return checked_test_name in task.classified_tests.get('flaky_tests', [])
  return False
示例#17
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 = BaseBuildModel.GetBuildInfoFromBuildKey(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
示例#18
0
def GetConsistentFailuresWhenAllTasksComplete(
        collect_consistent_failure_inputs, first_failed_steps):
    """Get consistent failures from swarming reruns in a build when all of them
    complete.

  This functions tries to collect swarming task results if all tasks complete.
  Otherwise it will give up what it has collected and return None.

  In the meanwhile it will also updates WfAnalysis about the flaky tests.

  Args:
    collect_consistent_failure_inputs (CollectSwarmingTaskResultsInputs): Key to
      a build and if the build has completed.
    first_failed_steps (list): A list of step_names that Findit needs to wait
      swarming tasks to complete and collect results for.

  Returns:
    (CollectSwarmingTaskResultsOutputs): Consistently failed tests.
      - It will be None if any task is still running.
      - It will be empty if
        - build has not completed,
        - no first time failure in build,
        - no consistent test failures in build.
  """

    master_name, builder_name, build_number = (
        collect_consistent_failure_inputs.build_key.GetParts())
    consistent_failures = {}
    flake_failures = {}
    non_reproducible_flaky_tests = {}
    all_tasks_completes = True

    for step_name in first_failed_steps:
        task = WfSwarmingTask.Get(master_name, builder_name, build_number,
                                  step_name)
        assert task, 'Cannot get WfSwarmingTask entity %s/%s/%d/%s.' % (
            master_name, builder_name, build_number, step_name)

        if task.status in [analysis_status.PENDING, analysis_status.RUNNING]:
            all_tasks_completes = False
            break

        if task.status == analysis_status.ERROR:
            logging.warning(
                'Swarming task %s/%s/%s/%s completed with error %s.' %
                (master_name, builder_name, build_number, step_name,
                 (task.error or {}).get('message', 'Unknown error.')))
            continue

        if not task.classified_tests:  # Task completed without results.
            logging.warning(
                'No result for swarming task %s/%s/%s/%s' %
                (master_name, builder_name, build_number, step_name))
            continue

        if task.reliable_tests:
            consistent_failures[task.canonical_step_name
                                or step_name] = task.reliable_tests

        if task.reproducible_flaky_tests:  # pragma: no branch
            flake_failures[step_name] = task.reproducible_flaky_tests

        non_reproducible_flaky_tests[step_name] = (
            set(task.flaky_tests) - set(task.reproducible_flaky_tests))

    test_failure_analysis.UpdateAnalysisWithFlakesFoundBySwarmingReruns(
        master_name, builder_name, build_number, flake_failures)

    if not all_tasks_completes:
        # Not all tasks completed, don't return any information about consistent
        # failures.
        return None

    # Reports all flakes to Flake Detector.
    detect_flake_occurrences.StoreDetectedCIFlakes(master_name, builder_name,
                                                   build_number,
                                                   flake_failures)

    for step_name, tests in non_reproducible_flaky_tests.iteritems():
        if tests:
            # Skips flake analyses on non reproducible tests, but keeps a record in
            # ts_mon.
            # For reproducible flakes, keeps a record for them in
            # trigger_flake_analyses_pipeline, depends on whether the analyses are
            # successfully triggered.
            step_metadata = step_util.LegacyGetStepMetadata(
                master_name, builder_name, build_number, step_name)
            canonical_step_name = step_metadata.get(
                'canonical_step_name') or 'Unknown'
            isolate_target_name = step_metadata.get(
                'isolate_target_name') or 'Unknown'
            monitoring.OnFlakeIdentified(canonical_step_name,
                                         isolate_target_name, 'skip',
                                         len(tests))

    return (CollectSwarmingTaskResultsOutputs.FromSerializable(
        {'consistent_failures': consistent_failures}) if consistent_failures
            else CollectSwarmingTaskResultsOutputs.FromSerializable({}))
 def _GetSwarmingTask(self, master_name, builder_name, build_number,
                      step_name):
     return WfSwarmingTask.Get(master_name, builder_name, build_number,
                               step_name)
示例#20
0
 def testOnSwarmingTaskTriggered(self):
     master_name = 'm'
     builder_name = 'b'
     build_number = 6
     step_name = 's'
     task = WfSwarmingTask.Create(master_name, builder_name, build_number,
                                  step_name)
     task.put()
     task_id = 'task_id'
     tests = ['t']
     iterations = 100
     new_request = {
         'expiration_secs':
         '3600',
         'name':
         'findit/ref_task_id/ref_task_id/2018-03-15 00:00:00 000000',
         'parent_task_id':
         '',
         'priority':
         '25',
         'properties': {
             'command':
             'cmd',
             'dimensions': [{
                 'key': 'k',
                 'value': 'v'
             }],
             'env': [
                 {
                     'key': 'a',
                     'value': '1'
                 },
             ],
             'execution_timeout_secs':
             '10',
             'extra_args': [
                 '--flag=value',
                 '--gtest_filter=a.b:a.c',
                 '--gtest_repeat=30',
                 '--test-launcher-retry-limit=0',
                 '--gtest_also_run_disabled_tests',
             ],
             'grace_period_secs':
             '30',
             'idempotent':
             False,
             'inputs_ref': {
                 'isolatedserver': 'isolatedserver',
                 'isolated': 'sha'
             },
             'io_timeout_secs':
             '1200',
         },
         'tags': [
             'ref_master:m',
             'ref_buildername:b',
             'ref_buildnumber:4',
             'ref_stepname:s',
             'ref_name:test',
         ],
         'user':
         '',
         'pubsub_auth_token':
         'auth_token',
         'pubsub_topic':
         'projects/app-id/topics/swarming',
         'pubsub_userdata':
         json.dumps({'runner_id': 'runner_id'}),
     }
     test_swarming.OnSwarmingTaskTriggered(
         master_name, builder_name, build_number, step_name, tests,
         'task_id', iterations,
         SwarmingTaskRequest.FromSerializable(new_request))
     task = WfSwarmingTask.Get(master_name, builder_name, build_number,
                               step_name)
     self.assertEqual(task.task_id, task_id)
示例#21
0
 def _GetSwarmingTask(self, master_name, builder_name, build_number,
                      step_name):
     # Gets the appropriate kind of swarming task (WfSwarmingTask).
     return WfSwarmingTask.Get(master_name, builder_name, build_number,
                               step_name)