1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass LitConfig: 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman """LitConfig - Configuration data for a 'lit' test runner instance, shared 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman across all tests. 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman The LitConfig object is also used to communicate with client configuration 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman files, it is always passed in as the global variable 'lit' so that 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman configuration files can access common functionality and internal components 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman easily. 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman """ 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman # Provide access to Test module. 1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman import Test 1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman # Provide access to built-in formats. 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman import LitFormats as formats 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman # Provide access to built-in utility functions. 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman import Util as util 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman def __init__(self, progname, path, quiet, 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman useValgrind, valgrindLeakCheck, valgrindArgs, 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman useTclAsSh, 2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman noExecute, ignoreStdErr, debug, isWindows, 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman params): 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman # The name of the test runner. 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.progname = progname 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman # The items to add to the PATH environment variable. 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.path = list(map(str, path)) 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.quiet = bool(quiet) 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.useValgrind = bool(useValgrind) 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.valgrindLeakCheck = bool(valgrindLeakCheck) 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.valgrindUserArgs = list(valgrindArgs) 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.useTclAsSh = bool(useTclAsSh) 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.noExecute = noExecute 3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman self.ignoreStdErr = ignoreStdErr 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.debug = debug 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.isWindows = bool(isWindows) 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.params = dict(params) 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.bashPath = None 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.numErrors = 0 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.numWarnings = 0 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.valgrindArgs = [] 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.valgrindTriple = "" 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if self.useValgrind: 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.valgrindTriple = "-vg" 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.valgrindArgs = ['valgrind', '-q', '--run-libc-freeres=no', 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman '--tool=memcheck', '--trace-children=yes', 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman '--error-exitcode=123'] 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if self.valgrindLeakCheck: 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.valgrindTriple += "_leak" 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.valgrindArgs.append('--leak-check=full') 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else: 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman # The default is 'summary'. 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.valgrindArgs.append('--leak-check=no') 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.valgrindArgs.extend(self.valgrindUserArgs) 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman def load_config(self, config, path): 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman """load_config(config, path) - Load a config object from an alternate 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman path.""" 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman from TestingConfig import TestingConfig 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return TestingConfig.frompath(path, config.parent, self, 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mustExist = True, 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman config = config) 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman def getBashPath(self): 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman """getBashPath - Get the path to 'bash'""" 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman import os, Util 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if self.bashPath is not None: 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return self.bashPath 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.bashPath = Util.which('bash', os.pathsep.join(self.path)) 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if self.bashPath is None: 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman # Check some known paths. 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for path in ('/bin/bash', '/usr/bin/bash', '/usr/local/bin/bash'): 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if os.path.exists(path): 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.bashPath = path 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if self.bashPath is None: 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.warning("Unable to find 'bash', running Tcl tests internally.") 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.bashPath = '' 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return self.bashPath 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman def getToolsPath(self, dir, paths, tools): 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman import os, Util 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if dir is not None and os.path.isabs(dir) and os.path.isdir(dir): 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if not Util.checkToolsPath(dir, tools): 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return None 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else: 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman dir = Util.whichTools(tools, paths) 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman # bash 9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman self.bashPath = Util.which('bash', dir) 9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if self.bashPath is None: 10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman self.note("Unable to find 'bash.exe'.") 10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman self.bashPath = '' 10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return dir 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman def _write_message(self, kind, message): 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman import inspect, os, sys 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman # Get the file/line where this message was generated. 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman f = inspect.currentframe() 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman # Step out of _write_message, and then out of wrapper. 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman f = f.f_back.f_back 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman file,line,_,_,_ = inspect.getframeinfo(f) 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman location = '%s:%d' % (os.path.basename(file), line) 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman print >>sys.stderr, '%s: %s: %s: %s' % (self.progname, location, 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman kind, message) 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman def note(self, message): 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self._write_message('note', message) 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman def warning(self, message): 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self._write_message('warning', message) 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.numWarnings += 1 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman def error(self, message): 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self._write_message('error', message) 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self.numErrors += 1 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman def fatal(self, message): 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman import sys 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman self._write_message('fatal', message) 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman sys.exit(2) 133