feat: add visual settings and readiness gate
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
from pathlib import Path
|
||||
|
||||
from app.config import Settings
|
||||
from app.runtime_settings import (
|
||||
EncryptedSettingsStore,
|
||||
RuntimeSettingsTestResult,
|
||||
generate_secret,
|
||||
)
|
||||
|
||||
|
||||
def create_store(path: Path) -> EncryptedSettingsStore:
|
||||
settings = Settings(
|
||||
_env_file=None,
|
||||
runtime_settings_dir=str(path),
|
||||
database_url="postgresql://user:secret@postgres:5432/app",
|
||||
redis_url="redis://:secret@redis:6379/0",
|
||||
)
|
||||
return EncryptedSettingsStore(settings)
|
||||
|
||||
|
||||
def test_runtime_secrets_are_encrypted_and_never_returned(tmp_path: Path) -> None:
|
||||
store = create_store(tmp_path)
|
||||
store.update(
|
||||
{
|
||||
"s3_endpoint": "http://minio:9000",
|
||||
"s3_public_endpoint": "http://localhost:9000",
|
||||
"s3_access_key_id": "service-account",
|
||||
"s3_secret_access_key": "very-private-secret",
|
||||
}
|
||||
)
|
||||
|
||||
response = store.public_response()
|
||||
assert "s3_secret_access_key" not in response.values
|
||||
assert response.configured["s3_secret_access_key"] is True
|
||||
assert b"very-private-secret" not in store.data_path.read_bytes()
|
||||
|
||||
|
||||
def test_readiness_requires_configuration_and_successful_tests(tmp_path: Path) -> None:
|
||||
store = create_store(tmp_path)
|
||||
store.update(
|
||||
{
|
||||
"s3_endpoint": "http://minio:9000",
|
||||
"s3_public_endpoint": "http://localhost:9000",
|
||||
"s3_access_key_id": "access",
|
||||
"s3_secret_access_key": "secret",
|
||||
"ai_provider": "lingke",
|
||||
"ai_base_url": "https://example.com/v1",
|
||||
"ai_api_key": "api-secret",
|
||||
"orchestrator_model": "planner",
|
||||
"vision_model": "vision",
|
||||
"image_model": "gpt-image-2",
|
||||
}
|
||||
)
|
||||
assert store.public_response().readiness.ready is False
|
||||
|
||||
for target in ("infrastructure", "storage", "ai_models"):
|
||||
store.record_test(RuntimeSettingsTestResult(target=target, ok=True, message="ok"))
|
||||
|
||||
assert store.public_response().readiness.ready is True
|
||||
|
||||
store.update({"image_model": "another-image-model"})
|
||||
assert store.public_response().readiness.ready is False
|
||||
assert store.public_response().tests.get("ai_models") is None
|
||||
|
||||
|
||||
def test_secret_generators_use_expected_lengths() -> None:
|
||||
assert len(generate_secret("hex24")) == 48
|
||||
assert len(generate_secret("hex32")) == 64
|
||||
assert len(generate_secret("base64_32")) == 44
|
||||
Reference in New Issue
Block a user