Reference příkazového řádku
Všechny přepínače obou příkazů, obě tabulky návratových kódů a jak číst to, co se vrátí. Vyprávěcí verze s odůvodněním je na stránce CLI a CI.
Dva příkazy
chrono run spustí aplikaci v jiném datu a čase.
chrono calc vypočítá datum a řekne, čím je zajímavé.
Sdílejí jednu gramatiku kroků, takže posun zapsaný pro jeden znamená totéž u druhého.
chrono version odpovídá na třetí, mnohem menší otázku: o které sestavení jde,
které z obou jader je spustitelný soubor a jakou verzi protokolu používá. Jeden řádek na stdout,
aby ho skript mohl zachytit.
chrono license odpovídá na čtvrtou: pod jakou licencí je toto sestavení šířeno,
prohlášení o záruce a komponenty třetích stran, které jsou do něj zalinkované. Říká také,
kde na disku najdete plné znění licence a upozornění k součástem třetích stran, nebo přizná,
že spuštěná kopie je vedle sebe nemá. --components vypíše každou přibalenou
komponentu s její verzí místo souhrnu.
chrono presets vypíše katalog presetů tak, jak ho čte --preset:
každý preset ve složce zapsaný slovy, která čte gramatika kalkulačky, a každý soubor, který
by odmítl, s důvodem. --json zapíše chronomock.presets/1 a
--dir určí jinou složku.
chrono run <target> [options] chrono calc [options] chrono version # chrono 0.4.0 (x64, protocol 1) chrono license # GPL-3.0-only a co je přibaleno chrono presets # katalog tak, jak ho čte --preset chrono --help # nápověda ke všem
chrono run - volby
| Přepínač | Co dělá |
|---|---|
--at <moment> |
Okamžik, ve kterém se začne, v pásmu sezení. Absolutní
(2038-01-19T03:14:07) nebo relativní s úvodním znaménkem
(+1d, -2h). Jednotky: s m h d w mo q y -
m jsou minuty a mo jsou měsíce. Bez tohoto
přepínače začínají hodiny sezení na skutečném aktuálním čase, takže samotné
--mode xN jednoduše spustí cíl rychleji. |
--zone +HH:MM |
Pásmo sezení: pásmo, ve kterém je okamžik zapsán a které hlásí volání místního času v cíli. Pevný posun, bez letního času. Bez něj pásmo samotného hostitele. |
--mode flow|frozen|xN |
flow běží skutečnou rychlostí, frozen drží hodiny na místě,
xN je pustí N-krát rychleji (x60 promění hodinu v minutu,
x1440 den). |
--scale-duration |
Zrychlit i osu uplynulého času: čítače tiků, čas přerušení, uspání a časovače. Čekání na objekty se počítají a zachovávají svou skutečnou délku. Ve výchozím stavu vypnuto, protože nástěnné hodiny a stopky jsou různé otázky. Časovač nebo zpoždění nastavené na konkrétní datum a čas sleduje hodiny sezení s touto volbou i bez ní. |
--scale-qpc |
Škáluje i čítač s vysokým rozlišením, ze kterého čtou uplynulý čas Python 3.13+
monotonic, .NET Stopwatch a Java nanoTime.
Ve výchozím stavu vypnuto: aplikace, která podle toho čítače měří vykreslování, může
vypadat zkresleně. |
--ticks N |
Ukončí sezení po N tepech, každý trvá jednu skutečnou vteřinu, a ohlásí výsledek. Bez něj zůstává nástroj připojený, dokud neskončí cíl a každý jím spuštěný program, který běží na hodinách sezení - spouštěč, který skončí okamžitě, nechává sezení aplikaci, kterou spustil. |
--timeout <s> |
Po tolika vteřinách to vzdá a skončí s kódem 6, pro pipeline, která nesmí viset. Nezávisle na tomto přepínači se jádro, které 15 sekund nic neřekne, zastaví a také skončí s kódem 6 - v obou případech je běh přerušen, takže nemá verdikt. |
--args "..." |
Argumenty pro cíl jako jeden řetězec, rozdělené podle stejného pravidla, jaké používá
Windows - takže argument obsahující mezery přežije. U cíle Chromium jsou
--user-data-dir a --remote-debugging-port odmítnuty, ne
přepsány: sezení potřebuje vlastní izolovaný profil a tiše běžet na vašem skutečném profilu
prohlížeče je jediná věc, která se nesmí stát. |
--cwd <dir> |
Spustí cíl v tomto adresáři. Bez něj cíl zdědí náš, což dělal každý běh, než tento
přepínač vznikl. Prázdná hodnota je chyba použití, ne „žádný adresář“ - chybějící a
prázdné jsou různé věci a Windows lze předat jen chybějící. Adresář, který neexistuje,
zastaví sezení s target.cwd_missing dřív, než se cokoli spustí, místo aby se
to později projevilo jako cíl, který se nespustí. |
--preset <id> |
Převezme okamžik a rychlost z presets/<id>.json. Vylučuje se s
--at, --mode a --scale-duration, protože preset je
pak jediným zdrojem obojího. |
--param id=value |
Vyplní parametr presetu. Lze opakovat, vyžaduje --preset. Pouze u
run se počáteční datum zkušební doby ve výchozím stavu bere z data vytvoření
spustitelného souboru cíle, takže preset zkušební doby počítá ode dne, kdy byla aplikace
nainstalována, aniž byste to zadávali. |
--set-after T:M |
V tepu T změní rychlost na M. Za běhu je násobitel alespoň 1 - zastavení hodin uprostřed sezení se zde nenabízí. |
--jump-after T:moment |
V tepu T skočí hodinami na daný okamžik, absolutní nebo relativní, v pásmu sezení. |
--force |
Ponechá sezení, i když úvodní verdikt říká, že náhrada času nezabrala - ve výchozím stavu se cíl místo toho zastaví, protože sezení, které nic neprokázalo, je horší než žádné sezení. Verdikt se nemění a návratový kód také ne. Rozhoduje to jen o tom, zda cíl běží dál. |
--no-embedded |
Nechá webové stránky uvnitř aplikace (WebView2, Qt WebEngine) na skutečných hodinách a neotevře žádný ladicí port. Bez něj sezení požádá takový engine, aby otevřel místní port, a jeho stránky přes něj přepne na hodiny sezení - dokud je port otevřený, může ho kterýkoli jiný program na tomto počítači použít k tomu, aby se k těm stránkám dostal. |
--elevated-embedded |
Pro aplikaci spuštěnou jako správce, z Chrono Mock, který běží také jako správce.
WebView2 u takové aplikace ignoruje nastavení, kterým se sezení dostává k jejím
stránkám, takže sezení po dobu svého trvání zapíše do registru počítače jednu hodnotu
(HKLM, pojmenovanou podle .exe aplikace) a na konci ji odstraní. Dokud aplikace běží,
může se k jejím stránkám přes port dostat kterýkoli jiný program na tomto počítači a
aplikace má práva správce. Ne s --no-embedded. |
--keep-background-timers |
Spustí webový engine - prohlížeč aplikace Chromium nebo Electron, nebo engine uvnitř
aplikace - s vypnutým zpomalováním časovačů ve skrytých oknech, takže minimalizované
okno zachová rychlost sezení. Aplikace pak pracuje plnou rychlostí i tehdy, když je
skrytá. Aplikace spuštěná jako správce přes --elevated-embedded ji
nedostane. |
--dry-run |
Vypíše, jaké by sezení bylo, a nic nespustí: vyřešený okamžik a pásmo a odkud
pocházejí, čím preset vyplnil jednotlivé parametry, argumenty po rozdělení a který ze
dvou mechanismů by cíl použil. Nespustí se žádný proces a nezapíše se žádný soubor,
včetně toho, který pojmenovává --report. Skončí kódem 0 pro proveditelný
plán a 2 pro cíl, který neexistuje, což je kód, který pro stejné zjištění vrací
skutečný běh. Plán nemá verdikt a říká to - verdikt má jen skutečné sezení. S
--json je plán datem, včetně session.elevated_embedded a
session.elevated_embedded_value, tedy názvu souboru, podle kterého by se
pojmenovala hodnota v registru, když se volba vztahuje na cíl .exe, jinak
null. Název tam není příslib zápisu: sezení hodnotu zapíše, jen když sám Chrono Mock
běží jako správce. |
--report <path> |
Zapíše zprávu pro lidi do souboru. Verdikt jiný než funguje začíná tento soubor bannerem o nespolehlivých důkazech, protože důkaz, který skrývá vlastní pochybnost, je horší než žádný. Tento banner dostane i sezení s verdiktem funguje, když aplikace nepřečetla žádné z hodin, které sezení nahrazuje, nebo když jde o program v Go, k jehož nástěnným hodinám Chrono Mock nedosáhne. Soubor také pojmenuje samotný běh: verzi, čas spuštění, cíl, jeho složku a přepínače. |
--report-args |
Spolu s --report zapíše do toho souboru i argumenty cíle, doslova. Ve výchozím stavu vypnuto, protože argument může obsahovat heslo - soubor pak uvede jen jejich počet. |
--json |
Vypíše sezení jako strojově čitelné záznamy místo zprávy - stejný proud, který spotřebovává samotné okno. Vlastní výstup konzolové aplikace jde na standardní chybový výstup, takže standardní výstup obsahuje záznamy a nic jiného. Aplikace, která ještě běží, když sezení skončí, tam dál zapisuje, takže cokoli čte standardní chybový výstup až do konce, na ni čeká, a běh to oznámí. |
chrono run - návratové kódy
Návratový kód je verdikt sezení, ne to, co vrátila aplikace. Vlastní návratový kód aplikace se hlásí zvlášť, ve zprávě a v datech sezení - proč je to uděláno takto, vysvětluje stránka CLI a CI.
| Kód | Význam |
|---|---|
| 0 | funguje - každý proces, který četl čas, viděl hodiny sezení |
| 10 | funguje částečně - některé kanály pokryté, jiné ne |
| 11 | nefunguje - náhrada času se nedostala ke klíčovým kanálům |
| 4 | neurčeno - pokrytí se nepodařilo zjistit. Upřímné „nedokážu říct“, nikdy předstíraný úspěch |
| 12 | cíl zmizel hned po injektáži a nezanechal nic, co by běželo na hodinách sezení, což naznačuje aplikaci s jedinou instancí, která předává řízení už běžící kopii, nebo předání programu, do kterého sezení nemohlo vstoupit, obvykle s opačnou bitovostí. Cíl, který spustí aplikaci a skončí, je spouštěč a sezení pokračuje pro aplikaci |
| 1 | chyba použití - špatný přepínač, špatný výraz nebo preset, který tento příkaz nepřijme |
| 2 | cíl se nepodařilo spustit nebo do něj injektovat |
| 3 | vnitřní chyba - jádro se nepodařilo spustit, narazilo na nečekaný stav, nebo se zastavilo dřív, než sezení uzavřelo (bez ohledu na vlastní návratový kód cíle). Takový běh nemá verdikt |
| 5 | operace není v tomto vydání sestavena - například preset, jehož okamžik potřebuje kalendář, který run zatím nedokáže načíst. Záměrně odlišné od chyby použití: požádali jste o něco, co zatím neexistuje, ne o něco špatného |
| 6 | běh byl přerušen - vypršel --timeout, nebo jádro přestalo na 15 sekund odpovídat a bylo zastaveno. Není to verdikt: sezení bylo přerušeno, takže nic o cíli neprokazuje ani jedním směrem |
| 7 | už běží jiné sezení - vždy jen jedno sezení naráz. Stačí to zkusit znovu, až skončí |
| 8 | sezení došlo k verdiktu, ale jeho důkaz není v souboru, který určuje --report - disk byl plný, nebo jiný program držel starý soubor otevřený, a ten pak zůstane beze změny. Verdikt je dál ve zprávě, kterou příkaz vypíše |
Jak číst zprávu
Bez --json sezení končí prostou zprávou. Každý řádek je buď fakt, který sezení
pozorovalo, nebo chybí - nic se nedoplňuje věrohodnou výchozí hodnotou.
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 - verdikt celé rodiny přes rodičovský a všechny podřízené procesy, s počtem procesů. Právě toto číslo nese návratový kód.
- exited - vlastní návratový kód aplikace, a to jen když se zavřela
sama. Běh omezený
--ticksnechává cíl běžet, sezení Chromium je takové, které nástroj zavírá sám, a sezení, které se nikdy nespustilo, takový kód nemá - řádek pak chybí, místo aby ukazoval vymyšlenou nulu. Kód pádu přichází jako velké záporné číslo, proto dostává i hexadecimální podobu. - covered - kanály, ke kterým se náhrada času dostala, s počtem skutečných volání každého, po procesech. Počty se mezi procesy nikdy nesčítají: audit jednoho procesu si nesmí půjčovat čísla jiného. Čítač se zastaví na 1048576 a pak ukazuje nejméně tolik.
- observed - kanály zachycené, ale záměrně ponechané skutečné, například čekání na objekty a multimediální časovače. Mají vlastní kategorii, aby se nikdy nečetly jako nahrazené.
- uncovered - kanály, na které se aplikace zeptala a sezení je nepokrylo. To mění verdikt na částečný.
- not fully cleaned up - cokoli, co úklid nedokázal odstranit. Při čistém konci, tedy v běžném případě, chybí.
chrono calc - volby
Žádný přirozený jazyk: každý přepínač je jeden krok a pořadí přepínačů je pořadí kroků. Výsledek po každém kroku se vypíše, takže špatný krok je vidět, ne zasypaný.
| Přepínač | Co dělá |
|---|---|
--base today|now|<moment> |
Kde začít, výchozí je today. Vyhodnocuje se v pásmu sezení. Nemožný den,
například 2025-02-31, se odmítne, nikdy se tiše nepřevede na další
měsíc. |
--base-utc <moment> |
Jako --base, ale začátek je okamžik v UTC s volitelným koncovým
Z, ne údaj nástěnných hodin v pásmu sezení. |
--shift ±N<unit> |
Lze opakovat. Znaménko je povinné. Jednotky: s m h d w mo q y bd nebo jejich
plné názvy. m jsou minuty, mo jsou
měsíce. Měsíce, čtvrtletí a roky se promítají na kalendářní datum s oříznutím,
takže měsíc po 31. lednu je konec února, ne pevný počet ticků. bd (pracovní
dny) vyžaduje --calendar. |
--set-time HH:MM:SS | Nastaví čas dne na aktuálním výsledku. |
--snap <target> |
Skočí na hranici období: som eom soq eoq soy eoy (začátek nebo konec
měsíce, čtvrtletí, roku). Začátek je první den v 00:00:00, konec poslední den
v 23:59:59. |
--nearest nbd|pbd |
Nejbližší pracovní den dopředu nebo zpět, včetně aktuálního dne, pokud už pracovním je.
Vyžaduje --calendar. |
--to-zone +HH:MM |
Krok: vyjádří tentýž okamžik v jiném pevném posunu. Okamžik se zachová, takže
hodnota epochy se nehýbe a mění se jen občanská pole. Nezaměňovat s
--zone. |
--zone +HH:MM |
Pásmo sezení, používané k vyhodnocení today a now a k zobrazení
výsledku. Bez něj pásmo hostitele. |
--calendar us-banking|us-federal|pl |
Načte kalendář svátků. Přidá do metadat pracovní den a svátek a zapne
bd a --nearest. Oba americké kalendáře se liší tím, jak řeší
svátek připadající na víkend, což je přesně ten druh chyby o jeden den, který má test
odhalit. Každý kalendář odpovídá za rozsah let: pl od roku 2002,
us-federal od roku 1960 a us-banking od roku 2008. Krok v
pracovních dnech, který dosáhne dne před tímto rozsahem, je odmítnut s kódem 1 a datum
před ním je zobrazeno jako neposouzené. Pokud byly svátky kalendáře naposledy ověřeny
podle zákona před více než rokem, pozdější den, který posoudil, nese značku
calendar_outdated, protože může chybět novější svátek. |
--preset <id> --param id=value |
Pojmenovaný okamžik z presets/<id>.json s vyplněnými parametry.
Vylučuje se s přepínači kroků a s --analyze a kombinuje se s
--calendar, --zone a --format. |
--analyze <date> |
Přečte vložené datum zpět a řekne, co to je. Nejednoznačné 04/08 se ukáže
v obou čteních, americkém i polském, místo aby se hádalo - tato
nejednoznačnost je skutečným zdrojem chybných hlášení chyb. |
--format <mask> |
Vypíše výsledek i ve vaší vlastní masce, aby odpovídal formátu testované aplikace:
yyyy-MM-dd HH:mm:ss. Tokeny rozlišují velikost písmen ve smyslu .NET a Javy -
M je měsíc, m je minuta. |
--json |
Strojový výstup (chronomock.calc/1) pro cokoli z výše uvedeného, aby
pipeline mohla vypočítat datum a rovnou ho předat zpět do chrono run. |
# Poslední pracovní den čtvrtletí, americký bankovní kalendář chrono calc --base today --snap eoq --nearest pbd --calendar us-banking
chrono calc - návratové kódy
Samostatná, menší tabulka: kalkulačka nemá verdikt o pokrytí, který by hlásila.
| Kód | Význam |
|---|---|
| 0 | vypočteno |
| 1 | chyba použití - špatný přepínač, nemožné datum, přetečení rozsahu nebo soubor kalendáře, ve kterém není žádný pracovní den |
| 5 | krok nebo jednotka není v tomto vydání sestavena, nebo krok potřebuje kalendář, který jste nezadali. Záměrně oddělené od chyby použití, aby skript dokázal rozlišit „ještě ne“ od „špatně“ |