OLD | NEW |
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 import pyauto | 48 import pyauto |
49 import simplejson # Must be imported after pyauto; located in third_party. | 49 import simplejson # Must be imported after pyauto; located in third_party. |
50 | 50 |
51 from netflix import NetflixTestHelper | 51 from netflix import NetflixTestHelper |
52 import pyauto_utils | 52 import pyauto_utils |
53 import test_utils | 53 import test_utils |
54 import webpagereplay | 54 import webpagereplay |
55 from youtube import YoutubeTestHelper | 55 from youtube import YoutubeTestHelper |
56 | 56 |
57 | 57 |
| 58 _CHROME_BASE_DIR = os.path.abspath(os.path.join( |
| 59 os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, os.pardir)) |
| 60 |
| 61 |
| 62 def FormatChromePath(posix_path, **kwargs): |
| 63 """Convert a path relative to the Chromium root into an OS-specific path. |
| 64 |
| 65 Args: |
| 66 posix_path: a path string that may be a format(). |
| 67 Example: 'src/third_party/{module_name}/__init__.py' |
| 68 kwargs: args for the format replacement. |
| 69 Example: {'module_name': 'pylib'} |
| 70 |
| 71 Returns: |
| 72 an absolute path in the current Chromium tree with formatting applied. |
| 73 """ |
| 74 formated_path = posix_path.format(**kwargs) |
| 75 path_parts = formated_path.split('/') |
| 76 return os.path.join(_CHROME_BASE_DIR, *path_parts) |
| 77 |
| 78 |
58 def StandardDeviation(values): | 79 def StandardDeviation(values): |
59 """Returns the standard deviation of |values|.""" | 80 """Returns the standard deviation of |values|.""" |
60 avg = Mean(values) | 81 avg = Mean(values) |
61 if len(values) < 2 or not avg: | 82 if len(values) < 2 or not avg: |
62 return 0.0 | 83 return 0.0 |
63 temp_vals = [math.pow(x - avg, 2) for x in values] | 84 temp_vals = [math.pow(x - avg, 2) for x in values] |
64 return math.sqrt(sum(temp_vals) / (len(temp_vals) - 1)) | 85 return math.sqrt(sum(temp_vals) / (len(temp_vals) - 1)) |
65 | 86 |
66 | 87 |
67 def Mean(values): | 88 def Mean(values): |
(...skipping 1663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1731 class PopularSitesScrollTest(BaseScrollTest): | 1752 class PopularSitesScrollTest(BaseScrollTest): |
1732 """Measures scrolling performance on recorded versions of popular sites.""" | 1753 """Measures scrolling performance on recorded versions of popular sites.""" |
1733 | 1754 |
1734 def ExtraChromeFlags(self): | 1755 def ExtraChromeFlags(self): |
1735 """Ensures Chrome is launched with custom flags. | 1756 """Ensures Chrome is launched with custom flags. |
1736 | 1757 |
1737 Returns: | 1758 Returns: |
1738 A list of extra flags to pass to Chrome when it is launched. | 1759 A list of extra flags to pass to Chrome when it is launched. |
1739 """ | 1760 """ |
1740 return super(PopularSitesScrollTest, | 1761 return super(PopularSitesScrollTest, |
1741 self).ExtraChromeFlags() + WebPageReplay.CHROME_FLAGS | 1762 self).ExtraChromeFlags() + PageCyclerReplay.CHROME_FLAGS |
1742 | 1763 |
1743 def _GetUrlList(self, test_name): | 1764 def _GetUrlList(self, test_name): |
1744 """Returns list of recorded sites.""" | 1765 """Returns list of recorded sites.""" |
1745 with open(WebPageReplay.Path('page_sets', test_name=test_name)) as f: | 1766 sites_path = PageCyclerReplay.Path('page_sets', test_name=test_name) |
| 1767 with open(sites_path) as f: |
1746 sites_text = f.read() | 1768 sites_text = f.read() |
1747 js = """ | 1769 js = """ |
1748 %s | 1770 %s |
1749 window.domAutomationController.send(JSON.stringify(pageSets)); | 1771 window.domAutomationController.send(JSON.stringify(pageSets)); |
1750 """ % sites_text | 1772 """ % sites_text |
1751 page_sets = eval(self.ExecuteJavascript(js)) | 1773 page_sets = eval(self.ExecuteJavascript(js)) |
1752 return list(itertools.chain(*page_sets))[1:] # Skip first. | 1774 return list(itertools.chain(*page_sets))[1:] # Skip first. |
1753 | 1775 |
1754 def _PrintScrollResults(self, results): | 1776 def _PrintScrollResults(self, results): |
1755 self._PrintSummaryResults( | 1777 self._PrintSummaryResults( |
(...skipping 11 matching lines...) Expand all Loading... |
1767 [r.repeat_frame_times.GetPercentBelow60Fps() for r in results], | 1789 [r.repeat_frame_times.GetPercentBelow60Fps() for r in results], |
1768 'percent', 'PercentBelow60FPS') | 1790 'percent', 'PercentBelow60FPS') |
1769 self._PrintSummaryResults( | 1791 self._PrintSummaryResults( |
1770 'first_paint_time', [r.first_paint_time for r in results], | 1792 'first_paint_time', [r.first_paint_time for r in results], |
1771 'ms', 'FirstPaintTime') | 1793 'ms', 'FirstPaintTime') |
1772 | 1794 |
1773 def test2012Q3(self): | 1795 def test2012Q3(self): |
1774 test_name = '2012Q3' | 1796 test_name = '2012Q3' |
1775 urls = self._GetUrlList(test_name) | 1797 urls = self._GetUrlList(test_name) |
1776 results = [] | 1798 results = [] |
1777 with WebPageReplay().GetReplayServer(test_name): | 1799 with PageCyclerReplay.ReplayServer(test_name) as replay_server: |
| 1800 if replay_server.is_record_mode: |
| 1801 self._num_iterations = 1 |
1778 for iteration in range(self._num_iterations): | 1802 for iteration in range(self._num_iterations): |
1779 for url in urls: | 1803 for url in urls: |
1780 result = self.RunSingleInvocation(url) | 1804 result = self.RunSingleInvocation(url) |
1781 fps = result.initial_frame_times.GetFps() | 1805 fps = result.initial_frame_times.GetFps() |
1782 assert fps, '%s did not scroll' % url | 1806 assert fps, '%s did not scroll' % url |
1783 logging.info('Iteration %d of %d: %f fps', iteration, | 1807 logging.info('Iteration %d of %d: %f fps', iteration, |
1784 self._num_iterations, fps) | 1808 self._num_iterations, fps) |
1785 results.append(result) | 1809 results.append(result) |
1786 self._PrintScrollResults(results) | 1810 self._PrintScrollResults(results) |
1787 | 1811 |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 def testIntl2File(self): | 2192 def testIntl2File(self): |
2169 self.RunPageCyclerTest('intl2', 'Intl2File') | 2193 self.RunPageCyclerTest('intl2', 'Intl2File') |
2170 | 2194 |
2171 def testMozFile(self): | 2195 def testMozFile(self): |
2172 self.RunPageCyclerTest('moz', 'MozFile') | 2196 self.RunPageCyclerTest('moz', 'MozFile') |
2173 | 2197 |
2174 def testMoz2File(self): | 2198 def testMoz2File(self): |
2175 self.RunPageCyclerTest('moz2', 'Moz2File') | 2199 self.RunPageCyclerTest('moz2', 'Moz2File') |
2176 | 2200 |
2177 | 2201 |
2178 class WebPageReplay(object): | 2202 class PageCyclerReplay(object): |
2179 """Run page cycler tests with network simulation via Web Page Replay. | 2203 """Run page cycler tests with network simulation via Web Page Replay. |
2180 | 2204 |
2181 Web Page Replay is a proxy that can record and "replay" web pages with | 2205 Web Page Replay is a proxy that can record and "replay" web pages with |
2182 simulated network characteristics -- without having to edit the pages | 2206 simulated network characteristics -- without having to edit the pages |
2183 by hand. With WPR, tests can use "real" web content, and catch | 2207 by hand. With WPR, tests can use "real" web content, and catch |
2184 performance issues that may result from introducing network delays and | 2208 performance issues that may result from introducing network delays and |
2185 bandwidth throttling. | 2209 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 """ | 2210 """ |
2192 _PATHS = { | 2211 _PATHS = { |
2193 'archive': 'src/data/page_cycler/webpagereplay/{test_name}.wpr', | 2212 'archive': 'src/data/page_cycler/webpagereplay/{test_name}.wpr', |
2194 'page_sets': 'src/tools/page_cycler/webpagereplay/tests/{test_name}.js', | 2213 'page_sets': 'src/tools/page_cycler/webpagereplay/tests/{test_name}.js', |
2195 'start_page': 'src/tools/page_cycler/webpagereplay/start.html', | 2214 'start_page': 'src/tools/page_cycler/webpagereplay/start.html', |
2196 'extension': 'src/tools/page_cycler/webpagereplay/extension', | 2215 'extension': 'src/tools/page_cycler/webpagereplay/extension', |
2197 'replay': 'src/third_party/webpagereplay', | |
2198 'logs': 'src/webpagereplay_logs', | |
2199 } | 2216 } |
2200 | 2217 |
2201 _BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), | 2218 CHROME_FLAGS = webpagereplay.CHROME_FLAGS + [ |
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', | 2219 '--log-level=0', |
2208 '--disable-background-networking', | 2220 '--disable-background-networking', |
2209 '--enable-experimental-extension-apis', | 2221 '--enable-experimental-extension-apis', |
2210 '--enable-logging', | 2222 '--enable-logging', |
2211 '--enable-stats-table', | 2223 '--enable-stats-table', |
2212 '--enable-benchmarking', | 2224 '--enable-benchmarking', |
2213 '--ignore-certificate-errors', | |
2214 '--metrics-recording-only', | 2225 '--metrics-recording-only', |
2215 '--activate-on-launch', | 2226 '--activate-on-launch', |
2216 '--no-first-run', | 2227 '--no-first-run', |
2217 '--no-proxy-server', | 2228 '--no-proxy-server', |
2218 ] | 2229 ] |
2219 | 2230 |
2220 @classmethod | 2231 @classmethod |
2221 def Path(cls, key, **kwargs): | 2232 def Path(cls, key, **kwargs): |
2222 """Provide paths for tests using Web Page Replay.""" | 2233 return FormatChromePath(cls._PATHS[key], **kwargs) |
2223 chromium_path = cls._PATHS[key].format(**kwargs) | |
2224 return os.path.join(cls._BASE_DIR, *chromium_path.split('/')) | |
2225 | 2234 |
2226 def _ArchivePath(self, test_name): | 2235 @classmethod |
2227 archive_path = self.archive_path or self.Path('archive', | 2236 def ReplayServer(cls, test_name): |
2228 test_name=test_name) | 2237 archive_path = cls.Path('archive', test_name=test_name) |
2229 if self.is_record_mode: | 2238 return webpagereplay.ReplayServer(archive_path) |
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 | 2239 |
2256 | 2240 |
2257 class PageCyclerNetSimTest(BasePageCyclerTest): | 2241 class PageCyclerNetSimTest(BasePageCyclerTest): |
2258 """Tests to run Web Page Replay backed page cycler tests.""" | 2242 """Tests to run Web Page Replay backed page cycler tests.""" |
2259 MAX_ITERATION_SECONDS = 180 | 2243 MAX_ITERATION_SECONDS = 180 |
2260 | 2244 |
2261 def ExtraChromeFlags(self): | 2245 def ExtraChromeFlags(self): |
2262 """Ensures Chrome is launched with custom flags. | 2246 """Ensures Chrome is launched with custom flags. |
2263 | 2247 |
2264 Returns: | 2248 Returns: |
2265 A list of extra flags to pass to Chrome when it is launched. | 2249 A list of extra flags to pass to Chrome when it is launched. |
2266 """ | 2250 """ |
2267 flags = super(PageCyclerNetSimTest, self).ExtraChromeFlags() | 2251 flags = super(PageCyclerNetSimTest, self).ExtraChromeFlags() |
2268 flags.append('--load-extension=%s' % WebPageReplay.Path('extension')) | 2252 flags.append('--load-extension=%s' % PageCyclerReplay.Path('extension')) |
2269 flags.extend(WebPageReplay.CHROME_FLAGS) | 2253 flags.extend(PageCyclerReplay.CHROME_FLAGS) |
2270 return flags | 2254 return flags |
2271 | 2255 |
2272 def StartUrl(self, test_name, iterations): | 2256 def StartUrl(self, test_name, iterations): |
| 2257 start_path = PageCyclerReplay.Path('start_page') |
2273 start_url = 'file://%s?test=%s&iterations=%d' % ( | 2258 start_url = 'file://%s?test=%s&iterations=%d' % ( |
2274 WebPageReplay.Path('start_page'), test_name, iterations) | 2259 start_path, test_name, iterations) |
2275 if self.use_auto: | 2260 if self.use_auto: |
2276 start_url += '&auto=1' | 2261 start_url += '&auto=1' |
2277 return start_url | 2262 return start_url |
2278 | 2263 |
2279 def RunPageCyclerTest(self, test_name, description): | 2264 def RunPageCyclerTest(self, test_name, description): |
2280 """Runs the specified PageCycler test. | 2265 """Runs the specified PageCycler test. |
2281 | 2266 |
2282 Args: | 2267 Args: |
2283 test_name: name for archive (.wpr) and config (.js) files. | 2268 test_name: name for archive (.wpr) and config (.js) files. |
2284 description: a string description for the test | 2269 description: a string description for the test |
2285 """ | 2270 """ |
2286 with WebPageReplay().GetReplayServer(test_name): | 2271 with PageCyclerReplay.ReplayServer(test_name) as replay_server: |
| 2272 if replay_server.is_record_mode: |
| 2273 self._num_iterations = 1 |
2287 super_self = super(PageCyclerNetSimTest, self) | 2274 super_self = super(PageCyclerNetSimTest, self) |
2288 super_self.RunPageCyclerTest(test_name, description) | 2275 super_self.RunPageCyclerTest(test_name, description) |
2289 | 2276 |
2290 def test2012Q2(self): | 2277 def test2012Q2(self): |
2291 self.RunPageCyclerTest('2012Q2', '2012Q2') | 2278 self.RunPageCyclerTest('2012Q2', '2012Q2') |
2292 | 2279 |
2293 | 2280 |
2294 class MemoryTest(BasePerfTest): | 2281 class MemoryTest(BasePerfTest): |
2295 """Tests to measure memory consumption under different usage scenarios.""" | 2282 """Tests to measure memory consumption under different usage scenarios.""" |
2296 | 2283 |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2624 """Identifies the port number to which the server is currently bound. | 2611 """Identifies the port number to which the server is currently bound. |
2625 | 2612 |
2626 Returns: | 2613 Returns: |
2627 The numeric port number to which the server is currently bound. | 2614 The numeric port number to which the server is currently bound. |
2628 """ | 2615 """ |
2629 return self._server.server_address[1] | 2616 return self._server.server_address[1] |
2630 | 2617 |
2631 | 2618 |
2632 if __name__ == '__main__': | 2619 if __name__ == '__main__': |
2633 pyauto_functional.Main() | 2620 pyauto_functional.Main() |
OLD | NEW |