Example #1
0
    def Sync(self, retry_count=3):
        """Perform a adb sync.
    
    Blocks until device package manager is responding.
    
    Args:
      retry_count: number of times to retry sync before failing
      
    Raises:
      WaitForResponseTimedOutError if package manager does not respond
    """
        output = self.SendCommand("sync", retry_count=retry_count)
        if "Read-only file system" in output:
            logger.SilentLog(output)
            logger.Log("Remounting read-only filesystem")
            self.SendCommand("remount")
            output = self.SendCommand("sync", retry_count=retry_count)
        if "No space left on device" in output:
            logger.SilentLog(output)
            logger.Log("Restarting device runtime")
            self.SendShellCommand("stop", retry_count=retry_count)
            output = self.SendCommand("sync", retry_count=retry_count)
            self.SendShellCommand("start", retry_count=retry_count)

        logger.SilentLog(output)
        self.WaitForDevicePm()
        return output
Example #2
0
    def _FindUpstreamTests(self, path):
        """Find tests defined upward from given path.

    Args:
      path: the location to start searching. If it points to a java class file
        or java package dir, the appropriate test suite filters will be set

    Returns:
      list of test_suite.AbstractTestSuite found, may be empty
    """
        class_name_arg = None
        package_name = None
        # if path is java file, populate class name
        if self._IsJavaFile(path):
            class_name_arg = self._GetClassNameFromFile(path)
            logger.SilentLog('Using java test class %s' % class_name_arg)
        elif self._IsJavaPackage(path):
            package_name = self._GetPackageNameFromDir(path)
            logger.SilentLog('Using java package %s' % package_name)
        manifest = self._FindUpstreamManifest(path)
        if manifest:
            logger.SilentLog('Found AndroidManifest at %s' %
                             manifest.GetAppPath())
            build_path = self._MakePathRelativeToBuild(manifest.GetAppPath())
            return self._CreateSuitesFromManifest(
                manifest,
                build_path,
                class_name=class_name_arg,
                java_package_name=package_name)
Example #3
0
    def CreateTests(self, sub_tests_path=None):
        """Create tests found in test_path.

    Will create a single InstrumentationTestSuite based on info found in
    AndroidManifest.xml found at build_path. Will set additional filters if
    test_path refers to a java package or java class.
    """
        tests = []
        class_name_arg = None
        java_package_name = None
        if sub_tests_path:
            # if path is java file, populate class name
            if self._IsJavaFile(sub_tests_path):
                class_name_arg = self._GetClassNameFromFile(sub_tests_path)
                logger.SilentLog('Using java test class %s' % class_name_arg)
            elif self._IsJavaPackage(sub_tests_path):
                java_package_name = self._GetPackageNameFromDir(sub_tests_path)
                logger.SilentLog('Using java package %s' % java_package_name)
        try:
            manifest_parser = android_manifest.AndroidManifest(
                app_path=self.GetTestsRootPath())
            instrs = manifest_parser.GetInstrumentationNames()
            if not instrs:
                logger.Log(
                    'Could not find instrumentation declarations in %s at %s' %
                    (android_manifest.AndroidManifest.FILENAME,
                     self.GetBuildPath()))
                return tests
            elif len(instrs) > 1:
                logger.Log(
                    "Found multiple instrumentation declarations in %s/%s. "
                    "Only using first declared." %
                    (self.GetBuildPath(),
                     android_manifest.AndroidManifest.FILENAME))
            instr_name = manifest_parser.GetInstrumentationNames()[0]
            # escape inner class names
            instr_name = instr_name.replace('$', '\$')
            pkg_name = manifest_parser.GetPackageName()
            if instr_name.find(".") < 0:
                instr_name = "." + instr_name
            logger.SilentLog('Found instrumentation %s/%s' %
                             (pkg_name, instr_name))
            suite = InstrumentationTestSuite()
            suite.SetPackageName(pkg_name)
            suite.SetBuildPath(self.GetBuildPath())
            suite.SetRunnerName(instr_name)
            suite.SetName(pkg_name)
            suite.SetClassName(class_name_arg)
            suite.SetJavaPackageFilter(java_package_name)
            tests.append(suite)
            return tests

        except:
            logger.Log('Could not find or parse %s at %s' %
                       (android_manifest.AndroidManifest.FILENAME,
                        self.GetBuildPath()))
        return tests
