logparser.py 4.35 KB
Newer Older
Daniel Smith's avatar
Daniel Smith committed
1 2 3 4 5 6
import os
import argparse
import re

failedTests = {}  # Typing.dict()
totalCount = 0
7
totalTestCaseCount = 0
Daniel Smith's avatar
Daniel Smith committed
8 9 10

def findFailedTests(logfile: str):
    global totalCount
11 12
    global totalTestCaseCount
    pattern = re.compile(r'[0-9]{1,}(?<!0) failed') # Look for the testresults line that includes the number of failed tests, where not 0.
Daniel Smith's avatar
Daniel Smith committed
13

14
    with open(logfile) as log:  #Open the log file
Daniel Smith's avatar
Daniel Smith committed
15
        logtext = log.read()
16 17 18 19 20 21 22 23 24 25 26
        if pattern.search(logtext): # Find match(es) with the regex pattern above.
            
            resultsFilename = ""  # Typing.str()
            if args.suppressFile:
                resultsFilename = os.devnull
            else:
                resultsFilename = "{0}{1}{2}_failures.txt".format(os.path.join(args.logDir, "parser_results"), os.sep,
                                                logfile[logfile.rfind(os.sep) + 1: logfile.rfind('.txt')])
            
            with open(resultsFilename, mode='w+') as outfile:
                for match in pattern.finditer(logtext):  # Iterate through the matches for failed tests and strip out the individual cases.
Daniel Smith's avatar
Daniel Smith committed
27
                    tstnameindex = 0
28
                    tstnameindex = logtext.rfind("********* Start testing of ", 0, match.span()[0]) + 27  # Search for the test case.
Daniel Smith's avatar
Daniel Smith committed
29
                    tstname = logtext[tstnameindex:
30 31 32 33
                                      logtext.find("*********", tstnameindex)-1]
                    if not args.suppressConsole:
                        print("{0}: {1}".format(tstname,match.group(0)))  # Print the test name and count failed.
                    outfile.writelines("{0}: {1}\r\n".format(tstname,match.group(0)))  # Write it to file.
Daniel Smith's avatar
Daniel Smith committed
34
                    
35
                    if int(re.match(r'[0-9]{0,}', match.group(0)).group(0)) > 9 and not args.printAll:  #
Daniel Smith's avatar
Daniel Smith committed
36
                        outfile.writelines("Too many fail cases. Not printing the failures here. See the original log for failure details.")
37 38
                        if not args.suppressConsole:
                            print("Too many fail cases. Not printing the failures here. See the original log for failure details.")
Daniel Smith's avatar
Daniel Smith committed
39 40
                        break

41
                    logsnip = logtext[tstnameindex : logtext.find("********* Finished testing of ", tstnameindex)]  # Save a snip of the log with the failed test(s)
Daniel Smith's avatar
Daniel Smith committed
42

43 44 45
                    for failcasematch in re.finditer('FAIL!  : ', logsnip):  # Find the actual fail case
                        totalTestCaseCount += 1
                        # Look for the end of the case. We know coin always print the file location. Grab up the the newline when we find that.
Daniel Smith's avatar
Daniel Smith committed
46
                        failcasestring = logsnip[failcasematch.span()[0] : logsnip.find('\n', logsnip.find("Loc: ", failcasematch.span()[0]))]
47 48
                        if not args.suppressConsole:
                            print("{0}\r\n".format(failcasestring))
Daniel Smith's avatar
Daniel Smith committed
49 50
                        outfile.writelines("{0}\r\n".format(failcasestring))
                    totalCount += 1
51 52

    if not args.suppressConsole: print("\r\n")  # just a spacer fore readability when printing results to screen.
Daniel Smith's avatar
Daniel Smith committed
53 54 55 56

if __name__ == "__main__":

    parser = argparse.ArgumentParser()
57 58 59 60
    parser.add_argument('--logdir',dest='logDir', type=str, required=True, help='The full path to a directory of logs')
    parser.add_argument('--printall', action='store_true', dest="printAll", help="Set --printall to force printing details of tests with more than 9 fail cases. ")
    parser.add_argument('--suppressconsole', action='store_true', dest="suppressConsole", help="Set --supressconsole to prevent writing to screen.")
    parser.add_argument('--suppressfile', action='store_true', dest="suppressFile", help="Set --supressfile to prevent writing results to file.")
Daniel Smith's avatar
Daniel Smith committed
61 62 63 64

    args = parser.parse_args()
    logfiles = os.listdir(args.logDir)

65 66 67 68 69
    # print(logfiles)  # diagnostic

    if not os.path.exists(os.path.join(args.logDir, "parser_results")) and not args.suppressFile:
        os.makedirs(os.path.join(args.logDir, "parser_results"))

Daniel Smith's avatar
Daniel Smith committed
70 71

    for logfile in logfiles:
72 73 74
        print("Processing {0}".format(logfile))
        if not os.path.isdir(os.path.join(args.logDir, logfile)):
            findFailedTests(os.path.join(args.logDir, logfile))
Daniel Smith's avatar
Daniel Smith committed
75

76
    print("Done parsing.\r\nTotal failed test applications: {0}\r\nTotal failed test cases: {1}".format(totalCount, totalTestCaseCount))