mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 22:36:09 +03:00
106 lines
3.3 KiB
Python
106 lines
3.3 KiB
Python
# Copyright 2015 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import logging
|
|
import re
|
|
|
|
# http://developer.android.com/reference/android/test/InstrumentationTestRunner.html
|
|
STATUS_CODE_START = 1
|
|
STATUS_CODE_OK = 0
|
|
STATUS_CODE_ERROR = -1
|
|
STATUS_CODE_FAILURE = -2
|
|
|
|
# AndroidJUnitRunner would status output -3 to indicate a test is skipped
|
|
STATUS_CODE_SKIP = -3
|
|
|
|
# AndroidJUnitRunner outputs -4 to indicate a failed assumption
|
|
# "A test for which an assumption fails should not generate a test
|
|
# case failure"
|
|
# http://junit.org/junit4/javadoc/4.12/org/junit/AssumptionViolatedException.html
|
|
STATUS_CODE_ASSUMPTION_FAILURE = -4
|
|
|
|
# http://developer.android.com/reference/android/app/Activity.html
|
|
RESULT_CODE_OK = -1
|
|
RESULT_CODE_CANCELED = 0
|
|
|
|
_INSTR_LINE_RE = re.compile(r'^\s*INSTRUMENTATION_([A-Z_]+): (.*)$')
|
|
|
|
|
|
class InstrumentationParser(object):
|
|
|
|
def __init__(self, stream):
|
|
"""An incremental parser for the output of Android instrumentation tests.
|
|
|
|
Example:
|
|
|
|
stream = adb.IterShell('am instrument -r ...')
|
|
parser = InstrumentationParser(stream)
|
|
|
|
for code, bundle in parser.IterStatus():
|
|
# do something with each instrumentation status
|
|
print 'status:', code, bundle
|
|
|
|
# do something with the final instrumentation result
|
|
code, bundle = parser.GetResult()
|
|
print 'result:', code, bundle
|
|
|
|
Args:
|
|
stream: a sequence of lines as produced by the raw output of an
|
|
instrumentation test (e.g. by |am instrument -r|).
|
|
"""
|
|
self._stream = stream
|
|
self._code = None
|
|
self._bundle = None
|
|
|
|
def IterStatus(self):
|
|
"""Iterate over statuses as they are produced by the instrumentation test.
|
|
|
|
Yields:
|
|
A tuple (code, bundle) for each instrumentation status found in the
|
|
output.
|
|
"""
|
|
def join_bundle_values(bundle):
|
|
for key in bundle:
|
|
bundle[key] = '\n'.join(bundle[key])
|
|
return bundle
|
|
|
|
bundle = {'STATUS': {}, 'RESULT': {}}
|
|
header = None
|
|
key = None
|
|
for line in self._stream:
|
|
m = _INSTR_LINE_RE.match(line)
|
|
if m:
|
|
header, value = m.groups()
|
|
key = None
|
|
if header in ['STATUS', 'RESULT'] and '=' in value:
|
|
key, value = value.split('=', 1)
|
|
bundle[header][key] = [value]
|
|
elif header == 'STATUS_CODE':
|
|
yield int(value), join_bundle_values(bundle['STATUS'])
|
|
bundle['STATUS'] = {}
|
|
elif header == 'CODE':
|
|
self._code = int(value)
|
|
else:
|
|
logging.warning('Unknown INSTRUMENTATION_%s line: %s', header, value)
|
|
elif key is not None:
|
|
bundle[header][key].append(line)
|
|
|
|
self._bundle = join_bundle_values(bundle['RESULT'])
|
|
|
|
def GetResult(self):
|
|
"""Return the final instrumentation result.
|
|
|
|
Returns:
|
|
A pair (code, bundle) with the final instrumentation result. The |code|
|
|
may be None if no instrumentation result was found in the output.
|
|
|
|
Raises:
|
|
AssertionError if attempting to get the instrumentation result before
|
|
exhausting |IterStatus| first.
|
|
"""
|
|
assert self._bundle is not None, (
|
|
'The IterStatus generator must be exhausted before reading the final'
|
|
' instrumentation result.')
|
|
return self._code, self._bundle
|