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

Side by Side Diff: build/android/pylib/remote/device/remote_device_test_run.py

Issue 862133002: Update from https://crrev.com/312398 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 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 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 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 """Run specific test on specific environment.""" 5 """Run specific test on specific environment."""
6 6
7 import json
7 import logging 8 import logging
8 import os 9 import os
9 import sys 10 import sys
10 import tempfile 11 import tempfile
11 import time 12 import time
12 import zipfile 13 import zipfile
13 14
14 from pylib import constants 15 from pylib import constants
15 from pylib.base import test_run 16 from pylib.base import test_run
16 from pylib.remote.device import appurify_sanitized 17 from pylib.remote.device import appurify_sanitized
17 from pylib.remote.device import remote_device_helper 18 from pylib.remote.device import remote_device_helper
18 from pylib.utils import zip_utils 19 from pylib.utils import zip_utils
19 20
20 class RemoteDeviceTestRun(test_run.TestRun): 21 class RemoteDeviceTestRun(test_run.TestRun):
21 """Run gtests and uirobot tests on a remote device.""" 22 """Run gtests and uirobot tests on a remote device."""
22 23
24 _TEST_RUN_KEY = 'test_run'
25 _TEST_RUN_ID_KEY = 'test_run_id'
26
23 WAIT_TIME = 5 27 WAIT_TIME = 5
24 COMPLETE = 'complete' 28 COMPLETE = 'complete'
25 HEARTBEAT_INTERVAL = 300 29 HEARTBEAT_INTERVAL = 300
26 30
27 def __init__(self, env, test_instance): 31 def __init__(self, env, test_instance):
28 """Constructor. 32 """Constructor.
29 33
30 Args: 34 Args:
31 env: Environment the tests will run in. 35 env: Environment the tests will run in.
32 test_instance: The test that will be run. 36 test_instance: The test that will be run.
33 """ 37 """
34 super(RemoteDeviceTestRun, self).__init__(env, test_instance) 38 super(RemoteDeviceTestRun, self).__init__(env, test_instance)
35 self._env = env 39 self._env = env
36 self._test_instance = test_instance 40 self._test_instance = test_instance
37 self._app_id = '' 41 self._app_id = ''
38 self._test_id = '' 42 self._test_id = ''
39 self._results = '' 43 self._results = ''
40 self._test_run_id = '' 44 self._test_run_id = ''
41 45
42 #override 46 #override
47 def SetUp(self):
48 """Set up a test run."""
49 if self._env.trigger:
50 self._TriggerSetUp()
51 elif self._env.collect:
52 assert isinstance(self._env.trigger, basestring), (
53 'File for storing test_run_id must be a string.')
54 with open(self._env.collect, 'r') as persisted_data_file:
55 persisted_data = json.loads(persisted_data_file.read())
56 self._env.LoadFrom(persisted_data)
57 self.LoadFrom(persisted_data)
58
59 def _TriggerSetUp(self):
60 """Set up the triggering of a test run."""
61 raise NotImplementedError
62
63 #override
43 def RunTests(self): 64 def RunTests(self):
44 """Run the test.""" 65 """Run the test."""
45 if self._env.trigger: 66 if self._env.trigger:
46 with appurify_sanitized.SanitizeLogging(self._env.verbose_count, 67 with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
47 logging.WARNING): 68 logging.WARNING):
48 test_start_res = appurify_sanitized.api.tests_run( 69 test_start_res = appurify_sanitized.api.tests_run(
49 self._env.token, self._env.device, self._app_id, self._test_id) 70 self._env.token, self._env.device_type_id, self._app_id,
71 self._test_id)
50 remote_device_helper.TestHttpResponse( 72 remote_device_helper.TestHttpResponse(
51 test_start_res, 'Unable to run test.') 73 test_start_res, 'Unable to run test.')
52 self._test_run_id = test_start_res.json()['response']['test_run_id'] 74 self._test_run_id = test_start_res.json()['response']['test_run_id']
53 logging.info('Test run id: %s' % self._test_run_id) 75 logging.info('Test run id: %s' % self._test_run_id)
54 if not self._env.collect:
55 assert isinstance(self._env.trigger, basestring), (
56 'File for storing test_run_id must be a string.')
57 with open(self._env.trigger, 'w') as test_run_id_file:
58 test_run_id_file.write(self._test_run_id)
59 76
60 if self._env.collect: 77 if self._env.collect:
61 if not self._env.trigger:
62 assert isinstance(self._env.trigger, basestring), (
63 'File for storing test_run_id must be a string.')
64 with open(self._env.collect, 'r') as test_run_id_file:
65 self._test_run_id = test_run_id_file.read().strip()
66 current_status = '' 78 current_status = ''
67 timeout_counter = 0 79 timeout_counter = 0
68 heartbeat_counter = 0 80 heartbeat_counter = 0
69 while self._GetTestStatus(self._test_run_id) != self.COMPLETE: 81 while self._GetTestStatus(self._test_run_id) != self.COMPLETE:
70 if self._results['detailed_status'] != current_status: 82 if self._results['detailed_status'] != current_status:
71 logging.info('Test status: %s', self._results['detailed_status']) 83 logging.info('Test status: %s', self._results['detailed_status'])
72 current_status = self._results['detailed_status'] 84 current_status = self._results['detailed_status']
73 timeout_counter = 0 85 timeout_counter = 0
74 heartbeat_counter = 0 86 heartbeat_counter = 0
75 if heartbeat_counter > self.HEARTBEAT_INTERVAL: 87 if heartbeat_counter > self.HEARTBEAT_INTERVAL:
76 logging.info('Test status: %s', self._results['detailed_status']) 88 logging.info('Test status: %s', self._results['detailed_status'])
77 heartbeat_counter = 0 89 heartbeat_counter = 0
78 90
79 timeout = self._env.timeouts.get( 91 timeout = self._env.timeouts.get(
80 current_status, self._env.timeouts['unknown']) 92 current_status, self._env.timeouts['unknown'])
81 if timeout_counter > timeout: 93 if timeout_counter > timeout:
82 raise remote_device_helper.RemoteDeviceError( 94 raise remote_device_helper.RemoteDeviceError(
83 'Timeout while in %s state for %s seconds' 95 'Timeout while in %s state for %s seconds'
84 % (current_status, timeout)) 96 % (current_status, timeout))
85 time.sleep(self.WAIT_TIME) 97 time.sleep(self.WAIT_TIME)
86 timeout_counter += self.WAIT_TIME 98 timeout_counter += self.WAIT_TIME
87 heartbeat_counter += self.WAIT_TIME 99 heartbeat_counter += self.WAIT_TIME
88 self._DownloadTestResults(self._env.results_path) 100 self._DownloadTestResults(self._env.results_path)
89 return self._ParseTestResults() 101 return self._ParseTestResults()
90 102
91 #override 103 #override
92 def TearDown(self): 104 def TearDown(self):
93 """Tear down the test run.""" 105 """Tear down the test run."""
94 if (self._env.collect 106 if self._env.collect:
95 and self._GetTestStatus(self._test_run_id) != self.COMPLETE): 107 self._CollectTearDown()
108 elif self._env.trigger:
109 assert isinstance(self._env.trigger, basestring), (
110 'File for storing test_run_id must be a string.')
111 with open(self._env.trigger, 'w') as persisted_data_file:
112 persisted_data = {}
113 self.DumpTo(persisted_data)
114 self._env.DumpTo(persisted_data)
115 persisted_data_file.write(json.dumps(persisted_data))
116
117 def _CollectTearDown(self):
118 if self._GetTestStatus(self._test_run_id) != self.COMPLETE:
96 with appurify_sanitized.SanitizeLogging(self._env.verbose_count, 119 with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
97 logging.WARNING): 120 logging.WARNING):
98 test_abort_res = appurify_sanitized.api.tests_abort( 121 test_abort_res = appurify_sanitized.api.tests_abort(
99 self._env.token, self._test_run_id, reason='Test runner exiting.') 122 self._env.token, self._test_run_id, reason='Test runner exiting.')
100 remote_device_helper.TestHttpResponse(test_abort_res, 123 remote_device_helper.TestHttpResponse(test_abort_res,
101 'Unable to abort test.') 124 'Unable to abort test.')
102 125
103 def __enter__(self): 126 def __enter__(self):
104 """Set up the test run when used as a context manager.""" 127 """Set up the test run when used as a context manager."""
105 self.SetUp() 128 self.SetUp()
106 return self 129 return self
107 130
108 def __exit__(self, exc_type, exc_val, exc_tb): 131 def __exit__(self, exc_type, exc_val, exc_tb):
109 """Tear down the test run when used as a context manager.""" 132 """Tear down the test run when used as a context manager."""
110 self.TearDown() 133 self.TearDown()
111 134
112 #override 135 def DumpTo(self, persisted_data):
113 def SetUp(self): 136 test_run_data = {
114 """Set up a test run.""" 137 self._TEST_RUN_ID_KEY: self._test_run_id,
115 if self._env.trigger: 138 }
116 self._TriggerSetUp() 139 persisted_data[self._TEST_RUN_KEY] = test_run_data
117 140
118 def _TriggerSetUp(self): 141 def LoadFrom(self, persisted_data):
119 """Set up the triggering of a test run.""" 142 test_run_data = persisted_data[self._TEST_RUN_KEY]
120 raise NotImplementedError 143 self._test_run_id = test_run_data[self._TEST_RUN_ID_KEY]
121 144
122 def _ParseTestResults(self): 145 def _ParseTestResults(self):
123 raise NotImplementedError 146 raise NotImplementedError
124 147
125 def _GetTestByName(self, test_name): 148 def _GetTestByName(self, test_name):
126 """Gets test_id for specific test. 149 """Gets test_id for specific test.
127 150
128 Args: 151 Args:
129 test_name: Test to find the ID of. 152 test_name: Test to find the ID of.
130 """ 153 """
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 186
164 with appurify_sanitized.SanitizeLogging(self._env.verbose_count, 187 with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
165 logging.WARNING): 188 logging.WARNING):
166 test_check_res = appurify_sanitized.api.tests_check_result( 189 test_check_res = appurify_sanitized.api.tests_check_result(
167 self._env.token, test_run_id) 190 self._env.token, test_run_id)
168 remote_device_helper.TestHttpResponse(test_check_res, 191 remote_device_helper.TestHttpResponse(test_check_res,
169 'Unable to get test status.') 192 'Unable to get test status.')
170 self._results = test_check_res.json()['response'] 193 self._results = test_check_res.json()['response']
171 return self._results['status'] 194 return self._results['status']
172 195
173 def _AmInstrumentTestSetup(self, app_path, test_path, runner_package): 196 def _AmInstrumentTestSetup(self, app_path, test_path, runner_package,
197 environment_variables):
174 config = {'runner': runner_package} 198 config = {'runner': runner_package}
199 if environment_variables:
200 config['environment_vars'] = ','.join(
201 '%s=%s' % (k, v) for k, v in environment_variables.iteritems())
175 202
176 self._app_id = self._UploadAppToDevice(app_path) 203 self._app_id = self._UploadAppToDevice(app_path)
177 204
178 data_deps = self._test_instance.GetDataDependencies() 205 data_deps = self._test_instance.GetDataDependencies()
179 if data_deps: 206 if data_deps:
180 with tempfile.NamedTemporaryFile(suffix='.zip') as test_with_deps: 207 with tempfile.NamedTemporaryFile(suffix='.zip') as test_with_deps:
181 sdcard_files = [] 208 sdcard_files = []
182 host_test = os.path.basename(test_path) 209 host_test = os.path.basename(test_path)
183 with zipfile.ZipFile(test_with_deps.name, 'w') as zip_file: 210 with zipfile.ZipFile(test_with_deps.name, 'w') as zip_file:
184 zip_file.write(test_path, host_test, zipfile.ZIP_DEFLATED) 211 zip_file.write(test_path, host_test, zipfile.ZIP_DEFLATED)
185 for h, _ in data_deps: 212 for h, _ in data_deps:
186 zip_utils.WriteToZipFile(zip_file, h, '.')
187 if os.path.isdir(h): 213 if os.path.isdir(h):
214 zip_utils.WriteToZipFile(zip_file, h, '.')
188 sdcard_files.extend(os.listdir(h)) 215 sdcard_files.extend(os.listdir(h))
189 else: 216 else:
190 sdcard_files.extend(h) 217 zip_utils.WriteToZipFile(zip_file, h, os.path.basename(h))
218 sdcard_files.append(os.path.basename(h))
191 config['sdcard_files'] = ','.join(sdcard_files) 219 config['sdcard_files'] = ','.join(sdcard_files)
192 config['host_test'] = host_test 220 config['host_test'] = host_test
193 self._test_id = self._UploadTestToDevice( 221 self._test_id = self._UploadTestToDevice(
194 'robotium', test_with_deps.name) 222 'robotium', test_with_deps.name)
195 else: 223 else:
196 self._test_id = self._UploadTestToDevice('robotium', test_path) 224 self._test_id = self._UploadTestToDevice('robotium', test_path)
197 225
198 logging.info('Setting config: %s' % config) 226 logging.info('Setting config: %s' % config)
199 self._SetTestConfig('robotium', config) 227 self._SetTestConfig('robotium', config)
200 228
(...skipping 24 matching lines...) Expand all
225 'Unable to upload %s.' % test_path) 253 'Unable to upload %s.' % test_path)
226 return upload_results.json()['response']['test_id'] 254 return upload_results.json()['response']['test_id']
227 255
228 def _SetTestConfig(self, runner_type, body): 256 def _SetTestConfig(self, runner_type, body):
229 """Generates and uploads config file for test. 257 """Generates and uploads config file for test.
230 Args: 258 Args:
231 extras: Extra arguments to set in the config file. 259 extras: Extra arguments to set in the config file.
232 """ 260 """
233 logging.info('Generating config file for test.') 261 logging.info('Generating config file for test.')
234 with tempfile.TemporaryFile() as config: 262 with tempfile.TemporaryFile() as config:
235 config_data = ['[appurify]', '[%s]' % runner_type] 263 config_data = [
264 '[appurify]',
265 'pcap=0',
266 'profiler=0',
267 'videocapture=0',
268 '[%s]' % runner_type
269 ]
236 config_data.extend('%s=%s' % (k, v) for k, v in body.iteritems()) 270 config_data.extend('%s=%s' % (k, v) for k, v in body.iteritems())
237 config.write(''.join('%s\n' % l for l in config_data)) 271 config.write(''.join('%s\n' % l for l in config_data))
238 config.flush() 272 config.flush()
239 config.seek(0) 273 config.seek(0)
240 with appurify_sanitized.SanitizeLogging(self._env.verbose_count, 274 with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
241 logging.WARNING): 275 logging.WARNING):
242 config_response = appurify_sanitized.api.config_upload( 276 config_response = appurify_sanitized.api.config_upload(
243 self._env.token, config, self._test_id) 277 self._env.token, config, self._test_id)
244 remote_device_helper.TestHttpResponse( 278 remote_device_helper.TestHttpResponse(
245 config_response, 'Unable to upload test config.') 279 config_response, 'Unable to upload test config.')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698