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 num_seconds = 60 |
585 total_shown_frames = total_shown_frames + self.GetVideoFrames() | 607 for sec_num in xrange(num_seconds): |
586 # Play the video for some time | 608 total_shown_frames = total_shown_frames + self.GetVideoFrames() |
587 time.sleep(1) | 609 if sec_num < num_seconds - 1: # Do not sleep on the last iteration. |
rohitbm
2011/11/18 00:24:53
Should we use xrange(num_seconds-1) above instead
dennis_jeffrey
2011/11/18 00:51:29
That's a good question. I actually do want the lo
| |
610 # Play the video for some time. | |
611 time.sleep(1) | |
588 total_dropped_frames = self.GetVideoDroppedFrames() - init_dropped_frames | 612 total_dropped_frames = self.GetVideoDroppedFrames() - init_dropped_frames |
589 cpu_usage2 = self.GetCPUUsage() | 613 cpu_usage_end = self._GetCPUUsage() |
590 | 614 |
591 x2 = cpu_usage2['user'] + cpu_usage2['nice'] + cpu_usage2['system'] | 615 fraction_non_idle_time = self._GetFractionNonIdleCPUTime( |
592 x1 = cpu_usage1['user'] + cpu_usage1['nice'] + cpu_usage1['system'] | 616 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 | 617 total_frames = total_shown_frames + total_dropped_frames |
598 # Counting extrapolation for utilization to play the video | 618 # Counting extrapolation for utilization to play the video. |
599 self._PrintSummaryResults('YoutubeCPUExtrapolation', | 619 extrapolation_value = (fraction_non_idle_time * |
600 [((float(x2) - x1) / (y2 - y1)) * total_frames/total_shown_frames], | 620 (total_frames / total_shown_frames)) |
601 'extrapolation') | 621 logging.info('Youtube CPU extrapolation: %.2f' % extrapolation_value) |
622 self._OutputPerfGraphValue('extrapolation_YoutubeCPUExtrapolation', | |
623 extrapolation_value) | |
602 | 624 |
603 | 625 |
604 class WebGLTest(BasePerfTest): | 626 class WebGLTest(BasePerfTest): |
605 """Tests for WebGL performance.""" | 627 """Tests for WebGL performance.""" |
606 | 628 |
607 def _RunWebGLTest(self, url, description): | 629 def _RunWebGLTest(self, url, description): |
608 """Measures FPS using a specified WebGL demo. | 630 """Measures FPS using a specified WebGL demo. |
609 | 631 |
610 Args: | 632 Args: |
611 url: The string URL that, once loaded, will run the WebGL demo (default | 633 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. | 1339 """Identifies the port number to which the server is currently bound. |
1318 | 1340 |
1319 Returns: | 1341 Returns: |
1320 The numeric port number to which the server is currently bound. | 1342 The numeric port number to which the server is currently bound. |
1321 """ | 1343 """ |
1322 return self._server.server_address[1] | 1344 return self._server.server_address[1] |
1323 | 1345 |
1324 | 1346 |
1325 if __name__ == '__main__': | 1347 if __name__ == '__main__': |
1326 pyauto_functional.Main() | 1348 pyauto_functional.Main() |
OLD | NEW |