# 機能設計書 139-テストスイート

## 概要

本ドキュメントは、Julia の `test/` ディレクトリによる回帰テストスイートについて、その設計・処理仕様を記述するものである。

### 本機能の処理概要

`test/` ディレクトリは Julia 本体の回帰テストスイートを格納・管理する。`runtests.jl` がテスト実行のエントリーポイントであり、`choosetests.jl` がテスト選択ロジックを提供する。Distributed モジュールを利用した並列テスト実行、Revise 統合によるリビルドなしのテスト、テスト失敗時の早期終了などの機能を備える。

**業務上の目的・背景**：Julia は大規模かつ複雑なソフトウェアプロジェクトであり、変更によるリグレッションを防止するために包括的なテストスイートが不可欠である。本テストスイートは Julia のコア機能からコンパイラ、標準ライブラリまでを網羅的にテストする。

**機能の利用シーン**：CI/CD パイプラインでの自動テスト、開発者によるローカルテスト実行（`make test`）、特定テストの個別実行（`make test-revise-{name}`）、Pull Request のマージ前検証など。

**主要な処理内容**：
1. `choosetests.jl` によるテスト選択（TESTNAMES リスト、除外リスト、ネットワーク依存テスト管理）
2. `runtests.jl` によるテスト実行制御（並列実行、Revise 統合、ワーカー管理）
3. `testenv.jl` によるテスト環境設定
4. 個別テストファイルの実行（test/{name}.jl）
5. 標準ライブラリテストの統合（stdlib/ 配下のテスト）
6. コンパイラテストの統合（Compiler/test/ 配下のテスト）

**関連システム・外部連携**：Distributed モジュール（並列テスト実行）、Revise（リビルドなしテスト）、Test 標準ライブラリ（テストフレームワーク）、Buildkite（CI 統合）。

**権限による制御**：テスト実行に特別な権限は不要。一部のテスト（ネットワーク、SharedArrays、threads）はリソース制約により特別な扱いを受ける。

## 関連画面

本機能は画面を持たない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | コマンドラインから make test を実行して利用する |

## 機能種別

テスト基盤

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ARGS | コマンドライン引数 | No | テスト名の一覧（空の場合は全テスト） | TESTNAMES または STDLIBS に含まれること |
| --exit-on-error | 引数 | No | テスト失敗時に即座に終了 | - |
| --revise | 引数 | No | Revise を使用したテスト実行 | - |
| --seed | 引数 | No | 乱数シード指定 | 整数値 |
| JULIA_TEST_FAILFAST | 環境変数 | No | 1 に設定でテスト失敗時に即座に終了 | "1" |
| JULIA_TEST_MAXRSS_MB | 環境変数 | No | ワーカーの最大 RSS（MB） | 正の整数 |

### 入力データソース

