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

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

Issue 914253005: Telemetry: Create new profile creator large_profile_creator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments from sullivan. Created 5 years, 10 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
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 import time 4 import time
5 5
6 from telemetry.core import browser_finder 6 from telemetry.core import browser_finder
7 from telemetry.core import browser_finder_exceptions 7 from telemetry.core import browser_finder_exceptions
8 from telemetry.core import exceptions 8 from telemetry.core import exceptions
9 from telemetry.core import platform
9 from telemetry.core import util 10 from telemetry.core import util
10 11
11 12
12 class FastNavigationProfileExtender(object): 13 class FastNavigationProfileExtender(object):
13 """Extends a Chrome profile. 14 """Extends a Chrome profile.
14 15
15 This class creates or extends an existing profile by performing a set of tab 16 This class creates or extends an existing profile by performing a set of tab
16 navigations in large batches. This is accomplished by opening a large number 17 navigations in large batches. This is accomplished by opening a large number
17 of tabs, simultaneously navigating all the tabs, and then waiting for all the 18 of tabs, simultaneously navigating all the tabs, and then waiting for all the
18 tabs to load. This provides two benefits: 19 tabs to load. This provides two benefits:
19 - Takes advantage of the high number of logical cores on modern CPUs. 20 - Takes advantage of the high number of logical cores on modern CPUs.
20 - The total time spent waiting for navigations to time out scales linearly 21 - The total time spent waiting for navigations to time out scales linearly
21 with the number of batches, but does not scale with the size of the 22 with the number of batches, but does not scale with the size of the
22 batch. 23 batch.
23 """ 24 """
24 def __init__(self): 25 def __init__(self, maximum_batch_size):
26 """Initializer.
27
28 Args:
29 maximum_batch_size: A positive integer indicating the number of tabs to
30 simultaneously perform navigations.
31 """
25 super(FastNavigationProfileExtender, self).__init__() 32 super(FastNavigationProfileExtender, self).__init__()
26 33
34 # The path of the profile that the browser will use while it's running.
35 # This member is initialized during SetUp().
36 self._profile_path = None
37
27 # A reference to the browser that will be performing all of the tab 38 # A reference to the browser that will be performing all of the tab
28 # navigations. 39 # navigations.
40 # This member is initialized during SetUp().
29 self._browser = None 41 self._browser = None
30 42
31 # A static copy of the urls that this class is going to navigate to.
32 self._navigation_urls = None
33
34 # The number of tabs to use. 43 # The number of tabs to use.
35 self._NUM_TABS = 15 44 self._NUM_TABS = maximum_batch_size
36
37 # The number of pages to load in parallel.
38 self._NUM_PARALLEL_PAGES = 15
39
40 assert self._NUM_PARALLEL_PAGES <= self._NUM_TABS, (' the batch size can\'t'
41 ' be larger than the number of available tabs')
42 45
43 # The amount of time to wait for a batch of pages to finish loading. 46 # The amount of time to wait for a batch of pages to finish loading.
44 self._BATCH_PAGE_LOAD_TIMEOUT_IN_SECONDS = 10 47 self._BATCH_PAGE_LOAD_TIMEOUT_IN_SECONDS = 10
45 48
46 # The default amount of time to wait for the retrieval of the URL of a tab. 49 # The default amount of time to wait for the retrieval of the URL of a tab.
47 self._TAB_URL_RETRIEVAL_TIMEOUT_IN_SECONDS = 1 50 self._TAB_URL_RETRIEVAL_TIMEOUT_IN_SECONDS = 1
48 51
49 def Run(self, finder_options): 52 def Run(self, finder_options):
50 """Extends the profile. 53 """Extends the profile.
51 54
52 Args: 55 Args:
53 finder_options: An instance of BrowserFinderOptions that contains the 56 finder_options: An instance of BrowserFinderOptions that contains the
54 directory of the input profile, the directory to place the output 57 directory of the input profile, the directory to place the output
55 profile, and sufficient information to choose a specific browser binary. 58 profile, and sufficient information to choose a specific browser binary.
56 """ 59 """
57 try: 60 try:
58 self._navigation_urls = self.GetUrlsToNavigate() 61 self.SetUp(finder_options)
59 self._SetUpBrowser(finder_options)
60 self._PerformNavigations() 62 self._PerformNavigations()
61 finally: 63 finally:
62 self._TearDownBrowser() 64 self.TearDown()
63 65
64 def GetUrlsToNavigate(self): 66 def GetUrlIterator(self):
65 """Returns a list of urls to be navigated to. 67 """Gets URLs for the browser to navigate to.
68
69 Intended for subclass override.
70
71 Returns:
72 An iterator whose elements are urls to be navigated to.
73 """
74 raise NotImplementedError()
75
76 def ShouldExitAfterBatchNavigation(self):
77 """Returns a boolean indicating whether profile extension is finished.
66 78
67 Intended for subclass override. 79 Intended for subclass override.
68 """ 80 """
69 raise NotImplementedError() 81 raise NotImplementedError()
70 82
83 def SetUp(self, finder_options):
84 """Finds the browser, starts the browser, and opens the requisite number of
85 tabs.
86
87 Can be overridden by subclasses. Subclasses must call the super class
88 implementation.
89 """
90 self._profile_path = finder_options.output_profile_path
91 possible_browser = self._GetPossibleBrowser(finder_options)
92
93 assert possible_browser.supports_tab_control
94 assert (platform.GetHostPlatform().GetOSName() in
95 ["win", "mac", "linux"])
96 self._browser = possible_browser.Create(finder_options)
97
98 while(len(self._browser.tabs) < self._NUM_TABS):
99 self._browser.tabs.New()
100
101 def TearDown(self):
102 """Teardown that is guaranteed to be executed before the instance is
103 destroyed.
104
105 Can be overridden by subclasses. Subclasses must call the super class
106 implementation.
107 """
108 if self._browser:
109 self._browser.Close()
110 self._browser = None
111
112 def CleanUpAfterBatchNavigation(self):
113 """A hook for subclasses to perform cleanup after each batch of
114 navigations.
115
116 Can be overridden by subclasses.
117 """
118 pass
119
120 @property
121 def profile_path(self):
122 return self._profile_path
71 123
72 def _GetPossibleBrowser(self, finder_options): 124 def _GetPossibleBrowser(self, finder_options):
73 """Return a possible_browser with the given options.""" 125 """Return a possible_browser with the given options."""
74 possible_browser = browser_finder.FindBrowser(finder_options) 126 possible_browser = browser_finder.FindBrowser(finder_options)
75 if not possible_browser: 127 if not possible_browser:
76 raise browser_finder_exceptions.BrowserFinderException( 128 raise browser_finder_exceptions.BrowserFinderException(
77 'No browser found.\n\nAvailable browsers:\n%s\n' % 129 'No browser found.\n\nAvailable browsers:\n%s\n' %
78 '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options))) 130 '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options)))
79 finder_options.browser_options.browser_type = ( 131 finder_options.browser_options.browser_type = (
80 possible_browser.browser_type) 132 possible_browser.browser_type)
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 207
156 seconds_to_wait = end_time - time.time() 208 seconds_to_wait = end_time - time.time()
157 seconds_to_wait = max(0, seconds_to_wait) 209 seconds_to_wait = max(0, seconds_to_wait)
158 210
159 try: 211 try:
160 tab.WaitForDocumentReadyStateToBeComplete(seconds_to_wait) 212 tab.WaitForDocumentReadyStateToBeComplete(seconds_to_wait)
161 except (util.TimeoutException, exceptions.DevtoolsTargetCrashException): 213 except (util.TimeoutException, exceptions.DevtoolsTargetCrashException):
162 # Ignore time outs and web page crashes. 214 # Ignore time outs and web page crashes.
163 pass 215 pass
164 216
165 def _SetUpBrowser(self, finder_options): 217 def _GetUrlsToNavigate(self, url_iterator):
166 """Finds the browser, starts the browser, and opens the requisite number of 218 """Returns an array of urls to navigate to, given a url_iterator."""
167 tabs.""" 219 urls = []
168 possible_browser = self._GetPossibleBrowser(finder_options) 220 for _ in xrange(self._NUM_TABS):
169 self._browser = possible_browser.Create(finder_options) 221 try:
170 222 urls.append(url_iterator.next())
171 for _ in range(self._NUM_TABS): 223 except StopIteration:
172 self._browser.tabs.New() 224 break
225 return urls
173 226
174 def _PerformNavigations(self): 227 def _PerformNavigations(self):
175 """Performs the navigations specified by |_navigation_urls| in large 228 """Repeatedly fetches a batch of urls, and navigates to those urls. This
176 batches.""" 229 will run until an empty batch is returned, or
177 # The index of the first url that has not yet been navigated to. 230 ShouldExitAfterBatchNavigation() returns True.
178 navigation_url_index = 0 231 """
232 url_iterator = self.GetUrlIterator()
179 while True: 233 while True:
180 # Generate the next batch of navigations. 234 urls = self._GetUrlsToNavigate(url_iterator)
235
236 if len(urls) == 0:
237 break
238
181 batch = [] 239 batch = []
182 max_index = min(navigation_url_index + self._NUM_PARALLEL_PAGES, 240 for i in range(len(urls)):
183 len(self._navigation_urls)) 241 url = urls[i]
184 for i in range(navigation_url_index, max_index): 242 tab = self._browser.tabs[i]
185 url = self._navigation_urls[i]
186 tab = self._browser.tabs[i % self._NUM_TABS]
187 batch.append((tab, url)) 243 batch.append((tab, url))
188 navigation_url_index = max_index
189 244
190 queued_tabs = self._BatchNavigateTabs(batch) 245 queued_tabs = self._BatchNavigateTabs(batch)
191 self._WaitForQueuedTabsToLoad(queued_tabs) 246 self._WaitForQueuedTabsToLoad(queued_tabs)
192 247
193 if navigation_url_index == len(self._navigation_urls): 248 self.CleanUpAfterBatchNavigation()
249
250 if self.ShouldExitAfterBatchNavigation():
194 break 251 break
195
196 def _TearDownBrowser(self):
197 """Teardown that is guaranteed to be executed before the instance is
198 destroyed."""
199 if self._browser:
200 self._browser.Close()
201 self._browser = None
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698