diff --git a/build/android/pylib/device/device_utils.py b/build/android/pylib/device/device_utils.py index fe9d2c64324ec..a4ddef1328057 100644 --- a/build/android/pylib/device/device_utils.py +++ b/build/android/pylib/device/device_utils.py @@ -634,9 +634,12 @@ class DeviceUtils(object): CommandTimeoutError on timeout. DeviceUnreachableError on missing device. """ - # Check that the package exists before clearing it. Necessary because - # calling pm clear on a package that doesn't exist may never return. - if self.GetApplicationPath(package): + # Check that the package exists before clearing it for android builds below + # JB MR2. Necessary because calling pm clear on a package that doesn't exist + # may never return. + if ((self.build_version_sdk >= + constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN_MR2) + or self.GetApplicationPath(package)): self.RunShellCommand(['pm', 'clear', package], check_return=True) @decorators.WithTimeoutAndRetriesFromInstance() diff --git a/build/android/pylib/device/device_utils_test.py b/build/android/pylib/device/device_utils_test.py index 58dd56ac9ee8a..72ab99ca03cb9 100755 --- a/build/android/pylib/device/device_utils_test.py +++ b/build/android/pylib/device/device_utils_test.py @@ -930,19 +930,35 @@ class DeviceUtilsForceStopTest(DeviceUtilsNewImplTest): class DeviceUtilsClearApplicationStateTest(DeviceUtilsNewImplTest): def testClearApplicationState_packageDoesntExist(self): - with self.assertCall( - self.call.device.GetApplicationPath('this.package.does.not.exist'), - None): + with self.assertCalls( + (self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'), + (self.call.device.GetApplicationPath('this.package.does.not.exist'), + None)): + self.device.ClearApplicationState('this.package.does.not.exist') + + def testClearApplicationState_packageDoesntExistOnAndroidJBMR2OrAbove(self): + with self.assertCalls( + (self.call.adb.Shell('getprop ro.build.version.sdk'), '18\n'), + (self.call.adb.Shell('pm clear this.package.does.not.exist'), + 'Failed\r\n')): self.device.ClearApplicationState('this.package.does.not.exist') def testClearApplicationState_packageExists(self): with self.assertCalls( + (self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'), (self.call.device.GetApplicationPath('this.package.exists'), '/data/app/this.package.exists.apk'), (self.call.adb.Shell('pm clear this.package.exists'), 'Success\r\n')): self.device.ClearApplicationState('this.package.exists') + def testClearApplicationState_packageExistsOnAndroidJBMR2OrAbove(self): + with self.assertCalls( + (self.call.adb.Shell('getprop ro.build.version.sdk'), '18\n'), + (self.call.adb.Shell('pm clear this.package.exists'), + 'Success\r\n')): + self.device.ClearApplicationState('this.package.exists') + class DeviceUtilsSendKeyEventTest(DeviceUtilsNewImplTest): diff --git a/build/android/pylib/gtest/test_package_apk.py b/build/android/pylib/gtest/test_package_apk.py index b4c67e650d6f8..cdb6dafa1a906 100644 --- a/build/android/pylib/gtest/test_package_apk.py +++ b/build/android/pylib/gtest/test_package_apk.py @@ -55,11 +55,11 @@ class TestPackageApk(TestPackage): device.RunShellCommand('rm -f ' + self._GetFifo()) def _WatchFifo(self, device, timeout, logfile=None): - for i in range(10): + for i in range(100): if device.FileExists(self._GetFifo()): - logging.info('Fifo created.') + logging.info('Fifo created. Slept for %f secs' % (i * 0.5)) break - time.sleep(i) + time.sleep(0.5) else: raise device_errors.DeviceUnreachableError( 'Unable to find fifo on device %s ' % self._GetFifo()) @@ -67,14 +67,14 @@ class TestPackageApk(TestPackage): args += ['shell', 'cat', self._GetFifo()] return pexpect.spawn('adb', args, timeout=timeout, logfile=logfile) - def _StartActivity(self, device): + def _StartActivity(self, device, force_stop=True): device.StartActivity( intent.Intent(package=self._package_info.package, activity=self._package_info.activity, action='android.intent.action.MAIN'), # No wait since the runner waits for FIFO creation anyway. blocking=False, - force_stop=True) + force_stop=force_stop) #override def ClearApplicationState(self, device): @@ -119,7 +119,10 @@ class TestPackageApk(TestPackage): try: self.tool.SetupEnvironment() self._ClearFifo(device) - self._StartActivity(device) + # Doesn't need to stop an Activity because ClearApplicationState() is + # always called before this call and so it is already stopped at this + # point. + self._StartActivity(device, force_stop=False) finally: self.tool.CleanUpEnvironment() logfile = android_commands.NewLineNormalizer(sys.stdout) diff --git a/build/android/pylib/gtest/test_runner.py b/build/android/pylib/gtest/test_runner.py index fa38c4f811cd4..4bb97379e042f 100644 --- a/build/android/pylib/gtest/test_runner.py +++ b/build/android/pylib/gtest/test_runner.py @@ -14,6 +14,18 @@ from pylib.device import device_errors from pylib.local import local_test_server_spawner from pylib.perf import perf_control +# Test case statuses. +RE_RUN = re.compile('\\[ RUN \\] ?(.*)\r\n') +RE_FAIL = re.compile('\\[ FAILED \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n') +RE_OK = re.compile('\\[ OK \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n') + +# Test run statuses. +RE_PASSED = re.compile('\\[ PASSED \\] ?(.*)\r\n') +RE_RUNNER_FAIL = re.compile('\\[ RUNNER_FAILED \\] ?(.*)\r\n') +# Signal handlers are installed before starting tests +# to output the CRASHED marker when a crash happens. +RE_CRASH = re.compile('\\[ CRASHED \\](.*)\r\n') + def _TestSuiteRequiresMockTestServer(suite_name): """Returns True if the test suite requires mock test server.""" @@ -77,45 +89,33 @@ class TestRunner(base_test_runner.BaseTestRunner): """ results = base_test_result.TestRunResults() - # Test case statuses. - re_run = re.compile('\\[ RUN \\] ?(.*)\r\n') - re_fail = re.compile('\\[ FAILED \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n') - re_ok = re.compile('\\[ OK \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n') - - # Test run statuses. - re_passed = re.compile('\\[ PASSED \\] ?(.*)\r\n') - re_runner_fail = re.compile('\\[ RUNNER_FAILED \\] ?(.*)\r\n') - # Signal handlers are installed before starting tests - # to output the CRASHED marker when a crash happens. - re_crash = re.compile('\\[ CRASHED \\](.*)\r\n') - log = '' try: while True: full_test_name = None - found = p.expect([re_run, re_passed, re_runner_fail], + found = p.expect([RE_RUN, RE_PASSED, RE_RUNNER_FAIL], timeout=self._timeout) - if found == 1: # re_passed + if found == 1: # RE_PASSED break - elif found == 2: # re_runner_fail + elif found == 2: # RE_RUNNER_FAIL break - else: # re_run + else: # RE_RUN full_test_name = p.match.group(1).replace('\r', '') - found = p.expect([re_ok, re_fail, re_crash], timeout=self._timeout) + found = p.expect([RE_OK, RE_FAIL, RE_CRASH], timeout=self._timeout) log = p.before.replace('\r', '') - if found == 0: # re_ok + if found == 0: # RE_OK if full_test_name == p.match.group(1).replace('\r', ''): duration_ms = int(p.match.group(3)) if p.match.group(3) else 0 results.AddResult(base_test_result.BaseTestResult( full_test_name, base_test_result.ResultType.PASS, duration=duration_ms, log=log)) - elif found == 2: # re_crash + elif found == 2: # RE_CRASH results.AddResult(base_test_result.BaseTestResult( full_test_name, base_test_result.ResultType.CRASH, log=log)) break - else: # re_fail + else: # RE_FAIL duration_ms = int(p.match.group(3)) if p.match.group(3) else 0 results.AddResult(base_test_result.BaseTestResult( full_test_name, base_test_result.ResultType.FAIL,