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

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: Env var to control usage of WPR 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 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after
1719 # Ignore the first iteration. 1719 # Ignore the first iteration.
1720 if iteration: 1720 if iteration:
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
fdeng1 2012/07/24 00:05:50 I restructured the old WebPageReplay to allow diff
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 a tests with
dennis_jeffrey 2012/07/24 00:39:35 'a tests' --> 'tests'
fdeng1 2012/07/24 04:30:05 Done.
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
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):
1770 # Initialize Web Page Replay related Paths
dennis_jeffrey 2012/07/24 00:39:35 'Paths' --> 'paths.'
fdeng1 2012/07/24 04:30:05 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.
dennis_jeffrey 2012/07/24 00:39:35 add a space after #
fdeng1 2012/07/24 04:30:05 Done.
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
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 Returns:
dennis_jeffrey 2012/07/24 00:39:35 Add a blank line above this line
fdeng1 2012/07/24 04:30:05 Done.
1801 a replay server.
dennis_jeffrey 2012/07/24 00:39:35 capitalize the first letter in the sentence: 'a' -
fdeng1 2012/07/24 04:30:05 Done.
1802 """
1803 replay_flags = self._replay_flags
1804 if self.is_record_mode:
1805 replay_flags += ['--record']
1806
1807 return webpagereplay.ReplayServer(
1808 self.replay_dir,
1809 self._ArchivePath(test_name),
1810 self.Path('logs'),
1811 replay_flags)
1812
1813
1814 class PerfWebPageReplay(BaseWebPageReplay):
1815 """Run page cycler and scroll tests with network simulation.
1816
1817 This class allows customized settings for page cycler and scroll tests.
1818 """
1819
1820 def __init__(self):
1821 # Call parent __init__
1822 super(PerfWebPageReplay, self).__init__()
1823
1824 # Extra paths for Web Page Replay
1825 extra_paths = {
1826 'archive': 'src/data/page_cycler/webpagereplay/{test_name}.wpr',
1827 'page_sets': 'src/tools/page_cycler/webpagereplay/tests/{test_name}.js',
1828 'start_page': 'src/tools/page_cycler/webpagereplay/start.html',
1829 'extension': 'src/tools/page_cycler/webpagereplay/extension',
1830 }
1831 self._paths.update(extra_paths)
1832
1833 # Extra chrome flags
1834 extra_chrome_flags = [
1835 '--log-level=0',
1836 '--disable-background-networking',
1837 '--enable-experimental-extension-apis',
1838 ' --enable-logging',
1839 '--enable-stats-table',
1840 '--enable-benchmarking',
1841 '--metrics-recording-only',
1842 '--activate-on-launch',
fdeng1 2012/07/24 00:05:50 This is the original settings from the old WebPage
1843 ]
1844 self.chrome_flags.extend(extra_chrome_flags)
1845
1846
1731 class PopularSitesScrollTest(BaseScrollTest): 1847 class PopularSitesScrollTest(BaseScrollTest):
1732 """Measures scrolling performance on recorded versions of popular sites.""" 1848 """Measures scrolling performance on recorded versions of popular sites."""
1733 1849
1850 web_page_replay = PerfWebPageReplay()
fdeng1 2012/07/24 00:05:50 Is it a good idea to use a class field to store th
dennis_jeffrey 2012/07/24 00:39:35 I think this is ok. We could prefix the variable
fdeng1 2012/07/24 04:30:05 Done.
1851
1734 def ExtraChromeFlags(self): 1852 def ExtraChromeFlags(self):
1735 """Ensures Chrome is launched with custom flags. 1853 """Ensures Chrome is launched with custom flags.
1736 1854
1737 Returns: 1855 Returns:
1738 A list of extra flags to pass to Chrome when it is launched. 1856 A list of extra flags to pass to Chrome when it is launched.
1739 """ 1857 """
1740 return super(PopularSitesScrollTest, 1858 return super(PopularSitesScrollTest,
1741 self).ExtraChromeFlags() + WebPageReplay.CHROME_FLAGS 1859 self).ExtraChromeFlags() + self.web_page_replay.chrome_flags
1742 1860
1743 def _GetUrlList(self, test_name): 1861 def _GetUrlList(self, test_name):
1744 """Returns list of recorded sites.""" 1862 """Returns list of recorded sites."""
1745 with open(WebPageReplay.Path('page_sets', test_name=test_name)) as f: 1863 with open(
1864 self.web_page_replay.Path('page_sets', test_name=test_name)) as f:
1746 sites_text = f.read() 1865 sites_text = f.read()
1747 js = """ 1866 js = """
1748 %s 1867 %s
1749 window.domAutomationController.send(JSON.stringify(pageSets)); 1868 window.domAutomationController.send(JSON.stringify(pageSets));
1750 """ % sites_text 1869 """ % sites_text
1751 page_sets = eval(self.ExecuteJavascript(js)) 1870 page_sets = eval(self.ExecuteJavascript(js))
1752 return list(itertools.chain(*page_sets))[1:] # Skip first. 1871 return list(itertools.chain(*page_sets))[1:] # Skip first.
1753 1872
1754 def _PrintScrollResults(self, results): 1873 def _PrintScrollResults(self, results):
1755 self._PrintSummaryResults( 1874 self._PrintSummaryResults(
(...skipping 11 matching lines...) Expand all
1767 [r.repeat_frame_times.GetPercentBelow60Fps() for r in results], 1886 [r.repeat_frame_times.GetPercentBelow60Fps() for r in results],
1768 'percent', 'PercentBelow60FPS') 1887 'percent', 'PercentBelow60FPS')
1769 self._PrintSummaryResults( 1888 self._PrintSummaryResults(
1770 'first_paint_time', [r.first_paint_time for r in results], 1889 'first_paint_time', [r.first_paint_time for r in results],
1771 'ms', 'FirstPaintTime') 1890 'ms', 'FirstPaintTime')
1772 1891
1773 def test2012Q3(self): 1892 def test2012Q3(self):
1774 test_name = '2012Q3' 1893 test_name = '2012Q3'
1775 urls = self._GetUrlList(test_name) 1894 urls = self._GetUrlList(test_name)
1776 results = [] 1895 results = []
1777 with WebPageReplay().GetReplayServer(test_name): 1896 with self.web_page_replay.GetReplayServer(test_name):
1778 for iteration in range(self._num_iterations): 1897 for iteration in range(self._num_iterations):
1779 for url in urls: 1898 for url in urls:
1780 result = self.RunSingleInvocation(url) 1899 result = self.RunSingleInvocation(url)
1781 fps = result.initial_frame_times.GetFps() 1900 fps = result.initial_frame_times.GetFps()
1782 assert fps, '%s did not scroll' % url 1901 assert fps, '%s did not scroll' % url
1783 logging.info('Iteration %d of %d: %f fps', iteration, 1902 logging.info('Iteration %d of %d: %f fps', iteration,
1784 self._num_iterations, fps) 1903 self._num_iterations, fps)
1785 results.append(result) 1904 results.append(result)
1786 self._PrintScrollResults(results) 1905 self._PrintScrollResults(results)
1787 1906
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 def testIntl2File(self): 2287 def testIntl2File(self):
2169 self.RunPageCyclerTest('intl2', 'Intl2File') 2288 self.RunPageCyclerTest('intl2', 'Intl2File')
2170 2289
2171 def testMozFile(self): 2290 def testMozFile(self):
2172 self.RunPageCyclerTest('moz', 'MozFile') 2291 self.RunPageCyclerTest('moz', 'MozFile')
2173 2292
2174 def testMoz2File(self): 2293 def testMoz2File(self):
2175 self.RunPageCyclerTest('moz2', 'Moz2File') 2294 self.RunPageCyclerTest('moz2', 'Moz2File')
2176 2295
2177 2296
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): 2297 class PageCyclerNetSimTest(BasePageCyclerTest):
2258 """Tests to run Web Page Replay backed page cycler tests.""" 2298 """Tests to run Web Page Replay backed page cycler tests."""
2259 MAX_ITERATION_SECONDS = 180 2299 MAX_ITERATION_SECONDS = 180
2300 web_page_replay = PerfWebPageReplay()
2260 2301
2261 def ExtraChromeFlags(self): 2302 def ExtraChromeFlags(self):
2262 """Ensures Chrome is launched with custom flags. 2303 """Ensures Chrome is launched with custom flags.
2263 2304
2264 Returns: 2305 Returns:
2265 A list of extra flags to pass to Chrome when it is launched. 2306 A list of extra flags to pass to Chrome when it is launched.
2266 """ 2307 """
2267 flags = super(PageCyclerNetSimTest, self).ExtraChromeFlags() 2308 flags = super(PageCyclerNetSimTest, self).ExtraChromeFlags()
2268 flags.append('--load-extension=%s' % WebPageReplay.Path('extension')) 2309 flags.append('--load-extension=%s' % self.web_page_replay.Path('extension'))
2269 flags.extend(WebPageReplay.CHROME_FLAGS) 2310 flags.extend(self.web_page_replay.chrome_flags)
2270 return flags 2311 return flags
2271 2312
2272 def StartUrl(self, test_name, iterations): 2313 def StartUrl(self, test_name, iterations):
2273 start_url = 'file://%s?test=%s&iterations=%d' % ( 2314 start_url = 'file://%s?test=%s&iterations=%d' % (
2274 WebPageReplay.Path('start_page'), test_name, iterations) 2315 self.web_page_replay.Path('start_page'), test_name, iterations)
2275 if self.use_auto: 2316 if self.use_auto:
2276 start_url += '&auto=1' 2317 start_url += '&auto=1'
2277 return start_url 2318 return start_url
2278 2319
2279 def RunPageCyclerTest(self, test_name, description): 2320 def RunPageCyclerTest(self, test_name, description):
2280 """Runs the specified PageCycler test. 2321 """Runs the specified PageCycler test.
2281 2322
2282 Args: 2323 Args:
2283 test_name: name for archive (.wpr) and config (.js) files. 2324 test_name: name for archive (.wpr) and config (.js) files.
2284 description: a string description for the test 2325 description: a string description for the test
2285 """ 2326 """
2286 with WebPageReplay().GetReplayServer(test_name): 2327 with self.web_page_replay.GetReplayServer(test_name):
2287 super_self = super(PageCyclerNetSimTest, self) 2328 super_self = super(PageCyclerNetSimTest, self)
2288 super_self.RunPageCyclerTest(test_name, description) 2329 super_self.RunPageCyclerTest(test_name, description)
2289 2330
2290 def test2012Q2(self): 2331 def test2012Q2(self):
2291 self.RunPageCyclerTest('2012Q2', '2012Q2') 2332 self.RunPageCyclerTest('2012Q2', '2012Q2')
2292 2333
2293 2334
2294 class MemoryTest(BasePerfTest): 2335 class MemoryTest(BasePerfTest):
2295 """Tests to measure memory consumption under different usage scenarios.""" 2336 """Tests to measure memory consumption under different usage scenarios."""
2296 2337
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 """Identifies the port number to which the server is currently bound. 2665 """Identifies the port number to which the server is currently bound.
2625 2666
2626 Returns: 2667 Returns:
2627 The numeric port number to which the server is currently bound. 2668 The numeric port number to which the server is currently bound.
2628 """ 2669 """
2629 return self._server.server_address[1] 2670 return self._server.server_address[1]
2630 2671
2631 2672
2632 if __name__ == '__main__': 2673 if __name__ == '__main__':
2633 pyauto_functional.Main() 2674 pyauto_functional.Main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698