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

Side by Side Diff: swarming.py

Issue 25549003: Fix running 'import run_isolated' at python interactive prompt. (Closed) Base URL: https://chromium.googlesource.com/a/chromium/tools/swarm_client@1_update_item
Patch Set: Added comment Created 7 years, 2 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
« no previous file with comments | « run_isolated.py ('k') | tests/swarming_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Copyright 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Client tool to trigger tasks or retrieve results from a Swarming server.""" 6 """Client tool to trigger tasks or retrieve results from a Swarming server."""
7 7
8 __version__ = '0.1' 8 __version__ = '0.1'
9 9
10 import binascii 10 import binascii
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 """Generic failure.""" 64 """Generic failure."""
65 pass 65 pass
66 66
67 67
68 class Manifest(object): 68 class Manifest(object):
69 """Represents a Swarming task manifest. 69 """Represents a Swarming task manifest.
70 70
71 Also includes code to zip code and upload itself. 71 Also includes code to zip code and upload itself.
72 """ 72 """
73 def __init__( 73 def __init__(
74 self, manifest_hash, test_name, shards, test_filter, slave_os, 74 self, isolated_hash, test_name, shards, test_filter, slave_os,
75 working_dir, isolate_server, verbose, profile, priority, algo): 75 working_dir, isolate_server, verbose, profile, priority, algo):
76 """Populates a manifest object. 76 """Populates a manifest object.
77 Args: 77 Args:
78 manifest_hash - The manifest's sha-1 that the slave is going to fetch. 78 isolated_hash - The manifest's sha-1 that the slave is going to fetch.
79 test_name - The name to give the test request. 79 test_name - The name to give the test request.
80 shards - The number of swarm shards to request. 80 shards - The number of swarm shards to request.
81 test_filter - The gtest filter to apply when running the test. 81 test_filter - The gtest filter to apply when running the test.
82 slave_os - OS to run on. 82 slave_os - OS to run on.
83 working_dir - Relative working directory to start the script. 83 working_dir - Relative working directory to start the script.
84 isolate_server - isolate server url. 84 isolate_server - isolate server url.
85 verbose - if True, have the slave print more details. 85 verbose - if True, have the slave print more details.
86 profile - if True, have the slave print more timing data. 86 profile - if True, have the slave print more timing data.
87 priority - int between 0 and 1000, lower the higher priority. 87 priority - int between 0 and 1000, lower the higher priority.
88 algo - hashing algorithm used. 88 algo - hashing algorithm used.
89 """ 89 """
90 self.manifest_hash = manifest_hash 90 self.isolated_hash = isolated_hash
91 self.bundle = zip_package.ZipPackage(ROOT_DIR) 91 self.bundle = zip_package.ZipPackage(ROOT_DIR)
92 92
93 self._test_name = test_name 93 self._test_name = test_name
94 self._shards = shards 94 self._shards = shards
95 self._test_filter = test_filter 95 self._test_filter = test_filter
96 self._target_platform = PLATFORM_MAPPING_SWARMING[slave_os] 96 self._target_platform = slave_os
97 self._working_dir = working_dir 97 self._working_dir = working_dir
98 98
99 self.isolate_server = isolate_server 99 self.isolate_server = isolate_server
100 self._data_server_retrieval = isolate_server + '/content/retrieve/default/' 100 self._data_server_retrieval = isolate_server + '/content/retrieve/default/'
101 self._data_server_storage = isolate_server + '/content/store/default/' 101 self._data_server_storage = isolate_server + '/content/store/default/'
102 self._data_server_has = isolate_server + '/content/contains/default' 102 self._data_server_has = isolate_server + '/content/contains/default'
103 self._data_server_get_token = isolate_server + '/content/get_token' 103 self._data_server_get_token = isolate_server + '/content/get_token'
104 104
105 self.verbose = bool(verbose) 105 self.verbose = bool(verbose)
106 self.profile = bool(profile) 106 self.profile = bool(profile)
107 self.priority = priority 107 self.priority = priority
108 self._algo = algo 108 self._algo = algo
109 109
110 self._zip_file_hash = '' 110 self._zip_file_hash = ''
111 self._tasks = [] 111 self._tasks = []
112 self._files = {}
113 self._token_cache = None 112 self._token_cache = None
114 113
115 def _token(self): 114 def _token(self):
116 if not self._token_cache: 115 if not self._token_cache:
117 result = net.url_open(self._data_server_get_token) 116 result = net.url_open(self._data_server_get_token)
118 if not result: 117 if not result:
119 # TODO(maruel): Implement authentication. 118 # TODO(maruel): Implement authentication.
120 raise Failure('Failed to get token, need authentication') 119 raise Failure('Failed to get token, need authentication')
121 # Quote it right away, so creating the urls is simpler. 120 # Quote it right away, so creating the urls is simpler.
122 self._token_cache = urllib.quote(result.read()) 121 self._token_cache = urllib.quote(result.read())
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 169
171 return True 170 return True
172 171
173 def to_json(self): 172 def to_json(self):
174 """Exports the current configuration into a swarm-readable manifest file. 173 """Exports the current configuration into a swarm-readable manifest file.
175 174
176 This function doesn't mutate the object. 175 This function doesn't mutate the object.
177 """ 176 """
178 test_case = { 177 test_case = {
179 'test_case_name': self._test_name, 178 'test_case_name': self._test_name,
180 'data': [ 179 'data': [],
181 [self._data_server_retrieval + urllib.quote(self._zip_file_hash),
182 'swarm_data.zip'],
183 ],
184 'tests': self._tasks, 180 'tests': self._tasks,
185 'env_vars': {}, 181 'env_vars': {},
186 'configurations': [ 182 'configurations': [
187 { 183 {
188 'min_instances': self._shards, 184 'min_instances': self._shards,
189 'config_name': self._target_platform, 185 'config_name': self._target_platform,
190 'dimensions': { 186 'dimensions': {
191 'os': self._target_platform, 187 'os': self._target_platform,
192 }, 188 },
193 }, 189 },
194 ], 190 ],
195 'working_dir': self._working_dir, 191 'working_dir': self._working_dir,
196 'restart_on_failure': True, 192 'restart_on_failure': True,
197 'cleanup': 'root', 193 'cleanup': 'root',
198 'priority': self.priority, 194 'priority': self.priority,
199 } 195 }
200 196 if self._zip_file_hash:
197 test_case['data'].append(
198 [
199 self._data_server_retrieval + urllib.quote(self._zip_file_hash),
200 'swarm_data.zip',
201 ])
201 # These flags are googletest specific. 202 # These flags are googletest specific.
202 if self._test_filter and self._test_filter != '*': 203 if self._test_filter and self._test_filter != '*':
203 test_case['env_vars']['GTEST_FILTER'] = self._test_filter 204 test_case['env_vars']['GTEST_FILTER'] = self._test_filter
204 if self._shards > 1: 205 if self._shards > 1:
205 test_case['env_vars']['GTEST_SHARD_INDEX'] = '%(instance_index)s' 206 test_case['env_vars']['GTEST_SHARD_INDEX'] = '%(instance_index)s'
206 test_case['env_vars']['GTEST_TOTAL_SHARDS'] = '%(num_instances)s' 207 test_case['env_vars']['GTEST_TOTAL_SHARDS'] = '%(num_instances)s'
207 208
208 return json.dumps(test_case, separators=(',',':')) 209 return json.dumps(test_case, separators=(',',':'))
209 210
210 211
(...skipping 21 matching lines...) Expand all
232 continue 233 continue
233 return json.loads(result) 234 return json.loads(result)
234 235
235 raise Failure( 236 raise Failure(
236 'Error: Unable to find any tests with the name, %s, on swarm server' 237 'Error: Unable to find any tests with the name, %s, on swarm server'
237 % test_name) 238 % test_name)
238 239
239 240
240 def retrieve_results(base_url, test_key, timeout, should_stop): 241 def retrieve_results(base_url, test_key, timeout, should_stop):
241 """Retrieves results for a single test_key.""" 242 """Retrieves results for a single test_key."""
242 assert isinstance(timeout, float) 243 assert isinstance(timeout, float), timeout
243 params = [('r', test_key)] 244 params = [('r', test_key)]
244 result_url = '%s/get_result?%s' % (base_url, urllib.urlencode(params)) 245 result_url = '%s/get_result?%s' % (base_url, urllib.urlencode(params))
245 start = now() 246 start = now()
246 while True: 247 while True:
247 if timeout and (now() - start) >= timeout: 248 if timeout and (now() - start) >= timeout:
248 logging.error('retrieve_results(%s) timed out', base_url) 249 logging.error('retrieve_results(%s) timed out', base_url)
249 return {} 250 return {}
250 # Do retries ourselves. 251 # Do retries ourselves.
251 response = net.url_read(result_url, retry_404=False, retry_50x=False) 252 response = net.url_read(result_url, retry_404=False, retry_50x=False)
252 if response is None: 253 if response is None:
253 # Aggressively poll for results. Do not use retry_404 so 254 # Aggressively poll for results. Do not use retry_404 so
254 # should_stop is polled more often. 255 # should_stop is polled more often.
255 remaining = min(5, timeout - (now() - start)) if timeout else 5 256 remaining = min(5, timeout - (now() - start)) if timeout else 5
256 if remaining > 0: 257 if remaining > 0:
258 if should_stop.get():
259 return {}
257 net.sleep_before_retry(1, remaining) 260 net.sleep_before_retry(1, remaining)
258 else: 261 else:
259 try: 262 try:
260 data = json.loads(response) or {} 263 data = json.loads(response) or {}
261 except (ValueError, TypeError): 264 except (ValueError, TypeError):
262 logging.warning( 265 logging.warning(
263 'Received corrupted data for test_key %s. Retrying.', test_key) 266 'Received corrupted data for test_key %s. Retrying.', test_key)
264 else: 267 else:
265 if data['output']: 268 if data['output']:
266 return data 269 return data
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 run_test_name = 'run_isolated.zip' 320 run_test_name = 'run_isolated.zip'
318 manifest.bundle.add_buffer(run_test_name, 321 manifest.bundle.add_buffer(run_test_name,
319 run_isolated.get_as_zip_package().zip_into_buffer(compress=False)) 322 run_isolated.get_as_zip_package().zip_into_buffer(compress=False))
320 323
321 cleanup_script_name = 'swarm_cleanup.py' 324 cleanup_script_name = 'swarm_cleanup.py'
322 manifest.bundle.add_file(os.path.join(TOOLS_PATH, cleanup_script_name), 325 manifest.bundle.add_file(os.path.join(TOOLS_PATH, cleanup_script_name),
323 cleanup_script_name) 326 cleanup_script_name)
324 327
325 run_cmd = [ 328 run_cmd = [
326 'python', run_test_name, 329 'python', run_test_name,
327 '--hash', manifest.manifest_hash, 330 '--hash', manifest.isolated_hash,
328 '--isolate-server', manifest.isolate_server, 331 '--isolate-server', manifest.isolate_server,
329 ] 332 ]
330 if manifest.verbose or manifest.profile: 333 if manifest.verbose or manifest.profile:
331 # Have it print the profiling section. 334 # Have it print the profiling section.
332 run_cmd.append('--verbose') 335 run_cmd.append('--verbose')
333 manifest.add_task('Run Test', run_cmd) 336 manifest.add_task('Run Test', run_cmd)
334 337
335 # Clean up 338 # Clean up
336 manifest.add_task('Clean Up', ['python', cleanup_script_name]) 339 manifest.add_task('Clean Up', ['python', cleanup_script_name])
337 340
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 print >> sys.stderr, 'Archival failure %s' % file_hash_or_isolated 376 print >> sys.stderr, 'Archival failure %s' % file_hash_or_isolated
374 return 1 377 return 1
375 elif isolateserver.is_valid_hash(file_hash_or_isolated, algo): 378 elif isolateserver.is_valid_hash(file_hash_or_isolated, algo):
376 file_hash = file_hash_or_isolated 379 file_hash = file_hash_or_isolated
377 else: 380 else:
378 print >> sys.stderr, 'Invalid hash %s' % file_hash_or_isolated 381 print >> sys.stderr, 'Invalid hash %s' % file_hash_or_isolated
379 return 1 382 return 1
380 383
381 try: 384 try:
382 manifest = Manifest( 385 manifest = Manifest(
383 file_hash, test_name, shards, test_filter, slave_os, 386 file_hash,
384 working_dir, isolate_server, verbose, profile, priority, algo) 387 test_name,
388 shards,
389 test_filter,
390 PLATFORM_MAPPING_SWARMING[slave_os],
391 working_dir,
392 isolate_server,
393 verbose,
394 profile,
395 priority,
396 algo)
385 except ValueError as e: 397 except ValueError as e:
386 print >> sys.stderr, 'Unable to process %s: %s' % (test_name, e) 398 print >> sys.stderr, 'Unable to process %s: %s' % (test_name, e)
387 return 1 399 return 1
388 400
389 chromium_setup(manifest) 401 chromium_setup(manifest)
390 402
391 # Zip up relevant files. 403 # Zip up relevant files.
392 print('Zipping up files...') 404 print('Zipping up files...')
393 if not manifest.zip_and_upload(): 405 if not manifest.zip_and_upload():
394 return 1 406 return 1
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 sys.stderr.write(str(e)) 685 sys.stderr.write(str(e))
674 sys.stderr.write('\n') 686 sys.stderr.write('\n')
675 return 1 687 return 1
676 688
677 689
678 if __name__ == '__main__': 690 if __name__ == '__main__':
679 fix_encoding.fix_encoding() 691 fix_encoding.fix_encoding()
680 tools.disable_buffering() 692 tools.disable_buffering()
681 colorama.init() 693 colorama.init()
682 sys.exit(main(sys.argv[1:])) 694 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « run_isolated.py ('k') | tests/swarming_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698