Skip to content

Commit 34a1872

Browse files
committed
[lit] Remove dead code not referenced in the LLVM SVN repo.
Summary: This change removes the intermediate 'FileBasedTest' format from lit. This format is only ever used by the ShTest format, so the logic can be moved into ShTest directly. In order to better clarify what the TestFormat subclasses do, I fleshed out the TestFormat base class with Python's notion of abstract methods, using @abc.abstractmethod. This gives a convenient way to document the expected interface, without the risk of instantiating an abstract class (that's what ABCMeta does -- it raises an exception if you try to instantiate a class which has abstract methods, but not if you instantiate a subclass that implements them). Reviewers: zturner, modocache Subscribers: sanjoy, llvm-commits Differential Revision: https://reviews.llvm.org/D34792 llvm-svn: 306623
1 parent 9f83f3b commit 34a1872

File tree

3 files changed

+90
-120
lines changed

3 files changed

+90
-120
lines changed
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
from lit.formats.base import ( # noqa: F401
2-
TestFormat,
3-
FileBasedTest,
4-
OneCommandPerFileTest
5-
)
6-
1+
from lit.formats.base import TestFormat # noqa: F401
72
from lit.formats.googletest import GoogleTest # noqa: F401
83
from lit.formats.shtest import ShTest # noqa: F401

llvm/utils/lit/lit/formats/base.py

Lines changed: 45 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,50 @@
1-
from __future__ import absolute_import
2-
import os
3-
4-
import lit.Test
5-
import lit.util
1+
import abc
62

