# バッチ設計書 10-eng/test-determinism.ps1

## 概要

本ドキュメントは、Roslynプロジェクトのビルド決定論性（Determinism）テストスクリプト「eng/test-determinism.ps1」の設計仕様を記載する。

### 本バッチの処理概要

eng/test-determinism.ps1は、Roslynコンパイラのビルドが決定論的（同一ソースから同一バイナリが生成される）であることを検証するためのPowerShellスクリプトである。

**業務上の目的・背景**：決定論的ビルドは、ソフトウェアのセキュリティと再現性において重要な特性である。同一のソースコードから常に同一のバイナリが生成されることで、以下が保証される：
- ビルドの再現性：任意の時点でのソースコードから同一のバイナリを再構築可能
- セキュリティ：ビルド成果物が改ざんされていないことの検証が可能
- パスマッピング：異なるディレクトリでビルドしても同一バイナリが生成される

**バッチの実行タイミング**：CI/CDパイプラインでの品質検証、リリースビルド前の決定論性確認、開発者による手動検証。

**主要な処理内容**：
1. ブートストラップコンパイラのビルド
2. 初期ビルドの実行とバイナリハッシュの記録
3. 同一ディレクトリでの再ビルドと比較（test1）
4. 異なるディレクトリ（substドライブ経由）での再ビルドと比較（test2）
5. バイナリ差分の検出と報告

**前後の処理との関連**：CI/CDパイプラインの品質検証フェーズで実行される。make-bootstrap.ps1でブートストラップコンパイラを構築し、MSBuildでビルドを実行する。

**影響範囲**：検証結果のみを出力し、ビルド成果物自体は変更しない。決定論性違反が検出された場合はZIPアーカイブを生成して報告する。

## バッチ種別

テスト処理（ビルド決定論性検証）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | CI/CDトリガーに応じて |
| 実行時刻 | 自動（イベント発生時） |
| 実行曜日 | 任意 |
| 実行日 | 任意 |
| トリガー | CI/CDパイプライン |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Windows OS | Windows環境でのみ実行可能（subst使用） |
| PowerShell | PowerShellが利用可能であること |
| .NET SDK | 必要な.NET SDKがインストールされていること |
| 管理者権限 | substコマンドの使用に必要な場合あり |

### 実行可否判定

- -helpオプションで使用方法を表示して終了
- -bootstrapDirが未指定の場合は自動的にブートストラップビルドを実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| -configuration | string | No | Debug | ビルド構成（Debug/Release） |
| -msbuildEngine | string | No | vs | MSBuildエンジン（dotnet/vs） |
| -altRootDrive | string | No | q: | 代替ビルドディレクトリ用ドライブ文字 |
| -bootstrapDir | string | No | "" | ブートストラップコンパイラのパス |
| -ci | switch | No | false | CI環境フラグ |
| -help | switch | No | false | ヘルプ表示 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| Roslyn.slnx | Solution | ビルド対象のソリューションファイル |
| ソースコード | C#/VB | コンパイル対象のソースファイル群 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | 検証進捗・結果 |
| artifacts/log | binlog/zip | ビルドログ、差分アーカイブ |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | Initial.binlog, test1.binlog, test2.binlog, determinism.zip |
| 出力先 | artifacts/log |
| 文字コード | バイナリ |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. 引数解析とヘルプ表示
   └─ -helpで使用方法表示
2. build-utils.ps1読み込み
   └─ 共通ユーティリティの読み込み
3. エラー出力ディレクトリ作成
   └─ DeterminismFailures/Left, Right
4. ブートストラップビルド（-bootstrapDir未指定時）
   └─ make-bootstrap.ps1呼び出し
5. Run-Test関数実行
   └─ 以下のサブステップを実行
   5.1. 初期ビルド実行
        └─ Run-Build関数でMSBuild実行
   5.2. バイナリハッシュ記録
        └─ Record-Binaries関数でMD5ハッシュを記録
   5.3. マップ内容検証
        └─ Test-MapContents関数で基本検証
   5.4. 同一ディレクトリでの再ビルドテスト
        └─ Test-Build関数で比較検証
   5.5. 異なるディレクトリでの再ビルドテスト
        └─ substでドライブ割り当て後、Test-Build実行
6. 正常終了
   └─ ExitWithExitCode 0
```

### フローチャート

```mermaid
flowchart TD
    A[test-determinism.ps1開始] --> B{-help?}
    B -->|Yes| C[使用方法表示]
    C --> D[終了]
    B -->|No| E[build-utils.ps1読み込み]
    E --> F[エラーディレクトリ作成]
    F --> G{bootstrapDir指定?}
    G -->|No| H[make-bootstrap.ps1実行]
    G -->|Yes| I[Run-Test開始]
    H --> I
    I --> J[初期ビルド実行]
    J --> K[バイナリハッシュ記録]
    K --> L[マップ内容検証]
    L --> M[同一ディレクトリ再ビルド]
    M --> N{ハッシュ一致?}
    N -->|No| O[差分記録]
    N -->|Yes| P[substでドライブ割り当て]
    O --> Q[エラー終了]
    P --> R[異なるディレクトリ再ビルド]
    R --> S{ハッシュ一致?}
    S -->|No| T[差分記録・ZIP作成]
    S -->|Yes| U[正常終了]
    T --> Q
```

## データベース操作仕様

### 操作別データベース影響一覧

本バッチはデータベース操作を行わない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | ビルドエラー | コンパイルエラー | エラーメッセージに従い修正 |
| 1 | 決定論性違反 | ハッシュ不一致 | determinism.zipを分析 |
| 1 | マップ検証失敗 | 必要なバイナリが不足 | ビルド設定を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 自動リトライなし |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. 終了コードを確認
2. artifacts/log/determinism.zipを取得
3. Left/Rightディレクトリの差分を比較分析
4. コンパイラチームに分析を依頼

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（ファイルシステム操作のみ） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | ソリューション全体（3回ビルド） |
| 目標処理時間 | 環境依存（通常60-120分） |
| メモリ使用量上限 | 環境依存 |

## 排他制御

- substコマンドで一時的にドライブ割り当てを行う
- 同一altRootDriveを使用する他プロセスとの競合に注意
- テスト完了後にsubst /dでドライブを解除

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 標準出力 | 常時 | 検証進捗、ハッシュ値 |
| バイナリログ | ビルド時 | MSBuild詳細ログ（Initial, test1, test2） |
| ZIPアーカイブ | 失敗時 | 差分バイナリ |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 非0 | CI/CDパイプライン |

## 備考

- スキップリスト（$skipList）に含まれるファイルは検証対象外
  - Microsoft.CodeAnalysis.EditorFeatures2.UnitTests.dll（既知の問題）
  - VSIX関連ファイル（インストールID等が非決定論的）
- DeterministicSourcePaths=trueでパスマッピングを有効化
- DebugDeterminism=trueとFeatures="debug-determinism"で詳細情報を出力
- 最低40個以上のバイナリが記録されていることを検証
- 必須バイナリ（Microsoft.CodeAnalysis.dll等）の存在を確認
