| 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_dir): |
| 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_dir) |
| 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_dir): |
| 84 raise Exception("Profile directory archive not downloaded: ", |
| 85 self._pregenerated_profile_archive_dir) |
| 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_dir) |
| 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_dir) 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.browser_options.output_profile_path |
| 127 |
| 128 # Set the input and output profiles. |
| 129 finder_options.browser_options.profile_dir = initial_profile |
| 130 finder_options.browser_options.output_profile_path = final_profile |
| 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.browser_options.output_profile_path = saved_output_profile |
| 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 |