
# Testowanie i git Oracle

Pitmaster traktuje kanoniczny plik binarny `git` jako oracle: jeśli `git` akceptuje to, co zapisuje Pitmaster, a Pitmaster odczytuje to, co zapisuje `git`, zachowanie jest prawidłowe. Infrastruktura testowa znajduje się w repozytorium Pitmaster. Pakiet Composer zawiera tylko `src/` i `bin/pitmaster`, dlatego wszystkie poniższe polecenia uruchamiaj z klonu po `composer install`.

## Zestawy testów

| Polecenie | Co uruchamia | Wymaga `git` |
|---------|--------------|-------------|
| `composer test:unit` | Zestaw PHPUnit `unit`: izolowane testy komponentów | Nie |
| `composer test:integration` | Zestaw PHPUnit `integration`: Pitmaster i `git` działające na tych samych repozytoriach | Tak |
| `composer test:oracle` | `bin/test-regression`: każdy scenariusz oracle | Tak |
| `composer test` | PHPUnit (oba zestawy) oraz test regresji oracle | Tak |
| `./bin/verify-all` | `composer verify`: dowody obsługi, rozbieżności względem upstream, artefakt dowodowy, test mutacji, `composer audit`, PHPStan, standardy kodowania i `composer test` | Tak |

CI uruchamia zestaw testów jednostkowych na kilku wersjach PHP, zestaw integracyjny, test regresji oracle (`PITMASTER_TEST_JOBS=4`) oraz kontrole dowodów obsługi i rozbieżności względem upstream.

## Scenariusze oracle

Każdy scenariusz to katalog w `scenarios/<category>/` (łącznie 761, z czego 156 przygotowano dla Pitmaster, a 605 zaimportowano z innych implementacji Git):

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

`scenario.json` podaje polecenie do uruchomienia za pomocą `git`, równoważne polecenie Pitmaster oraz elementy, które muszą być zgodne:

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

Uruchomienie kopiuje repozytorium utworzone przez `setup.sh`, uruchamia oracle i polecenia Pitmaster na osobnych kopiach, a następnie porównuje wyniki, obiekty, referencje i log. `fsck_clean` wymaga też, aby `git fsck` zaakceptował repozytorium zapisane przez Pitmaster. Wynik oracle jest przechwytywany z `git`, jeśli go brakuje lub jest odświeżany; w przeciwnym razie używane są zapisane w repozytorium pliki `oracle/`.

Scenariusz obejmuje dokładnie przypadki tworzone przez jego konfigurację. Na przykład scenariusze diff porównują zmodyfikowane pliki, dlatego nie wykrywają różnic w wynikach diff dla nowych, usuniętych i binarnych plików wymienionych w [Diff](https://pitmaster.inline0.dev/pl/docs/operations/diff).

### Praca ze scenariuszami

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

Aby sprawdzić kilka wersji git, wymień je w `PITMASTER_TEST_GIT_BINARIES` i uruchom test dymny:

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

## Zbiory testowe upstream

Scenariusze w `scenarios/upstream/` zaimportowano z zestawów testowych innych implementacji: własnego zestawu testowego git (412), isomorphic-git (71), libgit2 (63), go-git (46), JGit (7) i dulwich (6). Wymagane drzewa fixture znajdują się w repozytorium w katalogu `fixtures/upstream/`, więc cały zbiór działa po świeżym sklonowaniu, bez dostępu do sieci i ścieżek lokalnych dla danego komputera. Skrypty konfigurujące odnajdują je za pomocą zmiennej środowiskowej `PITMASTER_ROOT`.

`composer verify:drift` (`bin/audit-upstream-drift`) sprawdza, czy każdy przypadek upstream przechowywany w repozytorium jest przypisany do scenariusza.

## Macierz obsługi

`SUPPORT_MATRIX.md` w repozytorium zawiera listę wszystkich funkcji git objętych zakresem wraz ze statusem:

| Status | Znaczenie |
|--------|---------|
| `DONE` | Zaimplementowano i zweryfikowano za pomocą oracle w zadeklarowanym zakresie zgodności |
| `PART` | Zaimplementowano częściowo |
| `TODO` | W zakresie, jeszcze niezaimplementowane |
| `DEFER` | Jeszcze nieplanowane |
| `N/A` | Poza zakresem |

Plik jest generowany przez `bin/support-matrix` na podstawie `config/support-matrix.json`. `config/support-evidence.json` łączy każdy wiersz `DONE` i `PART` z konkretnymi testami i scenariuszami oracle, a `composer verify:evidence` kończy się błędem, jeśli wiersz nie ma potwierdzenia. CI ponownie generuje macierz i kończy się błędem, jeśli plik różni się od zatwierdzonego.

Wiersz `DONE` oznacza, że przypisane do niego scenariusze dają wyniki zgodne z git. Zachowanie poza tymi scenariuszami może się różnić; znane różnice są śledzone w [rejestrze zgłoszeń](https://github.com/inline0/pitmaster/issues).

## Testy wydajności

Prace nad wydajnością korzystają z narzędzia testowego w `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 weryfikuje raport z testu dymnego w odniesieniu do zatwierdzonych progów.
