OLD | NEW |
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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 CREDENTIALS_GS_PATH = '/playback/credentials/credentials.json' | 108 CREDENTIALS_GS_PATH = '/playback/credentials/credentials.json' |
109 | 109 |
110 X11_DISPLAY = os.getenv('DISPLAY', ':0') | 110 X11_DISPLAY = os.getenv('DISPLAY', ':0') |
111 | 111 |
112 GS_PREDEFINED_ACL = gs_utils.GSUtils.PredefinedACL.PRIVATE | 112 GS_PREDEFINED_ACL = gs_utils.GSUtils.PredefinedACL.PRIVATE |
113 GS_FINE_GRAINED_ACL_LIST = [ | 113 GS_FINE_GRAINED_ACL_LIST = [ |
114 (gs_utils.GSUtils.IdType.GROUP_BY_DOMAIN, 'google.com', | 114 (gs_utils.GSUtils.IdType.GROUP_BY_DOMAIN, 'google.com', |
115 gs_utils.GSUtils.Permission.READ), | 115 gs_utils.GSUtils.Permission.READ), |
116 ] | 116 ] |
117 | 117 |
| 118 # Path to Chromium's page sets. |
| 119 CHROMIUM_PAGE_SETS_PATH = os.path.join('tools', 'perf', 'page_sets') |
| 120 |
| 121 # Dictionary of supported Chromium page sets to their file prefixes. |
| 122 CHROMIUM_PAGE_SETS_TO_PREFIX = { |
| 123 # 'key_mobile_sites_smooth.py': 'keymobi', |
| 124 # TODO(rmistry): Uncomment the below after it is verified that the above |
| 125 # works. |
| 126 # 'top_25_smooth.py': 'top25desk', |
| 127 } |
| 128 |
| 129 |
118 def remove_prefix(s, prefix): | 130 def remove_prefix(s, prefix): |
119 if s.startswith(prefix): | 131 if s.startswith(prefix): |
120 return s[len(prefix):] | 132 return s[len(prefix):] |
121 return s | 133 return s |
122 | 134 |
| 135 |
123 class SkPicturePlayback(object): | 136 class SkPicturePlayback(object): |
124 """Class that archives or replays webpages and creates SKPs.""" | 137 """Class that archives or replays webpages and creates SKPs.""" |
125 | 138 |
126 def __init__(self, parse_options): | 139 def __init__(self, parse_options): |
127 """Constructs a SkPicturePlayback BuildStep instance.""" | 140 """Constructs a SkPicturePlayback BuildStep instance.""" |
128 assert parse_options.browser_executable, 'Must specify --browser_executable' | 141 assert parse_options.browser_executable, 'Must specify --browser_executable' |
129 self._browser_executable = parse_options.browser_executable | 142 self._browser_executable = parse_options.browser_executable |
130 | 143 |
| 144 self._chrome_page_sets_path = os.path.join(parse_options.chrome_src_path, |
| 145 CHROMIUM_PAGE_SETS_PATH) |
131 self._all_page_sets_specified = parse_options.page_sets == 'all' | 146 self._all_page_sets_specified = parse_options.page_sets == 'all' |
132 self._page_sets = self._ParsePageSets(parse_options.page_sets) | 147 self._page_sets = self._ParsePageSets(parse_options.page_sets) |
133 | 148 |
134 self._record = parse_options.record | 149 self._record = parse_options.record |
135 self._skia_tools = parse_options.skia_tools | 150 self._skia_tools = parse_options.skia_tools |
136 self._non_interactive = parse_options.non_interactive | 151 self._non_interactive = parse_options.non_interactive |
137 self._upload = parse_options.upload | 152 self._upload = parse_options.upload |
138 data_store_location = parse_options.data_store | 153 data_store_location = parse_options.data_store |
139 if data_store_location.startswith(gs_utils.GS_PREFIX): | 154 if data_store_location.startswith(gs_utils.GS_PREFIX): |
140 self.gs = GoogleStorageDataStore(data_store_location) | 155 self.gs = GoogleStorageDataStore(data_store_location) |
(...skipping 15 matching lines...) Expand all Loading... |
156 if not page_sets: | 171 if not page_sets: |
157 raise ValueError('Must specify at least one page_set!') | 172 raise ValueError('Must specify at least one page_set!') |
158 elif self._all_page_sets_specified: | 173 elif self._all_page_sets_specified: |
159 # Get everything from the page_sets directory. | 174 # Get everything from the page_sets directory. |
160 page_sets_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), | 175 page_sets_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), |
161 'page_sets') | 176 'page_sets') |
162 ps = [os.path.join(page_sets_dir, page_set) | 177 ps = [os.path.join(page_sets_dir, page_set) |
163 for page_set in os.listdir(page_sets_dir) | 178 for page_set in os.listdir(page_sets_dir) |
164 if not os.path.isdir(os.path.join(page_sets_dir, page_set)) and | 179 if not os.path.isdir(os.path.join(page_sets_dir, page_set)) and |
165 page_set.endswith('.py')] | 180 page_set.endswith('.py')] |
| 181 chromium_ps = [ |
| 182 os.path.join(self._chrome_page_sets_path, cr_page_set) |
| 183 for cr_page_set in CHROMIUM_PAGE_SETS_TO_PREFIX] |
| 184 ps.extend(chromium_ps) |
166 elif '*' in page_sets: | 185 elif '*' in page_sets: |
167 # Explode and return the glob. | 186 # Explode and return the glob. |
168 ps = glob.glob(page_sets) | 187 ps = glob.glob(page_sets) |
169 else: | 188 else: |
170 ps = page_sets.split(',') | 189 ps = page_sets.split(',') |
171 ps.sort() | 190 ps.sort() |
172 return ps | 191 return ps |
173 | 192 |
| 193 def _IsChromiumPageSet(self, page_set): |
| 194 """Returns true if the specified page set is a Chromium page set.""" |
| 195 return page_set.startswith(self._chrome_page_sets_path) |
| 196 |
174 def Run(self): | 197 def Run(self): |
175 """Run the SkPicturePlayback BuildStep.""" | 198 """Run the SkPicturePlayback BuildStep.""" |
176 | 199 |
177 # Download the credentials file if it was not previously downloaded. | 200 # Download the credentials file if it was not previously downloaded. |
178 if not os.path.isfile(CREDENTIALS_FILE_PATH): | 201 if not os.path.isfile(CREDENTIALS_FILE_PATH): |
179 # Download the credentials.json file from Google Storage. | 202 # Download the credentials.json file from Google Storage. |
180 self.gs.download_file(CREDENTIALS_GS_PATH, CREDENTIALS_FILE_PATH) | 203 self.gs.download_file(CREDENTIALS_GS_PATH, CREDENTIALS_FILE_PATH) |
181 | 204 |
182 if not os.path.isfile(CREDENTIALS_FILE_PATH): | 205 if not os.path.isfile(CREDENTIALS_FILE_PATH): |
183 print """\n\nCould not locate credentials file in the storage. | 206 print """\n\nCould not locate credentials file in the storage. |
(...skipping 26 matching lines...) Expand all Loading... |
210 start_time = time.time() | 233 start_time = time.time() |
211 | 234 |
212 # Loop through all page_sets. | 235 # Loop through all page_sets. |
213 for page_set in self._page_sets: | 236 for page_set in self._page_sets: |
214 | 237 |
215 page_set_basename = os.path.basename(page_set).split('.')[0] | 238 page_set_basename = os.path.basename(page_set).split('.')[0] |
216 page_set_json_name = page_set_basename + '.json' | 239 page_set_json_name = page_set_basename + '.json' |
217 wpr_data_file = page_set.split(os.path.sep)[-1].split('.')[0] + '_000.wpr' | 240 wpr_data_file = page_set.split(os.path.sep)[-1].split('.')[0] + '_000.wpr' |
218 page_set_dir = os.path.dirname(page_set) | 241 page_set_dir = os.path.dirname(page_set) |
219 | 242 |
220 if self._record: | 243 if self._IsChromiumPageSet(page_set): |
| 244 print 'Using Chromium\'s captured archives for Chromium\'s page sets.' |
| 245 elif self._record: |
221 # Create an archive of the specified webpages if '--record=True' is | 246 # Create an archive of the specified webpages if '--record=True' is |
222 # specified. | 247 # specified. |
223 record_wpr_cmd = ( | 248 record_wpr_cmd = ( |
224 'PYTHONPATH=%s:$PYTHONPATH' % page_set_dir, | 249 'PYTHONPATH=%s:$PYTHONPATH' % page_set_dir, |
225 'DISPLAY=%s' % X11_DISPLAY, | 250 'DISPLAY=%s' % X11_DISPLAY, |
226 os.path.join(self._telemetry_binaries_dir, 'record_wpr'), | 251 os.path.join(self._telemetry_binaries_dir, 'record_wpr'), |
227 '--extra-browser-args=--disable-setuid-sandbox', | 252 '--extra-browser-args=--disable-setuid-sandbox', |
228 '--browser=exact', | 253 '--browser=exact', |
229 '--browser-executable=%s' % self._browser_executable, | 254 '--browser-executable=%s' % self._browser_executable, |
230 '%s_page_set' % page_set_basename, | 255 '%s_page_set' % page_set_basename, |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 print '\n\n=======New SKPs have been uploaded to %s =======\n\n' % ( | 365 print '\n\n=======New SKPs have been uploaded to %s =======\n\n' % ( |
341 posixpath.join(self.gs.target_name(), dest_dir_name, | 366 posixpath.join(self.gs.target_name(), dest_dir_name, |
342 SKPICTURES_DIR_NAME)) | 367 SKPICTURES_DIR_NAME)) |
343 else: | 368 else: |
344 print '\n\n=======Not Uploading to %s=======\n\n' % self.gs.target_type() | 369 print '\n\n=======Not Uploading to %s=======\n\n' % self.gs.target_type() |
345 print 'Generated resources are available in %s\n\n' % ( | 370 print 'Generated resources are available in %s\n\n' % ( |
346 LOCAL_PLAYBACK_ROOT_DIR) | 371 LOCAL_PLAYBACK_ROOT_DIR) |
347 | 372 |
348 return 0 | 373 return 0 |
349 | 374 |
| 375 def _GetSkiaSkpFileName(self, page_set): |
| 376 """Returns the SKP file name for Skia page sets.""" |
| 377 # /path/to/skia_yahooanswers_desktop.py -> skia_yahooanswers_desktop.py |
| 378 ps_filename = os.path.basename(page_set) |
| 379 # skia_yahooanswers_desktop.py -> skia_yahooanswers_desktop |
| 380 ps_basename, _ = os.path.splitext(ps_filename) |
| 381 # skia_yahooanswers_desktop -> skia, yahooanswers, desktop |
| 382 _, page_name, device = ps_basename.split('_') |
| 383 basename = '%s_%s' % (DEVICE_TO_PLATFORM_PREFIX[device], page_name) |
| 384 return basename[:MAX_SKP_BASE_NAME_LEN] + '.skp' |
| 385 |
| 386 def _GetChromiumSkpFileName(self, page_set, site): |
| 387 """Returns the SKP file name for Chromium page sets.""" |
| 388 # /path/to/http___mobile_news_sandbox_pt0 -> http___mobile_news_sandbox_pt0 |
| 389 _, webpage = os.path.split(site) |
| 390 # http___mobile_news_sandbox_pt0 -> mobile_news_sandbox_pt0 |
| 391 webpage = webpage.lstrip('http___').lstrip('https___') |
| 392 # /path/to/skia_yahooanswers_desktop.py -> skia_yahooanswers_desktop.py |
| 393 ps_filename = os.path.basename(page_set) |
| 394 # http___mobile_news_sandbox -> pagesetprefix_http___mobile_news_sandbox |
| 395 basename = '%s_%s' % (CHROMIUM_PAGE_SETS_TO_PREFIX[ps_filename], webpage) |
| 396 return basename[:MAX_SKP_BASE_NAME_LEN] + '.skp' |
| 397 |
350 def _RenameSkpFiles(self, page_set): | 398 def _RenameSkpFiles(self, page_set): |
351 """Rename generated SKP files into more descriptive names. | 399 """Rename generated SKP files into more descriptive names. |
352 | 400 |
353 Look into the subdirectory of TMP_SKP_DIR and find the most interesting | 401 Look into the subdirectory of TMP_SKP_DIR and find the most interesting |
354 .skp in there to be this page_set's representative .skp. | 402 .skp in there to be this page_set's representative .skp. |
355 """ | 403 """ |
356 # Here's where we're assuming there's one page per pageset. | 404 subdirs = glob.glob(os.path.join(TMP_SKP_DIR, '*')) |
357 # If there were more than one, we'd overwrite filename below. | 405 for site in subdirs: |
| 406 if self._IsChromiumPageSet(page_set): |
| 407 filename = self._GetChromiumSkpFileName(page_set, site) |
| 408 else: |
| 409 filename = self._GetSkiaSkpFileName(page_set) |
358 | 410 |
359 # /path/to/skia_yahooanswers_desktop.json -> skia_yahooanswers_desktop.json | |
360 _, ps_filename = os.path.split(page_set) | |
361 # skia_yahooanswers_desktop.json -> skia_yahooanswers_desktop | |
362 ps_basename, _ = os.path.splitext(ps_filename) | |
363 # skia_yahooanswers_desktop -> skia, yahooanswers, desktop | |
364 _, page_name, device = ps_basename.split('_') | |
365 | |
366 basename = '%s_%s' % (DEVICE_TO_PLATFORM_PREFIX[device], page_name) | |
367 filename = basename[:MAX_SKP_BASE_NAME_LEN] + '.skp' | |
368 | |
369 subdirs = glob.glob(os.path.join(TMP_SKP_DIR, '*')) | |
370 assert len(subdirs) == 1 | |
371 for site in subdirs: | |
372 # We choose the largest .skp as the most likely to be interesting. | 411 # We choose the largest .skp as the most likely to be interesting. |
373 largest_skp = max(glob.glob(os.path.join(site, '*.skp')), | 412 largest_skp = max(glob.glob(os.path.join(site, '*.skp')), |
374 key=lambda path: os.stat(path).st_size) | 413 key=lambda path: os.stat(path).st_size) |
375 dest = os.path.join(self._local_skp_dir, filename) | 414 dest = os.path.join(self._local_skp_dir, filename) |
376 print 'Moving', largest_skp, 'to', dest | 415 print 'Moving', largest_skp, 'to', dest |
377 shutil.move(largest_skp, dest) | 416 shutil.move(largest_skp, dest) |
378 self._skp_files.append(filename) | 417 self._skp_files.append(filename) |
379 shutil.rmtree(site) | 418 shutil.rmtree(site) |
380 | 419 |
381 def _CreateLocalStorageDirs(self): | 420 def _CreateLocalStorageDirs(self): |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 def does_storage_object_exist(self, *args): | 455 def does_storage_object_exist(self, *args): |
417 raise NotImplementedError() | 456 raise NotImplementedError() |
418 def download_file(self, *args): | 457 def download_file(self, *args): |
419 raise NotImplementedError() | 458 raise NotImplementedError() |
420 def upload_dir_contents(self, source_dir, **kwargs): | 459 def upload_dir_contents(self, source_dir, **kwargs): |
421 raise NotImplementedError() | 460 raise NotImplementedError() |
422 | 461 |
423 class GoogleStorageDataStore(DataStore): | 462 class GoogleStorageDataStore(DataStore): |
424 def __init__(self, data_store_url): | 463 def __init__(self, data_store_url): |
425 self._data_store_url = data_store_url | 464 self._data_store_url = data_store_url |
426 self._bucket = remove_prefix(self._data_store_url.lstrip(), | 465 self._bucket = remove_prefix(self._data_store_url.lstrip(), |
427 gs_utils.GS_PREFIX) | 466 gs_utils.GS_PREFIX) |
428 self.gs = gs_utils.GSUtils() | 467 self.gs = gs_utils.GSUtils() |
429 def target_name(self): | 468 def target_name(self): |
430 return self._data_store_url | 469 return self._data_store_url |
431 def target_type(self): | 470 def target_type(self): |
432 return 'Google Storage' | 471 return 'Google Storage' |
433 def does_storage_object_exist(self, *args): | 472 def does_storage_object_exist(self, *args): |
434 return self.gs.does_storage_object_exist(self._bucket, *args) | 473 return self.gs.does_storage_object_exist(self._bucket, *args) |
435 def download_file(self, *args): | 474 def download_file(self, *args): |
436 self.gs.download_file(self._bucket, *args) | 475 self.gs.download_file(self._bucket, *args) |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 default=None) | 550 default=None) |
512 option_parser.add_option( | 551 option_parser.add_option( |
513 '', '--non-interactive', action='store_true', | 552 '', '--non-interactive', action='store_true', |
514 help='Runs the script without any prompts. If this flag is specified and ' | 553 help='Runs the script without any prompts. If this flag is specified and ' |
515 '--skia_tools is specified then the debugger is not run.', | 554 '--skia_tools is specified then the debugger is not run.', |
516 default=False) | 555 default=False) |
517 options, unused_args = option_parser.parse_args() | 556 options, unused_args = option_parser.parse_args() |
518 | 557 |
519 playback = SkPicturePlayback(options) | 558 playback = SkPicturePlayback(options) |
520 sys.exit(playback.Run()) | 559 sys.exit(playback.Run()) |
OLD | NEW |