go to a indexed parser from a enumerated line parser; [TOXIC CODE DONT USE]
This commit is contained in:
@@ -36,17 +36,58 @@
|
|||||||
#
|
#
|
||||||
# ***** END LICENSE BLOCK *****
|
# ***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
# TODO: document what all of the cases are, e.g
|
||||||
|
#
|
||||||
|
# - harness completes and automation.py hangs:
|
||||||
|
# "'62521 INFO TEST-PASS | /tests/content/xbl/test/test_bug542406.xhtml | Field three readonly?\n',
|
||||||
|
# '62523 INFO Passed: 60569\n',
|
||||||
|
# '62524 INFO Failed: 44\n',
|
||||||
|
# '62525 INFO Todo: 770\n',
|
||||||
|
# '62526 INFO SimpleTest FINISHED\n',
|
||||||
|
# 'TEST-UNEXPECTED-FAIL | automation.py | application timed out after 330 seconds with no output\n',
|
||||||
|
# "Can't trigger Breakpad, just killing process\n",
|
||||||
|
# 'INFO | automation.py | Application ran for: 0:24:44.270038\n',
|
||||||
|
# 'INFO | automation.py | Reading PID log: /var/folders/H5/H5TD8hgwEqKq9hgKlayjWU+++TM/-Tmp-/tmpEjNEf2pidlog\n',
|
||||||
|
# "WARNING | automationutils.processLeakLog() | refcount logging is off, so leaks can't be detected!\n",
|
||||||
|
# '\n',
|
||||||
|
# 'INFO | runtests.py | Running tests: end.\n',
|
||||||
|
# 'program finished with exit code 247\n',
|
||||||
|
# 'elapsedTime=1496.639870\n',"
|
||||||
|
#
|
||||||
|
# - leak at harness closure: see sample-logs/leaks-log.txt
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
class LogParser(object):
|
class LogParser(object):
|
||||||
"""abstract base class for parsing unittest logs"""
|
"""abstract base class for parsing unittest logs"""
|
||||||
|
|
||||||
# 'TestFailed' expected log format is "result | test | optional text".
|
# 'TestFailed' expected log format is "result | test | optional text".
|
||||||
testfailedRe = re.compile(r"(TEST-UNEXPECTED-.*) \| (.*) \|(.*)")
|
testfailedRe = re.compile(r"(TEST-UNEXPECTED-.*|PROCESS-CRASH) \| (.*) \|(.*)")
|
||||||
|
|
||||||
def get_potentialTestName(self, line):
|
def get_potentialTestName(self, line):
|
||||||
"""return potential test name [None by default]"""
|
"""return potential test name [None by default]"""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def processTestName(self, test, reason, potentialTestName):
|
||||||
|
"""substitute the potential name for the test (if applicable)"""
|
||||||
|
|
||||||
|
# for process crash, take the test-runner (automation) as the test failure
|
||||||
|
# (as already reported in test) and reset the potentialTestName to None
|
||||||
|
if 'PROCESS-CRASH' in reason:
|
||||||
|
return test
|
||||||
|
|
||||||
|
# an automation.py failure will ALWAYS be followed by a
|
||||||
|
# automationutils.processLeakLog line; so send a None here
|
||||||
|
# which will cause the parsing to continue and don't record this failure
|
||||||
|
if 'automation.py' in test:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if 'automationutils.processLeakLog' and (potentialTestName is not None):
|
||||||
|
return potentialTestName
|
||||||
|
|
||||||
|
# if these conditions are not met, return
|
||||||
|
# the test name and potentialTestName untouched
|
||||||
|
return test # no name substitution
|
||||||
|
|
||||||
def parse(self, fp):
|
def parse(self, fp):
|
||||||
"""
|
"""
|
||||||
@@ -58,7 +99,10 @@ class LogParser(object):
|
|||||||
failures = []
|
failures = []
|
||||||
lines = fp.readlines()
|
lines = fp.readlines()
|
||||||
potentialTestName = None
|
potentialTestName = None
|
||||||
for idx, line in enumerate(lines):
|
|
||||||
|
idx = 0
|
||||||
|
while idx < len(lines):
|
||||||
|
line = lines[idx]
|
||||||
|
|
||||||
# get the potential real name for reporting
|
# get the potential real name for reporting
|
||||||
# a test for an automation.py or automationutils.processLeakLog failure
|
# a test for an automation.py or automationutils.processLeakLog failure
|
||||||
@@ -69,16 +113,29 @@ class LogParser(object):
|
|||||||
if not m:
|
if not m:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# reason for failure [TEST-UNEXPECTED-.* or PROCESS-CRASH]
|
||||||
|
reason = m.group(1).rstrip()
|
||||||
|
|
||||||
# name of the test
|
# name of the test
|
||||||
test = m.group(2).strip() or "[unittest-log.py: no logged test]"
|
test = m.group(2).strip() or "[unittest-log.py: no logged test]"
|
||||||
|
|
||||||
# substitute potentialTestName for the test name if
|
# fail log text
|
||||||
# test is automation.py or automationutils.processLeakLog
|
text = m.group(3).strip() or "[unittest-log.py: no logged text]"
|
||||||
if 'automation.py' in test or 'automationutils.processLeakLog' in test:
|
|
||||||
if potentialTestName is not None:
|
|
||||||
test = potentialTestName
|
|
||||||
potentialTestName = None
|
|
||||||
|
|
||||||
|
# test to see if the harness hangs after a run completion
|
||||||
|
if lines[idx-1].strip().endswith('FINISHED'):
|
||||||
|
text = 'harness hangs after end of test run (or something)'
|
||||||
|
else:
|
||||||
|
# substitute potentialTestName for the test name if
|
||||||
|
# test is automation.py or automationutils.processLeakLog
|
||||||
|
test = self.processPotentialTestName(test, reason, potentialTestName)
|
||||||
|
|
||||||
|
if test is None: # don't add this test
|
||||||
|
continue
|
||||||
|
|
||||||
|
# reset potentialTestName
|
||||||
|
potentialTestName = None
|
||||||
|
|
||||||
# Code bits below try to change back slash to forward slash
|
# Code bits below try to change back slash to forward slash
|
||||||
# and get rid of varibale prepends to the /test/../.. names
|
# and get rid of varibale prepends to the /test/../.. names
|
||||||
if test.find('\\') != -1:
|
if test.find('\\') != -1:
|
||||||
@@ -90,12 +147,12 @@ class LogParser(object):
|
|||||||
else :
|
else :
|
||||||
test=tup[0]
|
test=tup[0]
|
||||||
|
|
||||||
# fail log text
|
|
||||||
text = m.group(3).strip() or "[unittest-log.py: no logged text]"
|
|
||||||
|
|
||||||
# append interesting data to failures return value
|
# append interesting data to failures return value
|
||||||
failures.append({'test': test, 'text': text, 'reason': m.group(1).rstrip()})
|
failures.append({'test': test, 'text': text, 'reason': reason})
|
||||||
|
|
||||||
|
# increment the line counter
|
||||||
|
idx += 1
|
||||||
|
|
||||||
return failures
|
return failures
|
||||||
|
|
||||||
class ReftestParser(LogParser):
|
class ReftestParser(LogParser):
|
||||||
@@ -104,11 +161,6 @@ class ReftestParser(LogParser):
|
|||||||
- Reftest
|
- Reftest
|
||||||
- Crashtest
|
- Crashtest
|
||||||
- JSReftest
|
- JSReftest
|
||||||
|
|
||||||
TODO:
|
|
||||||
- look for PROCESS-CRASH as well as UNEXPECTED-FAIL
|
|
||||||
[PROCESS-CRASH is a harness crash]
|
|
||||||
- need an actual log file with TEST-UNEXPECTED-FAIL with automation.py
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_potentialTestName(self, line):
|
def get_potentialTestName(self, line):
|
||||||
@@ -127,23 +179,6 @@ class MochitestParser(LogParser):
|
|||||||
- Mochitest-chrome
|
- Mochitest-chrome
|
||||||
- Mochitest-browserchrome
|
- Mochitest-browserchrome
|
||||||
- Mochitest-a11y
|
- Mochitest-a11y
|
||||||
|
|
||||||
TODO: unhandled cases:
|
|
||||||
- harness completes and automation.py hangs:
|
|
||||||
"'62521 INFO TEST-PASS | /tests/content/xbl/test/test_bug542406.xhtml | Field three readonly?\n',
|
|
||||||
'62523 INFO Passed: 60569\n',
|
|
||||||
'62524 INFO Failed: 44\n',
|
|
||||||
'62525 INFO Todo: 770\n',
|
|
||||||
'62526 INFO SimpleTest FINISHED\n',
|
|
||||||
'TEST-UNEXPECTED-FAIL | automation.py | application timed out after 330 seconds with no output\n',
|
|
||||||
"Can't trigger Breakpad, just killing process\n",
|
|
||||||
'INFO | automation.py | Application ran for: 0:24:44.270038\n',
|
|
||||||
'INFO | automation.py | Reading PID log: /var/folders/H5/H5TD8hgwEqKq9hgKlayjWU+++TM/-Tmp-/tmpEjNEf2pidlog\n',
|
|
||||||
"WARNING | automationutils.processLeakLog() | refcount logging is off, so leaks can't be detected!\n",
|
|
||||||
'\n',
|
|
||||||
'INFO | runtests.py | Running tests: end.\n',
|
|
||||||
'program finished with exit code 247\n',
|
|
||||||
'elapsedTime=1496.639870\n',"
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_potentialTestName(self, line):
|
def get_potentialTestName(self, line):
|
||||||
|
|||||||
Reference in New Issue
Block a user