Example #4
0
    def CreateTests(self, sub_tests_path=None):
        """Create tests found in test_path.

    Will create a single InstrumentationTestSuite based on info found in
    AndroidManifest.xml found at build_path. Will set additional filters if
    test_path refers to a java package or java class.
    """
        tests = []
        class_name_arg = None
        java_package_name = None
        if sub_tests_path:
            # if path is java file, populate class name
            if self._IsJavaFile(sub_tests_path):
                class_name_arg = self._GetClassNameFromFile(sub_tests_path)
                logger.SilentLog('Using java test class %s' % class_name_arg)
            elif self._IsJavaPackage(sub_tests_path):
                java_package_name = self._GetPackageNameFromDir(sub_tests_path)
                logger.SilentLog('Using java package %s' % java_package_name)
        try:
            manifest_parser = android_manifest.AndroidManifest(
                app_path=self.GetTestsRootPath())
            instrs = manifest_parser.GetInstrumentationNames()
            if not instrs:
                logger.Log(
                    'Could not find instrumentation declarations in %s at %s' %
                    (android_manifest.AndroidManifest.FILENAME,
                     self.GetBuildPath()))
                return tests

            for instr_name in manifest_parser.GetInstrumentationNames():
                pkg_name = manifest_parser.GetPackageName()
                if instr_name.find(".") < 0:
                    instr_name = "." + instr_name
                logger.SilentLog('Found instrumentation %s/%s' %
                                 (pkg_name, instr_name))
                suite = InstrumentationTestSuite()
                suite.SetPackageName(pkg_name)
                suite.SetBuildPath(self.GetBuildPath())
                suite.SetRunnerName(instr_name)
                suite.SetName(pkg_name)
                suite.SetClassName(class_name_arg)
                suite.SetJavaPackageFilter(java_package_name)
                # this is a bit of a hack, assume if 'com.android.cts' is in
                # package name, this is a cts test
                # this logic can be removed altogether when cts tests no longer require
                # custom build steps
                if suite.GetPackageName().startswith('com.android.cts'):
                    suite.SetSuite('cts')
                tests.append(suite)
            return tests

        except:
            logger.Log('Could not find or parse %s at %s' %
                       (android_manifest.AndroidManifest.FILENAME,
                        self.GetBuildPath()))
        return tests
Example #5
0
def RunOnce(cmd, timeout_time=None, return_output=True):
    start_time = time.time()
    so = []
    pid = []
    global _abort_on_error
    error_occurred = False

    def Run():
        if return_output:
            output_dest = subprocess.PIPE
        else:
            # None means direct to stdout
            output_dest = None
        pipe = subprocess.Popen(cmd,
                                executable='/bin/bash',
                                stdout=output_dest,
                                stderr=subprocess.STDOUT,
                                shell=True)
        pid.append(pipe.pid)
        try:
            output = pipe.communicate()[0]
            if output is not None and len(output) > 0:
                so.append(output)
        except OSError, e:
            logger.SilentLog("failed to retrieve stdout from: %s" % cmd)
            logger.Log(e)
            so.append("ERROR")
            error_occurred = True
        if pipe.returncode < 0:
            logger.SilentLog("Error: %s was terminated by signal %d" %
                             (cmd, pipe.returncode))
            error_occurred = True
