1764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot#!/usr/bin/python2.4
2764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot#
3764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot#
4764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot# Copyright 2008, The Android Open Source Project
5764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot#
6764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot# Licensed under the Apache License, Version 2.0 (the "License");
7764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot# you may not use this file except in compliance with the License.
8764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot# You may obtain a copy of the License at
9764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot#
10764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot#     http://www.apache.org/licenses/LICENSE-2.0
11764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot#
12764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot# Unless required by applicable law or agreed to in writing, software
13764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot# distributed under the License is distributed on an "AS IS" BASIS,
14764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot# See the License for the specific language governing permissions and
16764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot# limitations under the License.
17764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
18764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot"""TestSuite definition for Android instrumentation tests."""
19764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
20bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabotimport os
21bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabotimport re
22bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
23764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot# local imports
24bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabotimport android_manifest
258ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabotfrom coverage import coverage
26764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabotimport errors
27764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabotimport logger
28924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotimport test_suite
29764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
30764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
31924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotclass InstrumentationTestSuite(test_suite.AbstractTestSuite):
32924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  """Represents a java instrumentation test suite definition run on device."""
33764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
34924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  DEFAULT_RUNNER = "android.test.InstrumentationTestRunner"
35764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
36924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def __init__(self):
37924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    test_suite.AbstractTestSuite.__init__(self)
38924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    self._package_name = None
39924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    self._runner_name = self.DEFAULT_RUNNER
40924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    self._class_name = None
41924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    self._target_name = None
421cd617413095758758beef03e3f45d26e9ad7751Brett Chabot    self._java_package = None
43764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
44764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot  def GetPackageName(self):
45924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return self._package_name
46924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
47924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def SetPackageName(self, package_name):
48924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    self._package_name = package_name
49924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return self
50764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
51764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot  def GetRunnerName(self):
52924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return self._runner_name
53924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
54924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def SetRunnerName(self, runner_name):
55924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    self._runner_name = runner_name
56924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return self
57764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
58764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot  def GetClassName(self):
59924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return self._class_name
60924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
61924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def SetClassName(self, class_name):
62924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    self._class_name = class_name
63924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return self
64764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
651cd617413095758758beef03e3f45d26e9ad7751Brett Chabot  def GetJavaPackageFilter(self):
661cd617413095758758beef03e3f45d26e9ad7751Brett Chabot    return self._java_package
671cd617413095758758beef03e3f45d26e9ad7751Brett Chabot
681cd617413095758758beef03e3f45d26e9ad7751Brett Chabot  def SetJavaPackageFilter(self, java_package_name):
691cd617413095758758beef03e3f45d26e9ad7751Brett Chabot    """Configure the suite to only run tests in given java package."""
701cd617413095758758beef03e3f45d26e9ad7751Brett Chabot    self._java_package = java_package_name
711cd617413095758758beef03e3f45d26e9ad7751Brett Chabot    return self
721cd617413095758758beef03e3f45d26e9ad7751Brett Chabot
73764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot  def GetTargetName(self):
74764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    """Retrieve module that this test is targeting.
75764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
76764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    Used for generating code coverage metrics.
77924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    Returns:
78924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      the module target name
79764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    """
80924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return self._target_name
81924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
82924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def SetTargetName(self, target_name):
83924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    self._target_name = target_name
84924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return self
85764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
86764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot  def GetBuildDependencies(self, options):
878ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabot    if options.coverage_target_path:
888ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabot      return [options.coverage_target_path]
89764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    return []
90764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
91764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot  def Run(self, options, adb):
92764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    """Run the provided test suite.
93764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
94764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    Builds up an adb instrument command using provided input arguments.
95764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
96764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    Args:
97764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      options: command line options to provide to test run
98764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      adb: adb_interface to device under test
99924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
100924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    Raises:
101924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      errors.AbortError: if fatal error occurs
102764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    """
103764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
104764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    test_class = self.GetClassName()
105764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    if options.test_class is not None:
106764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      test_class = options.test_class.lstrip()
107764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      if test_class.startswith("."):
1083ae5f8a399ef9b4e930b988040f86f403e27c7f0Brett Chabot        test_class = self.GetPackageName() + test_class
109764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    if options.test_method is not None:
110764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      test_class = "%s#%s" % (test_class, options.test_method)
111764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
1121cd617413095758758beef03e3f45d26e9ad7751Brett Chabot    test_package = self.GetJavaPackageFilter()
1131cd617413095758758beef03e3f45d26e9ad7751Brett Chabot    if options.test_package:
1141cd617413095758758beef03e3f45d26e9ad7751Brett Chabot      test_package = options.test_package
1151cd617413095758758beef03e3f45d26e9ad7751Brett Chabot
1161cd617413095758758beef03e3f45d26e9ad7751Brett Chabot    if test_class and test_package:
1171cd617413095758758beef03e3f45d26e9ad7751Brett Chabot      logger.Log('Error: both class and java package options are specified')
1181cd617413095758758beef03e3f45d26e9ad7751Brett Chabot
119764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    instrumentation_args = {}
120764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    if test_class is not None:
121764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      instrumentation_args["class"] = test_class
1221cd617413095758758beef03e3f45d26e9ad7751Brett Chabot    if test_package:
1231cd617413095758758beef03e3f45d26e9ad7751Brett Chabot      instrumentation_args["package"] = test_package
124764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    if options.test_size:
125764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      instrumentation_args["size"] = options.test_size
126764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    if options.wait_for_debugger:
127764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      instrumentation_args["debug"] = "true"
128764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    if options.suite_assign_mode:
129764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      instrumentation_args["suiteAssignment"] = "true"
130764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    if options.coverage:
131764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      instrumentation_args["coverage"] = "true"
132c061154208c924fc31100bc453d9f698d4654703Brett Chabot    if options.test_annotation:
133c061154208c924fc31100bc453d9f698d4654703Brett Chabot      instrumentation_args["annotation"] = options.test_annotation
134c061154208c924fc31100bc453d9f698d4654703Brett Chabot    if options.test_not_annotation:
135c061154208c924fc31100bc453d9f698d4654703Brett Chabot      instrumentation_args["notAnnotation"] = options.test_not_annotation
136764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    if options.preview:
137764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      adb_cmd = adb.PreviewInstrumentationCommand(
138764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot          package_name=self.GetPackageName(),
139764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot          runner_name=self.GetRunnerName(),
140764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot          raw_mode=options.raw_mode,
141764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot          instrumentation_args=instrumentation_args)
142764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      logger.Log(adb_cmd)
143764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    elif options.coverage:
144764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      coverage_gen = coverage.CoverageGenerator(adb)
1458ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabot      if options.coverage_target_path:
1468ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabot        coverage_target = coverage_gen.GetCoverageTargetForPath(options.coverage_target_path)
1478ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabot      elif self.GetTargetName():
1488ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabot        coverage_target = coverage_gen.GetCoverageTarget(self.GetTargetName())
14981c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot      self._CheckInstrumentationInstalled(adb)
150764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      # need to parse test output to determine path to coverage file
151764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      logger.Log("Running in coverage mode, suppressing test output")
152764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      try:
153764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot        (test_results, status_map) = adb.StartInstrumentationForPackage(
154924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot            package_name=self.GetPackageName(),
155924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot            runner_name=self.GetRunnerName(),
156924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot            timeout_time=60*60,
157924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot            instrumentation_args=instrumentation_args)
158764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      except errors.InstrumentationError, errors.DeviceUnresponsiveError:
159764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot        return
160764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      self._PrintTestResults(test_results)
161764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      device_coverage_path = status_map.get("coverageFilePath", None)
162764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      if device_coverage_path is None:
163764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot        logger.Log("Error: could not find coverage data on device")
164764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot        return
165764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
1668424ffc02c61cc349b3e60bd2e9be93f738ad182Brett Chabot      coverage_file = coverage_gen.ExtractReport(
1678ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabot          self.GetName(), coverage_target, device_coverage_path,
1688ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabot          test_qualifier=options.test_size)
169764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      if coverage_file is not None:
170764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot        logger.Log("Coverage report generated at %s" % coverage_file)
17181c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot
172764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    else:
17381c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot      self._CheckInstrumentationInstalled(adb)
17481c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot      adb.StartInstrumentationNoResults(package_name=self.GetPackageName(),
17581c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot                                        runner_name=self.GetRunnerName(),
17681c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot                                        raw_mode=options.raw_mode,
17781c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot                                        instrumentation_args=
17881c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot                                        instrumentation_args)
17981c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot
18081c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot  def _CheckInstrumentationInstalled(self, adb):
1818ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabot    if not adb.IsInstrumentationInstalled(self.GetPackageName(),
18281c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot                                          self.GetRunnerName()):
18381c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot      msg=("Could not find instrumentation %s/%s on device. Try forcing a "
1848ac51186a6dd54c2bc3f1bb0c13364dd83d614b4Brett Chabot           "rebuild by updating a source file, and re-executing runtest." %
18581c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot           (self.GetPackageName(), self.GetRunnerName()))
18681c475e4acd22bbece8658356cf279d82e65ff3cBrett Chabot      raise errors.AbortError(msg=msg)
187764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
188764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot  def _PrintTestResults(self, test_results):
189764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    """Prints a summary of test result data to stdout.
190764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot
191764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    Args:
192764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      test_results: a list of am_instrument_parser.TestResult
193764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    """
194764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    total_count = 0
195764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    error_count = 0
196764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    fail_count = 0
197764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    for test_result in test_results:
198924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      if test_result.GetStatusCode() == -1:  # error
199764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot        logger.Log("Error in %s: %s" % (test_result.GetTestName(),
200764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot                                        test_result.GetFailureReason()))
201764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot        error_count+=1
202924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      elif test_result.GetStatusCode() == -2:  # failure
203764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot        logger.Log("Failure in %s: %s" % (test_result.GetTestName(),
204764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot                                          test_result.GetFailureReason()))
205764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot        fail_count+=1
206764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot      total_count+=1
207764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot    logger.Log("Tests run: %d, Failures: %d, Errors: %d" %
208764d3fa70d42a79e2ee999b790e69fc55f12bf61Brett Chabot               (total_count, fail_count, error_count))
209bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
210ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabotdef HasInstrumentationTest(path):
211ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabot  """Determine if given path defines an instrumentation test.
212ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabot
213ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabot  Args:
214ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabot    path: file system path to instrumentation test.
215ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabot  """
216ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabot  manifest_parser = android_manifest.CreateAndroidManifest(path)
217ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabot  if manifest_parser:
218ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabot    return manifest_parser.GetInstrumentationNames()
219ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabot  return False
220ecfcc7da8eb6db2c31bc45eb1d1b89ac231082a9Brett Chabot
221bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabotclass InstrumentationTestFactory(test_suite.AbstractTestFactory):
222bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot  """A factory for creating InstrumentationTestSuites"""
223bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
224b0fd2cf9421122462eee3263d81580a21ef2ce22Brett Chabot  def __init__(self, test_root_path, build_path):
225bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    test_suite.AbstractTestFactory.__init__(self, test_root_path,
226b0fd2cf9421122462eee3263d81580a21ef2ce22Brett Chabot                                            build_path)
227bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
228bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot  def CreateTests(self, sub_tests_path=None):
229bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """Create tests found in test_path.
230bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
231bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Will create a single InstrumentationTestSuite based on info found in
232bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    AndroidManifest.xml found at build_path. Will set additional filters if
233bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    test_path refers to a java package or java class.
234bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """
235bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    tests = []
236bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    class_name_arg = None
237bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    java_package_name = None
238bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    if sub_tests_path:
239bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      # if path is java file, populate class name
240bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      if self._IsJavaFile(sub_tests_path):
241bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        class_name_arg = self._GetClassNameFromFile(sub_tests_path)
242bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        logger.SilentLog('Using java test class %s' % class_name_arg)
243bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      elif self._IsJavaPackage(sub_tests_path):
244bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        java_package_name = self._GetPackageNameFromDir(sub_tests_path)
245bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        logger.SilentLog('Using java package %s' % java_package_name)
246bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    try:
247bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      manifest_parser = android_manifest.AndroidManifest(app_path=
248bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot                                                         self.GetTestsRootPath())
249bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      instrs = manifest_parser.GetInstrumentationNames()
250bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      if not instrs:
251bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        logger.Log('Could not find instrumentation declarations in %s at %s' %
252bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot                   (android_manifest.AndroidManifest.FILENAME,
253bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot                    self.GetBuildPath()))
254bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        return tests
255bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
256bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      for instr_name in manifest_parser.GetInstrumentationNames():
257bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        pkg_name = manifest_parser.GetPackageName()
258bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        if instr_name.find(".") < 0:
259bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot          instr_name = "." + instr_name
260bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        logger.SilentLog('Found instrumentation %s/%s' % (pkg_name, instr_name))
261bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        suite = InstrumentationTestSuite()
262bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        suite.SetPackageName(pkg_name)
263bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        suite.SetBuildPath(self.GetBuildPath())
264bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        suite.SetRunnerName(instr_name)
265bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        suite.SetName(pkg_name)
266bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        suite.SetClassName(class_name_arg)
267bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        suite.SetJavaPackageFilter(java_package_name)
268bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        # this is a bit of a hack, assume if 'com.android.cts' is in
269bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        # package name, this is a cts test
270bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        # this logic can be removed altogether when cts tests no longer require
271bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        # custom build steps
272bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        if suite.GetPackageName().startswith('com.android.cts'):
273bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot          suite.SetSuite('cts')
274bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        tests.append(suite)
275bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      return tests
276bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
277bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    except:
278bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      logger.Log('Could not find or parse %s at %s' %
279bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot                 (android_manifest.AndroidManifest.FILENAME,
280bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot                  self.GetBuildPath()))
281bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    return tests
282bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
283bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot  def _IsJavaFile(self, path):
284bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """Returns true if given file system path is a java file."""
285bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    return os.path.isfile(path) and self._IsJavaFileName(path)
286bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
287bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot  def _IsJavaFileName(self, filename):
288bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """Returns true if given file name is a java file name."""
289bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    return os.path.splitext(filename)[1] == '.java'
290bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
291bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot  def _IsJavaPackage(self, path):
292bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """Returns true if given file path is a java package.
293bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
294bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Currently assumes if any java file exists in this directory, than it
295bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    represents a java package.
296bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
297bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Args:
298bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      path: file system path of directory to check
299bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
300bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Returns:
301bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      True if path is a java package
302bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """
303bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    if not os.path.isdir(path):
304bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      return False
305bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    for file_name in os.listdir(path):
306bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      if self._IsJavaFileName(file_name):
307bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        return True
308bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    return False
309bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
310bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot  def _GetClassNameFromFile(self, java_file_path):
311bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """Gets the fully qualified java class name from path.
312bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
313bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Args:
314bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      java_file_path: file system path of java file
315bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
316bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Returns:
317bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      fully qualified java class name or None.
318bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """
319bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    package_name = self._GetPackageNameFromFile(java_file_path)
320bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    if package_name:
321bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      filename = os.path.basename(java_file_path)
322bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      class_name = os.path.splitext(filename)[0]
323bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      return '%s.%s' % (package_name, class_name)
324bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    return None
325bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
326bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot  def _GetPackageNameFromDir(self, path):
327bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """Gets the java package name associated with given directory path.
328bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
329bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Caveat: currently just parses defined java package name from first java
330bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    file found in directory.
331bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
332bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Args:
333bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      path: file system path of directory
334bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
335bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Returns:
336bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      the java package name or None
337bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """
338bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    for filename in os.listdir(path):
339bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      if self._IsJavaFileName(filename):
340bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        return self._GetPackageNameFromFile(os.path.join(path, filename))
341bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
342bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot  def _GetPackageNameFromFile(self, java_file_path):
343bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """Gets the java package name associated with given java file path.
344bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
345bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Args:
346bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      java_file_path: file system path of java file
347bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot
348bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    Returns:
349bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      the java package name or None
350bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    """
351bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    logger.SilentLog('Looking for java package name in %s' % java_file_path)
352bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    re_package = re.compile(r'package\s+(.*);')
353bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    file_handle = open(java_file_path, 'r')
354bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    for line in file_handle:
355bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      match = re_package.match(line)
356bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot      if match:
357bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot        return match.group(1)
358bb5918ed814ed8dded262d4558588a7183ca71ceBrett Chabot    return None
359