Chromium Code Reviews| 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 |