コマンドライン引数、環境変数、テストファイル（test/*.jl）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| テスト結果 | テキスト | 各テストの Pass / Fail / Error 結果 |
| テストサマリー | テキスト | 全テスト実行後のサマリー |

### 出力先

標準出力（stdout）。CI 環境では Buildkite JSON 形式のレポートも生成可能。

## 処理フロー

### 処理シーケンス

```
1. runtests.jl の開始
   └─ choosetests.jl の include と実行
2. choosetests(ARGS) によるテスト選択
   └─ TESTNAMES リストからの選択、除外処理、ネットワーク判定
3. テストファイルの存在確認
   └─ test_path で各テストファイルのパスを解決
4. node1 テストの分離
   └─ ccall / precompile / SharedArrays / threads / gc / stress をノード1に移動
5. Revise 統合（use_revise の場合）
   └─ Revise.track(Base) による Base 変更の反映
6. テストの並列実行
   └─ Distributed モジュールによるワーカーでの並列テスト
7. 結果集約
   └─ 各ワーカーの結果を集約して報告
```

### フローチャート

```mermaid
flowchart TD
    A["runtests.jl 開始"] --> B["choosetests(ARGS)"]
    B --> C["テストファイル存在確認"]
    C --> D["node1 テストの分離"]
    D --> E{"use_revise?"}
    E -->|Yes| F["Revise のセットアップ"]
    E -->|No| G["テスト並列実行開始"]
    F --> G
    G --> H["ワーカー追加 (addprocs)"]
    H --> I["各テストをワーカーに分配"]
    I --> J["テスト結果の集約"]
    J --> K["node1 テストの実行"]
    K --> L["最終結果レポート"]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-139-01 | テスト選択 | ARGS が空または "all" の場合、全テストを選択 | choosetests |
| BR-139-02 | node1 テスト | ccall / precompile / SharedArrays / threads / gc / stress はノード1で実行 | 常時 |
| BR-139-03 | ネットワーク依存 | Artifacts / Downloads / LibGit2 / Pkg 等はネットワーク利用可能時のみ実行 | NETWORK_REQUIRED_LIST |
| BR-139-04 | 長時間テストの優先 | LinearAlgebra / Pkg テストは先頭に移動して早期開始 | 常時 |
| BR-139-05 | ワーカー RSS 制限 | JULIA_TEST_MAXRSS_MB でワーカーのメモリ使用量を制限可能 | 環境変数設定時 |
| BR-139-06 | テストパス解決 | STDLIBS のテストは stdlib/{name}/test/ から、Core テストは test/ から解決 | test_path 関数 |

### 計算ロジック

**test_path 関数**（56-79行目）:
- STDLIBS に含まれるテスト: `stdlib/{name}/test/runtests.jl` を返す
- Compiler テスト: `Compiler/test/{path}.jl` を返す
- JuliaSyntax / JuliaLowering: 対応する test/ ディレクトリの `runtests_vendored.jl` を返す
- その他: `test/{name}.jl` を返す

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

本機能はデータベース操作を行わない。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ErrorException | テストファイルが見つからない | テスト名が正しいか確認 |
| - | テスト失敗 | テストアサーション失敗 | テスト内容を確認し修正 |
| - | ワーカータイムアウト | テストが長時間実行 | JULIA_TEST_LONGRUNNING_DELAY 環境変数を調整 |

### リトライ仕様

個別テストの再実行は `make test-revise-{name}` で可能。

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

該当なし。

## パフォーマンス要件

- Distributed による並列テスト実行で全体の実行時間を短縮
- 長時間テスト（LinearAlgebra / Pkg）の先頭配置による効率化
- ワーカーの RSS 制限によるメモリ制約環境での安定動作
- rr（record and replay）環境下でのタイムアウト緩和

## セキュリティ考慮事項

- テスト実行はサンドボックス化されていない
- ネットワーク依存テストは外部サービスにアクセスする

## 備考

- `TESTNAMES` リストに全コアテスト名が定義されている（choosetests.jl:8-35行目）
- `INTERNET_REQUIRED_LIST` にインターネット必要テストが定義（37-46行目）
- `TOP_LEVEL_PKGS` に Compiler / JuliaSyntax / JuliaLowering が定義（50-54行目）
- `running_under_rr()` で rr 環境を検出し、タイムアウトを調整（runtests.jl:20-27行目）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: テスト選択ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | choosetests.jl | `test/choosetests.jl` | **8-35行目**: `TESTNAMES` 定数 -- 全コアテスト名のリスト |
| 1-2 | choosetests.jl | `test/choosetests.jl` | **37-48行目**: `INTERNET_REQUIRED_LIST` / `NETWORK_REQUIRED_LIST` |
| 1-3 | choosetests.jl | `test/choosetests.jl` | **56-79行目**: `test_path` 関数 -- テスト名からファイルパスへの解決 |
| 1-4 | choosetests.jl | `test/choosetests.jl` | **82-100行目**: `choosetests` 関数の docstring とオプション解説 |

**読解のコツ**: TESTNAMES は手動管理されたリストで、新しいテストファイルを追加した場合はここにも追記が必要。STDLIBS は実行時に stdlib/ ディレクトリをスキャンして動的に生成される。

#### Step 2: テスト実行エンジンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | runtests.jl | `test/runtests.jl` | **1-11行目**: 依存モジュールの読み込みと初期設定 |
| 2-2 | runtests.jl | `test/runtests.jl` | **17行目**: `choosetests(ARGS)` の呼び出し |
| 2-3 | runtests.jl | `test/runtests.jl` | **32-49行目**: Revise 統合のセットアップ |
| 2-4 | runtests.jl | `test/runtests.jl` | **70-100行目**: node1 テストの分離と長時間テストの優先配置 |

**主要処理フロー**:
- **17行目**: テスト選択
- **32-49行目**: Revise 使用時のセットアップ（Pkg.activate / using Revise / revise_trackall）
- **70-77行目**: `move_to_node1` 関数で特定テストをノード1に分離
- **95-99行目**: LinearAlgebra / Pkg を先頭に移動

#### Step 3: テスト環境設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | testenv.jl | `test/testenv.jl` | テスト環境の共通設定 |

### プログラム呼び出し階層図

```
runtests.jl
    |
    +-- choosetests.jl
    |       +-- choosetests(ARGS)
    |       |       +-- TESTNAMES / STDLIBS の参照
    |       |       +-- test_path() によるパス解決
    |       +-- INTERNET_REQUIRED_LIST
    |       +-- NETWORK_REQUIRED_LIST
    |
    +-- testenv.jl
    |       +-- テスト環境変数の設定
    |
    +-- buildkitetestjson.jl
    |       +-- CI 向けレポート生成
    |
    +-- Distributed.addprocs()
    |       +-- ワーカープロセスの追加
    |
    +-- 各テストファイル (test/{name}.jl)
            +-- using Test
            +-- @testset / @test / @test_throws
```

### データフロー図

```
[入力]                       [処理]                        [出力]

ARGS (テスト選択)       --> choosetests()
                            +-- TESTNAMES フィルタ
                            +-- ネットワーク判定
                            +-- テストパス解決         --> テストリスト

テストリスト             --> runtests.jl
                            +-- node1 テスト分離
                            +-- ワーカー生成
                            +-- 並列テスト実行         --> テスト結果

テスト結果               --> サマリー生成              --> stdout / CI レポート
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| runtests.jl | `test/runtests.jl` | テスト | テスト実行のエントリーポイント |
| choosetests.jl | `test/choosetests.jl` | テスト | テスト選択ロジック |
| testenv.jl | `test/testenv.jl` | テスト | テスト環境設定 |
| buildkitetestjson.jl | `test/buildkitetestjson.jl` | テスト | Buildkite CI レポート生成 |
| test/*.jl | `test/*.jl` | テスト | 個別テストファイル群 |
| stdlib/*/test/ | `stdlib/*/test/` | テスト | 標準ライブラリのテスト |
| Compiler/test/ | `Compiler/test/` | テスト | コンパイラのテスト |
