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

Side by Side Diff: dashboard/dashboard/pinpoint/models/quest/run_test_test.py

Issue 2996473002: [pinpoint] Add QuestGenerator object. (Closed)
Patch Set: rebase Created 3 years, 4 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 unified diff | Download patch
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 unittest 5 import unittest
6 6
7 import mock 7 import mock
8 8
9 from dashboard.pinpoint.models.quest import run_test 9 from dashboard.pinpoint.models.quest import run_test
10 10
11 11
12 _SWARMING_TASK_EXTRA_ARGS = [ 12 _SWARMING_EXTRA_ARGS = [
13 'test_suite', '--story-filter', 'test', 13 'benchmark', '--story-filter', 'story',
14 '-v', '--upload-results', 14 '-v', '--upload-results',
15 '--output-format=chartjson', '--browser=release', 15 '--output-format=chartjson', '--browser=release',
16 '--isolated-script-test-output=${ISOLATED_OUTDIR}/output.json', 16 '--isolated-script-test-output=${ISOLATED_OUTDIR}/output.json',
17 '--isolated-script-test-chartjson-output=' 17 '--isolated-script-test-chartjson-output='
18 '${ISOLATED_OUTDIR}/chartjson-output.json', 18 '${ISOLATED_OUTDIR}/chartjson-output.json',
19 ] 19 ]
20 20
21 _SWARMING_DIMENSIONS = [
22 {"key": "cores", "value": "8"},
23 {"key": "gpu", "value": "1002:6821"},
24 {"key": "os", "value": "Mac-10.11"},
25 ]
26
21 27
22 class _RunTestTest(unittest.TestCase): 28 class _RunTestTest(unittest.TestCase):
23 29
24 def assertNewTaskHasDimensions(self, swarming_tasks_new): 30 def assertNewTaskHasDimensions(self, swarming_tasks_new):
25 body = { 31 body = {
26 'name': 'Pinpoint job on chromium-rel-mac11-pro', 32 'name': 'Pinpoint job',
27 'user': 'Pinpoint', 33 'user': 'Pinpoint',
28 'priority': '100', 34 'priority': '100',
29 'expiration_secs': '600', 35 'expiration_secs': '600',
30 'properties': { 36 'properties': {
31 'inputs_ref': {'isolated': 'input isolate hash'}, 37 'inputs_ref': {'isolated': 'input isolate hash'},
32 'extra_args': _SWARMING_TASK_EXTRA_ARGS, 38 'extra_args': _SWARMING_EXTRA_ARGS,
33 'dimensions': [ 39 'dimensions': [{'key': 'pool', 'value': 'Chrome-perf-pinpoint'}] +
34 {'key': 'pool', 'value': 'Chrome-perf-pinpoint'}, 40 _SWARMING_DIMENSIONS,
35 {"key": "cores", "value": "8"},
36 {"key": "gpu", "value": "1002:6821"},
37 {"key": "os", "value": "Mac-10.11"},
38 ],
39 'execution_timeout_secs': '3600', 41 'execution_timeout_secs': '3600',
40 'io_timeout_secs': '3600', 42 'io_timeout_secs': '3600',
41 }, 43 },
42 'tags': [
43 'configuration:chromium-rel-mac11-pro',
44 ],
45 } 44 }
46 swarming_tasks_new.assert_called_with(body) 45 swarming_tasks_new.assert_called_with(body)
47 46
48 def assertNewTaskHasBotId(self, swarming_tasks_new): 47 def assertNewTaskHasBotId(self, swarming_tasks_new):
49 body = { 48 body = {
50 'name': 'Pinpoint job on chromium-rel-mac11-pro', 49 'name': 'Pinpoint job',
51 'user': 'Pinpoint', 50 'user': 'Pinpoint',
52 'priority': '100', 51 'priority': '100',
53 'expiration_secs': '600', 52 'expiration_secs': '600',
54 'properties': { 53 'properties': {
55 'inputs_ref': {'isolated': 'input isolate hash'}, 54 'inputs_ref': {'isolated': 'input isolate hash'},
56 'extra_args': _SWARMING_TASK_EXTRA_ARGS, 55 'extra_args': _SWARMING_EXTRA_ARGS,
57 'dimensions': [ 56 'dimensions': [
58 {'key': 'pool', 'value': 'Chrome-perf-pinpoint'}, 57 {'key': 'pool', 'value': 'Chrome-perf-pinpoint'},
59 {'key': 'id', 'value': 'bot id'}, 58 {'key': 'id', 'value': 'bot id'},
60 ], 59 ],
61 'execution_timeout_secs': '3600', 60 'execution_timeout_secs': '3600',
62 'io_timeout_secs': '3600', 61 'io_timeout_secs': '3600',
63 }, 62 },
64 'tags': [
65 'configuration:chromium-rel-mac11-pro',
66 ],
67 } 63 }
68 swarming_tasks_new.assert_called_with(body) 64 swarming_tasks_new.assert_called_with(body)
69 65
70 66
71 @mock.patch('dashboard.services.swarming_service.Tasks.New') 67 @mock.patch('dashboard.services.swarming_service.Tasks.New')
72 @mock.patch('dashboard.services.swarming_service.Task.Result') 68 @mock.patch('dashboard.services.swarming_service.Task.Result')
73 class RunTestFullTest(_RunTestTest): 69 class RunTestFullTest(_RunTestTest):
74 70
75 def testSuccess(self, swarming_task_result, swarming_tasks_new): 71 def testSuccess(self, swarming_task_result, swarming_tasks_new):
76 # Goes through a full run of two Executions. 72 # Goes through a full run of two Executions.
77 73
78 # Call RunTest.Start() to create an Execution. 74 # Call RunTest.Start() to create an Execution.
79 quest = run_test.RunTest('chromium-rel-mac11-pro', 'test_suite', 'test', 1) 75 quest = run_test.RunTest(_SWARMING_DIMENSIONS, _SWARMING_EXTRA_ARGS)
80 execution = quest.Start('input isolate hash') 76 execution = quest.Start('input isolate hash')
81 77
82 swarming_task_result.assert_not_called() 78 swarming_task_result.assert_not_called()
83 swarming_tasks_new.assert_not_called() 79 swarming_tasks_new.assert_not_called()
84 80
85 # Call the first Poll() to start the swarming task. 81 # Call the first Poll() to start the swarming task.
86 swarming_tasks_new.return_value = {'task_id': 'task id'} 82 swarming_tasks_new.return_value = {'task_id': 'task id'}
87 execution.Poll() 83 execution.Poll()
88 84
89 swarming_task_result.assert_not_called() 85 swarming_task_result.assert_not_called()
(...skipping 26 matching lines...) Expand all
116 112
117 # Start a second Execution to check bot_id handling. We get a bot_id from 113 # Start a second Execution to check bot_id handling. We get a bot_id from
118 # Swarming from the first Execution and reuse it in subsequent Executions. 114 # Swarming from the first Execution and reuse it in subsequent Executions.
119 execution = quest.Start('input isolate hash') 115 execution = quest.Start('input isolate hash')
120 execution.Poll() 116 execution.Poll()
121 117
122 self.assertNewTaskHasBotId(swarming_tasks_new) 118 self.assertNewTaskHasBotId(swarming_tasks_new)
123 119
124 120
125 @mock.patch('dashboard.services.swarming_service.Tasks.New') 121 @mock.patch('dashboard.services.swarming_service.Tasks.New')
126 class SwarmingTaskStartTest(_RunTestTest):
127
128 def testPagesetRepeat(self, swarming_tasks_new):
129 quest = run_test.RunTest('chromium-rel-mac11-pro', 'test_suite', 'test', 10)
130 execution = quest.Start('input isolate hash')
131 execution.Poll()
132
133 new_call_body = swarming_tasks_new.call_args[0][0]
134 self.assertIn('--pageset-repeat', new_call_body['properties']['extra_args'])
135 self.assertIn('10', new_call_body['properties']['extra_args'])
136
137 @mock.patch('dashboard.services.swarming_service.Task.Result')
138 def testUnknownConfig(self, swarming_task_result, swarming_tasks_new):
139 quest = run_test.RunTest('configuration', 'test_suite', 'test', 1)
140 execution = quest.Start('input isolate hash')
141 execution.Poll()
142
143 swarming_task_result.assert_not_called()
144 swarming_tasks_new.assert_not_called()
145 self.assertTrue(execution.completed)
146 self.assertTrue(execution.failed)
147 self.assertEqual(len(execution.result_values), 1)
148 self.assertIsInstance(execution.result_values[0], basestring)
149 last_exception_line = execution.result_values[0].splitlines()[-1]
150 self.assertTrue(last_exception_line.startswith('UnknownConfigError'))
151
152
153 @mock.patch('dashboard.services.swarming_service.Tasks.New')
154 @mock.patch('dashboard.services.swarming_service.Task.Result') 122 @mock.patch('dashboard.services.swarming_service.Task.Result')
155 class SwarmingTaskStatusTest(_RunTestTest): 123 class SwarmingTaskStatusTest(_RunTestTest):
156 124
157 def testSwarmingError(self, swarming_task_result, swarming_tasks_new): 125 def testSwarmingError(self, swarming_task_result, swarming_tasks_new):
158 swarming_task_result.return_value = {'state': 'BOT_DIED'} 126 swarming_task_result.return_value = {'state': 'BOT_DIED'}
159 swarming_tasks_new.return_value = {'task_id': 'task id'} 127 swarming_tasks_new.return_value = {'task_id': 'task id'}
160 128
161 quest = run_test.RunTest('chromium-rel-mac11-pro', 'test_suite', 'test', 1) 129 quest = run_test.RunTest(_SWARMING_DIMENSIONS, _SWARMING_EXTRA_ARGS)
162 execution = quest.Start('input isolate hash') 130 execution = quest.Start('input isolate hash')
163 execution.Poll() 131 execution.Poll()
164 execution.Poll() 132 execution.Poll()
165 133
166 self.assertTrue(execution.completed) 134 self.assertTrue(execution.completed)
167 self.assertTrue(execution.failed) 135 self.assertTrue(execution.failed)
168 self.assertEqual(len(execution.result_values), 1) 136 self.assertEqual(len(execution.result_values), 1)
169 self.assertIsInstance(execution.result_values[0], basestring) 137 self.assertIsInstance(execution.result_values[0], basestring)
170 last_exception_line = execution.result_values[0].splitlines()[-1] 138 last_exception_line = execution.result_values[0].splitlines()[-1]
171 self.assertTrue(last_exception_line.startswith('SwarmingTaskError')) 139 self.assertTrue(last_exception_line.startswith('SwarmingTaskError'))
172 140
173 def testTestError(self, swarming_task_result, swarming_tasks_new): 141 def testTestError(self, swarming_task_result, swarming_tasks_new):
174 swarming_task_result.return_value = { 142 swarming_task_result.return_value = {
175 'bot_id': 'bot id', 143 'bot_id': 'bot id',
176 'exit_code': 1, 144 'exit_code': 1,
177 'failure': True, 145 'failure': True,
178 'state': 'COMPLETED', 146 'state': 'COMPLETED',
179 } 147 }
180 swarming_tasks_new.return_value = {'task_id': 'task id'} 148 swarming_tasks_new.return_value = {'task_id': 'task id'}
181 149
182 quest = run_test.RunTest('chromium-rel-mac11-pro', 'test_suite', 'test', 1) 150 quest = run_test.RunTest(_SWARMING_DIMENSIONS, _SWARMING_EXTRA_ARGS)
183 execution = quest.Start('isolate_hash') 151 execution = quest.Start('isolate_hash')
184 execution.Poll() 152 execution.Poll()
185 execution.Poll() 153 execution.Poll()
186 154
187 self.assertTrue(execution.completed) 155 self.assertTrue(execution.completed)
188 self.assertTrue(execution.failed) 156 self.assertTrue(execution.failed)
189 self.assertEqual(len(execution.result_values), 1) 157 self.assertEqual(len(execution.result_values), 1)
190 self.assertIsInstance(execution.result_values[0], basestring) 158 self.assertIsInstance(execution.result_values[0], basestring)
191 last_exception_line = execution.result_values[0].splitlines()[-1] 159 last_exception_line = execution.result_values[0].splitlines()[-1]
192 self.assertTrue(last_exception_line.startswith('SwarmingTestError')) 160 self.assertTrue(last_exception_line.startswith('SwarmingTestError'))
193 161
194 162
195 @mock.patch('dashboard.services.swarming_service.Tasks.New') 163 @mock.patch('dashboard.services.swarming_service.Tasks.New')
196 @mock.patch('dashboard.services.swarming_service.Task.Result') 164 @mock.patch('dashboard.services.swarming_service.Task.Result')
197 class BotIdHandlingTest(_RunTestTest): 165 class BotIdHandlingTest(_RunTestTest):
198 166
199 def testFirstExecutionFailedWithNoBotId( 167 def testFirstExecutionFailedWithNoBotId(
200 self, swarming_task_result, swarming_tasks_new): 168 self, swarming_task_result, swarming_tasks_new):
201 # If the first Execution fails before it gets a bot ID, it's likely it 169 # If the first Execution fails before it gets a bot ID, it's likely it
202 # couldn't find any device to run on. Subsequent Executions probably 170 # couldn't find any device to run on. Subsequent Executions probably
203 # wouldn't have any better luck, and failing fast is less complex than 171 # wouldn't have any better luck, and failing fast is less complex than
204 # handling retries. 172 # handling retries.
205 swarming_tasks_new.return_value = {'task_id': 'task id'} 173 swarming_tasks_new.return_value = {'task_id': 'task id'}
206 swarming_task_result.return_value = {'state': 'EXPIRED'} 174 swarming_task_result.return_value = {'state': 'EXPIRED'}
207 175
208 quest = run_test.RunTest('chromium-rel-mac11-pro', 'test_suite', 'test', 1) 176 quest = run_test.RunTest(_SWARMING_DIMENSIONS, _SWARMING_EXTRA_ARGS)
209 execution = quest.Start('input isolate hash') 177 execution = quest.Start('input isolate hash')
210 execution.Poll() 178 execution.Poll()
211 execution.Poll() 179 execution.Poll()
212 180
213 swarming_task_result.return_value = { 181 swarming_task_result.return_value = {
214 'bot_id': 'bot id', 182 'bot_id': 'bot id',
215 'exit_code': 0, 183 'exit_code': 0,
216 'failure': False, 184 'failure': False,
217 'outputs_ref': {'isolated': 'output isolate hash'}, 185 'outputs_ref': {'isolated': 'output isolate hash'},
218 'state': 'COMPLETED', 186 'state': 'COMPLETED',
219 } 187 }
220 execution = quest.Start('input isolate hash') 188 execution = quest.Start('input isolate hash')
221 execution.Poll() 189 execution.Poll()
222 190
223 self.assertTrue(execution.completed) 191 self.assertTrue(execution.completed)
224 self.assertTrue(execution.failed) 192 self.assertTrue(execution.failed)
225 self.assertEqual(len(execution.result_values), 1) 193 self.assertEqual(len(execution.result_values), 1)
226 self.assertIsInstance(execution.result_values[0], basestring) 194 self.assertIsInstance(execution.result_values[0], basestring)
227 last_exception_line = execution.result_values[0].splitlines()[-1] 195 last_exception_line = execution.result_values[0].splitlines()[-1]
228 self.assertTrue(last_exception_line.startswith('RunTestError')) 196 self.assertTrue(last_exception_line.startswith('RunTestError'))
229 197
230 def testSimultaneousExecutions(self, swarming_task_result, 198 def testSimultaneousExecutions(self, swarming_task_result,
231 swarming_tasks_new): 199 swarming_tasks_new):
232 # Executions after the first must wait for the first execution to get a bot 200 # Executions after the first must wait for the first execution to get a bot
233 # ID. To preserve device affinity, they must use the same bot. 201 # ID. To preserve device affinity, they must use the same bot.
234 quest = run_test.RunTest('chromium-rel-mac11-pro', 'test_suite', 'test', 1) 202 quest = run_test.RunTest(_SWARMING_DIMENSIONS, _SWARMING_EXTRA_ARGS)
235 execution_1 = quest.Start('input isolate hash') 203 execution_1 = quest.Start('input isolate hash')
236 execution_2 = quest.Start('input isolate hash') 204 execution_2 = quest.Start('input isolate hash')
237 205
238 swarming_tasks_new.return_value = {'task_id': 'task id'} 206 swarming_tasks_new.return_value = {'task_id': 'task id'}
239 swarming_task_result.return_value = {'state': 'PENDING'} 207 swarming_task_result.return_value = {'state': 'PENDING'}
240 execution_1.Poll() 208 execution_1.Poll()
241 execution_2.Poll() 209 execution_2.Poll()
242 210
243 self.assertEqual(swarming_tasks_new.call_count, 1) 211 self.assertEqual(swarming_tasks_new.call_count, 1)
244 212
245 swarming_task_result.return_value = { 213 swarming_task_result.return_value = {
246 'bot_id': 'bot id', 214 'bot_id': 'bot id',
247 'exit_code': 0, 215 'exit_code': 0,
248 'failure': False, 216 'failure': False,
249 'outputs_ref': {'isolated': 'output isolate hash'}, 217 'outputs_ref': {'isolated': 'output isolate hash'},
250 'state': 'COMPLETED', 218 'state': 'COMPLETED',
251 } 219 }
252 execution_1.Poll() 220 execution_1.Poll()
253 execution_2.Poll() 221 execution_2.Poll()
254 222
255 self.assertEqual(swarming_tasks_new.call_count, 2) 223 self.assertEqual(swarming_tasks_new.call_count, 2)
OLDNEW
« no previous file with comments | « dashboard/dashboard/pinpoint/models/quest/run_test.py ('k') | dashboard/dashboard/pinpoint/models/quest_generator.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698