Chrono Mock
LinguaItaliano

Riferimento della riga di comando

Ogni opzione dei due comandi, le due tabelle dei codici di uscita e come leggere ciò che torna indietro. La versione narrativa, con il ragionamento, è nella pagina CLI e CI.

Due comandi

chrono run avvia un'applicazione a una data e ora diverse. chrono calc calcola una data e dice che cosa la rende interessante. Condividono una sola grammatica di passi, quindi uno spostamento scritto per l'uno significa la stessa cosa nell'altro.

chrono version risponde a una terza domanda, molto più piccola: quale build è, quale dei due core è l'eseguibile e quale versione del protocollo parla. Una riga su stdout, così uno script può catturarla.

chrono license risponde alla quarta: sotto quale licenza è distribuita questa build, la clausola di esclusione della garanzia e i componenti di terze parti collegati. Dice anche dove si trovano su disco il testo completo della licenza e le note sui componenti di terze parti, oppure ammette che la copia in esecuzione non li ha accanto. --components elenca ogni componente incluso con la sua versione, invece di un riepilogo.

chrono presets elenca il catalogo degli scenari come lo legge --preset: ogni scenario della cartella, scritto con le parole che legge la grammatica del calcolatore, e ogni file che rifiuterebbe, con il motivo. --json scrive chronomock.presets/1 e --dir indica un'altra cartella.

chrono run <target> [options]
chrono calc [options]
chrono version        # chrono 0.4.0 (x64, protocol 1)
chrono license        # GPL-3.0-only, and what is bundled
chrono presets        # il catalogo, come lo legge --preset
chrono --help          # usage for all of them

chrono run - opzioni