Example #6
0
 def Run():
     global error_occurred
     if return_output:
         output_dest = subprocess.PIPE
     else:
         # None means direct to stdout
         output_dest = None
     if stdin_input:
         stdin_dest = subprocess.PIPE
     else:
         stdin_dest = None
     pipe = subprocess.Popen(cmd,
                             executable='/bin/bash',
                             stdin=stdin_dest,
                             stdout=output_dest,
                             stderr=subprocess.STDOUT,
                             shell=True)
     pid.append(pipe.pid)
     try:
         output = pipe.communicate(input=stdin_input)[0]
         if output is not None and len(output) > 0:
             so.append(output)
     except OSError, e:
         logger.SilentLog("failed to retrieve stdout from: %s" % cmd)
         logger.Log(e)
         so.append("ERROR")
         error_occurred = True
Example #7
0
  def _GetTestFactory(self, android_mk_parser, path, build_path):
    """Get the test factory for given makefile.

    If given path is a valid tests build path, will return the TestFactory
    for creating tests.

    Args:
      android_mk_parser: the android mk to evaluate
      path: the filesystem path of the makefile
      build_path: filesystem path for the directory
      to build when running tests, relative to source root.

    Returns:
      the TestFactory or None if path is not a valid tests build path
    """
    if android_mk_parser.HasGTest():
      return gtest.GTestFactory(path, build_path)
    elif instrumentation_test.HasInstrumentationTest(path):
      return instrumentation_test.InstrumentationTestFactory(path,
          build_path)
    else:
      # somewhat unusual, but will continue searching
      logger.SilentLog('Found makefile at %s, but did not detect any tests.'
                       % path)

    return None
Example #8
0
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(None)
        if options.combine_coverage:
            coverage.CombineCoverage()
        if options.tidy:
            coverage.TidyOutput()
    except errors.AbortError:
        logger.SilentLog("Exiting due to AbortError")
Example #9
0
    def CreateTests(self, sub_tests_path=None):
        """Create tests found in sub_tests_path.

    Looks for test files matching a pattern, and assumes each one is a separate
    binary on target.

    Test files must match one of the following pattern:
      - test_*.[c|cc|cpp]
      - *_test.[c|cc|cpp]
      - *_unittest.[c|cc|cpp]

    """
        if not sub_tests_path:
            sub_tests_path = self.GetTestRootPath()
        test_file_list = []
        if os.path.isfile(sub_tests_path):
            self._EvaluateFile(test_file_list,
                               os.path.basename(sub_tests_path))
        else:
            os.path.walk(sub_tests_path, self._CollectTestSources,
                         test_file_list)
        # TODO: obtain this from makefile instead of hardcoding
        target_root_path = os.path.join('/data', 'nativetest')
        test_suites = []
        for test_file in test_file_list:
            logger.SilentLog('Creating gtest suite for file %s' % test_file)
            suite = GTestSuite()
            suite.SetBuildPath(self.GetBuildPath())
            suite.SetTargetExecPath(os.path.join(target_root_path, test_file))
            test_suites.append(suite)
        return test_suites
Example #10
0
  def _CreateSuitesFromManifest(self, manifest, build_path, class_name=None,
                                java_package_name=None):
    """Creates TestSuites from a AndroidManifest.

    Args:
      manifest: the AndroidManifest
      build_path: the build path to use for test
      class_name: optionally, the class filter for the suite
      java_package_name: optionally, the java package filter for the suite

    Returns:
      the list of tests created
    """
    tests = []
    for instr_name in manifest.GetInstrumentationNames():
      pkg_name = manifest.GetPackageName()
      logger.SilentLog('Found instrumentation %s/%s' % (pkg_name, instr_name))
      suite = instrumentation_test.InstrumentationTestSuite()
      suite.SetPackageName(pkg_name)
      suite.SetBuildPath(build_path)
      suite.SetRunnerName(instr_name)
      suite.SetName(pkg_name)
      suite.SetClassName(class_name)
      suite.SetJavaPackageFilter(java_package_name)
      # this is a bit of a hack, assume if 'com.android.cts' is in
      # package name, this is a cts test
      # this logic can be removed altogether when cts tests no longer require
      # custom build steps
      suite.SetCts(suite.GetPackageName().startswith('com.android.cts'))
      tests.append(suite)
    return tests
