1import os 2import sys 3 4 5class TestingConfig(object): 6 """" 7 TestingConfig - Information on the tests inside a suite. 8 """ 9 10 @staticmethod 11 def fromdefaults(litConfig): 12 """ 13 fromdefaults(litConfig) -> TestingConfig 14 15 Create a TestingConfig object with default values. 16 """ 17 # Set the environment based on the command line arguments. 18 environment = { 19 'PATH' : os.pathsep.join(litConfig.path + 20 [os.environ.get('PATH','')]), 21 'LLVM_DISABLE_CRASH_REPORT' : '1', 22 } 23 24 pass_vars = ['LIBRARY_PATH', 'LD_LIBRARY_PATH', 'SYSTEMROOT', 'TERM', 25 'CLANG', 'LD_PRELOAD', 'ASAN_OPTIONS', 'UBSAN_OPTIONS', 26 'LSAN_OPTIONS', 'ADB', 'ANDROID_SERIAL', 'SSH_AUTH_SOCK', 27 'SANITIZER_IGNORE_CVE_2016_2143', 'TMPDIR', 'TMP', 'TEMP', 28 'TEMPDIR', 'AVRLIT_BOARD', 'AVRLIT_PORT', 29 'FILECHECK_OPTS', 'VCINSTALLDIR', 'VCToolsinstallDir', 30 'VSINSTALLDIR', 'WindowsSdkDir', 'WindowsSDKLibVersion'] 31 32 if sys.platform == 'win32': 33 pass_vars.append('INCLUDE') 34 pass_vars.append('LIB') 35 pass_vars.append('PATHEXT') 36 pass_vars.append('USERPROFILE') 37 environment['PYTHONBUFFERED'] = '1' 38 39 for var in pass_vars: 40 val = os.environ.get(var, '') 41 # Check for empty string as some variables such as LD_PRELOAD cannot be empty 42 # ('') for OS's such as OpenBSD. 43 if val: 44 environment[var] = val 45 46 # Set the default available features based on the LitConfig. 47 available_features = [] 48 if litConfig.useValgrind: 49 available_features.append('valgrind') 50 if litConfig.valgrindLeakCheck: 51 available_features.append('vg_leak') 52 53 return TestingConfig(None, 54 name = '<unnamed>', 55 suffixes = set(), 56 test_format = None, 57 environment = environment, 58 substitutions = [], 59 unsupported = False, 60 test_exec_root = None, 61 test_source_root = None, 62 excludes = [], 63 available_features = available_features, 64 pipefail = True) 65 66 def load_from_path(self, path, litConfig): 67 """ 68 load_from_path(path, litConfig) 69 70 Load the configuration module at the provided path into the given config 71 object. 72 """ 73 74 # Load the config script data. 75 data = None 76 f = open(path) 77 try: 78 data = f.read() 79 except: 80 litConfig.fatal('unable to load config file: %r' % (path,)) 81 f.close() 82 83 # Execute the config script to initialize the object. 84 cfg_globals = dict(globals()) 85 cfg_globals['config'] = self 86 cfg_globals['lit_config'] = litConfig 87 cfg_globals['__file__'] = path 88 try: 89 exec(compile(data, path, 'exec'), cfg_globals, None) 90 if litConfig.debug: 91 litConfig.note('... loaded config %r' % path) 92 except SystemExit: 93 e = sys.exc_info()[1] 94 # We allow normal system exit inside a config file to just 95 # return control without error. 96 if e.args: 97 raise 98 except: 99 import traceback 100 litConfig.fatal( 101 'unable to parse config file %r, traceback: %s' % ( 102 path, traceback.format_exc())) 103 self.finish(litConfig) 104 105 def __init__(self, parent, name, suffixes, test_format, 106 environment, substitutions, unsupported, 107 test_exec_root, test_source_root, excludes, 108 available_features, pipefail, limit_to_features = [], 109 is_early = False, parallelism_group = None): 110 self.parent = parent 111 self.name = str(name) 112 self.suffixes = set(suffixes) 113 self.test_format = test_format 114 self.environment = dict(environment) 115 self.substitutions = list(substitutions) 116 self.unsupported = unsupported 117 self.test_exec_root = test_exec_root 118 self.test_source_root = test_source_root 119 self.excludes = set(excludes) 120 self.available_features = set(available_features) 121 self.pipefail = pipefail 122 # This list is used by TestRunner.py to restrict running only tests that 123 # require one of the features in this list if this list is non-empty. 124 # Configurations can set this list to restrict the set of tests to run. 125 self.limit_to_features = set(limit_to_features) 126 # Whether the suite should be tested early in a given run. 127 self.is_early = bool(is_early) 128 self.parallelism_group = parallelism_group 129 self._recursiveExpansionLimit = None 130 131 @property 132 def recursiveExpansionLimit(self): 133 return self._recursiveExpansionLimit 134 135 @recursiveExpansionLimit.setter 136 def recursiveExpansionLimit(self, value): 137 if value is not None and not isinstance(value, int): 138 raise ValueError('recursiveExpansionLimit must be either None or an integer (got <{}>)'.format(value)) 139 if isinstance(value, int) and value < 0: 140 raise ValueError('recursiveExpansionLimit must be a non-negative integer (got <{}>)'.format(value)) 141 self._recursiveExpansionLimit = value 142 143 def finish(self, litConfig): 144 """finish() - Finish this config object, after loading is complete.""" 145 146 self.name = str(self.name) 147 self.suffixes = set(self.suffixes) 148 self.environment = dict(self.environment) 149 self.substitutions = list(self.substitutions) 150 if self.test_exec_root is not None: 151 # FIXME: This should really only be suite in test suite config 152 # files. Should we distinguish them? 153 self.test_exec_root = str(self.test_exec_root) 154 if self.test_source_root is not None: 155 # FIXME: This should really only be suite in test suite config 156 # files. Should we distinguish them? 157 self.test_source_root = str(self.test_source_root) 158 self.excludes = set(self.excludes) 159 160 @property 161 def root(self): 162 """root attribute - The root configuration for the test suite.""" 163 if self.parent is None: 164 return self 165 else: 166 return self.parent.root 167 168class SubstituteCaptures: 169 """ 170 Helper class to indicate that the substitutions contains backreferences. 171 172 This can be used as the following in lit12.cfg to mark subsitutions as having 173 back-references:: 174 175 config.substutions.append(('\b[^ ]*.cpp', SubstituteCaptures('\0.txt'))) 176 177 """ 178 def __init__(self, substitution): 179 self.substitution = substitution 180 181 def replace(self, pattern, replacement): 182 return self.substitution 183 184 def __str__(self): 185 return self.substitution 186 187 def __len__(self): 188 return len(self.substitution) 189 190 def __getitem__(self, item): 191 return self.substitution.__getitem__(item) 192 193