1import os 2import sys 3 4PY2 = sys.version_info[0] < 3 5 6class TestingConfig: 7 """" 8 TestingConfig - Information on the tests inside a suite. 9 """ 10 11 @staticmethod 12 def frompath(path, parent, litConfig, mustExist, config = None): 13 if config is None: 14 # Set the environment based on the command line arguments. 15 environment = { 16 'LIBRARY_PATH' : os.environ.get('LIBRARY_PATH',''), 17 'LD_LIBRARY_PATH' : os.environ.get('LD_LIBRARY_PATH',''), 18 'PATH' : os.pathsep.join(litConfig.path + 19 [os.environ.get('PATH','')]), 20 'SYSTEMROOT' : os.environ.get('SYSTEMROOT',''), 21 'TERM' : os.environ.get('TERM',''), 22 'LLVM_DISABLE_CRASH_REPORT' : '1', 23 } 24 25 if sys.platform == 'win32': 26 environment.update({ 27 'INCLUDE' : os.environ.get('INCLUDE',''), 28 'PATHEXT' : os.environ.get('PATHEXT',''), 29 'PYTHONUNBUFFERED' : '1', 30 'TEMP' : os.environ.get('TEMP',''), 31 'TMP' : os.environ.get('TMP',''), 32 }) 33 34 # Set the default available features based on the LitConfig. 35 available_features = [] 36 if litConfig.useValgrind: 37 available_features.append('valgrind') 38 if litConfig.valgrindLeakCheck: 39 available_features.append('vg_leak') 40 41 config = TestingConfig(parent, 42 name = '<unnamed>', 43 suffixes = set(), 44 test_format = None, 45 environment = environment, 46 substitutions = [], 47 unsupported = False, 48 on_clone = None, 49 test_exec_root = None, 50 test_source_root = None, 51 excludes = [], 52 available_features = available_features, 53 pipefail = True) 54 55 if os.path.exists(path): 56 # FIXME: Improve detection and error reporting of errors in the 57 # config file. 58 f = open(path) 59 cfg_globals = dict(globals()) 60 cfg_globals['config'] = config 61 cfg_globals['lit'] = litConfig 62 cfg_globals['__file__'] = path 63 try: 64 data = f.read() 65 if PY2: 66 exec("exec data in cfg_globals") 67 else: 68 exec(data, cfg_globals) 69 if litConfig.debug: 70 litConfig.note('... loaded config %r' % path) 71 except SystemExit: 72 e = sys.exc_info()[1] 73 # We allow normal system exit inside a config file to just 74 # return control without error. 75 if e.args: 76 raise 77 f.close() 78 else: 79 if mustExist: 80 litConfig.fatal('unable to load config from %r ' % path) 81 elif litConfig.debug: 82 litConfig.note('... config not found - %r' %path) 83 84 config.finish(litConfig) 85 return config 86 87 def __init__(self, parent, name, suffixes, test_format, 88 environment, substitutions, unsupported, on_clone, 89 test_exec_root, test_source_root, excludes, 90 available_features, pipefail): 91 self.parent = parent 92 self.name = str(name) 93 self.suffixes = set(suffixes) 94 self.test_format = test_format 95 self.environment = dict(environment) 96 self.substitutions = list(substitutions) 97 self.unsupported = unsupported 98 self.on_clone = on_clone 99 self.test_exec_root = test_exec_root 100 self.test_source_root = test_source_root 101 self.excludes = set(excludes) 102 self.available_features = set(available_features) 103 self.pipefail = pipefail 104 105 def clone(self, path): 106 # FIXME: Chain implementations? 107 # 108 # FIXME: Allow extra parameters? 109 cfg = TestingConfig(self, self.name, self.suffixes, self.test_format, 110 self.environment, self.substitutions, 111 self.unsupported, self.on_clone, 112 self.test_exec_root, self.test_source_root, 113 self.excludes, self.available_features, 114 self.pipefail) 115 if cfg.on_clone: 116 cfg.on_clone(self, cfg, path) 117 return cfg 118 119 def finish(self, litConfig): 120 """finish() - Finish this config object, after loading is complete.""" 121 122 self.name = str(self.name) 123 self.suffixes = set(self.suffixes) 124 self.environment = dict(self.environment) 125 self.substitutions = list(self.substitutions) 126 if self.test_exec_root is not None: 127 # FIXME: This should really only be suite in test suite config 128 # files. Should we distinguish them? 129 self.test_exec_root = str(self.test_exec_root) 130 if self.test_source_root is not None: 131 # FIXME: This should really only be suite in test suite config 132 # files. Should we distinguish them? 133 self.test_source_root = str(self.test_source_root) 134 self.excludes = set(self.excludes) 135 136 @property 137 def root(self): 138 """root attribute - The root configuration for the test suite.""" 139 if self.parent is None: 140 return self 141 else: 142 return self.parent.root 143 144