Example #11
0
    def _DoFullBuild(self, tests, test_requires_permissions):
        """If necessary, run a full 'make' command for the tests that need it."""
        extra_args_set = Set()

        for test in tests:
            if test.IsFullMake() and test.IsGrantedPermissions(
            ) == test_requires_permissions:
                if test.GetExtraBuildArgs():
                    # extra args contains the args to pass to 'make'
                    extra_args_set.add(test.GetExtraBuildArgs())
                else:
                    logger.Log(
                        "Warning: test %s needs a full build but does not specify"
                        " extra_build_args" % test.GetName())

        # check if there is actually any tests that required a full build
        if extra_args_set:
            cmd = ('make -j%s %s' %
                   (self._options.make_jobs, ' '.join(list(extra_args_set))))
            logger.Log(cmd)
            if not self._options.preview:
                old_dir = os.getcwd()
                os.chdir(self._root_path)
                output = run_command.RunCommand(cmd, return_output=True)
                logger.SilentLog(output)
                os.chdir(old_dir)
                self._DoInstall(output, test_requires_permissions)
Example #12
0
    def RunTests(self):
        """Main entry method - executes the tests according to command line args."""
        try:
            run_command.SetAbortOnError()
            self._ProcessOptions()
            if self._options.only_list_tests:
                self._DumpTests()
                return

            if not self._options.skip_build:
                self._DoBuild()

            if self._options.build_install_only:
                logger.Log(
                    "Skipping test execution (due to --build-install-only flag)"
                )
                return

            for test_suite in self._GetTestsToRun():
                try:
                    test_suite.Run(self._options, self._adb)
                except errors.WaitForResponseTimedOutError:
                    logger.Log("Timed out waiting for response")

        except KeyboardInterrupt:
            logger.Log("Exiting...")
        except errors.AbortError, error:
            logger.Log(error.msg)
            logger.SilentLog("Exiting due to AbortError...")
Example #13
0
def RunOnce(cmd, timeout_time=None, return_output=True, stdin_input=None):
    """Spawns a subprocess to run the given shell command.

  Args:
    cmd: shell command to run
    timeout_time: time in seconds to wait for command to run before aborting.
    return_output: if True return output of command as string. Otherwise,
      direct output of command to stdout.
    stdin_input: data to feed to stdin
  Returns:
    output of command
  Raises:
    errors.WaitForResponseTimedOutError if command did not complete within
      timeout_time seconds.
    errors.AbortError is command returned error code and SetAbortOnError is on.
  """
    start_time = time.time()
    so = []
    global _abort_on_error, error_occurred
    error_occurred = False

    if return_output:
        output_dest = tempfile.TemporaryFile(bufsize=0)
    else:
        # None means direct to stdout
        output_dest = None
    if stdin_input:
        stdin_dest = subprocess.PIPE
    else:
        stdin_dest = None
    pipe = subprocess.Popen(
        cmd,
        executable='/bin/bash',
        stdin=stdin_dest,
        stdout=output_dest,
        stderr=subprocess.STDOUT,
        shell=True,
        close_fds=True,
        preexec_fn=lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL))

    def Run():
        global error_occurred
        try:
            pipe.communicate(input=stdin_input)
            output = None
            if return_output:
                output_dest.seek(0)
                output = output_dest.read()
                output_dest.close()
            if output is not None and len(output) > 0:
                so.append(output)
        except OSError, e:
            logger.SilentLog("failed to retrieve stdout from: %s" % cmd)
            logger.Log(e)
            so.append("ERROR")
            error_occurred = True
        if pipe.returncode:
            logger.SilentLog("Error: %s returned %d error code" %
                             (cmd, pipe.returncode))
            error_occurred = True
Example #14
0
 def _EvaluateFile(self, test_list, file):
     (name, ext) = os.path.splitext(file)
     if ext == ".cc" or ext == ".cpp" or ext == ".c":
         if re.search("_test$|_test_$|_unittest$|_unittest_$|^test_|Tests$",
                      name):
             logger.SilentLog("Found native test file %s" % file)
             test_list.append(name)
