fix(perf): bound truth-chain quality reads
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 4m29s
CD Pipeline / build-and-deploy (push) Successful in 15m43s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 18s
CD Pipeline / post-deploy-checks (push) Successful in 11m37s
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 4m29s
CD Pipeline / build-and-deploy (push) Successful in 15m43s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 18s
CD Pipeline / post-deploy-checks (push) Successful in 11m37s
This commit is contained in:
@@ -3,12 +3,15 @@ from pathlib import Path
|
||||
from src.services.platform_operator_service import _provider_event_id_prefix_bounds
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
REPO_ROOT = ROOT.parents[1]
|
||||
MIGRATION = "awooop_conversation_event_hot_path_indexes_2026-07-01.sql"
|
||||
ROLLBACK = "awooop_conversation_event_hot_path_indexes_2026-07-01_down.sql"
|
||||
CONTENT_PREVIEW_MIGRATION = "awooop_conversation_event_content_preview_trgm_2026-07-01.sql"
|
||||
CONTENT_PREVIEW_ROLLBACK = "awooop_conversation_event_content_preview_trgm_2026-07-01_down.sql"
|
||||
AUTOMATION_LOG_MIGRATION = "automation_operation_log_truth_chain_hot_path_indexes_2026-07-01.sql"
|
||||
AUTOMATION_LOG_ROLLBACK = "automation_operation_log_truth_chain_hot_path_indexes_2026-07-01_down.sql"
|
||||
STRUCTURED_REFERENCE_MIGRATION = "awooop_truth_chain_structured_reference_indexes_2026-07-17.sql"
|
||||
STRUCTURED_REFERENCE_ROLLBACK = "awooop_truth_chain_structured_reference_indexes_2026-07-17_down.sql"
|
||||
|
||||
|
||||
def _read(path: str) -> str:
|
||||
@@ -39,6 +42,14 @@ def _automation_log_rollback_sql() -> str:
|
||||
return _read(f"migrations/{AUTOMATION_LOG_ROLLBACK}")
|
||||
|
||||
|
||||
def _structured_reference_migration_sql() -> str:
|
||||
return _read(f"migrations/{STRUCTURED_REFERENCE_MIGRATION}")
|
||||
|
||||
|
||||
def _structured_reference_rollback_sql() -> str:
|
||||
return _read(f"migrations/{STRUCTURED_REFERENCE_ROLLBACK}")
|
||||
|
||||
|
||||
def test_hot_path_indexes_are_concurrent_and_transactionless() -> None:
|
||||
sql = _migration_sql()
|
||||
|
||||
@@ -173,7 +184,7 @@ def test_automation_operation_log_indexes_bound_truth_chain_lookups() -> None:
|
||||
assert "incident_id::text" in truth_chain_source
|
||||
assert "coalesce(input::text, '') LIKE" in truth_chain_source
|
||||
assert "coalesce(output::text, '') LIKE" in truth_chain_source
|
||||
assert "coalesce(array_to_string(tags, ','), '') LIKE" in truth_chain_source
|
||||
assert "tags && CAST(:incident_tags AS text[])" in truth_chain_source
|
||||
|
||||
for index_name in (
|
||||
"idx_automation_operation_log_output_text_trgm",
|
||||
@@ -182,3 +193,63 @@ def test_automation_operation_log_indexes_bound_truth_chain_lookups() -> None:
|
||||
):
|
||||
assert f"DROP INDEX CONCURRENTLY IF EXISTS {index_name};" in rollback
|
||||
assert "DROP EXTENSION" not in rollback
|
||||
|
||||
|
||||
def test_structured_truth_chain_indexes_match_split_reference_branches() -> None:
|
||||
sql = _structured_reference_migration_sql()
|
||||
source = _read("src/services/awooop_truth_chain_service.py")
|
||||
|
||||
assert "BEGIN;" not in sql
|
||||
assert "COMMIT;" not in sql
|
||||
assert sql.count("CREATE INDEX CONCURRENTLY IF NOT EXISTS") == 12
|
||||
assert "idx_aol_incident_text_created" in sql
|
||||
assert "idx_aol_input_incident_created" in sql
|
||||
assert "idx_aol_output_incident_created" in sql
|
||||
assert "idx_aol_input_source_incidents_gin" in sql
|
||||
assert "idx_aol_output_source_incidents_gin" in sql
|
||||
assert "idx_outbound_source_incident_ids_gin" in sql
|
||||
assert "idx_outbound_source_code_refs_gin" in sql
|
||||
assert "idx_outbound_callback_incident_recent" in sql
|
||||
assert "idx_outbound_alert_incident_recent" in sql
|
||||
assert "idx_outbound_source_incident_recent" in sql
|
||||
assert "idx_outbound_top_incident_recent" in sql
|
||||
assert "idx_outbound_project_content_preview_trgm" in sql
|
||||
|
||||
assert "_fetch_automation_operation_rows_for_incidents" in source
|
||||
assert "_fetch_outbound_rows_for_incidents" in source
|
||||
assert "source_envelope::text" not in source
|
||||
assert "FROM unnest(CAST(:incident_ids AS text[]))" not in source
|
||||
|
||||
|
||||
def test_structured_truth_chain_rollback_only_drops_owned_indexes() -> None:
|
||||
rollback = _structured_reference_rollback_sql()
|
||||
|
||||
assert "BEGIN;" not in rollback
|
||||
assert "COMMIT;" not in rollback
|
||||
assert rollback.count("DROP INDEX CONCURRENTLY IF EXISTS") == 12
|
||||
assert "DROP EXTENSION" not in rollback
|
||||
for index_name in (
|
||||
"idx_outbound_project_content_preview_trgm",
|
||||
"idx_outbound_top_incident_recent",
|
||||
"idx_outbound_source_incident_recent",
|
||||
"idx_outbound_alert_incident_recent",
|
||||
"idx_outbound_callback_incident_recent",
|
||||
"idx_outbound_source_code_refs_gin",
|
||||
"idx_outbound_source_incident_ids_gin",
|
||||
"idx_aol_output_source_incidents_gin",
|
||||
"idx_aol_input_source_incidents_gin",
|
||||
"idx_aol_output_incident_created",
|
||||
"idx_aol_input_incident_created",
|
||||
"idx_aol_incident_text_created",
|
||||
):
|
||||
assert f"DROP INDEX CONCURRENTLY IF EXISTS {index_name};" in rollback
|
||||
|
||||
|
||||
def test_migration_workflow_keeps_concurrent_indexes_outside_transactions() -> None:
|
||||
workflow = (REPO_ROOT / ".gitea/workflows/run-migration.yml").read_text()
|
||||
|
||||
assert "migration_mode=transactionless_concurrently" in workflow
|
||||
assert "CONCURRENTLY migration must not contain an explicit transaction" in workflow
|
||||
assert "psql \"$url\" -v ON_ERROR_STOP=1 -f \"$file\"" in workflow
|
||||
assert "migration_mode=single_transaction" in workflow
|
||||
assert "--single-transaction -f \"$file\"" in workflow
|
||||
|
||||
@@ -11,6 +11,7 @@ from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
|
||||
import src.services.awooop_truth_chain_service as truth_chain_service
|
||||
from src.core.config import settings
|
||||
from src.jobs.awooop_ansible_candidate_backfill_job import (
|
||||
enqueue_ai_decision_ansible_candidate,
|
||||
@@ -150,14 +151,90 @@ def test_quality_summary_includes_recent_ansible_operation_incidents() -> None:
|
||||
|
||||
def test_quality_summary_uses_batched_truth_chain_inputs() -> None:
|
||||
source = inspect.getsource(fetch_automation_quality_summary)
|
||||
outbound_helper = inspect.getsource(
|
||||
truth_chain_service._fetch_outbound_rows_for_incidents
|
||||
)
|
||||
|
||||
assert "fetch_truth_chain(" not in source
|
||||
assert "approval_records" in source
|
||||
assert "incident_evidence" in source
|
||||
assert "awooop_outbound_message" in source
|
||||
assert "_fetch_outbound_rows_for_incidents" in source
|
||||
assert "awooop_outbound_message" in outbound_helper
|
||||
assert "_build_summary_quality_records" in source
|
||||
|
||||
|
||||
def test_quality_summary_bounds_database_work_and_uses_structured_helpers() -> None:
|
||||
source = inspect.getsource(fetch_automation_quality_summary)
|
||||
|
||||
assert "_QUALITY_SUMMARY_STATEMENT_TIMEOUT_MS" in source
|
||||
assert "_QUALITY_SUMMARY_MAX_BATCH_ROWS" in source
|
||||
assert "_fetch_automation_operation_rows_for_incidents" in source
|
||||
assert "_fetch_outbound_rows_for_incidents" in source
|
||||
assert "FROM unnest(CAST(:incident_ids AS text[]))" not in source
|
||||
assert "source_envelope::text" not in source
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_batch_operation_lookup_splits_indexable_reference_branches(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
calls: list[tuple[str, dict[str, object]]] = []
|
||||
|
||||
async def fake_fetch_all(
|
||||
_db: object, sql: str, params: dict[str, object]
|
||||
) -> list[dict[str, object]]:
|
||||
calls.append((sql, params))
|
||||
return []
|
||||
|
||||
monkeypatch.setattr(truth_chain_service, "_fetch_all", fake_fetch_all)
|
||||
cutoff = datetime.now(UTC) - timedelta(hours=24)
|
||||
rows = await truth_chain_service._fetch_automation_operation_rows_for_incidents(
|
||||
object(),
|
||||
incident_ids=["INC-20260717-AAAAAA", "INC-20260717-BBBBBB"],
|
||||
limit=200,
|
||||
cutoff=cutoff,
|
||||
)
|
||||
|
||||
assert rows == []
|
||||
assert len(calls) == 6
|
||||
assert all("FROM automation_operation_log" in sql for sql, _ in calls)
|
||||
assert all("created_at >= :cutoff" in sql for sql, _ in calls)
|
||||
assert all(params["cutoff"] == cutoff for _, params in calls)
|
||||
assert all("FROM unnest" not in sql for sql, _ in calls)
|
||||
assert all("LIKE '%' ||" not in sql for sql, _ in calls)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_batch_outbound_lookup_never_casts_full_envelope_to_text(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
calls: list[tuple[str, dict[str, object]]] = []
|
||||
|
||||
async def fake_fetch_all(
|
||||
_db: object, sql: str, params: dict[str, object]
|
||||
) -> list[dict[str, object]]:
|
||||
calls.append((sql, params))
|
||||
return []
|
||||
|
||||
monkeypatch.setattr(truth_chain_service, "_fetch_all", fake_fetch_all)
|
||||
cutoff = datetime.now(UTC) - timedelta(hours=24)
|
||||
rows = await truth_chain_service._fetch_outbound_rows_for_incidents(
|
||||
object(),
|
||||
project_id="awoooi",
|
||||
incident_ids=["INC-20260717-AAAAAA"],
|
||||
limit=100,
|
||||
cutoff=cutoff,
|
||||
)
|
||||
|
||||
assert rows == []
|
||||
assert len(calls) == 6
|
||||
assert all("FROM awooop_outbound_message" in sql for sql, _ in calls)
|
||||
assert all("queued_at >= :cutoff" in sql for sql, _ in calls)
|
||||
assert all("source_envelope::text" not in sql for sql, _ in calls)
|
||||
assert all("FROM unnest" not in sql for sql, _ in calls)
|
||||
assert all("content_preview ILIKE" not in sql for sql, _ in calls)
|
||||
|
||||
|
||||
def test_ansible_audit_keeps_external_incident_id_in_json_not_bigint_column() -> None:
|
||||
decision_source = inspect.getsource(record_ansible_decision_audit)
|
||||
terminal_source = verified_ansible_candidate_terminal_sql("candidate")
|
||||
@@ -195,8 +272,13 @@ def test_ansible_transport_cooldown_uses_asyncpg_safe_interval_parameter() -> No
|
||||
def test_fetch_truth_chain_returns_inbound_redacted_envelope_fields() -> None:
|
||||
source = inspect.getsource(fetch_truth_chain)
|
||||
helper_source = inspect.getsource(_fetch_inbound_conversation_event_rows)
|
||||
outbound_helper = inspect.getsource(
|
||||
truth_chain_service._fetch_outbound_rows_for_incidents
|
||||
)
|
||||
|
||||
assert "content_redacted" in source
|
||||
assert "_fetch_outbound_rows_for_incidents" in source
|
||||
assert "content_redacted" in helper_source
|
||||
assert "content_redacted" in outbound_helper
|
||||
assert "source_envelope" in helper_source
|
||||
assert "source_refs,event_ids" in helper_source
|
||||
assert "source_refs,incident_ids" in helper_source
|
||||
|
||||
Reference in New Issue
Block a user