Files
busya a1b20bf2cf feat(040): wire RunnerPool into run_load_run — real load execution (T075-T079)
Close the 040 MVP runtime gap: run_load_run previously only slept through
RAMP->STEADY->DRAIN->COMPLETED with zero Superset requests. Now it actually
executes load-test chart queries through the 037 client.

- executor.py: 037-native adapter (execute_superset_chart via
  execute_dashboard_query_envelope; build_execution_items with stable ids)
- persistence.py: write_load_executions batched LoadExecution persistence
- plugin load_testing.py: run_load_run -> _resolve_execution_scope ->
  _run_bounded_pool (RunnerPool + shared client_registry.get_semaphore +
  CircuitBreaker -> circuit_breaker_abort)
- test_executor_runtime.py: 5 tests proving executor delegation, item
  determinism, real-execution persistence (2 items -> 2 LoadExecution rows,
  run -> COMPLETED), and lifecycle-only degradation on missing env

Verification: tests/services/load_testing/ = 76 passed, ruff clean.
2026-08-07 13:37:46 +07:00

3.5 KiB
Raw Permalink Blame History

#region DashboardLoadTesting.Quickstart [C:2] [TYPE ADR] [SEMANTICS quickstart,load-testing,verification] @BRIEF Falsifiable verification sequence for 040 without implementing application code.

Feature: 040-dashboard-load-testing | Date: 2026-07-22

Fixture Setup

  1. Dashboard fixture: 2 charts, one scalar and one bounded table; 2 filter values; 2 viewport values; 2 repeated identical coordinates.
  2. Environment fixtures: DEV pool=20, PREPROD pool=20, PROD pool=10; one environment pool=5 edge.
  3. Superset response fixtures: is_cached=true, ordinary source (is_cached=null), force=true, cache_timeout=-1, absent/inconsistent metadata, error taxonomy.
  4. 041 fixtures: shared dataset with 3 dependent dashboards and pinned fingerprint.

Verification Sequence

  1. Profile and matrix: validate profile → effective cap, exact request estimate, deterministic matrix; shuffled axes yield same bytes; over-cap uses seeded sample.
  2. Capacity: DEV/PREPROD default cap=10, PROD=5, ceiling=25, pool reserve=5; pool=5 rejects load slot; two active runs share env capacity and total workers never exceed cap.
  3. Worker timing: inject queue delay, semaphore delay, and upstream delay; assert queue_wait_ms, resource_wait_ms, upstream_latency_ms are disjoint and upstream p99 excludes waits.
  4. Cache mapping: assert body fixtures map hit/miss/bypassed/disabled/unknown exactly; latency changes alone never change state.
  5. Bounded processing: 10,000-row response → digest over raw bytes, row count, sample ≤100 rows/256KiB; full 037 normalization is not called.
  6. Stop/drain: stop run → no new queue items, in-flight drains, status stopped_by_user, partial executions queryable.
  7. Circuit breaker: after ≥20 completed samples, error rate >25% or upstream p99 > configured threshold → intake closes, drain starts, circuit_breaker_abort with trigger details.
  8. PROD gate: unapproved/changed profile or 041 fingerprint dispatches zero requests; approved hash starts exactly one TaskManager task.
  9. Baseline isolation: catalog hash before/after load run identical; no candidate/source hash/immutability mutation.
  10. Recovery and comparison: disconnect/reconnect by load_run_id restores workers/queue/metrics; partial run compares against complete prior run.

Commands (implementation phase only)

cd backend && source .venv/bin/activate && python -m pytest tests/services/load_testing/ -v
cd backend && python -m ruff check .
cd frontend && npm run test
cd frontend && npm run lint

Runtime Closure Status (2026-08-07)

Ранее шаги 3–7 не выполнялись против реального Superset-потока (run_load_run не вызывал RunnerPool). После closure-задач T075–T079:

  • ✅ run_load_run гоняет execution items через RunnerPool с 037-native executor (services/load_testing/executor.py).
  • ✅ Shared per-env semaphore через client_registry.get_semaphore (один лимит для ordinary + load).
  • ✅ LoadExecution персистятся (реальные latency/cache/consistency), breaker → circuit_breaker_abort.
  • ✅ Verified: tests/services/load_testing/test_executor_runtime.py (5 тестов) + полный tests/services/load_testing/ (76 passed).

Проверка на живом Superset (или фикстурном 037-executor'е) остаётся обязательной для объявления operational — см. exit gate 6.

#endregion DashboardLoadTesting.Quickstart