Example #15
0
    def _DoBuild(self):
        logger.SilentLog("Building tests...")
        tests = self._GetTestsToRun()

        # Build and install tests that do not get granted permissions
        self._DoPermissionAwareBuild(tests, False)

        # Build and install tests that require granted permissions
        self._DoPermissionAwareBuild(tests, True)
Example #16
0
  def _DoBuild(self):
    logger.SilentLog("Building tests...")

    tests = self._GetTestsToRun()
    # turn off dalvik verifier if necessary
    self._TurnOffVerifier(tests)
    self._DoFullBuild(tests)

    target_set = []

    extra_args_set = []
    for test_suite in tests:
      self._AddBuildTarget(test_suite, target_set, extra_args_set)

    if not self._options.preview:
      self._adb.EnableAdbRoot()
    else:
      logger.Log("adb root")
    rebuild_libcore = False
    if target_set:
      if self._options.coverage:
        coverage.EnableCoverageBuild()
        # hack to remove core library intermediates
        # hack is needed because:
        # 1. EMMA_INSTRUMENT changes what source files to include in libcore
        #    but it does not trigger a rebuild
        # 2. there's no target (like "clear-intermediates") to remove the files
        #    decently
        rebuild_libcore = not coverage.TestDeviceCoverageSupport(self._adb)
        if rebuild_libcore:
          cmd = "rm -rf %s" % os.path.join(
              self._root_path,
              "out/target/common/obj/JAVA_LIBRARIES/core_intermediates/")
          logger.Log(cmd)
          run_command.RunCommand(cmd, return_output=False)

      target_build_string = " ".join(target_set)
      extra_args_string = " ".join(extra_args_set)

      # mmm cannot be used from python, so perform a similar operation using
      # ONE_SHOT_MAKEFILE
      cmd = 'ONE_SHOT_MAKEFILE="%s" make -j%s -C "%s" all_modules %s' % (
          target_build_string, self._options.make_jobs, self._root_path,
          extra_args_string)
      logger.Log(cmd)

      if self._options.preview:
        # in preview mode, just display to the user what command would have been
        # run
        logger.Log("adb sync")
      else:
        # set timeout for build to 10 minutes, since libcore may need to
        # be rebuilt
        run_command.RunCommand(cmd, return_output=False, timeout_time=600)
        logger.Log("Syncing to device...")
        self._adb.Sync(runtime_restart=rebuild_libcore)
Example #17
0
    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
Example #18
0
    def _DoBuild(self):
        logger.SilentLog("Building tests...")

        tests = self._GetTestsToRun()
        # turn off dalvik verifier if necessary
        self._TurnOffVerifier(tests)
        self._DoFullBuild(tests)

        target_tree = make_tree.MakeTree()

        extra_args_set = []
        for test_suite in tests:
            self._AddBuildTarget(test_suite, target_tree, extra_args_set)

        if not self._options.preview:
            self._adb.EnableAdbRoot()
        else:
            logger.Log("adb root")

        if not target_tree.IsEmpty():
            if self._options.coverage:
                coverage.EnableCoverageBuild()
                target_tree.AddPath("external/emma")

            target_list = target_tree.GetPrunedMakeList()
            target_build_string = " ".join(target_list)
            extra_args_string = " ".join(extra_args_set)

            # mmm cannot be used from python, so perform a similar operation using
            # ONE_SHOT_MAKEFILE
            cmd = 'ONE_SHOT_MAKEFILE="%s" make -j%s -C "%s" GET-INSTALL-PATH all_modules %s' % (
                target_build_string, self._options.make_jobs, self._root_path,
                extra_args_string)
            logger.Log(cmd)
            if not self._options.preview:
                output = run_command.RunCommand(cmd,
                                                return_output=True,
                                                timeout_time=600)
                logger.SilentLog(output)
                self._DoInstall(output)
