OLD | NEW |
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 """Quest and Execution for running a test in Swarming. | 5 """Quest and Execution for running a test in Swarming. |
6 | 6 |
7 This is the only Quest/Execution where the Execution has a reference back to | 7 This is the only Quest/Execution where the Execution has a reference back to |
8 modify the Quest. | 8 modify the Quest. |
9 """ | 9 """ |
10 | 10 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 class _RunTestExecution(execution_module.Execution): | 83 class _RunTestExecution(execution_module.Execution): |
84 | 84 |
85 def __init__(self, dimensions, extra_args, isolate_hash, | 85 def __init__(self, dimensions, extra_args, isolate_hash, |
86 first_execution=None): | 86 first_execution=None): |
87 super(_RunTestExecution, self).__init__() | 87 super(_RunTestExecution, self).__init__() |
88 self._dimensions = dimensions | 88 self._dimensions = dimensions |
89 self._extra_args = extra_args | 89 self._extra_args = extra_args |
90 self._isolate_hash = isolate_hash | 90 self._isolate_hash = isolate_hash |
91 self._first_execution = first_execution | 91 self._first_execution = first_execution |
92 | 92 |
93 self._task_id = None | 93 self._task_ids = [] |
94 self._bot_id = None | 94 self._bot_ids = [] |
95 | 95 |
96 @property | 96 @property |
97 def bot_id(self): | 97 def bot_ids(self): |
98 return self._bot_id | 98 return tuple(self._bot_ids) |
99 | 99 |
100 def _Poll(self): | 100 def _Poll(self): |
101 if not self._task_id: | 101 if not self._task_ids: |
102 self._StartTask() | 102 self._StartTask() |
103 return | 103 return |
104 | 104 |
105 result = swarming_service.Task(self._task_id).Result() | 105 isolate_hashes = [] |
| 106 for task_id in self._task_ids: |
| 107 result = swarming_service.Task(task_id).Result() |
106 | 108 |
107 if 'bot_id' in result: | 109 if 'bot_id' in result: |
108 # Set bot_id to pass the info back to the Quest. | 110 # Set bot_id to pass the info back to the Quest. |
109 self._bot_id = result['bot_id'] | 111 self._bot_ids.append(result['bot_id']) |
110 | 112 |
111 if result['state'] == 'PENDING' or result['state'] == 'RUNNING': | 113 if result['state'] == 'PENDING' or result['state'] == 'RUNNING': |
112 return | 114 return |
113 | 115 |
114 if result['state'] != 'COMPLETED': | 116 if result['state'] != 'COMPLETED': |
115 raise SwarmingTaskError(self._task_id, result['state']) | 117 raise SwarmingTaskError(task_id, result['state']) |
116 | 118 |
117 if result['failure']: | 119 if result['failure']: |
118 raise SwarmingTestError(self._task_id, result['exit_code']) | 120 raise SwarmingTestError(task_id, result['exit_code']) |
119 | 121 |
120 result_arguments = {'isolate_hash': result['outputs_ref']['isolated']} | 122 isolate_hashes.append(result['outputs_ref']['isolated']) |
| 123 |
| 124 result_arguments = {'isolate_hashes': tuple(isolate_hashes)} |
121 self._Complete(result_arguments=result_arguments) | 125 self._Complete(result_arguments=result_arguments) |
122 | 126 |
123 | 127 |
124 def _StartTask(self): | 128 def _StartTask(self): |
125 """Kick off a Swarming task to run a test.""" | 129 """Kick off a Swarming task to run a test.""" |
126 if self._first_execution and not self._first_execution._bot_id: | 130 if self._first_execution and not self._first_execution.bot_ids: |
127 if self._first_execution.failed: | 131 if self._first_execution.failed: |
128 # If the first Execution fails before it gets a bot ID, it's likely it | 132 # If the first Execution fails before it gets a bot ID, it's likely it |
129 # couldn't find any device to run on. Subsequent Executions probably | 133 # couldn't find any device to run on. Subsequent Executions probably |
130 # wouldn't have any better luck, and failing fast is less complex than | 134 # wouldn't have any better luck, and failing fast is less complex than |
131 # handling retries. | 135 # handling retries. |
132 raise RunTestError('There are no bots available to run the test.') | 136 raise RunTestError('There are no bots available to run the test.') |
133 else: | 137 else: |
134 return | 138 return |
135 | 139 |
136 dimensions = [{'key': 'pool', 'value': 'Chrome-perf-pinpoint'}] | 140 dimensions = [{'key': 'pool', 'value': 'Chrome-perf-pinpoint'}] |
137 if self._first_execution: | 141 if self._first_execution: |
138 dimensions.append({'key': 'id', 'value': self._first_execution.bot_id}) | 142 dimensions.append({ |
| 143 'key': 'id', |
| 144 # TODO: Use all the bot ids. |
| 145 'value': self._first_execution.bot_ids[0] |
| 146 }) |
139 else: | 147 else: |
140 dimensions += self._dimensions | 148 dimensions += self._dimensions |
141 | 149 |
142 body = { | 150 body = { |
143 'name': 'Pinpoint job', | 151 'name': 'Pinpoint job', |
144 'user': 'Pinpoint', | 152 'user': 'Pinpoint', |
145 'priority': '100', | 153 'priority': '100', |
146 'expiration_secs': '600', | 154 'expiration_secs': '600', |
147 'properties': { | 155 'properties': { |
148 'inputs_ref': {'isolated': self._isolate_hash}, | 156 'inputs_ref': {'isolated': self._isolate_hash}, |
149 'extra_args': self._extra_args, | 157 'extra_args': self._extra_args, |
150 'dimensions': dimensions, | 158 'dimensions': dimensions, |
151 'execution_timeout_secs': '3600', | 159 'execution_timeout_secs': '3600', |
152 'io_timeout_secs': '3600', | 160 'io_timeout_secs': '3600', |
153 }, | 161 }, |
154 } | 162 } |
155 response = swarming_service.Tasks().New(body) | 163 response = swarming_service.Tasks().New(body) |
156 | 164 |
157 self._task_id = response['task_id'] | 165 self._task_ids.append(response['task_id']) |
OLD | NEW |