| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 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 | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """A framework to run PyAuto HTML media tests. | |
| 7 | |
| 8 This PyAuto powered script plays media (video or audio) files (using the HTML5 | |
| 9 tag embedded in an HTML file). The parameters needed to run this test are | |
| 10 passed in the form of environment variables (such as the number of runs). | |
| 11 media_test_runner.py is used for generating these variables | |
| 12 (PyAuto does not support direct parameters). | |
| 13 """ | |
| 14 | |
| 15 import csv | |
| 16 import logging | |
| 17 import os | |
| 18 import time | |
| 19 | |
| 20 import pyauto_media | |
| 21 import pyauto | |
| 22 | |
| 23 from media_test_env_names import MediaTestEnvNames | |
| 24 from ui_perf_test_utils import UIPerfTestUtils | |
| 25 | |
| 26 | |
| 27 class MediaTestBase(pyauto.PyUITest): | |
| 28 """A base class for media related PyAuto tests. | |
| 29 | |
| 30 This class is meant to a base class for all media related Pyauto test and | |
| 31 provides useful functionality to run the test in conjunction with | |
| 32 player.html file, which contains basic html and JavaScipt for media test. | |
| 33 The main test method (ExecuteTest()) contains execution loops to get average | |
| 34 measured data over several runs with the same condition. This class also | |
| 35 contains several basic pre/post-processing methods that should be overridden. | |
| 36 """ | |
| 37 | |
| 38 # Default values used for default case. | |
| 39 DEFAULT_MEDIA_TAG_NAME = 'video' | |
| 40 DEFAULT_MEDIA_FILENAME = 'bear_silent.ogv' | |
| 41 DEFAULT_MEDIA_FILENAME_NICKNAME = 'bear_silent.ogv' | |
| 42 DEFAULT_PLAYER_HTML_URL_NICKNAME = 'local' | |
| 43 DEFAULT_NUMBER_OF_RUNS = 3 | |
| 44 # Timing out for checking if video has finished playing (in seconds). | |
| 45 # Currently, we do not have videos more than 1 minute. | |
| 46 TIMEOUT = 60 | |
| 47 # Instance variables that used across methods. | |
| 48 number_of_runs = 0 | |
| 49 url = '' | |
| 50 parameter_str = '' | |
| 51 times = [] | |
| 52 media_filename = '' | |
| 53 media_filename_nickname = '' | |
| 54 whole_test_scenarios = [] | |
| 55 reference_build = False | |
| 56 | |
| 57 def _GetMediaURLAndParameterString(self, media_filename): | |
| 58 """Get media url and parameter string. | |
| 59 | |
| 60 If media url is specified in environment variable, then it is used. | |
| 61 Otherwise, local media data directory is used for the url. | |
| 62 Parameter string is calculated based on the environment variables. | |
| 63 | |
| 64 Args: | |
| 65 media_filename: the file name for the media (video/audio) with extension. | |
| 66 | |
| 67 Returns: | |
| 68 a tuple of media_url (with proper query string) and a parameter string, | |
| 69 which is used for performance result display. | |
| 70 """ | |
| 71 # Read environment variables. | |
| 72 player_html_url = os.getenv(MediaTestEnvNames.PLAYER_HTML_URL_ENV_NAME, | |
| 73 'DEFAULT') | |
| 74 player_html_url_nickname = os.getenv( | |
| 75 MediaTestEnvNames.PLAYER_HTML_URL_NICKNAME_ENV_NAME, | |
| 76 self.DEFAULT_PLAYER_HTML_URL_NICKNAME) | |
| 77 extra_nickname = os.getenv(MediaTestEnvNames.EXTRA_NICKNAME_ENV_NAME, '') | |
| 78 | |
| 79 tag = os.getenv(MediaTestEnvNames.MEDIA_TAG_ENV_NAME, | |
| 80 self.DEFAULT_MEDIA_TAG_NAME) | |
| 81 query_dictionary = {'tag': tag, 'media': media_filename} | |
| 82 # This parameter tricks the media cache into thinking | |
| 83 # it's a new file every time. | |
| 84 # However, it looks like does not make much difference in | |
| 85 # performance. | |
| 86 if os.getenv(MediaTestEnvNames.ADD_T_PARAMETER_ENV_NAME): | |
| 87 query_dictionary['t'] = 'dummy' | |
| 88 track_file = os.getenv(MediaTestEnvNames.TRACK_FILE_ENV_NAME) | |
| 89 if track_file: | |
| 90 query_dictionary['track'] = track_file | |
| 91 query_dictionary['num_extra'] = ( | |
| 92 os.getenv(MediaTestEnvNames.N_EXTRA_PLAYERS_ENV_NAME, 0)) | |
| 93 if os.getenv(MediaTestEnvNames.JERKY_TEST_ENV_NAME): | |
| 94 query_dictionary['jerky'] = 'True' | |
| 95 query_str = '&'.join( | |
| 96 [k + '=' + str(v) for (k, v) in query_dictionary.items()]) | |
| 97 if player_html_url_nickname == self.DEFAULT_PLAYER_HTML_URL_NICKNAME: | |
| 98 # Default is local file under DataDir(). | |
| 99 file_url = self.GetFileURLForDataPath( | |
| 100 os.path.join('media', 'html', self.GetPlayerHTMLFileName())) | |
| 101 url = file_url + '?' + query_str | |
| 102 else: | |
| 103 url = player_html_url + '?' + query_str | |
| 104 parameter_str = '%s_%s_%s' % ( | |
| 105 extra_nickname, player_html_url_nickname, | |
| 106 os.getenv(MediaTestEnvNames.MEDIA_FILENAME_NICKNAME_ENV_NAME)) | |
| 107 return url, parameter_str | |
| 108 | |
| 109 def ReadTestScenarioFiles(self, test_scenario_filename): | |
| 110 """Read a test scenario CSV file with actions such as 'play'. | |
| 111 | |
| 112 In the CSV file, each row is a test scenario which consists of one | |
| 113 or more (time, action, action_argument) triples (time and action_argument | |
| 114 are in milliseconds). For example, the following CSV file contains 3 test | |
| 115 scenarios to be tested. | |
| 116 500, pause, 0 | |
| 117 1000, pause, 0, 2000, play, 0 | |
| 118 1000, seek, 0, 2000, ratechange, 2 | |
| 119 """ | |
| 120 test_scenarios = [] | |
| 121 rows = csv.reader(open(test_scenario_filename)) | |
| 122 for row in rows: | |
| 123 test_scenarios.append('|'.join(row)) | |
| 124 return test_scenarios | |
| 125 | |
| 126 def ExecuteTest(self): | |
| 127 """Test HTML5 Media Tag.""" | |
| 128 | |
| 129 def _VideoEndedOrErrorOut(): | |
| 130 """Determine if the video ended or there was an error when playing. | |
| 131 | |
| 132 When the video has finished playing or there is error in playing the | |
| 133 video (e.g, the video cannot be found), its title is updated by | |
| 134 player.html. | |
| 135 | |
| 136 Returns: | |
| 137 True if the video has ended or an error occurred. | |
| 138 """ | |
| 139 return (self.GetDOMValue('document.title').strip() == 'END' or | |
| 140 'ERROR' in self.GetDOMValue('document.title')) | |
| 141 | |
| 142 self.PreAllRunsProcess() | |
| 143 for run_counter in range(self.number_of_runs): | |
| 144 self.run_counter = run_counter | |
| 145 self.PreEachRunProcess(run_counter) | |
| 146 url = self.url | |
| 147 if self.whole_test_scenarios: | |
| 148 url += '&actions=' + self.whole_test_scenarios[run_counter] | |
| 149 logging.debug('Navigate to %s', url) | |
| 150 self.NavigateToURL(url) | |
| 151 self.WaitUntil(lambda: _VideoEndedOrErrorOut(), | |
| 152 self.TIMEOUT) | |
| 153 self.PostEachRunProcess(run_counter) | |
| 154 | |
| 155 self.PostAllRunsProcess() | |
| 156 | |
| 157 # A list of methods that should be overridden in the subclass. | |
| 158 # It is a good practice to call these methods even if these are | |
| 159 # overridden. | |
| 160 | |
| 161 def PreAllRunsProcess(self): | |
| 162 """A method to be executed before all runs. | |
| 163 | |
| 164 The default behavior is to read parameters for the tests and initialize | |
| 165 variables. | |
| 166 """ | |
| 167 self.media_filename = os.getenv(MediaTestEnvNames.MEDIA_FILENAME_ENV_NAME, | |
| 168 self.DEFAULT_MEDIA_FILENAME) | |
| 169 self.media_filename_nickname = os.getenv( | |
| 170 MediaTestEnvNames.MEDIA_FILENAME_NICKNAME_ENV_NAME, | |
| 171 self.DEFAULT_MEDIA_FILENAME_NICKNAME) | |
| 172 self.remove_first_result = os.getenv( | |
| 173 MediaTestEnvNames.REMOVE_FIRST_RESULT_ENV_NAME) | |
| 174 self.number_of_runs = int(os.getenv(MediaTestEnvNames.N_RUNS_ENV_NAME, | |
| 175 self.DEFAULT_NUMBER_OF_RUNS)) | |
| 176 self.url, self.parameter_str = self._GetMediaURLAndParameterString( | |
| 177 self.media_filename) | |
| 178 self.times = [] | |
| 179 self.reference_build = os.getenv( | |
| 180 MediaTestEnvNames.REFERENCE_BUILD_ENV_NAME, False) | |
| 181 test_scenario_filename = os.getenv( | |
| 182 MediaTestEnvNames.TEST_SCENARIO_FILE_ENV_NAME, '') | |
| 183 test_scenario = os.getenv( | |
| 184 MediaTestEnvNames.TEST_SCENARIO_ENV_NAME, '') | |
| 185 if test_scenario: | |
| 186 # Run test with the same action several times. | |
| 187 self.whole_test_scenarios = [test_scenario] * self.number_of_runs | |
| 188 if test_scenario_filename: | |
| 189 self.whole_test_scenarios = ( | |
| 190 self.ReadTestScenarioFiles(test_scenario_filename)) | |
| 191 # One run per test scenario. | |
| 192 self.number_of_runs = len(self.whole_test_scenarios) | |
| 193 | |
| 194 def PostAllRunsProcess(self): | |
| 195 """A method to execute after all runs. | |
| 196 | |
| 197 The default behavior is to do nothing | |
| 198 """ | |
| 199 pass | |
| 200 | |
| 201 def PreEachRunProcess(self, run_counter): | |
| 202 """A method to execute before each run. | |
| 203 | |
| 204 The default behavior is to record start time. | |
| 205 | |
| 206 Args: | |
| 207 run_counter: counter for each run. | |
| 208 """ | |
| 209 self.start = time.time() | |
| 210 | |
| 211 def PostEachRunProcess(self, run_counter): | |
| 212 """A method to execute after each run. | |
| 213 | |
| 214 The default behavior is to do nothing. | |
| 215 | |
| 216 Args: | |
| 217 run_counter: counter for each run. | |
| 218 """ | |
| 219 pass | |
| 220 | |
| 221 def GetPlayerHTMLFileName(self): | |
| 222 """A method to get the player HTML file name.""" | |
| 223 return 'media_playback.html' | |
| 224 | |
| 225 | |
| 226 if __name__ == '__main__': | |
| 227 pyauto_media.Main() | |
| OLD | NEW |