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

Side by Side Diff: tools/perf/profile_creators/extension_profile_extender.py

Issue 1240703003: Extension profile generator + benchmark for startup with profile. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Style, error handling fixes and zipped extension_set Created 5 years, 5 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
OLDNEW
(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
5 import json
6 import os
7 import platform
8 import zipfile
9
10 from catapult_base import cloud_storage
11 from profile_creators import fast_navigation_profile_extender
12 import page_sets
13
14 # Remote directory to download extensions from in cloud storage.
15 REMOTE_DIR = "extension_set"
16 # Name of zip archive to download.
17 ZIP_NAME = "extensions.zip"
18
19
20 class InvalidExtensionArchiveError(Exception):
erikchen 2015/07/16 00:33:28 this should inherit from exceptions.error, a telem
sydli 2015/07/16 00:53:14 Done.
21 """ Exception thrown when remote archive is invalid or malformed.
22
23 Remote archive should be located at REMOTE_DIR/ZIP_NAME. Upon failure,
24 Prompts user to update remote archive using update_remote_extensions
25 script. """
26
27 def __init__(self, msg=''):
28 msg += "\nTry running" + \
29 "\n\tpython update_remote_extensions.py -e extension_set.csv\n" + \
30 "in src/tools/perf/profile_creator subdirectory."
31 super(InvalidExtensionArchiveError, self).__init__(msg)
32
33
34 class ExtensionProfileExtender(
35 fast_navigation_profile_extender.FastNavigationProfileExtender):
36 """Creates a profile with many extensions. """
37
38 def __init__(self, finder_options):
39 maximum_batch_size = 1
40 super(ExtensionProfileExtender, self).__init__(
41 finder_options, maximum_batch_size)
42 self._page_set = page_sets.BlankPageSet()
43 urls = []
44 for story in self._page_set.stories:
45 urls.append(story.url)
46 self._navigation_urls = urls
47 finder_options.browser_options.disable_default_apps = False
48
49 def _DownloadRemoteExtensions(self, remote_bucket, local_extensions_dir):
50 """ Downloads archive of common extensions to disk and unzips.
51
52 Args:
53 remote_bucket: bucket to download remote archive from.
54 local_extensions_dir: directory to unzip archive into.
55
56 Raises:
57 InvalidExtensionArchiveError if cannot find remote archive.
58 """
59 remote_zip_path = os.path.join(REMOTE_DIR, ZIP_NAME)
60 local_zip_path = os.path.join(local_extensions_dir, ZIP_NAME)
61 try:
62 cloud_storage.Get(remote_bucket, remote_zip_path,
63 local_zip_path)
erikchen 2015/07/16 00:33:28 I think this is incorrectly formatted.
sydli 2015/07/16 00:53:13 Done. Probably did this wrong everywhere else, so
64 except:
65 raise InvalidExtensionArchiveError("Can't find archive at gs://%s/%s."
66 % (remote_bucket, remote_zip_path))
erikchen 2015/07/16 00:33:28 formatting
sydli 2015/07/16 00:53:13 Done.
67 with zipfile.ZipFile(local_zip_path, "r") as extensions_zip:
68 extensions_zip.extractall(local_extensions_dir)
69 os.remove(local_zip_path)
70
71 def _GetExtensionInfoFromCRX(self, crxfile):
72 """ Retrieves version + name of extension from CRX archive. """
73 crx_zip = zipfile.ZipFile(crxfile)
74 manifest_contents = crx_zip.read('manifest.json')
75 decoded_manifest = json.loads(manifest_contents)
76 crx_version = decoded_manifest['version']
77 extension_name = decoded_manifest['name']
78 return (crx_version, extension_name)
79
80 def _LoadExtensions(self, local_extensions_dir, profile_dir):
81 """ Loads extensions in _local_extensions_dir into user profile.
82
83 Extensions are loaded according to platform specifications at
84 https://developer.chrome.com/extensions/external_extensions.html .
85
86 Args:
87 local_extensions_dir: directory containing *CRX files.
88 profile_dir: user profile directory to load extensions into.
89
90 Raises:
91 InvalidExtensionArchiveError if archive contains a non-CRX file.
92 """
93 ext_files = os.listdir(local_extensions_dir)
94 external_ext_dir = os.path.join(profile_dir, "External Extensions")
95 os.makedirs(external_ext_dir)
96 for ext_file in ext_files:
97 ext_path = os.path.join(local_extensions_dir, ext_file)
98 if not ext_file.endswith(".crx"):
99 raise InvalidExtensionArchiveError("Archive contains non-crx file %s."
100 % ext_file)
101 (version, name) = self._GetExtensionInfoFromCRX(ext_path)
102 extension_info = {
103 'external_crx': ext_path,
104 'external_version': version,
105 '_comment': name
106 }
107 ext_id = os.path.splitext(os.path.basename(ext_path))[0]
108 extension_json_path = os.path.join(external_ext_dir, "%s.json" % ext_id)
109 with open(extension_json_path, 'w') as f:
110 f.write(json.dumps(extension_info))
111
112 def GetUrlIterator(self):
113 """Superclass override."""
114 return iter(self._navigation_urls)
115
116 def ShouldExitAfterBatchNavigation(self):
117 """Superclass override."""
118 return False
119
120 def Run(self):
121 # DL extensions from cloud & force-install extensions into profile.
122 if platform.system() != 'Darwin':
123 raise NotImplementedError('Extension profile generator on %s is not yet '
124 'supported' % platform.system())
125 local_extensions_dir = os.path.join(self.profile_path,
126 "external_extensions_crx")
127 self._DownloadRemoteExtensions(cloud_storage.PARTNER_BUCKET,
128 local_extensions_dir)
129 self._LoadExtensions(local_extensions_dir, self.profile_path)
130 super(ExtensionProfileExtender, self).Run()
131
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698