# Verificación integral T16 La fuente ejecutable es [acceptance-cases.json](acceptance-cases.json). Cada caso A01–A20 referencia métodos de prueba concretos. El checker exige ejecuciones reales en XML Surefire/Failsafe, rechaza cualquier fallo/error/skip y rechaza métodos faltantes. No considera suficiente que exista el código fuente de una prueba. ## Ejecución con Docker/Testcontainers (criterio de cierre) Requiere JDK 21, Python 3 y motor Docker operativo: ```sh docker info sh ./mvnw --batch-mode --no-transfer-progress clean verify python3 scripts/verify_acceptance.py --require-testcontainers ``` Windows: usar mvnw.cmd y python. La suite crea contenedores PostgreSQL 9.6.24 temporales, JWT/JWKS locales, proveedores HTTP loopback y procesos JVM exclusivos de pruebas. No necesita PostgreSQL productivo ni Keycloak real. Failsafe no omite tests si Docker falta: falla. CI ubuntu-24.04 ejecuta estas mismas puertas, limita el job a 30 min y conserva reportes/manifest por 30 días incluso al fallar Maven. Una configuración de CI guardada no demuestra que el job remoto ya se ejecutó. ## Verificación alternativa con PostgreSQL de pruebas ```powershell # Definir MIGRATION_TEST_DB_URL/USER/PASSWORD en el entorno del proceso. # URL permitida por los fixtures: jdbc:postgresql://HOST:PORT/orquestador_test ./mvnw.cmd --batch-mode --no-transfer-progress clean verify -Pmigration-tests-external python scripts/verify_acceptance.py ``` Usa esquemas/roles temporales propios y los elimina al finalizar. Nunca usar una base de runtime. Los secretos no se escriben en reportes de aceptación. El checker infiere external-postgresql de las propiedades reales de Failsafe; si se agrega --require-testcontainers a esta evidencia, devuelve error. La corrida alternativa verifica comportamiento SQL/HTTP/JVM, pero no satisface por sí sola el requisito de reproducibilidad Docker de T16. Ejecutar siempre clean verify antes del checker: no combinar reportes de corridas parciales anteriores. acceptance-report.json guarda los casos, métodos/parametrizaciones ejecutadas, totales, entorno y hashes de manifest/JAR. Archivar XML y reporte juntos. El checker tiene pruebas propias: `python -m unittest discover -s scripts -p 'test_*.py'`. ## Cobertura | Caso | Evidencia principal | | --- | --- | | A01 | DemoFlowsIT.creditBoundaries: cliente encontrado, persistencia y recorrido | | A02 | DemoFlowsIT.missingCustomerRemainsCreatedAndCanBeRetried: SUCCEEDED/CLIENTE_NO_ENCONTRADO | | A03 | DemoFlowsIT.customerApiFailureRetriesAndNeverBecomesCustomerNotFound: mock 503, tres intentos, FAILED | | A04 | DemoFlowsIT.creditBoundaries + DecisionEvaluatorTest: 71/70/61/60 y decimales | | A05 | DemoFlowsIT.invalidProviderScoreNeverDefaultsToManualReview | | A06 | DecisionEvaluatorTest UNIQUE + FlowSimulationTest.ambiguousDraftDecisionIsNotConvertedIntoDefault | | A07 | DemoFlowsIT.repeatedEventHasOneExecutionAndOneProviderCallEvenAfterCompletion | | A08 | EventAcceptanceIT.concurrentDifferentPayloadsConflictAndNumericCanonicalReplayIsStable | | A09 | EventAcceptanceIT.concurrentIdenticalAndDifferentKeysHaveOneAcceptance | | A10 | DemoFlowsIT.existingCreditKeepsV1WhileNewCreditRequiresLicense | | A11 | DocumentTasksIT: INVALID, documento ajeno/no conforme y referencia no reasignable | | A12 | RetryReconciliationIT: caídas reales de JVM; WorkerIT: checkpoint durable | | A13 | RetryReconciliationIT + WorkerIT: clave externa estable o conciliación | | A14 | WorkerIT: SKIP LOCKED, renovación y fencing de worker obsoleto | | A15 | EventAcceptanceIT, ObservabilityIT, SimulationIT: roles/ámbitos/propiedad | | A16 | FlowPublicationIT.databaseAndApplicationBothPreventPublishedMutation | | A17 | FlowPublicationIT: activación/retiro/asignación concurrentes | | A18 | DemoFlowTest y DemoFlowsIT: v1/v2 con mismo motor/binario; licencia en JSON/perfil | | A19 | WorkerIT y RetryReconciliationIT: rollback auditado y recuperación | | A20 | DocumentTasksIT.clientCannotSubmitProviderFieldsOrReplaceMetadata | Las carreras usan barreras/latches y bloqueos DB; los retries adelantan next_attempt_at en el esquema de pruebas sin esperar backoff real. CrashWorkerProcess usa Runtime.halt en JVM hija; el padre reconstruye el worker desde PostgreSQL. No es una prueba de reinicio de contenedor ni una garantía de exactly-once de un proveedor real. Pendiente histórico de T07 cerrado en implementación: [simulación](SIMULATION.md). T17 conserva empaquetado/demo desde checkout limpio y verificación de imagen Docker.