"in test_defs.xml?" % instrumentation_path)
raise errors.WaitForResponseTimedOutError()
- def Sync(self, retry_count=3):
+ def WaitForBootComplete(self, wait_time=120):
+ """Waits for targeted device's bootcomplete flag to be set.
+
+ Args:
+ wait_time: time in seconds to wait
+
+ Raises:
+ WaitForResponseTimedOutError if wait_time elapses and pm still does not
+ respond.
+ """
+ logger.Log("Waiting for boot complete...")
+ self.SendCommand("wait-for-device")
+ # Now the device is there, but may not be running.
+ # Query the package manager with a basic command
+ boot_complete = False
+ attempts = 0
+ wait_period = 5
+ while not boot_complete and (attempts*wait_period) < wait_time:
+ output = self.SendShellCommand("getprop dev.bootcomplete", retry_count=1)
+ output = output.strip()
+ if output == "1":
+ boot_complete = True
+ else:
+ time.sleep(wait_period)
+ attempts += 1
+ if not boot_complete:
+ raise errors.WaitForResponseTimedOutError(
+ "dev.bootcomplete flag was not set after %s seconds" % wait_time)
+
+ def Sync(self, retry_count=3, runtime_restart=False):
"""Perform a adb sync.
Blocks until device package manager is responding.
Args:
retry_count: number of times to retry sync before failing
+ runtime_restart: stop runtime during sync and restart afterwards, useful
+ for syncing system libraries (core, framework etc)
Raises:
WaitForResponseTimedOutError if package manager does not respond
"""
output = ""
error = None
+ if runtime_restart:
+ self.SendShellCommand("setprop ro.monkey 1", retry_count=retry_count)
+ # manual rest bootcomplete flag
+ self.SendShellCommand("setprop dev.bootcomplete 0",
+ retry_count=retry_count)
+ self.SendShellCommand("stop", retry_count=retry_count)
+
try:
output = self.SendCommand("sync", retry_count=retry_count)
except errors.AbortError, e:
# exception occurred that cannot be recovered from
raise error
logger.SilentLog(output)
- self.WaitForDevicePm()
+ if runtime_restart:
+ # start runtime and wait till boot complete flag is set
+ self.SendShellCommand("start", retry_count=retry_count)
+ self.WaitForBootComplete()
+ # press the MENU key, this will disable key guard if runtime is started
+ # with ro.monkey set to 1
+ self.SendShellCommand("input keyevent 82", retry_count=retry_count)
+ else:
+ self.WaitForDevicePm()
return output
def GetSerialNumber(self):
"""Returns the serial number of the targeted device."""
return self.SendCommand("get-serialno").strip()
-
self._adb = adb_interface
self._targets_manifest = self._ReadTargets()
- def TestDeviceCoverageSupport(self):
- """Check if device has support for generating code coverage metrics.
-
- Currently this will check if the emma.jar file is on the device's boot
- classpath.
-
- Returns:
- True if device can support code coverage. False otherwise.
- """
- try:
- output = self._adb.SendShellCommand("cat init.rc | grep BOOTCLASSPATH | "
- "grep emma.jar")
- if len(output) > 0:
- return True
- except errors.AbortError:
- pass
- logger.Log("Error: Targeted device does not have emma.jar on its "
- "BOOTCLASSPATH.")
- logger.Log("Modify the BOOTCLASSPATH entry in system/core/rootdir/init.rc"
- " to add emma.jar")
- return False
-
def ExtractReport(self, test_suite,
device_coverage_path,
output_path=None,
os.environ["EMMA_INSTRUMENT"] = "true"
+def TestDeviceCoverageSupport(adb):
+ """Check if device has support for generating code coverage metrics.
+
+ This tries to dump emma help information on device, a response containing
+ help information will indicate that emma is already on system class path.
+
+ Returns:
+ True if device can support code coverage. False otherwise.
+ """
+ try:
+ output = adb.SendShellCommand("exec app_process / emma -h")
+
+ if output.find('emma usage:') == 0:
+ return True
+ except errors.AbortError:
+ pass
+ return False
+
+
def Run():
"""Does coverage operations based on command line args."""
# TODO: do we want to support combining coverage for a single target
group.add_option("-s", "--serial", dest="serial",
help="use specific serial")
parser.add_option_group(group)
-
self._options, self._test_args = parser.parse_args()
if (not self._options.only_list_tests
for test_suite in tests:
self._AddBuildTarget(test_suite, target_set, extra_args_set)
+ rebuild_libcore = False
if target_set:
if self._options.coverage:
coverage.EnableCoverageBuild()
+ # hack to remove core library intermediates
+ # hack is needed because:
+ # 1. EMMA_INSTRUMENT changes what source files to include in libcore
+ # but it does not trigger a rebuild
+ # 2. there's no target (like "clear-intermediates") to remove the files
+ # decently
+ rebuild_libcore = not coverage.TestDeviceCoverageSupport(self._adb)
+ if rebuild_libcore:
+ cmd = "rm -rf %s" % os.path.join(
+ self._root_path,
+ "out/target/common/obj/JAVA_LIBRARIES/core_intermediates/")
+ logger.Log(cmd)
+ run_command.RunCommand(cmd, return_output=False)
# hack to build cts dependencies
# TODO: remove this when build dependency support added to runtest or
# run
logger.Log("adb sync")
else:
- run_command.RunCommand(cmd, return_output=False)
+ # set timeout for build to 10 minutes, since libcore may need to
+ # be rebuilt
+ run_command.RunCommand(cmd, return_output=False, timeout_time=600)
logger.Log("Syncing to device...")
- self._adb.Sync()
+ self._adb.Sync(runtime_restart=rebuild_libcore)
def _AddBuildTarget(self, test_suite, target_set, extra_args_set):
build_dir = test_suite.GetBuildPath()
DEFAULT_RUNNER = "android.test.InstrumentationTestRunner"
- # build path to Emma target Makefile
- _EMMA_BUILD_PATH = os.path.join("external", "emma")
+ # dependency on libcore (used for Emma)
+ _LIBCORE_BUILD_PATH = "libcore"
def __init__(self):
test_suite.AbstractTestSuite.__init__(self)
def GetBuildDependencies(self, options):
if options.coverage:
- return [self._EMMA_BUILD_PATH]
+ return [self._LIBCORE_BUILD_PATH]
return []
def Run(self, options, adb):
logger.Log(adb_cmd)
elif options.coverage:
coverage_gen = coverage.CoverageGenerator(adb)
- if not coverage_gen.TestDeviceCoverageSupport():
- raise errors.AbortError
adb.WaitForInstrumentation(self.GetPackageName(),
self.GetRunnerName())
# need to parse test output to determine path to coverage file