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.
3.5 KiB
3.5 KiB
#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
- Dashboard fixture: 2 charts, one scalar and one bounded table; 2 filter values; 2 viewport values; 2 repeated identical coordinates.
- Environment fixtures: DEV pool=20, PREPROD pool=20, PROD pool=10; one environment pool=5 edge.
- Superset response fixtures:
is_cached=true, ordinary source (is_cached=null),force=true,cache_timeout=-1, absent/inconsistent metadata, error taxonomy. - 041 fixtures: shared dataset with 3 dependent dashboards and pinned fingerprint.
Verification Sequence
- Profile and matrix: validate profile → effective cap, exact request estimate, deterministic matrix; shuffled axes yield same bytes; over-cap uses seeded sample.
- 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.
- Worker timing: inject queue delay, semaphore delay, and upstream delay; assert
queue_wait_ms,resource_wait_ms,upstream_latency_msare disjoint and upstream p99 excludes waits. - Cache mapping: assert body fixtures map hit/miss/bypassed/disabled/unknown exactly; latency changes alone never change state.
- Bounded processing: 10,000-row response → digest over raw bytes, row count, sample ≤100 rows/256KiB; full 037 normalization is not called.
- Stop/drain: stop run → no new queue items, in-flight drains, status
stopped_by_user, partial executions queryable. - Circuit breaker: after ≥20 completed samples, error rate >25% or upstream p99 > configured threshold → intake closes, drain starts,
circuit_breaker_abortwith trigger details. - PROD gate: unapproved/changed profile or 041 fingerprint dispatches zero requests; approved hash starts exactly one TaskManager task.
- Baseline isolation: catalog hash before/after load run identical; no candidate/source hash/immutability mutation.
- Recovery and comparison: disconnect/reconnect by
load_run_idrestores 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