Skip to content

Reportes de Test Run

Lee en tu idioma: 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.

Estado: Fase 1 entregada — reporte HTML print-styled con JSON estructurado. Fases 2–5 añaden PDF server-rendered, anexos de inventario DUT, firma Cosign y comparación N-runs. Ver platform/test-plans/catalog.yaml para el lado de test plan.

Por qué Reportes

Spirent CyberFlood e Ixia BreakingPoint ambos entregan reportes propietarios — PDFs caja-negra que operadores confían porque vinieron de un vendor pago. Este proyecto entrega un sistema de reporte abierto y determinístico, diseñado para ser demostrablemente más fuerte que esos:

Capacidad Spirent / Ixia Este proyecto
Portada con identidad del run
Identificador de plan estable entre engagements ✅ (vendor-locked) ✅ (CAP-FIND-KNEE-30M, git-versionado)
Hash del plan-snapshot probando que parámetros no fueron editados post-run
Hash del contenido del reporte para chain-of-custody forense ✅ (Fase 1)
Inventario del DUT (NGFW + switch) + config saneada como anexo 🟡 Fase 3 — Nexus 9000 + NGFW
Evidencia independiente del modo TLS-decrypt (cert del issuer) ✅ (probe en cableado de Fase 3)
Firma criptográfica en el PDF 🟡 Fase 4 — Cosign
Reporte de comparación N-runs (últimos 5 runs lado a lado) ⚠️ add-on pago 🟡 Fase 5
Reproducibilidad — replay de un reporte publicado contra tu propio NGFW 🟡 Fase 5 — modo replay
Aviso de licencia en cada página ✅ Fase 1

Once diferenciadores forenses

La tabla de comparación arriba cubre la base. Más allá de eso, el sistema de reporte agrega once capacidades concretas que apuntan más alto que las alternativas cerradas y pagas. Dos ya se entregaron; nueve están enmarcadas en las Fases 2–5.

# Capacidad Estado
1 Automatización de análisis causal — correlación topology-aware produce sentencias "hecho → consecuencia → recomendación" ✅ entregado en #177
2 Timeline del modo TLS Decrypt — probe independiente de issuer-cert como ground-truth; alerta TLSDecryptModeChanged invalida automáticamente resultados que cruzan un flip de estado ✅ entregado en #180
3 Prueba de validez del test-bed — verdict por ventana (e.g. "resultados en ventana 14:00–14:23 están limpios; 14:23–14:31 contaminados por saturación de UCS-2") 🟡 Fase 5
4 Breakdown de latencia por hop — handshake agent→NGFW / handshake NGFW→persona / TTFB / object load en columnas separadas, no solo end-to-end 🟡 Fase 5
5 Análisis por archetype — summary separado por skin / mock / har-replay / real-app — cada archetype ejercita un path diferente del NGFW 🟡 Fase 5
6 Manifiesto de reproducibilidad — git SHA, image digests SHA-256, sysctls aplicados por UCS, deployment mode, fingerprint de la config del NGFW — la receta completa 🟡 Fase 4
7 PDF firmado criptográficamente — Cosign keyless vía signing key del cluster; entrada Rekor/Sigstore opcional como log de transparencia 🟡 Fase 4
8 Intervalos de confianza por sección — toda métrica viene con CI basado en sample size, no solo la media 🟡 Fase 5
9 Atribución detallada de fallas — e.g. "47 de 12.847 errores fueron NGFW timeout, 12 fueron TLS handshake fail, 8 fueron conntrack overflow del test-bed" 🟡 Fase 5
10 Snapshot de replay — link "open in viewer" abre dashboards Grafana como estaban en el momento del run (Prometheus state congelado) 🟡 Fase 5
11 Narrativa en prosa de grado forense — exec summary en prosa que navega resultados con confidence levels — no solo un dump de tabla 🟡 Fase 5

Fase 1 — qué se entregó

La API de datos

GET /api/test-runs/{executionId}/report.json

Retorna el shape canónico ReportData:

{
  "version": 1,
  "generatedAt": "2026-05-06T14:35:00.000Z",
  "reportSha256": "<hex 64 chars>",
  "meta": {
    "runId": "...",
    "executionId": "...",
    "planIdentifier": "CAP-FIND-KNEE-30M",
    "planDisplayName": "Capacity — Find the knee (30 min)",
    "planCatalogVersion": 1,
    "planSnapshotSha256": "<hex 64 chars>",
    "durationS": 1800,
    "startedAt": "...",
    "endedAt": "...",
    "outcome": "..."
  },
  "license": { "id": "LicenseRef-PolyForm-Noncommercial-1.0.0-with-Appendix-A", ... },
  "plan":     { "identifier": "...", "phases": [...], ... },
  "topology": { "deploymentMode": "tri-node", "ucsCount": 3, ... },
  "tlsDecrypt": { "activeAtStart": "on", "activeAtEnd": "on", ... },
  "results":  { "aggregate": { "p50_ms": 142, "p95_ms": 380, "p99_ms": 487, ... } },
  "slo":      { "targetP99Ms": 500, "observedP99Ms": 487, "pass": true, ... },
  "annexes":  [{ "id": "annex-b-nexus", "title": "...", "sha256": "...", "body": "..." }, ...]
}

Headers X-Report-Sha256 y X-License cargan el mismo hash + license-id para tooling downstream.

La página de print

GET /runs/{executionId}/report

Una página HTML server-rendered, con estilo de print, conteniendo:

  • Portada — run id, plan, fechas, badge SLO, badge de licencia, SHA-256 del reporte + SHA-256 del plan-snapshot
  • Licensing & Use Restrictions — texto completo de audiencia + campo de uso en EN / PT-BR / ES en la página inmediatamente después de la portada
  • Executive Summary — KPIs agregados, SLO pass/fail con porcentaje de quema del budget
  • Test Plan Configuration — tabla de parámetros + timeline de fases
  • Anexos — placeholders para Fase 3 (inventario Nexus + NGFW)
  • Footer de licencia — fijado en cada página impresa (el operador no puede retirarlo sin re-renderizar)

La página renderiza con márgenes @page A4 portrait y footers con contador de páginas. Browsers pueden "Guardar como PDF" hoy; Fase 2 cambia por Puppeteer para renderización determinística en el servidor.

Hashes forenses ya presentes en Fase 1

Hash A qué se compromete
reportSha256 Payload JSON canónico completo — prueba que datos del reporte no fueron manipulados
planSnapshotSha256 Parámetros del plan congelados al inicio del run — prueba que el plan no fue editado durante el run
annex.sha256 (por anexo) Cuerpo de cada anexo — Fase 3 lo usa para atestación de config Nexus/NGFW

Un revisor que sospecha manipulación del PDF puede:

  1. Bajar el JSON ReportData original vía API
  2. Recomputar SHA-256 del JSON canónico
  3. Comparar con el valor impreso en la portada

Si coinciden — el reporte es auténtico. Fase 4 añade Cosign por encima para hacer esto trivialmente verificable.

Lo que Fases 2–5 añaden

Fase Añade
2 Puppeteer renderiza esta página server-side → /api/test-runs/{id}/report.pdf retorna PDF real
3 DUT Inventory Probe puebla Anexo B (Nexus 9000) + Anexo C (NGFW) + Anexo D (chasis UCS) con modelo real, S/N, running-config saneada. Parcialmente entregado: la fundación DUT API + 4 vendor adapters (Cisco FTD, Nexus, UCS CIMC Redfish, FortiGate) y la infraestructura de snapshot/hash ya están vivas desde v4.0.0 (#199, #210); conectar los snapshots a los Anexos B/C/D del reporte es la pieza que falta (PR-D en el roadmap v4.1)
4 Firma Cosign keyless OIDC en el PDF + embed de Grafana state snapshot (los dashboards reales como estaban durante el run)
5 Reporte de comparación N-runs (últimos 5 runs del mismo plan, p50/p95/p99 lado a lado) + modo replay (baja la versión del catálogo + snapshot del plan para reproducir la load shape en otro lugar)

Workflow del operador

  1. Elige un plan del catálogo, dispara un run vía Dashboard
  2. Run completa — fila en test_run_executions recibe endedAt + outcome
  3. Abre /runs/{executionId}/report en el browser
  4. Print → Save as PDF (Fase 1) — o espera Fase 2 y baja el PDF firmado directo
  5. Distribuye el PDF a partes autorizadas; el footer de licencia + portada recuerdan la política de audiencia

Comparado con alternativas comerciales

El reporte del Ixia BreakingPoint es un PDF de formato cerrado renderizado por un engine cerrado; el operador necesita confiar en el vendor que los números no fueron masajeados. Este sistema invierte eso:

  • Los datos son un shape JSON versionado (ReportData) — cualquiera puede re-parsearlo
  • El PDF es una renderización de print de una página HTML — cualquiera puede re-renderizarlo
  • El plan es un YAML git-versionado — cualquiera puede confirmar lo que se suponía debía correr
  • La config real del equipo bajo prueba queda embebida como anexo con hash (Fase 3)
  • El PDF será firmado criptográficamente (Fase 4) — cualquiera puede verificar la procedencia

Todo esto permaneciendo dentro de la política de audiencia de la licencia.

Relacionados