1 # Copyright 2011 Google Inc. All Rights Reserved. 2 # Author: kbaclawski (at] google.com (Krystian Baclawski) 3 # 4 5 from contextlib import contextmanager 6 import glob 7 from itertools import chain 8 import logging 9 import optparse 10 import os.path 11 import sys 12 13 from manifest import Manifest 14 import report 15 from summary import DejaGnuTestRun 16 17 18 def ExpandGlobExprList(paths): 19 """Returns an iterator that goes over expanded glob paths.""" 20 return chain.from_iterable(map(glob.glob, paths)) 21 22 23 @contextmanager 24 def OptionChecker(parser): 25 """Provides scoped environment for command line option checking.""" 26 try: 27 yield 28 except SystemExit as ex: 29 parser.print_help() 30 print '' 31 sys.exit('ERROR: %s' % str(ex)) 32 33 34 def ManifestCommand(argv): 35 parser = optparse.OptionParser( 36 description= 37 ('Read in one or more DejaGNU summary files (.sum), parse their ' 38 'content and generate manifest files. Manifest files store a list ' 39 'of failed tests that should be ignored. Generated files are ' 40 'stored in current directory under following name: ' 41 '${tool}-${board}.xfail (e.g. "gcc-unix.xfail").'), 42 usage='Usage: %prog manifest [file.sum] (file2.sum ...)') 43 44 _, args = parser.parse_args(argv[2:]) 45 46 with OptionChecker(parser): 47 if not args: 48 sys.exit('At least one *.sum file required.') 49 50 for filename in chain.from_iterable(map(glob.glob, args)): 51 test_run = DejaGnuTestRun.FromFile(filename) 52 53 manifest = Manifest.FromDejaGnuTestRun(test_run) 54 manifest_filename = '%s-%s.xfail' % (test_run.tool, test_run.board) 55 56 with open(manifest_filename, 'w') as manifest_file: 57 manifest_file.write(manifest.Generate()) 58 59 logging.info('Wrote manifest to "%s" file.', manifest_filename) 60 61 62 def ReportCommand(argv): 63 parser = optparse.OptionParser( 64 description= 65 ('Read in one or more DejaGNU summary files (.sum), parse their ' 66 'content and generate a single report file in selected format ' 67 '(currently only HTML).'), 68 usage=('Usage: %prog report (-m manifest.xfail) [-o report.html] ' 69 '[file.sum (file2.sum ...)')) 70 parser.add_option( 71 '-o', 72 dest='output', 73 type='string', 74 default=None, 75 help=('Suppress failures for test listed in provided manifest files. ' 76 '(use -m for each manifest file you want to read)')) 77 parser.add_option( 78 '-m', 79 dest='manifests', 80 type='string', 81 action='append', 82 default=None, 83 help=('Suppress failures for test listed in provided manifest files. ' 84 '(use -m for each manifest file you want to read)')) 85 86 opts, args = parser.parse_args(argv[2:]) 87 88 with OptionChecker(parser): 89 if not args: 90 sys.exit('At least one *.sum file required.') 91 92 if not opts.output: 93 sys.exit('Please provide name for report file.') 94 95 manifests = [] 96 97 for filename in ExpandGlobExprList(opts.manifests or []): 98 logging.info('Using "%s" manifest.', filename) 99 manifests.append(Manifest.FromFile(filename)) 100 101 test_runs = [DejaGnuTestRun.FromFile(filename) 102 for filename in chain.from_iterable(map(glob.glob, args))] 103 104 html = report.Generate(test_runs, manifests) 105 106 if html: 107 with open(opts.output, 'w') as html_file: 108 html_file.write(html) 109 logging.info('Wrote report to "%s" file.', opts.output) 110 else: 111 sys.exit(1) 112 113 114 def HelpCommand(argv): 115 sys.exit('\n'.join([ 116 'Usage: %s command [options]' % os.path.basename(argv[ 117 0]), '', 'Commands:', 118 ' manifest - manage files containing a list of suppressed test failures', 119 ' report - generate report file for selected test runs' 120 ])) 121 122 123 def Main(argv): 124 try: 125 cmd_name = argv[1] 126 except IndexError: 127 cmd_name = None 128 129 cmd_map = {'manifest': ManifestCommand, 'report': ReportCommand} 130 cmd_map.get(cmd_name, HelpCommand)(argv) 131 132 133 if __name__ == '__main__': 134 FORMAT = '%(asctime)-15s %(levelname)s %(message)s' 135 logging.basicConfig(format=FORMAT, level=logging.INFO) 136 137 Main(sys.argv) 138