| Index: appengine/findit/waterfall/schedule_test_try_job_pipeline.py
|
| diff --git a/appengine/findit/waterfall/schedule_test_try_job_pipeline.py b/appengine/findit/waterfall/schedule_test_try_job_pipeline.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a6ad02843c919ca636029afe203795d98950527d
|
| --- /dev/null
|
| +++ b/appengine/findit/waterfall/schedule_test_try_job_pipeline.py
|
| @@ -0,0 +1,81 @@
|
| +# Copyright 2016 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +from collections import defaultdict
|
| +import logging
|
| +
|
| +from common.waterfall import failure_type
|
| +from model.wf_try_job import WfTryJob
|
| +from waterfall.schedule_try_job_pipeline import ScheduleTryJobPipeline
|
| +
|
| +
|
| +def _GetTargetedTests(reliable_tests):
|
| + targeted_tests = defaultdict(list)
|
| + for step_reliable_tests in reliable_tests.itervalues():
|
| + step_name_no_platform = step_reliable_tests[0]
|
| + tests = step_reliable_tests[1]
|
| + if tests:
|
| + targeted_tests[step_name_no_platform].extend(tests)
|
| + return targeted_tests
|
| +
|
| +
|
| +class ScheduleTestTryJobPipeline(ScheduleTryJobPipeline):
|
| + """A pipeline for scheduling a new try job for failed test build."""
|
| +
|
| + def _GetBuildProperties(
|
| + self, master_name, builder_name, build_number, good_revision,
|
| + bad_revision, try_job_type, suspected_revisions):
|
| + properties = super(ScheduleTestTryJobPipeline, self)._GetBuildProperties(
|
| + master_name, builder_name, build_number, good_revision,
|
| + bad_revision, try_job_type, suspected_revisions)
|
| + properties['target_testername'] = builder_name
|
| +
|
| + return properties
|
| +
|
| + # Arguments number differs from overridden method - pylint: disable=W0221
|
| + def run(
|
| + self, master_name, builder_name, build_number, good_revision,
|
| + bad_revision, try_job_type, suspected_revisions, *reliable_tests):
|
| + """
|
| + Args:
|
| + master_name (str): the master name of a build.
|
| + builder_name (str): the builder name of a build.
|
| + build_number (int): the build number of a build.
|
| + good_revision (str): the revision of the last passed build.
|
| + bad__revision (str): the revision of the first failed build.
|
| + try_job_type (int): type of the try job: TEST in this case.
|
| + suspected_revisions (list): a list of suspected revisions from heuristic.
|
| + reliable_tests (list): a list of reliable failed tests.
|
| +
|
| + Returns:
|
| + build_id (str): id of the triggered try job.
|
| + """
|
| +
|
| + properties = self._GetBuildProperties(
|
| + master_name, builder_name, build_number, good_revision, bad_revision,
|
| + try_job_type, suspected_revisions)
|
| +
|
| + targeted_tests = _GetTargetedTests(dict(reliable_tests))
|
| + if not targeted_tests: # pragma: no cover
|
| + logging.info('All tests are flaky, no try job will be triggered.')
|
| + return
|
| +
|
| + additional_parameters = {'tests': targeted_tests}
|
| +
|
| + build_id = self._TriggerTryJob(
|
| + master_name, builder_name, properties, additional_parameters)
|
| +
|
| + try_job_result = WfTryJob.Get(master_name, builder_name, build_number)
|
| + try_job_result.test_results.append({'try_job_id': build_id})
|
| + try_job_result.try_job_ids.append(build_id)
|
| + try_job_result.put()
|
| +
|
| + # Create a corresponding WfTryJobData entity to capture as much metadata as
|
| + # early as possible.
|
| + self._CreateTryJobData(
|
| + build_id, master_name, builder_name, build_number,
|
| + failure_type.GetDescriptionForFailureType(try_job_type),
|
| + False, bool(suspected_revisions))
|
| +
|
| + return build_id
|
|
|