media/webrtc/trunk/build/android/pylib/single_test_runner.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
michael@0 2 # Use of this source code is governed by a BSD-style license that can be
michael@0 3 # found in the LICENSE file.
michael@0 4
michael@0 5 import glob
michael@0 6 import logging
michael@0 7 import os
michael@0 8 import sys
michael@0 9
michael@0 10 from base_test_runner import BaseTestRunner
michael@0 11 import debug_info
michael@0 12 import constants
michael@0 13 import perf_tests_helper
michael@0 14 import run_tests_helper
michael@0 15 from test_package_apk import TestPackageApk
michael@0 16 from test_package_executable import TestPackageExecutable
michael@0 17 from test_result import TestResults
michael@0 18
michael@0 19
michael@0 20 class SingleTestRunner(BaseTestRunner):
michael@0 21 """Single test suite attached to a single device.
michael@0 22
michael@0 23 Args:
michael@0 24 device: Device to run the tests.
michael@0 25 test_suite: A specific test suite to run, empty to run all.
michael@0 26 gtest_filter: A gtest_filter flag.
michael@0 27 test_arguments: Additional arguments to pass to the test binary.
michael@0 28 timeout: Timeout for each test.
michael@0 29 rebaseline: Whether or not to run tests in isolation and update the filter.
michael@0 30 performance_test: Whether or not performance test(s).
michael@0 31 cleanup_test_files: Whether or not to cleanup test files on device.
michael@0 32 tool: Name of the Valgrind tool.
michael@0 33 shard_index: index number of the shard on which the test suite will run.
michael@0 34 dump_debug_info: Whether or not to dump debug information.
michael@0 35 build_type: 'Release' or 'Debug'.
michael@0 36 """
michael@0 37
michael@0 38 def __init__(self, device, test_suite, gtest_filter, test_arguments, timeout,
michael@0 39 rebaseline, performance_test, cleanup_test_files, tool_name,
michael@0 40 shard_index, dump_debug_info, fast_and_loose, build_type):
michael@0 41 BaseTestRunner.__init__(self, device, tool_name, shard_index, build_type)
michael@0 42 self._running_on_emulator = self.device.startswith('emulator')
michael@0 43 self._gtest_filter = gtest_filter
michael@0 44 self._test_arguments = test_arguments
michael@0 45 self.test_results = TestResults()
michael@0 46 if dump_debug_info:
michael@0 47 self.dump_debug_info = debug_info.GTestDebugInfo(self.adb, device,
michael@0 48 os.path.basename(test_suite), gtest_filter)
michael@0 49 else:
michael@0 50 self.dump_debug_info = None
michael@0 51 self.fast_and_loose = fast_and_loose
michael@0 52
michael@0 53 logging.warning('Test suite: ' + test_suite)
michael@0 54 if os.path.splitext(test_suite)[1] == '.apk':
michael@0 55 self.test_package = TestPackageApk(self.adb, device,
michael@0 56 test_suite, timeout, rebaseline, performance_test, cleanup_test_files,
michael@0 57 self.tool, self.dump_debug_info)
michael@0 58 else:
michael@0 59 self.test_package = TestPackageExecutable(
michael@0 60 self.adb, device,
michael@0 61 test_suite, timeout, rebaseline, performance_test, cleanup_test_files,
michael@0 62 self.tool, self.dump_debug_info)
michael@0 63 self._performance_test_setup = None
michael@0 64 if performance_test:
michael@0 65 self._performance_test_setup = perf_tests_helper.PerfTestSetup(self.adb)
michael@0 66
michael@0 67 def _TestSuiteRequiresMockTestServer(self):
michael@0 68 """Returns True if the test suite requires mock test server."""
michael@0 69 return False
michael@0 70 # TODO(yfriedman): Disabled because of flakiness.
michael@0 71 # (self.test_package.test_suite_basename == 'unit_tests' or
michael@0 72 # self.test_package.test_suite_basename == 'net_unittests' or
michael@0 73 # False)
michael@0 74
michael@0 75 def _GetFilterFileName(self):
michael@0 76 """Returns the filename of gtest filter."""
michael@0 77 return os.path.join(sys.path[0], 'gtest_filter',
michael@0 78 self.test_package.test_suite_basename + '_disabled')
michael@0 79
michael@0 80 def _GetAdditionalEmulatorFilterName(self):
michael@0 81 """Returns the filename of additional gtest filter for emulator."""
michael@0 82 return os.path.join(sys.path[0], 'gtest_filter',
michael@0 83 self.test_package.test_suite_basename +
michael@0 84 '_emulator_additional_disabled')
michael@0 85
michael@0 86 def GetDisabledTests(self):
michael@0 87 """Returns a list of disabled tests.
michael@0 88
michael@0 89 Returns:
michael@0 90 A list of disabled tests obtained from gtest_filter/test_suite_disabled.
michael@0 91 """
michael@0 92 disabled_tests = run_tests_helper.GetExpectations(self._GetFilterFileName())
michael@0 93 if self._running_on_emulator:
michael@0 94 # Append emulator's filter file.
michael@0 95 disabled_tests.extend(run_tests_helper.GetExpectations(
michael@0 96 self._GetAdditionalEmulatorFilterName()))
michael@0 97 return disabled_tests
michael@0 98
michael@0 99 def UpdateFilter(self, failed_tests):
michael@0 100 """Updates test_suite_disabled file with the new filter (deletes if empty).
michael@0 101
michael@0 102 If running in Emulator, only the failed tests which are not in the normal
michael@0 103 filter returned by _GetFilterFileName() are written to emulator's
michael@0 104 additional filter file.
michael@0 105
michael@0 106 Args:
michael@0 107 failed_tests: A sorted list of failed tests.
michael@0 108 """
michael@0 109 disabled_tests = []
michael@0 110 if not self._running_on_emulator:
michael@0 111 filter_file_name = self._GetFilterFileName()
michael@0 112 else:
michael@0 113 filter_file_name = self._GetAdditionalEmulatorFilterName()
michael@0 114 disabled_tests.extend(
michael@0 115 run_tests_helper.GetExpectations(self._GetFilterFileName()))
michael@0 116 logging.info('About to update emulator\'s additional filter (%s).'
michael@0 117 % filter_file_name)
michael@0 118
michael@0 119 new_failed_tests = []
michael@0 120 if failed_tests:
michael@0 121 for test in failed_tests:
michael@0 122 if test.name not in disabled_tests:
michael@0 123 new_failed_tests.append(test.name)
michael@0 124
michael@0 125 if not new_failed_tests:
michael@0 126 if os.path.exists(filter_file_name):
michael@0 127 os.unlink(filter_file_name)
michael@0 128 return
michael@0 129
michael@0 130 filter_file = file(filter_file_name, 'w')
michael@0 131 if self._running_on_emulator:
michael@0 132 filter_file.write('# Addtional list of suppressions from emulator\n')
michael@0 133 else:
michael@0 134 filter_file.write('# List of suppressions\n')
michael@0 135 filter_file.write('# This file was automatically generated by %s\n'
michael@0 136 % sys.argv[0])
michael@0 137 filter_file.write('\n'.join(sorted(new_failed_tests)))
michael@0 138 filter_file.write('\n')
michael@0 139 filter_file.close()
michael@0 140
michael@0 141 def GetDataFilesForTestSuite(self):
michael@0 142 """Returns a list of data files/dirs needed by the test suite."""
michael@0 143 # Ideally, we'd just push all test data. However, it has >100MB, and a lot
michael@0 144 # of the files are not relevant (some are used for browser_tests, others for
michael@0 145 # features not supported, etc..).
michael@0 146 if self.test_package.test_suite_basename in ['base_unittests',
michael@0 147 'sql_unittests',
michael@0 148 'unit_tests']:
michael@0 149 test_files = [
michael@0 150 'base/data/file_util_unittest',
michael@0 151 'base/data/json/bom_feff.json',
michael@0 152 'chrome/test/data/download-test1.lib',
michael@0 153 'chrome/test/data/extensions/bad_magic.crx',
michael@0 154 'chrome/test/data/extensions/good.crx',
michael@0 155 'chrome/test/data/extensions/icon1.png',
michael@0 156 'chrome/test/data/extensions/icon2.png',
michael@0 157 'chrome/test/data/extensions/icon3.png',
michael@0 158 'chrome/test/data/extensions/allow_silent_upgrade/',
michael@0 159 'chrome/test/data/extensions/app/',
michael@0 160 'chrome/test/data/extensions/bad/',
michael@0 161 'chrome/test/data/extensions/effective_host_permissions/',
michael@0 162 'chrome/test/data/extensions/empty_manifest/',
michael@0 163 'chrome/test/data/extensions/good/Extensions/',
michael@0 164 'chrome/test/data/extensions/manifest_tests/',
michael@0 165 'chrome/test/data/extensions/page_action/',
michael@0 166 'chrome/test/data/extensions/permissions/',
michael@0 167 'chrome/test/data/extensions/script_and_capture/',
michael@0 168 'chrome/test/data/extensions/unpacker/',
michael@0 169 'chrome/test/data/bookmarks/',
michael@0 170 'chrome/test/data/components/',
michael@0 171 'chrome/test/data/extensions/json_schema_test.js',
michael@0 172 'chrome/test/data/History/',
michael@0 173 'chrome/test/data/json_schema_validator/',
michael@0 174 'chrome/test/data/pref_service/',
michael@0 175 'chrome/test/data/serializer_nested_test.js',
michael@0 176 'chrome/test/data/serializer_test.js',
michael@0 177 'chrome/test/data/serializer_test_nowhitespace.js',
michael@0 178 'chrome/test/data/top_sites/',
michael@0 179 'chrome/test/data/web_app_info/',
michael@0 180 'chrome/test/data/web_database',
michael@0 181 'chrome/test/data/webui/',
michael@0 182 'chrome/test/data/zip',
michael@0 183 'chrome/third_party/mock4js/',
michael@0 184 'content/browser/gpu/software_rendering_list.json',
michael@0 185 'net/data/cache_tests/insert_load1',
michael@0 186 'net/data/cache_tests/dirty_entry5',
michael@0 187 'net/data/ssl/certificates/',
michael@0 188 'ui/base/test/data/data_pack_unittest',
michael@0 189 ]
michael@0 190 if self.test_package.test_suite_basename == 'unit_tests':
michael@0 191 test_files += ['chrome/test/data/simple_open_search.xml']
michael@0 192 # The following are spell check data. Now only list the data under
michael@0 193 # third_party/hunspell_dictionaries which are used by unit tests.
michael@0 194 old_cwd = os.getcwd()
michael@0 195 os.chdir(constants.CHROME_DIR)
michael@0 196 test_files += glob.glob('third_party/hunspell_dictionaries/*.bdic')
michael@0 197 os.chdir(old_cwd)
michael@0 198 return test_files
michael@0 199 elif self.test_package.test_suite_basename == 'net_unittests':
michael@0 200 return [
michael@0 201 'net/data/cache_tests',
michael@0 202 'net/data/filter_unittests',
michael@0 203 'net/data/ftp',
michael@0 204 'net/data/proxy_resolver_v8_unittest',
michael@0 205 'net/data/ssl/certificates',
michael@0 206 'net/data/url_request_unittest/',
michael@0 207 'net/data/proxy_script_fetcher_unittest'
michael@0 208 ]
michael@0 209 elif self.test_package.test_suite_basename == 'ui_tests':
michael@0 210 return [
michael@0 211 'chrome/test/data/dromaeo',
michael@0 212 'chrome/test/data/json2.js',
michael@0 213 'chrome/test/data/sunspider',
michael@0 214 'chrome/test/data/v8_benchmark',
michael@0 215 'chrome/test/perf/sunspider_uitest.js',
michael@0 216 'chrome/test/perf/v8_benchmark_uitest.js',
michael@0 217 ]
michael@0 218 elif self.test_package.test_suite_basename == 'page_cycler_tests':
michael@0 219 data = [
michael@0 220 'tools/page_cycler',
michael@0 221 'data/page_cycler',
michael@0 222 ]
michael@0 223 for d in data:
michael@0 224 if not os.path.exists(d):
michael@0 225 raise Exception('Page cycler data not found.')
michael@0 226 return data
michael@0 227 elif self.test_package.test_suite_basename == 'webkit_unit_tests':
michael@0 228 return [
michael@0 229 'third_party/WebKit/Source/WebKit/chromium/tests/data',
michael@0 230 ]
michael@0 231 elif self.test_package.test_suite_basename == 'content_unittests':
michael@0 232 return [
michael@0 233 'content/test/data/gpu/webgl_conformance_test_expectations.txt',
michael@0 234 'net/data/ssl/certificates/',
michael@0 235 'webkit/data/dom_storage/webcore_test_database.localstorage',
michael@0 236 'third_party/hyphen/hyph_en_US.dic',
michael@0 237 ]
michael@0 238 elif self.test_package.test_suite_basename == 'media_unittests':
michael@0 239 return [
michael@0 240 'media/test/data',
michael@0 241 ]
michael@0 242 return []
michael@0 243
michael@0 244 def LaunchHelperToolsForTestSuite(self):
michael@0 245 """Launches helper tools for the test suite.
michael@0 246
michael@0 247 Sometimes one test may need to run some helper tools first in order to
michael@0 248 successfully complete the test.
michael@0 249 """
michael@0 250 if self._TestSuiteRequiresMockTestServer():
michael@0 251 self.LaunchChromeTestServerSpawner()
michael@0 252
michael@0 253 def StripAndCopyFiles(self):
michael@0 254 """Strips and copies the required data files for the test suite."""
michael@0 255 self.test_package.StripAndCopyExecutable()
michael@0 256 self.test_package.PushDataAndPakFiles()
michael@0 257 self.tool.CopyFiles()
michael@0 258 test_data = self.GetDataFilesForTestSuite()
michael@0 259 if test_data and not self.fast_and_loose:
michael@0 260 # Make sure SD card is ready.
michael@0 261 self.adb.WaitForSdCardReady(20)
michael@0 262 for data in test_data:
michael@0 263 self.CopyTestData([data], self.adb.GetExternalStorage())
michael@0 264
michael@0 265 def RunTestsWithFilter(self):
michael@0 266 """Runs a tests via a small, temporary shell script."""
michael@0 267 self.test_package.CreateTestRunnerScript(self._gtest_filter,
michael@0 268 self._test_arguments)
michael@0 269 self.test_results = self.test_package.RunTestsAndListResults()
michael@0 270
michael@0 271 def RebaselineTests(self):
michael@0 272 """Runs all available tests, restarting in case of failures."""
michael@0 273 if self._gtest_filter:
michael@0 274 all_tests = set(self._gtest_filter.split(':'))
michael@0 275 else:
michael@0 276 all_tests = set(self.test_package.GetAllTests())
michael@0 277 failed_results = set()
michael@0 278 executed_results = set()
michael@0 279 while True:
michael@0 280 executed_names = set([f.name for f in executed_results])
michael@0 281 self._gtest_filter = ':'.join(all_tests - executed_names)
michael@0 282 self.RunTestsWithFilter()
michael@0 283 failed_results.update(self.test_results.crashed,
michael@0 284 self.test_results.failed)
michael@0 285 executed_results.update(self.test_results.crashed,
michael@0 286 self.test_results.failed,
michael@0 287 self.test_results.ok)
michael@0 288 executed_names = set([f.name for f in executed_results])
michael@0 289 logging.info('*' * 80)
michael@0 290 logging.info(self.device)
michael@0 291 logging.info('Executed: ' + str(len(executed_names)) + ' of ' +
michael@0 292 str(len(all_tests)))
michael@0 293 logging.info('Failed so far: ' + str(len(failed_results)) + ' ' +
michael@0 294 str([f.name for f in failed_results]))
michael@0 295 logging.info('Remaining: ' + str(len(all_tests - executed_names)) + ' ' +
michael@0 296 str(all_tests - executed_names))
michael@0 297 logging.info('*' * 80)
michael@0 298 if executed_names == all_tests:
michael@0 299 break
michael@0 300 self.test_results = TestResults.FromRun(
michael@0 301 ok=list(executed_results - failed_results),
michael@0 302 failed=list(failed_results))
michael@0 303
michael@0 304 def RunTests(self):
michael@0 305 """Runs all tests (in rebaseline mode, runs each test in isolation).
michael@0 306
michael@0 307 Returns:
michael@0 308 A TestResults object.
michael@0 309 """
michael@0 310 if self.test_package.rebaseline:
michael@0 311 self.RebaselineTests()
michael@0 312 else:
michael@0 313 if not self._gtest_filter:
michael@0 314 self._gtest_filter = ('-' + ':'.join(self.GetDisabledTests()) + ':' +
michael@0 315 ':'.join(['*.' + x + '*' for x in
michael@0 316 self.test_package.GetDisabledPrefixes()]))
michael@0 317 self.RunTestsWithFilter()
michael@0 318 return self.test_results
michael@0 319
michael@0 320 def SetUp(self):
michael@0 321 """Sets up necessary test enviroment for the test suite."""
michael@0 322 super(SingleTestRunner, self).SetUp()
michael@0 323 self.adb.ClearApplicationState(constants.CHROME_PACKAGE)
michael@0 324 if self._performance_test_setup:
michael@0 325 self._performance_test_setup.SetUp()
michael@0 326 if self.dump_debug_info:
michael@0 327 self.dump_debug_info.StartRecordingLog(True)
michael@0 328 self.StripAndCopyFiles()
michael@0 329 self.LaunchHelperToolsForTestSuite()
michael@0 330 self.tool.SetupEnvironment()
michael@0 331
michael@0 332 def TearDown(self):
michael@0 333 """Cleans up the test enviroment for the test suite."""
michael@0 334 self.tool.CleanUpEnvironment()
michael@0 335 if self.test_package.cleanup_test_files:
michael@0 336 self.adb.RemovePushedFiles()
michael@0 337 if self.dump_debug_info:
michael@0 338 self.dump_debug_info.StopRecordingLog()
michael@0 339 if self._performance_test_setup:
michael@0 340 self._performance_test_setup.TearDown()
michael@0 341 if self.dump_debug_info:
michael@0 342 self.dump_debug_info.ArchiveNewCrashFiles()
michael@0 343 super(SingleTestRunner, self).TearDown()

mercurial