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

Side by Side Diff: tools/skp/webpages_playback.py

Issue 2406863002: webpages_playback: use gsutil instead of API, no shell_utils (Closed)
Patch Set: Address comments Created 4 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 | « no previous file | no next file » | 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 (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 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 """Archives or replays webpages and creates SKPs in a Google Storage location. 6 """Archives or replays webpages and creates SKPs in a Google Storage location.
7 7
8 To archive webpages and store SKP files (archives should be rarely updated): 8 To archive webpages and store SKP files (archives should be rarely updated):
9 9
10 cd skia 10 cd skia
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 import optparse 56 import optparse
57 import os 57 import os
58 import posixpath 58 import posixpath
59 import shutil 59 import shutil
60 import subprocess 60 import subprocess
61 import sys 61 import sys
62 import tempfile 62 import tempfile
63 import time 63 import time
64 import traceback 64 import traceback
65 65
66 SKIA_DIR = os.path.abspath(os.path.join(
67 os.path.realpath(os.path.dirname(__file__)),
68 os.pardir, os.pardir))
69 sys.path.insert(0, SKIA_DIR)
70
71 from common.py.utils import gs_utils
72 from common.py.utils import shell_utils
73 66
74 ROOT_PLAYBACK_DIR_NAME = 'playback' 67 ROOT_PLAYBACK_DIR_NAME = 'playback'
75 SKPICTURES_DIR_NAME = 'skps' 68 SKPICTURES_DIR_NAME = 'skps'
76 69
70 GS_PREFIX = 'gs://'
71
77 PARTNERS_GS_BUCKET = 'gs://chrome-partner-telemetry' 72 PARTNERS_GS_BUCKET = 'gs://chrome-partner-telemetry'
78 73
79 # Local archive and SKP directories. 74 # Local archive and SKP directories.
80 LOCAL_REPLAY_WEBPAGES_ARCHIVE_DIR = os.path.join( 75 LOCAL_REPLAY_WEBPAGES_ARCHIVE_DIR = os.path.join(
81 os.path.abspath(os.path.dirname(__file__)), 'page_sets', 'data') 76 os.path.abspath(os.path.dirname(__file__)), 'page_sets', 'data')
82 TMP_SKP_DIR = tempfile.mkdtemp() 77 TMP_SKP_DIR = tempfile.mkdtemp()
83 78
84 # Location of the credentials.json file and the string that represents missing 79 # Location of the credentials.json file and the string that represents missing
85 # passwords. 80 # passwords.
86 CREDENTIALS_FILE_PATH = os.path.join( 81 CREDENTIALS_FILE_PATH = os.path.join(
(...skipping 17 matching lines...) Expand all
104 # How many times the record_wpr binary should be retried. 99 # How many times the record_wpr binary should be retried.
105 RETRY_RECORD_WPR_COUNT = 5 100 RETRY_RECORD_WPR_COUNT = 5
106 # How many times the run_benchmark binary should be retried. 101 # How many times the run_benchmark binary should be retried.
107 RETRY_RUN_MEASUREMENT_COUNT = 5 102 RETRY_RUN_MEASUREMENT_COUNT = 5
108 103
109 # Location of the credentials.json file in Google Storage. 104 # Location of the credentials.json file in Google Storage.
110 CREDENTIALS_GS_PATH = '/playback/credentials/credentials.json' 105 CREDENTIALS_GS_PATH = '/playback/credentials/credentials.json'
111 106
112 X11_DISPLAY = os.getenv('DISPLAY', ':0') 107 X11_DISPLAY = os.getenv('DISPLAY', ':0')
113 108
114 GS_PREDEFINED_ACL = gs_utils.GSUtils.PredefinedACL.PRIVATE
115 GS_FINE_GRAINED_ACL_LIST = [
116 (gs_utils.GSUtils.IdType.GROUP_BY_DOMAIN, 'google.com',
117 gs_utils.GSUtils.Permission.READ),
118 ]
119
120 # Path to Chromium's page sets. 109 # Path to Chromium's page sets.
121 CHROMIUM_PAGE_SETS_PATH = os.path.join('tools', 'perf', 'page_sets') 110 CHROMIUM_PAGE_SETS_PATH = os.path.join('tools', 'perf', 'page_sets')
122 111
123 # Dictionary of supported Chromium page sets to their file prefixes. 112 # Dictionary of supported Chromium page sets to their file prefixes.
124 CHROMIUM_PAGE_SETS_TO_PREFIX = { 113 CHROMIUM_PAGE_SETS_TO_PREFIX = {
125 'key_mobile_sites_smooth.py': 'keymobi', 114 'key_mobile_sites_smooth.py': 'keymobi',
126 'top_25_smooth.py': 'top25desk', 115 'top_25_smooth.py': 'top25desk',
127 } 116 }
128 117
129 118
(...skipping 19 matching lines...) Expand all
149 CHROMIUM_PAGE_SETS_PATH) 138 CHROMIUM_PAGE_SETS_PATH)
150 self._all_page_sets_specified = parse_options.page_sets == 'all' 139 self._all_page_sets_specified = parse_options.page_sets == 'all'
151 self._page_sets = self._ParsePageSets(parse_options.page_sets) 140 self._page_sets = self._ParsePageSets(parse_options.page_sets)
152 141
153 self._record = parse_options.record 142 self._record = parse_options.record
154 self._skia_tools = parse_options.skia_tools 143 self._skia_tools = parse_options.skia_tools
155 self._non_interactive = parse_options.non_interactive 144 self._non_interactive = parse_options.non_interactive
156 self._upload = parse_options.upload 145 self._upload = parse_options.upload
157 self._skp_prefix = parse_options.skp_prefix 146 self._skp_prefix = parse_options.skp_prefix
158 data_store_location = parse_options.data_store 147 data_store_location = parse_options.data_store
159 if data_store_location.startswith(gs_utils.GS_PREFIX): 148 if data_store_location.startswith(GS_PREFIX):
160 self.gs = GoogleStorageDataStore(data_store_location) 149 self.gs = GoogleStorageDataStore(data_store_location)
161 else: 150 else:
162 self.gs = LocalFileSystemDataStore(data_store_location) 151 self.gs = LocalFileSystemDataStore(data_store_location)
163 self._upload_to_partner_bucket = parse_options.upload_to_partner_bucket 152 self._upload_to_partner_bucket = parse_options.upload_to_partner_bucket
164 self._alternate_upload_dir = parse_options.alternate_upload_dir 153 self._alternate_upload_dir = parse_options.alternate_upload_dir
165 self._telemetry_binaries_dir = os.path.join(parse_options.chrome_src_path, 154 self._telemetry_binaries_dir = os.path.join(parse_options.chrome_src_path,
166 'tools', 'perf') 155 'tools', 'perf')
167 self._catapult_dir = os.path.join(parse_options.chrome_src_path, 156 self._catapult_dir = os.path.join(parse_options.chrome_src_path,
168 'third_party', 'catapult') 157 'third_party', 'catapult')
169 158
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 'DISPLAY=%s' % X11_DISPLAY, 243 'DISPLAY=%s' % X11_DISPLAY,
255 os.path.join(self._telemetry_binaries_dir, 'record_wpr'), 244 os.path.join(self._telemetry_binaries_dir, 'record_wpr'),
256 '--extra-browser-args="%s"' % self._browser_args, 245 '--extra-browser-args="%s"' % self._browser_args,
257 '--browser=exact', 246 '--browser=exact',
258 '--browser-executable=%s' % self._browser_executable, 247 '--browser-executable=%s' % self._browser_executable,
259 '%s_page_set' % page_set_basename, 248 '%s_page_set' % page_set_basename,
260 '--page-set-base-dir=%s' % page_set_dir 249 '--page-set-base-dir=%s' % page_set_dir
261 ) 250 )
262 for _ in range(RETRY_RECORD_WPR_COUNT): 251 for _ in range(RETRY_RECORD_WPR_COUNT):
263 try: 252 try:
264 shell_utils.run(' '.join(record_wpr_cmd), shell=True) 253 subprocess.check_call(' '.join(record_wpr_cmd), shell=True)
265 254
266 # Move over the created archive into the local webpages archive 255 # Move over the created archive into the local webpages archive
267 # directory. 256 # directory.
268 shutil.move( 257 shutil.move(
269 os.path.join(LOCAL_REPLAY_WEBPAGES_ARCHIVE_DIR, wpr_data_file), 258 os.path.join(LOCAL_REPLAY_WEBPAGES_ARCHIVE_DIR, wpr_data_file),
270 self._local_record_webpages_archive_dir) 259 self._local_record_webpages_archive_dir)
271 shutil.move( 260 shutil.move(
272 os.path.join(LOCAL_REPLAY_WEBPAGES_ARCHIVE_DIR, 261 os.path.join(LOCAL_REPLAY_WEBPAGES_ARCHIVE_DIR,
273 page_set_json_name), 262 page_set_json_name),
274 self._local_record_webpages_archive_dir) 263 self._local_record_webpages_archive_dir)
(...skipping 23 matching lines...) Expand all
298 SKP_BENCHMARK, 287 SKP_BENCHMARK,
299 '--page-set-name=%s' % page_set_basename, 288 '--page-set-name=%s' % page_set_basename,
300 '--page-set-base-dir=%s' % page_set_dir, 289 '--page-set-base-dir=%s' % page_set_dir,
301 '--skp-outdir=%s' % TMP_SKP_DIR, 290 '--skp-outdir=%s' % TMP_SKP_DIR,
302 '--also-run-disabled-tests' 291 '--also-run-disabled-tests'
303 ) 292 )
304 293
305 for _ in range(RETRY_RUN_MEASUREMENT_COUNT): 294 for _ in range(RETRY_RUN_MEASUREMENT_COUNT):
306 try: 295 try:
307 print '\n\n=======Capturing SKP of %s=======\n\n' % page_set 296 print '\n\n=======Capturing SKP of %s=======\n\n' % page_set
308 shell_utils.run(' '.join(run_benchmark_cmd), shell=True) 297 subprocess.check_call(' '.join(run_benchmark_cmd), shell=True)
309 except shell_utils.CommandFailedException: 298 except subprocess.CalledProcessError:
310 # skpicture_printer sometimes fails with AssertionError but the 299 # skpicture_printer sometimes fails with AssertionError but the
311 # captured SKP is still valid. This is a known issue. 300 # captured SKP is still valid. This is a known issue.
312 pass 301 pass
313 302
314 # Rename generated SKP files into more descriptive names. 303 # Rename generated SKP files into more descriptive names.
315 try: 304 try:
316 self._RenameSkpFiles(page_set) 305 self._RenameSkpFiles(page_set)
317 # Break out of the retry loop since there were no errors. 306 # Break out of the retry loop since there were no errors.
318 break 307 break
319 except Exception: 308 except Exception:
(...skipping 14 matching lines...) Expand all
334 os.path.join(self._skia_tools, 'render_pictures'), 323 os.path.join(self._skia_tools, 'render_pictures'),
335 '-r', self._local_skp_dir 324 '-r', self._local_skp_dir
336 ] 325 ]
337 render_pdfs_cmd = [ 326 render_pdfs_cmd = [
338 os.path.join(self._skia_tools, 'render_pdfs'), 327 os.path.join(self._skia_tools, 'render_pdfs'),
339 '-r', self._local_skp_dir 328 '-r', self._local_skp_dir
340 ] 329 ]
341 330
342 for tools_cmd in (render_pictures_cmd, render_pdfs_cmd): 331 for tools_cmd in (render_pictures_cmd, render_pdfs_cmd):
343 print '\n\n=======Running %s=======' % ' '.join(tools_cmd) 332 print '\n\n=======Running %s=======' % ' '.join(tools_cmd)
344 proc = subprocess.Popen(tools_cmd) 333 subprocess.check_call(tools_cmd)
345 (code, _) = shell_utils.log_process_after_completion(proc, echo=False)
346 if code != 0:
347 raise Exception('%s failed!' % ' '.join(tools_cmd))
348 334
349 if not self._non_interactive: 335 if not self._non_interactive:
350 print '\n\n=======Running debugger=======' 336 print '\n\n=======Running debugger======='
351 os.system('%s %s' % (os.path.join(self._skia_tools, 'debugger'), 337 os.system('%s %s' % (os.path.join(self._skia_tools, 'debugger'),
352 self._local_skp_dir)) 338 self._local_skp_dir))
353 339
354 print '\n\n' 340 print '\n\n'
355 341
356 if self._upload: 342 if self._upload:
357 print '\n\n=======Uploading to %s=======\n\n' % self.gs.target_type() 343 print '\n\n=======Uploading to %s=======\n\n' % self.gs.target_type()
358 # Copy the directory structure in the root directory into Google Storage. 344 # Copy the directory structure in the root directory into Google Storage.
359 dest_dir_name = ROOT_PLAYBACK_DIR_NAME 345 dest_dir_name = ROOT_PLAYBACK_DIR_NAME
360 if self._alternate_upload_dir: 346 if self._alternate_upload_dir:
361 dest_dir_name = self._alternate_upload_dir 347 dest_dir_name = self._alternate_upload_dir
362 348
363 self.gs.upload_dir_contents( 349 self.gs.upload_dir_contents(
364 self._local_skp_dir, dest_dir=dest_dir_name, 350 self._local_skp_dir, dest_dir=dest_dir_name)
365 upload_if=gs_utils.GSUtils.UploadIf.IF_MODIFIED,
366 predefined_acl=GS_PREDEFINED_ACL,
367 fine_grained_acl_list=GS_FINE_GRAINED_ACL_LIST)
368 351
369 print '\n\n=======New SKPs have been uploaded to %s =======\n\n' % ( 352 print '\n\n=======New SKPs have been uploaded to %s =======\n\n' % (
370 posixpath.join(self.gs.target_name(), dest_dir_name, 353 posixpath.join(self.gs.target_name(), dest_dir_name,
371 SKPICTURES_DIR_NAME)) 354 SKPICTURES_DIR_NAME))
372 355
373 else: 356 else:
374 print '\n\n=======Not Uploading to %s=======\n\n' % self.gs.target_type() 357 print '\n\n=======Not Uploading to %s=======\n\n' % self.gs.target_type()
375 print 'Generated resources are available in %s\n\n' % ( 358 print 'Generated resources are available in %s\n\n' % (
376 self._local_skp_dir) 359 self._local_skp_dir)
377 360
378 if self._upload_to_partner_bucket: 361 if self._upload_to_partner_bucket:
379 print '\n\n=======Uploading to Partner bucket %s =======\n\n' % ( 362 print '\n\n=======Uploading to Partner bucket %s =======\n\n' % (
380 PARTNERS_GS_BUCKET) 363 PARTNERS_GS_BUCKET)
381 partner_gs = GoogleStorageDataStore(PARTNERS_GS_BUCKET) 364 partner_gs = GoogleStorageDataStore(PARTNERS_GS_BUCKET)
382 partner_gs.delete_path(SKPICTURES_DIR_NAME) 365 partner_gs.delete_path(SKPICTURES_DIR_NAME)
383 print 'Uploading %s to %s' % (self._local_skp_dir, SKPICTURES_DIR_NAME) 366 print 'Uploading %s to %s' % (self._local_skp_dir, SKPICTURES_DIR_NAME)
384 partner_gs.upload_dir_contents( 367 partner_gs.upload_dir_contents(self._local_skp_dir, SKPICTURES_DIR_NAME)
385 self._local_skp_dir,
386 dest_dir=SKPICTURES_DIR_NAME,
387 upload_if=gs_utils.GSUtils.UploadIf.IF_MODIFIED)
388 print '\n\n=======New SKPs have been uploaded to %s =======\n\n' % ( 368 print '\n\n=======New SKPs have been uploaded to %s =======\n\n' % (
389 posixpath.join(partner_gs.target_name(), SKPICTURES_DIR_NAME)) 369 posixpath.join(partner_gs.target_name(), SKPICTURES_DIR_NAME))
390 370
391 return 0 371 return 0
392 372
393 def _GetSkiaSkpFileName(self, page_set): 373 def _GetSkiaSkpFileName(self, page_set):
394 """Returns the SKP file name for Skia page sets.""" 374 """Returns the SKP file name for Skia page sets."""
395 # /path/to/skia_yahooanswers_desktop.py -> skia_yahooanswers_desktop.py 375 # /path/to/skia_yahooanswers_desktop.py -> skia_yahooanswers_desktop.py
396 ps_filename = os.path.basename(page_set) 376 ps_filename = os.path.basename(page_set)
397 # skia_yahooanswers_desktop.py -> skia_yahooanswers_desktop 377 # skia_yahooanswers_desktop.py -> skia_yahooanswers_desktop
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 raise Exception('%s and %s do not exist in %s!' % (gs.target_type(), 449 raise Exception('%s and %s do not exist in %s!' % (gs.target_type(),
470 wpr_source, page_set_source)) 450 wpr_source, page_set_source))
471 451
472 class DataStore: 452 class DataStore:
473 """An abstract base class for uploading recordings to a data storage. 453 """An abstract base class for uploading recordings to a data storage.
474 The interface emulates the google storage api.""" 454 The interface emulates the google storage api."""
475 def target_name(self): 455 def target_name(self):
476 raise NotImplementedError() 456 raise NotImplementedError()
477 def target_type(self): 457 def target_type(self):
478 raise NotImplementedError() 458 raise NotImplementedError()
479 def does_storage_object_exist(self, *args): 459 def does_storage_object_exist(self, name):
480 raise NotImplementedError() 460 raise NotImplementedError()
481 def download_file(self, *args): 461 def download_file(self, name, local_path):
482 raise NotImplementedError() 462 raise NotImplementedError()
483 def upload_dir_contents(self, source_dir, **kwargs): 463 def upload_dir_contents(self, source_dir, dest_dir):
484 raise NotImplementedError() 464 raise NotImplementedError()
485 465
466
486 class GoogleStorageDataStore(DataStore): 467 class GoogleStorageDataStore(DataStore):
487 def __init__(self, data_store_url): 468 def __init__(self, data_store_url):
488 self._data_store_url = data_store_url 469 self._url = data_store_url
489 self._bucket = remove_prefix(self._data_store_url.lstrip(), 470
490 gs_utils.GS_PREFIX)
491 self.gs = gs_utils.GSUtils()
492 def target_name(self): 471 def target_name(self):
493 return self._data_store_url 472 return self._url
473
494 def target_type(self): 474 def target_type(self):
495 return 'Google Storage' 475 return 'Google Storage'
496 def does_storage_object_exist(self, *args): 476
497 return self.gs.does_storage_object_exist(self._bucket, *args) 477 def does_storage_object_exist(self, name):
478 try:
479 output = subprocess.check_output([
480 'gsutil', 'ls', '/'.join((self._url, name))])
481 except subprocess.CalledProcessError:
482 return False
483 if len(output.splitlines) != 1:
484 return False
485 return True
486
498 def delete_path(self, path): 487 def delete_path(self, path):
499 _, files = self.gs.list_bucket_contents(self._bucket, subdir=path) 488 subprocess.check_call(['gsutil', 'rm', '-r', path])
500 for f in files: 489
501 self.gs.delete_file(self._bucket, posixpath.join(path, f)) 490 def download_file(self, name, local_path):
502 def download_file(self, *args): 491 subprocess.check_call([
503 self.gs.download_file(self._bucket, *args) 492 'gsutil', 'cp', '/'.join((self._url, name)), local_path])
504 def upload_dir_contents(self, source_dir, **kwargs): 493
505 self.gs.upload_dir_contents(source_dir, self._bucket, **kwargs) 494 def upload_dir_contents(self, source_dir, dest_dir):
495 subprocess.check_call([
496 'gsutil', 'cp', '-r', source_dir, '/'.join(self._url, dest_dir)])
497
506 498
507 class LocalFileSystemDataStore(DataStore): 499 class LocalFileSystemDataStore(DataStore):
508 def __init__(self, data_store_location): 500 def __init__(self, data_store_location):
509 self._base_dir = data_store_location 501 self._base_dir = data_store_location
510 def target_name(self): 502 def target_name(self):
511 return self._base_dir 503 return self._base_dir
512 def target_type(self): 504 def target_type(self):
513 return self._base_dir 505 return self._base_dir
514 def does_storage_object_exist(self, name, *args): 506 def does_storage_object_exist(self, name):
515 return os.path.isfile(os.path.join(self._base_dir, name)) 507 return os.path.isfile(os.path.join(self._base_dir, name))
516 def delete_path(self, path): 508 def delete_path(self, path):
517 shutil.rmtree(path) 509 shutil.rmtree(path)
518 def download_file(self, name, local_path, *args): 510 def download_file(self, name, local_path):
519 shutil.copyfile(os.path.join(self._base_dir, name), local_path) 511 shutil.copyfile(os.path.join(self._base_dir, name), local_path)
520 def upload_dir_contents(self, source_dir, dest_dir, **kwargs): 512 def upload_dir_contents(self, source_dir, dest_dir):
521 def copytree(source_dir, dest_dir): 513 def copytree(source_dir, dest_dir):
522 if not os.path.exists(dest_dir): 514 if not os.path.exists(dest_dir):
523 os.makedirs(dest_dir) 515 os.makedirs(dest_dir)
524 for item in os.listdir(source_dir): 516 for item in os.listdir(source_dir):
525 source = os.path.join(source_dir, item) 517 source = os.path.join(source_dir, item)
526 dest = os.path.join(dest_dir, item) 518 dest = os.path.join(dest_dir, item)
527 if os.path.isdir(source): 519 if os.path.isdir(source):
528 copytree(source, dest) 520 copytree(source, dest)
529 else: 521 else:
530 shutil.copy2(source, dest) 522 shutil.copy2(source, dest)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 '--skia_tools is specified then the debugger is not run.', 585 '--skia_tools is specified then the debugger is not run.',
594 default=False) 586 default=False)
595 option_parser.add_option( 587 option_parser.add_option(
596 '', '--skp_prefix', 588 '', '--skp_prefix',
597 help='Prefix to add to the names of generated SKPs.', 589 help='Prefix to add to the names of generated SKPs.',
598 default=None) 590 default=None)
599 options, unused_args = option_parser.parse_args() 591 options, unused_args = option_parser.parse_args()
600 592
601 playback = SkPicturePlayback(options) 593 playback = SkPicturePlayback(options)
602 sys.exit(playback.Run()) 594 sys.exit(playback.Run())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698