
# Testaus ja git-orakkeli

Pitmaster käyttää kanonista `git`-binaaria oraakkelinaan: toiminta on oikein, jos `git` hyväksyy sen, mitä Pitmaster kirjoittaa, ja Pitmaster lukee sen, mitä `git` kirjoittaa. Testi-infrastruktuuri sijaitsee repositoriossa Pitmaster. Paketti Composer sisältää vain `src/`- ja `bin/pitmaster`-tiedostot, joten suorita kaikki alla olevat komennot kloonatussa repositoriossa komennon `composer install` jälkeen.

## Testikokonaisuudet

| Komento | Mitä se suorittaa | Vaatii `git` |
|---------|------------------|-------------|
| `composer test:unit` | PHPUnit `unit` -testisarja: eristetyt komponenttitestit | Ei |
| `composer test:integration` | PHPUnit `integration` -testisarja: Pitmaster ja `git` toimivat samoissa repositorioissa | Kyllä |
| `composer test:oracle` | `bin/test-regression`: kaikki oracle-skenaariot | Kyllä |
| `composer test` | PHPUnit (molemmat testisarjat) sekä oracle-regressio | Kyllä |
| `./bin/verify-all` | `composer verify`: tukiaineisto, upstream-muutokset, todistusaineisto, mutaatiotesti, `composer audit`, PHPStan, koodausstandardit ja `composer test` | Kyllä |

CI suorittaa yksikkötestikokonaisuuden useilla PHP-versioilla, integraatiotestikokonaisuuden, oraakkeliregressiotestin (`PITMASTER_TEST_JOBS=4`) sekä tuki- ja alkuperäistarkistukset.

## Oraakkelitestit

Kukin testitapaus on hakemisto polussa `scenarios/<category>/` (yhteensä 761: Pitmaster:lle kirjoitettuja 156 tapausta ja muista Git-toteutuksista tuotuja 605 tapausta):

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

`scenario.json` ilmoittaa komennon, joka suoritetaan komennoilla `git` ja vastaavalla Pitmaster-komennolla, sekä sen, minkä on täsmättävä:

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

Testiajo kopioi komennolla `setup.sh` rakennetun repositorion, suorittaa oraakkelin ja komennot Pitmaster erillisissä kopioissa sekä vertaa tulosteita, objekteja, viitteitä ja lokia. `fsck_clean` edellyttää lisäksi, että `git fsck` hyväksyy repositorion, jonka Pitmaster kirjoitti. Oraakkelin tuloste kerätään kohteesta `git`, kun se puuttuu tai päivitetään; muussa tapauksessa käytetään repositorion mukana toimitettuja `oracle/`-tiedostoja.

Testitapaus kattaa täsmälleen ne tapaukset, jotka sen asetukset rakentavat. Esimerkiksi diff-testeissä verrataan muutettuja tiedostoja, joten ne eivät havaitse uusia, poistettuja ja binääritiedostoja koskevia eroja diff-tulosteessa, jotka on lueteltu kohdassa [Diff](https://pitmaster.inline0.dev/fi/docs/operations/diff).

### Testitapausten käyttäminen

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

Voit tarkistaa useita git-versioita lisäämällä ne luetteloon `PITMASTER_TEST_GIT_BINARIES` ja suorittamalla savutestin:

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

## Alkuperäiset testikokoelmat

Polun `scenarios/upstream/` testitapaukset on tuotu muiden toteutusten testikokonaisuuksista: gitin omasta testikokonaisuudesta (412), isomorphic-gitistä (71), libgit2:sta (63), go-gitistä (46), JGit-projektista (7) ja dulwichista (6). Niiden tarvitsemat testitiedostopuut sisältyvät polkuun `fixtures/upstream/`, joten koko testikokoelma toimii tuoreesta kloonauksesta ilman verkkoyhteyttä tai paikallisia polkuja. Asetuskomentosarjat löytävät ne ympäristömuuttujan `PITMASTER_ROOT` avulla.

`composer verify:drift` (`bin/audit-upstream-drift`) tarkistaa, että jokaiselle mukana toimitetulle alkuperäiselle tapaukselle on määritetty testitapaus.

## Tukimatriisi

Repositoriossa oleva `SUPPORT_MATRIX.md` luettelee kaikki tuen piiriin kuuluvat git-toiminnot tiloineen:

| Tila | Merkitys |
|--------|---------|
| `DONE` | Toteutettu ja oraakkelilla varmennettu määritellyn vastaavuusalueen puitteissa |
| `PART` | Osittain toteutettu |
| `TODO` | Tuen piirissä, ei vielä toteutettu |
| `DEFER` | Ei vielä suunniteltu |
| `N/A` | Ei tuen piirissä |

Tiedoston luo `bin/support-matrix` kohteesta `config/support-matrix.json`. `config/support-evidence.json` yhdistää jokaisen `DONE`- ja `PART`-rivin konkreettisiin testeihin ja oraakkelitapauksiin, ja `composer verify:evidence` epäonnistuu, jos rivillä ei ole todistusaineistoa. CI luo matriisin uudelleen ja epäonnistuu, jos tulos eroaa repositorion tiedostosta.

Rivi `DONE` tarkoittaa, että sille kirjatut testitapaukset vastaavat gitiä. Toiminta voi silti erota näiden tapausten ulkopuolella; tunnetut erot kirjataan [ongelmaseurantaan](https://github.com/inline0/pitmaster/issues).

## Suorituskykytestit

Suorituskykyä testataan polun `bench/` testiajurilla:

```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 tarkistaa, että savutestin raportti alittaa repositorion mukana toimitetut raja-arvot.
