--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/e32test-driver/rtest.py Fri Jan 15 09:07:44 2010 +0000
@@ -0,0 +1,246 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# RTestParser represents the results of running an RTest testsuite on the target in terms of RTest
+# objects. Each RTest object captures the LineTimeInfo associated with the test and can determine
+# whether the test errored, failed or passed. It also provides further information such as the name of
+# the test and how long it took to gather the output from the test (which is a crude estimate of how long
+# it took to run the test. It can provide various useful bits of information like the line number in the
+# raw test data of a given line and the 'context' of a failure (in terms of the lines in the raw data).
+
+import sys
+
+import re
+
+import qemuruntest
+
+startRTestPattern = re.compile('RTEST TITLE:')
+bmSuiteFailurePattern = re.compile('Error:')
+endRTestPattern = re.compile('RUNTESTS: Test')
+failedRTestPattern = re.compile('RUNTESTS: Test .* FAIL')
+erroredRTestPattern = re.compile('RUNTESTS: Test .* ERROR')
+nameRTestPattern = re.compile('RUNTESTS: Test (\w+)')
+testSuiteEndingPattern = re.compile('RUNTESTS: Elapsed')
+
+class NoRTestsFound(Exception):
+ def __init__(self, parser):
+ self.parser = parser
+
+ def __str__(self):
+ return "No test results found in output from running '%s' rom image" % (self.parser.GetRomName())
+
+ def GetParser(self):
+ return self.parser
+
+class RTestEndMissing(Exception):
+ def __init__(self, rtest):
+ self.rtest = rtest
+
+ def __str__(self):
+ return "Could not find end of test started on line %d: '%s'" % (self.rtest.GetLineNumber(0), self.rtest.GetLine(0))
+
+ def GetParser(self):
+ return self.parser
+
+ def GetIndex(self):
+ return self.index
+
+class RTestNameMissing(Exception):
+ def __init__(self, rtest, line):
+ self.rtest = rtest
+ self.line = line
+
+ def GetRTest(self):
+ return self.rtest
+
+ def __str__(self):
+ return "Could not find RTest name in line '%s'" % (self.line)
+
+ def GetParser(self):
+ return self.parser
+
+ def GetLine(self):
+ return self.line
+
+class RTest(object):
+ def __init__(self, parser, lineTimeInfo, startLine = 0):
+ """return new RTest instance"""
+ self.parser = parser
+ self.lineTimeInfoList = []
+ self.lineTimeInfoList.append(lineTimeInfo)
+ self.timeTaken = None
+ self.result = None
+ self.name = None
+ self.startLine = startLine
+ #line = lineTimeInfo.GetLine()
+ #print >> sys.stdout, line
+
+ def __str__(self):
+ return self.GetName() + " " + self.GetResult()
+
+ def Consume(self,lineTimeInfoList, start):
+ newStart = start;
+ for i in range(start, len(lineTimeInfoList) - 1):
+ lineTimeInfo = lineTimeInfoList[i]
+ self.lineTimeInfoList.append(lineTimeInfo)
+ line = lineTimeInfo.GetLine()
+ newStart = newStart + 1
+ if self.EndOfTestp(line):
+ break
+ else:
+ raise RTestEndMissing(self)
+
+ return newStart
+
+ def EndOfTestp(self,line):
+ return re.match(endRTestPattern, line) != None
+
+ def FailedTestp(self,line):
+ return re.match(failedRTestPattern, line) != None
+
+ def ErroredTestp(self,line):
+ return re.match(erroredRTestPattern, line) != None
+
+ def GetTimeTaken(self):
+ if self.timeTaken == None:
+ self.timeTaken = self.lineTimeInfoList[-1].GetTime() - self.lineTimeInfoList[0].GetTime()
+ return self.timeTaken
+
+ def GetResult(self):
+ if self.result == None:
+ line = self.lineTimeInfoList[-1].GetLine()
+ if self.FailedTestp(line):
+ self.result = 'Failed'
+ elif self.ErroredTestp(line):
+ self.result = 'Errored'
+ else:
+ self.result = 'Passed'
+ return self.result
+
+ def Failedp(self):
+ return self.GetResult() == 'Failed'
+
+ def Erroredp(self):
+ return self.GetResult() == 'Errored'
+
+ def Passedp(self):
+ return self.GetResult() == 'Passed'
+
+ def GetName(self):
+ if self.name == None:
+ try:
+ self.name = self.ParseName()
+ except RTestNameMissing, x:
+ print >> sys.stderr, "WARNING: ", x
+ self.name = "RTEST @ line %d" % (x.GetRTest().GetLineNumber(0))
+ return self.name
+
+ def ParseName(self):
+ line = self.lineTimeInfoList[-1].GetLine()
+ m = re.match(nameRTestPattern, line)
+ if m != None:
+ return m.group(1)
+ else:
+ raise RTestNameMissing(self, line)
+
+ def GetLineNumber(self, i):
+ return self.startLine + i
+
+ def GetLine(self, index):
+ return self.lineTimeInfoList[index].GetLine()
+
+ def ErrorContext(self):
+ if self.Failedp():
+ return map(qemuruntest.LineTimeInfo.GetLine, self.lineTimeInfoList[-5:-1])
+ else:
+ return []
+
+
+class RTestParser(object):
+ def __init__(self, testRunner, lineTimeInfoList = None):
+ self.testRunner = testRunner
+ if lineTimeInfoList == None:
+ self.lineTimeInfoList = testRunner.GetResults()
+ else:
+ self.lineTimeInfoList = lineTimeInfoList
+ self.rtestList = []
+ self.result = None
+
+ def Parse(self):
+ index = 0
+ end = len(self.lineTimeInfoList)
+ self.rtestList = []
+ testSuiteComplete = False
+ testErroredp = False
+
+ # find first test
+ while index < end:
+ lineTimeInfo = self.lineTimeInfoList[index]
+ index += 1;
+ line = lineTimeInfo.GetLine()
+ if self.StartOfTestp(line):
+ break
+ if self.ErroredTestp(line):
+ self.rtestList.append(RTest(self, lineTimeInfo, index-1))
+ else:
+ raise NoRTestsFound(self)
+
+ try:
+ while index < end:
+ # NB making startLine index means that line number are based at 1 rather than 0
+ rtest = RTest(self, lineTimeInfo, startLine = index)
+ self.rtestList.append(rtest)
+ index = rtest.Consume(self.lineTimeInfoList, index)
+
+ if self.TestSuiteEnding(self.lineTimeInfoList[index].GetLine()):
+ testSuiteComplete = True
+ break
+
+ while index < end:
+ lineTimeInfo = self.lineTimeInfoList[index]
+ index += 1;
+ line = lineTimeInfo.GetLine()
+ if self.StartOfTestp(line):
+ break
+ if self.ErroredTestp(line):
+ self.rtestList.append(RTest(self, lineTimeInfo, startLine = index))
+ except RTestEndMissing, x:
+ print >> sys.stderr, "WARNING: ", x
+ return testSuiteComplete
+
+ def StartOfTestp(self,line):
+ if re.match(startRTestPattern, line) != None:
+ return True
+ if re.match(bmSuiteFailurePattern, line) != None:
+ return True
+ return False
+
+ def ErroredTestp(self,line):
+ if re.match(erroredRTestPattern, line) != None:
+ return True
+
+ def TestSuiteEnding(self,line):
+ return re.match(testSuiteEndingPattern, line) != None
+
+ def GetRTests(self):
+ return self.rtestList
+
+ def GetLine(self,index):
+ return self.lineTimeInfoList[index]
+
+ def GetRomName(self):
+ return self.testRunner.GetRomName()