def _FindSubTests(self, path, tests, build_path=None): """Recursively finds all tests within given path. Args: path: absolute file system path to check tests: current list of found tests build_path: the parent directory where Android.mk was found Returns: updated list of tests """ if not os.path.isdir(path): return tests filenames = os.listdir(path) # Try to build as much of original path as possible, so # keep track of upper-most parent directory where Android.mk was found # this is also necessary in case of overlapping tests # ie if a test exists at 'foo' directory and 'foo/sub', attempting to # build both 'foo' and 'foo/sub' will fail. if not build_path and filenames.count(android_mk.AndroidMK.FILENAME): build_path = self._MakePathRelativeToBuild(path) if filenames.count(android_manifest.AndroidManifest.FILENAME): # found a manifest! now parse it to find the test definition(s) manifest = android_manifest.AndroidManifest(app_path=path) tests.extend(self._CreateSuitesFromManifest(manifest, build_path)) for filename in filenames: self._FindSubTests(os.path.join(path, filename), tests, build_path) return tests
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
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
def _FindUpstreamManifest(self, path): """Recursively searches filesystem upwards for a AndroidManifest file. Args: path: file system path to search Returns: the AndroidManifest found or None """ if (os.path.isdir(path) and os.listdir(path).count( android_manifest.AndroidManifest.FILENAME)): return android_manifest.AndroidManifest(app_path=path) dirpath = os.path.dirname(path) if self._IsPathInBuildTree(path): return self._FindUpstreamManifest(dirpath) logger.Log('AndroidManifest.xml not found') return None
def _FindSubTests(self, path, tests, build_path=None): """Recursively finds all tests within given path. Args: path: absolute file system path to check tests: current list of found tests build_path: the parent directory where Android.mk that builds sub-folders was found Returns: updated list of tests """ if not os.path.isdir(path): return tests filenames = os.listdir(path) if filenames.count(android_manifest.AndroidManifest.FILENAME): # found a manifest! now parse it to find the test definition(s) manifest = android_manifest.AndroidManifest(app_path=path) if not build_path: # haven't found a parent makefile which builds this dir. Use current # dir as build path tests.extend( self._CreateSuitesFromManifest( manifest, self._MakePathRelativeToBuild(path))) else: tests.extend( self._CreateSuitesFromManifest(manifest, build_path)) # Try to build as much of original path as possible, so # keep track of upper-most parent directory where Android.mk was found that # has rule to build sub-directory makefiles # this is also necessary in case of overlapping tests # ie if a test exists at 'foo' directory and 'foo/sub', attempting to # build both 'foo' and 'foo/sub' will fail. if filenames.count(android_mk.AndroidMK.FILENAME): android_mk_parser = android_mk.AndroidMK(app_path=path) if android_mk_parser.HasInclude( 'call all-makefiles-under,$(LOCAL_PATH)'): # found rule to build sub-directories. The parent path can be used, # or if not set, use current path if not build_path: build_path = self._MakePathRelativeToBuild(path) else: build_path = None for filename in filenames: self._FindSubTests(os.path.join(path, filename), tests, build_path) return tests
def main(argv): options, args = _ParseArgs(argv) app_path = args[0]; if not os.path.exists(app_path): _PrintError("Error: Application path %s not found" % app_path) sys.exit() try: mk = android_mk.CreateAndroidMK(path=app_path) manifest = android_manifest.AndroidManifest(app_path=app_path) _ValidateInputFiles(mk, manifest) module_name = mk.GetVariable(mk.PACKAGE_NAME) _GenerateTestMK(mk, app_path) _GenerateTestManifest(manifest, module_name) except Exception, e: _PrintError("Error: %s" % e) _PrintError("Error encountered, script aborted") sys.exit()