Home | History | Annotate | Download | only in misc
      1 #!/usr/bin/env python
      2 
      3 import testlog_parser, sys, os, xml, glob, re
      4 from table_formatter import *
      5 from optparse import OptionParser
      6 from operator import itemgetter, attrgetter
      7 from summary import getSetName, alphanum_keyselector
      8 import re
      9 
     10 if __name__ == "__main__":
     11     usage = "%prog <log_name>.xml [...]"
     12     parser = OptionParser(usage = usage)
     13 
     14     parser.add_option("-o", "--output", dest = "format",
     15         help = "output results in text format (can be 'txt', 'html' or 'auto' - default)",
     16         metavar = 'FMT', default = 'auto')
     17 
     18     parser.add_option("--failed-only", action = "store_true", dest = "failedOnly",
     19         help = "print only failed tests", default = False)
     20 
     21     (options, args) = parser.parse_args()
     22 
     23     options.generateHtml = detectHtmlOutputType(options.format)
     24 
     25     files = []
     26     testsuits = [] # testsuit module, name, time, num, flag for failed tests
     27     overall_time = 0
     28 
     29     seen = set()
     30     for arg in args:
     31         if ("*" in arg) or ("?" in arg):
     32             flist = [os.path.abspath(f) for f in glob.glob(arg)]
     33             flist = sorted(flist, key= lambda text: str(text).replace("M", "_"))
     34             files.extend([ x for x in flist if x not in seen and not seen.add(x)])
     35         else:
     36             fname = os.path.abspath(arg)
     37             if fname not in seen and not seen.add(fname):
     38                 files.append(fname)
     39 
     40             file = os.path.abspath(fname)
     41             if not os.path.isfile(file):
     42                 sys.stderr.write("IOError reading \"" + file + "\" - " + str(err) + os.linesep)
     43                 parser.print_help()
     44                 exit(0)
     45 
     46             fname = os.path.basename(fname)
     47             find_module_name = re.search(r'([^_]*)', fname)
     48             module_name = find_module_name.group(0)
     49 
     50             test_sets = []
     51             try:
     52                 tests = testlog_parser.parseLogFile(file)
     53                 if tests:
     54                     test_sets.append((os.path.basename(file), tests))
     55             except IOError as err:
     56                 sys.stderr.write("IOError reading \"" + file + "\" - " + str(err) + os.linesep)
     57             except xml.parsers.expat.ExpatError as err:
     58                 sys.stderr.write("ExpatError reading \"" + file + "\" - " + str(err) + os.linesep)
     59 
     60             if not test_sets:
     61                 continue
     62 
     63             # find matches
     64             setsCount = len(test_sets)
     65             test_cases = {}
     66 
     67             name_extractor = lambda name: str(name)
     68 
     69             for i in range(setsCount):
     70                 for case in test_sets[i][1]:
     71                     name = name_extractor(case)
     72                     if name not in test_cases:
     73                         test_cases[name] = [None] * setsCount
     74                     test_cases[name][i] = case
     75 
     76             prevGroupName = None
     77             suit_time = 0
     78             suit_num = 0
     79             fails_num = 0
     80             for name in sorted(test_cases.iterkeys(), key=alphanum_keyselector):
     81                 cases = test_cases[name]
     82 
     83                 groupName = next(c for c in cases if c).shortName()
     84                 if groupName != prevGroupName:
     85                     if prevGroupName != None:
     86                         suit_time = suit_time/60 #from seconds to minutes
     87                         testsuits.append({'module': module_name, 'name': prevGroupName, \
     88                             'time': suit_time, 'num': suit_num, 'failed': fails_num})
     89                         overall_time += suit_time
     90                         suit_time = 0
     91                         suit_num = 0
     92                         fails_num = 0
     93                     prevGroupName = groupName
     94 
     95                 for i in range(setsCount):
     96                     case = cases[i]
     97                     if not case is None:
     98                         suit_num += 1
     99                         if case.get('status') == 'run':
    100                             suit_time += case.get('time')
    101                         if case.get('status') == 'failed':
    102                             fails_num += 1
    103 
    104             # last testsuit processing
    105             suit_time = suit_time/60
    106             testsuits.append({'module': module_name, 'name': prevGroupName, \
    107                 'time': suit_time, 'num': suit_num, 'failed': fails_num})
    108             overall_time += suit_time
    109 
    110     if len(testsuits)==0:
    111         exit(0)
    112 
    113     tbl = table()
    114     rows = 0
    115 
    116     if not options.failedOnly:
    117         tbl.newColumn('module', 'Module', align = 'left', cssclass = 'col_name')
    118         tbl.newColumn('name', 'Testsuit', align = 'left', cssclass = 'col_name')
    119         tbl.newColumn('time', 'Time (min)', align = 'center', cssclass = 'col_name')
    120         tbl.newColumn('num', 'Num of tests', align = 'center', cssclass = 'col_name')
    121         tbl.newColumn('failed', 'Failed', align = 'center', cssclass = 'col_name')
    122 
    123         # rows
    124         for suit in sorted(testsuits, key = lambda suit: suit['time'], reverse = True):
    125             tbl.newRow()
    126             tbl.newCell('module', suit['module'])
    127             tbl.newCell('name', suit['name'])
    128             tbl.newCell('time', formatValue(suit['time'], '', ''), suit['time'])
    129             tbl.newCell('num', suit['num'])
    130             if (suit['failed'] != 0):
    131                 tbl.newCell('failed', suit['failed'])
    132             else:
    133                 tbl.newCell('failed', ' ')
    134             rows += 1
    135 
    136     else:
    137         tbl.newColumn('module', 'Module', align = 'left', cssclass = 'col_name')
    138         tbl.newColumn('name', 'Testsuit', align = 'left', cssclass = 'col_name')
    139         tbl.newColumn('failed', 'Failed', align = 'center', cssclass = 'col_name')
    140 
    141         # rows
    142         for suit in sorted(testsuits, key = lambda suit: suit['time'], reverse = True):
    143             if (suit['failed'] != 0):
    144                 tbl.newRow()
    145                 tbl.newCell('module', suit['module'])
    146                 tbl.newCell('name', suit['name'])
    147                 tbl.newCell('failed', suit['failed'])
    148                 rows += 1
    149 
    150     # output table
    151     if rows:
    152         if options.generateHtml:
    153             tbl.htmlPrintTable(sys.stdout)
    154             htmlPrintFooter(sys.stdout)
    155         else:
    156             if not options.failedOnly:
    157                 print '\nOverall time: %.2f min\n' % overall_time
    158             tbl.consolePrintTable(sys.stdout)
    159             print 2 * '\n'
    160