Chrono Mock
LinguaItaliano

Test sulle date in una pipeline

La finestra serve per esplorare. Questa è l'altra metà: una build da riga di comando di circa 2,4 MB, senza alcun runtime da installare, il cui codice di uscita è il verdetto di copertura e non quello del target.

Il codice di uscita è il verdetto

È la scelta di progetto che rende lo strumento adatto agli script. Quando una sessione finisce, il codice di uscita risponde a «la sostituzione del tempo ha avuto effetto?», non a «che cosa ha restituito l'applicazione?». Una pipeline può quindi fallire davanti a una sostituzione che silenziosamente non è avvenuta - ed è il fallimento per cui vale la pena fallire, perché tutto ciò che viene dopo è un test che non ha dimostrato nulla.

Il codice di uscita del target stesso viene comunque riportato, nei dati della sessione.

CodiceSignificato
0funziona - ogni processo che ha letto l'ora ha visto l'orologio della sessione
10funziona in parte - alcuni canali coperti, altri no
11non funziona - la sostituzione non ha raggiunto i canali chiave
4indeterminato - non è stato possibile stabilire la copertura
1errore d'uso - un'opzione o un'espressione errata
2non è stato possibile avviare o iniettare il target
12il target è scomparso, il che fa pensare a un'applicazione a istanza singola
3errore interno - il motore non è riuscito ad avviarsi, ha incontrato uno stato imprevisto o si è fermato prima di chiudere la sessione (qualunque fosse il suo codice di uscita). Un'esecuzione così non porta alcun verdetto
5l'operazione non è inclusa in questa versione
6l'esecuzione è stata interrotta - --timeout è scaduto, oppure il motore ha smesso di rispondere per 15 secondi ed è stato fermato. Non è un verdetto: la sessione è stata interrotta, quindi non dimostra nulla sul target né in un senso né nell'altro
7un'altra sessione è già in corso - una sessione alla volta. Basta riprovare quando è terminata
8la sessione è arrivata a un verdetto, ma la sua prova non è nel file indicato da --report - il disco era pieno, oppure un altro programma teneva aperto il vecchio file, che allora resta com'era. Il verdetto resta nel report che il comando stampa

Tutte le opzioni dei due comandi, e la stessa tabella per il calcolatore, sono nel riferimento della riga di comando.

Esecuzioni limitate

Una pipeline non può aspettare che una persona chiuda un'applicazione desktop. --ticks N termina la sessione dopo N heartbeat - uno al secondo reale - e riferisce ciò che ha trovato fino a quel momento. La copertura si stabilisce comunque nei primi istanti del processo, quindi di solito basta un limite breve.

# Dieci secondi, poi fermarsi e riferire
chrono run ".\build\test.exe" --preset year-rollover --ticks 10 --report evidence.txt

Output per le macchine e prove

  • --json emette la sessione come record leggibili da una macchina invece del report per le persone - gli stessi fatti, compresa la copertura per canale.
  • --report <path> scrive il report per le persone in un file, che costituisce un ragionevole artefatto di build. Una sessione il cui verdetto non è funziona apre quel file con un avviso di prova inaffidabile, invece di seppellire la riserva in fondo.
  • Anche il calcolatore capisce --json, così una pipeline può calcolare la data di cui ha bisogno e restituirla.
# Calcolare la data, poi eseguire a quella data
chrono calc --base today --snap eom --json
chrono run ".\build\test.exe" --preset month-end --ticks 10 --json

Uno step, più o meno

- name: Month-end behaviour
  shell: pwsh
  run: |
    .\chrono.exe run ".\build\test.exe" --preset month-end --ticks 10 --report evidence.txt
    # un codice di uscita diverso da zero qui significa che la sostituzione non ha attecchito, quindi
    # il test successivo non avrebbe dimostrato nulla

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

Due riserve oneste sui runner

  • Serve un runner Windows. Non esiste una build per Linux o macOS, e non ci sarà - su Linux, libfaketime copre già questo caso.
  • L'antivirus su un runner ospitato può bloccare l'iniezione. Spostare il tempo significa iniettare una libreria nel processo di destinazione, una tecnica Windows documentata che usa anche il malware. Un runner che la blocca produce un codice di uscita che lo dice, invece di un falso successo - ma è una cosa da scoprire prima di farci affidamento.

Per lo stesso motivo, la suite di test end-to-end di questo progetto gira su macchine reali e non su un runner ospitato. La sua integrazione continua compila e testa tutto con test unitari, e la sostituzione vera e propria viene provata a mano su applicazioni reali, sia nelle build a 32 bit sia in quelle a 64 bit, prima di ogni rilascio.

Provalo