
# Test e Oracle di git

Pitmaster considera il binario canonico di `git` il proprio oracle: se `git` accetta ciò che Pitmaster scrive e Pitmaster legge ciò che `git` scrive, il comportamento è corretto. L'infrastruttura di test si trova nel repository Pitmaster. Il pacchetto Composer include solo `src/` e `bin/pitmaster`, quindi esegui tutto quanto segue da un clone dopo `composer install`.

## Suite di test

| Comando | Cosa esegue | Richiede `git` |
|---------|--------------|-------------|
| `composer test:unit` | suite PHPUnit `unit`: test dei componenti isolati | No |
| `composer test:integration` | suite PHPUnit `integration`: Pitmaster e `git` operano sugli stessi repository | Sì |
| `composer test:oracle` | `bin/test-regression`: tutti gli scenari oracle | Sì |
| `composer test` | PHPUnit (entrambe le suite) più la regressione oracle | Sì |
| `./bin/verify-all` | `composer verify`: prove di supporto, derive upstream, artefatto di prova, test rapido delle mutazioni, `composer audit`, PHPStan, standard di codifica e `composer test` | Sì |

CI esegue la suite di unità su diverse versioni di PHP, la suite di integrazione, la regressione oracle (`PITMASTER_TEST_JOBS=4`) e i controlli sulle prove di supporto e sulle derive upstream.

## Scenari oracle

Ogni scenario è una directory in `scenarios/<category>/` (761 in totale: 156 creati per Pitmaster e 605 importati da altre implementazioni di Git):

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

`scenario.json` indica il comando da eseguire con `git` e il comando Pitmaster equivalente, oltre a ciò che deve corrispondere:

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

Un'esecuzione copia il repository creato da `setup.sh`, esegue oracle e comandi Pitmaster su copie separate e confronta output, oggetti, riferimenti e log. `fsck_clean` richiede anche che `git fsck` accetti il repository scritto da Pitmaster. L'output oracle viene acquisito da `git` se manca o viene aggiornato; altrimenti si usano i file `oracle/` salvati nel repository.

Uno scenario copre esattamente i casi creati dalla sua configurazione. Gli scenari diff, per esempio, confrontano file modificati; per questo le differenze nell'output diff per i file nuovi, eliminati e binari elencate in [Diff](https://pitmaster.inline0.dev/it/docs/operations/diff) non vengono rilevate.

### Lavorare con gli scenari

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

Per verificare diverse versioni di git, elencale in `PITMASTER_TEST_GIT_BINARIES` ed esegui il test rapido:

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

## Corpora upstream

Gli scenari in `scenarios/upstream/` sono importati dalle suite di test di altre implementazioni: la suite di test di git (412), isomorphic-git (71), libgit2 (63), go-git (46), JGit (7) e dulwich (6). Gli alberi dei dati di test necessari sono inclusi nel repository in `fixtures/upstream/`, quindi l'intero corpus può essere eseguito da un checkout pulito senza accesso alla rete né percorsi specifici della macchina. Gli script di configurazione li individuano tramite la variabile d'ambiente `PITMASTER_ROOT`.

`composer verify:drift` (`bin/audit-upstream-drift`) verifica che ogni caso upstream incluso nel repository sia associato a uno scenario.

## Matrice di supporto

`SUPPORT_MATRIX.md` nel repository elenca tutte le funzionalità git incluse nell'ambito e il loro stato:

| Stato | Significato |
|--------|---------|
| `DONE` | Implementata e verificata con oracle nell'ambito di parità dichiarato |
| `PART` | Implementata parzialmente |
| `TODO` | Inclusa nell'ambito, non ancora implementata |
| `DEFER` | Non ancora pianificata |
| `N/A` | Fuori ambito |

Il file viene generato da `bin/support-matrix` a partire da `config/support-matrix.json`. `config/support-evidence.json` collega ogni riga `DONE` e `PART` a test e scenari oracle concreti, mentre `composer verify:evidence` genera un errore se una riga non ha prove. CI rigenera la matrice e segnala un errore se il file salvato nel repository è diverso.

Una riga `DONE` indica che gli scenari registrati per essa corrispondono a git. Il comportamento al di fuori di tali scenari può comunque differire; le differenze note sono tracciate nel [tracker dei problemi](https://github.com/inline0/pitmaster/issues).

## Benchmark

Per le ottimizzazioni delle prestazioni si usa il sistema di test in `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 verifica il rapporto del test rapido rispetto alle soglie salvate nel repository.
