def __init__(self, adb_interface): self._root_path = android_build.GetTop() self._output_root_path = os.path.join(self._root_path, self._COVERAGE_REPORT_PATH) self._emma_jar_path = os.path.join(self._root_path, self._EMMA_JAR) self._adb = adb_interface self._targets_manifest = self._ReadTargets()
def __init__(self): # disable logging of timestamp self._root_path = android_build.GetTop() logger.SetTimestampLogging(False) self._adb = None self._known_tests = None self._options = None self._test_args = None self._tests_to_run = None
def _DoesIncludesSubMake(self): if self._includes_submake is None: if self._is_leaf: path = os.path.join(android_build.GetTop(), self._path) mk_parser = android_mk.CreateAndroidMK(path) self._includes_submake = mk_parser.IncludesMakefilesUnder() else: self._includes_submake = False return self._includes_submake
def FindTests(self, path): """Gets list of Android tests found at given path. Tests are created from info found in Android.mk and AndroidManifest.xml files relative to the given path. Currently supported tests are: - Android application tests run via instrumentation - native C/C++ tests using GTest framework. (note Android.mk must follow expected GTest template) FindTests will first scan sub-folders of path for tests. If none are found, it will scan the file system upwards until a valid test Android.mk is found or the Android build root is reached. Some sample values for path: - a parent directory containing many tests: ie development/samples will return tests for instrumentation's in ApiDemos, ApiDemos/tests, Notepad/tests etc - a java test class file ie ApiDemos/tests/src/../ApiDemosTest.java will return a test for the instrumentation in ApiDemos/tests, with the class name filter set to ApiDemosTest - a java package directory ie ApiDemos/tests/src/com/example/android/apis will return a test for the instrumentation in ApiDemos/tests, with the java package filter set to com.example.android.apis. TODO: add GTest examples Args: path: file system path to search Returns: list of test suites that support operations defined by test_suite.AbstractTestSuite """ if not os.path.exists(path): logger.Log('%s does not exist' % path) return [] realpath = os.path.realpath(path) # ensure path is in ANDROID_BUILD_ROOT self._build_top = os.path.realpath(android_build.GetTop()) if not self._IsPathInBuildTree(realpath): logger.Log('%s is not a sub-directory of build root %s' % (path, self._build_top)) return [] # first, assume path is a parent directory, which specifies to run all # tests within this directory tests = self._FindSubTests(realpath, []) if not tests: logger.SilentLog('No tests found within %s, searching upwards' % path) tests = self._FindUpstreamTests(realpath) return tests
def __init__(self): # disable logging of timestamp self._root_path = android_build.GetTop() out_base_name = os.path.basename(android_build.GetOutDir()) # regular expression to find remote device path from a file path relative # to build root pattern = r'' + out_base_name + r'\/target\/product\/\w+\/(.+)$' self._re_make_install_path = re.compile(pattern) logger.SetTimestampLogging(False) self._adb = None self._known_tests = None self._options = None self._test_args = None self._tests_to_run = None
def AddPath(self, path): """Adds make directory path to tree. Will have no effect if path is already included in make set. Args: path: filesystem path to directory to build, relative to build root. """ path = os.path.normpath(path) mk_path = os.path.join(android_build.GetTop(), path, "Android.mk") if not os.path.isfile(mk_path): raise errors.AbortError("%s does not exist" % mk_path) path_segs = path.split(os.sep) child = self._AddPath(path_segs) child._SetLeaf(True)
def Run(): """Does coverage operations based on command line args.""" # TODO: do we want to support combining coverage for a single target try: parser = optparse.OptionParser(usage="usage: %prog --combine-coverage") parser.add_option( "-c", "--combine-coverage", dest="combine_coverage", default=False, action="store_true", help="Combine coverage results stored given " "android root path") parser.add_option( "-t", "--tidy", dest="tidy", default=False, action="store_true", help="Run tidy on all generated html files") options, args = parser.parse_args() coverage = CoverageGenerator(android_build.GetTop(), None) if options.combine_coverage: coverage.CombineCoverage() if options.tidy: coverage.TidyOutput() except errors.AbortError: logger.SilentLog("Exiting due to AbortError")
def Run(self, options, adb): """Run the provided *native* test suite. The test_suite must contain a build path where the native test files are. Subdirectories are automatically scanned as well. Each test's name must have a .cc or .cpp extension and match one of the following patterns: - test_* - *_test.[cc|cpp] - *_unittest.[cc|cpp] A successful test must return 0. Any other value will be considered as an error. Args: options: command line options adb: adb interface """ # find all test files, convert unicode names to ascii, take the basename # and drop the .cc/.cpp extension. source_list = [] build_path = os.path.join(android_build.GetTop(), self.GetBuildPath()) os.path.walk(build_path, self._CollectTestSources, source_list) logger.SilentLog("Tests source %s" % source_list) # Host tests are under out/host/<os>-<arch>/bin. host_list = self._FilterOutMissing(android_build.GetHostBin(), source_list) logger.SilentLog("Host tests %s" % host_list) # Target tests are under $ANDROID_PRODUCT_OUT/system/bin. target_list = self._FilterOutMissing(android_build.GetTargetSystemBin(), source_list) logger.SilentLog("Target tests %s" % target_list) # Run on the host logger.Log("\nRunning on host") for f in host_list: if run_command.RunHostCommand(f) != 0: logger.Log("%s... failed" % f) else: if run_command.HasValgrind(): if run_command.RunHostCommand(f, valgrind=True) == 0: logger.Log("%s... ok\t\t[valgrind: ok]" % f) else: logger.Log("%s... ok\t\t[valgrind: failed]" % f) else: logger.Log("%s... ok\t\t[valgrind: missing]" % f) # Run on the device logger.Log("\nRunning on target") for f in target_list: full_path = os.path.join(os.sep, "system", "bin", f) # Single quotes are needed to prevent the shell splitting it. output = adb.SendShellCommand("'%s 2>&1;echo -n exit code:$?'" % "(cd /sdcard;%s)" % full_path, int(options.timeout)) success = output.endswith("exit code:0") logger.Log("%s... %s" % (f, success and "ok" or "failed")) # Print the captured output when the test failed. if not success or options.verbose: pos = output.rfind("exit code") output = output[0:pos] logger.Log(output) # Cleanup adb.SendShellCommand("rm %s" % full_path)
def _ProcessOptions(self): """Processes command-line options.""" # TODO error messages on once-only or mutually-exclusive options. user_test_default = os.path.join(os.environ.get("HOME"), ".android", self._TEST_FILE_NAME) parser = optparse.OptionParser(usage=self._RUNTEST_USAGE) parser.add_option("-l", "--list-tests", dest="only_list_tests", default=False, action="store_true", help="To view the list of tests") parser.add_option("-b", "--skip-build", dest="skip_build", default=False, action="store_true", help="Skip build - just launch") parser.add_option("-n", "--skip_execute", dest="preview", default=False, action="store_true", help="Do not execute, just preview commands") parser.add_option("-r", "--raw-mode", dest="raw_mode", default=False, action="store_true", help="Raw mode (for output to other tools)") parser.add_option("-a", "--suite-assign", dest="suite_assign_mode", default=False, action="store_true", help="Suite assignment (for details & usage see " "InstrumentationTestRunner)") parser.add_option("-v", "--verbose", dest="verbose", default=False, action="store_true", help="Increase verbosity of %s" % sys.argv[0]) parser.add_option("-w", "--wait-for-debugger", dest="wait_for_debugger", default=False, action="store_true", help="Wait for debugger before launching tests") parser.add_option("-c", "--test-class", dest="test_class", help="Restrict test to a specific class") parser.add_option("-m", "--test-method", dest="test_method", help="Restrict test to a specific method") parser.add_option("-u", "--user-tests-file", dest="user_tests_file", metavar="FILE", default=user_test_default, help="Alternate source of user test definitions") parser.add_option("-o", "--coverage", dest="coverage", default=False, action="store_true", help="Generate code coverage metrics for test(s)") parser.add_option("-t", "--all-tests", dest="all_tests", default=False, action="store_true", help="Run all defined tests") parser.add_option( "--continuous", dest="continuous_tests", default=False, action="store_true", help="Run all tests defined as part of the continuous " "test set") group = optparse.OptionGroup( parser, "Targets", "Use these options to direct tests to a specific " "Android target") group.add_option("-e", "--emulator", dest="emulator", default=False, action="store_true", help="use emulator") group.add_option("-d", "--device", dest="device", default=False, action="store_true", help="use device") group.add_option("-s", "--serial", dest="serial", help="use specific serial") parser.add_option_group(group) self._options, self._test_args = parser.parse_args() if (not self._options.only_list_tests and not self._options.all_tests and not self._options.continuous_tests and len(self._test_args) < 1): parser.print_help() logger.SilentLog("at least one test name must be specified") raise errors.AbortError self._adb = adb_interface.AdbInterface() if self._options.emulator: self._adb.SetEmulatorTarget() elif self._options.device: self._adb.SetDeviceTarget() elif self._options.serial is not None: self._adb.SetTargetSerial(self._options.serial) if self._options.verbose: logger.SetVerbose(True) self._root_path = android_build.GetTop() self._known_tests = self._ReadTests() self._coverage_gen = coverage.CoverageGenerator( android_root_path=self._root_path, adb_interface=self._adb)