OSDN Git Service

Manual merge of runtest fixes in donut and new account test def add in master.
authorBrett Chabot <brettchabot@google.com>
Wed, 6 May 2009 18:45:33 +0000 (11:45 -0700)
committerBrett Chabot <brettchabot@google.com>
Wed, 6 May 2009 18:45:33 +0000 (11:45 -0700)
commit 8a101cb057c1d1d5397b988b6a3f4c3add879008
Author: Brett Chabot <brettchabot@google.com>
Date:   Tue May 5 12:56:39 2009 -0700

    runtest.py bug fixes.

    Improved error handling, and added support for "size" and "package" arguments.
    Removed deprecated runtest shell script.

testrunner/adb_interface.py
testrunner/errors.py
testrunner/run_command.py
testrunner/runtest.py
testrunner/test_defs.xml
tools/runtest [deleted file]

index ad1b2c9..dd8d6f4 100755 (executable)
@@ -64,7 +64,7 @@ class AdbInterface:
       string output of command
 
     Raises:
-      WaitForResponseTimedOutError if device does not respond to command
+      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)
@@ -327,32 +327,30 @@ class AdbInterface:
       
     Raises:
       WaitForResponseTimedOutError if package manager does not respond
+      AbortError if unrecoverable error occurred
     """
-    output = self.SendCommand("sync", retry_count=retry_count)
+    output = ""
+    error = None
+    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)
-    if "No space left on device" in output:
+    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)
     self.WaitForDevicePm()
     return output
-  
-  def IsDevicePresent(self):
-    """Check if targeted device is present.
 