73
class TestFormat(object):
8-
pass
9-
10-
###
11-
12-
class FileBasedTest(TestFormat):
13-
def getTestsInDirectory(self, testSuite, path_in_suite,
14-
litConfig, localConfig):
15-
source_path = testSuite.getSourcePath(path_in_suite)
16-
for filename in os.listdir(source_path):
17-
# Ignore dot files and excluded tests.
18-
if (filename.startswith('.') or
19-
filename in localConfig.excludes):
20-
continue
21-
22-
filepath = os.path.join(source_path, filename)
23-
if not os.path.isdir(filepath):
24-
base,ext = os.path.splitext(filename)
25-
if ext in localConfig.suffixes:
26-
yield lit.Test.Test(testSuite, path_in_suite + (filename,),
27-
localConfig)
28-
29-
###
30-
31-
import re
32-
import tempfile
33-
34-
class OneCommandPerFileTest(TestFormat):
35-
# FIXME: Refactor into generic test for running some command on a directory
36-
# of inputs.
37-
38-
def __init__(self, command, dir, recursive=False,
39-
pattern=".*", useTempInput=False):
40-
if isinstance(command, str):
41-
self.command = [command]
42-
else:
43-
self.command = list(command)
44-
if dir is not None:
45-
dir = str(dir)
46-
self.dir = dir
47-
self.recursive = bool(recursive)
48-
self.pattern = re.compile(pattern)
49-
self.useTempInput = useTempInput
50-
51-
def getTestsInDirectory(self, testSuite, path_in_suite,
52-
litConfig, localConfig):
53-
dir = self.dir
54-
if dir is None:
55-
dir = testSuite.getSourcePath(path_in_suite)
56-
57-
for dirname,subdirs,filenames in os.walk(dir):
58-
if not self.recursive:
59-
subdirs[:] = []
60-
61-
subdirs[:] = [d for d in subdirs
62-
if (d != '.svn' and
63-
d not in localConfig.excludes)]
64-
65-
for filename in filenames:
66-
if (filename.startswith('.') or
67-
not self.pattern.match(filename) or
68-
filename in localConfig.excludes):
69-
continue
70-
71-
path = os.path.join(dirname,filename)
72-
suffix = path[len(dir):]
73-
if suffix.startswith(os.sep):
74-
suffix = suffix[1:]
75-
test = lit.Test.Test(
76-
testSuite, path_in_suite + tuple(suffix.split(os.sep)),
77-
localConfig)
78-
# FIXME: Hack?
79-
test.source_path = path
80-
yield test
81-
82-
def createTempInput(self, tmp, test):
83-
raise NotImplementedError('This is an abstract method.')
84-
4+
"""Base class for test formats.
5+
6+
A TestFormat encapsulates logic for finding and executing a certain type of
7+
test. For example, a subclass FooTestFormat would contain the logic for
8+
finding tests written in the 'Foo' format, and the logic for running a
9+
single one.
10+
11+
TestFormat is an Abstract Base Class (ABC). It uses the Python abc.ABCMeta
12+
type and associated @abc.abstractmethod decorator. Together, these provide
13+
subclass behaviour which is notionally similar to C++ pure virtual classes:
14+
only subclasses which implement all abstract methods can be instantiated
15+
(the implementation may come from an intermediate base).
16+
17+
For details on ABCs, see: https://docs.python.org/2/library/abc.html. Note
18+
that Python ABCs have extensive abilities beyond what is used here. For
19+
TestFormat, we only care about enforcing that abstract methods are
20+
implemented.
21+
"""
22+
23+
__metaclass__ = abc.ABCMeta
24+
25+
@abc.abstractmethod
26+
def getTestsInDirectory(self, testSuite, path_in_suite, litConfig,
27+
localConfig):
28+
"""Finds tests of this format in the given directory.
29+
30+
Args:
31+
testSuite: a Test.TestSuite object.
32+
path_in_suite: the subpath under testSuite to look for tests.
33+
litConfig: the LitConfig for the test suite.
34+
localConfig: a LitConfig with local specializations.
35+
36+
Returns:
37+
An iterable of Test.Test objects.
38+
"""
39+
40+
@abc.abstractmethod
8541
def execute(self, test, litConfig):
86-
if test.config.unsupported:
87-
return (lit.Test.UNSUPPORTED, 'Test is unsupported')
88-
89-
cmd = list(self.command)
90-
91-
# If using temp input, create a temporary file and hand it to the
92-
# subclass.
93-
if self.useTempInput:
94-
tmp = tempfile.NamedTemporaryFile(suffix='.cpp')
95-
self.createTempInput(tmp, test)
96-
tmp.flush()
97-
cmd.append(tmp.name)
98-
elif hasattr(test, 'source_path'):
99-
cmd.append(test.source_path)
100-
else:
101-
cmd.append(test.getSourcePath())
102-
103-
out, err, exitCode = lit.util.executeCommand(cmd)
104-
105-
diags = out + err
106-
if not exitCode and not diags.strip():
107-
return lit.Test.PASS,''
42+
"""Runs the given 'test', which is of this format.
10843
109-
# Try to include some useful information.
110-
report = """Command: %s\n""" % ' '.join(["'%s'" % a
111-
for a in cmd])
112-
if self.useTempInput:
113-
report += """Temporary File: %s\n""" % tmp.name
114-
report += "--\n%s--\n""" % open(tmp.name).read()
115-
report += """Output:\n--\n%s--""" % diags
44+
Args:
45+
test: a Test.Test object describing the test to run.
46+
litConfig: the LitConfig for the test suite.
11647
117-
return lit.Test.FAIL, report
48+
Returns:
49+
A tuple of (status:Test.ResultCode, message:str)
50+
"""

llvm/utils/lit/lit/formats/shtest.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,54 @@
11
from __future__ import absolute_import
22

3+
import os
4+
5+
import lit.Test
36
import lit.TestRunner
4-
from .base import FileBasedTest
7+
from .base import TestFormat
8+
9+
class ShTest(TestFormat):
10+
"""ShTest is a format with one file per test.
11+
12+
This is the primary format for regression tests as described in the LLVM
13+
testing guide:
14+
15+
http://llvm.org/docs/TestingGuide.html
16+
17+
The ShTest files contain some number of shell-like command pipelines, along
18+
with assertions about what should be in the output.
19+
"""
520

6-
class ShTest(FileBasedTest):
721
def __init__(self, execute_external = False):
22+
"""Initializer.
23+
24+
The 'execute_external' argument controls whether lit uses its internal
25+
logic for command pipelines, or passes the command to a shell
26+
subprocess.
27+
28+
Args:
29+
execute_external: (optional) If true, use shell subprocesses instead
30+
of lit's internal pipeline logic.
31+
"""
832
self.execute_external = execute_external
933

34+
def getTestsInDirectory(self, testSuite, path_in_suite,
35+
litConfig, localConfig):
36+
"""Yields test files matching 'suffixes' from the localConfig."""
37+
source_path = testSuite.getSourcePath(path_in_suite)
38+
for filename in os.listdir(source_path):
39+
# Ignore dot files and excluded tests.
40+
if (filename.startswith('.') or
41+
filename in localConfig.excludes):
42+
continue
43+
44+
filepath = os.path.join(source_path, filename)
45+
if not os.path.isdir(filepath):
46+
base,ext = os.path.splitext(filename)
47+
if ext in localConfig.suffixes:
48+
yield lit.Test.Test(testSuite, path_in_suite + (filename,),
49+
localConfig)
50+
1051
def execute(self, test, litConfig):
52+
"""Interprets and runs the given test file, and returns the result."""
1153
return lit.TestRunner.executeShTest(test, litConfig,
1254
self.execute_external)

0 commit comments

Comments
 (0)