Chrono Mock
SpracheDeutsch

Kommandozeilen-Referenz

Jede Option beider Befehle, beide Exit-Code-Tabellen und wie man liest, was zurückkommt. Die erzählende Fassung mit der Begründung steht auf der Seite CLI und CI.

Zwei Befehle

chrono run startet eine Anwendung zu einem anderen Datum und einer anderen Uhrzeit. chrono calc berechnet ein Datum und sagt, was daran interessant ist. Beide teilen eine Schrittgrammatik, eine für den einen geschriebene Verschiebung bedeutet also im anderen dasselbe.

chrono version beantwortet eine dritte, viel kleinere Frage: welcher Build das ist, welcher der beiden Kerne die ausführbare Datei ist und welche Protokollversion sie spricht. Eine Zeile auf stdout, sodass ein Skript sie abgreifen kann.

chrono license beantwortet die vierte: unter welcher Lizenz dieser Build vertrieben wird, den Gewährleistungsausschluss und die Komponenten Dritter, die eingebunden sind. Außerdem nennt es, wo auf dem Datenträger der volle Lizenztext und die Hinweise zu Komponenten Dritter liegen, oder gibt zu, dass die ausgeführte Kopie sie nicht neben sich hat. --components listet jede mitgelieferte Komponente mit ihrer Version auf, statt nur eine Zusammenfassung zu geben.

chrono presets listet den Szenarienkatalog so auf, wie --preset ihn liest: jedes Szenario im Ordner, in den Worten geschrieben, die die Grammatik des Rechners liest, und jede Datei, die es ablehnen würde, mit dem Grund. --json schreibt chronomock.presets/1, und --dir nennt einen anderen Ordner.

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        # der Katalog, wie --preset ihn liest
chrono --help          # usage for all of them

chrono run - Optionen

OptionWas sie tut
--at <moment> Der Startzeitpunkt, in der Sitzungszone. Absolut (2038-01-19T03:14:07) oder relativ mit führendem Vorzeichen (+1d, -2h). Einheiten: s m h d w mo q y - m sind Minuten und mo Monate. Ohne diese Option startet die Sitzungsuhr mit der echten aktuellen Zeit, sodass --mode xN allein das Ziel einfach schneller laufen lässt.
--zone +HH:MM Die Sitzungszone: die Zone, in der der Zeitpunkt geschrieben ist und die die Ortszeit-Aufrufe des Ziels melden. Ein fester Offset, ohne Sommerzeit. Ohne Angabe die eigene Zone des Hosts.
--mode flow|frozen|xN flow läuft in Echtzeit, frozen hält die Uhr an, xN lässt sie N-mal schneller laufen (x60 macht aus einer Stunde eine Minute, x1440 aus einem Tag).
--scale-duration Auch die Achse der verstrichenen Zeit beschleunigen: Tick-Zähler, Interrupt-Zeit, Pausen und Timer. Wartevorgänge auf Objekte werden gezählt und behalten ihre echte Länge. Standardmäßig aus, weil eine Wanduhr und eine Stoppuhr verschiedene Fragen sind. Ein Timer oder eine Verzögerung auf ein bestimmtes Datum mit Uhrzeit folgt der Sitzungsuhr mit und ohne diese Option.
--scale-qpc Skaliert zusätzlich den hochauflösenden Zähler, aus dem Python 3.13+ monotonic, .NET Stopwatch und Java nanoTime die verstrichene Zeit lesen. Standardmäßig aus: Eine Anwendung, die ihr Rendering an diesem Zähler misst, kann verzerrt aussehen.
--ticks N Beendet die Sitzung nach N Herzschlägen, je einer realen Sekunde, und berichtet. Ohne diese Option bleibt das Werkzeug angehängt, bis das Ziel und jedes von ihm gestartete Programm, das auf der Sitzungsuhr läuft, beendet ist - ein Launcher, der sofort endet, überlässt die Sitzung der Anwendung, die er gestartet hat.
--timeout <s> Gibt nach so vielen Sekunden auf und endet mit 6, für eine Pipeline, die nicht hängen darf. Unabhängig von dieser Option wird ein Kern, der 15 Sekunden schweigt, angehalten und endet ebenfalls mit 6 - in beiden Fällen wurde der Lauf abgebrochen und trägt daher kein Urteil.
--args "..." Argumente für das Ziel, als ein einziger String, getrennt nach derselben Regel, die Windows verwendet - ein Argument mit Leerzeichen übersteht das also. Für ein Chromium-Ziel werden --user-data-dir und --remote-debugging-port abgelehnt, nicht überschrieben: Die Sitzung braucht ihr eigenes, isoliertes Profil, und der stille Start mit Ihrem echten Browserprofil ist das Einzige, was nicht passieren darf.
--cwd <dir> Startet das Ziel in diesem Verzeichnis. Ohne Angabe erbt das Ziel unseres, wie es jeder Lauf tat, bevor es diese Option gab. Ein leerer Wert ist ein Aufruffehler und nicht „kein Verzeichnis“ - fehlend und leer sind verschiedene Dinge, und nur fehlend kann Windows übergeben werden. Ein Verzeichnis, das nicht existiert, stoppt die Sitzung mit target.cwd_missing, bevor irgendetwas gestartet wird, statt später als ein Ziel aufzufallen, das nicht starten wollte.
--preset <id> Übernimmt Zeitpunkt und Geschwindigkeit aus presets/<id>.json. Schließt sich mit --at, --mode und --scale-duration aus, da das Szenario dann die einzige Quelle von beidem ist.
--param id=value Füllt einen Szenario-Parameter. Wiederholbar, erfordert --preset. Nur bei run ist das Startdatum einer Testversion standardmäßig das eigene Erstellungsdatum der Ziel-Programmdatei, sodass ein Testversions-Szenario ab dem Tag zählt, an dem die Anwendung installiert wurde, ohne dass Sie es eintippen.
--set-after T:M Ändert beim Herzschlag T die Geschwindigkeit auf M. Im laufenden Betrieb ist der Faktor mindestens 1 - Einfrieren mitten in der Sitzung wird hier nicht angeboten.
--jump-after T:moment Springt beim Herzschlag T mit der Uhr zu diesem Zeitpunkt, absolut oder relativ, in der Sitzungszone.
--force Behält die Sitzung auch dann, wenn das Anfangsurteil sagt, dass die Ersetzung nicht gewirkt hat - standardmäßig wird das Ziel stattdessen angehalten, weil eine Sitzung, die nichts bewiesen hat, schlimmer ist als keine. Das Urteil ändert sich nicht, und der Exit-Code auch nicht. Das entscheidet nur, ob das Ziel weiterläuft.
--no-embedded Lässt die Webseiten innerhalb der Anwendung (WebView2, Qt WebEngine) auf der echten Uhr und öffnet keinen Debugging-Port. Ohne die Option bittet die Sitzung eine solche Engine, einen lokalen Port zu öffnen, und stellt ihre Seiten darüber auf die Sitzungsuhr - solange der Port offen ist, kann jedes andere Programm auf diesem Rechner ihn nutzen, um diese Seiten zu erreichen.
--elevated-embedded Für eine Anwendung, die als Administrator läuft, aus einem Chrono Mock, das ebenfalls als Administrator läuft. WebView2 ignoriert für eine solche Anwendung die Einstellung, über die die Sitzung ihre Seiten erreicht, daher schreibt die Sitzung für ihre Dauer einen Wert in die Registrierung des Rechners (HKLM, benannt nach der .exe der Anwendung) und entfernt ihn am Ende. Solange die Anwendung läuft, kann jedes andere Programm auf diesem Rechner ihre Seiten über den Port erreichen, und die Anwendung hat Administratorrechte. Nicht zusammen mit --no-embedded.
--keep-background-timers Startet die Web-Engine - den Browser einer Chromium- oder Electron-Anwendung oder die Engine innerhalb einer Anwendung - mit ausgeschalteter Drosselung der Timer in verborgenen Fenstern, sodass ein minimiertes Fenster die Sitzungsgeschwindigkeit behält. Die Anwendung arbeitet dann auch im verborgenen Zustand mit voller Geschwindigkeit. Eine über --elevated-embedded als Administrator gestartete Anwendung bekommt sie nicht.
--dry-run Gibt aus, was die Sitzung wäre, und startet nichts: den aufgelösten Zeitpunkt und die Zone samt Herkunft, womit ein Szenario jeden Parameter gefüllt hat, die Argumente nach dem Aufteilen und welchen der beiden Mechanismen das Ziel nehmen würde. Es wird kein Prozess gestartet und keine Datei geschrieben, auch nicht die, die --report nennt. Es endet mit 0 bei einem ausführbaren Plan und mit 2 bei einem Ziel, das nicht da ist - dem Code, den ein echter Lauf für dieselbe Tatsache gibt. Ein Plan trägt kein Urteil und sagt das auch - nur eine echte Sitzung hat eines. Mit --json ist der Plan Daten, darunter session.elevated_embedded und session.elevated_embedded_value, der Dateiname, nach dem der Registrierungswert benannt würde, wenn die Option auf ein .exe-Ziel zutrifft, sonst null. Ein Name dort ist kein Versprechen, dass geschrieben wird: Die Sitzung schreibt den Wert nur, wenn Chrono Mock selbst als Administrator läuft.
--report <path> Schreibt den Bericht für Menschen in eine Datei. Ein anderes Urteil als funktioniert setzt einen Hinweis auf unzuverlässige Nachweise an den Anfang dieser Datei, denn ein Nachweis, der seinen eigenen Zweifel verbirgt, ist schlimmer als keiner. Diesen Hinweis bekommt auch eine Sitzung mit dem Urteil funktioniert, wenn die Anwendung keine der Uhren gelesen hat, die die Sitzung ersetzt, oder wenn sie ein Go-Programm ist, dessen Wanduhr Chrono Mock nicht erreicht. Die Datei nennt außerdem den Lauf selbst: die Version, den Startzeitpunkt, das Ziel, seinen Ordner und die Optionen.
--report-args Schreibt zusammen mit --report auch die Argumente des Ziels wörtlich in diese Datei. Standardmäßig aus, weil ein Argument ein Passwort enthalten kann - die Datei nennt dann nur ihre Anzahl.
--json Gibt die Sitzung als maschinenlesbare Datensätze aus statt als Bericht - derselbe Strom, den das Fenster selbst verarbeitet. Die eigene Ausgabe einer Konsolenanwendung geht an stderr, sodass stdout die Datensätze enthält und sonst nichts. Eine Anwendung, die beim Ende der Sitzung noch läuft, schreibt dort weiter, deshalb wartet alles, was stderr bis zum Ende liest, auf sie, und der Lauf sagt das.

chrono run - Exit-Codes

Der Exit-Code ist das Sitzungsurteil, nicht das, was die Anwendung zurückgab. Der eigene Exit-Code der Anwendung wird getrennt gemeldet, im Bericht und in den Sitzungsdaten - die Seite CLI und CI erklärt, warum es so herum ist.

CodeBedeutung
0funktioniert - jeder Prozess, der die Zeit las, sah die Sitzungsuhr
10funktioniert teilweise - einige Kanäle abgedeckt, andere nicht
11funktioniert nicht - die Ersetzung hat die wichtigen Kanäle nicht erreicht
4unbestimmt - die Abdeckung ließ sich nicht feststellen. Ein ehrliches „kann ich nicht sagen“, nie ein vorgetäuschtes Bestehen
12das Ziel verschwand gleich nach der Injektion und ließ nichts auf der Sitzungsuhr laufen, was auf eine Einzelinstanz-Anwendung hindeutet, die an eine bereits laufende Kopie übergibt, oder auf eine Übergabe an ein Programm, das die Sitzung nicht betreten konnte, meist eines der anderen Bitness. Ein Ziel, das die Anwendung startet und endet, ist ein Launcher, und die Sitzung läuft für die Anwendung weiter
1Aufruffehler - eine falsche Option, ein falscher Ausdruck oder ein Szenario, das dieser Befehl nicht annimmt
2das Ziel konnte nicht gestartet oder injiziert werden
3interner Fehler - die Engine konnte nicht starten, geriet in einen unerwarteten Zustand oder hielt an, bevor sie die Sitzung abschloss (gleich welchen Code sie selbst hatte). Ein solcher Lauf trägt kein Urteil
5die Operation ist in diesem Release nicht enthalten - zum Beispiel ein Szenario, dessen Zeitpunkt einen Kalender braucht, den run noch nicht laden kann. Bewusst verschieden von einem Aufruffehler: Sie haben nach etwas gefragt, das es noch nicht gibt, nicht nach etwas Falschem
6der Lauf wurde abgebrochen - --timeout ist abgelaufen, oder die Engine antwortete 15 Sekunden lang nicht und wurde angehalten. Das ist kein Urteil: Die Sitzung wurde unterbrochen und beweist daher weder in die eine noch in die andere Richtung etwas über das Ziel
7eine andere Sitzung läuft bereits - immer nur eine Sitzung zur Zeit. Es genügt, es nach ihrem Ende erneut zu versuchen
8die Sitzung kam zu einem Urteil, aber ihr Nachweis steht nicht in der Datei, die --report nennt - die Festplatte war voll, oder ein anderes Programm hielt die alte Datei offen, die dann unverändert bleibt. Das Urteil steht weiterhin im Bericht, den der Befehl ausgibt

Den Bericht lesen

Ohne --json endet die Sitzung in einem schlichten Bericht. Jede Zeile ist entweder eine Tatsache, die die Sitzung beobachtet hat, oder fehlt - nichts wird mit einem plausiblen Standardwert aufgefüllt.

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 - das Familienurteil über den Elternprozess und jeden Kindprozess, mit der Prozesszahl. Das ist die Zahl, die der Exit-Code trägt.
  • exited - der eigene Exit-Code der Anwendung, und nur dann, wenn sie sich selbst beendet hat. Ein mit --ticks begrenzter Lauf lässt das Ziel laufen, eine Chromium-Sitzung beendet das Werkzeug selbst, und eine Sitzung, die nie gestartet ist, hat keinen solchen Code - die Zeile fehlt dann, statt eine erfundene Null zu zeigen. Ein Absturzcode kommt als große negative Zahl an und erhält daher auch seine hexadezimale Form.
  • covered - Kanäle, die die Ersetzung erreicht hat, mit der Zahl der tatsächlichen Aufrufe je Prozess. Zahlen werden nie über Prozesse hinweg addiert: Die Prüfung eines Prozesses darf sich nicht die Zahlen eines anderen borgen. Ein Zähler bleibt bei 1048576 stehen und lautet dann mindestens so viele.
  • observed - Kanäle, die abgefangen, aber bewusst echt gelassen wurden, etwa Objekt-Waits und Multimedia-Timer. Ein eigener Behälter, damit sie nie als ersetzt gelesen werden.
  • uncovered - Kanäle, die die Anwendung abgefragt hat und die die Sitzung nicht abgedeckt hat. Das macht aus einem Urteil teilweise.
  • not fully cleaned up - alles, was das Aufräumen nicht entfernen konnte. Fehlt bei einem sauberen Ende, dem Normalfall.

chrono calc - Optionen

Keine natürliche Sprache: Jede Option ist ein Schritt, und die Reihenfolge der Optionen ist die Reihenfolge der Schritte. Das Ergebnis nach jedem Schritt wird ausgegeben, sodass ein falscher Schritt sichtbar ist, statt unterzugehen.

OptionWas sie tut
--base today|now|<moment> Wo es beginnt, standardmäßig today. Aufgelöst in der Sitzungszone. Ein unmöglicher Tag wie 2025-02-31 wird abgelehnt und nie stillschweigend auf den nächsten Monat normalisiert.
--base-utc <moment> Wie --base, aber der Start ist ein Zeitpunkt in UTC, mit optionalem abschließendem Z, und keine Wanduhrzeit in der Sitzungszone.
--shift ±N<unit> Wiederholbar. Das Vorzeichen ist Pflicht. Einheiten: s m h d w mo q y bd oder ihre vollen Namen. m sind Minuten, mo Monate. Monate, Quartale und Jahre werden mit Begrenzung auf das Kalenderdatum abgebildet, ein Monat nach dem 31. Januar ist also das Ende des Februars und keine feste Zahl von Ticks. bd (Werktage) braucht --calendar.
--set-time HH:MM:SSSetzt die Uhrzeit auf dem aktuellen Ergebnis.
--snap <target> Springt auf eine Periodengrenze: som eom soq eoq soy eoy (Anfang oder Ende von Monat, Quartal, Jahr). Ein Anfang ist der erste Tag um 00:00:00, ein Ende der letzte Tag um 23:59:59.
--nearest nbd|pbd Der nächste Werktag vorwärts oder rückwärts, einschließlich des aktuellen Tages, wenn er schon einer ist. Braucht --calendar.
--to-zone +HH:MM Ein Schritt: drückt denselben Zeitpunkt in einem anderen festen Offset aus. Der Zeitpunkt bleibt erhalten, der Epochenwert bewegt sich also nicht und nur die bürgerlichen Felder ändern sich. Nicht mit --zone zu verwechseln.
--zone +HH:MM Die Sitzungszone, mit der today und now aufgelöst und das Ergebnis dargestellt werden. Ohne Angabe die Zone des Hosts.
--calendar us-banking|us-federal|pl Lädt einen Feiertagskalender. Er ergänzt Werktag und Feiertag in den Metadaten und schaltet bd und --nearest frei. Die beiden amerikanischen Kalender unterscheiden sich darin, wie sie einen auf ein Wochenende fallenden Feiertag begehen, und genau das ist die Art Abweichung um einen Tag, die ein Test finden soll. Jeder Kalender gilt für einen Bereich von Jahren: pl ab 2002, us-federal ab 1960 und us-banking ab 2008. Ein Werktagsschritt, der einen Tag davor erreicht, wird mit Exit 1 abgelehnt, und ein Datum davor wird als nicht beurteilt angezeigt. Wurden die Feiertage eines Kalenders zuletzt vor mehr als einem Jahr gegen das Recht geprüft, trägt ein später beurteilter Tag die Markierung calendar_outdated, weil ein neuerer Feiertag fehlen kann.
--preset <id> --param id=value Ein benannter Zeitpunkt aus presets/<id>.json mit ausgefüllten Parametern. Schließt sich mit den Schritt-Optionen und mit --analyze aus und lässt sich mit --calendar, --zone und --format kombinieren.
--analyze <date> Liest ein eingefügtes Datum zurück und sagt, was es ist. Ein mehrdeutiges 04/08 wird in beiden Lesarten gezeigt, amerikanisch und polnisch, statt geraten zu werden - diese Mehrdeutigkeit ist eine echte Quelle falscher Fehlerberichte.
--format <mask> Gibt das Ergebnis zusätzlich in Ihrer eigenen Maske aus, damit es zum Format der getesteten Anwendung passt: yyyy-MM-dd HH:mm:ss. Die Token unterscheiden Groß- und Kleinschreibung im Sinne von .NET und Java - M ist Monat, m ist Minute.
--json Maschinenausgabe (chronomock.calc/1) für alles oben Genannte, damit eine Pipeline ein Datum berechnen und direkt in chrono run zurückgeben kann.
# Letzter Werktag des Quartals, amerikanischer Bankenkalender
chrono calc --base today --snap eoq --nearest pbd --calendar us-banking

chrono calc - Exit-Codes

Eine eigene, kleinere Tabelle: Der Rechner hat kein Abdeckungsurteil zu melden.

CodeBedeutung
0berechnet
1Aufruffehler - eine falsche Option, ein unmögliches Datum, ein Bereichsüberlauf oder eine Kalenderdatei ohne einen einzigen Werktag
5der Schritt oder die Einheit ist in diesem Release nicht enthalten, oder der Schritt braucht einen Kalender, den Sie nicht übergeben haben. Absichtlich von einem Aufruffehler getrennt, damit ein Skript „noch nicht“ von „falsch“ unterscheiden kann

Weiter