Chrono Mock
IdiomaEspañol

Pruebas de fechas en un pipeline

La ventana sirve para explorar. Esta es la otra mitad: una compilación de línea de comandos de unos 2,4 MB sin entorno de ejecución que instalar, cuyo código de salida es el veredicto de cobertura y no el del propio objetivo.

El código de salida es el veredicto

Esta es la decisión de diseño que hace la herramienta scriptable. Cuando termina una sesión, el código de salida responde a «¿tuvo efecto la sustitución del tiempo?», no a «¿qué devolvió la aplicación?». Un pipeline puede entonces fallar ante una sustitución que silenciosamente no ocurrió - que es el fallo por el que merece la pena fallar, porque todo lo que viene después es una prueba que no demostró nada.

El código de salida del propio objetivo se sigue informando, en los datos de la sesión.

CódigoSignificado
0funciona - todo proceso que leyó la hora vio el reloj de la sesión
10funciona parcialmente - algunos canales cubiertos, otros no
11no funciona - la sustitución no llegó a los canales clave
4indeterminado - no se pudo establecer la cobertura
1error de uso - una opción o una expresión incorrecta
2el objetivo no se pudo lanzar ni inyectar
12el objetivo desapareció, lo que sugiere una aplicación de instancia única
3error interno - el motor no pudo arrancar, llegó a un estado inesperado o se detuvo antes de cerrar la sesión (sea cual sea su propio código de salida). Una ejecución así no lleva veredicto
5la operación no está incluida en esta versión
6la ejecución se cortó - venció --timeout, o el motor dejó de responder durante 15 segundos y se detuvo. No es un veredicto: la sesión se interrumpió, así que no demuestra nada sobre el objetivo en ningún sentido
7ya hay otra sesión en marcha - solo una sesión a la vez. Basta con volver a intentarlo cuando termine
8la sesión llegó a un veredicto, pero su evidencia no está en el archivo que indica --report - el disco estaba lleno, u otro programa mantenía abierto el archivo anterior, que entonces queda como estaba. El veredicto sigue en el informe que imprime el comando

Todas las opciones de ambos comandos, y la misma tabla para la calculadora, están en la referencia de la línea de comandos.

Ejecuciones acotadas

Un pipeline no puede esperar a que una persona cierre una aplicación de escritorio. --ticks N termina la sesión tras N latidos - de un segundo real cada uno - e informa de lo que encontró hasta ese momento. La cobertura se establece en los primeros instantes del proceso de todos modos, así que un límite corto suele bastar.

# Diez segundos, luego parar e informar
chrono run ".\build\test.exe" --preset year-rollover --ticks 10 --report evidence.txt

Salida para máquinas y evidencias

  • --json emite la sesión como registros legibles por máquina en lugar del informe para personas - los mismos hechos, incluida la cobertura por canal.
  • --report <path> escribe el informe para personas en un archivo, que sirve como artefacto de compilación. Una sesión cuyo veredicto no sea funciona abre ese archivo con un aviso de evidencia poco fiable en lugar de enterrar la salvedad al final.
  • La calculadora también entiende --json, de modo que un pipeline puede calcular la fecha que necesita y devolverla.
# Calcular la fecha y luego ejecutar en ella
chrono calc --base today --snap eom --json
chrono run ".\build\test.exe" --preset month-end --ticks 10 --json

Un paso, más o menos

- name: Month-end behaviour
  shell: pwsh
  run: |
    .\chrono.exe run ".\build\test.exe" --preset month-end --ticks 10 --report evidence.txt
    # un código de salida distinto de cero aquí significa que la sustitución no tuvo efecto,
    # así que la prueba siguiente no habría demostrado nada

- name: Keep the evidence
  uses: actions/upload-artifact@v7
  with:
    name: chrono-evidence
    path: evidence.txt

Dos salvedades honestas sobre los runners

  • Necesita un runner de Windows. No hay versión para Linux ni macOS, y no la habrá - en Linux, libfaketime ya cubre este caso.
  • El antivirus de un runner alojado puede bloquear la inyección. Desplazar el tiempo implica inyectar una biblioteca en el proceso objetivo, una técnica documentada de Windows que también usa el malware. Un runner que la bloquee produce un código de salida que lo dice en vez de un falso éxito - pero conviene averiguarlo antes de depender de ello.

Por la misma razón, la suite de pruebas de extremo a extremo de este proyecto se ejecuta en máquinas reales y no en un runner alojado. Su integración continua compila y prueba todo con pruebas unitarias, y la sustitución en sí se ejercita a mano con aplicaciones reales, tanto en compilaciones de 32 como de 64 bits, antes de cada versión.

Pruébalo