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.warning("Unable to find 'bash'.") 80 self.bashPath = '' 81 82 return self.bashPath 83 84 def getToolsPath(self, dir, paths, tools): 85 if dir is not None and os.path.isabs(dir) and os.path.isdir(dir): 86 if not lit.util.checkToolsPath(dir, tools): 87 return None 88 else: 89 dir = lit.util.whichTools(tools, paths) 90 91 # bash 92 self.bashPath = lit.util.which('bash', dir) 93 if self.bashPath is None: 94 self.note("Unable to find 'bash.exe'.") 95 self.bashPath = '' 96 97 return dir 98 99 def _write_message(self, kind, message): 100 # Get the file/line where this message was generated. 101 f = inspect.currentframe() 102 # Step out of _write_message, and then out of wrapper. 103 f = f.f_back.f_back 104 file,line,_,_,_ = inspect.getframeinfo(f) 105 location = '%s:%d' % (os.path.basename(file), line) 106 107 sys.stderr.write('%s: %s: %s: %s\n' % (self.progname, location, 108 kind, message)) 109 110 def note(self, message): 111 self._write_message('note', message) 112 113 def warning(self, message): 114 self._write_message('warning', message) 115 self.numWarnings += 1 116 117 def error(self, message): 118 self._write_message('error', message) 119 self.numErrors += 1 120 121 def fatal(self, message): 122 self._write_message('fatal', message) 123 sys.exit(2) 124