144 lines
4.5 KiB
Python
Executable File
144 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
##===--- run_iwyu_tests.py - include-what-you-use test framework driver ---===##
|
|
#
|
|
# The LLVM Compiler Infrastructure
|
|
#
|
|
# This file is distributed under the University of Illinois Open Source
|
|
# License. See LICENSE.TXT for details.
|
|
#
|
|
##===----------------------------------------------------------------------===##
|
|
|
|
"""A test harness for IWYU testing."""
|
|
|
|
__author__ = 'dsturtevant@google.com (Dean Sturtevant)'
|
|
|
|
import argparse
|
|
import glob
|
|
import os
|
|
import re
|
|
import sys
|
|
import unittest
|
|
import logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
import posixpath
|
|
from fnmatch import fnmatch
|
|
import iwyu_test_util
|
|
|
|
|
|
def PosixPath(path):
|
|
"""Normalize Windows path separators to POSIX path separators."""
|
|
return path.replace('\\', '/')
|
|
|
|
|
|
def Partition(l, delimiter):
|
|
try:
|
|
delim_index = l.index(delimiter)
|
|
except ValueError:
|
|
return l, []
|
|
|
|
return l[:delim_index], l[delim_index+1:]
|
|
|
|
|
|
def TestIwyuOnRelevantFiles(filename):
|
|
logging.info('Testing iwyu on %s', filename)
|
|
# Split full/path/to/foo.cc into full/path/to/foo and .cc.
|
|
(all_but_extension, extension) = os.path.splitext(filename)
|
|
(dirname, basename) = os.path.split(all_but_extension)
|
|
# Generate diagnostics on all foo-* files (well, not other
|
|
# foo-*.cc files, which is not kosher but is legal), in addition
|
|
# to foo.h (if present) and foo.cc.
|
|
all_files = (glob.glob('%s-*' % all_but_extension) +
|
|
glob.glob('%s/*/%s-*' % (dirname, basename)) +
|
|
glob.glob('%s.h' % all_but_extension) +
|
|
glob.glob('%s/*/%s.h' % (dirname, basename)))
|
|
|
|
files_to_check = [f for f in all_files if not f.endswith(extension)]
|
|
files_to_check.append(filename)
|
|
|
|
# IWYU emits summaries with canonicalized filepaths, where all the
|
|
# directory separators are set to '/'. In order for the testsuite to
|
|
# correctly match up file summaries, we must canonicalize the filepaths
|
|
# in the same way here.
|
|
files_to_check = [PosixPath(f) for f in files_to_check]
|
|
iwyu_test_util.TestIwyuOnRelativeFile(filename, files_to_check, verbose=True)
|
|
|
|
|
|
def GenerateTests(rootdir, pattern):
|
|
def _AddTestFunctions(cls):
|
|
filenames = []
|
|
test_files = {}
|
|
for (dirpath, _, files) in os.walk(rootdir):
|
|
dirpath = PosixPath(dirpath) # Normalize path separators.
|
|
filenames.extend(posixpath.join(dirpath, f) for f in files
|
|
if fnmatch(f, pattern))
|
|
if not filenames:
|
|
print('No tests found in %s!' % os.path.abspath(rootdir))
|
|
return
|
|
|
|
for filename in filenames:
|
|
all_but_extension = os.path.splitext(filename)[0]
|
|
basename = os.path.basename(all_but_extension)
|
|
test_name = re.sub('[^0-9a-zA-Z_]', '_', basename) # python-clean
|
|
test_name = 'test_%s' % test_name
|
|
|
|
while hasattr(cls, test_name): # already have a class with that name
|
|
test_name += '2' # just append a suffix :-)
|
|
|
|
setattr(cls, test_name, lambda x, f=filename: TestIwyuOnRelevantFiles(f))
|
|
test_files[test_name] = filename
|
|
|
|
setattr(cls, 'test_files', test_files)
|
|
|
|
return cls
|
|
|
|
return _AddTestFunctions
|
|
|
|
|
|
def EnumerateLoadedTests():
|
|
for suite in unittest.defaultTestLoader.loadTestsFromModule(sys.modules[__name__]):
|
|
for test in suite:
|
|
yield (test.__class__, test._testMethodName)
|
|
|
|
|
|
def PrintLoadedTests():
|
|
for (cls, test) in EnumerateLoadedTests():
|
|
print('%s.%s' % (cls.__name__, test))
|
|
|
|
|
|
def PrintLoadedTestsAndFiles():
|
|
for (cls, test) in EnumerateLoadedTests():
|
|
print('%s.%s:%s' % (cls.__name__, test, cls.test_files[test]))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest_args, additional_args = Partition(sys.argv, '--')
|
|
if additional_args:
|
|
iwyu_test_util.SetIwyuPath(additional_args[0])
|
|
|
|
parser = argparse.ArgumentParser(add_help=False, usage=argparse.SUPPRESS)
|
|
group = parser.add_mutually_exclusive_group()
|
|
group.add_argument('--list', dest='list_tests', action='store_true')
|
|
group.add_argument('--list-test-files', action='store_true')
|
|
group.add_argument('--run-test-file')
|
|
(runner_args, _) = parser.parse_known_args(unittest_args)
|
|
|
|
if runner_args.run_test_file:
|
|
exit(TestIwyuOnRelevantFiles(runner_args.run_test_file))
|
|
|
|
@GenerateTests(rootdir='tests/c', pattern='*.c')
|
|
class c(unittest.TestCase): pass
|
|
|
|
@GenerateTests(rootdir='tests/cxx', pattern='*.cc')
|
|
class cxx(unittest.TestCase): pass
|
|
|
|
@GenerateTests(rootdir='tests/driver', pattern='*.c')
|
|
class driver(unittest.TestCase): pass
|
|
|
|
if runner_args.list_tests:
|
|
exit(PrintLoadedTests())
|
|
elif runner_args.list_test_files:
|
|
exit(PrintLoadedTestsAndFiles())
|
|
|
|
unittest.main(argv=unittest_args)
|