Detect sub-options
When option A is only meaningful if option B is enabled, when enumerating
single-option test cases, emit A:B and !A:B rather than A and !A. This way
the "!A" case is actually meaningful.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/scripts/generate_config_tests.py b/scripts/generate_config_tests.py
index e78ff35..d97adad 100755
--- a/scripts/generate_config_tests.py
+++ b/scripts/generate_config_tests.py
@@ -40,6 +40,63 @@
return tc
+PSA_WANT_KEY_TYPE_KEY_PAIR_RE = \
+ re.compile(r'(?P<prefix>PSA_WANT_KEY_TYPE_(?P<type>\w+)_KEY_PAIR_)(?P<operation>\w+)\Z')
+
+# If foo is an option that is only meaningful when bar is enabled, set
+# SUPER_SETTINGS[foo]=bar. More generally, bar can be a colon-separated
+# list of options, meaning that all the options must be enabled. Each option
+# can be prefixed with '!' to negate it. This is the same syntax as a
+# depends_on directive in test data.
+# See also `find_super_option`.
+SUPER_SETTINGS = {
+ 'MBEDTLS_AESCE_C': 'MBEDTLS_AES_C',
+ 'MBEDTLS_AESNI_C': 'MBEDTLS_AES_C',
+ 'MBEDTLS_ERROR_STRERROR_DUMMY': '!MBEDTLS_ERROR_C',
+ 'MBEDTLS_GENPRIME': 'MBEDTLS_RSA_C',
+ 'MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES': 'MBEDTLS_ENTROPY_C',
+ 'MBEDTLS_NO_PLATFORM_ENTROPY': 'MBEDTLS_ENTROPY_C',
+ 'MBEDTLS_PKCS1_V15': 'MBEDTLS_RSA_C',
+ 'MBEDTLS_PKCS1_V21': 'MBEDTLS_RSA_C',
+ 'MBEDTLS_PSA_CRYPTO_CLIENT': 'MBEDTLS_PSA_CRYPTO_C',
+ 'MBEDTLS_PSA_INJECT_ENTROPY': 'MBEDTLS_PSA_CRYPTO_C',
+ 'MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS': 'MBEDTLS_PSA_CRYPTO_C',
+}
+
+def find_super_option(cfg: config.Config,
+ setting: config.Setting) -> Optional[str]:
+ """If setting is only meaningful when some option is enabled, return that option.
+
+ The return value can be a colon-separated list of options, if the setting
+ is only meaningful when all of these options are enabled. Options can be
+ negated by prefixing them with '!'. This is the same syntax as a
+ depends_on directive in test data.
+ """
+ #pylint: disable=too-many-return-statements
+ name = setting.name
+ if name in SUPER_SETTINGS:
+ return SUPER_SETTINGS[name]
+ if name.startswith('MBEDTLS_') and not name.endswith('_C'):
+ if name.startswith('MBEDTLS_CIPHER_PADDING_'):
+ return 'MBEDTLS_CIPHER_C:MBEDTLS_CIPHER_MODE_CBC'
+ if name.startswith('MBEDTLS_PK_PARSE_EC_'):
+ return 'MBEDTLS_PK_C:MBEDTLS_PK_HAVE_ECC_KEYS'
+ if name.startswith('MBEDTLS_SSL_TLS1_3_') or \
+ name == 'MBEDTLS_SSL_EARLY_DATA':
+ return 'MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_PROTO_TLS1_3'
+ if name.startswith('MBEDTLS_SSL_DTLS_'):
+ return 'MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_PROTO_DTLS'
+ if name.startswith('MBEDTLS_SSL_'):
+ return 'MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C'
+ for m in re.finditer(r'_', name):
+ super_name = name[:m.start()] + '_C'
+ if cfg.known(super_name):
+ return super_name
+ m = re.match(PSA_WANT_KEY_TYPE_KEY_PAIR_RE, name)
+ if m and m.group('operation') != 'BASIC':
+ return m.group('prefix') + 'BASIC'
+ return None
+
def conditions_for_option(cfg: config.Config,
setting: config.Setting
) -> Iterator[Tuple[List[str], str]]:
@@ -63,6 +120,10 @@
if name.endswith('_ALT') and not config.is_seamless_alt(name):
# We don't test alt implementations, except (most) platform alts
return
+ super_setting = find_super_option(cfg, setting)
+ if super_setting:
+ yield [super_setting], ''
+ return
yield [], ''