
# Test og git-oraklet

Pitmaster bruger den kanoniske `git`-binærfil som orakel: Hvis `git` accepterer det, som Pitmaster skriver, og Pitmaster kan læse det, som `git` skriver, er adfærden korrekt. Testinfrastrukturen ligger i Pitmaster-repositoryet. Pakken Composer indeholder kun `src/` og `bin/pitmaster`, så kør alt nedenfor fra en klon efter `composer install`.

## Testsuiter

| Kommando | Hvad den kører | Kræver `git` |
|---------|--------------|-------------|
| `composer test:unit` | PHPUnit-`unit`-suite: isolerede komponenttests | Nej |
| `composer test:integration` | PHPUnit-`integration`-suite: Pitmaster og `git` arbejder på de samme repositories | Ja |
| `composer test:oracle` | `bin/test-regression`: alle orakelscenarier | Ja |
| `composer test` | PHPUnit (begge suiter) samt orakelregressionen | Ja |
| `./bin/verify-all` | `composer verify`: supportbevis, upstream-afvigelser, bevisartefakt, mutationsrøgestest, `composer audit`, PHPStan, kodningsstandarder og `composer test` | Ja |

CI kører enhedssuiten på flere PHP-versioner, integrationssuiten, orakelregressionen (`PITMASTER_TEST_JOBS=4`) samt kontrollerne af supportbevis og upstream-afvigelser.

## Orakelscenarier

Hvert scenarie er en mappe under `scenarios/<category>/` (i alt 761, hvor 156 er skrevet til Pitmaster, og 605 er importeret fra andre Git-implementeringer):

```
scenarios/diff/diff-add-lines/
  scenario.json   # commands and expectations
  setup.sh        # builds the starting repository
  oracle/         # outputs captured from git
```

`scenario.json` angiver kommandoen, der skal køres med `git`, den tilsvarende Pitmaster-kommando og hvad der skal stemme overens:

```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 }
}
```

En kørsel kopierer repositoryet, som `setup.sh` har opbygget, kører oraklet og Pitmaster-kommandoerne på separate kopier og sammenligner output, objekter, refs og log. `fsck_clean` kræver også, at `git fsck` kan acceptere det repository, som Pitmaster skrev. Orakeloutputtet hentes fra `git`, hvis det mangler eller skal opdateres; ellers bruges de versionsstyrede `oracle/`-filer.

Et scenarie dækker præcis de tilfælde, som dets opsætning opbygger. Diff-scenarierne sammenligner for eksempel ændrede filer, og derfor fanger de ikke forskellene i diff-output for nye, slettede og binære filer, som er angivet i [Diff](https://pitmaster.inline0.dev/da/docs/operations/diff).

### Arbejd med scenarier

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

Hvis du vil kontrollere flere git-versioner, skal du angive dem i `PITMASTER_TEST_GIT_BINARIES` og køre røgestesten:

```bash
PITMASTER_TEST_GIT_BINARIES=/path/to/git-2.45:/path/to/git-2.46 \
  vendor/bin/phpunit --filter MultiGitVersionSmokeTest
```

## Upstream-korpora

Scenarier under `scenarios/upstream/` er importeret fra andre implementeringers testsuiter: gits egen testsuite (412), isomorphic-git (71), libgit2 (63), go-git (46), JGit (7) og dulwich (6). De nødvendige fixture-træer er inkluderet under `fixtures/upstream/`, så hele korpusset kan køres fra en frisk checkout uden netværksadgang eller lokale maskinstier. Opsætningsscripts finder dem via miljøvariablen `PITMASTER_ROOT`.

`composer verify:drift` (`bin/audit-upstream-drift`) kontrollerer, at hvert inkluderet upstream-tilfælde er knyttet til et scenarie.

## Supportmatrix

`SUPPORT_MATRIX.md` i repositoryet viser alle git-funktioner inden for omfanget sammen med deres status:

| Status | Betydning |
|--------|---------|
| `DONE` | Implementeret og verificeret mod oraklet inden for det erklærede paritetsomfang |
| `PART` | Delvist implementeret |
| `TODO` | Inden for omfanget, endnu ikke implementeret |
| `DEFER` | Ikke planlagt endnu |
| `N/A` | Uden for omfanget |

Filen genereres af `bin/support-matrix` fra `config/support-matrix.json`. `config/support-evidence.json` knytter hver række med `DONE` og `PART` til konkrete tests og orakelscenarier, og `composer verify:evidence` fejler, hvis en række mangler dokumentation. CI genererer matricen igen og fejler, hvis den indsendte fil er anderledes.

En række med `DONE` betyder, at de registrerede scenarier stemmer overens med git. Adfærden kan stadig være anderledes uden for disse scenarier; kendte forskelle registreres i [problemtrackeren](https://github.com/inline0/pitmaster/issues).

## Benchmarks

Ydelsesarbejdet bruger testværktøjet under `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 kontrollerer røgerapporten mod de indsendte tærskler.