-    Returns:
-      True if device is present, False otherwise.
-    """
-    output = self.SendShellCommand("ls", retry_count=0)
-    if output.startswith("error:"):
-      return False
-    else:
-      return True
index 6d606ec..e240899 100755 (executable)
@@ -34,6 +34,9 @@ class AbortError(Exception):
   """Generic exception that indicates a fatal error has occurred and program
   execution should be aborted."""
 
+  def __init__(self, msg="AbortError"):
+    self.msg = msg
+
 
 class ParseError(Exception):
   """Raised when xml data to parse has unrecognized format."""
index 4449945..a98a943 100755 (executable)
@@ -58,10 +58,11 @@ def RunOnce(cmd, timeout_time=None, return_output=True):
   start_time = time.time()
   so = []
   pid = []
-  global _abort_on_error
+  global _abort_on_error, error_occurred
   error_occurred = False
 
   def Run():
+    global error_occurred
     if return_output:
       output_dest = subprocess.PIPE
     else:
@@ -83,8 +84,8 @@ def RunOnce(cmd, timeout_time=None, return_output=True):
       logger.Log(e)
       so.append("ERROR")
       error_occurred = True
-    if pipe.returncode < 0:
-      logger.SilentLog("Error: %s was terminated by signal %d" %(cmd,
+    if pipe.returncode != 0:
+      logger.SilentLog("Error: %s returned %d error code" %(cmd,
           pipe.returncode))
       error_occurred = True
 
@@ -111,9 +112,9 @@ def RunOnce(cmd, timeout_time=None, return_output=True):
       time.sleep(0.1)
 
   t.join()
-
+  output = "".join(so)
   if _abort_on_error and error_occurred:
-    raise errors.AbortError
+    raise errors.AbortError(msg=output)
 
   return "".join(so)
 
index fe6dfad..fde67ad 100755 (executable)
@@ -95,6 +95,10 @@ class TestRunner(object):
                       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("-u", "--user-tests-file", dest="user_tests_file",
                       metavar="FILE", default=user_test_default,
                       help="Alternate source of user test definitions")
@@ -252,6 +256,10 @@ class TestRunner(object):
     instrumentation_args = {}
     if test_class is not None:
       instrumentation_args["class"] = test_class
+    if self._options.test_package:
+      instrumentation_args["package"] = self._options.test_package
+    if self._options.test_size:
+      instrumentation_args["size"] = self._options.test_size
     if self._options.wait_for_debugger:
       instrumentation_args["debug"] = "true"
     if self._options.suite_assign_mode:
@@ -386,10 +394,6 @@ class TestRunner(object):
         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()
 
@@ -400,7 +404,8 @@ class TestRunner(object):
           self._RunTest(test_suite)
     except KeyboardInterrupt:
       logger.Log("Exiting...")
-    except errors.AbortError:
+    except errors.AbortError, e:
+      logger.Log(e.msg)
       logger.SilentLog("Exiting due to AbortError...")
     except errors.WaitForResponseTimedOutError:
       logger.Log("Timed out waiting for response")
index 8508b34..1565945 100644 (file)
@@ -100,6 +100,12 @@ Native tests:
     coverage_target="framework"
     continuous="true" />
 
+<test name="account"
+    build_path="frameworks/base/tests/AndroidTests"
+    package="com.android.unit_tests"
+    class="com.android.unit_tests.accounts.AccountManagerServiceTest"
+    coverage_target="framework" />
+
 <test name="smoke"
     build_path="frameworks/base/tests/SmokeTest"
     package="com.android.smoketest.tests"
diff --git a/tools/runtest b/tools/runtest
deleted file mode 100755 (executable)
index 5e4cbd6..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Options and default values
-# TODO: other options ideas:
-#   pass options to am (then remove some of the more specific options)
-# TODO capture more non-error output when not -v
-# TODO read configs from vendor/*, not just from vendor/google
-
-optListTests=0
-optSkipBuild=0
-optPreview=0
-optRawmode=0
-optSuiteAssignmentMode=0
-optAdbTarget=""
-optVerbose=0
-optWaitForDebugger=0
-optTestClass=""
-optTestMethod=""
-optUserTests=${HOME}/.android/runtest.rc
-
-#
-# process command-line options.  You must pass them into this function.
-# TODO error messages on once-only or mutually-exclusive options
-#
-function processOptions() {
-  while getopts "l b n a r d e s: v w c:t:u:" opt ; do
-    case ${opt} in
-      l ) optListTests=1 ;;
-      b ) optSkipBuild=1 ;;
-      n ) optPreview=1 ;;
-      r ) optRawMode=1 ;;
-      a ) optSuiteAssignmentMode=1 ;;
-      d ) optAdbTarget="-d" ;;
-      e ) optAdbTarget="-e" ;;
-      s ) optAdbTarget="-s ${OPTARG}" ;;
-      v ) optVerbose=1 ;;
-      w ) optWaitForDebugger=1 ;;
-      c ) optTestClass=${OPTARG} ;;
-      t ) optTestMethod=${OPTARG} ;;
-      u ) optUserTests=${OPTARG} ;;
-      esac
-  done
-}
-
-#
-# Show the command usage and options
-#
-function showUsage() {
-  echo "usage: The $progName script works in two ways.  You can query it for a list" >&2
-  echo "       of tests, or you can launch a test, test case, or test suite." >&2
-  echo "" >&2
-  echo "       $progName -l           # To view the list of tests" >&2
-  echo "" >&2
-  echo "       $progName              # To launch tests" >&2
-  echo "           [-b]                     # Skip build - just launch" >&2
-  echo "           [-n]                     # Do not execute, just preview commands" >&2
-  echo "           [-r]                     # Raw mode (for output to other tools)" >&2
-  echo "           [-a]                     # Suite assignment (for details & usage" >&2
-  echo "                                    #   see InstrumentationTestRunner)" >&2
-  echo "           [-v]                     # Increase verbosity of ${progName}" >&2
-  echo "           [-w]                     # Wait for debugger before launching tests" >&2
-  echo "           [-c test-class]          # Restrict test to a specific class" >&2
-  echo "           [-t test-method]         # Restrict test to a specific method" >&2
-  echo "           [-e | -d | -s ser-num]   # use emulator, device, or serial number" >&2
-  echo "           [-u user-tests-file]     # Alternate source of user definitions" >&2
-  echo "           short-test-name          # (req'd) test configuration to launch" >&2
-}
-
-# The list below are built-in test definitions.  You can also define your own
-# tests by creating a file named "~/.android/runtest.rc" and adding them to that
-# file.  (No array needed, just plain lines of text).
-#
-# Tests are defined by entries with the following format:
-# <short-name> <build-path> <test-package> <test-class>
-#              <testrunner-package> <testrunner-component>
-#
-# These map to the following commands:
-#   (if test-class = "#")
-#      adb shell am instrument -w \
-#        <testrunner-package>/<testrunner-component>
-#   (else)
-#      adb shell am instrument -w \
-#        -e class <test-package>.<test-class> \
-#        <testrunner-package>/<testrunner-component>
-#
-# In order to define the most common cases simply, "#" can be used for some of
-# the fields, with the following default values:
-#   <build-path> = "#":  skip build/sync step
-#   <test-package> = "#": test class is fully qualified with package
-#   <test-class> = "#":  omit "-e class" section
-#   <testrunner-package> = "#":   use same value as test-package
-#   <testrunner-component> = "#":  use "android.test.InstrumentationTestRunner"
-#
-# TODO: fields may be omitted completely if the trailing values are all "#"
-# TODO: this should be a here doc instead of an array
-
-knownTests=(
-  # NAME      BUILD DIR               <test-package> <test-class> <testrunner-package> <testrunner-component>
-
-  # system-wide tests
-  "framework  frameworks/base/tests/FrameworkTest # com.android.frameworktest.AllTests com.android.frameworktest.tests #"
-  "account    frameworks/base/tests/AndroidTests  # com.android.unit_tests.accounts.AccountManagerServiceTest com.android.unit_tests #"
-  "android    frameworks/base/tests/AndroidTests  com.android.unit_tests AndroidTests # #"
-  "smoke      frameworks/base/tests/SmokeTest     com.android.smoketest # com.android.smoketest.tests #"
-  "core       frameworks/base/tests/CoreTests     # android.core.CoreTests android.core #"
-  "libcore    frameworks/base/tests/CoreTests     # android.core.JavaTests android.core #"
-  "apidemos   development/samples/ApiDemos        com.example.android.apis # com.example.android.apis.tests #"
-  "launchperf development/apps/launchperf         com.android.launchperf # # .SimpleActivityLaunchPerformance"
-
-  # targeted framework tests
-  "heap       frameworks/base/tests/AndroidTests  com.android.unit_tests HeapTest # #"
-  "activity   frameworks/base/tests/AndroidTests  com.android.unit_tests activity.ActivityTests # #"
-  "deadlock  tests/Deadlock                       com.android.deadlock # com.android.deadlock.tests #"
-  "syncadapter vendor/google/tests/AbstractGDataSyncAdapterTest # # com.google.android.providers.abstractgdatasyncadaptertests #"
-  "tablemerger frameworks/base/tests/FrameworkTest # android.content.AbstractTableMergerTest com.android.frameworktest.tests #"
-
-  # selected app tests
-  "browser    packages/apps/Browser            com.android.browser # # .BrowserTestRunner"
-  "browserfunc packages/apps/Browser           com.android.browser # # .BrowserFunctionalTestRunner"
-  "calendar   packages/apps/Calendar/tests     com.android.calendar.tests # # #"
-  "calprov    packages/providers/CalendarProvider   com.android.providers.calendar # com.android.providers.calendar.tests #"
-  "camera     tests/Camera            com.android.cameratests # # CameraInstrumentationTestRunner"
-  "contactsprov packages/providers/GoogleContactsProvider/tests com.android.providers.contacts # com.android.providers.contactstests #"
-  "email      packages/apps/Email              com.android.email # com.android.email.tests #"
-  "emailsmall packages/apps/Email              com.android.email SmallTests com.android.email.tests #"
-  "media      tests/MediaFrameworkTest    com.android.mediaframeworktest # # .MediaFrameworkTestRunner"
-  "mediaunit  tests/MediaFrameworkTest com.android.mediaframeworktest # # .MediaFrameworkUnitTestRunner"
-  "mediaprov  tests/MediaProvider     com.android.mediaprovidertests # # .MediaProviderTestsInstrumentation"
-  "mms        packages/apps/Mms                # # com.android.mms.tests com.android.mms.ui.MMSInstrumentationTestRunner"
-  "mmslaunch  packages/apps/Mms                # # com.android.mms.tests com.android.mms.SmsLaunchPerformance"
-  "phone      tests/Phone             com.android.phonetests # # .PhoneInstrumentationTestRunner"
-  "phonestress tests/Phone            com.android.phonetests # # .PhoneInstrumentationStressTestRunner"
-  "ringtone   tests/RingtoneSettings  com.android.ringtonesettingstests # # .RingtoneSettingsInstrumentationTestRunner"
-)
-
-#
-# Searches for a runtest.rc file in a given directory and, if found, prepends it to
-# the list of known tests.
-#
-function readConfigFile () {
-  rcFile=$1
-  if [[ -f ${rcFile} ]] ; then
-    declare -a lines
-    exec 3<${rcFile} || exit
-    while read curline <&3; do
-      if [[ -z ${curline} || ${curline:0:1} = "#" ]]; then
-        continue
-      fi
-      lines=("${lines[@]}" "${curline}")
-    done
-    exec 3<&-
-
-    # now prepend the user lines (so they can override defaults)
-    knownTests=("${lines[@]}" "${knownTests[@]}")
-  fi
-}
-
-#
-# Searches for a specific test in the knownTests array.  If found, writes out
-# the remaining elements in the definition line (not including the test name).
-#
-function findTest() {
-  count=${#knownTests[@]}
-  index=0
-  while [[ ${index} -lt ${count} ]]
-  do
-    # If the first word in the entry matches the argument...
-    test=(${knownTests[$index]})
-    if [[ ${test[0]} = $1 ]] ; then
-      # Print all but the first word
-      echo ${test[@]:1}
-      return
-    fi
-    let "index = $index + 1"
-  done
-}
-
-#
-# Generate a simple listing of available tests
-#
-function dumpTests() {
-  echo "The following tests are currently defined:"
-  count=${#knownTests[@]}
-  index=0
-  while [[ ${index} -lt ${count} ]]
-  do
-    test=(${knownTests[$index]})
-    echo "  " ${test[0]}
-    let "index = $index + 1"
-  done
-}
-
-#
-# Writes the full pathname of the "top" of the development tree, as set by envsetup & lunch.
-# (based on gettop() from envsetup.sh)
-#
-function gettop {
-  TOPFILE=build/core/envsetup.mk
-  if [[ -n ${TOP} && -f ${TOP}/${TOPFILE} ]] ; then
-    echo ${TOP}
-  else
-    if [[ -f ${TOPFILE} ]] ; then
-      echo ${PWD}
-    else
-      # We redirect cd to /dev/null in case it's aliased to
-      # a command that prints something as a side-effect
-      # (like pushd)
-      HERE=${PWD}
-      T=
-    # while [ \( ! \( -f ${TOPFILE} \) \) -a \( $PWD != "/" \) ]; do
-      while [[ ! -f ${TOPFILE} && ${PWD} != "/" ]] ; do
-        cd .. > /dev/null
-        T=${PWD}
-      done
-      cd ${HERE} > /dev/null
-      if [[ -f ${T}/${TOPFILE} ]]; then
-        echo ${T}
-      fi
-    fi
-  fi
-}
-
-#
-# Captures the "mmm" command from envsetup.sh
-#
-function call_mmm() {
-  TOP=$(gettop)
-  if [[ -n ${TOP} ]] ; then
-    . ${TOP}/build/envsetup.sh
-    mmm ${TOP}/$@
-  fi
-}
-
-# main script
-
-progName=$(basename $0)
-
-if [[ $# -eq 0 ]] ; then
-  showUsage
-  exit 1
-fi
-
-processOptions $@
-shift $((OPTIND-1))
-
-readConfigFile $optUserTests
-# TODO: Read from *any* vendor/*/runtest.rc
-readConfigFile $(gettop)/vendor/google/runtest.rc
-
-# if requested, list all tests and halt
-if [[ ${optListTests} -ne 0 ]] ; then
-  dumpTests
-  exit 0
-fi
-
-testInfo=($(findTest $1))
-if [[ ${#testInfo[@]} -eq 5 ]] ; then
-  # break out test definition elements
-  buildPath=${testInfo[0]}
-  testPackage=${testInfo[1]}
-  testClass=${testInfo[2]}
-  runnerPackage=${testInfo[3]}
-  runnerComponent=${testInfo[4]}
-
-  # replace wildcards with default values
-  if [[ ${testPackage} == "#" ]] ; then
-    testPackage=
-  fi
-  if [[ ${runnerPackage} == "#" ]] ; then
-    runnerPackage=$testPackage
-  fi
-  if [[ ${runnerComponent} == "#" ]] ; then
-    runnerComponent="android.test.InstrumentationTestRunner"
-  fi
-
-  if [[ -n ${optTestClass} ]] ; then
-    testClass=$optTestClass
-  fi
-
-  # build & sync, if requested
-  if [[ ${optSkipBuild} -eq 0 ]] ; then
-    if [[ ${buildPath} != "#" ]] ; then
-      if [[ $optVerbose -ne 0 || ${optPreview} -ne 0 ]] ; then
-        echo mmm ${buildPath} "&&" adb ${optAdbTarget} remount "&&" adb ${optAdbTarget} sync
-      fi
-      if [[ ${optPreview} -eq 0 ]] ; then
-        call_mmm ${buildPath} && adb ${optAdbTarget} remount && adb ${optAdbTarget} sync
-        buildResult=$?
-      else
-        buildResult=0
-      fi
-      if [[ $buildResult -ne 0 ]] ; then
-        exit ${buildResult}
-      fi
-      # finally, sleep a bit.  this is a hack.  it gives the package manager time to
-      # install the package(s) that were just synced.  this causes a reduction in the number
-      # of false failures, but it's not a perfect solution.
-      if [ ${optPreview} -eq 0 ] ; then
-        echo "sleeping..."
-        sleep 2
-      fi
-    fi
-  fi
-
-  # setup additional clauses for the command
-  classOptions=""
-  if [[ ${testClass} != "#" ]] ; then
-    if [[ -z ${testPackage} ]] ; then
-      classOptions="-e class ${testClass}"
-    else
-      classOptions="-e class ${testPackage}.${testClass}"
-    fi
-    if [[ -n ${optTestMethod} ]] ; then
-      classOptions=${classOptions}#${optTestMethod}
-    fi
-  fi
-  debugOptions=""
-  if [[ ${optWaitForDebugger} -ne 0 ]] ; then
-    debugOptions="-e debug true"
-  fi
-      fi
-  if [[ ${optSuiteAssignmentMode} -ne 0 ]] ; then
-    debugOptions="-e suiteAssignment true "${debugOptions}
-  fi
-  if [[ ${optRawMode} -ne 0 ]] ; then
-    debugOptions="-r "${debugOptions}
-  fi
-
-  # "prevent" a race condition where we try to run the tests before they're
-  # actually installed
-  if [ ${optPreview} -eq 0 ] ; then
-    echo "sleeping..."
-    sleep 2
-  fi
-
-  # now run the command
-  if [[ $optVerbose -ne 0 || ${optPreview} -ne 0 ]] ; then
-    echo adb ${optAdbTarget} shell am instrument -w \
-      ${debugOptions} \
-      ${classOptions} \
-      ${runnerPackage}/${runnerComponent}
-  fi
-  if [[ ${optPreview} -eq 0 ]] ; then
-    adb ${optAdbTarget} shell am instrument -w \
-      ${debugOptions} \
-      ${classOptions} \
-      ${runnerPackage}/${runnerComponent}
-  fi
-  exit 0
-else
-  echo "$progName: unknown test \"$1\"" >&2
-  exit 1
-fi
-