Hive Hive
Sign in

perf(server): back flaky-alert default-branch validation with a marker MV

GitHub issue · Closed

Metadata
Source
tuist/tuist #11626
Updated
Jul 5, 2026
Domains
Testing
Details

Follow-up from the ClickHouse CPU investigation. Fixes the #1 CPU-consuming query (the flaky-alert default-branch validation gate). Independent of the OOM/memory fix (already shipped in #11623).

What

Adds test_case_runs_validated_on_branch — a ReplacingMergeTree fed by a new materialized view holding one marker row per (project_id, git_branch, test_case_id) that has ever had a successful, non-flaky run. The flaky-alert validation gate now reads that small table via a primary-key point lookup instead of scanning the raw test_case_runs table.

Why

During the ClickHouse CPU investigation, the top single query by CPU (last 10 min: 704 core-seconds) was:

SELECT DISTINCT test_case_id FROM test_case_runs
WHERE project_id = ? AND test_case_id IN (…≤2000…)
AND git_branch = <default> AND status = 'success' AND is_flaky = false

This is Tests.test_case_ids_with_successful_default_branch_run/3, called from AlertEvaluationWorker.reject_unvalidated_test_cases/2 to filter a flaky alert’s triggered test cases down to those proven on the default branch (so brand-new/PR-only tests aren’t auto-quarantined). It scanned raw test_case_runs for the whole triggered set on every evaluation.

Measured behavior on a busy project: it read millions of rows per evaluation and its per-call latency went from ~100 ms (idle cluster) to ~1.5 s under contention, making it a top contributor to the CPU-saturation feedback loop we saw (queries slowing 5–13×, concurrency 1.1→11.3).

How the fix works

  • New MV test_case_runs_validated_on_branch_mv pre-applies status = 'success' AND is_flaky = false and groups to distinct (project_id, git_branch, test_case_id), writing marker rows into the ReplacingMergeTree.
  • The validation query drops the status / is_flaky filters and reads the marker table keyed on (project_id, git_branch, test_case_id) — a bounded point lookup per test case instead of a per-test-case run scan.
  • One-time partition-chunked backfill (throttled, max_memory_usage-capped, TABLE_IS_READ_ONLY/MEMORY_LIMIT_EXCEEDED retry), matching the existing per-case aggregate migrations.

Correctness

Semantics are identical: a marker exists iff a (project, branch, test case) had a successful, non-flaky run — exactly the predicate the old raw query used. The existing tests_test.exs test (validated / PR-only / failing-on-main / flaky-success-on-main) now exercises the MV path end-to-end and asserts only the truly-validated id is returned.

Trade-off / note

This adds one more MV firing on test_case_runs inserts. It’s lightweight (distinct-key marker, no array state) and insert-path CPU was already negligible in the investigation (~34 core-s vs 704 for the query it replaces), so this is a large net CPU win. A separate follow-up will trim the unused reliability success buckets (250/500/750) added in #11623 to cut merge write-amplification.

Validation

  • mix format + Code.string_to_quoted! on changed files.
  • Existing tests_test.exs test_case_ids_with_successful_default_branch_run/3 describe block covers all four cases; it runs against ClickHouse in CI with the new MV migrated in.

How to test locally

  1. mix ecto.migrate (ingest repo) to create the MV + backfill.
  2. mix test test/tuist/tests_test.exs -o "test_case_ids_with_successful_default_branch_run" (or run the describe block) — inserts runs across branches/statuses and asserts only the default-branch success/non-flaky test case validates.
Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments

No GitHub comments yet.