Rework TestGenerator to add file targets

BaseTarget-derived targets are now added to TestGenerator.targets in
initialization. This reduces repeated code in generate_xxx_tests.py
scripts which use this framework.

Signed-off-by: Werner Lewis <werner.lewis@arm.com>
This commit is contained in:
Werner Lewis 2022-09-02 11:56:34 +01:00
parent aaf3b79bbb
commit a4668a6b6c
3 changed files with 20 additions and 20 deletions

View File

@ -133,6 +133,11 @@ class TestGenerator:
"""Generate test data.""" """Generate test data."""
def __init__(self, options) -> None: def __init__(self, options) -> None:
self.test_suite_directory = getattr(options, 'directory') self.test_suite_directory = getattr(options, 'directory')
# Add file Targets which have been declared in other modules
self.targets.update({
subclass.target_basename: subclass.generate_tests
for subclass in BaseTarget.__subclasses__()
})
def filename_for(self, basename: str) -> str: def filename_for(self, basename: str) -> str:
"""The location of the data file with the specified base name.""" """The location of the data file with the specified base name."""
@ -149,7 +154,7 @@ class TestGenerator:
# Note that targets whose names contain 'test_format' have their content # Note that targets whose names contain 'test_format' have their content
# validated by `abi_check.py`. # validated by `abi_check.py`.
TARGETS = {} # type: Dict[str, Callable[..., Iterable[test_case.TestCase]]] targets = {} # type: Dict[str, Callable[..., Iterable[test_case.TestCase]]]
def generate_target(self, name: str, *target_args) -> None: def generate_target(self, name: str, *target_args) -> None:
"""Generate cases and write to data file for a target. """Generate cases and write to data file for a target.
@ -157,7 +162,7 @@ class TestGenerator:
For target callables which require arguments, override this function For target callables which require arguments, override this function
and pass these arguments using super() (see PSATestGenerator). and pass these arguments using super() (see PSATestGenerator).
""" """
test_cases = self.TARGETS[name](*target_args) test_cases = self.targets[name](*target_args)
self.write_test_data_file(name, test_cases) self.write_test_data_file(name, test_cases)
def main(args, generator_class: Type[TestGenerator] = TestGenerator): def main(args, generator_class: Type[TestGenerator] = TestGenerator):
@ -170,25 +175,27 @@ def main(args, generator_class: Type[TestGenerator] = TestGenerator):
parser.add_argument('--directory', default="tests/suites", metavar='DIR', parser.add_argument('--directory', default="tests/suites", metavar='DIR',
help='Output directory (default: tests/suites)') help='Output directory (default: tests/suites)')
parser.add_argument('targets', nargs='*', metavar='TARGET', parser.add_argument('targets', nargs='*', metavar='TARGET',
default=sorted(generator_class.TARGETS),
help='Target file to generate (default: all; "-": none)') help='Target file to generate (default: all; "-": none)')
options = parser.parse_args(args) options = parser.parse_args(args)
build_tree.chdir_to_root() build_tree.chdir_to_root()
generator = generator_class(options) generator = generator_class(options)
if options.list: if options.list:
for name in sorted(generator.TARGETS): for name in sorted(generator.targets):
print(generator.filename_for(name)) print(generator.filename_for(name))
return return
# List in a cmake list format (i.e. ';'-separated) # List in a cmake list format (i.e. ';'-separated)
if options.list_for_cmake: if options.list_for_cmake:
print(';'.join(generator.filename_for(name) print(';'.join(generator.filename_for(name)
for name in sorted(generator.TARGETS)), end='') for name in sorted(generator.targets)), end='')
return return
# Allow "-" as a special case so you can run if options.targets:
# ``generate_xxx_tests.py - $targets`` and it works uniformly whether # Allow "-" as a special case so you can run
# ``$targets`` is empty or not. # ``generate_xxx_tests.py - $targets`` and it works uniformly whether
options.targets = [os.path.basename(re.sub(r'\.data\Z', r'', target)) # ``$targets`` is empty or not.
for target in options.targets options.targets = [os.path.basename(re.sub(r'\.data\Z', r'', target))
if target != '-'] for target in options.targets
if target != '-']
else:
options.targets = sorted(generator.targets)
for target in options.targets: for target in options.targets:
generator.generate_target(target) generator.generate_target(target)

View File

@ -231,12 +231,5 @@ class BignumAdd(BignumOperation):
return quote_str(hex(self.int_l + self.int_r).replace("0x", "", 1)) return quote_str(hex(self.int_l + self.int_r).replace("0x", "", 1))
class BignumTestGenerator(test_generation.TestGenerator):
"""Test generator subclass, for bignum file Targets."""
TARGETS = {
subclass.target_basename: subclass.generate_tests for subclass in
test_generation.BaseTarget.__subclasses__()
} # type: Dict[str, Callable[[], Iterable[test_case.TestCase]]]
if __name__ == '__main__': if __name__ == '__main__':
test_generation.main(sys.argv[1:], BignumTestGenerator) test_generation.main(sys.argv[1:])

View File

@ -896,7 +896,7 @@ class PSATestGenerator(test_generation.TestGenerator):
"""Test generator subclass including PSA targets and info.""" """Test generator subclass including PSA targets and info."""
# Note that targets whose names contain 'test_format' have their content # Note that targets whose names contain 'test_format' have their content
# validated by `abi_check.py`. # validated by `abi_check.py`.
TARGETS = { targets = {
'test_suite_psa_crypto_generate_key.generated': 'test_suite_psa_crypto_generate_key.generated':
lambda info: KeyGenerate(info).test_cases_for_key_generation(), lambda info: KeyGenerate(info).test_cases_for_key_generation(),
'test_suite_psa_crypto_not_supported.generated': 'test_suite_psa_crypto_not_supported.generated':