
# 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:

```json
{
    "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](https://pitmaster.inline0.dev/de/docs/operations/diff) aufgeführten Unterschiede bei der Diff-Ausgabe für neue, gelöschte und binäre Dateien.

### Mit Szenarien arbeiten

```bash
./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:

```bash
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](https://github.com/inline0/pitmaster/issues) dokumentiert.

## Benchmarks

Die Performance-Arbeit verwendet den Harness unter `bench/`:

```bash
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.
