
# Тестване и Oracle на git

Pitmaster използва каноничния двоичен файл на `git` като Oracle: ако `git` приема написаното от Pitmaster и Pitmaster прочита написаното от `git`, поведението е правилно. Тестовата инфраструктура е в хранилището Pitmaster. Пакетът Composer включва само `src/` и `bin/pitmaster`, затова изпълнявайте всичко по-долу от клонирано хранилище след `composer install`.

## Тестови набори

| Команда | Какво изпълнява | Изисква `git` |
|---------|--------------|-------------|
| `composer test:unit` | Наборът PHPUnit `unit`: изолирани тестове на компоненти | Не |
| `composer test:integration` | Наборът PHPUnit `integration`: Pitmaster и `git` работят върху едни и същи хранилища | Да |
| `composer test:oracle` | `bin/test-regression`: всички сценарии с Oracle | Да |
| `composer test` | PHPUnit (и двата набора) плюс регресионния тест с Oracle | Да |
| `./bin/verify-all` | `composer verify`: доказателства за поддръжката, промени в upstream, артефакт за доказателство, проверка за мутации, `composer audit`, PHPStan, стандарти за кодиране и `composer test` | Да |

CI изпълнява модулния набор с няколко версии на PHP, интеграционния набор, регресионния тест с Oracle (`PITMASTER_TEST_JOBS=4`), както и проверките за доказателства за поддръжката и промени в upstream.

## Сценарии с Oracle

Всеки сценарий е директория в `scenarios/<category>/` (общо 761, от които 156 са написани за Pitmaster, а 605 са внесени от други реализации на Git):

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

`scenario.json` посочва командата за изпълнение с `git` и съответстващата команда Pitmaster, както и какво трябва да съвпада:

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

При изпълнение се копира хранилището, създадено от `setup.sh`, стартират се Oracle и командите Pitmaster върху отделни копия и се сравняват изходите, обектите, refs и журналът. `fsck_clean` изисква също `git fsck` да приема хранилището, записано от Pitmaster. Изходът на Oracle се записва от `git`, ако липсва или трябва да се обнови; иначе се използват записаните файлове `oracle/`.

Сценарият обхваща точно случаите, създадени от настройката му. Например сценариите за diff сравняват променени файлове, затова разликите в изхода на diff за нови, изтрити и двоични файлове, изброени в [Diff](https://pitmaster.inline0.dev/bg/docs/operations/diff), не се откриват от тях.

### Работа със сценарии

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

За да проверите няколко версии на git, избройте ги в `PITMASTER_TEST_GIT_BINARIES` и изпълнете проверката за съвместимост:

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

## Корпуси от други проекти

Сценариите в `scenarios/upstream/` са внесени от тестовите набори на други реализации: собствения тестов набор на git (412), isomorphic-git (71), libgit2 (63), go-git (46), JGit (7) и dulwich (6). Необходимите дървета с тестови данни се включват в `fixtures/upstream/`, така че целият корпус може да се изпълни от чисто клониране без мрежов достъп или локални за машината пътища. Скриптовете за настройка намират тези данни чрез променливата на средата `PITMASTER_ROOT`.

`composer verify:drift` (`bin/audit-upstream-drift`) проверява дали всеки внесен upstream случай е свързан със сценарий.

## Матрица на поддръжката

`SUPPORT_MATRIX.md` в хранилището изброява всички функции на git в обхвата и техния статус:

| Статус | Значение |
|--------|---------|
| `DONE` | Реализирано и проверено спрямо Oracle в обявения обхват на съвместимост |
| `PART` | Реализирано частично |
| `TODO` | В обхвата, но все още нереализирано |
| `DEFER` | Все още не е планирано |
| `N/A` | Извън обхвата |

Файлът се генерира от `bin/support-matrix` от `config/support-matrix.json`. `config/support-evidence.json` свързва всеки ред със статус `DONE` и `PART` с конкретни тестове и сценарии с Oracle, а `composer verify:evidence` се проваля, ако ред няма доказателства. CI генерира матрицата отново и се проваля, ако записаният файл се различава.

Ред със статус `DONE` означава, че записаните за него сценарии съвпадат с git. Поведението извън тези сценарии все още може да се различава; известните разлики се проследяват в [системата за проследяване на проблеми](https://github.com/inline0/pitmaster/issues).

## Тестове за производителност

Работата по производителността използва средата за тестове в `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 проверява отчета от проверката за съвместимост спрямо записаните прагове.