OpzioneChe cosa fa
--at <moment> Il momento da cui partire, nel fuso della sessione. Assoluto (2038-01-19T03:14:07) o relativo con un segno iniziale (+1d, -2h). Unità: s m h d w mo q y - m sono i minuti e mo i mesi. Senza questa opzione l'orologio della sessione parte dall'ora reale attuale, quindi --mode xN da solo fa semplicemente correre il target più veloce.
--zone +HH:MM Il fuso della sessione: il fuso in cui è scritto il momento e quello che le chiamate di ora locale del target riportano. Uno scostamento fisso, senza ora legale. Senza l'opzione, il fuso dell'host.
--mode flow|frozen|xN flow scorre a velocità reale, frozen tiene fermo l'orologio, xN lo fa correre N volte più veloce (x60 trasforma un'ora in un minuto, x1440 un giorno).
--scale-duration Accelera anche l'asse del tempo trascorso: contatori di tick, tempo di interrupt, pause e timer. Le attese su oggetti vengono contate e mantengono la durata reale. Disattivato per impostazione predefinita, perché un orologio a muro e un cronometro sono domande diverse. Un timer o un ritardo impostato su una data e un'ora segue l'orologio della sessione con o senza questa opzione.
--scale-qpc Scala anche il contatore ad alta risoluzione, da cui Python 3.13+ monotonic, .NET Stopwatch e Java nanoTime leggono il tempo trascorso. Disattivato per impostazione predefinita: un'applicazione che misura il proprio rendering con quel contatore può sembrare distorta.
--ticks N Termina la sessione dopo N heartbeat, uno al secondo reale, e riferisce. Senza l'opzione lo strumento resta agganciato finché il target, e ogni programma che ha avviato e che gira sull'orologio della sessione, non sono usciti - un launcher che termina subito lascia la sessione all'applicazione che ha avviato.
--timeout <s> Rinuncia dopo questi secondi ed esce con 6, per una pipeline che non deve bloccarsi. Indipendentemente da questa opzione, un core che tace per 15 secondi viene fermato ed esce anch'esso con 6 - in entrambi i casi l'esecuzione è interrotta, quindi non porta alcun verdetto.
--args "..." Argomenti per il target, come un'unica stringa, suddivisa con la stessa regola che usa Windows - così un argomento contenente spazi sopravvive. Per un target Chromium, --user-data-dir e --remote-debugging-port vengono rifiutati invece di essere sovrascritti: la sessione ha bisogno di un proprio profilo isolato, e avviare di nascosto sul tuo vero profilo del browser è l'unica cosa che non deve accadere.
--cwd <dir> Avvia il target in quella directory. Senza l'opzione il target eredita la nostra, che è ciò che faceva ogni esecuzione prima che l'opzione esistesse. Un valore vuoto è un errore d'uso e non «nessuna directory» - assente e vuoto sono cose diverse, e solo l'assente è qualcosa che Windows può ricevere. Una directory che non esiste ferma la sessione con target.cwd_missing prima che venga avviato qualsiasi cosa, invece di comparire più tardi come un target che non voleva partire.
--preset <id> Prende il momento e la velocità da presets/<id>.json. Esclusiva rispetto a --at, --mode e --scale-duration, perché lo scenario è allora l'unica fonte di entrambi.
--param id=value Compila un parametro dello scenario. Ripetibile, richiede --preset. Solo in run, la data di inizio di una prova usa come valore predefinito la data di creazione dell'eseguibile di destinazione, così uno scenario di prova conta dal giorno in cui l'applicazione è stata installata senza che tu debba digitarla.
--set-after T:M All'heartbeat T, cambia la velocità in M. In corsa il moltiplicatore è almeno 1 - congelare a sessione in corso non è previsto qui.
--jump-after T:moment All'heartbeat T, fa saltare l'orologio a quel momento, assoluto o relativo, nel fuso della sessione.
--force Mantiene la sessione anche quando il verdetto iniziale dice che la sostituzione non ha avuto effetto - per impostazione predefinita il target viene fermato, perché una sessione che non ha dimostrato nulla è peggio di nessuna sessione. Il verdetto non cambia, né cambia il codice di uscita. Decide solo se il target continua a girare.
--no-embedded Lascia le pagine web dentro l'applicazione (WebView2, Qt WebEngine) sull'orologio reale e non apre nessuna porta di debug. Senza questa opzione la sessione chiede a un tale motore di aprire una porta locale e porta le sue pagine sull'orologio della sessione attraverso di essa - finché la porta è aperta, qualsiasi altro programma su questo computer può usarla per raggiungere quelle pagine.
--elevated-embedded Per un'applicazione eseguita come amministratore, da un Chrono Mock eseguito anch'esso come amministratore. WebView2 ignora per una tale applicazione l'impostazione con cui la sessione raggiunge le sue pagine, quindi la sessione scrive un valore nel registro della macchina (HKLM, con il nome dell'.exe dell'applicazione) per la sua durata e lo rimuove alla fine. Finché l'applicazione è in esecuzione, qualsiasi altro programma su questo computer può raggiungere le sue pagine tramite la porta, e l'applicazione ha diritti di amministratore. Non con --no-embedded.
--keep-background-timers Avvia il motore web - il browser di un'applicazione Chromium o Electron, o il motore dentro un'applicazione - con il rallentamento dei timer nelle finestre nascoste disattivato, così una finestra ridotta a icona mantiene la velocità della sessione. L'applicazione lavora allora a pieno ritmo anche mentre è nascosta. Un'applicazione avviata come amministratore tramite --elevated-embedded non la riceve.
--dry-run Stampa che cosa sarebbe la sessione e non avvia nulla: il momento e il fuso risolti e da dove vengono, con che cosa uno scenario ha compilato ogni parametro, gli argomenti dopo la suddivisione e quale dei due meccanismi prenderebbe il target. Non viene avviato alcun processo e non viene scritto alcun file, compreso quello che --report indica. Esce con 0 per un piano praticabile e con 2 per un target che non c'è, che è il codice che un'esecuzione vera dà per lo stesso fatto. Un piano non porta alcun verdetto e lo dice - solo una sessione vera ne ha uno. Con --json il piano è dato come dati, inclusi session.elevated_embedded e session.elevated_embedded_value, il nome del file con cui sarebbe chiamato il valore del registro quando l'opzione si applica a un bersaglio .exe, altrimenti null. Un nome lì non è una promessa di scrittura: la sessione scrive il valore solo quando Chrono Mock stesso è eseguito come amministratore.
--report <path> Scrive il report per le persone in un file. Un verdetto diverso da funziona apre quel file con un avviso di prova inaffidabile, perché una prova che nasconde il proprio dubbio è peggio di nessuna. Anche una sessione con verdetto funziona riceve questo avviso quando l'applicazione non ha letto nessuno degli orologi che la sessione sostituisce, o quando è un programma Go, il cui orologio di sistema Chrono Mock non raggiunge. Il file nomina anche l'esecuzione stessa: la versione, quando è partita, il target, la sua cartella e le opzioni.
--report-args Insieme a --report, scrive in quel file anche gli argomenti del target, parola per parola. Disattivato per impostazione predefinita, perché un argomento può contenere una password - il file dice allora solo quanti erano.
--json Emette la sessione come record leggibili da una macchina invece del report - lo stesso flusso che consuma la finestra stessa. L'output proprio di un'applicazione console va su standard error, quindi lo standard output contiene i record e nient'altro. Un'applicazione ancora in esecuzione quando la sessione termina continua a scrivere lì, così tutto ciò che legge standard error fino alla fine la aspetta, e l'esecuzione lo dice.

