Dokumentacja wiersza poleceń
Wszystkie flagi obu komend, obie tabele kodów wyjścia i sposób czytania tego, co wraca. Wersja z uzasadnieniem, a nie samymi faktami, stoi na stronie CLI i CI.
Dwie komendy
chrono run uruchamia aplikację w innej dacie i godzinie.
chrono calc liczy datę i mówi, co w niej ciekawego. Obie mówią tą samą
gramatyką kroków, więc przesunięcie napisane dla jednej znaczy w drugiej to samo.
chrono version odpowiada na trzecie, dużo mniejsze pytanie: która to wersja,
którym z dwóch rdzeni jest ten plik i jaką wersję protokołu mówi. Jedna linia na
standardowym wyjściu, więc skrypt może ją przechwycić.
chrono license odpowiada na czwarte: na jakiej licencji jest ta wersja, jaka
jest klauzula braku gwarancji i jakie komponenty obce są w niej wkompilowane. Mówi też,
gdzie na dysku leży pełny tekst licencji i noty komponentów obcych, a gdy uruchomiona kopia
ich obok siebie nie ma, przyznaje to wprost. --components wypisuje każdy
dołączony komponent wraz z wersją zamiast podsumowania.
chrono presets wypisuje katalog presetów tak, jak czyta go
--preset: każdy preset z folderu, zapisany słowami, które czyta gramatyka
kalkulatora, oraz każdy plik, który zostałby odrzucony, wraz z powodem. --json
zapisuje chronomock.presets/1, a --dir wskazuje inny folder.
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 # katalog tak, jak czyta go --preset chrono --help # usage for all of them
chrono run - opcje
| Flaga | Co robi |
|---|---|
--at <moment> |
Moment, od którego zaczyna się sesja, w strefie sesji. Bezwzględny
(2038-01-19T03:14:07) albo względny z wiodącym znakiem
(+1d, -2h). Jednostki: s m h d w mo q y -
m to minuty, a mo miesiące. Bez tej flagi
zegar sesji startuje od realnego teraz, więc samo --mode xN po prostu
przyspiesza aplikację. |
--zone +HH:MM |
Strefa sesji: strefa, w której zapisany jest moment, i ta, którą raportują wywołania czasu lokalnego w celu. Stały offset, bez zmiany czasu. Bez flagi - strefa hosta. |
--mode flow|frozen|xN |
flow to tempo realne, frozen zatrzymuje zegar,
xN przyspiesza go N razy (x60 zamienia godzinę w minutę,
x1440 dobę). |
--scale-duration |
Przyspiesz także oś czasu trwania: liczniki taktów, czas przerwań, uśpienia i timery. Czekania na obiekty są liczone i zachowują prawdziwą długość. Domyślnie wyłączone, bo zegar ścienny i stoper to różne pytania. Timer albo opóźnienie nastawione na konkretną datę i godzinę podąża za zegarem sesji z tą flagą i bez niej. |
--scale-qpc |
Skaluje też licznik wysokiej rozdzielczości, z którego czytają czas miniony
monotonic w Pythonie 3.13+, Stopwatch w .NET i
nanoTime w Javie. Domyślnie wyłączone: aplikacja, która mierzy tym
licznikiem własne renderowanie, potrafi wyglądać na zniekształconą. |
--ticks N |
Kończy sesję po N biciach serca, każde po jednej realnej sekundzie, i raportuje. Bez tej flagi narzędzie zostaje przy sesji, dopóki działa cel albo którykolwiek uruchomiony przez niego program na zegarze sesji - launcher, który kończy się od razu, zostawia sesję uruchomionej przez siebie aplikacji. |
--timeout <s> |
Poddaje się po tylu sekundach i kończy kodem 6, dla potoku, który nie może wisieć. Niezależnie od tej flagi rdzeń, który milczy przez 15 sekund, zostaje zatrzymany i też daje kod 6 - w obu przypadkach przebieg został ucięty, więc nie niesie werdyktu. |
--args "..." |
Argumenty dla celu, jako jeden łańcuch, dzielony tą samą regułą, której używa
Windows - więc argument ze spacją przeżywa podróż. Dla celu Chromium
--user-data-dir i --remote-debugging-port są
odmawiane, nie nadpisywane: sesja potrzebuje własnego, odizolowanego
profilu, a ciche uruchomienie na twoim prawdziwym profilu przeglądarki to jedyna
rzecz, która stać się nie może. |
--cwd <katalog> |
Uruchamia cel w tym katalogu. Bez flagi cel dziedziczy nasz - tak działał każdy
przebieg, zanim ta flaga powstała. Pusta wartość to błąd użycia, a nie „brak
katalogu": brak i pustka to co innego, a tylko brak jest czymś, co Windows przyjmie.
Katalog, którego nie ma, zatrzymuje sesję z kluczem target.cwd_missing
jeszcze przed uruchomieniem czegokolwiek, zamiast wyjść później jako cel, który nie
chciał wystartować. |
--preset <id> |
Bierze moment i tempo z presets/<id>.json. Wyłączna wobec
--at, --mode i --scale-duration, bo preset
jest wtedy jedynym źródłem obu. |
--param id=value |
Wypełnia parametr presetu. Powtarzalna, wymaga --preset. Tylko w
run data startu wersji próbnej domyślnie bierze się z daty utworzenia
pliku celu, więc preset triala liczy od dnia instalacji aplikacji bez wpisywania
czegokolwiek. |
--set-after T:M |
Na biciu T zmienia tempo na M. W locie mnożnik wynosi co najmniej 1 - zamrażanie w trakcie sesji nie jest tu oferowane. |
--jump-after T:moment |
Na biciu T przeskakuje zegar na podany moment, bezwzględny albo względny, w strefie sesji. |
--force |
Prowadzi sesję nawet wtedy, gdy werdykt otwarcia mówi, że podmiana nie zadziałała - domyślnie cel jest wtedy zatrzymywany, bo sesja, która niczego nie dowodzi, jest gorsza niż jej brak. Werdykt się nie zmienia, kod wyjścia też nie. Ta flaga rozstrzyga wyłącznie, czy cel biegnie dalej. |
--no-embedded |
Zostawia strony internetowe wewnątrz aplikacji (WebView2, Qt WebEngine) na prawdziwym zegarze i nie otwiera portu diagnostycznego. Bez tej flagi sesja prosi taki silnik o otwarcie lokalnego portu i przez niego przenosi jego strony na zegar sesji - gdy port jest otwarty, każdy inny program na tym komputerze może go użyć, by dotrzeć do tych stron. |
--elevated-embedded |
Dla aplikacji uruchomionej jako administrator, z Chrono Mock uruchomionego również
jako administrator. WebView2 pomija dla takiej aplikacji ustawienie, przez które sesja
dociera do jej stron, więc sesja zapisuje na czas swojego trwania jedną wartość w
rejestrze maszyny (HKLM, nazwaną od pliku .exe aplikacji) i usuwa ją na końcu. Gdy
aplikacja działa, każdy inny program na tym komputerze może dotrzeć do jej stron przez
port, a aplikacja ma uprawnienia administratora. Nie z
--no-embedded. |
--keep-background-timers |
Uruchamia silnik webowy - przeglądarkę aplikacji Chromium lub Electron albo silnik
wewnątrz aplikacji - z wyłączonym spowalnianiem timerów w ukrytych oknach, więc
zminimalizowane okno zachowuje tempo sesji. Aplikacja pracuje wtedy pełnym tempem
także wtedy, gdy jest ukryta. Aplikacja uruchomiona jako administrator przez
--elevated-embedded go nie dostaje. |
--dry-run |
Wypisuje, czym byłaby sesja, i nie uruchamia niczego: rozwiązany moment i strefę
wraz z ich pochodzeniem, wartości, którymi preset wypełnił swoje parametry, argumenty
po podziale oraz to, który z dwóch mechanizmów objąłby cel. Nie powstaje żaden proces
ani żaden plik, także ten wskazany przez --report. Kończy 0 dla planu,
który da się wykonać, i 2 dla celu, którego nie ma - tym samym kodem, który za ten sam
fakt daje prawdziwy przebieg. Plan nie niesie werdyktu i mówi to wprost, bo werdykt ma
wyłącznie prawdziwa sesja. Z --json plan jest danymi, w tym
session.elevated_embedded i session.elevated_embedded_value,
czyli nazwą pliku, po której nazwano by wartość w rejestrze, gdy opcja dotyczy celu
.exe, a poza tym null. Nazwa tam nie jest obietnicą zapisu: sesja
zapisuje wartość tylko wtedy, gdy sam Chrono Mock działa jako administrator. |
--report <plik> |
Zapisuje czytelny raport do pliku. Werdykt inny niż works prowadzi taki plik banerem o nierzetelnym dowodzie, bo dowód, który przemilcza własną wątpliwość, jest gorszy niż brak dowodu. Ten baner dostaje też sesja z werdyktem works, gdy aplikacja nie przeczytała żadnego zegara, który sesja podmienia, albo gdy jest programem w Go, którego zegara ściennego Chrono Mock nie sięga. Plik nazywa też sam przebieg: wersję, czas startu, cel, jego katalog i flagi. |
--report-args |
Razem z --report wpisuje do tego pliku także argumenty celu, dosłownie. Domyślnie wyłączone, bo argument może zawierać hasło - plik podaje wtedy tylko, ile ich było. |
--json |
Wypisuje sesję jako rekordy maszynowe zamiast raportu - ten sam strumień, który konsumuje okno aplikacji. Wyjście samej aplikacji konsolowej trafia na standardowe wyjście błędów, więc na standardowym wyjściu są tylko rekordy. Aplikacja, która działa jeszcze po końcu sesji, pisze tam dalej, więc to, co czyta wyjście błędów do końca, czeka na nią, i przebieg mówi o tym wprost. |
chrono run - kody wyjścia
Kod wyjścia to werdykt sesji, a nie to, co zwróciła aplikacja. Własny kod wyjścia aplikacji jest raportowany osobno, w raporcie i w danych sesji - dlaczego akurat tak, wyjaśnia strona CLI i CI.
| Kod | Znaczenie |
|---|---|
| 0 | działa - każdy proces, który czytał czas, zobaczył zegar sesji |
| 10 | działa częściowo - część kanałów objęta, część nie |
| 11 | nie działa - podmiana nie dosięgła kluczowych kanałów |
| 4 | nieokreślony - nie dało się ustalić pokrycia. Uczciwe „nie wiem", nigdy udawane „działa" |
| 12 | cel zniknął zaraz po wstrzyknięciu i nie zostawił niczego na zegarze sesji, co wskazuje na aplikację jednoinstancyjną, która oddała robotę już działającej kopii, albo na przekazanie programowi, do którego sesja nie mogła wejść, zwykle o innej bitowości. Cel, który uruchamia aplikację i się kończy, to launcher - sesja idzie dalej za aplikacją |
| 1 | błąd użycia - zła flaga, złe wyrażenie albo preset, którego ta komenda nie przyjmuje |
| 2 | nie udało się uruchomić celu albo wstrzyknąć do niego biblioteki |
| 3 | błąd wewnętrzny - rdzeń nie wystartował, trafił na nieoczekiwany stan albo zakończył się, zanim zamknął sesję (bez względu na własny kod wyjścia). Taki przebieg nie niesie werdyktu |
| 5 | operacja niezbudowana w tym wydaniu - na przykład preset, którego moment wymaga kalendarza, a run nie umie go jeszcze wczytać. Celowo odróżnialne od błędu użycia: poprosiłeś o coś, czego jeszcze nie ma, a nie o coś złego |
| 6 | przebieg został ucięty - minął --timeout albo rdzeń przestał odpowiadać na 15 sekund i został zatrzymany. To nie jest werdykt: sesję przerwano, więc nie dowodzi ona niczego o celu w żadną stronę |
| 7 | inna sesja już działa - jedna sesja naraz. Wystarczy spróbować ponownie, gdy się zakończy |
| 8 | sesja doszła do werdyktu, ale jej dowodu nie ma w pliku wskazanym przez --report - dysk był pełny albo inny program trzymał otwarty stary plik, który wtedy zostaje bez zmian. Werdykt nadal stoi w raporcie, który wypisuje polecenie |
Jak czytać raport
Bez --json sesja kończy się zwykłym raportem. Każdy wiersz jest albo faktem,
który sesja zaobserwowała, albo go nie ma - nic nie jest dopisywane prawdopodobną wartością
domyślną.
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 - werdykt rodziny, czyli rodzica i wszystkich procesów potomnych, wraz z ich liczbą. To jest liczba, którą niesie kod wyjścia.
- exited - własny kod wyjścia aplikacji, i tylko wtedy, gdy
zamknęła się sama. Przebieg ograniczony przez
--tickszostawia cel działający, sesję Chromium narzędzie zamyka samo, a sesja, która nigdy nie wystartowała, takiego kodu nie ma - wtedy tego wiersza po prostu nie ma, zamiast zmyślonego zera. Kod awaryjny przychodzi jako duża liczba ujemna, więc dostaje też postać szesnastkową. - covered - kanały, które podmiana objęła, z liczbą realnych wywołań każdego, osobno per proces. Liczniki nigdy nie są sumowane między procesami: audyt jednego procesu nie może pożyczać liczb od drugiego. Licznik zatrzymuje się na 1048576 i wtedy pokazuje co najmniej tyle.
- observed - kanały podpięte, ale celowo zostawione prawdziwe, jak czekania na obiekty czy timery multimedialne. Mają własny kubełek, żeby nikt nie przeczytał ich jako podmienionych.
- uncovered - kanały, o które aplikacja pytała, a sesja ich nie objęła. To one zamieniają werdykt w częściowy.
- not fully cleaned up - to, czego sprzątanie nie zdołało usunąć. Przy czystym zakończeniu, czyli normalnie, tego wiersza nie ma.
chrono calc - opcje
Zero języka naturalnego: każda flaga to jeden krok, a kolejność flag to kolejność kroków. Wynik po każdym kroku jest wypisywany, więc zły krok widać, zamiast go zakopywać.
| Flaga | Co robi |
|---|---|
--base today|now|<moment> |
Punkt wyjścia, domyślnie today. Rozwiązywany w strefie sesji.
Niemożliwy dzień, taki jak 2025-02-31, jest odrzucany, a nie po cichu
normalizowany na następny miesiąc. |
--base-utc <moment> |
Jak --base, ale początek to chwila w UTC, z opcjonalnym końcowym
Z, a nie odczyt zegara ściennego w strefie sesji. |
--shift ±N<jednostka> |
Powtarzalna. Znak obowiązkowy. Jednostki: s m h d w mo q y bd albo
ich pełne nazwy. m to minuty, mo miesiące.
Miesiące, kwartały i lata składają się na datę cywilną z zaciskiem, więc miesiąc po
31 stycznia to koniec lutego, a nie stała liczba ticków. bd (dni
robocze) wymaga --calendar. |
--set-time HH:MM:SS | Ustawia porę dnia na bieżącym wyniku. |
--snap <cel> |
Skok do granicy okresu: som eom soq eoq soy eoy (początek albo koniec
miesiąca, kwartału, roku). Początek to pierwszy dzień o 00:00:00, koniec - ostatni o
23:59:59. |
--nearest nbd|pbd |
Najbliższy dzień roboczy naprzód albo wstecz, włącznie z bieżącym, jeśli już nim
jest. Wymaga --calendar. |
--to-zone +HH:MM |
Krok: wyraża tę samą chwilę w innym stałym offsecie. Chwila jest
zachowana, więc wartość epoch się nie rusza, przesuwają się tylko pola cywilne. Nie
mylić z --zone. |
--zone +HH:MM |
Strefa sesji, w której rozwiązywane są today i now i w
której renderowany jest wynik. Bez flagi - strefa hosta. |
--calendar us-banking|us-federal|pl |
Wczytuje kalendarz świąt. Dokłada do metadanych dzień roboczy i święto oraz włącza
bd i --nearest. Dwa kalendarze amerykańskie różnią się tym,
jak obserwują święto wypadające w weekend - czyli dokładnie tym błędem o jeden dzień,
który test ma znaleźć. Każdy kalendarz odpowiada za zakres lat: pl od
2002, us-federal od 1960 i us-banking od 2008. Krok w dniach
roboczych, który sięga dnia sprzed zakresu, jest odrzucany z kodem 1, a data sprzed
zakresu jest pokazana jako nieoceniona. Gdy święta kalendarza sprawdzono z prawem
ponad rok temu, późniejszy dzień, który ocenił, dostaje znacznik
calendar_outdated, bo może brakować nowszego święta. |
--preset <id> --param id=value |
Nazwany moment z presets/<id>.json, z wypełnionymi parametrami.
Wyłączna wobec flag kroków i wobec --analyze, komponuje się z
--calendar, --zone i --format. |
--analyze <data> |
Czyta wklejoną datę i mówi, co to jest. Niejednoznaczne 04/08
pokazywane jest w obu odczytach, amerykańskim i polskim, zamiast
zgadywane - ta niejednoznaczność to realne źródło błędnych zgłoszeń. |
--format <maska> |
Wypisuje wynik dodatkowo we własnej masce, żeby trafić w format testowanej
aplikacji: yyyy-MM-dd HH:mm:ss. Tokeny rozróżniają wielkość liter w
sensie .NET i Javy - M to miesiąc, m to
minuta. |
--json |
Wyjście maszynowe (chronomock.calc/1) dla każdego z powyższych, więc
potok może policzyć datę i podać ją z powrotem do chrono run. |
# Last business day of the quarter, American banking calendar chrono calc --base today --snap eoq --nearest pbd --calendar us-banking
chrono calc - kody wyjścia
Osobna, mniejsza tabela: kalkulator nie ma werdyktu pokrycia, o którym miałby meldować.
| Kod | Znaczenie |
|---|---|
| 0 | policzono |
| 1 | błąd użycia - zła flaga, niemożliwa data, przepełnienie zakresu albo plik kalendarza, w którym nie ma ani jednego dnia roboczego |
| 5 | krok albo jednostka niezbudowane w tym wydaniu, albo krok wymaga kalendarza, którego nie podałeś. Celowo oddzielone od błędu użycia, żeby skrypt odróżnił „jeszcze nie" od „źle" |