
# 테스트와 git Oracle

Pitmaster는 표준 `git` 바이너리를 오라클로 사용합니다. `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`: 모든 오라클 시나리오 | 예 |
| `composer test` | PHPUnit(두 테스트 모음 모두) 및 오라클 회귀 테스트 | 예 |
| `./bin/verify-all` | `composer verify`: 지원 근거, 업스트림 변경 감지, 증명 산출물, 변이 스모크 테스트, `composer audit`, PHPStan, 코딩 표준, `composer test` | 예 |

CI는 여러 PHP 버전에서 단위 테스트 모음, 통합 테스트 모음, 오라클 회귀 테스트(`PITMASTER_TEST_JOBS=4`), 지원 근거 및 업스트림 변경 감지 검사를 실행합니다.

## 오라클 시나리오

각 시나리오는 `scenarios/<category>/` 아래의 디렉터리입니다(총 761개. Pitmaster 및 605용으로 작성된 156개, 다른 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`가 만든 저장소를 복사하고, 오라클 명령과 Pitmaster 명령을 별도 복사본에서 실행한 뒤 출력, 객체, 참조, 로그를 비교합니다. `fsck_clean`의 경우 `git fsck`가 Pitmaster가 기록한 저장소를 받아들이는지도 확인합니다. 오라클 출력은 없거나 갱신할 때 `git`에서 캡처하고, 그 외에는 커밋된 `oracle/` 파일을 사용합니다.

시나리오는 설정 과정에서 구성한 사례만 정확히 다룹니다. 예를 들어 diff 시나리오는 수정된 파일을 비교하므로 [Diff](https://pitmaster.inline0.dev/ko/docs/operations/diff)에 나열된 새 파일, 삭제된 파일, 바이너리 파일의 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`)는 포함된 모든 업스트림 사례가 시나리오에 연결되어 있는지 확인합니다.

## 지원 매트릭스

저장소의 `SUPPORT_MATRIX.md`에는 범위에 포함된 모든 git 기능과 상태가 나열됩니다:

| 상태 | 의미 |
|--------|---------|
| `DONE` | 선언된 호환 범위 내에서 구현 및 오라클 검증 완료 |
| `PART` | 부분 구현 |
| `TODO` | 범위에 포함되었으나 아직 미구현 |
| `DEFER` | 아직 계획되지 않음 |
| `N/A` | 범위 외 |

이 파일은 `config/support-matrix.json`에서 `bin/support-matrix`가 생성합니다. `config/support-evidence.json`는 모든 `DONE` 및 `PART` 행을 실제 테스트 및 오라클 시나리오에 연결하며, 근거가 없는 행이 있으면 `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는 스모크 보고서를 커밋된 임계값과 대조해 검증합니다.
