base.py revision 7b0cdf7bf44e626977d607279a933e45346aeac8
1from __future__ import absolute_import
2import os
3import sys
4
5import lit.Test
6import lit.util
7
8class TestFormat(object):
9    pass
10
11###
12
13class FileBasedTest(TestFormat):
14    def getTestsInDirectory(self, testSuite, path_in_suite,
15                            litConfig, localConfig):
16        source_path = testSuite.getSourcePath(path_in_suite)
17        for filename in os.listdir(source_path):
18            # Ignore dot files and excluded tests.
19            if (filename.startswith('.') or
20                filename in localConfig.excludes):
21                continue
22
23            filepath = os.path.join(source_path, filename)
24            if not os.path.isdir(filepath):
25                base,ext = os.path.splitext(filename)
26                if ext in localConfig.suffixes:
27                    yield lit.Test.Test(testSuite, path_in_suite + (filename,),
28                                        localConfig)
29
30###
31
32import re
33import tempfile
34
35class OneCommandPerFileTest(TestFormat):
36    # FIXME: Refactor into generic test for running some command on a directory
37    # of inputs.
38
39    def __init__(self, command, dir, recursive=False,
40                 pattern=".*", useTempInput=False):
41        if isinstance(command, str):
42            self.command = [command]
43        else:
44            self.command = list(command)
45        if dir is not None:
46            dir = str(dir)
47        self.dir = dir
48        self.recursive = bool(recursive)
49        self.pattern = re.compile(pattern)
50        self.useTempInput = useTempInput
51
52    def getTestsInDirectory(self, testSuite, path_in_suite,
53                            litConfig, localConfig):
54        dir = self.dir
55        if dir is None:
56            dir = testSuite.getSourcePath(path_in_suite)
57
58        for dirname,subdirs,filenames in os.walk(dir):
59            if not self.recursive:
60                subdirs[:] = []
61
62            subdirs[:] = [d for d in subdirs
63                          if (d != '.svn' and
64                              d not in localConfig.excludes)]
65
66            for filename in filenames:
67                if (filename.startswith('.') or
68                    not self.pattern.match(filename) or
69                    filename in localConfig.excludes):
70                    continue
71
72                path = os.path.join(dirname,filename)
73                suffix = path[len(dir):]
74                if suffix.startswith(os.sep):
75                    suffix = suffix[1:]
76                test = lit.Test.Test(
77                    testSuite, path_in_suite + tuple(suffix.split(os.sep)),
78                    localConfig)
79                # FIXME: Hack?
80                test.source_path = path
81                yield test
82
83    def createTempInput(self, tmp, test):
84        abstract
85
86    def execute(self, test, litConfig):
87        if test.config.unsupported:
88            return (lit.Test.UNSUPPORTED, 'Test is unsupported')
89
90        cmd = list(self.command)
91
92        # If using temp input, create a temporary file and hand it to the
93        # subclass.
94        if self.useTempInput:
95            tmp = tempfile.NamedTemporaryFile(suffix='.cpp')
96            self.createTempInput(tmp, test)
97            tmp.flush()
98            cmd.append(tmp.name)
99        elif hasattr(test, 'source_path'):
100            cmd.append(test.source_path)
101        else:
102            cmd.append(test.getSourcePath())
103
104        out, err, exitCode = lit.util.executeCommand(cmd)
105
106        diags = out + err
107        if not exitCode and not diags.strip():
108            return lit.Test.PASS,''
109
110        # Try to include some useful information.
111        report = """Command: %s\n""" % ' '.join(["'%s'" % a
112                                                 for a in cmd])
113        if self.useTempInput:
114            report += """Temporary File: %s\n""" % tmp.name
115            report += "--\n%s--\n""" % open(tmp.name).read()
116        report += """Output:\n--\n%s--""" % diags
117
118        return lit.Test.FAIL, report
119