テストと git オラクル
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用に作成したものが156件、他の Git 実装から取り込んだものが605件)。
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で実行するコマンドと、一致すべき内容が記載されています。
{
"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では、Pitmasterが書き込んだリポジトリをgit fsckが受け入れることも確認します。オラクルの出力がない場合や更新する場合はgitから取得し、それ以外の場合はコミット済みのoracle/ファイルを使います。
各シナリオが対象とするのは、セットアップで構築されたケースだけです。たとえば diff シナリオでは変更済みファイルを比較するため、Diffに記載された新規、削除済み、バイナリファイルの diff 出力の違いは検出されません。
シナリオの操作
./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に一覧を記載してスモークテストを実行します。
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 と一致することを意味します。これらのシナリオ以外では動作が異なる場合があり、既知の差異は課題トラッカーで管理されています。
ベンチマーク
パフォーマンス改善には、bench/配下のハーネスを使います。
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 はスモークレポートをコミット済みのしきい値と照合します。