import os
+import sys
+
+OldPy = sys.version_info[0] == 2 and sys.version_info[1] < 7
class TestingConfig:
""""
"""
@staticmethod
- def frompath(path, parent, litConfig, mustExist, config = None):
- if config is None:
- # Set the environment based on the command line arguments.
- environment = {
- 'LIBRARY_PATH' : os.environ.get('LIBRARY_PATH',''),
- 'LD_LIBRARY_PATH' : os.environ.get('LD_LIBRARY_PATH',''),
- 'PATH' : os.pathsep.join(litConfig.path +
- [os.environ.get('PATH','')]),
- 'PATHEXT' : os.environ.get('PATHEXT',''),
- 'SYSTEMROOT' : os.environ.get('SYSTEMROOT',''),
- 'LLVM_DISABLE_CRT_DEBUG' : '1',
- 'PYTHONUNBUFFERED' : '1',
- }
-
- config = TestingConfig(parent,
- name = '<unnamed>',
- suffixes = set(),
- test_format = None,
- environment = environment,
- substitutions = [],
- unsupported = False,
- on_clone = None,
- test_exec_root = None,
- test_source_root = None,
- excludes = [],
- available_features = [])
-
- if os.path.exists(path):
- # FIXME: Improve detection and error reporting of errors in the
- # config file.
+ def fromdefaults(litConfig):
+ """
+ fromdefaults(litConfig) -> TestingConfig
+
+ Create a TestingConfig object with default values.
+ """
+ # Set the environment based on the command line arguments.
+ environment = {
+ 'LIBRARY_PATH' : os.environ.get('LIBRARY_PATH',''),
+ 'LD_LIBRARY_PATH' : os.environ.get('LD_LIBRARY_PATH',''),
+ 'PATH' : os.pathsep.join(litConfig.path +
+ [os.environ.get('PATH','')]),
+ 'SYSTEMROOT' : os.environ.get('SYSTEMROOT',''),
+ 'TERM' : os.environ.get('TERM',''),
+ 'LLVM_DISABLE_CRASH_REPORT' : '1',
+ }
+
+ if sys.platform == 'win32':
+ environment.update({
+ 'INCLUDE' : os.environ.get('INCLUDE',''),
+ 'PATHEXT' : os.environ.get('PATHEXT',''),
+ 'PYTHONUNBUFFERED' : '1',
+ 'TEMP' : os.environ.get('TEMP',''),
+ 'TMP' : os.environ.get('TMP',''),
+ })
+
+ # The option to preserve TEMP, TMP, and TMPDIR.
+ # This is intended to check how many temporary files would be generated
+ # (and be not cleaned up) in automated builders.
+ if 'LIT_PRESERVES_TMP' in os.environ:
+ environment.update({
+ 'TEMP' : os.environ.get('TEMP',''),
+ 'TMP' : os.environ.get('TMP',''),
+ 'TMPDIR' : os.environ.get('TMPDIR',''),
+ })
+
+ # Set the default available features based on the LitConfig.
+ available_features = []
+ if litConfig.useValgrind:
+ available_features.append('valgrind')
+ if litConfig.valgrindLeakCheck:
+ available_features.append('vg_leak')
+
+ return TestingConfig(None,
+ name = '<unnamed>',
+ suffixes = set(),
+ test_format = None,
+ environment = environment,
+ substitutions = [],
+ unsupported = False,
+ test_exec_root = None,
+ test_source_root = None,
+ excludes = [],
+ available_features = available_features,
+ pipefail = True)
+
+ def load_from_path(self, path, litConfig):
+ """
+ load_from_path(path, litConfig)
+
+ Load the configuration module at the provided path into the given config
+ object.
+ """
+
+ # Load the config script data.
+ data = None
+ if not OldPy:
f = open(path)
- cfg_globals = dict(globals())
- cfg_globals['config'] = config
- cfg_globals['lit'] = litConfig
- cfg_globals['__file__'] = path
try:
- exec f in cfg_globals
- except SystemExit,status:
- # We allow normal system exit inside a config file to just
- # return control without error.
- if status.args:
- raise
+ data = f.read()
+ except:
+ litConfig.fatal('unable to load config file: %r' % (path,))
f.close()
- elif mustExist:
- litConfig.fatal('unable to load config from %r ' % path)
- config.finish(litConfig)
- return config
+ # Execute the config script to initialize the object.
+ cfg_globals = dict(globals())
+ cfg_globals['config'] = self
+ cfg_globals['lit_config'] = litConfig
+ cfg_globals['__file__'] = path
+ try:
+ if OldPy:
+ execfile(path, cfg_globals)
+ else:
+ exec(compile(data, path, 'exec'), cfg_globals, None)
+ if litConfig.debug:
+ litConfig.note('... loaded config %r' % path)
+ except SystemExit:
+ e = sys.exc_info()[1]
+ # We allow normal system exit inside a config file to just
+ # return control without error.
+ if e.args:
+ raise
+ except:
+ import traceback
+ litConfig.fatal(
+ 'unable to parse config file %r, traceback: %s' % (
+ path, traceback.format_exc()))
+
+ self.finish(litConfig)
def __init__(self, parent, name, suffixes, test_format,
- environment, substitutions, unsupported, on_clone,
+ environment, substitutions, unsupported,
test_exec_root, test_source_root, excludes,
- available_features):
+ available_features, pipefail):
self.parent = parent
self.name = str(name)
self.suffixes = set(suffixes)
self.environment = dict(environment)
self.substitutions = list(substitutions)
self.unsupported = unsupported
- self.on_clone = on_clone
self.test_exec_root = test_exec_root
self.test_source_root = test_source_root
self.excludes = set(excludes)
self.available_features = set(available_features)
-
- def clone(self, path):
- # FIXME: Chain implementations?
- #
- # FIXME: Allow extra parameters?
- cfg = TestingConfig(self, self.name, self.suffixes, self.test_format,
- self.environment, self.substitutions,
- self.unsupported, self.on_clone,
- self.test_exec_root, self.test_source_root,
- self.excludes, self.available_features)
- if cfg.on_clone:
- cfg.on_clone(self, cfg, path)
- return cfg
+ self.pipefail = pipefail
def finish(self, litConfig):
"""finish() - Finish this config object, after loading is complete."""
# files. Should we distinguish them?
self.test_source_root = str(self.test_source_root)
self.excludes = set(self.excludes)
+
+ @property
+ def root(self):
+ """root attribute - The root configuration for the test suite."""
+ if self.parent is None:
+ return self
+ else:
+ return self.parent.root
+