diff --git a/libcxx/utils/libcxx/test/format.py b/libcxx/utils/libcxx/test/format.py --- a/libcxx/utils/libcxx/test/format.py +++ b/libcxx/utils/libcxx/test/format.py @@ -182,7 +182,7 @@ return script -class CxxStandardLibraryTest(lit.formats.TestFormat): +class CxxStandardLibraryTest(lit.formats.FileBasedTest): """ Lit test format for the C++ Standard Library conformance test suite. @@ -278,7 +278,7 @@ in conjunction with the %{build} substitution. """ - def getTestsInDirectory(self, testSuite, pathInSuite, litConfig, localConfig): + def getTestsForFilename(self, testSuite, pathInSuite, litConfig, localConfig): SUPPORTED_SUFFIXES = [ "[.]pass[.]cpp$", "[.]pass[.]mm$", @@ -293,22 +293,22 @@ "[.]verify[.]cpp$", "[.]fail[.]cpp$", ] + sourcePath = testSuite.getSourcePath(pathInSuite) - for filename in os.listdir(sourcePath): - # Ignore dot files and excluded tests. - if filename.startswith(".") or filename in localConfig.excludes: - continue - - filepath = os.path.join(sourcePath, filename) - if not os.path.isdir(filepath): - if any([re.search(ext, filename) for ext in SUPPORTED_SUFFIXES]): - # If this is a generated test, run the generation step and add - # as many Lit tests as necessary. - if re.search('[.]gen[.][^.]+$', filename): - for test in self._generateGenTest(testSuite, pathInSuite + (filename,), litConfig, localConfig): - yield test - else: - yield lit.Test.Test(testSuite, pathInSuite + (filename,), localConfig) + filename = os.path.basename(sourcePath) + + # Ignore dot files, excluded tests and tests with an unsupported suffix + hasSupportedSuffix = lambda f: any([re.search(ext, f) for ext in SUPPORTED_SUFFIXES]) + if filename.startswith(".") or filename in localConfig.excludes or not hasSupportedSuffix(filename): + return + + # If this is a generated test, run the generation step and add + # as many Lit tests as necessary. + if re.search('[.]gen[.][^.]+$', filename): + for test in self._generateGenTest(testSuite, pathInSuite, litConfig, localConfig): + yield test + else: + yield lit.Test.Test(testSuite, pathInSuite, localConfig) def execute(self, test, litConfig): VERIFY_FLAGS = ( diff --git a/llvm/utils/lit/examples/many-tests/ManyTests.py b/llvm/utils/lit/examples/many-tests/ManyTests.py --- a/llvm/utils/lit/examples/many-tests/ManyTests.py +++ b/llvm/utils/lit/examples/many-tests/ManyTests.py @@ -1,7 +1,7 @@ -from lit import Test +from lit import Test, TestFormat -class ManyTests(object): +class ManyTests(TestFormat): def __init__(self, N=10000): self.N = N diff --git a/llvm/utils/lit/lit/discovery.py b/llvm/utils/lit/lit/discovery.py --- a/llvm/utils/lit/lit/discovery.py +++ b/llvm/utils/lit/lit/discovery.py @@ -163,35 +163,38 @@ if not os.path.isdir(source_path): test_dir_in_suite = path_in_suite[:-1] lc = getLocalConfig(ts, test_dir_in_suite, litConfig, localConfigCache) - test = Test.Test(ts, path_in_suite, lc) - - # Issue a error if the specified test would not be run if - # the user had specified the containing directory instead of - # of naming the test directly. This helps to avoid writing - # tests which are not executed. The check adds some performance - # overhead which might be important if a large number of tests - # are being run directly. - # This check can be disabled by using --no-indirectly-run-check or - # setting the standalone_tests variable in the suite's configuration. - if ( - indirectlyRunCheck - and lc.test_format is not None - and not lc.standalone_tests - ): - found = False - for res in lc.test_format.getTestsInDirectory( - ts, test_dir_in_suite, litConfig, lc + + tests = [Test.Test(ts, path_in_suite, lc)] if lc.test_format is None else \ + lc.test_format.getTestsForFilename(ts, path_in_suite, litConfig, lc) + + for test in tests: + # Issue a error if the specified test would not be run if + # the user had specified the containing directory instead of + # of naming the test directly. This helps to avoid writing + # tests which are not executed. The check adds some performance + # overhead which might be important if a large number of tests + # are being run directly. + # This check can be disabled by using --no-indirectly-run-check or + # setting the standalone_tests variable in the suite's configuration. + if ( + indirectlyRunCheck + and lc.test_format is not None + and not lc.standalone_tests ): - if test.getFullName() == res.getFullName(): - found = True - break - if not found: - litConfig.error( - "%r would not be run indirectly: change name or LIT config" - "(e.g. suffixes or standalone_tests variables)" % test.getFullName() - ) - - yield test + found = False + for res in lc.test_format.getTestsInDirectory( + ts, test_dir_in_suite, litConfig, lc + ): + if test.getFullName() == res.getFullName(): + found = True + break + if not found: + litConfig.error( + "%r would not be run indirectly: change name or LIT config" + "(e.g. suffixes or standalone_tests variables)" % test.getFullName() + ) + + yield test return # Otherwise we have a directory to search for tests, start by getting the diff --git a/llvm/utils/lit/lit/formats/base.py b/llvm/utils/lit/lit/formats/base.py --- a/llvm/utils/lit/lit/formats/base.py +++ b/llvm/utils/lit/lit/formats/base.py @@ -6,8 +6,21 @@ class TestFormat(object): - pass - + def getTestsForFilename(self, testSuite, path_in_suite, litConfig, localConfig): + """ + Given the path to a test in the test suite, generates the Lit tests associated + to that path. There can be more than one test in cases where the testing format + allows generating multiple tests associated to a single path. + """ + filename = path_in_suite[-1] + + # Ignore dot files and excluded tests. + if filename.startswith(".") or filename in localConfig.excludes: + return + + base, ext = os.path.splitext(filename) + if ext in localConfig.suffixes: + yield lit.Test.Test(testSuite, path_in_suite, localConfig) ### @@ -16,17 +29,10 @@ def getTestsInDirectory(self, testSuite, path_in_suite, litConfig, localConfig): source_path = testSuite.getSourcePath(path_in_suite) for filename in os.listdir(source_path): - # Ignore dot files and excluded tests. - if filename.startswith(".") or filename in localConfig.excludes: - continue - filepath = os.path.join(source_path, filename) if not os.path.isdir(filepath): - base, ext = os.path.splitext(filename) - if ext in localConfig.suffixes: - yield lit.Test.Test( - testSuite, path_in_suite + (filename,), localConfig - ) + for t in self.getTestsForFilename(testSuite, path_in_suite + (filename,), litConfig, localConfig): + yield t ### @@ -76,12 +82,10 @@ suffix = path[len(dir) :] if suffix.startswith(os.sep): suffix = suffix[1:] - test = lit.Test.Test( - testSuite, path_in_suite + tuple(suffix.split(os.sep)), localConfig - ) - # FIXME: Hack? - test.source_path = path - yield test + for test in self.getTestsForFilename(testSuite, path_in_suite + tuple(suffix.split(os.sep)), litConfig, localConfig): + # FIXME: Hack? + test.source_path = path + yield test def createTempInput(self, tmp, test): raise NotImplementedError("This is an abstract method.")