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