Example #19
0
 def Run():
   global error_occurred
   try:
     pipe.communicate(input=stdin_input)
     output = None
     if return_output:
       output_dest.seek(0)
       output = output_dest.read()
       output_dest.close()
     if output is not None and len(output) > 0:
       so.append(output)
   except OSError, e:
     logger.SilentLog("failed to retrieve stdout from: %s" % cmd)
     logger.Log(e)
     so.append("ERROR")
     error_occurred = True
Example #20
0
 def __RecursiveGetVariable(self, identifier, visited_variables):
   variable_value = self.GetVariable(identifier)
   if not variable_value:
     return None
   if variable_value in visited_variables:
     raise RuntimeError('recursive loop found for makefile variable %s'
                        % variable_value)
   m = self._RE_VARIABLE_REF.match(variable_value)
   if m:
     logger.SilentLog('Found variable ref %s for identifier %s'
                      % (variable_value, identifier))
     variable_ref = m.group(1)
     visited_variables.add(variable_ref)
     return self.__RecursiveGetVariable(variable_ref, visited_variables)
   else:
     return variable_value
Example #21
0
  def _GetPackageNameFromFile(self, java_file_path):
    """Gets the java package name associated with given java file path.

    Args:
      java_file_path: file system path of java file

    Returns:
      the java package name or None
    """
    logger.SilentLog('Looking for java package name in %s' % java_file_path)
    re_package = re.compile(r'package\s+(.*);')
    file_handle = open(java_file_path, 'r')
    for line in file_handle:
      match = re_package.match(line)
      if match:
        return match.group(1)
    return None
Example #22
0
  def SendCommand(self, command_string, timeout_time=60, retry_count=3):
    """Send a command via adb.

    Args:
      command_string: adb command to run
      timeout_time: number of seconds to wait for command to respond before
        retrying
      retry_count: number of times to retry command before raising
        WaitForResponseTimedOutError
    Returns:
      string output of command

    Raises:
      WaitForResponseTimedOutError if device does not respond to command within time
    """
    adb_cmd = "adb %s %s" % (self._target_arg, command_string)
    logger.SilentLog("about to run %s" % adb_cmd)
    return run_command.RunCommand(adb_cmd, timeout_time=timeout_time,
                                  retry_count=retry_count)
Example #23
0
  def _DoBuild(self):
    logger.SilentLog("Building tests...")
    target_set = Set()
    extra_args_set = Set()
    tests = self._GetTestsToRun()
    for test_suite in tests:
      self._AddBuildTarget(test_suite, target_set, extra_args_set)

    if target_set:
      if self._options.coverage:
        coverage.EnableCoverageBuild()

      # hack to build cts dependencies
      # TODO: remove this when build dependency support added to runtest or
      # cts dependencies are removed
      if self._IsCtsTests(tests):
        # need to use make since these fail building with ONE_SHOT_MAKEFILE
        cmd = ('make -j%s CtsTestStubs android.core.tests.runner' %
               self._options.make_jobs)
        logger.Log(cmd)
        if not self._options.preview:
          old_dir = os.getcwd()
          os.chdir(self._root_path)
          run_command.RunCommand(cmd, return_output=False)
          os.chdir(old_dir)
      target_build_string = " ".join(list(target_set))
      extra_args_string = " ".join(list(extra_args_set))
      # mmm cannot be used from python, so perform a similar operation using
      # ONE_SHOT_MAKEFILE
      cmd = 'ONE_SHOT_MAKEFILE="%s" make -j%s -C "%s" files %s' % (
          target_build_string, self._options.make_jobs, self._root_path,
          extra_args_string)
      logger.Log(cmd)

      if self._options.preview:
        # in preview mode, just display to the user what command would have been
        # run
        logger.Log("adb sync")
      else:
        run_command.RunCommand(cmd, return_output=False)
        logger.Log("Syncing to device...")
        self._adb.Sync()
  def RunTests(self):
    """Main entry method - executes the tests according to command line args."""
    try:
      run_command.SetAbortOnError()
      self._ProcessOptions()
      if self._options.only_list_tests:
        self._DumpTests()
        return

      if not self._options.skip_build:
        self._DoBuild()

      for test_suite in self._GetTestsToRun():
        test_suite.Run(self._options, self._adb)

    except KeyboardInterrupt:
      logger.Log("Exiting...")
    except errors.AbortError, error:
      logger.Log(error.msg)
      logger.SilentLog("Exiting due to AbortError...")
