Add gtest target support for runtest --path.
This is a rough initial version. It makes several assumptions: - assumes each test source file is built into module with name equal to basename of source file - assumes tests get installed into /data/nativetest However, given those assumptions, both: $ runtest --path <path to directory containing gtest source> and $ runtest --path <path to single source file> should work. Coming soon: gtest host support Bugs 4563370, 4584339 Change-Id: Ia42aeed7f9ee6402b0ceb7b5ccaaa66ac636fe49
This commit is contained in:
@@ -263,8 +263,10 @@ class AdbInterface:
|
|||||||
inst_command_string = self._BuildInstrumentationCommand(
|
inst_command_string = self._BuildInstrumentationCommand(
|
||||||
package_name, runner_name, no_window_animation=no_window_animation,
|
package_name, runner_name, no_window_animation=no_window_animation,
|
||||||
raw_mode=raw_mode, instrumentation_args=instrumentation_args)
|
raw_mode=raw_mode, instrumentation_args=instrumentation_args)
|
||||||
command_string = "adb %s shell %s" % (self._target_arg, inst_command_string)
|
return self.PreviewShellCommand(inst_command_string)
|
||||||
return command_string
|
|
||||||
|
def PreviewShellCommand(self, cmd):
|
||||||
|
return "adb %s shell %s" % (self._target_arg, cmd)
|
||||||
|
|
||||||
def _BuildInstrumentationCommand(
|
def _BuildInstrumentationCommand(
|
||||||
self, package, runner_name, no_window_animation=False, profile=False,
|
self, package, runner_name, no_window_animation=False, profile=False,
|
||||||
|
|||||||
@@ -21,25 +21,26 @@ Specifications for Android.mk can be found at
|
|||||||
development/ndk/docs/ANDROID-MK.txt
|
development/ndk/docs/ANDROID-MK.txt
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
from sets import Set
|
from sets import Set
|
||||||
|
|
||||||
|
import logger
|
||||||
|
|
||||||
class AndroidMK(object):
|
class AndroidMK(object):
|
||||||
"""In memory representation of Android.mk file."""
|
"""In memory representation of Android.mk file."""
|
||||||
|
|
||||||
_RE_INCLUDE = re.compile(r'include\s+\$\((.+)\)')
|
_RE_INCLUDE = re.compile(r'include\s+\$\((.+)\)')
|
||||||
|
_RE_VARIABLE_REF = re.compile(r'\$\((.+)\)')
|
||||||
_VAR_DELIMITER = ":="
|
_VAR_DELIMITER = ":="
|
||||||
FILENAME = "Android.mk"
|
FILENAME = "Android.mk"
|
||||||
CERTIFICATE = "LOCAL_CERTIFICATE"
|
CERTIFICATE = "LOCAL_CERTIFICATE"
|
||||||
PACKAGE_NAME = "LOCAL_PACKAGE_NAME"
|
PACKAGE_NAME = "LOCAL_PACKAGE_NAME"
|
||||||
|
|
||||||
def __init__(self, app_path=None):
|
def __init__(self):
|
||||||
self._includes = Set() # variables included in makefile
|
self._includes = Set() # variables included in makefile
|
||||||
self._variables = {} # variables defined in makefile
|
self._variables = {} # variables defined in makefile
|
||||||
|
self._has_gtestlib = False
|
||||||
if app_path:
|
|
||||||
self.ParseMK(app_path)
|
|
||||||
|
|
||||||
def _ProcessMKLine(self, line):
|
def _ProcessMKLine(self, line):
|
||||||
"""Add a variable definition or include.
|
"""Add a variable definition or include.
|
||||||
@@ -56,6 +57,9 @@ class AndroidMK(object):
|
|||||||
parts = line.split(self._VAR_DELIMITER)
|
parts = line.split(self._VAR_DELIMITER)
|
||||||
if len(parts) > 1:
|
if len(parts) > 1:
|
||||||
self._variables[parts[0].strip()] = parts[1].strip()
|
self._variables[parts[0].strip()] = parts[1].strip()
|
||||||
|
# hack, look for explicit mention of libgtest_main
|
||||||
|
if line.find('libgtest_main') != -1:
|
||||||
|
self._has_gtestlib = True
|
||||||
|
|
||||||
def GetVariable(self, identifier):
|
def GetVariable(self, identifier):
|
||||||
"""Retrieve makefile variable.
|
"""Retrieve makefile variable.
|
||||||
@@ -69,6 +73,38 @@ class AndroidMK(object):
|
|||||||
# so None is returned if identifier not found
|
# so None is returned if identifier not found
|
||||||
return self._variables.get(identifier, None)
|
return self._variables.get(identifier, None)
|
||||||
|
|
||||||
|
def GetExpandedVariable(self, identifier):
|
||||||
|
"""Retrieve makefile variable.
|
||||||
|
|
||||||
|
If variable value refers to another variable, recursively expand it to
|
||||||
|
find its literal value
|
||||||
|
|
||||||
|
Args:
|
||||||
|
identifier: name of variable to retrieve
|
||||||
|
Returns:
|
||||||
|
value of specified identifier, None if identifier not found in makefile
|
||||||
|
"""
|
||||||
|
# use dict.get(x) rather than dict[x] to avoid KeyError exception,
|
||||||
|
# so None is returned if identifier not found
|
||||||
|
return self.__RecursiveGetVariable(identifier, Set())
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
def HasInclude(self, identifier):
|
def HasInclude(self, identifier):
|
||||||
"""Check variable is included in makefile.
|
"""Check variable is included in makefile.
|
||||||
|
|
||||||
@@ -79,18 +115,57 @@ class AndroidMK(object):
|
|||||||
"""
|
"""
|
||||||
return identifier in self._includes
|
return identifier in self._includes
|
||||||
|
|
||||||
def ParseMK(self, app_path):
|
def HasJavaLibrary(self, library_name):
|
||||||
|
"""Check if library is specified as a local java library in makefile.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
library_name: name of library to check
|
||||||
|
Returns:
|
||||||
|
True if library_name is included in makefile, otherwise False
|
||||||
|
"""
|
||||||
|
java_lib_string = self.GetExpandedVariable('LOCAL_JAVA_LIBRARIES')
|
||||||
|
if java_lib_string:
|
||||||
|
java_libs = java_lib_string.split(' ')
|
||||||
|
return library_name in java_libs
|
||||||
|
return False
|
||||||
|
|
||||||
|
def HasGTest(self):
|
||||||
|
"""Check if makefile includes rule to build a native gtest.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if rule to build native test is in makefile, otherwise False
|
||||||
|
"""
|
||||||
|
return self._has_gtestlib or self.HasInclude('BUILD_NATIVE_TEST')
|
||||||
|
|
||||||
|
def _ParseMK(self, mk_path):
|
||||||
"""Parse Android.mk at the specified path.
|
"""Parse Android.mk at the specified path.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
app_path: path to folder containing Android.mk
|
mk_path: path to Android.mk
|
||||||
Raises:
|
Raises:
|
||||||
IOError: Android.mk cannot be found at given path, or cannot be opened
|
IOError: Android.mk cannot be found at given path, or cannot be opened
|
||||||
for reading
|
for reading
|
||||||
"""
|
"""
|
||||||
self.app_path = app_path.rstrip("/")
|
mk = open(mk_path)
|
||||||
self.mk_path = "%s/%s" % (self.app_path, self.FILENAME)
|
|
||||||
mk = open(self.mk_path)
|
|
||||||
for line in mk:
|
for line in mk:
|
||||||
self._ProcessMKLine(line)
|
self._ProcessMKLine(line)
|
||||||
mk.close()
|
mk.close()
|
||||||
|
|
||||||
|
|
||||||
|
def CreateAndroidMK(path, filename=AndroidMK.FILENAME):
|
||||||
|
"""Factory method for creating a AndroidMK.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: the directory of the make file
|
||||||
|
filename: the filename of the makefile
|
||||||
|
|
||||||
|
Return:
|
||||||
|
the AndroidMK or None if there was no file present
|
||||||
|
"""
|
||||||
|
mk_path = os.path.join(path, filename)
|
||||||
|
if os.path.isfile(mk_path):
|
||||||
|
mk = AndroidMK()
|
||||||
|
mk._ParseMK(mk_path)
|
||||||
|
return mk
|
||||||
|
else:
|
||||||
|
return None
|
||||||
119
testrunner/test_defs/gtest.py
Normal file
119
testrunner/test_defs/gtest.py
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Copyright 2011, 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.
|
||||||
|
|
||||||
|
"""TestSuite for running C/C++ Android tests using gtest framework."""
|
||||||
|
|
||||||
|
# python imports
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
import logger
|
||||||
|
import run_command
|
||||||
|
import test_suite
|
||||||
|
|
||||||
|
|
||||||
|
class GTestSuite(test_suite.AbstractTestSuite):
|
||||||
|
"""A test suite for running gtest on device."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
test_suite.AbstractTestSuite.__init__(self)
|
||||||
|
self._target_exec_path = None
|
||||||
|
|
||||||
|
def GetTargetExecPath(self):
|
||||||
|
"""Get the target path to gtest executable."""
|
||||||
|
return self._target_exec_path
|
||||||
|
|
||||||
|
def SetTargetExecPath(self, path):
|
||||||
|
self._target_exec_path = path
|
||||||
|
return self
|
||||||
|
|
||||||
|
def Run(self, options, adb):
|
||||||
|
"""Run the provided gtest test suite.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
options: command line options
|
||||||
|
adb: adb interface
|
||||||
|
"""
|
||||||
|
shell_cmd = adb.PreviewShellCommand(self.GetTargetExecPath())
|
||||||
|
logger.Log(shell_cmd)
|
||||||
|
if not options.preview:
|
||||||
|
# gtest will log to test results to stdout, so no need to do any
|
||||||
|
# extra processing
|
||||||
|
run_command.RunCommand(shell_cmd, return_output=False)
|
||||||
|
|
||||||
|
|
||||||
|
class GTestFactory(test_suite.AbstractTestFactory):
|
||||||
|
|
||||||
|
def __init__(self, test_root_path, upstream_build_path=None):
|
||||||
|
test_suite.AbstractTestFactory.__init__(self, test_root_path,
|
||||||
|
upstream_build_path=upstream_build_path)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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:
|
||||||
|
self._EvaluateFile(test_list, f)
|
||||||
|
|
||||||
|
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_", name):
|
||||||
|
logger.SilentLog("Found native test file %s" % file)
|
||||||
|
test_list.append(name)
|
||||||
@@ -17,7 +17,11 @@
|
|||||||
|
|
||||||
"""TestSuite definition for Android instrumentation tests."""
|
"""TestSuite definition for Android instrumentation tests."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
|
import android_manifest
|
||||||
import coverage
|
import coverage
|
||||||
import errors
|
import errors
|
||||||
import logger
|
import logger
|
||||||
@@ -193,3 +197,143 @@ class InstrumentationTestSuite(test_suite.AbstractTestSuite):
|
|||||||
total_count+=1
|
total_count+=1
|
||||||
logger.Log("Tests run: %d, Failures: %d, Errors: %d" %
|
logger.Log("Tests run: %d, Failures: %d, Errors: %d" %
|
||||||
(total_count, fail_count, error_count))
|
(total_count, fail_count, error_count))
|
||||||
|
|
||||||
|
|
||||||
|
class InstrumentationTestFactory(test_suite.AbstractTestFactory):
|
||||||
|
"""A factory for creating InstrumentationTestSuites"""
|
||||||
|
|
||||||
|
def __init__(self, test_root_path, upstream_build_path=None):
|
||||||
|
test_suite.AbstractTestFactory.__init__(self, test_root_path,
|
||||||
|
upstream_build_path=upstream_build_path)
|
||||||
|
|
||||||
|
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 _IsJavaFile(self, path):
|
||||||
|
"""Returns true if given file system path is a java file."""
|
||||||
|
return os.path.isfile(path) and self._IsJavaFileName(path)
|
||||||
|
|
||||||
|
def _IsJavaFileName(self, filename):
|
||||||
|
"""Returns true if given file name is a java file name."""
|
||||||
|
return os.path.splitext(filename)[1] == '.java'
|
||||||
|
|
||||||
|
def _IsJavaPackage(self, path):
|
||||||
|
"""Returns true if given file path is a java package.
|
||||||
|
|
||||||
|
Currently assumes if any java file exists in this directory, than it
|
||||||
|
represents a java package.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: file system path of directory to check
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if path is a java package
|
||||||
|
"""
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
return False
|
||||||
|
for file_name in os.listdir(path):
|
||||||
|
if self._IsJavaFileName(file_name):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _GetClassNameFromFile(self, java_file_path):
|
||||||
|
"""Gets the fully qualified java class name from path.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
java_file_path: file system path of java file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
fully qualified java class name or None.
|
||||||
|
"""
|
||||||
|
package_name = self._GetPackageNameFromFile(java_file_path)
|
||||||
|
if package_name:
|
||||||
|
filename = os.path.basename(java_file_path)
|
||||||
|
class_name = os.path.splitext(filename)[0]
|
||||||
|
return '%s.%s' % (package_name, class_name)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _GetPackageNameFromDir(self, path):
|
||||||
|
"""Gets the java package name associated with given directory path.
|
||||||
|
|
||||||
|
Caveat: currently just parses defined java package name from first java
|
||||||
|
file found in directory.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: file system path of directory
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
the java package name or None
|
||||||
|
"""
|
||||||
|
for filename in os.listdir(path):
|
||||||
|
if self._IsJavaFileName(filename):
|
||||||
|
return self._GetPackageNameFromFile(os.path.join(path, filename))
|
||||||
|
|
||||||
|
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
|
||||||
|
|||||||
@@ -105,3 +105,41 @@ class AbstractTestSuite(object):
|
|||||||
adb: asdb_interface to device under test
|
adb: asdb_interface to device under test
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
class AbstractTestFactory(object):
|
||||||
|
"""generic test suite factory."""
|
||||||
|
|
||||||
|
def __init__(self, test_root_path, upstream_build_path=None):
|
||||||
|
"""Creates a test suite factory.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
test_root_path: the filesystem path to the tests build directory
|
||||||
|
upstream_build_path: optional filesystem path for the directory
|
||||||
|
to build when running tests. If unspecified, will use test_root_path
|
||||||
|
"""
|
||||||
|
self._test_root_path = test_root_path
|
||||||
|
if upstream_build_path:
|
||||||
|
self._build_path = upstream_build_path
|
||||||
|
else:
|
||||||
|
self._build_path = self._test_root_path
|
||||||
|
|
||||||
|
def GetBuildPath(self):
|
||||||
|
return self._build_path
|
||||||
|
|
||||||
|
def GetTestsRootPath(self):
|
||||||
|
return self._test_root_path
|
||||||
|
|
||||||
|
def CreateTests(self, sub_tests_path=None):
|
||||||
|
"""Creates the tests at given test_path.
|
||||||
|
|
||||||
|
Subclasses must implement this.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sub_tests_path: the child path of test_root_path containing the tests to
|
||||||
|
run. If unspecified will be set to test_root_path.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
an array of AbstractTestSuite, or empty AbstractTestSuite if no tests
|
||||||
|
were defined
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|||||||
@@ -19,27 +19,31 @@
|
|||||||
|
|
||||||
# python imports
|
# python imports
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
import android_build
|
import android_build
|
||||||
import android_manifest
|
|
||||||
import android_mk
|
import android_mk
|
||||||
|
import gtest
|
||||||
import instrumentation_test
|
import instrumentation_test
|
||||||
import logger
|
import logger
|
||||||
|
|
||||||
|
|
||||||
class TestWalker(object):
|
class TestWalker(object):
|
||||||
"""Finds instrumentation tests from filesystem."""
|
"""Finds Android tests from filesystem."""
|
||||||
|
|
||||||
def FindTests(self, path):
|
def FindTests(self, path):
|
||||||
"""Gets list of Android instrumentation tests found at given path.
|
"""Gets list of Android tests found at given path.
|
||||||
|
|
||||||
Tests are created from the <instrumentation> tags found in
|
Tests are created from info found in Android.mk and AndroidManifest.xml
|
||||||
AndroidManifest.xml files relative to the given path.
|
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,
|
FindTests will first scan sub-folders of path for tests. If none are found,
|
||||||
it will scan the file system upwards until a AndroidManifest.xml is found
|
it will scan the file system upwards until a valid test Android.mk is found
|
||||||
or the Android build root is reached.
|
or the Android build root is reached.
|
||||||
|
|
||||||
Some sample values for path:
|
Some sample values for path:
|
||||||
@@ -55,6 +59,8 @@ class TestWalker(object):
|
|||||||
the instrumentation in ApiDemos/tests, with the java package filter set
|
the instrumentation in ApiDemos/tests, with the java package filter set
|
||||||
to com.example.android.apis.
|
to com.example.android.apis.
|
||||||
|
|
||||||
|
TODO: add GTest examples
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
path: file system path to search
|
path: file system path to search
|
||||||
|
|
||||||
@@ -110,204 +116,143 @@ class TestWalker(object):
|
|||||||
# return string with common build_path removed
|
# return string with common build_path removed
|
||||||
return path[build_path_len:]
|
return path[build_path_len:]
|
||||||
|
|
||||||
def _FindSubTests(self, path, tests, build_path=None):
|
def _FindSubTests(self, path, tests, upstream_build_path=None):
|
||||||
"""Recursively finds all tests within given path.
|
"""Recursively finds all tests within given path.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
path: absolute file system path to check
|
path: absolute file system path to check
|
||||||
tests: current list of found tests
|
tests: current list of found tests
|
||||||
build_path: the parent directory where Android.mk that builds sub-folders
|
upstream_build_path: the parent directory where Android.mk that builds
|
||||||
was found
|
sub-folders was found
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
updated list of tests
|
updated list of tests
|
||||||
"""
|
"""
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
return tests
|
return tests
|
||||||
filenames = os.listdir(path)
|
android_mk_parser = android_mk.CreateAndroidMK(path)
|
||||||
if filenames.count(android_manifest.AndroidManifest.FILENAME):
|
if android_mk_parser:
|
||||||
# found a manifest! now parse it to find the test definition(s)
|
if not upstream_build_path:
|
||||||
manifest = android_manifest.AndroidManifest(app_path=path)
|
|
||||||
if not build_path:
|
|
||||||
# haven't found a parent makefile which builds this dir. Use current
|
# haven't found a parent makefile which builds this dir. Use current
|
||||||
# dir as build path
|
# dir as build path
|
||||||
tests.extend(self._CreateSuitesFromManifest(
|
tests.extend(self._CreateSuites(
|
||||||
manifest, self._MakePathRelativeToBuild(path)))
|
android_mk_parser, path, self._MakePathRelativeToBuild(path)))
|
||||||
else:
|
else:
|
||||||
tests.extend(self._CreateSuitesFromManifest(manifest, build_path))
|
tests.extend(self._CreateSuites(android_mk_parser, path,
|
||||||
# Try to build as much of original path as possible, so
|
upstream_build_path))
|
||||||
# keep track of upper-most parent directory where Android.mk was found that
|
# Try to build as much of original path as possible, so
|
||||||
# has rule to build sub-directory makefiles
|
# keep track of upper-most parent directory where Android.mk was found
|
||||||
# this is also necessary in case of overlapping tests
|
# that has rule to build sub-directory makefiles.
|
||||||
# ie if a test exists at 'foo' directory and 'foo/sub', attempting to
|
# this is also necessary in case of overlapping tests
|
||||||
# build both 'foo' and 'foo/sub' will fail.
|
# ie if a test exists at 'foo' directory and 'foo/sub', attempting to
|
||||||
if filenames.count(android_mk.AndroidMK.FILENAME):
|
# build both 'foo' and 'foo/sub' will fail.
|
||||||
android_mk_parser = android_mk.AndroidMK(app_path=path)
|
|
||||||
if android_mk_parser.HasInclude('call all-makefiles-under,$(LOCAL_PATH)'):
|
if android_mk_parser.HasInclude('call all-makefiles-under,$(LOCAL_PATH)'):
|
||||||
# found rule to build sub-directories. The parent path can be used,
|
# found rule to build sub-directories. The parent path can be used,
|
||||||
# or if not set, use current path
|
# or if not set, use current path
|
||||||
if not build_path:
|
if not upstream_build_path:
|
||||||
build_path = self._MakePathRelativeToBuild(path)
|
upstream_build_path = self._MakePathRelativeToBuild(path)
|
||||||
else:
|
else:
|
||||||
build_path = None
|
upstream_build_path = None
|
||||||
for filename in filenames:
|
for filename in os.listdir(path):
|
||||||
self._FindSubTests(os.path.join(path, filename), tests, build_path)
|
self._FindSubTests(os.path.join(path, filename), tests,
|
||||||
|
upstream_build_path)
|
||||||
return tests
|
return tests
|
||||||
|
|
||||||
def _FindUpstreamTests(self, path):
|
def _FindUpstreamTests(self, path):
|
||||||
"""Find tests defined upward from given path.
|
"""Find tests defined upward from given path.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
path: the location to start searching. If it points to a java class file
|
path: the location to start searching.
|
||||||
or java package dir, the appropriate test suite filters will be set
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list of test_suite.AbstractTestSuite found, may be empty
|
list of test_suite.AbstractTestSuite found, may be empty
|
||||||
"""
|
"""
|
||||||
class_name_arg = None
|
factory = self._FindUpstreamTestFactory(path)
|
||||||
package_name = None
|
if factory:
|
||||||
# if path is java file, populate class name
|
return factory.CreateTests(sub_tests_path=path)
|
||||||
if self._IsJavaFile(path):
|
else:
|
||||||
class_name_arg = self._GetClassNameFromFile(path)
|
return []
|
||||||
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)
|
|
||||||
|
|
||||||
def _IsJavaFile(self, path):
|
def _GetTestFactory(self, android_mk_parser, path, upstream_build_path=None):
|
||||||
"""Returns true if given file system path is a java file."""
|
"""Get the test factory for given makefile.
|
||||||
return os.path.isfile(path) and self._IsJavaFileName(path)
|
|
||||||
|
|
||||||
def _IsJavaFileName(self, filename):
|
If given path is a valid tests build path, will return the TestFactory
|
||||||
"""Returns true if given file name is a java file name."""
|
for creating tests.
|
||||||
return os.path.splitext(filename)[1] == '.java'
|
|
||||||
|
|
||||||
def _IsJavaPackage(self, path):
|
|
||||||
"""Returns true if given file path is a java package.
|
|
||||||
|
|
||||||
Currently assumes if any java file exists in this directory, than it
|
|
||||||
represents a java package.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
path: file system path of directory to check
|
android_mk_parser: the android mk to evaluate
|
||||||
|
path: the filesystem path of the makefile
|
||||||
|
upstream_build_path: optional filesystem path for the directory
|
||||||
|
to build when running tests. If unspecified, will use path
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if path is a java package
|
the TestFactory or None if path is not a valid tests build path
|
||||||
"""
|
"""
|
||||||
if not os.path.isdir(path):
|
if android_mk_parser.HasGTest():
|
||||||
return False
|
return gtest.GTestFactory(path, upstream_build_path=upstream_build_path)
|
||||||
for file_name in os.listdir(path):
|
elif android_mk_parser.HasJavaLibrary('android.test.runner'):
|
||||||
if self._IsJavaFileName(file_name):
|
return instrumentation_test.InstrumentationTestFactory(path,
|
||||||
return True
|
upstream_build_path=upstream_build_path)
|
||||||
return False
|
else:
|
||||||
|
# somewhat unusual, but will continue searching
|
||||||
|
logger.SilentLog('Found makefile at %s, but did not detect any tests.'
|
||||||
|
% path)
|
||||||
|
|
||||||
def _GetClassNameFromFile(self, java_file_path):
|
|
||||||
"""Gets the fully qualified java class name from path.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
java_file_path: file system path of java file
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
fully qualified java class name or None.
|
|
||||||
"""
|
|
||||||
package_name = self._GetPackageNameFromFile(java_file_path)
|
|
||||||
if package_name:
|
|
||||||
filename = os.path.basename(java_file_path)
|
|
||||||
class_name = os.path.splitext(filename)[0]
|
|
||||||
return '%s.%s' % (package_name, class_name)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _GetPackageNameFromDir(self, path):
|
def _GetTestFactoryForPath(self, path):
|
||||||
"""Gets the java package name associated with given directory path.
|
"""Get the test factory for given path.
|
||||||
|
|
||||||
Caveat: currently just parses defined java package name from first java
|
If given path is a valid tests build path, will return the TestFactory
|
||||||
file found in directory.
|
for creating tests.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
path: file system path of directory
|
path: the filesystem path to evaluate
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
the java package name or None
|
the TestFactory or None if path is not a valid tests build path
|
||||||
"""
|
"""
|
||||||
for filename in os.listdir(path):
|
android_mk_parser = android_mk.CreateAndroidMK(path)
|
||||||
if self._IsJavaFileName(filename):
|
if android_mk_parser:
|
||||||
return self._GetPackageNameFromFile(os.path.join(path, filename))
|
return self._GetTestFactory(android_mk_parser, path)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def _GetPackageNameFromFile(self, java_file_path):
|
def _FindUpstreamTestFactory(self, path):
|
||||||
"""Gets the java package name associated with given java file path.
|
"""Recursively searches filesystem upwards for a test factory.
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def _FindUpstreamManifest(self, path):
|
|
||||||
"""Recursively searches filesystem upwards for a AndroidManifest file.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
path: file system path to search
|
path: file system path to search
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
the AndroidManifest found or None
|
the TestFactory found or None
|
||||||
"""
|
"""
|
||||||
if (os.path.isdir(path) and
|
factory = self._GetTestFactoryForPath(path)
|
||||||
os.listdir(path).count(android_manifest.AndroidManifest.FILENAME)):
|
if factory:
|
||||||
return android_manifest.AndroidManifest(app_path=path)
|
return factory
|
||||||
dirpath = os.path.dirname(path)
|
dirpath = os.path.dirname(path)
|
||||||
if self._IsPathInBuildTree(path):
|
if self._IsPathInBuildTree(path):
|
||||||
return self._FindUpstreamManifest(dirpath)
|
return self._FindUpstreamTestFactory(dirpath)
|
||||||
logger.Log('AndroidManifest.xml not found')
|
logger.Log('A tests Android.mk was not found')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _CreateSuitesFromManifest(self, manifest, build_path, class_name=None,
|
def _CreateSuites(self, android_mk_parser, path, upstream_build_path):
|
||||||
java_package_name=None):
|
"""Creates TestSuites from a AndroidMK.
|
||||||
"""Creates TestSuites from a AndroidManifest.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
manifest: the AndroidManifest
|
android_mk_parser: the AndroidMK
|
||||||
build_path: the build path to use for test
|
path: absolute file system path of the makefile to evaluate
|
||||||
class_name: optionally, the class filter for the suite
|
upstream_build_path: the build path to use for test. This can be
|
||||||
java_package_name: optionally, the java package filter for the suite
|
different than the 'path', in cases where an upstream makefile
|
||||||
|
is being used.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
the list of tests created
|
the list of tests created
|
||||||
"""
|
"""
|
||||||
tests = []
|
factory = self._GetTestFactory(android_mk_parser, path,
|
||||||
for instr_name in manifest.GetInstrumentationNames():
|
upstream_build_path=upstream_build_path)
|
||||||
pkg_name = manifest.GetPackageName()
|
if factory:
|
||||||
if instr_name.find(".") < 0:
|
return factory.CreateTests(path)
|
||||||
instr_name = "." + instr_name
|
else:
|
||||||
logger.SilentLog('Found instrumentation %s/%s' % (pkg_name, instr_name))
|
return []
|
||||||
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
|
|
||||||
if suite.GetPackageName().startswith('com.android.cts'):
|
|
||||||
suite.SetSuite('cts')
|
|
||||||
tests.append(suite)
|
|
||||||
return tests
|
|
||||||
|
|||||||
56
testrunner/tests/Android_gtestlib.mk
Normal file
56
testrunner/tests/Android_gtestlib.mk
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# Copyright (C) 2011 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.
|
||||||
|
|
||||||
|
# Build the unit tests.
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
ifneq ($(TARGET_SIMULATOR),true)
|
||||||
|
|
||||||
|
# Build the unit tests.
|
||||||
|
test_src_files := $(call find-subdir-files, *.cpp)
|
||||||
|
|
||||||
|
shared_libraries := \
|
||||||
|
libz \
|
||||||
|
liblog \
|
||||||
|
libcutils \
|
||||||
|
libutils \
|
||||||
|
libstlport
|
||||||
|
|
||||||
|
static_libraries := \
|
||||||
|
libgtest \
|
||||||
|
libgtest_main
|
||||||
|
|
||||||
|
c_includes := \
|
||||||
|
external/zlib \
|
||||||
|
external/icu4c/common \
|
||||||
|
bionic \
|
||||||
|
bionic/libstdc++/include \
|
||||||
|
external/gtest/include \
|
||||||
|
external/stlport/stlport
|
||||||
|
|
||||||
|
module_tags := eng tests
|
||||||
|
|
||||||
|
$(foreach file,$(test_src_files), \
|
||||||
|
$(eval include $(CLEAR_VARS)) \
|
||||||
|
$(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
|
||||||
|
$(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
|
||||||
|
$(eval LOCAL_C_INCLUDES := $(c_includes)) \
|
||||||
|
$(eval LOCAL_SRC_FILES := $(file)) \
|
||||||
|
$(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
|
||||||
|
$(eval LOCAL_MODULE_TAGS := $(module_tags)) \
|
||||||
|
$(eval include $(BUILD_EXECUTABLE)) \
|
||||||
|
)
|
||||||
|
|
||||||
|
endif
|
||||||
26
testrunner/tests/Android_java.mk
Normal file
26
testrunner/tests/Android_java.mk
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Copyright (C) 2011 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.
|
||||||
|
|
||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
# We only want this apk build for tests.
|
||||||
|
LOCAL_MODULE_TAGS := tests
|
||||||
|
LOCAL_JAVA_LIBRARIES := foo android.test.runner
|
||||||
|
# Include all test java files.
|
||||||
|
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||||
|
LOCAL_PACKAGE_NAME := ApiDemosTests
|
||||||
|
LOCAL_INSTRUMENTATION_FOR := ApiDemos
|
||||||
|
LOCAL_SDK_VERSION := current
|
||||||
|
|
||||||
|
include $(BUILD_PACKAGE)
|
||||||
21
testrunner/tests/Android_native.mk
Normal file
21
testrunner/tests/Android_native.mk
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (C) 2011 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.
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
test_module := foo
|
||||||
|
LOCAL_MODULE := $(test_module)
|
||||||
|
recursive_var := $(recursive_var)
|
||||||
|
LOCAL_MODULE_TAGS := tags
|
||||||
|
LOCAL_SRC_FILES := src
|
||||||
|
include $(BUILD_NATIVE_TEST)
|
||||||
90
testrunner/tests/android_mk_tests.py
Executable file
90
testrunner/tests/android_mk_tests.py
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Copyright 2011, 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.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
sys.path.append('../..')
|
||||||
|
|
||||||
|
from testrunner import android_mk
|
||||||
|
|
||||||
|
|
||||||
|
class AndroidMKTest(unittest.TestCase):
|
||||||
|
"""Unit tests for AndroidMK."""
|
||||||
|
|
||||||
|
def testHasGTest(self):
|
||||||
|
"""Test for AndroidMK.HasGTest."""
|
||||||
|
mk_parser = android_mk.CreateAndroidMK(path='.',
|
||||||
|
filename='Android_native.mk')
|
||||||
|
self.assertTrue(mk_parser.HasGTest())
|
||||||
|
|
||||||
|
def testHasGTest_lib(self):
|
||||||
|
"""Test for AndroidMK.HasGTest."""
|
||||||
|
mk_parser = android_mk.CreateAndroidMK(path='.',
|
||||||
|
filename='Android_gtestlib.mk')
|
||||||
|
self.assertTrue(mk_parser.HasGTest())
|
||||||
|
|
||||||
|
def testHasGTest_false(self):
|
||||||
|
"""Negative test for AndroidMK.HasGTest."""
|
||||||
|
mk_parser = android_mk.CreateAndroidMK(path='.', filename='Android_java.mk')
|
||||||
|
self.assertFalse(mk_parser.HasGTest())
|
||||||
|
|
||||||
|
def testHasJavaLibrary(self):
|
||||||
|
"""Test for AndroidMK.HasJavaLibrary."""
|
||||||
|
mk_parser = android_mk.CreateAndroidMK(path='.',
|
||||||
|
filename='Android_java.mk')
|
||||||
|
self.assertTrue(mk_parser.HasJavaLibrary('android.test.runner'))
|
||||||
|
|
||||||
|
def testHasJavaLibrary_missing(self):
|
||||||
|
"""Negative test for AndroidMK.HasJavaLibrary.
|
||||||
|
|
||||||
|
Test behavior when LOCAL_JAVA_LIBARIES rule is not present in makefile.
|
||||||
|
"""
|
||||||
|
mk_parser = android_mk.CreateAndroidMK(path='.',
|
||||||
|
filename='Android_native.mk')
|
||||||
|
self.assertFalse(mk_parser.HasJavaLibrary('android.test.runner'))
|
||||||
|
|
||||||
|
def testHasJavaLibrary_false(self):
|
||||||
|
"""Negative test for AndroidMK.HasJavaLibrary.
|
||||||
|
|
||||||
|
Test behavior when LOCAL_JAVA_LIBARIES rule is present, but does not list
|
||||||
|
given library.
|
||||||
|
"""
|
||||||
|
mk_parser = android_mk.CreateAndroidMK(path='.', filename='Android_java.mk')
|
||||||
|
self.assertFalse(mk_parser.HasJavaLibrary('doesntexist'))
|
||||||
|
|
||||||
|
def testGetExpandedVariable(self):
|
||||||
|
"""Test for AndroidMK.GetExpandedVariable.
|
||||||
|
"""
|
||||||
|
mk_parser = android_mk.CreateAndroidMK(path='.',
|
||||||
|
filename='Android_native.mk')
|
||||||
|
self.assertEquals('foo', mk_parser.GetExpandedVariable('LOCAL_MODULE'))
|
||||||
|
|
||||||
|
def testGetExpandedVariable_loop(self):
|
||||||
|
"""Test for AndroidMK.GetExpandedVariable where variable expansion loops
|
||||||
|
"""
|
||||||
|
mk_parser = android_mk.CreateAndroidMK(path='.',
|
||||||
|
filename='Android_native.mk')
|
||||||
|
try:
|
||||||
|
mk_parser.GetExpandedVariable('recursive_var')
|
||||||
|
self.assertTrue(False)
|
||||||
|
except RuntimeError:
|
||||||
|
# expected
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user