Planes de Prueba — patrones de carga preconfigurados¶
Read in your language: English · Português · Español
Estado del alcance (post-congelación de alcance 2026-05-10) — Ver ARCHITECTURE.md para los 37 MÓDULOs canónicos + 7 Test Kinds + arquitectura de safety DOM/CPOS/PIE-PA. ADRs 0014, 0019-0025 cubren adiciones post-Freeze.
Status: 15 planes entregados. Catálogo en
platform/test-plans/catalog.yaml.
Por qué Planes de Prueba¶
Cada ejecución de prueba en este cluster necesita tres cosas para ser comparable entre engagements:
- Un inicio y fin definidos — duración en minutos / horas, no "hasta que el ingeniero diga basta"
- Una metodología de ramp-up — los agentes no llegan a carga máxima al instante; hacen ramp a lo largo de una línea de tiempo definida para que el NGFW tenga ocasión de calentarse
- Un identifier compartido — dos ingenieros en geografías distintas pueden decir "ejecuté
CAP-FIND-KNEE-30Mcontra este FTD, p99 inflexionó en 720 RPS" y la comparación es inequívoca
Los appliances comerciales (Spirent CyberFlood, Ixia BreakingPoint) tienen estos conceptos bajo nombres como "test profile" / "load specification" / "phase configuration". Este proyecto los entrega como YAML en git — versionables, revisables como código, replayables byte-a-byte entre runs.
Los 15 planes¶
El catálogo está agrupado en 7 categorías. Cada plan tiene un identifier estable que aparece literalmente en el reporte de la prueba.
| Categoría | # | Identifier | Use cuando |
|---|---|---|---|
| Baseline | 1 | BASELINE-SMOKE-5M |
Primer run tras cualquier cambio en el cluster |
| 2 | BASELINE-SLO-30M |
Establecer el baseline de referencia de SLO antes de cualquier otro run | |
| Capacity | 3 | CAP-FIND-KNEE-30M |
Encontrar el conteo de agentes donde p99 inflexiona (la rodilla del NGFW) |
| 4 | CAP-MAX-1H |
Sostener al 90% de la rodilla descubierta durante una hora | |
| Stress | 5 | STR-OVERLOAD-15M |
Empujar a 2× la capacidad y observar modos de falla |
| 6 | STR-CONNECTION-FLOOD-10M |
Tasa máxima de nuevos handshakes TLS (sin reuso de sesión) | |
| Soak | 7 | SOAK-ENDURANCE-24H |
24 h sostenidas al 70% de capacidad — detecta leaks |
| 8 | SOAK-WEEKEND-72H |
72 h con patrón diurno — ciclos de pico/valle | |
| Spike | 9 | SPIKE-RECOVERY-10X-2M |
Burst de 10× con tiempo de recuperación medido |
| 10 | SPIKE-FLASH-CROWD-5M |
Patrón flash-crowd asimétrico (estilo Black Friday) | |
| Mix | 11 | MIX-FULL-ARCHETYPES-1H |
Peso igual entre skin/mock/HAR/real-app |
| 12 | MIX-CLONED-HEAVY-30M |
70% a slots Cloned — mix realista de empresa | |
| Protocol | 13 | H3-ONLY-SESSION-PRESSURE-30M |
100% HTTP/3, sesión nueva por petición |
| 14 | H2-LONGLIVED-CONN-30M |
100% HTTP/2 con conexiones multiplexadas de larga vida | |
| Realistic | 15 | REPLAY-REAL-CUSTOMER-1H |
HAR-replay de un trace real de cliente |
Anatomía de un plan¶
- identifier: CAP-FIND-KNEE-30M
display_name: "Capacity — Find the knee (30 min)"
description: "Step ramp from 50 → 1000 agents in 5 stages of 2 min each."
duration_total: 30m
phases:
- { name: warm, duration: 2m, pattern: linear, target: { playwright: 50, k6: 100 } }
- { name: s100, duration: 4m, pattern: step, target: { playwright: 100, k6: 500 } }
- { name: s250, duration: 4m, pattern: step, target: { playwright: 250, k6: 1000 } }
- { name: s500, duration: 4m, pattern: step, target: { playwright: 500, k6: 2500 } }
- { name: s750, duration: 4m, pattern: step, target: { playwright: 750, k6: 5000 } }
- { name: s1000, duration: 8m, pattern: step, target: { playwright: 1000, k6: 7500 } }
- { name: rampdown, duration: 4m, pattern: linear, target: { playwright: 0, k6: 0 } }
agent_target_strategy: round_robin_all
persona_mix:
synthetic_archetypes: { skin: 0.40, mock: 0.30, har: 0.20, real_app: 0.10 }
synthetic_weight: 1.0
cloned_weight: 0.0
protocol_mix: { h2: 0.30, h3: 0.70 }
cycle_interval_seconds: 3
ngfw_state_required: decrypt-on
slo_target_p99_seconds: 0.5
Campos explicados¶
| Campo | Qué controla |
|---|---|
identifier |
El contrato. Estable para siempre. Citado en reportes. Formato: CATEGORÍA-CARACTERÍSTICA-DURACIÓN |
display_name |
Versión amigable para humanos en dropdowns de UI |
description |
Por qué un operador escogería este plan. Leído por la UI de selección |
duration_total |
La duración total que el operador promete asignar. El engine rehúsa agendar un plan cuyas phases excedan esto |
phases[] |
Lista ordenada de phases de la línea de tiempo |
phases[].pattern |
linear (ramp suave), exponential (aceleración rápida), exponential_decay (decaimiento lento), step (salto instantáneo), hold (estable), sinusoidal (diurno) |
phases[].target |
Conteos de agentes objetivo al FINAL de la phase |
phases[].target_min / target_max |
Usado solo con sinusoidal para definir la envolvente de la oscilación |
agent_target_strategy |
Cómo los agentes eligen qué persona golpear: round_robin_all / round_robin_first_5 / random_each_request / weighted_top10 / weighted_cloned_70pct / pinned_first_5 / har_replay_only |
persona_mix.synthetic_archetypes |
Pesos para los 4 archetypes (deben sumar 1.0) |
persona_mix.synthetic_weight + cloned_weight |
División entre los 20 slots Synthetic y los 10 Cloned (deben sumar 1.0) |
protocol_mix |
Pesos H2 vs H3 (deben sumar 1.0) |
cycle_interval_seconds |
Cada cuánto cada agente hace una petición (0 = ritmado por trace HAR) |
tls_session_reuse |
Si false, cada ciclo crea un handshake TLS nuevo — presiona el engine de handshake del NGFW |
ngfw_state_required |
any / decrypt-on / decrypt-off. El engine rehúsa iniciar el run si el TLS Decrypt Mode Probe reporta un estado distinto |
slo_target_p99_seconds |
El p99 esperado para ESTE plan. Usado para computar pass/fail en el reporte |
prerequisite |
Precondiciones legibles por humanos (ej.: "5 cloned slots deben tener un SITE_NAME asignado") |
Cómo escoger un plan¶
Un engagement típico ejecuta 3–5 planes en este orden:
BASELINE-SMOKE-5M— confirmar que el test bed está saludableBASELINE-SLO-30M— registrar los números de referencia de SLOCAP-FIND-KNEE-30M— encontrar el conteo de agentes donde el NGFW dobla la rodillaCAP-MAX-1H— confirmar que la rodilla descubierta se sostiene por una hora- (Opcional, si el engagement permite tiempo)
SOAK-ENDURANCE-24Hpara detección de leaks, OSTR-OVERLOAD-15Mpara descubrimiento de modos de falla
Para demos / PoVs puede detenerse en #3 — el número de la rodilla es el titular. Para pruebas de aceptación o planificación de capacidad, ejecute los cinco.
Comparación entre engagements¶
El identifier es el contrato entre engagements. Dos SEs en países distintos ejecutando el mismo plan contra NGFWs distintos DEBEN estar comparando la misma forma de carga. Para hacer esto seguro:
- Los identifiers son inmutables. Un plan nunca cambia su forma de carga tras publicación. Para cambiar una forma de carga, publique un nuevo plan con un nuevo identifier (ej.:
CAP-FIND-KNEE-30M-v2) - El catálogo está versionado en git. Cada cambio es revisable como código; un job de CI verifica que los identifiers permanezcan estables
- Los reportes citan la versión del catálogo + el identifier: "Run ejecutó
CAP-FIND-KNEE-30Mdel catálogo v1, plan-snapshot-hashsha256:abc.... NGFW = Cisco FTD 7.4. Resultado: rodilla en 720 agentes concurrentes, p99 = 487 ms"
API¶
El Dashboard sincroniza el catálogo en Postgres al arrancar y expone:
GET /api/test-plans/catalog— lista completaGET /api/test-plans/{identifier}— plan único con phases
Ambos retornan JSON. Sin auth requerida para lectura; el catálogo es información pública sobre qué planes existen (no sobre lo que un run hizo).
Agregar un nuevo plan¶
- Anexe la nueva entrada a
platform/test-plans/catalog.yamlcon un identifier nuevo siguiendo la convención de nomenclatura - Bump el
version: 1en lo alto del archivo (es el metadato de versión del catálogo) - Abra un PR — los revisores verifican que el identifier no choque y que la forma de carga sea sensata
- Al merge, cada pod del Dashboard re-sincroniza en el próximo restart
Deprecar un plan¶
Establezca deprecated: true y (opcionalmente) replaced_by: NEW-IDENTIFIER. La API del catálogo aún retorna el plan (para que reportes históricos sigan funcionando), pero el picker del Dashboard lo oculta de "available plans" y lo expone solo como "view legacy plans".
Relacionados¶
platform/test-plans/catalog.yaml— fuente de verdad del catálogoMONITORING_TEST_VALIDITY.md— alertas que confirman que el test bed en sí no es el cuello de botellaTLS_DECRYPT_MODE_VERIFICATION.en.md— enforcement dengfw_state_requiredTRACING.md— tracing distribuido durante runs