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