mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-07-29 11:41:15 +03:00
Clean up not-implemented detection
Move hack_dependencies_not_implemented into a class to make the file structure easier to understand and reduce the visibility of the _implemented_dependencies cache. Rename it because it's no longer a temporary hack (originally intended to work around the fact that not all PSA_WANT symbols were implemented), it's now a way to detect test cases for cryptographic mechanisms that are declared but not implemented. Internal refactoring only. No behavior change. Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
import re
|
||||
from typing import Dict, FrozenSet, List, Optional, Set
|
||||
from typing import Dict, FrozenSet, Iterator, List, Optional, Set
|
||||
|
||||
from . import macro_collector
|
||||
from . import test_case
|
||||
@ -54,30 +54,6 @@ def automatic_dependencies(*expressions: str) -> List[str]:
|
||||
used.difference_update(SYMBOLS_WITHOUT_DEPENDENCY)
|
||||
return sorted(psa_want_symbol(name) for name in used)
|
||||
|
||||
# Skip test cases for which the dependency symbols are not defined.
|
||||
# We assume that this means that a required mechanism is not implemented.
|
||||
# Note that if we erroneously skip generating test cases for
|
||||
# mechanisms that are not implemented, this should be caught
|
||||
# by the NOT_SUPPORTED test cases generated by generate_psa_tests.py
|
||||
# in test_suite_psa_crypto_not_supported and test_suite_psa_crypto_op_fail:
|
||||
# those emit negative tests, which will not be skipped here.
|
||||
def read_implemented_dependencies(filename: str) -> FrozenSet[str]:
|
||||
return frozenset(symbol
|
||||
for line in open(filename)
|
||||
for symbol in re.findall(r'\bPSA_WANT_\w+\b', line))
|
||||
_implemented_dependencies = None #type: Optional[FrozenSet[str]] #pylint: disable=invalid-name
|
||||
|
||||
def hack_dependencies_not_implemented(dependencies: List[str]) -> None:
|
||||
global _implemented_dependencies #pylint: disable=global-statement,invalid-name
|
||||
if _implemented_dependencies is None:
|
||||
_implemented_dependencies = \
|
||||
read_implemented_dependencies('include/psa/crypto_config.h')
|
||||
_implemented_dependencies = _implemented_dependencies.union(
|
||||
read_implemented_dependencies('include/mbedtls/config_psa.h'))
|
||||
for dep in dependencies:
|
||||
if dep.startswith('PSA_WANT') and dep not in _implemented_dependencies:
|
||||
dependencies.append('DEPENDENCY_NOT_IMPLEMENTED_YET_' + dep)
|
||||
dependencies.sort()
|
||||
|
||||
class Information:
|
||||
"""Gather information about PSA constructors."""
|
||||
@ -119,6 +95,47 @@ class TestCase(test_case.TestCase):
|
||||
involved in a given test case.
|
||||
"""
|
||||
|
||||
# Use a class variable to cache the set of implemented dependencies.
|
||||
# Call read_implemented_dependencies() to fill the cache.
|
||||
_implemented_dependencies = None #type: Optional[FrozenSet[str]]
|
||||
|
||||
DEPENDENCY_SYMBOL_RE = re.compile(r'\bPSA_WANT_\w+\b')
|
||||
@classmethod
|
||||
def _yield_implemented_dependencies(cls) -> Iterator[str]:
|
||||
for filename in ['include/psa/crypto_config.h',
|
||||
'include/mbedtls/config_psa.h']:
|
||||
with open(filename) as inp:
|
||||
content = inp.read()
|
||||
yield from cls.DEPENDENCY_SYMBOL_RE.findall(content)
|
||||
|
||||
@classmethod
|
||||
def read_implemented_dependencies(cls) -> FrozenSet[str]:
|
||||
if cls._implemented_dependencies is None:
|
||||
cls._implemented_dependencies = \
|
||||
frozenset(cls._yield_implemented_dependencies())
|
||||
# Redundant return to reassure pylint (mypy is fine without it).
|
||||
# Known issue: https://github.com/pylint-dev/pylint/issues/3045
|
||||
return cls._implemented_dependencies
|
||||
return cls._implemented_dependencies
|
||||
|
||||
# We skip test cases for which the dependency symbols are not defined.
|
||||
# We assume that this means that a required mechanism is not implemented.
|
||||
# Note that if we erroneously skip generating test cases for
|
||||
# mechanisms that are not implemented, this should be caught
|
||||
# by the NOT_SUPPORTED test cases generated by generate_psa_tests.py
|
||||
# in test_suite_psa_crypto_not_supported and test_suite_psa_crypto_op_fail:
|
||||
# those emit negative tests, which will not be skipped here.
|
||||
def detect_not_implemented_dependencies(self) -> None:
|
||||
"""Detect dependencies that are not implemented."""
|
||||
all_implemented_dependencies = self.read_implemented_dependencies()
|
||||
not_implemented = set()
|
||||
for dep in self.dependencies:
|
||||
if (dep.startswith('PSA_WANT') and
|
||||
dep not in all_implemented_dependencies):
|
||||
not_implemented.add('DEPENDENCY_NOT_IMPLEMENTED_YET_' + dep)
|
||||
self.dependencies = sorted(not_implemented) + self.dependencies
|
||||
self.dependencies.sort()
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.key_bits = None #type: Optional[int]
|
||||
@ -157,5 +174,5 @@ class TestCase(test_case.TestCase):
|
||||
dependencies[i] = '!' + dependencies[i]
|
||||
if self.key_bits is not None:
|
||||
dependencies = finish_family_dependencies(dependencies, self.key_bits)
|
||||
hack_dependencies_not_implemented(dependencies)
|
||||
self.dependencies += dependencies
|
||||
self.dependencies += sorted(dependencies)
|
||||
self.detect_not_implemented_dependencies()
|
||||
|
Reference in New Issue
Block a user