Skip to content

Commit 78f2e02

Browse files
author
git apple-llvm automerger
committed
Merge commit '5b55eb1e8884' from llvm.org/main into next
2 parents 8a44352 + 5b55eb1 commit 78f2e02

File tree

8 files changed

+116
-62
lines changed

8 files changed

+116
-62
lines changed

libcxx/utils/libcxx/test/format.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def parseScript(test, preamble):
182182
return script
183183

184184

185-
class CxxStandardLibraryTest(lit.formats.TestFormat):
185+
class CxxStandardLibraryTest(lit.formats.FileBasedTest):
186186
"""
187187
Lit test format for the C++ Standard Library conformance test suite.
188188
@@ -278,7 +278,7 @@ class CxxStandardLibraryTest(lit.formats.TestFormat):
278278
in conjunction with the %{build} substitution.
279279
"""
280280

281-
def getTestsInDirectory(self, testSuite, pathInSuite, litConfig, localConfig):
281+
def getTestsForPath(self, testSuite, pathInSuite, litConfig, localConfig):
282282
SUPPORTED_SUFFIXES = [
283283
"[.]pass[.]cpp$",
284284
"[.]pass[.]mm$",
@@ -293,22 +293,22 @@ def getTestsInDirectory(self, testSuite, pathInSuite, litConfig, localConfig):
293293
"[.]verify[.]cpp$",
294294
"[.]fail[.]cpp$",
295295
]
296+
296297
sourcePath = testSuite.getSourcePath(pathInSuite)
297-
for filename in os.listdir(sourcePath):
298-
# Ignore dot files and excluded tests.
299-
if filename.startswith(".") or filename in localConfig.excludes:
300-
continue
301-
302-
filepath = os.path.join(sourcePath, filename)
303-
if not os.path.isdir(filepath):
304-
if any([re.search(ext, filename) for ext in SUPPORTED_SUFFIXES]):
305-
# If this is a generated test, run the generation step and add
306-
# as many Lit tests as necessary.
307-
if re.search('[.]gen[.][^.]+$', filename):
308-
for test in self._generateGenTest(testSuite, pathInSuite + (filename,), litConfig, localConfig):
309-
yield test
310-
else:
311-
yield lit.Test.Test(testSuite, pathInSuite + (filename,), localConfig)
298+
filename = os.path.basename(sourcePath)
299+
300+
# Ignore dot files, excluded tests and tests with an unsupported suffix
301+
hasSupportedSuffix = lambda f: any([re.search(ext, f) for ext in SUPPORTED_SUFFIXES])
302+
if filename.startswith(".") or filename in localConfig.excludes or not hasSupportedSuffix(filename):
303+
return
304+
305+
# If this is a generated test, run the generation step and add
306+
# as many Lit tests as necessary.
307+
if re.search('[.]gen[.][^.]+$', filename):
308+
for test in self._generateGenTest(testSuite, pathInSuite, litConfig, localConfig):
309+
yield test
310+
else:
311+
yield lit.Test.Test(testSuite, pathInSuite, localConfig)
312312

