blob: 11de5ada9024989709cdb794e95168244b472eeb [file] [log] [blame]
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +00001# -*- Python -*-
2
3# Configuration file for the 'lit' test runner.
4
5import os
6import platform
7import tempfile
8import signal
9import subprocess
10
11class LibcxxTestFormat(lit.formats.FileBasedTest):
12 """
13 Custom test format handler for use with the test format use by libc++.
14
15 Tests fall into two categories:
16 FOO.pass.cpp - Executable test which should compile, run, and exit with
17 code 0.
18 FOO.fail.cpp - Negative test case which is expected to fail compilation.
19 """
20
21 def __init__(self, cxx_under_test, options): self.cxx_under_test =
22 cxx_under_test self.options = list(options)
23
24 def execute_command(self, command):
25 p = subprocess.Popen(command, stdin=subprocess.PIPE,
26 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
27 out,err = p.communicate()
28 exitCode = p.wait()
29
30 # Detect Ctrl-C in subprocess.
31 if exitCode == -signal.SIGINT:
32 raise KeyboardInterrupt
33
34 return out, err, exitCode
35
36 def execute(self, test, lit_config):
37 name = test.path_in_suite[-1]
38 source_path = test.getSourcePath()
39
40 # Check what kind of test this is.
41 assert name.endswith('.pass.cpp') or name.endswith('.fail.cpp')
42 expected_compile_fail = name.endswith('.fail.cpp')
43
44 # If this is a compile (failure) test, build it and check for failure.
45 if expected_compile_fail:
46 cmd = [self.cxx_under_test, '-c',
47 '-o', '/dev/null', source_path] + self.options
48 out, err, exitCode = self.execute_command(cmd)
49 if exitCode == 1:
50 return lit.Test.PASS, ""
51 else:
52 report = """Command: %s\n""" % ' '.join(["'%s'" % a
53 for a in cmd])
54 report += """Exit Code: %d\n""" % exitCode
55 if out:
56 report += """Standard Output:\n--\n%s--""" % out
57 if err:
58 report += """Standard Error:\n--\n%s--""" % err
59 report += "\n\nExpected compilation to fail!"
60 return Test.FAIL, report
61 else:
62 exec_file = tempfile.NamedTemporaryFile(suffix="exe", delete=False)
63 exec_path = exec_file.name
64 exec_file.close()
65
66 try:
67 cmd = [self.cxx_under_test, '-o', exec_path,
68 source_path] + self.options
69 out, err, exitCode = self.execute_command(cmd)
70 if exitCode != 0:
71 exec_file.close()
72 report = """Command: %s\n""" % ' '.join(["'%s'" % a
73 for a in cmd])
74 report += """Exit Code: %d\n""" % exitCode
75 if out:
76 report += """Standard Output:\n--\n%s--""" % out
77 if err:
78 report += """Standard Error:\n--\n%s--""" % err
79 report += "\n\nCompilation failed unexpectedly!"
80 return lit.Test.FAIL, report
81
82 cmd = [exec_path]
83 out, err, exitCode = self.execute_command(cmd)
84 if exitCode != 0:
85 exec_path.close()
86 report = """Command: %s\n""" % ' '.join(["'%s'" % a
87 for a in cmd])
88 report += """Exit Code: %d\n""" % exitCode
89 if out:
90 report += """Standard Output:\n--\n%s--""" % out
91 if err:
92 report += """Standard Error:\n--\n%s--""" % err
93 report += "\n\nCompiled test failed unexpectedly!"
94 return lit.Test.FAIL, report
95 finally:
96 try:
97 os.remove(exec_path)
98 except:
99 pass
100 return lit.Test.PASS, ""
101
102# name: The name of this test suite.
103config.name = 'libc++'
104
105# suffixes: A list of file extensions to treat as test files.
106config.suffixes = ['.cpp']
107
108# test_source_root: The root path where tests are located.
109config.test_source_root = os.path.dirname(__file__)
110
111# FIXME: Would be nice to Use -stdlib=libc++ option with Clang's that accept it.
112cxx_under_test = lit.params.get('cxx_under_test', None)
113if cxx_under_test is None:
114 lit.fatal('must specify user parameter cxx_under_test '
115 '(e.g., --param=cxx_under_test=clang++)')
116config.test_format = LibcxxTestFormat(cxx_under_test,
117 ['-nostdinc++',
118 '-I/usr/include/c++/v1',
119 '-nodefaultlibs', '-lc++',
120 '-lSystem'])
121
122config.target_triple = None