fix: align release gate with AI Redis service
This commit is contained in:
@@ -766,7 +766,7 @@ def validate_compose_gate_report(
|
||||
if not isinstance(expected_digest, str) or not SHA256_RE.fullmatch(expected_digest):
|
||||
raise ReleaseValidationError(f"source manifest lacks Compose input: {expected_path}")
|
||||
validated_inputs.append({"path": expected_path, "sha256": expected_digest})
|
||||
if report["application_service_count"] != 9 or report["production_service_count"] != 16:
|
||||
if report["application_service_count"] != 9 or report["production_service_count"] != 17:
|
||||
raise ReleaseValidationError("production Compose gate service inventory drift")
|
||||
|
||||
applications_without_web = [
|
||||
@@ -781,10 +781,10 @@ def validate_compose_gate_report(
|
||||
]
|
||||
expected_cases = []
|
||||
for profile_name, profiles, service_count, includes_web in (
|
||||
("default", [], 13, False),
|
||||
("backend-hosted-web", ["backend-hosted-web"], 14, True),
|
||||
("ops", ["ops"], 15, False),
|
||||
("backend-hosted-web+ops", ["backend-hosted-web", "ops"], 16, True),
|
||||
("default", [], 14, False),
|
||||
("backend-hosted-web", ["backend-hosted-web"], 15, True),
|
||||
("ops", ["ops"], 16, False),
|
||||
("backend-hosted-web+ops", ["backend-hosted-web", "ops"], 17, True),
|
||||
):
|
||||
applications = applications_without_web + (["contract-web"] if includes_web else [])
|
||||
for mode in ("online", "offline"):
|
||||
|
||||
@@ -102,6 +102,7 @@ TRUSTED_PRODUCTION_SERVICES = (
|
||||
"postgres",
|
||||
"postgres-init-databases",
|
||||
"redis",
|
||||
"ai-redis",
|
||||
"minio",
|
||||
"contract-api-migrate",
|
||||
"contract-api",
|
||||
|
||||
@@ -528,12 +528,10 @@ def _compose_gate_report(source: dict[str, Any]) -> tuple[bytes, dict[str, Any]]
|
||||
]
|
||||
cases = []
|
||||
case_index = 0
|
||||
for profile_name, profiles, service_count, includes_web in (
|
||||
("default", [], 13, False),
|
||||
("backend-hosted-web", ["backend-hosted-web"], 14, True),
|
||||
("ops", ["ops"], 15, False),
|
||||
("backend-hosted-web+ops", ["backend-hosted-web", "ops"], 16, True),
|
||||
):
|
||||
for profile_name, profile_tuple in builder.TRUSTED_PROFILE_CASES:
|
||||
profiles = list(profile_tuple)
|
||||
service_count = len(builder._required_compose_services(profile_tuple))
|
||||
includes_web = "backend-hosted-web" in profile_tuple
|
||||
applications = applications_without_web + (["contract-web"] if includes_web else [])
|
||||
for mode in ("online", "offline"):
|
||||
case_index += 1
|
||||
@@ -555,8 +553,8 @@ def _compose_gate_report(source: dict[str, Any]) -> tuple[bytes, dict[str, Any]]
|
||||
{"path": path, "sha256": source_records[path]["sha256"]}
|
||||
for path in common.COMPOSE_GATE_POLICY["compose_inputs"]
|
||||
],
|
||||
"application_service_count": 9,
|
||||
"production_service_count": 16,
|
||||
"application_service_count": len(builder.TRUSTED_APPLICATION_SERVICE_IMAGE_ENV),
|
||||
"production_service_count": len(builder.TRUSTED_PRODUCTION_SERVICES),
|
||||
"cases": cases,
|
||||
}
|
||||
return env_bytes, report
|
||||
@@ -583,6 +581,46 @@ def test_synthetic_compose_gate_env_covers_required_interpolation() -> None:
|
||||
assert values["BACKEND_TLS_TRUSTED_CA_FILE"] == "/synthetic/tls/trusted-ca.pem"
|
||||
|
||||
|
||||
def _compose_service_blocks(relative_path: str) -> dict[str, list[str]]:
|
||||
blocks: dict[str, list[str]] = {}
|
||||
current_service: str | None = None
|
||||
in_services = False
|
||||
for line in (REPO_ROOT / relative_path).read_text(encoding="utf-8").splitlines():
|
||||
if not in_services:
|
||||
in_services = line == "services:"
|
||||
continue
|
||||
if line and not line[0].isspace():
|
||||
break
|
||||
match = re.fullmatch(r" ([a-z0-9][a-z0-9-]*):\s*", line)
|
||||
if match:
|
||||
current_service = match.group(1)
|
||||
blocks[current_service] = []
|
||||
elif current_service is not None:
|
||||
blocks[current_service].append(line)
|
||||
return blocks
|
||||
|
||||
|
||||
def test_compose_gate_inventory_matches_candidate_compose_sources() -> None:
|
||||
compose_services: set[str] = set()
|
||||
for relative_path in common.COMPOSE_GATE_POLICY["compose_inputs"]:
|
||||
compose_services.update(_compose_service_blocks(relative_path))
|
||||
assert compose_services == set(builder.TRUSTED_PRODUCTION_SERVICES)
|
||||
|
||||
production_blocks = _compose_service_blocks(
|
||||
"yuqei-infra/compose/docker-compose.production.yml"
|
||||
)
|
||||
actual_profiles: dict[str, str] = {}
|
||||
for service_name, lines in production_blocks.items():
|
||||
profile_lines = [line for line in lines if line.strip().startswith("profiles:")]
|
||||
if not profile_lines:
|
||||
continue
|
||||
assert len(profile_lines) == 1
|
||||
profiles = re.findall(r'"([a-z0-9][a-z0-9-]*)"', profile_lines[0])
|
||||
assert len(profiles) == 1
|
||||
actual_profiles[service_name] = profiles[0]
|
||||
assert actual_profiles == dict(builder.TRUSTED_PROFILE_ONLY_SERVICES)
|
||||
|
||||
|
||||
def _compose_model(
|
||||
*, mode: str, profile_name: str, profiles: tuple[str, ...]
|
||||
) -> dict[str, Any]:
|
||||
|
||||
Reference in New Issue
Block a user