1be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbarclass LitConfig: 2be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar """LitConfig - Configuration data for a 'lit' test runner instance, shared 3be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar across all tests. 4be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 5be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar The LitConfig object is also used to communicate with client configuration 6be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar files, it is always passed in as the global variable 'lit' so that 7be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar configuration files can access common functionality and internal components 8be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar easily. 9be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar """ 10be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 11c2be84fd490d2e0a8de1731adf9c996ba15bba5cDaniel Dunbar # Provide access to Test module. 12c2be84fd490d2e0a8de1731adf9c996ba15bba5cDaniel Dunbar import Test 13c2be84fd490d2e0a8de1731adf9c996ba15bba5cDaniel Dunbar 14be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Provide access to built-in formats. 15be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar import LitFormats as formats 16be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 17be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Provide access to built-in utility functions. 18be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar import Util as util 19be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 20be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar def __init__(self, progname, path, quiet, 2132989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin useValgrind, valgrindLeakCheck, valgrindArgs, 22be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar useTclAsSh, 237c12837916e647a9225fe2433f826588f2f28726Andrew Trick noExecute, ignoreStdErr, debug, isWindows, 24f626167e69d08f500805d209ff80720240adde3fDaniel Dunbar params): 25be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # The name of the test runner. 26be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.progname = progname 27be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # The items to add to the PATH environment variable. 28be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.path = list(map(str, path)) 29be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.quiet = bool(quiet) 30be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.useValgrind = bool(useValgrind) 3132989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin self.valgrindLeakCheck = bool(valgrindLeakCheck) 3232989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin self.valgrindUserArgs = list(valgrindArgs) 33be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.useTclAsSh = bool(useTclAsSh) 34be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.noExecute = noExecute 357c12837916e647a9225fe2433f826588f2f28726Andrew Trick self.ignoreStdErr = ignoreStdErr 36be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.debug = debug 37be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.isWindows = bool(isWindows) 38f626167e69d08f500805d209ff80720240adde3fDaniel Dunbar self.params = dict(params) 397723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar self.bashPath = None 40be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 41be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.numErrors = 0 42be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.numWarnings = 0 43be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 4432989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin self.valgrindArgs = [] 4532989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin self.valgrindTriple = "" 4632989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin if self.useValgrind: 4732989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin self.valgrindTriple = "-vg" 4832989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin self.valgrindArgs = ['valgrind', '-q', '--run-libc-freeres=no', 4932989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin '--tool=memcheck', '--trace-children=yes', 5032989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin '--error-exitcode=123'] 5132989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin if self.valgrindLeakCheck: 5232989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin self.valgrindTriple += "_leak" 5332989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin self.valgrindArgs.append('--leak-check=full') 54982873cdfb3faa9fc06a5b9ce6296bfddc0b05c3Jeffrey Yasskin else: 55982873cdfb3faa9fc06a5b9ce6296bfddc0b05c3Jeffrey Yasskin # The default is 'summary'. 56982873cdfb3faa9fc06a5b9ce6296bfddc0b05c3Jeffrey Yasskin self.valgrindArgs.append('--leak-check=no') 5732989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin self.valgrindArgs.extend(self.valgrindUserArgs) 5832989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin 5932989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin 60be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar def load_config(self, config, path): 61be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar """load_config(config, path) - Load a config object from an alternate 62be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar path.""" 63be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar from TestingConfig import TestingConfig 64d0b3da1ea266774f97c63b5ec163de964c5711bfAndrew Trick if self.debug: 65d0b3da1ea266774f97c63b5ec163de964c5711bfAndrew Trick self.note('load_config from %r' % path) 66be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return TestingConfig.frompath(path, config.parent, self, 67be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar mustExist = True, 68be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar config = config) 69be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 707723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar def getBashPath(self): 717723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar """getBashPath - Get the path to 'bash'""" 727723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar import os, Util 737723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar 747723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar if self.bashPath is not None: 757723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar return self.bashPath 767723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar 777723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar self.bashPath = Util.which('bash', os.pathsep.join(self.path)) 787723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar if self.bashPath is None: 797723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar # Check some known paths. 80b0ac8677fdcfacea2ff62251ea6515fe6665e37eDaniel Dunbar for path in ('/bin/bash', '/usr/bin/bash', '/usr/local/bin/bash'): 817723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar if os.path.exists(path): 827723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar self.bashPath = path 837723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar break 847723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar 857723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar if self.bashPath is None: 867723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar self.warning("Unable to find 'bash', running Tcl tests internally.") 877723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar self.bashPath = '' 887723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar 897723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar return self.bashPath 907723d45153c5610349486121e2b50b5ba60b2f5cDaniel Dunbar 91302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi def getToolsPath(self, dir, paths, tools): 92302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi import os, Util 93302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi if dir is not None and os.path.isabs(dir) and os.path.isdir(dir): 94302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi if not Util.checkToolsPath(dir, tools): 95302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi return None 96302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi else: 97302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi dir = Util.whichTools(tools, paths) 98302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi 99302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi # bash 100302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi self.bashPath = Util.which('bash', dir) 101302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi if self.bashPath is None: 1026bb5fe3a0d7cf92cd5e77382f1c737a919ab7669NAKAMURA Takumi self.note("Unable to find 'bash.exe'.") 103302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi self.bashPath = '' 104302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi 105302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi return dir 106302b16932332fc3eb46a3a65f33597ab1519988aNAKAMURA Takumi 107be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar def _write_message(self, kind, message): 108be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar import inspect, os, sys 109be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 110be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Get the file/line where this message was generated. 111be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar f = inspect.currentframe() 112be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Step out of _write_message, and then out of wrapper. 113be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar f = f.f_back.f_back 114be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar file,line,_,_,_ = inspect.getframeinfo(f) 115be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar location = '%s:%d' % (os.path.basename(file), line) 116be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 117be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar print >>sys.stderr, '%s: %s: %s: %s' % (self.progname, location, 118be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar kind, message) 119be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 120be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar def note(self, message): 121be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self._write_message('note', message) 122be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 123be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar def warning(self, message): 124be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self._write_message('warning', message) 125be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.numWarnings += 1 126be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 127be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar def error(self, message): 128be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self._write_message('error', message) 129be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self.numErrors += 1 130be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 131be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar def fatal(self, message): 132be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar import sys 133be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar self._write_message('fatal', message) 134be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar sys.exit(2) 135