Home | History | Annotate | Download | only in test_defs
      1 #!/usr/bin/python2.4
      2 #
      3 #
      4 # Copyright 2008, The Android Open Source Project
      5 #
      6 # Licensed under the Apache License, Version 2.0 (the "License");
      7 # you may not use this file except in compliance with the License.
      8 # You may obtain a copy of the License at
      9 #
     10 #     http://www.apache.org/licenses/LICENSE-2.0
     11 #
     12 # Unless required by applicable law or agreed to in writing, software
     13 # distributed under the License is distributed on an "AS IS" BASIS,
     14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 # See the License for the specific language governing permissions and
     16 # limitations under the License.
     17 
     18 """TestSuite definition for Android instrumentation tests."""
     19 
     20 # python imports
     21 import os
     22 
     23 # local imports
     24 import coverage
     25 import errors
     26 import logger
     27 import test_suite
     28 
     29 
     30 class InstrumentationTestSuite(test_suite.AbstractTestSuite):
     31   """Represents a java instrumentation test suite definition run on device."""
     32 
     33   DEFAULT_RUNNER = "android.test.InstrumentationTestRunner"
     34 
     35     # build path to Emma target Makefile
     36   _EMMA_BUILD_PATH = os.path.join("external", "emma")
     37 
     38   def __init__(self):
     39     test_suite.AbstractTestSuite.__init__(self)
     40     self._package_name = None
     41     self._runner_name = self.DEFAULT_RUNNER
     42     self._class_name = None
     43     self._target_name = None
     44     self._java_package = None
     45 
     46   def GetPackageName(self):
     47     return self._package_name
     48 
     49   def SetPackageName(self, package_name):
     50     self._package_name = package_name
     51     return self
     52 
     53   def GetRunnerName(self):
     54     return self._runner_name
     55 
     56   def SetRunnerName(self, runner_name):
     57     self._runner_name = runner_name
     58     return self
     59 
     60   def GetClassName(self):
     61     return self._class_name
     62 
     63   def SetClassName(self, class_name):
     64     self._class_name = class_name
     65     return self
     66 
     67   def GetJavaPackageFilter(self):
     68     return self._java_package
     69 
     70   def SetJavaPackageFilter(self, java_package_name):
     71     """Configure the suite to only run tests in given java package."""
     72     self._java_package = java_package_name
     73     return self
     74 
     75   def GetTargetName(self):
     76     """Retrieve module that this test is targeting.
     77 
     78     Used for generating code coverage metrics.
     79     Returns:
     80       the module target name
     81     """
     82     return self._target_name
     83 
     84   def SetTargetName(self, target_name):
     85     self._target_name = target_name
     86     return self
     87 
     88   def GetBuildDependencies(self, options):
     89     if options.coverage:
     90       return [self._EMMA_BUILD_PATH]
     91     return []
     92 
     93   def Run(self, options, adb):
     94     """Run the provided test suite.
     95 
     96     Builds up an adb instrument command using provided input arguments.
     97 
     98     Args:
     99       options: command line options to provide to test run
    100       adb: adb_interface to device under test
    101 
    102     Raises:
    103       errors.AbortError: if fatal error occurs
    104     """
    105 
    106     test_class = self.GetClassName()
    107     if options.test_class is not None:
    108       test_class = options.test_class.lstrip()
    109       if test_class.startswith("."):
    110         test_class = self.GetPackageName() + test_class
    111     if options.test_method is not None:
    112       test_class = "%s#%s" % (test_class, options.test_method)
    113 
    114     test_package = self.GetJavaPackageFilter()
    115     if options.test_package:
    116       test_package = options.test_package
    117 
    118     if test_class and test_package:
    119       logger.Log('Error: both class and java package options are specified')
    120 
    121     instrumentation_args = {}
    122     if test_class is not None:
    123       instrumentation_args["class"] = test_class
    124     if test_package:
    125       instrumentation_args["package"] = test_package
    126     if options.test_size:
    127       instrumentation_args["size"] = options.test_size
    128     if options.wait_for_debugger:
    129       instrumentation_args["debug"] = "true"
    130     if options.suite_assign_mode:
    131       instrumentation_args["suiteAssignment"] = "true"
    132     if options.coverage:
    133       instrumentation_args["coverage"] = "true"
    134     if options.test_annotation:
    135       instrumentation_args["annotation"] = options.test_annotation
    136     if options.test_not_annotation:
    137       instrumentation_args["notAnnotation"] = options.test_not_annotation
    138     if options.preview:
    139       adb_cmd = adb.PreviewInstrumentationCommand(
    140           package_name=self.GetPackageName(),
    141           runner_name=self.GetRunnerName(),
    142           raw_mode=options.raw_mode,
    143           instrumentation_args=instrumentation_args)
    144       logger.Log(adb_cmd)
    145     elif options.coverage:
    146       coverage_gen = coverage.CoverageGenerator(adb)
    147       if not coverage_gen.TestDeviceCoverageSupport():
    148         raise errors.AbortError
    149       adb.WaitForInstrumentation(self.GetPackageName(),
    150                                  self.GetRunnerName())
    151       # need to parse test output to determine path to coverage file
    152       logger.Log("Running in coverage mode, suppressing test output")
    153       try:
    154         (test_results, status_map) = adb.StartInstrumentationForPackage(
    155             package_name=self.GetPackageName(),
    156             runner_name=self.GetRunnerName(),
    157             timeout_time=60*60,
    158             instrumentation_args=instrumentation_args)
    159       except errors.InstrumentationError, errors.DeviceUnresponsiveError:
    160         return
    161       self._PrintTestResults(test_results)
    162       device_coverage_path = status_map.get("coverageFilePath", None)
    163       if device_coverage_path is None:
    164         logger.Log("Error: could not find coverage data on device")
    165         return
    166 
    167       coverage_file = coverage_gen.ExtractReport(
    168           self, device_coverage_path, test_qualifier=options.test_size)
    169       if coverage_file is not None:
    170         logger.Log("Coverage report generated at %s" % coverage_file)
    171     else:
    172       adb.WaitForInstrumentation(self.GetPackageName(),
    173                                  self.GetRunnerName())
    174       adb.StartInstrumentationNoResults(
    175           package_name=self.GetPackageName(),
    176           runner_name=self.GetRunnerName(),
    177           raw_mode=options.raw_mode,
    178           instrumentation_args=instrumentation_args)
    179 
    180   def _PrintTestResults(self, test_results):
    181     """Prints a summary of test result data to stdout.
    182 
    183     Args:
    184       test_results: a list of am_instrument_parser.TestResult
    185     """
    186     total_count = 0
    187     error_count = 0
    188     fail_count = 0
    189     for test_result in test_results:
    190       if test_result.GetStatusCode() == -1:  # error
    191         logger.Log("Error in %s: %s" % (test_result.GetTestName(),
    192                                         test_result.GetFailureReason()))
    193         error_count+=1
    194       elif test_result.GetStatusCode() == -2:  # failure
    195         logger.Log("Failure in %s: %s" % (test_result.GetTestName(),
    196                                           test_result.GetFailureReason()))
    197         fail_count+=1
    198       total_count+=1
    199     logger.Log("Tests run: %d, Failures: %d, Errors: %d" %
    200                (total_count, fail_count, error_count))
    201