Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1144)

Side by Side Diff: appengine/findit/waterfall/trigger_swarming_task_pipeline.py

Issue 2508603002: [Findit] Refactoring trigger swarming task pipelines (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « appengine/findit/waterfall/trigger_flake_swarming_task_pipeline.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2016 The Chromium Authors. All rights reserved. 1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import copy
6 import logging
7 import time
8
9 from google.appengine.ext import ndb
10
11 from common.http_client_appengine import HttpClientAppengine as HttpClient
12 from common.pipeline_wrapper import BasePipeline
13 from lib import time_util
14 from model import analysis_status
15 from model.wf_swarming_task import WfSwarmingTask 5 from model.wf_swarming_task import WfSwarmingTask
16 from waterfall import swarming_util
17 from waterfall import waterfall_config 6 from waterfall import waterfall_config
7 from waterfall.trigger_base_swarming_task_pipeline import (
8 TriggerBaseSwarmingTaskPipeline)
18 9
19 10
20 def _GetSwarmingTaskName(ref_task_id): # pragma: no cover. 11 class TriggerSwarmingTaskPipeline(TriggerBaseSwarmingTaskPipeline):
21 """Returns a unique task name.
22
23 Have this separate function in order to mock for testing purpose.
24 """
25 return 'findit/deflake/ref_task_id/%s/%s' % (
26 ref_task_id, time_util.GetUTCNow().strftime('%Y-%m-%d %H:%M:%S %f'))
27
28
29 def _CreateNewSwarmingTaskRequest(
30 ref_task_id, ref_request, master_name, builder_name, build_number,
31 step_name, tests, iterations):
32 """Returns a SwarmingTaskRequest instance to run the given tests only."""
33 # Make a copy of the referred request and drop or overwrite some fields.
34 new_request = copy.deepcopy(ref_request)
35 new_request.name = _GetSwarmingTaskName(ref_task_id)
36 new_request.parent_task_id = ''
37 new_request.user = ''
38
39 # To force a fresh re-run and ignore cached result of any equivalent run.
40 new_request.idempotent = False
41
42 # Set the gtest_filter to run the given tests only.
43 new_request.extra_args.append('--gtest_repeat=%s' % iterations)
44 new_request.extra_args.append('--test-launcher-retry-limit=0')
45 new_request.extra_args = [
46 a for a in new_request.extra_args if not a.startswith('--gtest_filter')
47 ]
48 new_request.extra_args.append('--gtest_filter=%s' % ':'.join(tests))
49
50 # Remove the env setting for sharding.
51 sharding_settings = ['GTEST_SHARD_INDEX', 'GTEST_TOTAL_SHARDS']
52 new_request.env = [
53 e for e in new_request.env if e['key'] not in sharding_settings
54 ]
55
56 # Reset tags for searching and monitoring.
57 ref_name = swarming_util.GetTagValue(ref_request.tags, 'name')
58 new_request.tags = []
59 new_request.tags.append('purpose:deflake')
60 new_request.tags.append('ref_master:%s' % master_name)
61 new_request.tags.append('ref_buildername:%s' % builder_name)
62 new_request.tags.append('ref_buildnumber:%s' % build_number)
63 new_request.tags.append('ref_stepname:%s' % step_name)
64 new_request.tags.append('ref_task_id:%s' % ref_task_id)
65 new_request.tags.append('ref_name:%s' % ref_name)
66
67 return new_request
68
69
70 @ndb.transactional
71 def _NeedANewSwarmingTask(master_name, builder_name, build_number, step_name):
72 swarming_task = WfSwarmingTask.Get(
73 master_name, builder_name, build_number, step_name)
74
75 if not swarming_task:
76 swarming_task = WfSwarmingTask.Create(
77 master_name, builder_name, build_number, step_name)
78 swarming_task.status = analysis_status.PENDING
79 swarming_task.put()
80 return True
81 else:
82 # TODO(http://crbug.com/585676): Rerun the Swarming task if it runs into
83 # unexpected infra errors.
84 return False
85
86
87 def _GetSwarmingTaskId(master_name, builder_name, build_number, step_name):
88 deadline = time.time() + 5 * 60 # Wait for 5 minutes.
89 while time.time() < deadline:
90 swarming_task = WfSwarmingTask.Get(
91 master_name, builder_name, build_number, step_name)
92
93 if not swarming_task: # pragma: no cover. Pipeline will retry.
94 raise Exception('Swarming task was deleted unexpectedly!!!')
95
96 if swarming_task.task_id:
97 return swarming_task.task_id
98
99 time.sleep(10) # Wait for the existing pipeline to start the Swarming task.
100
101 raise Exception('Time out!') # pragma: no cover. Pipeline will retry.
102
103
104 class TriggerSwarmingTaskPipeline(BasePipeline):
105 """A pipeline to trigger a Swarming task to re-run selected tests of a step. 12 """A pipeline to trigger a Swarming task to re-run selected tests of a step.
106 13
107 This pipeline only supports test steps that run on Swarming and support the 14 This pipeline only supports test steps that run on Swarming and support the
108 gtest filter. 15 gtest filter.
109 """ 16 """
110 17
18 def _GetArgs(self, master_name, builder_name, build_number, step_name, _):
19 return master_name, builder_name, build_number, step_name
20
111 # Arguments number differs from overridden method - pylint: disable=W0221 21 # Arguments number differs from overridden method - pylint: disable=W0221
112 def run(self, master_name, builder_name, build_number, step_name, tests): 22 def _GetSwarmingTask(
113 """Triggers a new Swarming task to run the given tests. 23 self, master_name, builder_name, build_number, step_name):
24 return WfSwarmingTask.Get(
25 master_name, builder_name, build_number, step_name)
114 26
115 Args: 27 # Arguments number differs from overridden method - pylint: disable=W0221
116 master_name (str): The master name. 28 def _CreateSwarmingTask(
117 builder_name (str): The builder name. 29 self, master_name, builder_name, build_number, step_name):
118 build_number (str): The build number. 30 return WfSwarmingTask.Create(
119 step_name (str): The failed test step name. 31 master_name, builder_name, build_number, step_name)
120 tests (list): A list of test cases, eg: ['suite1.test1', 'suite2.test2'].
121 32
122 Returns: 33 def _GetIterationsToRerun(self):
123 task_id (str): The new Swarming task that re-run the given tests. 34 return waterfall_config.GetSwarmingSettings().get('iterations_to_rerun')
124 """
125 # Check if a new Swarming Task is really needed.
126 if not _NeedANewSwarmingTask(
127 master_name, builder_name, build_number, step_name):
128 return _GetSwarmingTaskId(
129 master_name, builder_name, build_number, step_name)
130
131 assert tests
132
133 http_client = HttpClient()
134
135 # 0. Retrieve existing Swarming task ids for the given step.
136 swarming_task_items = swarming_util.ListSwarmingTasksDataByTags(
137 master_name, builder_name, build_number, http_client,
138 {'stepname': step_name})
139 assert len(swarming_task_items) > 0, 'No Swarming task was run.'
140 ref_task_id = swarming_task_items[0]['task_id']
141
142 # 1. Retrieve Swarming task parameters from a given Swarming task id.
143 ref_request = swarming_util.GetSwarmingTaskRequest(
144 ref_task_id, http_client)
145
146 # 2. Update/Overwrite parameters for the re-run.
147 iterations_to_rerun = waterfall_config.GetSwarmingSettings().get(
148 'iterations_to_rerun')
149 new_request = _CreateNewSwarmingTaskRequest(
150 ref_task_id, ref_request, master_name, builder_name, build_number,
151 step_name, tests, iterations_to_rerun)
152
153 # 3. Trigger a new Swarming task to re-run the failed tests.
154 task_id = swarming_util.TriggerSwarmingTask(new_request, http_client)
155
156 # Save the task id.
157 swarming_task = WfSwarmingTask.Get(
158 master_name, builder_name, build_number, step_name)
159 swarming_task.task_id = task_id
160 swarming_task.parameters['tests'] = tests
161 swarming_task.parameters['iterations_to_rerun'] = iterations_to_rerun
162 swarming_task.parameters['ref_name'] = swarming_util.GetTagValue(
163 new_request.tags, 'ref_name')
164 swarming_task.put()
165
166 logging.info('A Swarming task was triggered:%s', task_id)
167 return task_id
OLDNEW
« no previous file with comments | « appengine/findit/waterfall/trigger_flake_swarming_task_pipeline.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698