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|. |
11 That value can optionally be tweaked by setting an environment variable | 11 That value can optionally be tweaked by setting an environment variable |
12 'NUM_ITERATIONS' to a positive integer, representing the number of iterations | 12 'NUM_ITERATIONS' to a positive integer, representing the number of iterations |
13 to run. | 13 to run. |
14 | 14 |
15 Some tests rely on repeatedly appending tabs to Chrome. Occasionally, these | 15 Some tests rely on repeatedly appending tabs to Chrome. Occasionally, these |
16 automation calls time out, thereby affecting the timing measurements (see issue | 16 automation calls time out, thereby affecting the timing measurements (see issue |
17 crosbug.com/20503). To work around this, the tests discard timing measurements | 17 crosbug.com/20503). To work around this, the tests discard timing measurements |
18 that involve automation timeouts. The value |_DEFAULT_MAX_TIMEOUT_COUNT| | 18 that involve automation timeouts. The value |_DEFAULT_MAX_TIMEOUT_COUNT| |
19 specifies the threshold number of timeouts that can be tolerated before the test | 19 specifies the threshold number of timeouts that can be tolerated before the test |
20 fails. To tweak this value, set environment variable 'MAX_TIMEOUT_COUNT' to the | 20 fails. To tweak this value, set environment variable 'MAX_TIMEOUT_COUNT' to the |
21 desired threshold value. | 21 desired threshold value. |
22 """ | 22 """ |
23 | 23 |
24 import BaseHTTPServer | 24 import BaseHTTPServer |
25 import commands | |
25 import logging | 26 import logging |
26 import math | 27 import math |
27 import os | 28 import os |
28 import posixpath | 29 import posixpath |
29 import re | 30 import re |
30 import SimpleHTTPServer | 31 import SimpleHTTPServer |
31 import SocketServer | 32 import SocketServer |
32 import tempfile | 33 import tempfile |
33 import threading | 34 import threading |
34 import time | 35 import time |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 self._RunNewTabTest('NewTabDocs', _RunSingleDocsTabOpen) | 491 self._RunNewTabTest('NewTabDocs', _RunSingleDocsTabOpen) |
491 | 492 |
492 | 493 |
493 class YoutubePerfTest(BasePerfTest, YoutubeTestHelper): | 494 class YoutubePerfTest(BasePerfTest, YoutubeTestHelper): |
494 """Test Youtube video performance.""" | 495 """Test Youtube video performance.""" |
495 | 496 |
496 def __init__(self, methodName='runTest', **kwargs): | 497 def __init__(self, methodName='runTest', **kwargs): |
497 pyauto.PyUITest.__init__(self, methodName, **kwargs) | 498 pyauto.PyUITest.__init__(self, methodName, **kwargs) |
498 YoutubeTestHelper.__init__(self, self) | 499 YoutubeTestHelper.__init__(self, self) |
499 | 500 |
500 def testYoutubeDroppedFrames(self): | 501 def GetCPUUsage(self): |
501 """Measures the Youtube video dropped frames. Runs for 60 secs.""" | 502 """Returns machine's CPU usage |
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 file = open('/proc/stat') | |
516 cpu = file.readline().split() | |
Nirnimesh
2011/11/15 08:11:29
merge with previous line. you don't need the |file
| |
517 return { | |
518 'user': int(cpu[1]), | |
519 'nice': int(cpu[2]), | |
520 'system': int(cpu[3]), | |
521 'idle': int(cpu[4]) | |
522 } | |
523 | |
524 def VerifyVideoTotalBytes(self): | |
525 """Returns true if video total bytes information is available""" | |
526 return self.GetVideoTotalBytes() > 0 | |
527 | |
528 def VerifyVideoLoadedBytes(self): | |
529 """Returns true if video loaded bytes information is available""" | |
530 return self.GetVideoLoadedBytes() > 0 | |
531 | |
532 def StartVideoForPerformance(self): | |
533 """Start the test video with all required buffering""" | |
502 self.PlayVideoAndAssert() | 534 self.PlayVideoAndAssert() |
503 self.ExecuteJavascript(""" | 535 self.ExecuteJavascript(""" |
504 ytplayer.setPlaybackQuality('hd720'); | 536 ytplayer.setPlaybackQuality('hd720'); |
505 window.domAutomationController.send(''); | 537 window.domAutomationController.send(''); |
506 """) | 538 """) |
539 self.AssertPlayingState() | |
540 self.assertTrue( | |
541 self.WaitUntil(self.VerifyVideoTotalBytes, expect_retval=True), | |
542 msg='Failed to get video total bytes information.') | |
543 self.assertTrue( | |
544 self.WaitUntil(self.VerifyVideoLoadedBytes, expect_retval=True), | |
545 msg='Failed to get video loaded bytes information') | |
546 loaded_video_bytes = self.GetVideoLoadedBytes() | |
547 total_video_bytes = self.GetVideoTotalBytes() | |
548 self.PauseVideo() | |
549 count = 0 | |
550 while total_video_bytes > loaded_video_bytes: | |
551 loaded_video_bytes = self.GetVideoLoadedBytes() | |
552 time.sleep(1) | |
553 count = count + 1 | |
554 self.PlayVideo() | |
555 # Ignoring first 10 seconds of video playing so we get smooth | |
556 # videoplayback. | |
557 time.sleep(10) | |
558 | |
559 def testYoutubeDroppedFrames(self): | |
560 """Measures the Youtube video dropped frames. Runs for 60 secs.""" | |
561 self.StartVideoForPerformance() | |
562 init_dropped_frames = self.GetVideoDroppedFrames() | |
507 total_dropped_frames = 0 | 563 total_dropped_frames = 0 |
508 dropped_fps = [] | 564 dropped_fps = [] |
509 youtube_apis = self.GetPrivateInfo()['youtube_api'] | |
510 youtube_debug_text = youtube_apis['GetDebugText'] | |
511 for _ in xrange(60): | 565 for _ in xrange(60): |
512 video_data = self.ExecuteJavascript( | 566 frames = self.GetVideoDroppedFrames() - init_dropped_frames |
513 'window.domAutomationController.send(%s);' % youtube_debug_text) | |
514 # Video data returns total dropped frames so far, so calculating | |
515 # the dropped frames for the last second. | |
516 matched = re.search('droppedFrames=([\d\.]+)', video_data) | |
517 if matched: | |
518 frames = int(matched.group(1)) | |
519 current_dropped_frames = frames - total_dropped_frames | 567 current_dropped_frames = frames - total_dropped_frames |
520 dropped_fps.append(current_dropped_frames) | 568 dropped_fps.append(current_dropped_frames) |
521 total_dropped_frames = frames | 569 total_dropped_frames = frames |
570 # Play the video for some time | |
522 time.sleep(1) | 571 time.sleep(1) |
523 self._PrintSummaryResults('YoutubeDroppedFrames', dropped_fps, 'frames') | 572 self._PrintSummaryResults('YoutubeDroppedFrames', dropped_fps, 'frames') |
524 | 573 |
574 def testYoutubeCPU(self): | |
575 """Measure the Youtube video CPU usage. Runs for 60 seconds. | |
576 | |
577 Measures the Youtube video CPU usage (between 0 and 1) extrapolated to | |
578 totalframes in the video by taking dropped frames into account. For smooth | |
579 videoplayback this number should be < 0.5..1.0 on a hyperthreaded CPU. | |
580 """ | |
581 self.StartVideoForPerformance() | |
582 init_dropped_frames = self.GetVideoDroppedFrames() | |
583 cpu_usage1 = self.GetCPUUsage() | |
584 total_shown_frames = 0 | |
585 for _ in xrange(60): | |
586 total_shown_frames = total_shown_frames + self.GetVideoFrames() | |
587 # Play the video for some time | |
588 time.sleep(1) | |
589 total_dropped_frames = self.GetVideoDroppedFrames() - init_dropped_frames | |
590 cpu_usage2 = self.GetCPUUsage() | |
591 | |
592 x2 = cpu_usage2['user'] + cpu_usage2['nice'] + cpu_usage2['system'] | |
593 x1 = cpu_usage1['user'] + cpu_usage1['nice'] + cpu_usage1['system'] | |
594 y2 = cpu_usage2['user'] + cpu_usage2['nice'] + \ | |
595 cpu_usage2['system'] + cpu_usage2['idle'] | |
596 y1 = cpu_usage1['user'] + cpu_usage1['nice'] + \ | |
597 cpu_usage1['system'] + cpu_usage1['idle'] | |
598 total_frames = total_shown_frames + total_dropped_frames | |
599 # Counting extrapolation for utilization to play the video | |
600 self._PrintSummaryResults('YoutubeCPUExtrapolation', | |
601 [((float(x2) - x1) / (y2 - y1)) * total_frames/total_shown_frames], | |
602 'extrapolation') | |
603 | |
525 | 604 |
526 class FileUploadDownloadTest(BasePerfTest): | 605 class FileUploadDownloadTest(BasePerfTest): |
527 """Tests that involve measuring performance of upload and download.""" | 606 """Tests that involve measuring performance of upload and download.""" |
528 | 607 |
529 def setUp(self): | 608 def setUp(self): |
530 """Performs necessary setup work before running each test in this class.""" | 609 """Performs necessary setup work before running each test in this class.""" |
531 self._temp_dir = tempfile.mkdtemp() | 610 self._temp_dir = tempfile.mkdtemp() |
532 self._test_server = PerfTestServer(self._temp_dir) | 611 self._test_server = PerfTestServer(self._temp_dir) |
533 self._test_server_port = self._test_server.GetPort() | 612 self._test_server_port = self._test_server.GetPort() |
534 self._test_server.Run() | 613 self._test_server.Run() |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1180 """Identifies the port number to which the server is currently bound. | 1259 """Identifies the port number to which the server is currently bound. |
1181 | 1260 |
1182 Returns: | 1261 Returns: |
1183 The numeric port number to which the server is currently bound. | 1262 The numeric port number to which the server is currently bound. |
1184 """ | 1263 """ |
1185 return self._server.server_address[1] | 1264 return self._server.server_address[1] |
1186 | 1265 |
1187 | 1266 |
1188 if __name__ == '__main__': | 1267 if __name__ == '__main__': |
1189 pyauto_functional.Main() | 1268 pyauto_functional.Main() |
OLD | NEW |