Refactor test scripts for android to improve performance
-. Skip checking package existence -. Skip stopping an Activity -. Reduce waiting time for fifo BUG=449354 Review URL: https://codereview.chromium.org/839893004 Cr-Original-Commit-Position: refs/heads/master@{#312552} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: e3a24e9786ac3483c60e91c39742243aa15e7a14
This commit is contained in:
Родитель
bbfd485e08
Коммит
30c7a06d49
|
@ -634,9 +634,12 @@ class DeviceUtils(object):
|
||||||
CommandTimeoutError on timeout.
|
CommandTimeoutError on timeout.
|
||||||
DeviceUnreachableError on missing device.
|
DeviceUnreachableError on missing device.
|
||||||
"""
|
"""
|
||||||
# Check that the package exists before clearing it. Necessary because
|
# Check that the package exists before clearing it for android builds below
|
||||||
# calling pm clear on a package that doesn't exist may never return.
|
# JB MR2. Necessary because calling pm clear on a package that doesn't exist
|
||||||
if self.GetApplicationPath(package):
|
# 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)
|
self.RunShellCommand(['pm', 'clear', package], check_return=True)
|
||||||
|
|
||||||
@decorators.WithTimeoutAndRetriesFromInstance()
|
@decorators.WithTimeoutAndRetriesFromInstance()
|
||||||
|
|
|
@ -930,19 +930,35 @@ class DeviceUtilsForceStopTest(DeviceUtilsNewImplTest):
|
||||||
class DeviceUtilsClearApplicationStateTest(DeviceUtilsNewImplTest):
|
class DeviceUtilsClearApplicationStateTest(DeviceUtilsNewImplTest):
|
||||||
|
|
||||||
def testClearApplicationState_packageDoesntExist(self):
|
def testClearApplicationState_packageDoesntExist(self):
|
||||||
with self.assertCall(
|
with self.assertCalls(
|
||||||
self.call.device.GetApplicationPath('this.package.does.not.exist'),
|
(self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'),
|
||||||
None):
|
(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')
|
self.device.ClearApplicationState('this.package.does.not.exist')
|
||||||
|
|
||||||
def testClearApplicationState_packageExists(self):
|
def testClearApplicationState_packageExists(self):
|
||||||
with self.assertCalls(
|
with self.assertCalls(
|
||||||
|
(self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'),
|
||||||
(self.call.device.GetApplicationPath('this.package.exists'),
|
(self.call.device.GetApplicationPath('this.package.exists'),
|
||||||
'/data/app/this.package.exists.apk'),
|
'/data/app/this.package.exists.apk'),
|
||||||
(self.call.adb.Shell('pm clear this.package.exists'),
|
(self.call.adb.Shell('pm clear this.package.exists'),
|
||||||
'Success\r\n')):
|
'Success\r\n')):
|
||||||
self.device.ClearApplicationState('this.package.exists')
|
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):
|
class DeviceUtilsSendKeyEventTest(DeviceUtilsNewImplTest):
|
||||||
|
|
||||||
|
|
|
@ -55,11 +55,11 @@ class TestPackageApk(TestPackage):
|
||||||
device.RunShellCommand('rm -f ' + self._GetFifo())
|
device.RunShellCommand('rm -f ' + self._GetFifo())
|
||||||
|
|
||||||
def _WatchFifo(self, device, timeout, logfile=None):
|
def _WatchFifo(self, device, timeout, logfile=None):
|
||||||
for i in range(10):
|
for i in range(100):
|
||||||
if device.FileExists(self._GetFifo()):
|
if device.FileExists(self._GetFifo()):
|
||||||
logging.info('Fifo created.')
|
logging.info('Fifo created. Slept for %f secs' % (i * 0.5))
|
||||||
break
|
break
|
||||||
time.sleep(i)
|
time.sleep(0.5)
|
||||||
else:
|
else:
|
||||||
raise device_errors.DeviceUnreachableError(
|
raise device_errors.DeviceUnreachableError(
|
||||||
'Unable to find fifo on device %s ' % self._GetFifo())
|
'Unable to find fifo on device %s ' % self._GetFifo())
|
||||||
|
@ -67,14 +67,14 @@ class TestPackageApk(TestPackage):
|
||||||
args += ['shell', 'cat', self._GetFifo()]
|
args += ['shell', 'cat', self._GetFifo()]
|
||||||
return pexpect.spawn('adb', args, timeout=timeout, logfile=logfile)
|
return pexpect.spawn('adb', args, timeout=timeout, logfile=logfile)
|
||||||
|
|
||||||
def _StartActivity(self, device):
|
def _StartActivity(self, device, force_stop=True):
|
||||||
device.StartActivity(
|
device.StartActivity(
|
||||||
intent.Intent(package=self._package_info.package,
|
intent.Intent(package=self._package_info.package,
|
||||||
activity=self._package_info.activity,
|
activity=self._package_info.activity,
|
||||||
action='android.intent.action.MAIN'),
|
action='android.intent.action.MAIN'),
|
||||||
# No wait since the runner waits for FIFO creation anyway.
|
# No wait since the runner waits for FIFO creation anyway.
|
||||||
blocking=False,
|
blocking=False,
|
||||||
force_stop=True)
|
force_stop=force_stop)
|
||||||
|
|
||||||
#override
|
#override
|
||||||
def ClearApplicationState(self, device):
|
def ClearApplicationState(self, device):
|
||||||
|
@ -119,7 +119,10 @@ class TestPackageApk(TestPackage):
|
||||||
try:
|
try:
|
||||||
self.tool.SetupEnvironment()
|
self.tool.SetupEnvironment()
|
||||||
self._ClearFifo(device)
|
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:
|
finally:
|
||||||
self.tool.CleanUpEnvironment()
|
self.tool.CleanUpEnvironment()
|
||||||
logfile = android_commands.NewLineNormalizer(sys.stdout)
|
logfile = android_commands.NewLineNormalizer(sys.stdout)
|
||||||
|
|
|
@ -14,6 +14,18 @@ from pylib.device import device_errors
|
||||||
from pylib.local import local_test_server_spawner
|
from pylib.local import local_test_server_spawner
|
||||||
from pylib.perf import perf_control
|
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):
|
def _TestSuiteRequiresMockTestServer(suite_name):
|
||||||
"""Returns True if the test suite requires mock test server."""
|
"""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()
|
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 = ''
|
log = ''
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
full_test_name = None
|
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)
|
timeout=self._timeout)
|
||||||
if found == 1: # re_passed
|
if found == 1: # RE_PASSED
|
||||||
break
|
break
|
||||||
elif found == 2: # re_runner_fail
|
elif found == 2: # RE_RUNNER_FAIL
|
||||||
break
|
break
|
||||||
else: # re_run
|
else: # RE_RUN
|
||||||
full_test_name = p.match.group(1).replace('\r', '')
|
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', '')
|
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', ''):
|
if full_test_name == p.match.group(1).replace('\r', ''):
|
||||||
duration_ms = int(p.match.group(3)) if p.match.group(3) else 0
|
duration_ms = int(p.match.group(3)) if p.match.group(3) else 0
|
||||||
results.AddResult(base_test_result.BaseTestResult(
|
results.AddResult(base_test_result.BaseTestResult(
|
||||||
full_test_name, base_test_result.ResultType.PASS,
|
full_test_name, base_test_result.ResultType.PASS,
|
||||||
duration=duration_ms, log=log))
|
duration=duration_ms, log=log))
|
||||||
elif found == 2: # re_crash
|
elif found == 2: # RE_CRASH
|
||||||
results.AddResult(base_test_result.BaseTestResult(
|
results.AddResult(base_test_result.BaseTestResult(
|
||||||
full_test_name, base_test_result.ResultType.CRASH,
|
full_test_name, base_test_result.ResultType.CRASH,
|
||||||
log=log))
|
log=log))
|
||||||
break
|
break
|
||||||
else: # re_fail
|
else: # RE_FAIL
|
||||||
duration_ms = int(p.match.group(3)) if p.match.group(3) else 0
|
duration_ms = int(p.match.group(3)) if p.match.group(3) else 0
|
||||||
results.AddResult(base_test_result.BaseTestResult(
|
results.AddResult(base_test_result.BaseTestResult(
|
||||||
full_test_name, base_test_result.ResultType.FAIL,
|
full_test_name, base_test_result.ResultType.FAIL,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче