Skip to content

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:

  1. Un inicio y fin definidos — duración en minutos / horas, no "hasta que el ingeniero diga basta"
  2. 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
  3. Un identifier compartido — dos ingenieros en geografías distintas pueden decir "ejecuté CAP-FIND-KNEE-30M contra 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:

  1. BASELINE-SMOKE-5M — confirmar que el test bed está saludable
  2. BASELINE-SLO-30M — registrar los números de referencia de SLO
  3. CAP-FIND-KNEE-30M — encontrar el conteo de agentes donde el NGFW dobla la rodilla
  4. CAP-MAX-1H — confirmar que la rodilla descubierta se sostiene por una hora
  5. (Opcional, si el engagement permite tiempo) SOAK-ENDURANCE-24H para detección de leaks, O STR-OVERLOAD-15M para 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-30M del catálogo v1, plan-snapshot-hash sha256: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 completa
  • GET /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

  1. Anexe la nueva entrada a platform/test-plans/catalog.yaml con un identifier nuevo siguiendo la convención de nomenclatura
  2. Bump el version: 1 en lo alto del archivo (es el metadato de versión del catálogo)
  3. Abra un PR — los revisores verifican que el identifier no choque y que la forma de carga sea sensata
  4. 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