unittest_config_checks debugging facility

Set the environment variable `UNITTEST_CONFIG_CHECKS_DEBUG` to
dump the preprocessor output to a file if a test case fails.

Signed-off-by: Gilles Peskine <[email protected]>
This commit is contained in:
Gilles Peskine
2025-07-22 23:37:01 +02:00
parent a51bd7b729
commit bc7bc36993
@@ -33,6 +33,24 @@ class TestConfigChecks(unittest.TestCase):
# to say.
maxDiff = 9999
def setUp(self) -> None:
self.cpp_output = None #type: Optional[str]
def tearDown(self) -> None:
"""Log the preprocessor output to a file, if available and desired.
This is intended for debugging. It only happens if the environment
variable UNITTEST_CONFIG_CHECKS_DEBUG is non-empty.
"""
if os.getenv('UNITTEST_CONFIG_CHECKS_DEBUG'):
# We set self.cpp_output to the preprocessor output before
# asserting, and set it to None if all the assertions pass.
if self.cpp_output is not None:
basename = os.path.splitext(os.path.basename(sys.argv[0]))[0]
filename = f'{basename}.{self._testMethodName}.out.txt'
with open(filename, 'w') as out:
out.write(self.cpp_output)
def user_config_file_name(self, variant: str) -> str:
"""Construct a unique temporary file name for a user config header."""
name = os.path.splitext(os.path.basename(sys.argv[0]))[0]
@@ -69,6 +87,8 @@ class TestConfigChecks(unittest.TestCase):
stdout and stderr.
"""
cmd = ['cpp']
if os.getenv('UNITTEST_CONFIG_CHECKS_DEBUG'):
cmd += ['-dD']
if crypto_user_config_file is not None:
cmd.append(f'-DTF_PSA_CRYPTO_USER_CONFIG_FILE="{crypto_user_config_file}"')
if mbedtls_user_config_file is not None:
@@ -137,8 +157,10 @@ class TestConfigChecks(unittest.TestCase):
extra_options=extra_options)
# Assert the error text before the status. That way, if it fails,
# we see the unexpected error messages in the test log.
self.cpp_output = cp.stdout
self.assertEqual(cp.stderr, '')
self.assertEqual(cp.returncode, 0)
self.cpp_output = None
def bad_case(self,
crypto_user_config: Optional[str],
@@ -154,12 +176,14 @@ class TestConfigChecks(unittest.TestCase):
"""
cp = self.run_with_config(crypto_user_config, mbedtls_user_config,
extra_options=extra_options)
self.cpp_output = cp.stdout
if error is not None:
# Assert the error text before the status. That way, if it fails,
# we see the unexpected error messages in the test log.
self.assertRegex(cp.stderr, error)
self.assertGreater(cp.returncode, 0)
self.assertLess(cp.returncode, 126)
self.cpp_output = None
# Nominal case, run first
def test_01_nominal(self) -> None: