Datumstests in der Pipeline
Das Fenster dient zum Ausprobieren. Dies ist die andere Hälfte: ein Kommandozeilen-Build von etwa 2,4 MB ohne Laufzeitumgebung, dessen Exit-Code das Abdeckungsurteil ist und nicht der Code des Zielprogramms.
Der Exit-Code ist das Urteil
Diese Entwurfsentscheidung macht das Werkzeug skriptbar. Wenn eine Sitzung endet, beantwortet der Exit-Code „hat die Zeitersetzung gewirkt“ und nicht „was hat die Anwendung zurückgegeben“. Eine Pipeline kann also an einer Ersetzung scheitern, die stillschweigend nicht stattgefunden hat - und genau daran lohnt es sich zu scheitern, denn alles danach ist ein Test, der nichts bewiesen hat.
Der eigene Exit-Code des Ziels wird weiterhin gemeldet, in den Sitzungsdaten.
| Code | Bedeutung |
|---|---|
| 0 | funktioniert - jeder Prozess, der die Zeit las, sah die Sitzungsuhr |
| 10 | funktioniert teilweise - einige Kanäle abgedeckt, andere nicht |
| 11 | funktioniert nicht - die Ersetzung hat die wichtigen Kanäle nicht erreicht |
| 4 | unbestimmt - die Abdeckung ließ sich nicht feststellen |
| 1 | Aufruffehler - eine falsche Option oder ein falscher Ausdruck |
| 2 | das Ziel konnte nicht gestartet oder injiziert werden |
| 12 | das Ziel ist verschwunden, was auf eine Einzelinstanz-Anwendung hindeutet |
| 3 | interner 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 |
| 5 | die Operation ist in diesem Release nicht enthalten |
| 6 | der 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 |
| 7 | eine andere Sitzung läuft bereits - immer nur eine Sitzung zur Zeit. Es genügt, es nach ihrem Ende erneut zu versuchen |
| 8 | die 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 |
Alle Optionen beider Befehle und dieselbe Tabelle für den Rechner stehen in der Kommandozeilen-Referenz.
Begrenzte Läufe
Eine Pipeline kann nicht darauf warten, dass ein Mensch eine Desktop-Anwendung schließt.
--ticks N beendet die Sitzung nach N Herzschlägen - je einer realen Sekunde - und
meldet, was bis dahin gefunden wurde. Die Abdeckung steht ohnehin in den ersten Momenten des
Prozesses fest, deshalb genügt meist eine kurze Grenze.
# Zehn Sekunden, dann anhalten und berichten chrono run ".\build\test.exe" --preset year-rollover --ticks 10 --report evidence.txt
Maschinenausgabe und Nachweise
--jsongibt die Sitzung als maschinenlesbare Datensätze aus statt als Bericht für Menschen - dieselben Fakten, einschließlich der Abdeckung je Kanal.--report <path>schreibt den Bericht für Menschen in eine Datei, die sich als Build-Artefakt eignet. Hat eine Sitzung ein anderes Urteil als funktioniert, steht am Anfang dieser Datei ein Hinweis auf unzuverlässige Nachweise, statt dass die Einschränkung unten untergeht.- Auch der Rechner versteht
--json, sodass eine Pipeline das benötigte Datum berechnen und zurückspeisen kann.
# Das Datum berechnen, dann damit ausführen chrono calc --base today --snap eom --json chrono run ".\build\test.exe" --preset month-end --ticks 10 --json
Ein Schritt, ungefähr so
- name: Month-end behaviour
shell: pwsh
run: |
.\chrono.exe run ".\build\test.exe" --preset month-end --ticks 10 --report evidence.txt
# ein Exit-Code ungleich null heißt: die Ersetzung hat nicht gegriffen, der
# Test danach hätte also nichts bewiesen
- name: Keep the evidence
uses: actions/upload-artifact@v7
with:
name: chrono-evidence
path: evidence.txt
Zwei ehrliche Einschränkungen zu Runnern
- Es braucht einen Windows-Runner. Es gibt keinen Linux- oder macOS-Build, und es wird keinen geben - unter Linux deckt libfaketime das bereits ab.
- Virenschutz auf einem gehosteten Runner kann die Injektion blockieren. Die Zeit zu verschieben bedeutet, eine Bibliothek in den Zielprozess einzuschleusen - eine dokumentierte Windows-Technik, die auch Schadsoftware nutzt. Ein Runner, der sie blockiert, liefert einen Exit-Code, der das sagt, statt eines falschen Bestehens - aber man sollte es herausfinden, bevor man sich darauf verlässt.
Aus demselben Grund läuft die End-to-End-Suite dieses Projekts auf echten Rechnern und nicht auf einem gehosteten Runner. Die Continuous Integration baut und testet alles per Unit-Tests, und die Ersetzung selbst wird vor einem Release von Hand an echten Anwendungen geprüft, sowohl in 32-Bit- als auch in 64-Bit-Builds.