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

Unified Diff: dashboard/dashboard/pinpoint/models/quest/run_test.py

Issue 3010873003: [pinpoint] Limit executions to one test run each + device sharding. (Closed)
Patch Set: Ready! Created 3 years, 3 months 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 side-by-side diff with in-line comments
Download patch
Index: dashboard/dashboard/pinpoint/models/quest/run_test.py
diff --git a/dashboard/dashboard/pinpoint/models/quest/run_test.py b/dashboard/dashboard/pinpoint/models/quest/run_test.py
index 8ee61cce3b77401cd6f3303e1af261fc14e95eb3..996a289cc1d7b47f0f4e5bb63034412b17aa6e64 100644
--- a/dashboard/dashboard/pinpoint/models/quest/run_test.py
+++ b/dashboard/dashboard/pinpoint/models/quest/run_test.py
@@ -8,6 +8,8 @@ This is the only Quest/Execution where the Execution has a reference back to
modify the Quest.
"""
+import collections
+
from dashboard.pinpoint.models.quest import execution as execution_module
from dashboard.pinpoint.models.quest import quest
from dashboard.services import swarming_service
@@ -53,25 +55,32 @@ class RunTest(quest.Quest):
self._extra_args = extra_args
# We want subsequent executions use the same bot as the first one.
- self._first_execution = None
+ self._canonical_executions = []
+ self._execution_counts = collections.defaultdict(int)
def __eq__(self, other):
return (isinstance(other, type(self)) and
self._dimensions == other._dimensions and
self._extra_args == other._extra_args and
- self._first_execution == other._first_execution)
+ self._canonical_executions == other._canonical_executions and
+ self._execution_counts == other._execution_counts)
def __str__(self):
return 'Test'
- def Start(self, isolate_hash):
- execution = _RunTestExecution(
- self._dimensions, self._extra_args, isolate_hash,
- first_execution=self._first_execution)
+ def Start(self, change, isolate_hash):
+ index = self._execution_counts[change]
+ self._execution_counts[change] += 1
- if not self._first_execution:
- self._first_execution = execution
+ if len(self._canonical_executions) <= index:
+ execution = _RunTestExecution(
+ self._dimensions, self._extra_args, isolate_hash)
+ self._canonical_executions.append(execution)
+ else:
+ execution = _RunTestExecution(
+ self._dimensions, self._extra_args, isolate_hash,
+ previous_execution=self._canonical_executions[index])
return execution
@@ -79,62 +88,59 @@ class RunTest(quest.Quest):
class _RunTestExecution(execution_module.Execution):
def __init__(self, dimensions, extra_args, isolate_hash,
- first_execution=None):
+ previous_execution=None):
super(_RunTestExecution, self).__init__()
self._dimensions = dimensions
self._extra_args = extra_args
self._isolate_hash = isolate_hash
- self._first_execution = first_execution
+ self._previous_execution = previous_execution
- self._task_ids = []
- self._bot_ids = []
+ self._task_id = None
+ self._bot_id = None
@property
- def bot_ids(self):
- return tuple(self._bot_ids)
+ def bot_id(self):
+ return self._bot_id
def _AsDict(self):
return {
- 'bot_ids': self._bot_ids,
- 'task_ids': self._task_ids,
+ 'bot_id': self._bot_id,
+ 'task_id': self._task_id,
'input_isolate_hash': self._isolate_hash,
}
def _Poll(self):
- if not self._task_ids:
+ if not self._task_id:
self._StartTask()
return
- self._bot_ids = []
- isolate_hashes = []
- for task_id in self._task_ids:
- result = swarming_service.Task(task_id).Result()
+ result = swarming_service.Task(self._task_id).Result()
- if 'bot_id' in result:
- # Set bot_id to pass the info back to the Quest.
- self._bot_ids.append(result['bot_id'])
+ if 'bot_id' in result:
+ # Set bot_id to pass the info back to the Quest.
+ self._bot_id = result['bot_id']
- if result['state'] == 'PENDING' or result['state'] == 'RUNNING':
- return
+ if result['state'] == 'PENDING' or result['state'] == 'RUNNING':
+ return
- if result['state'] != 'COMPLETED':
- raise SwarmingTaskError(task_id, result['state'])
+ if result['state'] != 'COMPLETED':
+ raise SwarmingTaskError(self._task_id, result['state'])
- if result['failure']:
- raise SwarmingTestError(task_id, result['exit_code'])
+ if result['failure']:
+ raise SwarmingTestError(self._task_id, result['exit_code'])
- isolate_hashes.append(result['outputs_ref']['isolated'])
+ isolate_hash = result['outputs_ref']['isolated']
- result_arguments = {'isolate_hashes': tuple(isolate_hashes)}
+ result_arguments = {'isolate_hash': isolate_hash}
self._Complete(result_arguments=result_arguments)
def _StartTask(self):
"""Kick off a Swarming task to run a test."""
- if self._first_execution and not self._first_execution.bot_ids:
- if self._first_execution.failed:
- # If the first Execution fails before it gets a bot ID, it's likely it
- # couldn't find any device to run on. Subsequent Executions probably
+ if self._previous_execution and not self._previous_execution.bot_id:
+ if self._previous_execution.failed:
+ # If the previous Execution fails before it gets a bot ID, it's likely
+ # it couldn't find any device to run on. Subsequent Executions probably
# wouldn't have any better luck, and failing fast is less complex than
# handling retries.
raise RunTestError('There are no bots available to run the test.')
@@ -142,11 +148,10 @@ class _RunTestExecution(execution_module.Execution):
return
dimensions = [{'key': 'pool', 'value': 'Chrome-perf-pinpoint'}]
- if self._first_execution:
+ if self._previous_execution:
dimensions.append({
'key': 'id',
- # TODO: Use all the bot ids.
- 'value': self._first_execution.bot_ids[0]
+ 'value': self._previous_execution.bot_id
})
else:
dimensions += self._dimensions
@@ -166,4 +171,4 @@ class _RunTestExecution(execution_module.Execution):
}
response = swarming_service.Tasks().New(body)
- self._task_ids.append(response['task_id'])
+ self._task_id = response['task_id']

Powered by Google App Engine
This is Rietveld 408576698