| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 self.GetBrowserWindow(0).GetTab(1).Close(True) | 192 self.GetBrowserWindow(0).GetTab(1).Close(True) |
| 193 | 193 |
| 194 self._PrintSummaryResults(description, timings, 'milliseconds') | 194 self._PrintSummaryResults(description, timings, 'milliseconds') |
| 195 | 195 |
| 196 def _LoginToGoogleAccount(self): | 196 def _LoginToGoogleAccount(self): |
| 197 """Logs in to a testing Google account.""" | 197 """Logs in to a testing Google account.""" |
| 198 creds = self.GetPrivateInfo()['test_google_account'] | 198 creds = self.GetPrivateInfo()['test_google_account'] |
| 199 test_utils.GoogleAccountsLogin(self, creds['username'], creds['password']) | 199 test_utils.GoogleAccountsLogin(self, creds['username'], creds['password']) |
| 200 self.NavigateToURL('about:blank') # Clear the existing tab. | 200 self.NavigateToURL('about:blank') # Clear the existing tab. |
| 201 | 201 |
| 202 def _GetCPUUsage(self): |
| 203 """Returns machine's CPU usage. |
| 204 |
| 205 This function uses /proc/stat to identify CPU usage, and therefore works |
| 206 only on Linux/ChromeOS. |
| 207 |
| 208 Returns: |
| 209 A dictionary with 'user', 'nice', 'system' and 'idle' values. |
| 210 Sample dictionary: |
| 211 { |
| 212 'user': 254544, |
| 213 'nice': 9, |
| 214 'system': 254768, |
| 215 'idle': 2859878, |
| 216 } |
| 217 """ |
| 218 try: |
| 219 f = open('/proc/stat', 'r') |
| 220 cpu_usage_str = f.readline().split() |
| 221 f.close() |
| 222 except IOError, e: |
| 223 self.fail('Could not retrieve CPU usage: ' + str(e)) |
| 224 return { |
| 225 'user': int(cpu_usage_str[1]), |
| 226 'nice': int(cpu_usage_str[2]), |
| 227 'system': int(cpu_usage_str[3]), |
| 228 'idle': int(cpu_usage_str[4]) |
| 229 } |
| 230 |
| 231 def _GetFractionNonIdleCPUTime(self, cpu_usage_start, cpu_usage_end): |
| 232 """Computes the fraction of CPU time spent non-idling. |
| 233 |
| 234 This function should be invoked using before/after values from calls to |
| 235 _GetCPUUsage(). |
| 236 """ |
| 237 time_non_idling_end = (cpu_usage_end['user'] + cpu_usage_end['nice'] + |
| 238 cpu_usage_end['system']) |
| 239 time_non_idling_start = (cpu_usage_start['user'] + cpu_usage_start['nice'] + |
| 240 cpu_usage_start['system']) |
| 241 total_time_end = (cpu_usage_end['user'] + cpu_usage_end['nice'] + |
| 242 cpu_usage_end['system'] + cpu_usage_end['idle']) |
| 243 total_time_start = (cpu_usage_start['user'] + cpu_usage_start['nice'] + |
| 244 cpu_usage_start['system'] + cpu_usage_start['idle']) |
| 245 return ((float(time_non_idling_end) - time_non_idling_start) / |
| 246 (total_time_end - total_time_start)) |
| 247 |
| 202 | 248 |
| 203 class TabPerfTest(BasePerfTest): | 249 class TabPerfTest(BasePerfTest): |
| 204 """Tests that involve opening tabs.""" | 250 """Tests that involve opening tabs.""" |
| 205 | 251 |
| 206 def testNewTab(self): | 252 def testNewTab(self): |
| 207 """Measures time to open a new tab.""" | 253 """Measures time to open a new tab.""" |
| 208 self._RunNewTabTest('NewTabPage', | 254 self._RunNewTabTest('NewTabPage', |
| 209 lambda: self._AppendTab('chrome://newtab')) | 255 lambda: self._AppendTab('chrome://newtab')) |
| 210 | 256 |
| 211 def testNewTabPdf(self): | 257 def testNewTabPdf(self): |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 self._RunNewTabTest('NewTabDocs', _RunSingleDocsTabOpen) | 537 self._RunNewTabTest('NewTabDocs', _RunSingleDocsTabOpen) |
| 492 | 538 |
| 493 | 539 |
| 494 class YoutubePerfTest(BasePerfTest, YoutubeTestHelper): | 540 class YoutubePerfTest(BasePerfTest, YoutubeTestHelper): |
| 495 """Test Youtube video performance.""" | 541 """Test Youtube video performance.""" |
| 496 | 542 |
| 497 def __init__(self, methodName='runTest', **kwargs): | 543 def __init__(self, methodName='runTest', **kwargs): |
| 498 pyauto.PyUITest.__init__(self, methodName, **kwargs) | 544 pyauto.PyUITest.__init__(self, methodName, **kwargs) |
| 499 YoutubeTestHelper.__init__(self, self) | 545 YoutubeTestHelper.__init__(self, self) |
| 500 | 546 |
| 501 def GetCPUUsage(self): | 547 def _VerifyVideoTotalBytes(self): |
| 502 """Returns machine's CPU usage | 548 """Returns true if video total bytes information is available.""" |
| 503 | |
| 504 It uses /proc/stat to count CPU usage. | |
| 505 Returns: | |
| 506 A dictionary with user, nice, system and idle values. | |
| 507 Sample dictionary : | |
| 508 { | |
| 509 'user': 254544, | |
| 510 'nice': 9, | |
| 511 'system': 254768, | |
| 512 'idle': 2859878, | |
| 513 } | |
| 514 """ | |
| 515 cpu = open('/proc/stat').readline().split() | |
| 516 return { | |
| 517 'user': int(cpu[1]), | |
| 518 'nice': int(cpu[2]), | |
| 519 'system': int(cpu[3]), | |
| 520 'idle': int(cpu[4]) | |
| 521 } | |
| 522 | |
| 523 def VerifyVideoTotalBytes(self): | |
| 524 """Returns true if video total bytes information is available""" | |
| 525 return self.GetVideoTotalBytes() > 0 | 549 return self.GetVideoTotalBytes() > 0 |
| 526 | 550 |
| 527 def VerifyVideoLoadedBytes(self): | 551 def _VerifyVideoLoadedBytes(self): |
| 528 """Returns true if video loaded bytes information is available""" | 552 """Returns true if video loaded bytes information is available.""" |
| 529 return self.GetVideoLoadedBytes() > 0 | 553 return self.GetVideoLoadedBytes() > 0 |
| 530 | 554 |
| 531 def StartVideoForPerformance(self): | 555 def StartVideoForPerformance(self): |
| 532 """Start the test video with all required buffering""" | 556 """Start the test video with all required buffering.""" |
| 533 self.PlayVideoAndAssert() | 557 self.PlayVideoAndAssert() |
| 534 self.ExecuteJavascript(""" | 558 self.ExecuteJavascript(""" |
| 535 ytplayer.setPlaybackQuality('hd720'); | 559 ytplayer.setPlaybackQuality('hd720'); |
| 536 window.domAutomationController.send(''); | 560 window.domAutomationController.send(''); |
| 537 """) | 561 """) |
| 538 self.AssertPlayingState() | 562 self.AssertPlayingState() |
| 539 self.assertTrue( | 563 self.assertTrue( |
| 540 self.WaitUntil(self.VerifyVideoTotalBytes, expect_retval=True), | 564 self.WaitUntil(self._VerifyVideoTotalBytes, expect_retval=True), |
| 541 msg='Failed to get video total bytes information.') | 565 msg='Failed to get video total bytes information.') |
| 542 self.assertTrue( | 566 self.assertTrue( |
| 543 self.WaitUntil(self.VerifyVideoLoadedBytes, expect_retval=True), | 567 self.WaitUntil(self._VerifyVideoLoadedBytes, expect_retval=True), |
| 544 msg='Failed to get video loaded bytes information') | 568 msg='Failed to get video loaded bytes information') |
| 545 loaded_video_bytes = self.GetVideoLoadedBytes() | 569 loaded_video_bytes = self.GetVideoLoadedBytes() |
| 546 total_video_bytes = self.GetVideoTotalBytes() | 570 total_video_bytes = self.GetVideoTotalBytes() |
| 547 self.PauseVideo() | 571 self.PauseVideo() |
| 548 count = 0 | 572 # Wait for the video to finish loading. |
| 549 while total_video_bytes > loaded_video_bytes: | 573 while total_video_bytes > loaded_video_bytes: |
| 550 loaded_video_bytes = self.GetVideoLoadedBytes() | 574 loaded_video_bytes = self.GetVideoLoadedBytes() |
| 551 time.sleep(1) | 575 time.sleep(1) |
| 552 count = count + 1 | |
| 553 self.PlayVideo() | 576 self.PlayVideo() |
| 554 # Ignoring first 10 seconds of video playing so we get smooth | 577 # Ignore first 10 seconds of video playing so we get smooth videoplayback. |
| 555 # videoplayback. | |
| 556 time.sleep(10) | 578 time.sleep(10) |
| 557 | 579 |
| 558 def testYoutubeDroppedFrames(self): | 580 def testYoutubeDroppedFrames(self): |
| 559 """Measures the Youtube video dropped frames. Runs for 60 secs.""" | 581 """Measures the Youtube video dropped frames. Runs for 60 secs.""" |
| 560 self.StartVideoForPerformance() | 582 self.StartVideoForPerformance() |
| 561 init_dropped_frames = self.GetVideoDroppedFrames() | 583 init_dropped_frames = self.GetVideoDroppedFrames() |
| 562 total_dropped_frames = 0 | 584 total_dropped_frames = 0 |
| 563 dropped_fps = [] | 585 dropped_fps = [] |
| 564 for _ in xrange(60): | 586 for _ in xrange(60): |
| 565 frames = self.GetVideoDroppedFrames() - init_dropped_frames | 587 frames = self.GetVideoDroppedFrames() - init_dropped_frames |
| 566 current_dropped_frames = frames - total_dropped_frames | 588 current_dropped_frames = frames - total_dropped_frames |
| 567 dropped_fps.append(current_dropped_frames) | 589 dropped_fps.append(current_dropped_frames) |
| 568 total_dropped_frames = frames | 590 total_dropped_frames = frames |
| 569 # Play the video for some time | 591 # Play the video for some time |
| 570 time.sleep(1) | 592 time.sleep(1) |
| 571 self._PrintSummaryResults('YoutubeDroppedFrames', dropped_fps, 'frames') | 593 self._PrintSummaryResults('YoutubeDroppedFrames', dropped_fps, 'frames') |
| 572 | 594 |
| 573 def testYoutubeCPU(self): | 595 def testYoutubeCPU(self): |
| 574 """Measure the Youtube video CPU usage. Runs for 60 seconds. | 596 """Measures the Youtube video CPU usage. Runs for 60 seconds. |
| 575 | 597 |
| 576 Measures the Youtube video CPU usage (between 0 and 1) extrapolated to | 598 Measures the Youtube video CPU usage (between 0 and 1), extrapolated to |
| 577 totalframes in the video by taking dropped frames into account. For smooth | 599 totalframes in the video by taking dropped frames into account. For smooth |
| 578 videoplayback this number should be < 0.5..1.0 on a hyperthreaded CPU. | 600 videoplayback this number should be < 0.5..1.0 on a hyperthreaded CPU. |
| 579 """ | 601 """ |
| 580 self.StartVideoForPerformance() | 602 self.StartVideoForPerformance() |
| 581 init_dropped_frames = self.GetVideoDroppedFrames() | 603 init_dropped_frames = self.GetVideoDroppedFrames() |
| 582 cpu_usage1 = self.GetCPUUsage() | 604 cpu_usage_start = self._GetCPUUsage() |
| 583 total_shown_frames = 0 | 605 total_shown_frames = 0 |
| 584 for _ in xrange(60): | 606 for sec_num in xrange(60): |
| 585 total_shown_frames = total_shown_frames + self.GetVideoFrames() | 607 # Play the video for some time. |
| 586 # Play the video for some time | |
| 587 time.sleep(1) | 608 time.sleep(1) |
| 609 total_shown_frames = total_shown_frames + self.GetVideoFrames() |
| 588 total_dropped_frames = self.GetVideoDroppedFrames() - init_dropped_frames | 610 total_dropped_frames = self.GetVideoDroppedFrames() - init_dropped_frames |
| 589 cpu_usage2 = self.GetCPUUsage() | 611 cpu_usage_end = self._GetCPUUsage() |
| 590 | 612 |
| 591 x2 = cpu_usage2['user'] + cpu_usage2['nice'] + cpu_usage2['system'] | 613 fraction_non_idle_time = self._GetFractionNonIdleCPUTime( |
| 592 x1 = cpu_usage1['user'] + cpu_usage1['nice'] + cpu_usage1['system'] | 614 cpu_usage_start, cpu_usage_end) |
| 593 y2 = cpu_usage2['user'] + cpu_usage2['nice'] + \ | |
| 594 cpu_usage2['system'] + cpu_usage2['idle'] | |
| 595 y1 = cpu_usage1['user'] + cpu_usage1['nice'] + \ | |
| 596 cpu_usage1['system'] + cpu_usage1['idle'] | |
| 597 total_frames = total_shown_frames + total_dropped_frames | 615 total_frames = total_shown_frames + total_dropped_frames |
| 598 # Counting extrapolation for utilization to play the video | 616 # Counting extrapolation for utilization to play the video. |
| 599 self._PrintSummaryResults('YoutubeCPUExtrapolation', | 617 extrapolation_value = (fraction_non_idle_time * |
| 600 [((float(x2) - x1) / (y2 - y1)) * total_frames/total_shown_frames], | 618 (total_frames / total_shown_frames)) |
| 601 'extrapolation') | 619 logging.info('Youtube CPU extrapolation: %.2f' % extrapolation_value) |
| 620 self._OutputPerfGraphValue('extrapolation_YoutubeCPUExtrapolation', |
| 621 extrapolation_value) |
| 602 | 622 |
| 603 | 623 |
| 604 class WebGLTest(BasePerfTest): | 624 class WebGLTest(BasePerfTest): |
| 605 """Tests for WebGL performance.""" | 625 """Tests for WebGL performance.""" |
| 606 | 626 |
| 607 def _RunWebGLTest(self, url, description): | 627 def _RunWebGLTest(self, url, description): |
| 608 """Measures FPS using a specified WebGL demo. | 628 """Measures FPS using a specified WebGL demo. |
| 609 | 629 |
| 610 Args: | 630 Args: |
| 611 url: The string URL that, once loaded, will run the WebGL demo (default | 631 url: The string URL that, once loaded, will run the WebGL demo (default |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 """Identifies the port number to which the server is currently bound. | 1337 """Identifies the port number to which the server is currently bound. |
| 1318 | 1338 |
| 1319 Returns: | 1339 Returns: |
| 1320 The numeric port number to which the server is currently bound. | 1340 The numeric port number to which the server is currently bound. |
| 1321 """ | 1341 """ |
| 1322 return self._server.server_address[1] | 1342 return self._server.server_address[1] |
| 1323 | 1343 |
| 1324 | 1344 |
| 1325 if __name__ == '__main__': | 1345 if __name__ == '__main__': |
| 1326 pyauto_functional.Main() | 1346 pyauto_functional.Main() |
| OLD | NEW |