ext: Run pre-commit run --files ext/testlib

Change-Id: Ic581132f6136dddb127e2a1c5a1ecc19876488c3
This commit is contained in:
Bobby R. Bruce
2023-09-04 23:51:14 -07:00
parent ff75e5b30e
commit 9e1afdecef
17 changed files with 952 additions and 709 deletions

View File

@@ -26,7 +26,7 @@
#
# Authors: Sean Wilson
'''
"""
Contains the :class:`Loader` which is responsible for discovering and loading
tests.
@@ -63,7 +63,7 @@ a :class:`TestSuite` by the test writer will be placed into
a :class:`TestSuite` named after the module.
.. seealso:: :func:`load_file`
'''
"""
import os
import re
@@ -77,44 +77,52 @@ import testlib.fixture as fixture_mod
import testlib.wrappers as wrappers
import testlib.uid as uid
class DuplicateTestItemException(Exception):
'''
"""
Exception indicates multiple test items with the same UID
were discovered.
'''
"""
pass
# Match filenames that either begin or end with 'test' or tests and use
# - or _ to separate additional name components.
default_filepath_regex = re.compile(
r'(((.+[_])?tests?)|(tests?([-_].+)?))\.py$')
r"(((.+[_])?tests?)|(tests?([-_].+)?))\.py$"
)
def default_filepath_filter(filepath):
'''The default filter applied to filepaths to marks as test sources.'''
"""The default filter applied to filepaths to marks as test sources."""
filepath = os.path.basename(filepath)
if default_filepath_regex.match(filepath):
# Make sure doesn't start with .
return not filepath.startswith('.')
return not filepath.startswith(".")
return False
def path_as_modulename(filepath):
'''Return the given filepath as a module name.'''
"""Return the given filepath as a module name."""
# Remove the file extention (.py)
return os.path.splitext(os.path.basename(filepath))[0]
def path_as_suitename(filepath):
return os.path.split(os.path.dirname(os.path.abspath((filepath))))[-1]
def _assert_files_in_same_dir(files):
if __debug__:
if files:
directory = os.path.dirname(files[0])
for f in files:
assert(os.path.dirname(f) == directory)
assert os.path.dirname(f) == directory
class Loader(object):
'''
"""
Class for discovering tests.
Discovered :class:`TestCase` and :class:`TestSuite` objects are wrapped by
@@ -135,7 +143,8 @@ class Loader(object):
.. warn:: This class is extremely thread-unsafe.
It modifies the sys path and global config.
Use with care.
'''
"""
def __init__(self):
self.suites = []
self.suite_uids = {}
@@ -153,16 +162,15 @@ class Loader(object):
for file_ in files:
self.load_file(file_)
return wrappers.LoadedLibrary(
[self.suite_uids[id_] for id_ in uids])
return wrappers.LoadedLibrary([self.suite_uids[id_] for id_ in uids])
def _verify_no_duplicate_suites(self, new_suites):
new_suite_uids = self.suite_uids.copy()
for suite in new_suites:
if suite.uid in new_suite_uids:
raise DuplicateTestItemException(
"More than one suite with UID '%s' was defined" %\
suite.uid)
"More than one suite with UID '%s' was defined" % suite.uid
)
new_suite_uids[suite.uid] = suite
def _verify_no_duplicate_tests_in_suites(self, new_suites):
@@ -170,17 +178,17 @@ class Loader(object):
test_uids = set()
for test in suite:
if test.uid in test_uids:
raise DuplicateTestItemException(
"More than one test with UID '%s' was defined"
" in suite '%s'"
% (test.uid, suite.uid))
raise DuplicateTestItemException(
"More than one test with UID '%s' was defined"
" in suite '%s'" % (test.uid, suite.uid)
)
test_uids.add(test.uid)
def load_root(self, root):
'''
"""
Load files from the given root directory which match
`self.filepath_filter`.
'''
"""
for directory in self._discover_files(root):
directory = list(directory)
if directory:
@@ -193,17 +201,18 @@ class Loader(object):
if path in self._files:
if not self._files[path]:
raise Exception('Attempted to load a file which already'
' failed to load')
raise Exception(
"Attempted to load a file which already" " failed to load"
)
else:
log.test_log.debug('Tried to reload: %s' % path)
log.test_log.debug("Tried to reload: %s" % path)
return
# Create a custom dictionary for the loaded module.
newdict = {
'__builtins__':__builtins__,
'__name__': path_as_modulename(path),
'__file__': path,
"__builtins__": __builtins__,
"__name__": path_as_modulename(path),
"__file__": path,
}
# Add the file's containing directory to the system path. So it can do
@@ -222,9 +231,9 @@ class Loader(object):
except Exception as e:
log.test_log.debug(traceback.format_exc())
log.test_log.warn(
'Exception thrown while loading "%s"\n'
'Ignoring all tests in this file.'
% (path))
'Exception thrown while loading "%s"\n'
"Ignoring all tests in this file." % (path)
)
# Clean up
sys.path[:] = old_path
os.chdir(cwd)
@@ -247,27 +256,34 @@ class Loader(object):
# tests.
# NOTE: This is automatically collected (we still have the
# collector active.)
suite_mod.TestSuite(tests=orphan_tests,
name=path_as_suitename(path))
suite_mod.TestSuite(
tests=orphan_tests, name=path_as_suitename(path)
)
try:
loaded_suites = [wrappers.LoadedSuite(suite, path)
for suite in new_suites]
loaded_suites = [
wrappers.LoadedSuite(suite, path) for suite in new_suites
]
self._verify_no_duplicate_suites(loaded_suites)
self._verify_no_duplicate_tests_in_suites(loaded_suites)
except Exception as e:
log.test_log.warn('%s\n'
'Exception thrown while loading "%s"\n'
'Ignoring all tests in this file.'
% (traceback.format_exc(), path))
log.test_log.warn(
"%s\n"
'Exception thrown while loading "%s"\n'
"Ignoring all tests in this file."
% (traceback.format_exc(), path)
)
else:
log.test_log.info('Discovered %d tests and %d suites in %s'
'' % (len(new_tests), len(loaded_suites), path))
log.test_log.info(
"Discovered %d tests and %d suites in %s"
"" % (len(new_tests), len(loaded_suites), path)
)
self.suites.extend(loaded_suites)
self.suite_uids.update({suite.uid: suite
for suite in loaded_suites})
self.suite_uids.update(
{suite.uid: suite for suite in loaded_suites}
)
# Clean up
sys.path[:] = old_path
os.chdir(cwd)
@@ -276,18 +292,19 @@ class Loader(object):
fixture_mod.Fixture.collector.remove(new_fixtures)
def _discover_files(self, root):
'''
"""
Recurse down from the given root directory returning a list of
directories which contain a list of files matching
`self.filepath_filter`.
'''
"""
# Will probably want to order this traversal.
for root, dirnames, filenames in os.walk(root):
dirnames.sort()
if filenames:
filenames.sort()
filepaths = [os.path.join(root, filename) \
for filename in filenames]
filepaths = [
os.path.join(root, filename) for filename in filenames
]
filepaths = filter(self.filepath_filter, filepaths)
if filepaths:
yield filepaths