Example #25
0
  def _CollectTestSources(self, test_list, dirname, files):
    """For each directory, find tests source file and add them to the list.

    Test files must match one of the following pattern:
      - test_*.[cc|cpp]
      - *_test.[cc|cpp]
      - *_unittest.[cc|cpp]

    This method is a callback for os.path.walk.

    Args:
      test_list: Where new tests should be inserted.
      dirname: Current directory.
      files: List of files in the current directory.
    """
    for f in files:
      (name, ext) = os.path.splitext(f)
      if ext == ".cc" or ext == ".cpp" or ext == ".c":
        if re.search("_test$|_test_$|_unittest$|_unittest_$|^test_", name):
          logger.SilentLog("Found %s" % f)
          test_list.append(str(os.path.join(dirname, f)))
Example #26
0
    def _DoFullBuild(self, tests):
        """If necessary, run a full 'make' command for the tests that need it."""
        extra_args_set = Set()

        # hack to build cts dependencies
        # TODO: remove this when cts dependencies are removed
        is_cts = self._IsCtsTests(tests)
        if is_cts:
            # need to use make since these fail building with ONE_SHOT_MAKEFILE
            extra_args_set.add('CtsTestStubs')
            extra_args_set.add('android.core.tests.runner')
        for test in tests:
            if test.IsFullMake():
                if test.GetExtraBuildArgs():
                    # extra args contains the args to pass to 'make'
                    extra_args_set.add(test.GetExtraBuildArgs())
                else:
                    logger.Log(
                        "Warning: test %s needs a full build but does not specify"
                        " extra_build_args" % test.GetName())

        # check if there is actually any tests that required a full build
        if extra_args_set:
            cmd = ('make -j%s %s' %
                   (self._options.make_jobs, ' '.join(list(extra_args_set))))
            logger.Log(cmd)
            if not self._options.preview:
                old_dir = os.getcwd()
                os.chdir(self._root_path)
                output = run_command.RunCommand(cmd, return_output=True)
                logger.SilentLog(output)
                os.chdir(old_dir)
                self._DoInstall(output)
                if is_cts:
                    # hack! hardcode install of CtsTestStubs
                    out = android_build.GetTestAppPath()
                    abs_install_path = os.path.join(out, "CtsTestStubs.apk")
                    logger.Log("adb install -r %s" % abs_install_path)
                    logger.Log(self._adb.Install(abs_install_path))
Example #27
0
    def _DoBuild(self):
        logger.SilentLog("Building tests...")
        target_set = Set()
        for test_suite in self._GetTestsToRun():
            self._AddBuildTarget(test_suite.GetBuildPath(), target_set)

        if target_set:
            if self._options.coverage:
                self._coverage_gen.EnableCoverageBuild()
                self._AddBuildTarget(self._coverage_gen.GetEmmaBuildPath(),
                                     target_set)
            target_build_string = " ".join(list(target_set))
            logger.Log("mmm %s" % target_build_string)
            cmd = 'ONE_SHOT_MAKEFILE="%s" make -C "%s" files' % (
                target_build_string, self._root_path)
            if self._options.preview:
                # in preview mode, just display to the user what command would have been
                # run
                logger.Log("adb sync")
            else:
                run_command.RunCommand(cmd, return_output=False)
                logger.Log("Syncing to device...")
                self._adb.Sync()
