blob: dc843ac5214bd0bbe30f3733a4a917c51472a549 [file] [log] [blame]
Daniel Dunbar42ea4632010-09-15 03:57:04 +00001# -*- Python -*-
2
3# Configuration file for the 'lit' test runner.
4
5import os
Michael J. Spencerf5799be2010-12-10 19:47:54 +00006import sys
Daniel Dunbar42ea4632010-09-15 03:57:04 +00007import platform
8import tempfile
9import signal
10import subprocess
Howard Hinnant3778f272013-01-14 17:12:54 +000011import errno
12import time
Daniel Dunbar42ea4632010-09-15 03:57:04 +000013
14class LibcxxTestFormat(lit.formats.FileBasedTest):
15 """
16 Custom test format handler for use with the test format use by libc++.
17
18 Tests fall into two categories:
19 FOO.pass.cpp - Executable test which should compile, run, and exit with
20 code 0.
21 FOO.fail.cpp - Negative test case which is expected to fail compilation.
22 """
23
Daniel Dunbar5f09d9e02010-09-15 04:31:58 +000024 def __init__(self, cxx_under_test, cpp_flags, ld_flags):
Daniel Dunbarbc9a8482010-09-15 04:11:29 +000025 self.cxx_under_test = cxx_under_test
Daniel Dunbar5f09d9e02010-09-15 04:31:58 +000026 self.cpp_flags = list(cpp_flags)
27 self.ld_flags = list(ld_flags)
Daniel Dunbar42ea4632010-09-15 03:57:04 +000028
Howard Hinnant3778f272013-01-14 17:12:54 +000029 def execute_command(self, command, in_dir=None):
30 kwargs = {
31 'stdin' :subprocess.PIPE,
32 'stdout':subprocess.PIPE,
33 'stderr':subprocess.PIPE,
34 }
35 if in_dir:
36 kwargs['cwd'] = in_dir
37 p = subprocess.Popen(command, **kwargs)
Daniel Dunbar42ea4632010-09-15 03:57:04 +000038 out,err = p.communicate()
39 exitCode = p.wait()
40
41 # Detect Ctrl-C in subprocess.
42 if exitCode == -signal.SIGINT:
43 raise KeyboardInterrupt
44
45 return out, err, exitCode
46
47 def execute(self, test, lit_config):
Howard Hinnant3778f272013-01-14 17:12:54 +000048 while True:
49 try:
50 return self._execute(test, lit_config)
51 except OSError, oe:
52 if oe.errno != errno.ETXTBSY:
53 raise
54 time.sleep(0.1)
55
56 def _execute(self, test, lit_config):
Daniel Dunbar42ea4632010-09-15 03:57:04 +000057 name = test.path_in_suite[-1]
58 source_path = test.getSourcePath()
Howard Hinnant3778f272013-01-14 17:12:54 +000059 source_dir = os.path.dirname(source_path)
Daniel Dunbar42ea4632010-09-15 03:57:04 +000060
61 # Check what kind of test this is.
62 assert name.endswith('.pass.cpp') or name.endswith('.fail.cpp')
63 expected_compile_fail = name.endswith('.fail.cpp')
64
65 # If this is a compile (failure) test, build it and check for failure.
66 if expected_compile_fail:
67 cmd = [self.cxx_under_test, '-c',
Daniel Dunbar5f09d9e02010-09-15 04:31:58 +000068 '-o', '/dev/null', source_path] + self.cpp_flags
Daniel Dunbar42ea4632010-09-15 03:57:04 +000069 out, err, exitCode = self.execute_command(cmd)
70 if exitCode == 1:
71 return lit.Test.PASS, ""
72 else:
73 report = """Command: %s\n""" % ' '.join(["'%s'" % a
74 for a in cmd])
75 report += """Exit Code: %d\n""" % exitCode
76 if out:
77 report += """Standard Output:\n--\n%s--""" % out
78 if err:
79 report += """Standard Error:\n--\n%s--""" % err
80 report += "\n\nExpected compilation to fail!"
Daniel Dunbar5f09d9e02010-09-15 04:31:58 +000081 return lit.Test.FAIL, report
Daniel Dunbar42ea4632010-09-15 03:57:04 +000082 else:
83 exec_file = tempfile.NamedTemporaryFile(suffix="exe", delete=False)
84 exec_path = exec_file.name
85 exec_file.close()
86
87 try:
Michael J. Spencerf5799be2010-12-10 19:47:54 +000088 compile_cmd = [self.cxx_under_test, '-o', exec_path,
Daniel Dunbar5f09d9e02010-09-15 04:31:58 +000089 source_path] + self.cpp_flags + self.ld_flags
Michael J. Spencerf5799be2010-12-10 19:47:54 +000090 cmd = compile_cmd
Daniel Dunbar42ea4632010-09-15 03:57:04 +000091 out, err, exitCode = self.execute_command(cmd)
92 if exitCode != 0:
Daniel Dunbar42ea4632010-09-15 03:57:04 +000093 report = """Command: %s\n""" % ' '.join(["'%s'" % a
94 for a in cmd])
95 report += """Exit Code: %d\n""" % exitCode
96 if out:
97 report += """Standard Output:\n--\n%s--""" % out
98 if err:
99 report += """Standard Error:\n--\n%s--""" % err
100 report += "\n\nCompilation failed unexpectedly!"
101 return lit.Test.FAIL, report
102
103 cmd = [exec_path]
Howard Hinnantc1a45fb2012-08-02 18:36:47 +0000104 if lit_config.useValgrind:
105 cmd = lit_config.valgrindArgs + cmd
Howard Hinnant3778f272013-01-14 17:12:54 +0000106 out, err, exitCode = self.execute_command(cmd, source_dir)
Daniel Dunbar42ea4632010-09-15 03:57:04 +0000107 if exitCode != 0:
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000108 report = """Compiled With: %s\n""" % ' '.join(["'%s'" % a
109 for a in compile_cmd])
110 report += """Command: %s\n""" % ' '.join(["'%s'" % a
Daniel Dunbar42ea4632010-09-15 03:57:04 +0000111 for a in cmd])
112 report += """Exit Code: %d\n""" % exitCode
113 if out:
114 report += """Standard Output:\n--\n%s--""" % out
115 if err:
116 report += """Standard Error:\n--\n%s--""" % err
117 report += "\n\nCompiled test failed unexpectedly!"
118 return lit.Test.FAIL, report
119 finally:
120 try:
121 os.remove(exec_path)
122 except:
123 pass
124 return lit.Test.PASS, ""
125
126# name: The name of this test suite.
127config.name = 'libc++'
128
129# suffixes: A list of file extensions to treat as test files.
130config.suffixes = ['.cpp']
131
132# test_source_root: The root path where tests are located.
133config.test_source_root = os.path.dirname(__file__)
134
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000135# Gather various compiler parameters.
Daniel Dunbar42ea4632010-09-15 03:57:04 +0000136cxx_under_test = lit.params.get('cxx_under_test', None)
137if cxx_under_test is None:
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000138 cxx_under_test = getattr(config, 'cxx_under_test', None)
139 if cxx_under_test is None:
140 lit.fatal('must specify user parameter cxx_under_test '
141 '(e.g., --param=cxx_under_test=clang++)')
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000142
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000143libcxx_src_root = lit.params.get('libcxx_src_root', None)
144if libcxx_src_root is None:
145 libcxx_src_root = getattr(config, 'libcxx_src_root', None)
146 if libcxx_src_root is None:
147 libcxx_src_root = os.path.dirname(config.test_source_root)
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000148
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000149libcxx_obj_root = lit.params.get('libcxx_obj_root', None)
150if libcxx_obj_root is None:
151 libcxx_obj_root = getattr(config, 'libcxx_obj_root', None)
152 if libcxx_obj_root is None:
153 libcxx_obj_root = libcxx_src_root
154
155cxx_has_stdcxx0x_flag_str = lit.params.get('cxx_has_stdcxx0x_flag', None)
156if cxx_has_stdcxx0x_flag_str is not None:
157 if cxx_has_stdcxx0x_flag_str in ('1', 'True'):
158 cxx_has_stdcxx0x_flag = True
159 elif cxx_has_stdcxx0x_flag_str in ('', '0', 'False'):
160 cxx_has_stdcxx0x_flag = False
161 else:
162 lit.fatal('user parameter cxx_has_stdcxx0x_flag_str should be 0 or 1')
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000163else:
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000164 cxx_has_stdcxx0x_flag = getattr(config, 'cxx_has_stdcxx0x_flag', True)
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000165
Chandler Carruthce395a92011-01-23 01:05:20 +0000166# Configure extra compiler flags.
Howard Hinnantf1e633c2013-01-14 17:07:27 +0000167include_paths = ['-I' + libcxx_src_root + '/include', '-I' + libcxx_src_root + '/test/support']
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000168library_paths = ['-L' + libcxx_obj_root + '/lib']
Chandler Carruthce395a92011-01-23 01:05:20 +0000169compile_flags = []
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000170if cxx_has_stdcxx0x_flag:
Chandler Carruthce395a92011-01-23 01:05:20 +0000171 compile_flags += ['-std=c++0x']
172
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000173# Configure extra libraries.
174libraries = []
175if sys.platform == 'darwin':
176 libraries += ['-lSystem']
177if sys.platform == 'linux2':
Howard Hinnant3778f272013-01-14 17:12:54 +0000178 libraries += ['-lsupc++', '-lgcc_eh', '-lc', '-lm', '-lpthread', '-lrt', '-lgcc_s']
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000179 libraries += ['-Wl,-R', libcxx_obj_root + '/lib']
Howard Hinnant3778f272013-01-14 17:12:54 +0000180 compile_flags += ['-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS']
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000181
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000182config.test_format = LibcxxTestFormat(
183 cxx_under_test,
184 cpp_flags = ['-nostdinc++'] + compile_flags + include_paths,
185 ld_flags = ['-nodefaultlibs'] + library_paths + ['-lc++'] + libraries)
Daniel Dunbar42ea4632010-09-15 03:57:04 +0000186
187config.target_triple = None