109467b48Spatrickimport os 209467b48Spatrickimport sys 309467b48Spatrick 409467b48Spatrick 5097a140dSpatrickclass TestingConfig(object): 609467b48Spatrick """" 709467b48Spatrick TestingConfig - Information on the tests inside a suite. 809467b48Spatrick """ 909467b48Spatrick 1009467b48Spatrick @staticmethod 1109467b48Spatrick def fromdefaults(litConfig): 1209467b48Spatrick """ 1309467b48Spatrick fromdefaults(litConfig) -> TestingConfig 1409467b48Spatrick 1509467b48Spatrick Create a TestingConfig object with default values. 1609467b48Spatrick """ 1709467b48Spatrick # Set the environment based on the command line arguments. 1809467b48Spatrick environment = { 1909467b48Spatrick 'PATH' : os.pathsep.join(litConfig.path + 2009467b48Spatrick [os.environ.get('PATH','')]), 2109467b48Spatrick 'LLVM_DISABLE_CRASH_REPORT' : '1', 2209467b48Spatrick } 2309467b48Spatrick 24*d415bd75Srobert pass_vars = [ 25*d415bd75Srobert 'LIBRARY_PATH', 26*d415bd75Srobert 'LD_LIBRARY_PATH', 27*d415bd75Srobert 'SYSTEMROOT', 28*d415bd75Srobert 'TERM', 29*d415bd75Srobert 'CLANG', 30*d415bd75Srobert 'LLDB', 31*d415bd75Srobert 'LD_PRELOAD', 32*d415bd75Srobert 'LLVM_SYMBOLIZER_PATH', 33*d415bd75Srobert 'ASAN_SYMBOLIZER_PATH', 34*d415bd75Srobert 'HWASAN_SYMBOLIZER_PATH', 35*d415bd75Srobert 'LSAN_SYMBOLIZER_PATH', 36*d415bd75Srobert 'MSAN_SYMBOLIZER_PATH', 37*d415bd75Srobert 'TSAN_SYMBOLIZER_PATH', 38*d415bd75Srobert 'UBSAN_SYMBOLIZER_PATH', 39*d415bd75Srobert 'ASAN_OPTIONS', 40*d415bd75Srobert 'LSAN_OPTIONS', 41*d415bd75Srobert 'HWASAN_OPTIONS', 42*d415bd75Srobert 'MSAN_OPTIONS', 43*d415bd75Srobert 'TSAN_OPTIONS', 44*d415bd75Srobert 'UBSAN_OPTIONS', 45*d415bd75Srobert 'ADB', 46*d415bd75Srobert 'ANDROID_SERIAL', 47*d415bd75Srobert 'SSH_AUTH_SOCK', 48*d415bd75Srobert 'SANITIZER_IGNORE_CVE_2016_2143', 49*d415bd75Srobert 'TMPDIR', 50*d415bd75Srobert 'TMP', 51*d415bd75Srobert 'TEMP', 52*d415bd75Srobert 'TEMPDIR', 53*d415bd75Srobert 'AVRLIT_BOARD', 54*d415bd75Srobert 'AVRLIT_PORT', 55*d415bd75Srobert 'FILECHECK_OPTS', 56*d415bd75Srobert 'VCINSTALLDIR', 57*d415bd75Srobert 'VCToolsinstallDir', 58*d415bd75Srobert 'VSINSTALLDIR', 59*d415bd75Srobert 'WindowsSdkDir', 60*d415bd75Srobert 'WindowsSDKLibVersion', 61*d415bd75Srobert 'SOURCE_DATE_EPOCH', 62*d415bd75Srobert 'GTEST_FILTER', 63*d415bd75Srobert 'DFLTCC', 64*d415bd75Srobert ] 6509467b48Spatrick 66*d415bd75Srobert if sys.platform.startswith('aix'): 67*d415bd75Srobert pass_vars += ['LIBPATH'] 68*d415bd75Srobert elif sys.platform == 'win32': 69*d415bd75Srobert pass_vars += [ 70*d415bd75Srobert 'COMSPEC', 71*d415bd75Srobert 'INCLUDE', 72*d415bd75Srobert 'LIB', 73*d415bd75Srobert 'PATHEXT', 74*d415bd75Srobert 'USERPROFILE', 75*d415bd75Srobert ] 7609467b48Spatrick environment['PYTHONBUFFERED'] = '1' 7709467b48Spatrick 7809467b48Spatrick for var in pass_vars: 7909467b48Spatrick val = os.environ.get(var, '') 8009467b48Spatrick # Check for empty string as some variables such as LD_PRELOAD cannot be empty 8109467b48Spatrick # ('') for OS's such as OpenBSD. 8209467b48Spatrick if val: 8309467b48Spatrick environment[var] = val 8409467b48Spatrick 8509467b48Spatrick # Set the default available features based on the LitConfig. 8609467b48Spatrick available_features = [] 8709467b48Spatrick if litConfig.useValgrind: 8809467b48Spatrick available_features.append('valgrind') 8909467b48Spatrick if litConfig.valgrindLeakCheck: 9009467b48Spatrick available_features.append('vg_leak') 9109467b48Spatrick 9209467b48Spatrick return TestingConfig(None, 9309467b48Spatrick name = '<unnamed>', 9409467b48Spatrick suffixes = set(), 9509467b48Spatrick test_format = None, 9609467b48Spatrick environment = environment, 9709467b48Spatrick substitutions = [], 9809467b48Spatrick unsupported = False, 9909467b48Spatrick test_exec_root = None, 10009467b48Spatrick test_source_root = None, 10109467b48Spatrick excludes = [], 10209467b48Spatrick available_features = available_features, 10373471bf0Spatrick pipefail = True, 10473471bf0Spatrick standalone_tests = False) 10509467b48Spatrick 10609467b48Spatrick def load_from_path(self, path, litConfig): 10709467b48Spatrick """ 10809467b48Spatrick load_from_path(path, litConfig) 10909467b48Spatrick 11009467b48Spatrick Load the configuration module at the provided path into the given config 11109467b48Spatrick object. 11209467b48Spatrick """ 11309467b48Spatrick 11409467b48Spatrick # Load the config script data. 11509467b48Spatrick data = None 11609467b48Spatrick f = open(path) 11709467b48Spatrick try: 11809467b48Spatrick data = f.read() 11909467b48Spatrick except: 12009467b48Spatrick litConfig.fatal('unable to load config file: %r' % (path,)) 12109467b48Spatrick f.close() 12209467b48Spatrick 12309467b48Spatrick # Execute the config script to initialize the object. 12409467b48Spatrick cfg_globals = dict(globals()) 12509467b48Spatrick cfg_globals['config'] = self 12609467b48Spatrick cfg_globals['lit_config'] = litConfig 12709467b48Spatrick cfg_globals['__file__'] = path 12809467b48Spatrick try: 12909467b48Spatrick exec(compile(data, path, 'exec'), cfg_globals, None) 13009467b48Spatrick if litConfig.debug: 13109467b48Spatrick litConfig.note('... loaded config %r' % path) 13209467b48Spatrick except SystemExit: 13309467b48Spatrick e = sys.exc_info()[1] 13409467b48Spatrick # We allow normal system exit inside a config file to just 13509467b48Spatrick # return control without error. 13609467b48Spatrick if e.args: 13709467b48Spatrick raise 13809467b48Spatrick except: 13909467b48Spatrick import traceback 14009467b48Spatrick litConfig.fatal( 14109467b48Spatrick 'unable to parse config file %r, traceback: %s' % ( 14209467b48Spatrick path, traceback.format_exc())) 14309467b48Spatrick self.finish(litConfig) 14409467b48Spatrick 14509467b48Spatrick def __init__(self, parent, name, suffixes, test_format, 14609467b48Spatrick environment, substitutions, unsupported, 14709467b48Spatrick test_exec_root, test_source_root, excludes, 14809467b48Spatrick available_features, pipefail, limit_to_features = [], 14973471bf0Spatrick is_early = False, parallelism_group = None, 15073471bf0Spatrick standalone_tests = False): 15109467b48Spatrick self.parent = parent 15209467b48Spatrick self.name = str(name) 15309467b48Spatrick self.suffixes = set(suffixes) 15409467b48Spatrick self.test_format = test_format 15509467b48Spatrick self.environment = dict(environment) 15609467b48Spatrick self.substitutions = list(substitutions) 15709467b48Spatrick self.unsupported = unsupported 15809467b48Spatrick self.test_exec_root = test_exec_root 15909467b48Spatrick self.test_source_root = test_source_root 16009467b48Spatrick self.excludes = set(excludes) 16109467b48Spatrick self.available_features = set(available_features) 16209467b48Spatrick self.pipefail = pipefail 16373471bf0Spatrick self.standalone_tests = standalone_tests 16409467b48Spatrick # This list is used by TestRunner.py to restrict running only tests that 16509467b48Spatrick # require one of the features in this list if this list is non-empty. 16609467b48Spatrick # Configurations can set this list to restrict the set of tests to run. 16709467b48Spatrick self.limit_to_features = set(limit_to_features) 16809467b48Spatrick self.parallelism_group = parallelism_group 169097a140dSpatrick self._recursiveExpansionLimit = None 170097a140dSpatrick 171097a140dSpatrick @property 172097a140dSpatrick def recursiveExpansionLimit(self): 173097a140dSpatrick return self._recursiveExpansionLimit 174097a140dSpatrick 175097a140dSpatrick @recursiveExpansionLimit.setter 176097a140dSpatrick def recursiveExpansionLimit(self, value): 177097a140dSpatrick if value is not None and not isinstance(value, int): 178097a140dSpatrick raise ValueError('recursiveExpansionLimit must be either None or an integer (got <{}>)'.format(value)) 179097a140dSpatrick if isinstance(value, int) and value < 0: 180097a140dSpatrick raise ValueError('recursiveExpansionLimit must be a non-negative integer (got <{}>)'.format(value)) 181097a140dSpatrick self._recursiveExpansionLimit = value 18209467b48Spatrick 18309467b48Spatrick def finish(self, litConfig): 18409467b48Spatrick """finish() - Finish this config object, after loading is complete.""" 18509467b48Spatrick 18609467b48Spatrick self.name = str(self.name) 18709467b48Spatrick self.suffixes = set(self.suffixes) 18809467b48Spatrick self.environment = dict(self.environment) 18909467b48Spatrick self.substitutions = list(self.substitutions) 19009467b48Spatrick if self.test_exec_root is not None: 19109467b48Spatrick # FIXME: This should really only be suite in test suite config 19209467b48Spatrick # files. Should we distinguish them? 19309467b48Spatrick self.test_exec_root = str(self.test_exec_root) 19409467b48Spatrick if self.test_source_root is not None: 19509467b48Spatrick # FIXME: This should really only be suite in test suite config 19609467b48Spatrick # files. Should we distinguish them? 19709467b48Spatrick self.test_source_root = str(self.test_source_root) 19809467b48Spatrick self.excludes = set(self.excludes) 19909467b48Spatrick 20009467b48Spatrick @property 20109467b48Spatrick def root(self): 20209467b48Spatrick """root attribute - The root configuration for the test suite.""" 20309467b48Spatrick if self.parent is None: 20409467b48Spatrick return self 20509467b48Spatrick else: 20609467b48Spatrick return self.parent.root 20709467b48Spatrick 20809467b48Spatrickclass SubstituteCaptures: 20909467b48Spatrick """ 21009467b48Spatrick Helper class to indicate that the substitutions contains backreferences. 21109467b48Spatrick 21209467b48Spatrick This can be used as the following in lit.cfg to mark subsitutions as having 21309467b48Spatrick back-references:: 21409467b48Spatrick 21509467b48Spatrick config.substutions.append(('\b[^ ]*.cpp', SubstituteCaptures('\0.txt'))) 21609467b48Spatrick 21709467b48Spatrick """ 21809467b48Spatrick def __init__(self, substitution): 21909467b48Spatrick self.substitution = substitution 22009467b48Spatrick 22109467b48Spatrick def replace(self, pattern, replacement): 22209467b48Spatrick return self.substitution 22309467b48Spatrick 22409467b48Spatrick def __str__(self): 22509467b48Spatrick return self.substitution 22609467b48Spatrick 22709467b48Spatrick def __len__(self): 22809467b48Spatrick return len(self.substitution) 22909467b48Spatrick 23009467b48Spatrick def __getitem__(self, item): 23109467b48Spatrick return self.substitution.__getitem__(item) 23209467b48Spatrick 233