| Index: tools/telemetry/telemetry/page/extensions_profile_creator.py
|
| diff --git a/tools/telemetry/telemetry/page/extensions_profile_creator.py b/tools/telemetry/telemetry/page/extensions_profile_creator.py
|
| deleted file mode 100644
|
| index 2ea15bd3e6909fdc87d53493bd494adcad1fc29b..0000000000000000000000000000000000000000
|
| --- a/tools/telemetry/telemetry/page/extensions_profile_creator.py
|
| +++ /dev/null
|
| @@ -1,223 +0,0 @@
|
| -# Copyright 2013 The Chromium Authors. All rights reserved.
|
| -# Use of this source code is governed by a BSD-style license that can be
|
| -# found in the LICENSE file.
|
| -import json
|
| -import logging
|
| -import os
|
| -import platform
|
| -import shutil
|
| -import socket
|
| -import sys
|
| -import tempfile
|
| -import time
|
| -import urllib2
|
| -import zipfile
|
| -
|
| -from telemetry.core import util
|
| -from telemetry.page import page_set
|
| -from telemetry.page import profile_creator
|
| -
|
| -
|
| -def _ExternalExtensionsPath():
|
| - """Returns the OS-dependent path at which to install the extension deployment
|
| - files"""
|
| - if platform.system() == 'Darwin':
|
| - return os.path.join('/Library', 'Application Support', 'Google', 'Chrome',
|
| - 'External Extensions')
|
| - elif platform.system() == 'Linux':
|
| - return os.path.join('/opt', 'google', 'chrome', 'extensions' )
|
| - else:
|
| - raise NotImplementedError('Extension install on %s is not yet supported' %
|
| - platform.system())
|
| -
|
| -def _DownloadExtension(extension_id, output_dir):
|
| - """Download an extension to disk.
|
| -
|
| - Args:
|
| - extension_id: the extension id.
|
| - output_dir: Directory to download into.
|
| -
|
| - Returns:
|
| - Extension file downloaded."""
|
| - extension_download_path = os.path.join(output_dir, "%s.crx" % extension_id)
|
| - extension_url = (
|
| - "https://clients2.google.com/service/update2/crx?response=redirect"
|
| - "&x=id%%3D%s%%26lang%%3Den-US%%26uc" % extension_id)
|
| - response = urllib2.urlopen(extension_url)
|
| - assert(response.getcode() == 200)
|
| -
|
| - with open(extension_download_path, "w") as f:
|
| - f.write(response.read())
|
| -
|
| - return extension_download_path
|
| -
|
| -def _GetExtensionInfoFromCRX(crx_path):
|
| - """Parse an extension archive and return information.
|
| -
|
| - Note:
|
| - The extension name returned by this function may not be valid
|
| - (e.g. in the case of a localized extension name). It's use is just
|
| - meant to be informational.
|
| -
|
| - Args:
|
| - crx_path: path to crx archive to look at.
|
| -
|
| - Returns:
|
| - Tuple consisting of:
|
| - (crx_version, extension_name)"""
|
| - crx_zip = zipfile.ZipFile(crx_path)
|
| - manifest_contents = crx_zip.read('manifest.json')
|
| - decoded_manifest = json.loads(manifest_contents)
|
| - crx_version = decoded_manifest['version']
|
| - extension_name = decoded_manifest['name']
|
| -
|
| - return (crx_version, extension_name)
|
| -
|
| -class ExtensionsProfileCreator(profile_creator.ProfileCreator):
|
| - """Virtual base class for profile creators that install extensions.
|
| -
|
| - Extensions are installed using the mechanism described in
|
| - https://developer.chrome.com/extensions/external_extensions.html .
|
| -
|
| - Subclasses are meant to be run interactively.
|
| - """
|
| -
|
| - def __init__(self):
|
| - super(ExtensionsProfileCreator, self).__init__()
|
| - typical_25 = os.path.join(util.GetBaseDir(), 'page_sets', 'typical_25.py')
|
| - self._page_set = page_set.PageSet.FromFile(typical_25)
|
| -
|
| - # Directory into which the output profile is written.
|
| - self._output_profile_path = None
|
| -
|
| - # List of extensions to install.
|
| - self._extensions_to_install = []
|
| -
|
| - # Theme to install (if any).
|
| - self._theme_to_install = None
|
| -
|
| - # Directory to download extension files into.
|
| - self._extension_download_dir = None
|
| -
|
| - # Have the extensions been installed yet?
|
| - self._extensions_installed = False
|
| -
|
| - # List of files to delete after run.
|
| - self._files_to_cleanup = []
|
| -
|
| - def _PrepareExtensionInstallFiles(self):
|
| - """Download extension archives and create extension install files."""
|
| - extensions_to_install = self._extensions_to_install
|
| - if self._theme_to_install:
|
| - extensions_to_install = extensions_to_install + [self._theme_to_install]
|
| - num_extensions = len(extensions_to_install)
|
| - if not num_extensions:
|
| - raise ValueError("No extensions or themes to install:",
|
| - extensions_to_install)
|
| -
|
| - # Create external extensions path if it doesn't exist already.
|
| - external_extensions_dir = _ExternalExtensionsPath()
|
| - if not os.path.isdir(external_extensions_dir):
|
| - os.makedirs(external_extensions_dir)
|
| -
|
| - self._extension_download_dir = tempfile.mkdtemp()
|
| -
|
| - for i in xrange(num_extensions):
|
| - extension_id = extensions_to_install[i]
|
| - logging.info("Downloading %s - %d/%d" % (
|
| - extension_id, (i + 1), num_extensions))
|
| - extension_path = _DownloadExtension(extension_id,
|
| - self._extension_download_dir)
|
| - (version, name) = _GetExtensionInfoFromCRX(extension_path)
|
| - extension_info = {'external_crx' : extension_path,
|
| - 'external_version' : version,
|
| - '_comment' : name}
|
| - extension_json_path = os.path.join(external_extensions_dir,
|
| - "%s.json" % extension_id)
|
| - with open(extension_json_path, 'w') as f:
|
| - f.write(json.dumps(extension_info))
|
| - self._files_to_cleanup.append(extension_json_path)
|
| -
|
| - def _CleanupExtensionInstallFiles(self):
|
| - """Cleanup stray files before exiting."""
|
| - logging.info("Cleaning up stray files")
|
| - for filename in self._files_to_cleanup:
|
| - os.remove(filename)
|
| -
|
| - if self._extension_download_dir:
|
| - # Simple sanity check to lessen the impact of a stray rmtree().
|
| - if len(self._extension_download_dir.split(os.sep)) < 3:
|
| - raise Exception("Path too shallow: %s" % self._extension_download_dir)
|
| - shutil.rmtree(self._extension_download_dir)
|
| - self._extension_download_dir = None
|
| -
|
| - def CustomizeBrowserOptions(self, options):
|
| - self._output_profile_path = options.output_profile_path
|
| -
|
| - def WillRunTest(self, options):
|
| - """Run before browser starts.
|
| -
|
| - Download extensions and write installation files."""
|
| - super(ExtensionsProfileCreator, self).WillRunTest(options)
|
| -
|
| - # Running this script on a corporate network or other managed environment
|
| - # could potentially alter the profile contents.
|
| - hostname = socket.gethostname()
|
| - if hostname.endswith('corp.google.com'):
|
| - raise Exception("It appears you are connected to a corporate network "
|
| - "(hostname=%s). This script needs to be run off the corp "
|
| - "network." % hostname)
|
| -
|
| - prompt = ("\n!!!This script must be run on a fresh OS installation, "
|
| - "disconnected from any corporate network. Are you sure you want to "
|
| - "continue? (y/N) ")
|
| - if (raw_input(prompt).lower() != 'y'):
|
| - sys.exit(-1)
|
| - self._PrepareExtensionInstallFiles()
|
| -
|
| - def DidRunTest(self, browser, results):
|
| - """Run before exit."""
|
| - super(ExtensionsProfileCreator, self).DidRunTest()
|
| - # Do some basic sanity checks to make sure the profile is complete.
|
| - installed_extensions = browser.extensions.keys()
|
| - if not len(installed_extensions) == len(self._extensions_to_install):
|
| - # Diagnosing errors:
|
| - # Too many extensions: Managed environment may be installing additional
|
| - # extensions.
|
| - raise Exception("Unexpected number of extensions installed in browser",
|
| - installed_extensions)
|
| -
|
| - # Check that files on this list exist and have content.
|
| - expected_files = [
|
| - os.path.join('Default', 'Network Action Predictor')]
|
| - for filename in expected_files:
|
| - filename = os.path.join(self._output_profile_path, filename)
|
| - if not os.path.getsize(filename) > 0:
|
| - raise Exception("Profile not complete: %s is zero length." % filename)
|
| -
|
| - self._CleanupExtensionInstallFiles()
|
| -
|
| - def CanRunForPage(self, page):
|
| - # No matter how many pages in the pageset, just perform two test iterations.
|
| - return page.page_set.pages.index(page) < 2
|
| -
|
| - def MeasurePage(self, _, tab, results):
|
| - # Profile setup works in 2 phases:
|
| - # Phase 1: When the first page is loaded: we wait for a timeout to allow
|
| - # all extensions to install and to prime safe browsing and other
|
| - # caches. Extensions may open tabs as part of the install process.
|
| - # Phase 2: When the second page loads, page_runner closes all tabs -
|
| - # we are left with one open tab, wait for that to finish loading.
|
| -
|
| - # Sleep for a bit to allow safe browsing and other data to load +
|
| - # extensions to install.
|
| - if not self._extensions_installed:
|
| - sleep_seconds = 5 * 60
|
| - logging.info("Sleeping for %d seconds." % sleep_seconds)
|
| - time.sleep(sleep_seconds)
|
| - self._extensions_installed = True
|
| - else:
|
| - # Phase 2: Wait for tab to finish loading.
|
| - for i in xrange(len(tab.browser.tabs)):
|
| - t = tab.browser.tabs[i]
|
| - t.WaitForDocumentReadyStateToBeComplete()
|
|
|