1 from __future__ import absolute_import
8 import lit.TestingConfig
11 # LitConfig must be a new style class for properties to work
12 class LitConfig(object):
13 """LitConfig - Configuration data for a 'lit' test runner instance, shared
16 The LitConfig object is also used to communicate with client configuration
17 files, it is always passed in as the global variable 'lit' so that
18 configuration files can access common functionality and internal components
22 def __init__(self, progname, path, quiet,
23 useValgrind, valgrindLeakCheck, valgrindArgs,
24 noExecute, debug, isWindows,
25 params, config_prefix = None,
26 maxIndividualTestTime = 0):
27 # The name of the test runner.
28 self.progname = progname
29 # The items to add to the PATH environment variable.
30 self.path = [str(p) for p in path]
31 self.quiet = bool(quiet)
32 self.useValgrind = bool(useValgrind)
33 self.valgrindLeakCheck = bool(valgrindLeakCheck)
34 self.valgrindUserArgs = list(valgrindArgs)
35 self.noExecute = noExecute
37 self.isWindows = bool(isWindows)
38 self.params = dict(params)
41 # Configuration files to look for when discovering test suites.
42 self.config_prefix = config_prefix or 'lit'
43 self.config_name = '%s.cfg' % (self.config_prefix,)
44 self.site_config_name = '%s.site.cfg' % (self.config_prefix,)
45 self.local_config_name = '%s.local.cfg' % (self.config_prefix,)
50 self.valgrindArgs = []
52 self.valgrindArgs = ['valgrind', '-q', '--run-libc-freeres=no',
53 '--tool=memcheck', '--trace-children=yes',
54 '--error-exitcode=123']
55 if self.valgrindLeakCheck:
56 self.valgrindArgs.append('--leak-check=full')
58 # The default is 'summary'.
59 self.valgrindArgs.append('--leak-check=no')
60 self.valgrindArgs.extend(self.valgrindUserArgs)
62 self.maxIndividualTestTime = maxIndividualTestTime
65 def maxIndividualTestTime(self):
67 Interface for getting maximum time to spend executing
70 return self._maxIndividualTestTime
72 @maxIndividualTestTime.setter
73 def maxIndividualTestTime(self, value):
75 Interface for setting maximum time to spend executing
78 self._maxIndividualTestTime = value
79 if self.maxIndividualTestTime > 0:
80 # The current implementation needs psutil to set
81 # a timeout per test. Check it's available.
82 # See lit.util.killProcessAndChildren()
86 self.fatal("Setting a timeout per test requires the"
87 " Python psutil module but it could not be"
88 " found. Try installing it via pip or via"
89 " your operating system's package manager.")
90 elif self.maxIndividualTestTime < 0:
91 self.fatal('The timeout per test must be >= 0 seconds')
93 def load_config(self, config, path):
94 """load_config(config, path) - Load a config object from an alternate
97 self.note('load_config from %r' % path)
98 config.load_from_path(path, self)
101 def getBashPath(self):
102 """getBashPath - Get the path to 'bash'"""
103 if self.bashPath is not None:
106 self.bashPath = lit.util.which('bash', os.pathsep.join(self.path))
107 if self.bashPath is None:
108 self.bashPath = lit.util.which('bash')
110 if self.bashPath is None:
115 def getToolsPath(self, dir, paths, tools):
116 if dir is not None and os.path.isabs(dir) and os.path.isdir(dir):
117 if not lit.util.checkToolsPath(dir, tools):
120 dir = lit.util.whichTools(tools, paths)
123 self.bashPath = lit.util.which('bash', dir)
124 if self.bashPath is None:
129 def _write_message(self, kind, message):
130 # Get the file/line where this message was generated.
131 f = inspect.currentframe()
132 # Step out of _write_message, and then out of wrapper.
134 file,line,_,_,_ = inspect.getframeinfo(f)
135 location = '%s:%d' % (os.path.basename(file), line)
137 sys.stderr.write('%s: %s: %s: %s\n' % (self.progname, location,
140 def note(self, message):
141 self._write_message('note', message)
143 def warning(self, message):
144 self._write_message('warning', message)
145 self.numWarnings += 1
147 def error(self, message):
148 self._write_message('error', message)
151 def fatal(self, message):
152 self._write_message('fatal', message)