Clarify documentation

Signed-off-by: Werner Lewis <werner.lewis@arm.com>
This commit is contained in:
Werner Lewis 2022-08-25 12:29:46 +01:00
parent f156c43702
commit 6ef5436f3c
2 changed files with 40 additions and 30 deletions

View file

@ -35,6 +35,8 @@ T = TypeVar('T') #pylint: disable=invalid-name
class BaseTarget(metaclass=ABCMeta): class BaseTarget(metaclass=ABCMeta):
"""Base target for test case generation. """Base target for test case generation.
This should be derived from for file Targets.
Attributes: Attributes:
count: Counter for test cases from this class. count: Counter for test cases from this class.
case_description: Short description of the test case. This may be case_description: Short description of the test case. This may be
@ -43,7 +45,8 @@ class BaseTarget(metaclass=ABCMeta):
should be specified in a child class of BaseTarget. should be specified in a child class of BaseTarget.
test_function: Test function which the class generates cases for. test_function: Test function which the class generates cases for.
test_name: A common name or description of the test function. This can test_name: A common name or description of the test function. This can
be the function's name, or a short summary of its purpose. be `test_function`, a clearer equivalent, or a short summary of the
test function's purpose.
""" """
count = 0 count = 0
case_description = "" case_description = ""
@ -61,7 +64,7 @@ class BaseTarget(metaclass=ABCMeta):
"""Get the list of arguments for the test case. """Get the list of arguments for the test case.
Override this method to provide the list of arguments required for Override this method to provide the list of arguments required for
generating the test_function. the `test_function`.
Returns: Returns:
List of arguments required for the test function. List of arguments required for the test function.
@ -69,12 +72,12 @@ class BaseTarget(metaclass=ABCMeta):
raise NotImplementedError raise NotImplementedError
def description(self) -> str: def description(self) -> str:
"""Create a test description. """Create a test case description.
Creates a description of the test case, including a name for the test Creates a description of the test case, including a name for the test
function, and describing the specific test case. This should inform a function, a case number, and a description the specific test case.
reader of the purpose of the case. The case description may be This should inform a reader what is being tested, and provide context
generated in the class, or provided manually as needed. for the test case.
Returns: Returns:
Description for the test case. Description for the test case.
@ -85,7 +88,7 @@ class BaseTarget(metaclass=ABCMeta):
def create_test_case(self) -> test_case.TestCase: def create_test_case(self) -> test_case.TestCase:
"""Generate TestCase from the current object.""" """Generate TestCase from the instance."""
tc = test_case.TestCase() tc = test_case.TestCase()
tc.set_description(self.description()) tc.set_description(self.description())
tc.set_function(self.test_function) tc.set_function(self.test_function)
@ -96,7 +99,7 @@ class BaseTarget(metaclass=ABCMeta):
@classmethod @classmethod
@abstractmethod @abstractmethod
def generate_function_tests(cls) -> Iterator[test_case.TestCase]: def generate_function_tests(cls) -> Iterator[test_case.TestCase]:
"""Generate test cases for the test function. """Generate test cases for the class test function.
This will be called in classes where `test_function` is set. This will be called in classes where `test_function` is set.
Implementations should yield TestCase objects, by creating instances Implementations should yield TestCase objects, by creating instances
@ -111,11 +114,10 @@ class BaseTarget(metaclass=ABCMeta):
In classes with `test_function` set, `generate_function_tests()` is In classes with `test_function` set, `generate_function_tests()` is
used to generate test cases first. used to generate test cases first.
In all classes, this method will iterate over its subclasses, and
yield from `generate_tests()` in each.
Calling this method on a class X will yield test cases from all classes In all classes, this method will iterate over its subclasses, and
derived from X. yield from `generate_tests()` in each. Calling this method on a class X
will yield test cases from all classes derived from X.
""" """
if cls.test_function: if cls.test_function:
yield from cls.generate_function_tests() yield from cls.generate_function_tests()

View file