chrono run - codici di uscita

Il codice di uscita è il verdetto della sessione, non ciò che l'applicazione ha restituito. Il codice di uscita proprio dell'applicazione è riportato separatamente, nel report e nei dati della sessione - la pagina CLI e CI spiega perché è così.

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. Un onesto «non so dirlo», mai un successo fittizio
12il target è scomparso subito dopo l'iniezione senza lasciare nulla in esecuzione sull'orologio della sessione, il che fa pensare a un'applicazione a istanza singola che passa il testimone a una copia già in esecuzione, oppure a un passaggio a un programma in cui la sessione non è potuta entrare, di solito l'altra architettura (32/64 bit). Un target che avvia l'applicazione e termina è un launcher, e la sessione prosegue per l'applicazione
1errore d'uso - un'opzione errata, un'espressione errata o uno scenario che questo comando non accetta
2non è stato possibile avviare o iniettare il target
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 - per esempio uno scenario il cui momento richiede un calendario che run non sa ancora caricare. Volutamente distinto da un errore d'uso: hai chiesto qualcosa che non esiste ancora, non qualcosa di sbagliato
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

Leggere il report

Senza --json la sessione termina con un report in chiaro. Ogni riga è o un fatto che la sessione ha osservato o è assente - nulla viene riempito con un valore predefinito plausibile.

Chrono Mock - session report
  target:   .\build\test.exe
  verdict:  WORKS - time substitution took effect  (processes: 1)
            every process that read time saw the session clock
  session:  fake clock reached 2038-01-19T03:14:08
            real elapsed 1.3s, fake elapsed 1.3s
  exited:   the target closed itself with code 3
  covered channels (substituted, with call counts, 10 calls in all):
            - pid 21240: GetSystemTimeAsFileTime (5 calls)
            - pid 21240: GetLocalTime (5 calls)
  observed channels (hooked but left real):
            - pid 21240: NtCreateUserProcess (0 calls)
  warnings:
            - the target opened a network connection ...
  • verdict - il verdetto della famiglia sul processo padre e su ogni processo figlio, con il numero di processi. È il numero che porta il codice di uscita.
  • exited - il codice di uscita proprio dell'applicazione, e solo quando si è chiusa da sola. Un'esecuzione limitata da --ticks lascia il target in esecuzione, una sessione Chromium è una che lo strumento chiude da sé, e una sessione mai partita non ha un codice del genere - la riga è allora assente invece di mostrare uno zero inventato. Un codice di crash arriva come un grande numero negativo, quindi riceve anche la forma esadecimale.
  • covered - i canali che la sostituzione ha raggiunto, con quante volte ciascuno è stato effettivamente chiamato, per processo. I conteggi non vengono mai sommati tra processi: l'audit di un processo non deve prendere in prestito i numeri di un altro. Un contatore si ferma a 1048576 e da lì indica almeno quel numero.
  • observed - i canali intercettati ma lasciati deliberatamente reali, come le attese su oggetti e i timer multimediali. Una categoria a sé, perché non vengano mai letti come sostituiti.
  • uncovered - i canali che l'applicazione ha richiesto e la sessione non ha coperto. È ciò che trasforma un verdetto in in parte.
  • not fully cleaned up - tutto ciò che la pulizia non ha potuto rimuovere. Assente in una chiusura pulita, che è il caso normale.

chrono calc - opzioni

