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

Side by Side Diff: chrome/test/functional/perf.py

Issue 10803002: Run Chrome Endure tests with network simulation via Web Page Replay. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Dennis' Comments Created 8 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 | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Basic pyauto performance tests. 6 """Basic pyauto performance tests.
7 7
8 For tests that need to be run for multiple iterations (e.g., so that average 8 For tests that need to be run for multiple iterations (e.g., so that average
9 and standard deviation values can be reported), the default number of iterations 9 and standard deviation values can be reported), the default number of iterations
10 run for each of these tests is specified by |_DEFAULT_NUM_ITERATIONS|. 10 run for each of these tests is specified by |_DEFAULT_NUM_ITERATIONS|.
(...skipping 1710 matching lines...) Expand 10 before | Expand all | Expand 10 after
1721 fps = result.repeat_frame_times.GetFps() 1721 fps = result.repeat_frame_times.GetFps()
1722 assert fps, '%s did not scroll' % url 1722 assert fps, '%s did not scroll' % url
1723 logging.info('Iteration %d of %d: %f fps', iteration, 1723 logging.info('Iteration %d of %d: %f fps', iteration,
1724 self._num_iterations, fps) 1724 self._num_iterations, fps)
1725 results.append(result) 1725 results.append(result)
1726 self._PrintSummaryResults( 1726 self._PrintSummaryResults(
1727 description, [r.repeat_frame_times.GetFps() for r in results], 1727 description, [r.repeat_frame_times.GetFps() for r in results],
1728 'FPS', graph_name) 1728 'FPS', graph_name)
1729 1729
1730 1730
1731 class BaseWebPageReplay(object):
1732 """Run tests with network simulation via Web Page Replay.
1733
1734 Web Page Replay is a proxy that can record and "replay" web pages with
1735 simulated network characteristics -- without having to edit the pages
1736 by hand. With WPR, tests can use "real" web content, and catch
1737 performance issues that may result from introducing network delays and
1738 bandwidth throttling.
1739
1740 This class provides a minimum set of settings for running tests with
1741 Web Page Replay.
1742
1743 Environment Variables:
1744 WPR_RECORD: if set, puts Web Page Replay in record mode instead of replay.
1745 WPR_REPLAY_DIR: path to alternate Web Page Replay source (for development).
1746 WPR_ARCHIVE_PATH: path to alternate archive file (e.g. '/tmp/foo.wpr').
1747 """
1748 _BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
1749 '..', '..', '..', '..'))
1750
1751 def Path(self, key, **kwargs):
1752 """Provide paths for tests using Web Page Replay."""
1753 chromium_path = self._paths[key].format(**kwargs)
1754 return os.path.join(self._BASE_DIR, *chromium_path.split('/'))
1755
1756 def _ArchivePath(self, test_name):
1757 archive_path = self.archive_path or self.Path('archive',
1758 test_name=test_name)
1759
slamm_google 2012/07/25 17:20:48 Remove extra blank line.
fdeng1 2012/07/25 22:53:28 Done.
1760 if self.is_record_mode:
1761 archive_dir = os.path.dirname(archive_path)
1762 assert os.path.exists(archive_dir), \
1763 'Archive directory does not exist: %s' % archive_dir
1764 else:
1765 assert os.path.exists(archive_path), \
1766 'Archive file path does not exist: %s' % archive_path
1767 return archive_path
1768
1769 def __init__(self):
slamm_google 2012/07/25 17:20:48 Move __init__ before Path().
fdeng1 2012/07/25 22:53:28 Done.
1770 # Initialize Web Page Replay related paths
dennis_jeffrey 2012/07/24 21:03:19 add period at end of sentence
slamm_google 2012/07/25 17:20:48 How about dropping the comment? And the others too
fdeng1 2012/07/25 22:53:28 Done.
1771 self._paths = {
1772 'archive': os.path.join(os.getcwd(), '{test_name}.wpr'),
1773 'replay': 'src/third_party/webpagereplay',
1774 'logs': 'src/webpagereplay_logs',
1775 }
1776
1777 # Initialize extra flags for chrome.
1778 self.chrome_flags = [
1779 ('--host-resolver-rules=MAP * %s,EXCLUDE localhost' %
1780 webpagereplay.REPLAY_HOST),
1781 '--testing-fixed-http-port=%s' % webpagereplay.HTTP_PORT,
1782 '--testing-fixed-https-port=%s' % webpagereplay.HTTPS_PORT,
1783 '--ignore-certificate-errors',
1784 ]
1785
1786 # Initialize Web Page Replay flags.
1787 self._replay_flags = ['--no-dns_forwarding']
1788
1789 self.archive_path = os.environ.get('WPR_ARCHIVE_PATH')
1790 self.replay_dir = os.environ.get('WPR_REPLAY_DIR', self.Path('replay'))
1791 self.is_record_mode = 'WPR_RECORD' in os.environ
1792 if self.is_record_mode:
1793 self._num_iterations = 1
slamm_google 2012/07/25 17:20:48 This is a bug from an earlier change. Need to find
fdeng1 2012/07/25 22:53:28 I moved it the setSep() functions in PageCyclerNet
1794
1795 def GetReplayServer(self, test_name):
1796 """Create a replay server.
1797
1798 Args:
1799 test_name: the name of the test which is starting the server.
1800
1801 Returns:
1802 A replay server.
1803 """
1804 replay_flags = self._replay_flags
1805 if self.is_record_mode:
1806 replay_flags += ['--record']
1807
1808 return webpagereplay.ReplayServer(
1809 self.replay_dir,
1810 self._ArchivePath(test_name),
1811 self.Path('logs'),
1812 replay_flags)
1813
1814
1815 class PerfWebPageReplay(BaseWebPageReplay):
1816 """Run page cycler and scroll tests with network simulation.
1817
1818 This class allows customized settings for page cycler and scroll tests.
1819 """
1820
1821 def __init__(self):
1822 # Call parent __init__
slamm_google 2012/07/25 17:20:48 The comments in this method do not add any value a
fdeng1 2012/07/25 22:53:28 Done.
1823 super(PerfWebPageReplay, self).__init__()
1824
1825 # Extra paths for Web Page Replay
1826 extra_paths = {
1827 'archive': 'src/data/page_cycler/webpagereplay/{test_name}.wpr',
1828 'page_sets': 'src/tools/page_cycler/webpagereplay/tests/{test_name}.js',
1829 'start_page': 'src/tools/page_cycler/webpagereplay/start.html',
1830 'extension': 'src/tools/page_cycler/webpagereplay/extension',
1831 }
1832 self._paths.update(extra_paths)
1833
1834 # Extra chrome flags
1835 extra_chrome_flags = [
1836 '--log-level=0',
1837 '--disable-background-networking',
1838 '--enable-experimental-extension-apis',
1839 ' --enable-logging',
slamm_google 2012/07/25 17:20:48 Remove the extra whitespace from the flag.
fdeng1 2012/07/25 22:53:28 Done.
1840 '--enable-stats-table',
1841 '--enable-benchmarking',
1842 '--metrics-recording-only',
1843 '--activate-on-launch',
1844 ]
1845 self.chrome_flags.extend(extra_chrome_flags)
1846
1847
1731 class PopularSitesScrollTest(BaseScrollTest): 1848 class PopularSitesScrollTest(BaseScrollTest):
1732 """Measures scrolling performance on recorded versions of popular sites.""" 1849 """Measures scrolling performance on recorded versions of popular sites."""
1733 1850
1851 _web_page_replay = PerfWebPageReplay()
1852
1734 def ExtraChromeFlags(self): 1853 def ExtraChromeFlags(self):
1735 """Ensures Chrome is launched with custom flags. 1854 """Ensures Chrome is launched with custom flags.
1736 1855
1737 Returns: 1856 Returns:
1738 A list of extra flags to pass to Chrome when it is launched. 1857 A list of extra flags to pass to Chrome when it is launched.
1739 """ 1858 """
1740 return super(PopularSitesScrollTest, 1859 return super(PopularSitesScrollTest,
1741 self).ExtraChromeFlags() + WebPageReplay.CHROME_FLAGS 1860 self).ExtraChromeFlags() + self._web_page_replay.chrome_flags
1742 1861
1743 def _GetUrlList(self, test_name): 1862 def _GetUrlList(self, test_name):
1744 """Returns list of recorded sites.""" 1863 """Returns list of recorded sites."""
1745 with open(WebPageReplay.Path('page_sets', test_name=test_name)) as f: 1864 with open(
1865 self._web_page_replay.Path('page_sets', test_name=test_name)) as f:
1746 sites_text = f.read() 1866 sites_text = f.read()
1747 js = """ 1867 js = """
1748 %s 1868 %s
1749 window.domAutomationController.send(JSON.stringify(pageSets)); 1869 window.domAutomationController.send(JSON.stringify(pageSets));
1750 """ % sites_text 1870 """ % sites_text
1751 page_sets = eval(self.ExecuteJavascript(js)) 1871 page_sets = eval(self.ExecuteJavascript(js))
1752 return list(itertools.chain(*page_sets))[1:] # Skip first. 1872 return list(itertools.chain(*page_sets))[1:] # Skip first.
1753 1873
1754 def _PrintScrollResults(self, results): 1874 def _PrintScrollResults(self, results):
1755 self._PrintSummaryResults( 1875 self._PrintSummaryResults(
(...skipping 11 matching lines...) Expand all
1767 [r.repeat_frame_times.GetPercentBelow60Fps() for r in results], 1887 [r.repeat_frame_times.GetPercentBelow60Fps() for r in results],
1768 'percent', 'PercentBelow60FPS') 1888 'percent', 'PercentBelow60FPS')
1769 self._PrintSummaryResults( 1889 self._PrintSummaryResults(
1770 'first_paint_time', [r.first_paint_time for r in results], 1890 'first_paint_time', [r.first_paint_time for r in results],
1771 'ms', 'FirstPaintTime') 1891 'ms', 'FirstPaintTime')
1772 1892
1773 def test2012Q3(self): 1893 def test2012Q3(self):
1774 test_name = '2012Q3' 1894 test_name = '2012Q3'
1775 urls = self._GetUrlList(test_name) 1895 urls = self._GetUrlList(test_name)
1776 results = [] 1896 results = []
1777 with WebPageReplay().GetReplayServer(test_name): 1897 with self._web_page_replay.GetReplayServer(test_name):
1778 for iteration in range(self._num_iterations): 1898 for iteration in range(self._num_iterations):
1779 for url in urls: 1899 for url in urls:
1780 result = self.RunSingleInvocation(url) 1900 result = self.RunSingleInvocation(url)
1781 fps = result.initial_frame_times.GetFps() 1901 fps = result.initial_frame_times.GetFps()
1782 assert fps, '%s did not scroll' % url 1902 assert fps, '%s did not scroll' % url
1783 logging.info('Iteration %d of %d: %f fps', iteration, 1903 logging.info('Iteration %d of %d: %f fps', iteration,
1784 self._num_iterations, fps) 1904 self._num_iterations, fps)
1785 results.append(result) 1905 results.append(result)
1786 self._PrintScrollResults(results) 1906 self._PrintScrollResults(results)
1787 1907
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 def testIntl2File(self): 2288 def testIntl2File(self):
2169 self.RunPageCyclerTest('intl2', 'Intl2File') 2289 self.RunPageCyclerTest('intl2', 'Intl2File')
2170 2290
2171 def testMozFile(self): 2291 def testMozFile(self):
2172 self.RunPageCyclerTest('moz', 'MozFile') 2292 self.RunPageCyclerTest('moz', 'MozFile')
2173 2293
2174 def testMoz2File(self): 2294 def testMoz2File(self):
2175 self.RunPageCyclerTest('moz2', 'Moz2File') 2295 self.RunPageCyclerTest('moz2', 'Moz2File')
2176 2296
2177 2297
2178 class WebPageReplay(object):
2179 """Run page cycler tests with network simulation via Web Page Replay.
2180
2181 Web Page Replay is a proxy that can record and "replay" web pages with
2182 simulated network characteristics -- without having to edit the pages
2183 by hand. With WPR, tests can use "real" web content, and catch
2184 performance issues that may result from introducing network delays and
2185 bandwidth throttling.
2186
2187 Environment Variables:
2188 WPR_RECORD: if set, puts Web Page Replay in record mode instead of replay.
2189 WPR_REPLAY_DIR: path to alternate Web Page Replay source (for development).
2190 WPR_ARCHIVE_PATH: path to alternate archive file (e.g. '/tmp/foo.wpr').
2191 """
2192 _PATHS = {
2193 'archive': 'src/data/page_cycler/webpagereplay/{test_name}.wpr',
2194 'page_sets': 'src/tools/page_cycler/webpagereplay/tests/{test_name}.js',
2195 'start_page': 'src/tools/page_cycler/webpagereplay/start.html',
2196 'extension': 'src/tools/page_cycler/webpagereplay/extension',
2197 'replay': 'src/third_party/webpagereplay',
2198 'logs': 'src/webpagereplay_logs',
2199 }
2200
2201 _BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
2202 '..', '..', '..', '..'))
2203 CHROME_FLAGS = [
2204 '--host-resolver-rules=MAP * %s' % webpagereplay.REPLAY_HOST,
2205 '--testing-fixed-http-port=%s' % webpagereplay.HTTP_PORT,
2206 '--testing-fixed-https-port=%s' % webpagereplay.HTTPS_PORT,
2207 '--log-level=0',
2208 '--disable-background-networking',
2209 '--enable-experimental-extension-apis',
2210 '--enable-logging',
2211 '--enable-stats-table',
2212 '--enable-benchmarking',
2213 '--ignore-certificate-errors',
2214 '--metrics-recording-only',
2215 '--activate-on-launch',
2216 '--no-first-run',
2217 '--no-proxy-server',
2218 ]
2219
2220 @classmethod
2221 def Path(cls, key, **kwargs):
2222 """Provide paths for tests using Web Page Replay."""
2223 chromium_path = cls._PATHS[key].format(**kwargs)
2224 return os.path.join(cls._BASE_DIR, *chromium_path.split('/'))
2225
2226 def _ArchivePath(self, test_name):
2227 archive_path = self.archive_path or self.Path('archive',
2228 test_name=test_name)
2229 if self.is_record_mode:
2230 archive_dir = os.path.dirname(archive_path)
2231 assert os.path.exists(archive_dir), \
2232 'Archive directory does not exist: %s' % archive_dir
2233 else:
2234 assert os.path.exists(archive_path), \
2235 'Archive file path does not exist: %s' % archive_path
2236 return archive_path
2237
2238 def __init__(self):
2239 self.archive_path = os.environ.get('WPR_ARCHIVE_PATH')
2240 self.replay_dir = os.environ.get('WPR_REPLAY_DIR', self.Path('replay'))
2241 self.is_record_mode = 'WPR_RECORD' in os.environ
2242 if self.is_record_mode:
2243 self._num_iterations = 1
2244
2245 def GetReplayServer(self, test_name):
2246 replay_options = []
2247 replay_options.append('--no-dns_forwarding')
2248 if self.is_record_mode:
2249 replay_options.append('--record')
2250 return webpagereplay.ReplayServer(
2251 self.replay_dir,
2252 self._ArchivePath(test_name),
2253 self.Path('logs'),
2254 replay_options)
2255
2256
2257 class PageCyclerNetSimTest(BasePageCyclerTest): 2298 class PageCyclerNetSimTest(BasePageCyclerTest):
2258 """Tests to run Web Page Replay backed page cycler tests.""" 2299 """Tests to run Web Page Replay backed page cycler tests."""
2259 MAX_ITERATION_SECONDS = 180 2300 MAX_ITERATION_SECONDS = 180
2301 _web_page_replay = PerfWebPageReplay()
2260 2302
2261 def ExtraChromeFlags(self): 2303 def ExtraChromeFlags(self):
2262 """Ensures Chrome is launched with custom flags. 2304 """Ensures Chrome is launched with custom flags.
2263 2305
2264 Returns: 2306 Returns:
2265 A list of extra flags to pass to Chrome when it is launched. 2307 A list of extra flags to pass to Chrome when it is launched.
2266 """ 2308 """
2267 flags = super(PageCyclerNetSimTest, self).ExtraChromeFlags() 2309 flags = super(PageCyclerNetSimTest, self).ExtraChromeFlags()
2268 flags.append('--load-extension=%s' % WebPageReplay.Path('extension')) 2310 flags.append('--load-extension=%s' %
2269 flags.extend(WebPageReplay.CHROME_FLAGS) 2311 self._web_page_replay.Path('extension'))
2312 flags.extend(self._web_page_replay.chrome_flags)
2270 return flags 2313 return flags
2271 2314
2272 def StartUrl(self, test_name, iterations): 2315 def StartUrl(self, test_name, iterations):
2273 start_url = 'file://%s?test=%s&iterations=%d' % ( 2316 start_url = 'file://%s?test=%s&iterations=%d' % (
2274 WebPageReplay.Path('start_page'), test_name, iterations) 2317 self._web_page_replay.Path('start_page'), test_name, iterations)
2275 if self.use_auto: 2318 if self.use_auto:
2276 start_url += '&auto=1' 2319 start_url += '&auto=1'
2277 return start_url 2320 return start_url
2278 2321
2279 def RunPageCyclerTest(self, test_name, description): 2322 def RunPageCyclerTest(self, test_name, description):
2280 """Runs the specified PageCycler test. 2323 """Runs the specified PageCycler test.
2281 2324
2282 Args: 2325 Args:
2283 test_name: name for archive (.wpr) and config (.js) files. 2326 test_name: name for archive (.wpr) and config (.js) files.
2284 description: a string description for the test 2327 description: a string description for the test
2285 """ 2328 """
2286 with WebPageReplay().GetReplayServer(test_name): 2329 with self._web_page_replay.GetReplayServer(test_name):
2287 super_self = super(PageCyclerNetSimTest, self) 2330 super_self = super(PageCyclerNetSimTest, self)
2288 super_self.RunPageCyclerTest(test_name, description) 2331 super_self.RunPageCyclerTest(test_name, description)
2289 2332
2290 def test2012Q2(self): 2333 def test2012Q2(self):
2291 self.RunPageCyclerTest('2012Q2', '2012Q2') 2334 self.RunPageCyclerTest('2012Q2', '2012Q2')
2292 2335
2293 2336
2294 class MemoryTest(BasePerfTest): 2337 class MemoryTest(BasePerfTest):
2295 """Tests to measure memory consumption under different usage scenarios.""" 2338 """Tests to measure memory consumption under different usage scenarios."""
2296 2339
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 """Identifies the port number to which the server is currently bound. 2667 """Identifies the port number to which the server is currently bound.
2625 2668
2626 Returns: 2669 Returns:
2627 The numeric port number to which the server is currently bound. 2670 The numeric port number to which the server is currently bound.
2628 """ 2671 """
2629 return self._server.server_address[1] 2672 return self._server.server_address[1]
2630 2673
2631 2674
2632 if __name__ == '__main__': 2675 if __name__ == '__main__':
2633 pyauto_functional.Main() 2676 pyauto_functional.Main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698