Index: build/android/pylib/instrumentation/test_runner.py |
diff --git a/build/android/pylib/instrumentation/test_runner.py b/build/android/pylib/instrumentation/test_runner.py |
index a86b5ceae419ea3ad1be528364217220c7cb912b..74898c2c366c34130fd15dd2f416575a7bfe959e 100644 |
--- a/build/android/pylib/instrumentation/test_runner.py |
+++ b/build/android/pylib/instrumentation/test_runner.py |
@@ -16,8 +16,10 @@ from pylib import valgrind_tools |
from pylib.base import base_test_result |
from pylib.base import base_test_runner |
from pylib.device import device_errors |
+from pylib.instrumentation import instrumentation_test_instance |
from pylib.instrumentation import json_perf_parser |
from pylib.instrumentation import test_result |
+from pylib.local.device import local_device_instrumentation_test_run |
sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib', |
'common')) |
@@ -319,124 +321,6 @@ class TestRunner(base_test_runner.BaseTestRunner): |
'%s/%s' % (self.test_pkg.GetPackageName(), self.options.test_runner), |
raw=True, extras=extras, timeout=timeout, retries=0) |
- @staticmethod |
- def _ParseAmInstrumentRawOutput(raw_output): |
- """Parses the output of an |am instrument -r| call. |
- |
- Args: |
- raw_output: the output of an |am instrument -r| call as a list of lines |
- Returns: |
- A 3-tuple containing: |
- - the instrumentation code as an integer |
- - the instrumentation result as a list of lines |
- - the instrumentation statuses received as a list of 2-tuples |
- containing: |
- - the status code as an integer |
- - the bundle dump as a dict mapping string keys to a list of |
- strings, one for each line. |
- """ |
- INSTR_STATUS = 'INSTRUMENTATION_STATUS: ' |
- INSTR_STATUS_CODE = 'INSTRUMENTATION_STATUS_CODE: ' |
- INSTR_RESULT = 'INSTRUMENTATION_RESULT: ' |
- INSTR_CODE = 'INSTRUMENTATION_CODE: ' |
- |
- last = None |
- instr_code = None |
- instr_result = [] |
- instr_statuses = [] |
- bundle = {} |
- for line in raw_output: |
- if line.startswith(INSTR_STATUS): |
- instr_var = line[len(INSTR_STATUS):] |
- if '=' in instr_var: |
- k, v = instr_var.split('=', 1) |
- bundle[k] = [v] |
- last = INSTR_STATUS |
- last_key = k |
- else: |
- logging.debug('Unknown "%s" line: %s' % (INSTR_STATUS, line)) |
- |
- elif line.startswith(INSTR_STATUS_CODE): |
- instr_status = line[len(INSTR_STATUS_CODE):] |
- instr_statuses.append((int(instr_status), bundle)) |
- bundle = {} |
- last = INSTR_STATUS_CODE |
- |
- elif line.startswith(INSTR_RESULT): |
- instr_result.append(line[len(INSTR_RESULT):]) |
- last = INSTR_RESULT |
- |
- elif line.startswith(INSTR_CODE): |
- instr_code = int(line[len(INSTR_CODE):]) |
- last = INSTR_CODE |
- |
- elif last == INSTR_STATUS: |
- bundle[last_key].append(line) |
- |
- elif last == INSTR_RESULT: |
- instr_result.append(line) |
- |
- return (instr_code, instr_result, instr_statuses) |
- |
- def _GenerateTestResult(self, test, instr_statuses, start_ms, duration_ms): |
- """Generate the result of |test| from |instr_statuses|. |
- |
- Args: |
- instr_statuses: A list of 2-tuples containing: |
- - the status code as an integer |
- - the bundle dump as a dict mapping string keys to string values |
- Note that this is the same as the third item in the 3-tuple returned by |
- |_ParseAmInstrumentRawOutput|. |
- start_ms: The start time of the test in milliseconds. |
- duration_ms: The duration of the test in milliseconds. |
- Returns: |
- An InstrumentationTestResult object. |
- """ |
- INSTR_STATUS_CODE_START = 1 |
- INSTR_STATUS_CODE_OK = 0 |
- INSTR_STATUS_CODE_ERROR = -1 |
- INSTR_STATUS_CODE_FAIL = -2 |
- |
- log = '' |
- result_type = base_test_result.ResultType.UNKNOWN |
- |
- for status_code, bundle in instr_statuses: |
- if status_code == INSTR_STATUS_CODE_START: |
- pass |
- elif status_code == INSTR_STATUS_CODE_OK: |
- bundle_test = '%s#%s' % ( |
- ''.join(bundle.get('class', [''])), |
- ''.join(bundle.get('test', ['']))) |
- skipped = ''.join(bundle.get('test_skipped', [''])) |
- |
- if (test == bundle_test and |
- result_type == base_test_result.ResultType.UNKNOWN): |
- result_type = base_test_result.ResultType.PASS |
- elif skipped.lower() in ('true', '1', 'yes'): |
- result_type = base_test_result.ResultType.SKIP |
- logging.info('Skipped ' + test) |
- else: |
- if status_code not in (INSTR_STATUS_CODE_ERROR, |
- INSTR_STATUS_CODE_FAIL): |
- logging.info('Unrecognized status code %d. Handling as an error.', |
- status_code) |
- result_type = base_test_result.ResultType.FAIL |
- if 'stack' in bundle: |
- log = '\n'.join(bundle['stack']) |
- # Dismiss any error dialogs. Limit the number in case we have an error |
- # loop or we are failing to dismiss. |
- for _ in xrange(10): |
- package = self.device.old_interface.DismissCrashDialogIfNeeded() |
- if not package: |
- break |
- # Assume test package convention of ".test" suffix |
- if package in self.test_pkg.GetPackageName(): |
- result_type = base_test_result.ResultType.CRASH |
- break |
- |
- return test_result.InstrumentationTestResult( |
- test, result_type, start_ms, duration_ms, log=log) |
- |
#override |
def RunTest(self, test): |
results = base_test_result.TestRunResults() |
@@ -458,8 +342,13 @@ class TestRunner(base_test_runner.BaseTestRunner): |
duration_ms = time_ms() - start_ms |
# Parse the test output |
- _, _, statuses = self._ParseAmInstrumentRawOutput(raw_output) |
- result = self._GenerateTestResult(test, statuses, start_ms, duration_ms) |
+ _, _, statuses = ( |
+ instrumentation_test_instance.ParseAmInstrumentRawOutput(raw_output)) |
+ result = instrumentation_test_instance.GenerateTestResult( |
+ test, statuses, start_ms, duration_ms) |
+ if local_device_instrumentation_test_run.DidPackageCrashOnDevice( |
+ self.test_pkg.GetPackageName(), self.device): |
+ result.SetType(base_test_result.ResultType.CRASH) |
results.AddResult(result) |
except device_errors.CommandTimeoutError as e: |
results.AddResult(test_result.InstrumentationTestResult( |