Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a049a4-ee9f-78e1-9d66-2cb0f9bea3e3
292 lines
11 KiB
Python
292 lines
11 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
import pytest
|
|
from sqlalchemy import func, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
|
|
|
from api.models.agent_message import AgentMessage
|
|
from api.models.fabric_graph import FabricGraphImport, FabricGraphNode
|
|
from api.models.interface_change import InterfaceChange
|
|
from api.models.managed_repo import ManagedRepo
|
|
from api.models.repository_rename import RepositorySlug
|
|
from tests.conftest import (
|
|
create_test_domain,
|
|
create_test_repo,
|
|
create_test_workplan,
|
|
)
|
|
|
|
|
|
async def _rename_in_state_hub(test_engine, repo_id: str) -> None:
|
|
factory = async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False)
|
|
async with factory() as session:
|
|
repo = await session.get(ManagedRepo, repo_id)
|
|
old = (
|
|
await session.execute(
|
|
select(RepositorySlug).where(RepositorySlug.slug == "flex-auth")
|
|
)
|
|
).scalar_one()
|
|
old.kind = "alias"
|
|
old.protected = True
|
|
repo.slug = "access-engine"
|
|
repo.name = "Access Engine"
|
|
session.add(
|
|
RepositorySlug(
|
|
repo_id=repo.id,
|
|
slug="access-engine",
|
|
kind="canonical",
|
|
protected=True,
|
|
)
|
|
)
|
|
await session.commit()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_alias_lookup_dispatch_bindings_and_external_staleness(
|
|
client, test_engine
|
|
):
|
|
domain = await create_test_domain(client)
|
|
repo = await create_test_repo(client, domain_slug=domain["slug"], slug="flex-auth")
|
|
workplan = await create_test_workplan(
|
|
client,
|
|
repo_id=repo["id"],
|
|
slug="FLEX-WP-0001",
|
|
title="Security stack migration",
|
|
)
|
|
task = await client.post(
|
|
"/tasks/",
|
|
json={
|
|
"workplan_id": workplan["id"],
|
|
"title": "Preserve identity",
|
|
"status": "todo",
|
|
"priority": "high",
|
|
},
|
|
)
|
|
assert task.status_code == 201, task.text
|
|
|
|
await _rename_in_state_hub(test_engine, repo["id"])
|
|
factory = async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False)
|
|
async with factory() as session:
|
|
change = InterfaceChange(
|
|
repo_id=repo["id"],
|
|
interface_type="rest_api",
|
|
change_type="breaking",
|
|
title="Historical consumer notice",
|
|
description="Recorded before cutover",
|
|
affected_paths=["/authorize"],
|
|
affected_repo_slugs=["flex-auth"],
|
|
status="published",
|
|
published_at=datetime.now(timezone.utc),
|
|
author="pytest",
|
|
)
|
|
import_run = FabricGraphImport(
|
|
source_repo_slug="railiance-fabric",
|
|
content_hash="a" * 64,
|
|
graph_json={},
|
|
validation_status="valid",
|
|
is_latest=True,
|
|
)
|
|
session.add_all([change, import_run])
|
|
await session.flush()
|
|
session.add(
|
|
FabricGraphNode(
|
|
import_id=import_run.id,
|
|
source_repo_slug="railiance-fabric",
|
|
graph_id="repo:flex-auth",
|
|
kind="repository",
|
|
name="Flex Auth",
|
|
repo_slug="flex-auth",
|
|
domain_slug="infotech",
|
|
lifecycle="active",
|
|
)
|
|
)
|
|
await session.commit()
|
|
|
|
old_lookup = await client.get("/repos/flex-auth")
|
|
new_lookup = await client.get("/repos/access-engine")
|
|
assert old_lookup.status_code == new_lookup.status_code == 200
|
|
assert old_lookup.json()["id"] == new_lookup.json()["id"] == repo["id"]
|
|
assert old_lookup.json()["requested_slug"] == "flex-auth"
|
|
assert old_lookup.json()["canonical_slug"] == "access-engine"
|
|
assert old_lookup.json()["slug_status"] == "alias"
|
|
assert old_lookup.json()["aliases"] == ["flex-auth"]
|
|
assert new_lookup.json()["slug_status"] == "canonical"
|
|
assert old_lookup.json()["stale_external_references"] == [
|
|
{
|
|
"owner": "railiance-fabric",
|
|
"surface": "fabric_graph_nodes",
|
|
"field": "repo_slug",
|
|
"value": "flex-auth",
|
|
"count": 1,
|
|
"status": "stale",
|
|
"handoff": "owner update or re-ingest required",
|
|
}
|
|
]
|
|
|
|
dispatch = await client.get("/repos/access-engine/dispatch")
|
|
assert dispatch.status_code == 200, dispatch.text
|
|
assert dispatch.json()["repo_slug"] == "access-engine"
|
|
assert dispatch.json()["pending_interface_changes"][0]["title"] == change.title
|
|
|
|
bound = await client.get(f"/workplans/{workplan['id']}")
|
|
assert bound.status_code == 200
|
|
assert bound.json()["id"] == workplan["id"]
|
|
assert bound.json()["repo_id"] == repo["id"]
|
|
bound_task = await client.get(f"/tasks/{task.json()['id']}")
|
|
assert bound_task.status_code == 200
|
|
assert bound_task.json()["id"] == task.json()["id"]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_message_history_is_immutable_and_old_slug_write_replays_once(
|
|
client, test_engine
|
|
):
|
|
domain = await create_test_domain(client)
|
|
repo = await create_test_repo(client, domain_slug=domain["slug"], slug="flex-auth")
|
|
await _rename_in_state_hub(test_engine, repo["id"])
|
|
factory = async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False)
|
|
async with factory() as session:
|
|
historical = AgentMessage(
|
|
from_agent="security-review",
|
|
to_agent="flex-auth",
|
|
subject="Before cutover",
|
|
body="Historical recipient must not be rewritten",
|
|
)
|
|
session.add(historical)
|
|
await session.commit()
|
|
historical_id = historical.id
|
|
|
|
history = await client.get("/messages/", params={"to_agent": "access-engine"})
|
|
assert history.status_code == 200
|
|
assert [item["id"] for item in history.json()] == [str(historical_id)]
|
|
assert history.json()[0]["to_agent"] == "flex-auth"
|
|
|
|
payload = {
|
|
"from_agent": "flex-auth",
|
|
"to_agent": "flex-auth",
|
|
"subject": "Queued during cutover",
|
|
"body": "Replay exactly once",
|
|
}
|
|
headers = {"Idempotency-Key": "repo-rename-old-slug-message"}
|
|
first = await client.post("/messages/", json=payload, headers=headers)
|
|
replay = await client.post("/messages/", json=payload, headers=headers)
|
|
assert first.status_code == replay.status_code == 201
|
|
assert first.json()["id"] == replay.json()["id"]
|
|
assert first.json()["from_agent"] == "access-engine"
|
|
assert first.json()["to_agent"] == "access-engine"
|
|
|
|
async with factory() as session:
|
|
assert await session.scalar(
|
|
select(func.count())
|
|
.select_from(AgentMessage)
|
|
.where(AgentMessage.subject == "Queued during cutover")
|
|
) == 1
|
|
unchanged = await session.get(AgentMessage, historical_id)
|
|
assert unchanged.to_agent == "flex-auth"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_alias_aware_interface_catalog_sbom_and_telemetry_reads(
|
|
client, test_engine
|
|
):
|
|
domain = await create_test_domain(client)
|
|
repo = await create_test_repo(client, domain_slug=domain["slug"], slug="flex-auth")
|
|
await _rename_in_state_hub(test_engine, repo["id"])
|
|
|
|
interface = await client.post(
|
|
"/interface-changes/",
|
|
json={
|
|
"repo_slug": "flex-auth",
|
|
"interface_type": "rest_api",
|
|
"change_type": "additive",
|
|
"title": "Canonical write",
|
|
"description": "New references use the current slug",
|
|
"affected_repo_slugs": ["flex-auth"],
|
|
},
|
|
)
|
|
assert interface.status_code == 201, interface.text
|
|
assert interface.json()["repo_slug"] == "access-engine"
|
|
assert interface.json()["affected_repo_slugs"] == ["access-engine"]
|
|
affected = await client.get(
|
|
"/interface-changes/", params={"affected_repo": "flex-auth"}
|
|
)
|
|
assert [item["id"] for item in affected.json()] == [interface.json()["id"]]
|
|
|
|
goal = await client.post(
|
|
"/repo-goals/",
|
|
json={
|
|
"repo_id": repo["id"],
|
|
"title": "Preserve authorization continuity",
|
|
"description": "Keep Net Kingdom consumers online",
|
|
},
|
|
)
|
|
assert goal.status_code == 201, goal.text
|
|
goals = await client.get("/repo-goals/", params={"repo_slug": "flex-auth"})
|
|
assert [item["id"] for item in goals.json()] == [goal.json()["id"]]
|
|
assert goals.json()[0]["repo_slug"] == "access-engine"
|
|
|
|
capability = await client.post(
|
|
"/capability-catalog/",
|
|
json={
|
|
"domain": "infotech",
|
|
"repo_slug": "flex-auth",
|
|
"capability_type": "authorization",
|
|
"title": "Policy decisions",
|
|
"description": "Net Kingdom authorization",
|
|
"keywords": ["authorize"],
|
|
},
|
|
)
|
|
assert capability.status_code == 201, capability.text
|
|
catalog = await client.get(
|
|
"/capability-catalog/", params={"repo_slug": "access-engine"}
|
|
)
|
|
assert [item["id"] for item in catalog.json()] == [capability.json()["id"]]
|
|
assert catalog.json()[0]["repo_slug"] == "access-engine"
|
|
|
|
service = await client.post(
|
|
"/services/catalog",
|
|
json={
|
|
"slug": "access-engine-api",
|
|
"name": "Access Engine API",
|
|
"hosting_type": "self_hosted",
|
|
"development_type": "first_party",
|
|
"first_party": {"repo_slug": "flex-auth", "owning_domain": "infotech"},
|
|
"self_hosted": {},
|
|
},
|
|
)
|
|
assert service.status_code == 201, service.text
|
|
services = await client.get("/services/catalog", params={"repo_slug": "flex-auth"})
|
|
assert [item["id"] for item in services.json()] == [service.json()["id"]]
|
|
|
|
ingested = await client.post(
|
|
"/sbom/ingest/",
|
|
json={
|
|
"repo_slug": "flex-auth",
|
|
"entries": [
|
|
{
|
|
"package_name": "opa",
|
|
"package_version": "1.0",
|
|
"ecosystem": "go",
|
|
}
|
|
],
|
|
},
|
|
)
|
|
assert ingested.status_code == 200, ingested.text
|
|
assert ingested.json()["repo_slug"] == "access-engine"
|
|
sbom = await client.get("/sbom/flex-auth")
|
|
assert sbom.status_code == 200
|
|
assert sbom.json()["repo_slug"] == "access-engine"
|
|
|
|
event = await client.post(
|
|
"/token-events/",
|
|
json={"repo_id": repo["id"], "tokens_in": 12, "tokens_out": 3},
|
|
)
|
|
assert event.status_code == 201, event.text
|
|
summary = await client.get(
|
|
"/token-events/by-repo/", params={"repo_slug": "flex-auth"}
|
|
)
|
|
assert summary.status_code == 200
|
|
assert len(summary.json()) == 1
|
|
assert summary.json()[0]["repo_slug"] == "access-engine"
|
|
assert summary.json()[0]["tokens_total"] == 15
|