From e409d280ce48dc52de6ca65dade36df2cc3e9d4e Mon Sep 17 00:00:00 2001 From: InstanceBrick <94509043+InstanceBrick@users.noreply.github.com> Date: Fri, 16 Oct 2026 15:49:54 -0400 Subject: [PATCH] Validate native CMake build values across cache option types --- packaging/steam-frame/verify_image.sh | 26 ++++++++++---- tests/steam_frame_image_policy_test.py | 48 ++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 tests/steam_frame_image_policy_test.py diff --git a/packaging/steam-frame/verify_image.sh b/packaging/steam-frame/verify_image.sh index 64fa9dc..8faa419 100644 --- a/packaging/steam-frame/verify_image.sh +++ b/packaging/steam-frame/verify_image.sh @@ -60,15 +60,29 @@ for path in license_files: if not path.is_file() or not path.stat().st_size: raise SystemExit(f'Missing source license notices: {path}') +def verify_native_cmake_settings(cache_text): + settings = {} + for line in cache_text.splitlines(): + if not line or line.startswith(('#', '//')): + continue + declaration, separator, value = line.partition('=') + name, type_separator, cache_type = declaration.partition(':') + if separator and type_separator and cache_type: + settings[name] = value + # VR is a STRING option (AUTO/ON/OFF), while the other flags are BOOL. + # The configured value determines the build policy, not the cache type. + required = {'MOCKTAIL_ENABLE_VR': 'ON', + 'MOCKTAIL_ENABLE_FSR3': 'OFF', + 'MOCKTAIL_VR_DIAGNOSTICS': 'OFF'} + for name, expected in required.items(): + if settings.get(name) != expected: + raise SystemExit(f'Unexpected build setting: {name}={settings.get(name)!r}; expected {expected}') + + cache = Path('/work/build-frame-arm64/CMakeCache.txt') build_policy = 'source-build-cache' if cache.exists(): - settings = cache.read_text().splitlines() - for setting in ('MOCKTAIL_ENABLE_VR:BOOL=ON', - 'MOCKTAIL_ENABLE_FSR3:BOOL=OFF', - 'MOCKTAIL_VR_DIAGNOSTICS:BOOL=OFF'): - if setting not in settings: - raise SystemExit(f'Unexpected build setting: {setting}') + verify_native_cmake_settings(cache.read_text()) else: # Source-audited release images may omit their disposable compiler cache. provenance = json.loads((metadata / 'steam-frame-source.json').read_text()) diff --git a/tests/steam_frame_image_policy_test.py b/tests/steam_frame_image_policy_test.py new file mode 100644 index 0000000..1d8ce62 --- /dev/null +++ b/tests/steam_frame_image_policy_test.py @@ -0,0 +1,48 @@ +import ast +from pathlib import Path +import unittest + +script = Path(__file__).resolve().parents[1] / 'packaging/steam-frame/verify_image.sh' +embedded = script.read_text().split("<<'PY'\n", 1)[1].rsplit("\nPY", 1)[0] +module = ast.parse(embedded) +functions = [node for node in module.body if isinstance(node, ast.FunctionDef) + and node.name == 'verify_native_cmake_settings'] +scope = {} +exec(compile(ast.Module(body=functions, type_ignores=[]), str(script), 'exec'), scope) +verify = scope['verify_native_cmake_settings'] + + +class NativeImagePolicy(unittest.TestCase): + def test_accepts_real_cmake_string_vr_and_boolean_flags(self): + verify("// Native Frame build\nMOCKTAIL_ENABLE_VR:STRING=ON\n" + "MOCKTAIL_ENABLE_FSR3:BOOL=OFF\nMOCKTAIL_VR_DIAGNOSTICS:BOOL=OFF\n") + + def test_accepts_equivalent_configured_values_across_cache_types(self): + verify("MOCKTAIL_ENABLE_VR:BOOL=ON\nMOCKTAIL_ENABLE_FSR3:UNINITIALIZED=OFF\n" + "MOCKTAIL_VR_DIAGNOSTICS:BOOL=OFF\n") + + def test_rejects_incorrect_build_values(self): + settings = {'MOCKTAIL_ENABLE_VR': 'ON', 'MOCKTAIL_ENABLE_FSR3': 'OFF', + 'MOCKTAIL_VR_DIAGNOSTICS': 'OFF'} + for name, invalid in [('MOCKTAIL_ENABLE_VR', 'OFF'), + ('MOCKTAIL_ENABLE_VR', 'AUTO'), + ('MOCKTAIL_ENABLE_FSR3', 'ON'), + ('MOCKTAIL_VR_DIAGNOSTICS', 'ON')]: + with self.subTest(name=name, invalid=invalid): + changed = dict(settings, **{name: invalid}) + with self.assertRaises(SystemExit): + verify('\n'.join(f'{key}:STRING={value}' for key, value in changed.items())) + + def test_rejects_missing_or_commented_out_build_settings(self): + settings = {'MOCKTAIL_ENABLE_VR': 'ON', 'MOCKTAIL_ENABLE_FSR3': 'OFF', + 'MOCKTAIL_VR_DIAGNOSTICS': 'OFF'} + for omitted in settings: + with self.subTest(omitted=omitted): + lines = [f'{key}:STRING={value}' for key, value in settings.items() if key != omitted] + lines.append(f'//{omitted}:STRING={settings[omitted]}') + with self.assertRaises(SystemExit): + verify('\n'.join(lines)) + + +if __name__ == '__main__': + unittest.main()