Example #28
0
    def RunTests(self):
        """Main entry method - executes the tests according to command line args."""
        try:
            run_command.SetAbortOnError()
            self._ProcessOptions()
            if self._options.only_list_tests:
                self._DumpTests()
                return

            if not self._adb.IsDevicePresent():
                logger.Log("Error: specified device cannot be found")
                return

            if not self._options.skip_build:
                self._DoBuild()

            for test_suite in self._GetTestsToRun():
                self._RunTest(test_suite)
        except KeyboardInterrupt:
            logger.Log("Exiting...")
        except errors.AbortError:
            logger.SilentLog("Exiting due to AbortError...")
        except errors.WaitForResponseTimedOutError:
            logger.Log("Timed out waiting for response")
Example #29
0
        error = None
        if runtime_restart:
            self.SendShellCommand("setprop ro.test_harness 1",
                                  retry_count=retry_count)
            # manual rest bootcomplete flag
            self.SendShellCommand("setprop dev.bootcomplete 0",
                                  retry_count=retry_count)
            self.SendShellCommand("stop", retry_count=retry_count)

        try:
            output = self.SendCommand("sync", retry_count=retry_count)
        except errors.AbortError, e:
            error = e
            output = e.msg
        if "Read-only file system" in output:
            logger.SilentLog(output)
            logger.Log("Remounting read-only filesystem")
            self.SendCommand("remount")
            output = self.SendCommand("sync", retry_count=retry_count)
        elif "No space left on device" in output:
            logger.SilentLog(output)
            logger.Log("Restarting device runtime")
            self.SendShellCommand("stop", retry_count=retry_count)
            output = self.SendCommand("sync", retry_count=retry_count)
            self.SendShellCommand("start", retry_count=retry_count)
        elif error is not None:
            # exception occurred that cannot be recovered from
            raise error
        logger.SilentLog(output)
        if runtime_restart:
            # start runtime and wait till boot complete flag is set
Example #30
0
    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("-j",
                          "--jobs",
                          dest="make_jobs",
                          metavar="X",
                          default=self._DEFAULT_JOBS,
                          help="Number of make jobs to use when building")
        parser.add_option("-n",
                          "--skip_execute",
                          dest="preview",
                          default=False,
                          action="store_true",
                          help="Do not execute, just preview commands")
        parser.add_option(
            "-i",
            "--build-install-only",
            dest="build_install_only",
            default=False,
            action="store_true",
            help="Do not execute, build tests and install to device only")
        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("-p",
                          "--test-package",
                          dest="test_package",
                          help="Restrict test to a specific java package")
        parser.add_option("-z",
                          "--size",
                          dest="test_size",
                          help="Restrict test to a specific test size")
        parser.add_option(
            "--annotation",
            dest="test_annotation",
            help="Include only those tests tagged with a specific"
            " annotation")
        parser.add_option("--not-annotation",
                          dest="test_not_annotation",
                          help="Exclude any tests tagged with a specific"
                          " annotation")
        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(
            "--coverage-target",
            dest="coverage_target_path",
            default=None,
            help="Path to app to collect code coverage target data for.")
        parser.add_option(
            "-k",
            "--skip-permissions",
            dest="skip_permissions",
            default=False,
            action="store_true",
            help="Do not grant runtime permissions during test package"
            " installation.")
        parser.add_option("-x",
                          "--path",
                          dest="test_path",
                          help="Run test(s) at given file system path")
        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")
        parser.add_option(
            "--timeout",
            dest="timeout",
            default=300,
            help="Set a timeout limit (in sec) for "
            "running native tests on a device (default: 300 secs)")
        parser.add_option("--suite",
                          dest="suite",
                          help="Run all tests defined as part of the "
                          "the given test suite")
        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 not self._options.suite and not self._options.test_path
                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)

        if self._options.coverage_target_path:
            self._options.coverage = True

        self._known_tests = self._ReadTests()

        self._options.host_lib_path = android_build.GetHostLibraryPath()
        self._options.test_data_path = android_build.GetTestAppPath()