"""Runtime-root env-var fail-fast — AZ-263 AC-8 (updated by AZ-270 to pass a Config). AZ-270 swapped ``compose_root()`` to ``compose_root(config: Config)``; the env-var fail-fast still happens inside ``compose_root`` before any factory construction, so this AC-8 contract is intact. """ import pytest from gps_denied_onboard.config import Config from gps_denied_onboard.runtime_root import ConfigurationError, compose_root def test_compose_root_fails_fast_on_missing_required(monkeypatch: pytest.MonkeyPatch) -> None: # Arrange for var in ( "GPS_DENIED_FC_PROFILE", "GPS_DENIED_TIER", "DB_URL", "CAMERA_CALIBRATION_PATH", "LOG_LEVEL", "LOG_SINK", "INFERENCE_BACKEND", "FDR_PATH", "TILE_CACHE_PATH", "MAVLINK_SIGNING_KEY", ): monkeypatch.delenv(var, raising=False) # Act / Assert with pytest.raises(ConfigurationError) as excinfo: compose_root(Config()) assert "Missing required environment variable" in str(excinfo.value) def test_compose_root_names_the_first_missing_var(monkeypatch: pytest.MonkeyPatch) -> None: # Arrange for var in ( "GPS_DENIED_FC_PROFILE", "GPS_DENIED_TIER", "DB_URL", "CAMERA_CALIBRATION_PATH", "LOG_LEVEL", "LOG_SINK", "INFERENCE_BACKEND", "FDR_PATH", "TILE_CACHE_PATH", "MAVLINK_SIGNING_KEY", ): monkeypatch.delenv(var, raising=False) # Act with pytest.raises(ConfigurationError) as excinfo: compose_root(Config()) # Assert msg = str(excinfo.value) assert "GPS_DENIED_FC_PROFILE" in msg