Niente linguaggio naturale: ogni opzione è un passo, e l'ordine delle opzioni è l'ordine dei passi. Il risultato dopo ogni passo viene stampato, così un passo sbagliato è visibile invece di restare sepolto.

OpzioneChe cosa fa
--base today|now|<moment> Da dove partire, today per impostazione predefinita. Risolto nel fuso della sessione. Un giorno impossibile come 2025-02-31 viene rifiutato, mai normalizzato in silenzio al mese successivo.
--base-utc <moment> Come --base, ma l'inizio è un istante in UTC, con una Z finale facoltativa, invece di una lettura dell'orologio da parete nel fuso della sessione.
--shift ±N<unit> Ripetibile. Il segno è obbligatorio. Unità: s m h d w mo q y bd, o i loro nomi estesi. m sono i minuti, mo i mesi. Mesi, trimestri e anni si ripiegano sulla data di calendario con un limite, quindi un mese dopo il 31 gennaio è la fine di febbraio, non un numero fisso di tick. bd (giorni lavorativi) richiede --calendar.
--set-time HH:MM:SSImposta l'ora del giorno sul risultato corrente.
--snap <target> Salta a un confine di periodo: som eom soq eoq soy eoy (inizio o fine di mese, trimestre, anno). Un inizio è il primo giorno alle 00:00:00, una fine l'ultimo giorno alle 23:59:59.
--nearest nbd|pbd Il giorno lavorativo più vicino in avanti o indietro, compreso il giorno corrente quando lo è già. Richiede --calendar.
--to-zone +HH:MM Un passo: riesprime lo stesso istante in un altro scostamento fisso. L'istante è conservato, quindi il valore epoch non si muove e cambiano solo i campi civili. Da non confondere con --zone.
--zone +HH:MM Il fuso della sessione, usato per risolvere today e now e per rendere il risultato. Senza l'opzione, il fuso dell'host.
--calendar us-banking|us-federal|pl Carica un calendario dei festivi. Aggiunge giorno lavorativo e festivo ai metadati e abilita bd e --nearest. I due calendari americani differiscono nel modo in cui osservano un festivo che cade nel fine settimana, ed è esattamente il tipo di errore di un giorno che un test deve trovare. Ogni calendario risponde per un intervallo di anni: pl dal 2002, us-federal dal 1960 e us-banking dal 2008. Un passo in giorni lavorativi che raggiunge un giorno precedente viene rifiutato con il codice 1, e una data precedente viene mostrata come non giudicata. Quando i giorni festivi di un calendario sono stati verificati rispetto alla legge più di un anno fa, un giorno successivo che ha giudicato porta il segno calendar_outdated, perché potrebbe mancare una festività più recente.
--preset <id> --param id=value Un momento con nome da presets/<id>.json, con i suoi parametri compilati. Esclusivo rispetto alle opzioni di passo e a --analyze, e si combina con --calendar, --zone e --format.
--analyze <date> Rilegge una data incollata e dice che cos'è. Un 04/08 ambiguo viene mostrato in entrambe le letture, americana e polacca, invece di essere indovinato - quell'ambiguità è una vera fonte di segnalazioni di bug sbagliate.
--format <mask> Stampa il risultato anche nella tua maschera, in modo che corrisponda al formato dell'applicazione testata: yyyy-MM-dd HH:mm:ss. I token distinguono maiuscole e minuscole nel senso di .NET e Java - M è il mese, m il minuto.
--json Output per le macchine (chronomock.calc/1) per qualsiasi cosa sopra, così una pipeline può calcolare una data e restituirla direttamente a chrono run.
# Ultimo giorno lavorativo del trimestre, calendario bancario americano
chrono calc --base today --snap eoq --nearest pbd --calendar us-banking

chrono calc - codici di uscita

Una tabella a parte, più piccola: il calcolatore non ha un verdetto di copertura da riferire.

CodiceSignificato
0calcolato
1errore d'uso - un'opzione errata, una data impossibile, un overflow di intervallo o un file di calendario senza alcun giorno lavorativo
5il passo o l'unità non è incluso in questa versione, oppure il passo richiede un calendario che non hai passato. Separato di proposito da un errore d'uso, perché uno script possa distinguere «non ancora» da «sbagliato»

Avanti