1from __future__ import absolute_import 2import inspect 3import os 4import sys 5 6import lit.Test 7import lit.formats 8import lit.TestingConfig 9import lit.util 10 11class LitConfig: 12 """LitConfig - Configuration data for a 'lit' test runner instance, shared 13 across all tests. 14 15 The LitConfig object is also used to communicate with client configuration 16 files, it is always passed in as the global variable 'lit' so that 17 configuration files can access common functionality and internal components 18 easily. 19 """ 20 21 def __init__(self, progname, path, quiet, 22 useValgrind, valgrindLeakCheck, valgrindArgs, 23 noExecute, debug, isWindows, 24 params, config_prefix = None): 25 # The name of the test runner. 26 self.progname = progname 27 # The items to add to the PATH environment variable. 28 self.path = [str(p) for p in path] 29 self.quiet = bool(quiet) 30 self.useValgrind = bool(useValgrind) 31 self.valgrindLeakCheck = bool(valgrindLeakCheck) 32 self.valgrindUserArgs = list(valgrindArgs) 33 self.noExecute = noExecute 34 self.debug = debug 35 self.isWindows = bool(isWindows) 36 self.params = dict(params) 37 self.bashPath = None 38 39 # Configuration files to look for when discovering test suites. 40 self.config_prefix = config_prefix or 'lit' 41 self.config_name = '%s.cfg' % (self.config_prefix,) 42 self.site_config_name = '%s.site.cfg' % (self.config_prefix,) 43 self.local_config_name = '%s.local.cfg' % (self.config_prefix,) 44 45 self.numErrors = 0 46 self.numWarnings = 0 47 48 self.valgrindArgs = [] 49 if self.useValgrind: 50 self.valgrindArgs = ['valgrind', '-q', '--run-libc-freeres=no', 51 '--tool=memcheck', '--trace-children=yes', 52 '--error-exitcode=123'] 53 if self.valgrindLeakCheck: 54 self.valgrindArgs.append('--leak-check=full') 55 else: 56 # The default is 'summary'. 57 self.valgrindArgs.append('--leak-check=no') 58 self.valgrindArgs.extend(self.valgrindUserArgs) 59 60 61 def load_config(self, config, path): 62 """load_config(config, path) - Load a config object from an alternate 63 path.""" 64 if self.debug: 65 self.note('load_config from %r' % path) 66 config.load_from_path(path, self) 67 return config 68 69 def getBashPath(self): 70 """getBashPath - Get the path to 'bash'""" 71 if self.bashPath is not None: 72 return self.bashPath 73 74 self.bashPath = lit.util.which('bash', os.pathsep.join(self.path)) 75 if self.bashPath is None: 76 self.bashPath = lit.util.which('bash') 77 78 if self.bashPath is None: 79 self.bashPath = '' 80 81 return self.bashPath 82 83 def getToolsPath(self, dir, paths, tools): 84 if dir is not None and os.path.isabs(dir) and os.path.isdir(dir): 85 if not lit.util.checkToolsPath(dir, tools): 86 return None 87 else: 88 dir = lit.util.whichTools(tools, paths) 89 90 # bash 91 self.bashPath = lit.util.which('bash', dir) 92 if self.bashPath is None: 93 self.bashPath = '' 94 95 return dir 96 97 def _write_message(self, kind, message): 98 # Get the file/line where this message was generated. 99 f = inspect.currentframe() 100 # Step out of _write_message, and then out of wrapper. 101 f = f.f_back.f_back 102 file,line,_,_,_ = inspect.getframeinfo(f) 103 location = '%s:%d' % (os.path.basename(file), line) 104 105 sys.stderr.write('%s: %s: %s: %s\n' % (self.progname, location, 106 kind, message)) 107 108 def note(self, message): 109 self._write_message('note', message) 110 111 def warning(self, message): 112 self._write_message('warning', message) 113 self.numWarnings += 1 114 115 def error(self, message): 116 self._write_message('error', message) 117 self.numErrors += 1 118 119 def fatal(self, message): 120 self._write_message('fatal', message) 121 sys.exit(2) 122