Testen und die git-Oracle
Pitmaster verwendet die kanonische git-Binärdatei als Oracle: Wenn git akzeptiert, was Pitmaster schreibt, und Pitmaster liest, was git schreibt, ist das Verhalten korrekt. Die Testinfrastruktur befindet sich im Repository Pitmaster. Das Composer-Paket enthält nur src/ und bin/pitmaster. Führe die folgenden Schritte daher nach composer install in einem Klon aus.
Testsuiten
| Befehl | Ausgeführte Tests | Benötigt git |
|---|---|---|
composer test:unit |
PHPUnit-unit-Suite: isolierte Komponententests |
Nein |
composer test:integration |
PHPUnit-integration-Suite: Pitmaster und git arbeiten am selben Repository |
Ja |
composer test:oracle |
bin/test-regression: alle Oracle-Szenarien |
Ja |
composer test |
PHPUnit (beide Suites) plus Oracle-Regressionstest | Ja |
./bin/verify-all |
composer verify: Support-Nachweise, Upstream-Abweichungen, Proof-Artefakt, Mutation Smoke, composer audit, PHPStan, Coding-Standards und composer test |
Ja |
CI führt die Unit-Suite mit mehreren PHP-Versionen aus, außerdem die Integrationssuite, die Oracle-Regression (PITMASTER_TEST_JOBS=4) sowie Prüfungen der Support-Nachweise und Upstream-Abweichungen.
Oracle-Szenarien
Jedes Szenario ist ein Verzeichnis unter scenarios/<category>/ (insgesamt 761: 156 für Pitmaster geschrieben und 605 aus anderen Git-Implementierungen übernommen):
scenarios/diff/diff-add-lines/
scenario.json # commands and expectations
setup.sh # builds the starting repository
oracle/ # outputs captured from git
scenario.json benennt den mit git auszuführenden Befehl, den entsprechenden Pitmaster-Befehl und die Ergebnisse, die übereinstimmen müssen:
{
"name": "diff-add-lines",
"category": "diff",
"operations": ["diff"],
"oracle_commands": { "diff": "git -c color.ui=never diff" },
"actual_commands": { "diff": "php \"{{ROOT}}/bin/pitmaster\" diff | perl -pe 's/\\e\\[[0-9;]*m//g'" },
"expectations": { "exact_match": ["diff"], "fsck_clean": true }
}
Bei einem Durchlauf wird das von setup.sh erstellte Repository kopiert. Oracle- und Pitmaster-Befehle werden auf getrennten Kopien ausgeführt, anschließend werden Ausgaben, Objekte, Refs und Log verglichen. fsck_clean verlangt außerdem, dass git fsck das von Pitmaster geschriebene Repository akzeptiert. Die Oracle-Ausgabe wird von git übernommen, wenn sie fehlt oder aktualisiert wird; andernfalls werden die eingecheckten oracle/-Dateien verwendet.
Ein Szenario deckt genau die Fälle ab, die seine Einrichtung erstellt. Die Diff-Szenarien vergleichen beispielsweise geänderte Dateien. Deshalb erkennen sie nicht die in Diff aufgeführten Unterschiede bei der Diff-Ausgabe für neue, gelöschte und binäre Dateien.
Mit Szenarien arbeiten
./bin/test-scenario <name> # oracle, actual, compare for one scenario
./bin/test-regression # all scenarios
./bin/test-regression --jobs 4 # in parallel (or PITMASTER_TEST_JOBS=4)
./bin/test-regression --category diff # one category
./bin/test-regression --fast # pass/fail only, no reports
./bin/oracle <name> # capture git output for a scenario
./bin/oracle --refresh <name> # re-capture, for example after a git upgrade
./bin/actual <name> # run Pitmaster and capture its output
./bin/compare <name> # compare oracle and actual output
Um mehrere git-Versionen zu prüfen, führe sie in PITMASTER_TEST_GIT_BINARIES auf und starte den Smoke-Test:
PITMASTER_TEST_GIT_BINARIES=/path/to/git-2.45:/path/to/git-2.46 \
vendor/bin/phpunit --filter MultiGitVersionSmokeTest
Upstream-Korpora
Szenarien unter scenarios/upstream/ stammen aus den Testsuiten anderer Implementierungen: der git-eigenen Testsuite (412), isomorphic-git (71), libgit2 (63), go-git (46), JGit (7) und dulwich (6). Die benötigten Fixture-Trees liegen unter fixtures/upstream/ im Repository. Daher kann das gesamte Korpus direkt nach einem frischen Checkout ohne Netzwerkzugriff oder lokale Maschinenpfade ausgeführt werden. Einrichtungsskripte finden sie über die Umgebungsvariable PITMASTER_ROOT.
composer verify:drift (bin/audit-upstream-drift) prüft, ob jeder übernommene Upstream-Fall einem Szenario zugeordnet ist.
Support-Matrix
SUPPORT_MATRIX.md im Repository listet alle erfassten git-Funktionen samt Status auf:
| Status | Bedeutung |
|---|---|
DONE |
Implementiert und innerhalb des angegebenen Paritätsumfangs mit dem Oracle überprüft |
PART |
Teilweise implementiert |
TODO |
Im Umfang, noch nicht implementiert |
DEFER |
Noch nicht geplant |
N/A |
Nicht im Umfang |
Die Datei wird von bin/support-matrix aus config/support-matrix.json generiert. config/support-evidence.json verknüpft jede Zeile mit Status DONE und PART mit konkreten Tests und Oracle-Szenarien, und composer verify:evidence schlägt fehl, wenn für eine Zeile keine Nachweise vorliegen. CI generiert die Matrix erneut und schlägt fehl, wenn sich die eingecheckte Datei unterscheidet.
Eine Zeile mit Status DONE bedeutet, dass die dafür aufgezeichneten Szenarien mit git übereinstimmen. Außerhalb dieser Szenarien kann das Verhalten weiterhin abweichen; bekannte Unterschiede werden im Issue-Tracker dokumentiert.
Benchmarks
Die Performance-Arbeit verwendet den Harness unter bench/:
composer bench -- --suite=smoke --runs=1 --warmups=0 # quick check
composer bench:baseline # full report
composer bench:compare -- <before.json> <after.json> # compare two reports
composer bench:verify -- <report.json> bench/reports/smoke-thresholds.json
CI prüft den Smoke-Bericht anhand der eingecheckten Schwellenwerte.