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

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

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 """Runs the Python tests (relies on using the Java test runner)."""
michael@0 6
michael@0 7 import logging
michael@0 8 import os
michael@0 9 import sys
michael@0 10 import types
michael@0 11
michael@0 12 import android_commands
michael@0 13 import apk_info
michael@0 14 import constants
michael@0 15 import python_test_base
michael@0 16 from python_test_caller import CallPythonTest
michael@0 17 from python_test_sharder import PythonTestSharder
michael@0 18 import run_java_tests
michael@0 19 from run_java_tests import FatalTestException
michael@0 20 from test_info_collection import TestInfoCollection
michael@0 21 from test_result import TestResults
michael@0 22
michael@0 23
michael@0 24 def _GetPythonFiles(root, files):
michael@0 25 """Returns all files from |files| that end in 'Test.py'.
michael@0 26
michael@0 27 Args:
michael@0 28 root: A directory name with python files.
michael@0 29 files: A list of file names.
michael@0 30
michael@0 31 Returns:
michael@0 32 A list with all Python driven test file paths.
michael@0 33 """
michael@0 34 return [os.path.join(root, f) for f in files if f.endswith('Test.py')]
michael@0 35
michael@0 36
michael@0 37 def _InferImportNameFromFile(python_file):
michael@0 38 """Given a file, infer the import name for that file.
michael@0 39
michael@0 40 Example: /usr/foo/bar/baz.py -> baz.
michael@0 41
michael@0 42 Args:
michael@0 43 python_file: path to the Python file, ostensibly to import later.
michael@0 44
michael@0 45 Returns:
michael@0 46 The module name for the given file.
michael@0 47 """
michael@0 48 return os.path.splitext(os.path.basename(python_file))[0]
michael@0 49
michael@0 50
michael@0 51 def DispatchPythonTests(options):
michael@0 52 """Dispatches the Python tests. If there are multiple devices, use sharding.
michael@0 53
michael@0 54 Args:
michael@0 55 options: command line options.
michael@0 56
michael@0 57 Returns:
michael@0 58 A list of test results.
michael@0 59 """
michael@0 60
michael@0 61 attached_devices = android_commands.GetAttachedDevices()
michael@0 62 if not attached_devices:
michael@0 63 raise FatalTestException('You have no devices attached or visible!')
michael@0 64 if options.device:
michael@0 65 attached_devices = [options.device]
michael@0 66
michael@0 67 test_collection = TestInfoCollection()
michael@0 68 all_tests = _GetAllTests(options.python_test_root, options.official_build)
michael@0 69 test_collection.AddTests(all_tests)
michael@0 70 test_names = [t.qualified_name for t in all_tests]
michael@0 71 logging.debug('All available tests: ' + str(test_names))
michael@0 72
michael@0 73 available_tests = test_collection.GetAvailableTests(
michael@0 74 options.annotation, options.test_filter)
michael@0 75
michael@0 76 if not available_tests:
michael@0 77 logging.warning('No Python tests to run with current args.')
michael@0 78 return TestResults()
michael@0 79
michael@0 80 available_tests *= options.number_of_runs
michael@0 81 test_names = [t.qualified_name for t in available_tests]
michael@0 82 logging.debug('Final list of tests to run: ' + str(test_names))
michael@0 83
michael@0 84 # Copy files to each device before running any tests.
michael@0 85 for device_id in attached_devices:
michael@0 86 logging.debug('Pushing files to device %s', device_id)
michael@0 87 apks = [apk_info.ApkInfo(options.test_apk_path, options.test_apk_jar_path)]
michael@0 88 test_files_copier = run_java_tests.TestRunner(options, device_id,
michael@0 89 None, False, 0, apks, [])
michael@0 90 test_files_copier.CopyTestFilesOnce()
michael@0 91
michael@0 92 # Actually run the tests.
michael@0 93 if len(attached_devices) > 1 and options.wait_for_debugger:
michael@0 94 logging.warning('Debugger can not be sharded, '
michael@0 95 'using first available device')
michael@0 96 attached_devices = attached_devices[:1]
michael@0 97 logging.debug('Running Python tests')
michael@0 98 sharder = PythonTestSharder(attached_devices, available_tests, options)
michael@0 99 test_results = sharder.RunShardedTests()
michael@0 100
michael@0 101 return test_results
michael@0 102
michael@0 103
michael@0 104 def _GetTestModules(python_test_root, is_official_build):
michael@0 105 """Retrieve a sorted list of pythonDrivenTests.
michael@0 106
michael@0 107 Walks the location of pythonDrivenTests, imports them, and provides the list
michael@0 108 of imported modules to the caller.
michael@0 109
michael@0 110 Args:
michael@0 111 python_test_root: the path to walk, looking for pythonDrivenTests
michael@0 112 is_official_build: whether to run only those tests marked 'official'
michael@0 113
michael@0 114 Returns:
michael@0 115 A list of Python modules which may have zero or more tests.
michael@0 116 """
michael@0 117 # By default run all python tests under pythonDrivenTests.
michael@0 118 python_test_file_list = []
michael@0 119 for root, _, files in os.walk(python_test_root):
michael@0 120 if (root.endswith('pythonDrivenTests')
michael@0 121 or (is_official_build
michael@0 122 and root.endswith('pythonDrivenTests/official'))):
michael@0 123 python_test_file_list += _GetPythonFiles(root, files)
michael@0 124 python_test_file_list.sort()
michael@0 125
michael@0 126 test_module_list = [_GetModuleFromFile(test_file)
michael@0 127 for test_file in python_test_file_list]
michael@0 128 return test_module_list
michael@0 129
michael@0 130
michael@0 131 def _GetModuleFromFile(python_file):
michael@0 132 """Gets the module associated with a file by importing it.
michael@0 133
michael@0 134 Args:
michael@0 135 python_file: file to import
michael@0 136
michael@0 137 Returns:
michael@0 138 The module object.
michael@0 139 """
michael@0 140 sys.path.append(os.path.dirname(python_file))
michael@0 141 import_name = _InferImportNameFromFile(python_file)
michael@0 142 return __import__(import_name)
michael@0 143
michael@0 144
michael@0 145 def _GetTestsFromClass(test_class):
michael@0 146 """Create a list of test objects for each test method on this class.
michael@0 147
michael@0 148 Test methods are methods on the class which begin with 'test'.
michael@0 149
michael@0 150 Args:
michael@0 151 test_class: class object which contains zero or more test methods.
michael@0 152
michael@0 153 Returns:
michael@0 154 A list of test objects, each of which is bound to one test.
michael@0 155 """
michael@0 156 test_names = [m for m in dir(test_class)
michael@0 157 if _IsTestMethod(m, test_class)]
michael@0 158 return map(test_class, test_names)
michael@0 159
michael@0 160
michael@0 161 def _GetTestClassesFromModule(test_module):
michael@0 162 tests = []
michael@0 163 for name in dir(test_module):
michael@0 164 attr = getattr(test_module, name)
michael@0 165 if _IsTestClass(attr):
michael@0 166 tests.extend(_GetTestsFromClass(attr))
michael@0 167 return tests
michael@0 168
michael@0 169
michael@0 170 def _IsTestClass(test_class):
michael@0 171 return (type(test_class) is types.TypeType and
michael@0 172 issubclass(test_class, python_test_base.PythonTestBase) and
michael@0 173 test_class is not python_test_base.PythonTestBase)
michael@0 174
michael@0 175
michael@0 176 def _IsTestMethod(attrname, test_case_class):
michael@0 177 """Checks whether this is a valid test method.
michael@0 178
michael@0 179 Args:
michael@0 180 attrname: the method name.
michael@0 181 test_case_class: the test case class.
michael@0 182
michael@0 183 Returns:
michael@0 184 True if test_case_class.'attrname' is callable and it starts with 'test';
michael@0 185 False otherwise.
michael@0 186 """
michael@0 187 attr = getattr(test_case_class, attrname)
michael@0 188 return callable(attr) and attrname.startswith('test')
michael@0 189
michael@0 190
michael@0 191 def _GetAllTests(test_root, is_official_build):
michael@0 192 """Retrieve a list of Python test modules and their respective methods.
michael@0 193
michael@0 194 Args:
michael@0 195 test_root: path which contains Python-driven test files
michael@0 196 is_official_build: whether this is an official build
michael@0 197
michael@0 198 Returns:
michael@0 199 List of test case objects for all available test methods.
michael@0 200 """
michael@0 201 if not test_root:
michael@0 202 return []
michael@0 203 all_tests = []
michael@0 204 test_module_list = _GetTestModules(test_root, is_official_build)
michael@0 205 for module in test_module_list:
michael@0 206 all_tests.extend(_GetTestClassesFromModule(module))
michael@0 207 return all_tests

mercurial