Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 # found in the LICENSE file. | |
| 4 import logging | |
| 5 import os | |
| 6 import shutil | |
| 7 import sys | |
| 8 import tempfile | |
| 9 import zipfile | |
| 10 | |
| 11 from catapult_base import cloud_storage | |
| 12 | |
| 13 from telemetry.page import shared_page_state | |
| 14 | |
| 15 | |
| 16 class PregeneratedProfileSharedState(shared_page_state.SharedPageState): | |
| 17 def __init__(self, test, finder_options, story_set): | |
| 18 super(PregeneratedProfileSharedState, self).__init__( | |
| 19 test, finder_options, story_set) | |
| 20 self._unzipped_profile = None | |
| 21 self._migrated_profile = None | |
| 22 self._pregenerated_profile_archive_dir = None | |
| 23 | |
| 24 def WillRunStory(self, page): | |
| 25 if self._ShouldDownloadPregeneratedProfileArchive(): | |
| 26 self._DownloadPregeneratedProfileArchive() | |
| 27 | |
| 28 if self._ShouldMigrateProfile(): | |
| 29 self._MigratePregeneratedProfile() | |
| 30 super(PregeneratedProfileSharedState, self).WillRunStory(page) | |
| 31 | |
| 32 def TearDownState(self): | |
| 33 if self._unzipped_profile: | |
| 34 shutil.rmtree(self._unzipped_profile) | |
| 35 self._unzipped_profile = None | |
| 36 if self._migrated_profile: | |
| 37 shutil.rmtree(self._migrated_profile) | |
| 38 self._migrated_profile = None | |
| 39 super(PregeneratedProfileSharedState, self).TearDownState() | |
| 40 | |
| 41 def _ShouldDownloadPregeneratedProfileArchive(self): | |
| 42 """Whether to download a pre-generated profile archive.""" | |
| 43 if not self._pregenerated_profile_archive_dir: | |
| 44 return False | |
| 45 | |
| 46 if self._finder_options.browser_options.profile_dir: | |
| 47 logging.warning("Profile directory specified on command line: %s, this" | |
| 48 "overrides the benchmark's default profile directory.", | |
| 49 self._finder_options.browser_options.profile_dir) | |
| 50 return False | |
| 51 | |
| 52 if self._possible_browser.IsRemote(): | |
| 53 return False | |
| 54 | |
| 55 return True | |
| 56 | |
| 57 def _DownloadPregeneratedProfileArchive(self): | |
| 58 """Download and extract the profile directory archive if one exists. | |
| 59 | |
| 60 On success, updates self._finder_options.browser_options.profile_dir with | |
| 61 the directory of the extracted profile. | |
| 62 """ | |
| 63 try: | |
| 64 cloud_storage.GetIfChanged(self._pregenerated_profile_archive_dir, | |
| 65 cloud_storage.PUBLIC_BUCKET) | |
| 66 except (cloud_storage.CredentialsError, | |
| 67 cloud_storage.PermissionError) as e: | |
| 68 if os.path.exists(self._pregenerated_profile_archive_path): | |
| 69 # If the profile directory archive exists, assume the user has their | |
| 70 # own local copy simply warn. | |
| 71 logging.warning('Could not download Profile archive: %s', | |
| 72 self._pregenerated_profile_archive_dir) | |
| 73 else: | |
| 74 # If the archive profile directory doesn't exist, this is fatal. | |
| 75 logging.error('Can not run without required profile archive: %s. ' | |
| 76 'If you believe you have credentials, follow the ' | |
| 77 'instructions below.', | |
| 78 self._pregenerated_profile_archive_path) | |
| 79 logging.error(str(e)) | |
| 80 sys.exit(-1) | |
| 81 | |
| 82 # Check to make sure the zip file exists. | |
| 83 if not os.path.isfile(self._pregenerated_profile_archive_path): | |
| 84 raise Exception("Profile directory archive not downloaded: ", | |
| 85 self._pregenerated_profile_archive_path) | |
| 86 | |
| 87 # The location to extract the profile into. | |
| 88 self._unzipped_profile = tempfile.mkdtemp() | |
| 89 profile_archive_path_basename = os.path.basename( | |
| 90 self._pregenerated_profile_archive_path) | |
| 91 extracted_profile_dir_path = os.path.join( | |
| 92 self._unzipped_profile, | |
| 93 os.path.splitext(profile_archive_path_basename)[0]) | |
| 94 | |
| 95 # Unzip profile directory. | |
| 96 with zipfile.ZipFile(self._pregenerated_profile_archive_path) as f: | |
| 97 try: | |
| 98 f.extractall(self._unzipped_profile) | |
| 99 except Exception as e: | |
| 100 # Cleanup any leftovers from unzipping. | |
| 101 shutil.rmtree(self._unzipped_profile) | |
| 102 logging.error("Error extracting profile directory zip file: %s", e) | |
| 103 sys.exit(-1) | |
| 104 | |
| 105 if not os.path.exists(extracted_profile_dir_path): | |
| 106 raise Exception("Failed to extract profile: ", | |
| 107 extracted_profile_dir_path) | |
| 108 | |
| 109 # Run with freshly extracted profile directory. | |
| 110 logging.info("Using profile archive directory: %s", | |
| 111 extracted_profile_dir_path) | |
| 112 self._finder_options.browser_options.profile_dir = ( | |
| 113 extracted_profile_dir_path) | |
| 114 | |
| 115 def _ShouldMigrateProfile(self): | |
| 116 return not self._migrated_profile | |
| 117 | |
| 118 def _MigrateProfile(self, finder_options, found_browser, | |
| 119 initial_profile, final_profile): | |
| 120 """Migrates a profile to be compatible with a newer version of Chrome. | |
| 121 | |
| 122 Launching Chrome with the old profile will perform the migration. | |
| 123 """ | |
| 124 # Save the current input and output profiles. | |
| 125 saved_input_profile = finder_options.browser_options.profile_dir | |
| 126 saved_output_profile = finder_options.output_profile_path | |
|
eakuefner
2016/04/12 18:13:23
Since https://codereview.chromium.org/1874473006 h
| |
| 127 | |
| 128 # Set the input and output profiles. | |
| 129 finder_options.browser_options.profile_dir = initial_profile | |
| 130 finder_options.output_profile_path = final_profile | |
|
eakuefner
2016/04/12 18:13:22
and here
| |
| 131 | |
| 132 # Launch the browser, then close it. | |
| 133 browser = found_browser.Create(finder_options) | |
| 134 browser.Close() | |
| 135 | |
| 136 # Load the saved input and output profiles. | |
| 137 finder_options.browser_options.profile_dir = saved_input_profile | |
| 138 finder_options.output_profile_path = saved_output_profile | |
|
eakuefner
2016/04/12 18:13:22
and here
| |
| 139 | |
| 140 def _MigratePregeneratedProfile(self): | |
| 141 """Migrates the pre-generated profile by launching Chrome with it. | |
| 142 | |
| 143 On success, updates self._migrated_profile and | |
| 144 self._finder_options.browser_options.profile_dir with the directory of the | |
| 145 migrated profile. | |
| 146 """ | |
| 147 self._migrated_profile = tempfile.mkdtemp() | |
| 148 logging.info("Starting migration of pre-generated profile to %s", | |
| 149 self._migrated_profile) | |
| 150 pregenerated_profile = self._finder_options.browser_options.profile_dir | |
| 151 | |
| 152 possible_browser = self._FindBrowser(self._finder_options) | |
| 153 self._MigrateProfile(self._finder_options, possible_browser, | |
| 154 pregenerated_profile, self._migrated_profile) | |
| 155 self._finder_options.browser_options.profile_dir = self._migrated_profile | |
| 156 logging.info("Finished migration of pre-generated profile to %s", | |
| 157 self._migrated_profile) | |
| OLD | NEW |