tools/e32test-driver/rtest.py
author johnathan.white@2718R8BGH51.accenture.com
Mon, 08 Mar 2010 18:45:03 +0000
changeset 46 b6935a90ca64
parent 34 92d87f2e53c2
permissions -rwxr-xr-x
Modify framebuffer and NGA framebuffer to read screen size from board model dtb file. Optimise memory usuage of frame buffer Add example minigui application with hooks to profiler (which writes results to S:\). Modified NGA framebuffer to run its own dfc queue at high priority

#
# 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()