Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: functional/perf.py

Issue 8548002: Adding CPU performance test for Youtube video (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/chrome/test/
Patch Set: '' Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « data/media/youtube.html ('k') | functional/youtube.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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()
OLDNEW
« no previous file with comments | « data/media/youtube.html ('k') | functional/youtube.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698