@ -6,25 +6,33 @@ generate only the specified files.
Class structure: Class structure:
Target classes are directly derived from test_generation.BaseTarget, Child classes of test_generation.BaseTarget (file Targets) represent a target
representing a target file. These indicate where test cases will be written file. These indicate where test cases will be written to, for all subclasses of
to in classes derived from the Target. Multiple Target classes must not this Target. Multiple Target classes should not reuse a `target_basename`.
represent the same target_basename.
Each subclass derived from a Target can either be: Each subclass derived from a file Target can either be:
- A concrete class, representing a test function, which generates test cases. - A concrete class, representing a test function, which generates test cases.
- An abstract class containing shared methods and attributes, not associated - An abstract class containing shared methods and attributes, not associated
with a test function. An example is BignumOperation, which provides common with a test function. An example is BignumOperation, which provides
features used in binary bignum operations. common features used for bignum binary operations.
Both concrete and abstract subclasses can be derived from, to implement
additional test cases (see BignumCmp and BignumCmpAbs for examples of deriving
from abstract and concrete classes).
Adding test generation for a function: Adding test case generation for a function:
A subclass representing the test function should be added, deriving from a A subclass representing the test function should be added, deriving from a
Target class or a descendant. This subclass must set/implement the following: file Target. This test class must set/implement the following:
- test_function: the function name from the associated .function file. - test_function: the function name from the associated .function file.
- arguments(): generation of the arguments required for the test_function. - test_name: a descriptive name or brief summary to refer to the test
- generate_function_test(): generation of the test cases for the function. function.
- arguments(): a method to generate the list of arguments required for the
test_function.
- generate_function_test(): a method to generate TestCases for the function.
This should create instances of the class with required input data, and
call `.create_test_case()` to yield the TestCase.
Additional details and other attributes/methods are given in the documentation Additional details and other attributes/methods are given in the documentation
of BaseTarget in test_generation.py. of BaseTarget in test_generation.py.
@ -71,7 +79,7 @@ class BignumTarget(test_generation.BaseTarget, metaclass=ABCMeta):
class BignumOperation(BignumTarget, metaclass=ABCMeta): class BignumOperation(BignumTarget, metaclass=ABCMeta):
"""Common features for test cases covering binary bignum operations. """Common features for bignum binary operations.
This adds functionality common in binary operation tests. This includes This adds functionality common in binary operation tests. This includes
generation of case descriptions, using descriptions of values and symbols generation of case descriptions, using descriptions of values and symbols
@ -130,7 +138,7 @@ class BignumOperation(BignumTarget, metaclass=ABCMeta):
"""Generate a description of the argument val. """Generate a description of the argument val.
This produces a simple description of the value, which are used in test This produces a simple description of the value, which are used in test
case naming, to add context to the test cases. case naming, to add context.
""" """
if val == "": if val == "":
return "0 (null)" return "0 (null)"
@ -150,7 +158,7 @@ class BignumOperation(BignumTarget, metaclass=ABCMeta):
@classmethod @classmethod
def get_value_pairs(cls) -> Iterator[Tuple[str, str]]: def get_value_pairs(cls) -> Iterator[Tuple[str, str]]:
"""Generator for pairs of inputs. """Generator to yield pairs of inputs.
Combinations are first generated from all input values, and then Combinations are first generated from all input values, and then
specific cases provided. specific cases provided.
@ -169,7 +177,7 @@ class BignumOperation(BignumTarget, metaclass=ABCMeta):
class BignumCmp(BignumOperation): class BignumCmp(BignumOperation):
"""Target for bignum comparison test cases.""" """Test cases for bignum value comparison."""
count = 0 count = 0
test_function = "mbedtls_mpi_cmp_mpi" test_function = "mbedtls_mpi_cmp_mpi"
test_name = "MPI compare" test_name = "MPI compare"
@ -190,7 +198,7 @@ class BignumCmp(BignumOperation):
class BignumCmpAbs(BignumCmp): class BignumCmpAbs(BignumCmp):
"""Target for bignum comparison, absolute variant.""" """Test cases for absolute bignum value comparison."""
count = 0 count = 0
test_function = "mbedtls_mpi_cmp_abs" test_function = "mbedtls_mpi_cmp_abs"
test_name = "MPI compare (abs)" test_name = "MPI compare (abs)"
@ -200,7 +208,7 @@ class BignumCmpAbs(BignumCmp):
class BignumAdd(BignumOperation): class BignumAdd(BignumOperation):
"""Target for bignum addition test cases.""" """Test cases for bignum value addition."""
count = 0 count = 0
test_function = "mbedtls_mpi_add_mpi" test_function = "mbedtls_mpi_add_mpi"
test_name = "MPI add" test_name = "MPI add"
@ -223,7 +231,7 @@ class BignumAdd(BignumOperation):
class BignumTestGenerator(test_generation.TestGenerator): class BignumTestGenerator(test_generation.TestGenerator):
"""Test generator subclass including bignum targets.""" """Test generator subclass setting bignum targets."""
TARGETS = { TARGETS = {
subclass.target_basename: subclass.generate_tests for subclass in subclass.target_basename: subclass.generate_tests for subclass in
test_generation.BaseTarget.__subclasses__() test_generation.BaseTarget.__subclasses__()