mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-08-01 10:06:53 +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
|
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 macro_collector
|
||||||
from . import test_case
|
from . import test_case
|
||||||
@ -54,30 +54,6 @@ def automatic_dependencies(*expressions: str) -> List[str]:
|
|||||||
used.difference_update(SYMBOLS_WITHOUT_DEPENDENCY)
|
used.difference_update(SYMBOLS_WITHOUT_DEPENDENCY)
|
||||||
return sorted(psa_want_symbol(name) for name in used)
|
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:
|
class Information:
|
||||||
"""Gather information about PSA constructors."""
|
"""Gather information about PSA constructors."""
|
||||||
@ -119,6 +95,47 @@ class TestCase(test_case.TestCase):
|
|||||||
involved in a given test case.
|
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:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.key_bits = None #type: Optional[int]
|
self.key_bits = None #type: Optional[int]
|
||||||
@ -157,5 +174,5 @@ class TestCase(test_case.TestCase):
|
|||||||
dependencies[i] = '!' + dependencies[i]
|
dependencies[i] = '!' + dependencies[i]
|
||||||
if self.key_bits is not None:
|
if self.key_bits is not None:
|
||||||
dependencies = finish_family_dependencies(dependencies, self.key_bits)
|
dependencies = finish_family_dependencies(dependencies, self.key_bits)
|
||||||
hack_dependencies_not_implemented(dependencies)
|
self.dependencies += sorted(dependencies)
|
||||||
self.dependencies += dependencies
|
self.detect_not_implemented_dependencies()
|
||||||
|
Reference in New Issue
Block a user