blob: 5dfd54ac5ec06c06f2458624116cae05d5054cba [file] [log] [blame]
Daniel Dunbar160f3512009-09-14 02:38:46 +00001import os
2
3import Test
4import TestRunner
5import Util
6
7class GoogleTest(object):
8 def __init__(self, test_sub_dir, test_suffix):
9 self.test_sub_dir = str(test_sub_dir)
10 self.test_suffix = str(test_suffix)
11
Daniel Dunbar91978072009-12-15 22:00:37 +000012 def getGTestTests(self, path, litConfig):
Daniel Dunbar160f3512009-09-14 02:38:46 +000013 """getGTestTests(path) - [name]
14
15 Return the tests available in gtest executable."""
16
Daniel Dunbar91978072009-12-15 22:00:37 +000017 try:
18 lines = Util.capture([path, '--gtest_list_tests']).split('\n')
19 except:
20 litConfig.error("unable to discover google-tests in %r" % path)
21 raise StopIteration
22
Daniel Dunbar160f3512009-09-14 02:38:46 +000023 nested_tests = []
24 for ln in lines:
25 if not ln.strip():
26 continue
27
28 prefix = ''
29 index = 0
30 while ln[index*2:index*2+2] == ' ':
31 index += 1
32 while len(nested_tests) > index:
33 nested_tests.pop()
34
35 ln = ln[index*2:]
36 if ln.endswith('.'):
37 nested_tests.append(ln)
38 else:
39 yield ''.join(nested_tests) + ln
40
41 def getTestsInDirectory(self, testSuite, path_in_suite,
42 litConfig, localConfig):
43 source_path = testSuite.getSourcePath(path_in_suite)
44 for filename in os.listdir(source_path):
45 # Check for the one subdirectory (build directory) tests will be in.
46 if filename != self.test_sub_dir:
47 continue
48
49 filepath = os.path.join(source_path, filename)
50 for subfilename in os.listdir(filepath):
51 if subfilename.endswith(self.test_suffix):
52 execpath = os.path.join(filepath, subfilename)
53
54 # Discover the tests in this executable.
Daniel Dunbar91978072009-12-15 22:00:37 +000055 for name in self.getGTestTests(execpath, litConfig):
Daniel Dunbar160f3512009-09-14 02:38:46 +000056 testPath = path_in_suite + (filename, subfilename, name)
57 yield Test.Test(testSuite, testPath, localConfig)
58
59 def execute(self, test, litConfig):
60 testPath,testName = os.path.split(test.getSourcePath())
Jeffrey Yasskine233d8a2009-11-16 22:41:33 +000061 while not os.path.exists(testPath):
62 # Handle GTest parametrized and typed tests, whose name includes
63 # some '/'s.
Jeffrey Yasskinc3ad8092009-10-18 02:05:42 +000064 testPath, namePrefix = os.path.split(testPath)
65 testName = os.path.join(namePrefix, testName)
Daniel Dunbar160f3512009-09-14 02:38:46 +000066
67 cmd = [testPath, '--gtest_filter=' + testName]
68 out, err, exitCode = TestRunner.executeCommand(cmd)
69
70 if not exitCode:
71 return Test.PASS,''
72
73 return Test.FAIL, out + err
74
75###
76
77class FileBasedTest(object):
78 def getTestsInDirectory(self, testSuite, path_in_suite,
79 litConfig, localConfig):
80 source_path = testSuite.getSourcePath(path_in_suite)
81 for filename in os.listdir(source_path):
82 filepath = os.path.join(source_path, filename)
83 if not os.path.isdir(filepath):
84 base,ext = os.path.splitext(filename)
85 if ext in localConfig.suffixes:
86 yield Test.Test(testSuite, path_in_suite + (filename,),
87 localConfig)
88
89class ShTest(FileBasedTest):
Daniel Dunbar7613ba52009-11-08 09:07:13 +000090 def __init__(self, execute_external = False):
Daniel Dunbar160f3512009-09-14 02:38:46 +000091 self.execute_external = execute_external
Daniel Dunbar160f3512009-09-14 02:38:46 +000092
93 def execute(self, test, litConfig):
94 return TestRunner.executeShTest(test, litConfig,
Daniel Dunbar7613ba52009-11-08 09:07:13 +000095 self.execute_external)
Daniel Dunbar160f3512009-09-14 02:38:46 +000096
97class TclTest(FileBasedTest):
98 def execute(self, test, litConfig):
99 return TestRunner.executeTclTest(test, litConfig)
Daniel Dunbar73944d42009-09-16 01:34:52 +0000100
101###
102
103import re
104import tempfile
105
Daniel Dunbar4d0c9982009-11-15 08:10:29 +0000106class OneCommandPerFileTest:
Daniel Dunbar73944d42009-09-16 01:34:52 +0000107 # FIXME: Refactor into generic test for running some command on a directory
108 # of inputs.
109
Daniel Dunbar4d0c9982009-11-15 08:10:29 +0000110 def __init__(self, command, dir, recursive=False,
111 pattern=".*", useTempInput=False):
112 if isinstance(command, str):
113 self.command = [command]
114 else:
115 self.command = list(command)
Daniel Dunbar73944d42009-09-16 01:34:52 +0000116 self.dir = str(dir)
117 self.recursive = bool(recursive)
118 self.pattern = re.compile(pattern)
Daniel Dunbar4d0c9982009-11-15 08:10:29 +0000119 self.useTempInput = useTempInput
Daniel Dunbar73944d42009-09-16 01:34:52 +0000120
121 def getTestsInDirectory(self, testSuite, path_in_suite,
122 litConfig, localConfig):
123 for dirname,subdirs,filenames in os.walk(self.dir):
124 if not self.recursive:
125 subdirs[:] = []
126
Daniel Dunbar0b3f26d2009-11-18 17:42:17 +0000127 subdirs[:] = [d for d in subdirs
128 if (d != '.svn' and
129 d not in localConfig.excludes)]
Daniel Dunbard71aeb72009-11-15 07:22:58 +0000130
Daniel Dunbar73944d42009-09-16 01:34:52 +0000131 for filename in filenames:
132 if (not self.pattern.match(filename) or
133 filename in localConfig.excludes):
134 continue
135
136 path = os.path.join(dirname,filename)
137 suffix = path[len(self.dir):]
138 if suffix.startswith(os.sep):
139 suffix = suffix[1:]
140 test = Test.Test(testSuite,
141 path_in_suite + tuple(suffix.split(os.sep)),
142 localConfig)
143 # FIXME: Hack?
144 test.source_path = path
145 yield test
146
Daniel Dunbar4d0c9982009-11-15 08:10:29 +0000147 def createTempInput(self, tmp, test):
148 abstract
149
Daniel Dunbar73944d42009-09-16 01:34:52 +0000150 def execute(self, test, litConfig):
Daniel Dunbard71aeb72009-11-15 07:22:58 +0000151 if test.config.unsupported:
152 return (Test.UNSUPPORTED, 'Test is unsupported')
153
Daniel Dunbar4d0c9982009-11-15 08:10:29 +0000154 cmd = list(self.command)
Daniel Dunbar73944d42009-09-16 01:34:52 +0000155
Daniel Dunbar4d0c9982009-11-15 08:10:29 +0000156 # If using temp input, create a temporary file and hand it to the
157 # subclass.
158 if self.useTempInput:
159 tmp = tempfile.NamedTemporaryFile(suffix='.cpp')
160 self.createTempInput(tmp, test)
161 tmp.flush()
162 cmd.append(tmp.name)
163 else:
164 cmd.append(test.source_path)
165
Daniel Dunbar73944d42009-09-16 01:34:52 +0000166 out, err, exitCode = TestRunner.executeCommand(cmd)
167
168 diags = out + err
169 if not exitCode and not diags.strip():
170 return Test.PASS,''
171
Daniel Dunbar4d0c9982009-11-15 08:10:29 +0000172 # Try to include some useful information.
173 report = """Command: %s\n""" % ' '.join(["'%s'" % a
174 for a in cmd])
175 if self.useTempInput:
176 report += """Temporary File: %s\n""" % tmp.name
177 report += "--\n%s--\n""" % open(tmp.name).read()
178 report += """Output:\n--\n%s--""" % diags
179
180 return Test.FAIL, report
181
182class SyntaxCheckTest(OneCommandPerFileTest):
183 def __init__(self, compiler, dir, extra_cxx_args=[], *args, **kwargs):
184 cmd = [compiler, '-x', 'c++', '-fsyntax-only'] + extra_cxx_args
185 OneCommandPerFileTest.__init__(self, cmd, dir,
186 useTempInput=1, *args, **kwargs)
187
188 def createTempInput(self, tmp, test):
189 print >>tmp, '#include "%s"' % test.source_path