313313
def execute(self, test, litConfig):
314314
VERIFY_FLAGS = (

llvm/utils/lit/examples/many-tests/ManyTests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from lit import Test
1+
from lit import Test, TestFormat
22

33

4-
class ManyTests(object):
4+
class ManyTests(TestFormat):
55
def __init__(self, N=10000):
66
self.N = N
77

llvm/utils/lit/lit/discovery.py

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -163,35 +163,43 @@ def getTestsInSuite(
163163
if not os.path.isdir(source_path):
164164
test_dir_in_suite = path_in_suite[:-1]
165165
lc = getLocalConfig(ts, test_dir_in_suite, litConfig, localConfigCache)
166-
test = Test.Test(ts, path_in_suite, lc)
167-
168-
# Issue a error if the specified test would not be run if
169-
# the user had specified the containing directory instead of
170-
# of naming the test directly. This helps to avoid writing
171-
# tests which are not executed. The check adds some performance
172-
# overhead which might be important if a large number of tests
173-
# are being run directly.
174-
# This check can be disabled by using --no-indirectly-run-check or
175-
# setting the standalone_tests variable in the suite's configuration.
176-
if (
177-
indirectlyRunCheck
178-
and lc.test_format is not None
179-
and not lc.standalone_tests
180-
):
181-
found = False
182-
for res in lc.test_format.getTestsInDirectory(
183-
ts, test_dir_in_suite, litConfig, lc
166+
167+
# TODO: Stop checking for indirectlyRunCheck and lc.standalone_tests here
168+
# once we remove --no-indirectly-run-check, which is not needed anymore
169+
# now that we error out when trying to run a test that wouldn't be
170+
# discovered in the directory.
171+
fallbackOnSingleTest = lc.test_format is None or not indirectlyRunCheck or lc.standalone_tests
172+
tests = [Test.Test(ts, path_in_suite, lc)] if fallbackOnSingleTest else \
173+
lc.test_format.getTestsForPath(ts, path_in_suite, litConfig, lc)
174+
175+
for test in tests:
176+
# Issue a error if the specified test would not be run if
177+
# the user had specified the containing directory instead of
178+
# of naming the test directly. This helps to avoid writing
179+
# tests which are not executed. The check adds some performance
180+
# overhead which might be important if a large number of tests
181+
# are being run directly.
182+
# This check can be disabled by using --no-indirectly-run-check or
183+
# setting the standalone_tests variable in the suite's configuration.
184+
if (
185+
indirectlyRunCheck
186+
and lc.test_format is not None
187+
and not lc.standalone_tests
184188
):
185-
if test.getFullName() == res.getFullName():
186-
found = True
187-
break
188-
if not found:
189-
litConfig.error(
190-
"%r would not be run indirectly: change name or LIT config"
191-
"(e.g. suffixes or standalone_tests variables)" % test.getFullName()
192-
)
193-
194-
yield test
189+
found = False
190+
for res in lc.test_format.getTestsInDirectory(
191+
ts, test_dir_in_suite, litConfig, lc
192+
):
193+
if test.getFullName() == res.getFullName():
194+
found = True
195+
break
196+
if not found:
197+
litConfig.error(
198+
"%r would not be run indirectly: change name or LIT config"
199+
"(e.g. suffixes or standalone_tests variables)" % test.getFullName()
200+
)
201+
202+
yield test
195203
return
196204

197205
# Otherwise we have a directory to search for tests, start by getting the

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

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,42 @@
66

77

88
class TestFormat(object):
9-
pass
10-
9+
def getTestsForPath(self, testSuite, path_in_suite, litConfig, localConfig):
10+
"""
11+
Given the path to a test in the test suite, generates the Lit tests associated
12+
to that path. There can be zero, one or more tests. For example, some testing
13+
formats allow expanding a single path in the test suite into multiple Lit tests
14+
(e.g. they are generated on the fly).
15+
"""
16+
yield lit.Test.Test(testSuite, path_in_suite, localConfig)
1117

1218
###
1319

1420

1521
class FileBasedTest(TestFormat):
22+
def getTestsForPath(self, testSuite, path_in_suite, litConfig, localConfig):
23+
"""
24+
Expand each path in a test suite to a Lit test using that path and assuming
25+
it is a file containing the test. File extensions excluded by the configuration
26+
or not contained in the allowed extensions are ignored.
27+
"""
28+
filename = path_in_suite[-1]
29+
30+
# Ignore dot files and excluded tests.
31+
if filename.startswith(".") or filename in localConfig.excludes:
32+
return
33+
34+
base, ext = os.path.splitext(filename)
35+
if ext in localConfig.suffixes:
36+
yield lit.Test.Test(testSuite, path_in_suite, localConfig)
37+
1638
def getTestsInDirectory(self, testSuite, path_in_suite, litConfig, localConfig):
1739
source_path = testSuite.getSourcePath(path_in_suite)
1840
for filename in os.listdir(source_path):
19-
# Ignore dot files and excluded tests.
20-
if filename.startswith(".") or filename in localConfig.excludes:
21-
continue
22-
2341
filepath = os.path.join(source_path, filename)
2442
if not os.path.isdir(filepath):
25-
base, ext = os.path.splitext(filename)
26-
if ext in localConfig.suffixes:
27-
yield lit.Test.Test(
28-
testSuite, path_in_suite + (filename,), localConfig
29-
)
43+
for t in self.getTestsForPath(testSuite, path_in_suite + (filename,), litConfig, localConfig):
44+
yield t
3045

3146

3247
###
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import os
2+
import lit.formats
3+
4+
class CustomFormat(lit.formats.ShTest):
5+
def getTestsForPath(self, testSuite, path_in_suite, litConfig, localConfig):
6+
for sub in ['one.test', 'two.test']:
7+
basePath = os.path.dirname(testSuite.getExecPath(path_in_suite))
8+
os.makedirs(basePath, exist_ok=True)
9+
generatedFile = os.path.join(basePath, sub)
10+
with open(generatedFile, 'w') as f:
11+
f.write('RUN: true')
12+
yield lit.Test.Test(testSuite, (generatedFile, ), localConfig)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import sys, os
2+
sys.path.append(os.path.dirname(__file__))
3+
from custom_format import CustomFormat
4+
5+
config.name = "discovery-getTestsForPath-suite"
6+
config.suffixes = [".test"]
7+
config.test_format = CustomFormat()
8+
config.test_source_root = None
9+
config.test_exec_root = None

llvm/utils/lit/tests/Inputs/discovery-getTestsForPath/x.test

Whitespace-only changes.

llvm/utils/lit/tests/discovery.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,15 @@
134134
# CHECK-ASEXEC-DIRECT-TEST: -- Available Tests --
135135
# CHECK-ASEXEC-DIRECT-TEST: top-level-suite :: subdir/test-three
136136

137-
# Check an error is emitted when the directly named test would not be run
138-
# indirectly (e.g. when the directory containing the test is specified).
137+
# Check that an error is emitted when the directly named test does not satisfy
138+
# the test config's requirements.
139139
#
140140
# RUN: not %{lit} \
141141
# RUN: %{inputs}/discovery/test.not-txt 2>%t.err
142-
# RUN: FileCheck --check-prefix=CHECK-ERROR-INDIRECT-RUN-CHECK < %t.err %s
142+
# RUN: FileCheck --check-prefix=CHECK-ERROR-INPUT-CONTAINED-NO-TESTS < %t.err %s
143143
#
144-
# CHECK-ERROR-INDIRECT-RUN-CHECK: error: 'top-level-suite :: test.not-txt' would not be run indirectly
144+
# CHECK-ERROR-INPUT-CONTAINED-NO-TESTS: warning: input 'Inputs/discovery/test.not-txt' contained no tests
145+
# CHECK-ERROR-INPUT-CONTAINED-NO-TESTS: error: did not discover any tests for provided path(s)
145146

146147
# Check that no error is emitted with --no-indirectly-run-check.
147148
#
@@ -178,6 +179,15 @@
178179
#
179180
# CHECK-STANDALONE-DISCOVERY: error: did not discover any tests for provided path(s)
180181

182+
# Check that a single file path can result in multiple tests being discovered if
183+
# the test format implements those semantics.
184+
#
185+
# RUN: %{lit} %{inputs}/discovery-getTestsForPath/x.test > %t.out
186+
# RUN: FileCheck --check-prefix=CHECK-getTestsForPath < %t.out %s
187+
#
188+
# CHECK-getTestsForPath: PASS: discovery-getTestsForPath-suite :: {{.+}}one.test
189+
# CHECK-getTestsForPath: PASS: discovery-getTestsForPath-suite :: {{.+}}two.test
190+
181191
# Check that we don't recurse infinitely when loading an site specific test
182192
# suite located inside the test source root.
183193
#

0 commit comments

Comments
 (0)