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

This commit is contained in:
Your Name
2026-07-17 04:59:22 +08:00
parent 937134aaa1
commit 0382c120e9
6 changed files with 557 additions and 201 deletions

View File

@@ -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

View File

@@ -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