# 機能設計書 85-テストユーティリティ

## 概要

本ドキュメントは、Apache Flinkのテスト用ユーティリティとハーネス（flink-test-utils-parent）の機能設計書である。Flink開発者およびFlinkを使用するアプリケーション開発者がテストを効率的に実施するためのユーティリティを提供する。

### 本機能の処理概要

flink-test-utils-parentモジュールは、Flinkのテストを支援するためのユーティリティ、テストハーネス、JUnit拡張機能を提供する。MiniClusterExtensionにより、テスト時にローカルFlinkクラスターを自動的に起動・管理できる。

**業務上の目的・背景**：Flinkアプリケーションのテストは、分散システムの性質上、複雑になりがちである。テストユーティリティを提供することで、開発者が単体テスト・統合テストを効率的に記述できるようになる。MiniClusterを使用することで、本番に近い環境でのテストをローカルで実行可能。

**機能の利用シーン**：(1)Flink本体の開発・テスト、(2)Flinkアプリケーションの単体テスト、(3)統合テスト（ITCase）、(4)CI/CDパイプラインでの自動テスト

**主要な処理内容**：
1. **MiniClusterExtension**: JUnit 5用のMiniCluster管理拡張
2. **AbstractTestBase**: テスト基底クラス
3. **TestStreamEnvironment**: テスト用StreamExecutionEnvironment
4. **MetricListener**: メトリクステスト用リスナー
5. **TestUtils**: 各種テストユーティリティ
6. **PojoTestUtils**: POJOのシリアライゼーションテスト

**関連システム・外部連携**：JUnit 5、JUnit 4（後方互換）

**権限による制御**：なし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | テストユーティリティのため関連画面なし |

## 機能種別

テストフレームワーク / ユーティリティライブラリ

## 入力仕様

### 入力パラメータ（MiniClusterExtension）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| numberOfTaskManagers | int | No | TaskManager数（デフォルト: 1） | 正の整数 |
| numberOfSlotsPerTaskManager | int | No | TaskManagerあたりのスロット数（デフォルト: 1） | 正の整数 |
| configuration | Configuration | No | MiniCluster設定 | - |

### 入力データソース

テストコード内で定義されるテストデータ

## 出力仕様

### 出力データ

テスト結果（JUnit標準形式）

### 出力先

JUnitテストレポート

## 処理フロー

### 処理シーケンス（MiniClusterExtension）

```
1. @BeforeAll: MiniCluster起動
   └─ InternalMiniClusterExtension.beforeAll()
2. @BeforeEach: TestStreamEnvironment登録
   └─ registerEnv()
3. テスト実行
   └─ StreamExecutionEnvironment.getExecutionEnvironment()でテスト用環境取得
4. @AfterEach: TestStreamEnvironment解除
   └─ unregisterEnv()
5. @AfterAll: MiniCluster停止
   └─ InternalMiniClusterExtension.afterAll()
```

### フローチャート

```mermaid
flowchart TD
    A[テストクラス開始] --> B[beforeAll - MiniCluster起動]
    B --> C[テストメソッド1開始]
    C --> D[beforeEach - Environment登録]
    D --> E[テスト実行]
    E --> F[afterEach - Environment解除]
    F --> G{次のテスト?}
    G -->|Yes| C
    G -->|No| H[afterAll - MiniCluster停止]
    H --> I[テストクラス終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | クラスター共有 | 同一テストクラス内のテストでMiniClusterを共有 | MiniClusterExtension使用時 |
| BR-002 | Environment自動設定 | getExecutionEnvironment()がテスト用環境を返す | TestStreamEnvironment登録時 |
| BR-003 | ジョブクリーンアップ | テスト終了時に未完了ジョブをキャンセル | AbstractTestBase継承時 |

### 計算ロジック

特になし

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

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ParameterResolutionException | パラメータインジェクション失敗 | アノテーションと型を確認 |

### リトライ仕様

RetryOnExceptionExtension、RetryOnFailureExtensionによるテストリトライ機能を提供。

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

なし

## パフォーマンス要件

MiniCluster起動は数秒を要する。テストクラス単位で共有することで起動オーバーヘッドを最小化。

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

テスト環境のため特別なセキュリティ対策は含まれていない。SecureTestEnvironmentでKerberos環境のテストをサポート。

## 備考

- JUnit 4とJUnit 5の両方をサポート
- パラメータインジェクション（@InjectMiniCluster, @InjectClusterClient等）をサポート
- flink-test-utils-junit: JUnit拡張機能
- flink-test-utils-connector: コネクタテスト用ユーティリティ

---

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

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

### 推奨読解順序

#### Step 1: JUnit 5拡張機能を理解する

MiniClusterExtensionの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MiniClusterExtension.java | `flink-test-utils-parent/flink-test-utils/src/main/java/org/apache/flink/test/junit5/MiniClusterExtension.java` | JUnit 5拡張機能 |

**主要処理フロー**:
- **128-133行目**: JUnit 5コールバックインターフェース実装（BeforeAllCallback等）
- **148-165行目**: コンストラクタとMiniClusterResourceConfiguration
- **228-231行目**: beforeAll() - MiniCluster起動
- **235-237行目**: beforeEach() - Environment登録
- **240-242行目**: afterEach() - Environment解除
- **245-249行目**: afterAll() - MiniCluster停止
- **257-272行目**: registerEnv() - TestStreamEnvironment設定
- **169-223行目**: パラメータリゾルバー実装

**読解のコツ**: JUnit 5のExtension APIを使用してテストライフサイクルにフックしている。BeforeAllCallbackでMiniClusterを起動し、BeforeEachCallbackで各テストにEnvironmentを提供する。

#### Step 2: テスト基底クラスを理解する

AbstractTestBaseの機能を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractTestBase.java | `flink-test-utils-parent/flink-test-utils/src/main/java/org/apache/flink/test/util/AbstractTestBase.java` | テスト基底クラス |

**主要処理フロー**:
- **68-74行目**: MINI_CLUSTER_EXTENSION定義
- **78-95行目**: cleanupRunningJobs() - テスト後のジョブクリーンアップ
- **101-123行目**: 一時ファイルユーティリティメソッド

**読解のコツ**: @RegisterExtensionでMiniClusterExtensionを登録。テスト終了後に未完了ジョブを自動キャンセル。

#### Step 3: パラメータインジェクションを理解する

テストメソッドへのパラメータ注入方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | InjectClusterClient.java | `flink-test-utils-parent/flink-test-utils/src/main/java/org/apache/flink/test/junit5/InjectClusterClient.java` | アノテーション定義 |

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

```
MiniClusterExtension
    │
    ├─ beforeAll(ExtensionContext)
    │      └─ InternalMiniClusterExtension.beforeAll()
    │             └─ MiniCluster.start()
    │
    ├─ beforeEach(ExtensionContext)
    │      └─ registerEnv()
    │             └─ TestStreamEnvironment.setAsContext()
    │
    ├─ supportsParameter(ParameterContext, ExtensionContext)
    │      └─ @InjectClusterClient, @InjectMiniCluster等の判定
    │
    ├─ resolveParameter(ParameterContext, ExtensionContext)
    │      └─ MiniClusterClient / RestClusterClient 作成
    │
    ├─ afterEach(ExtensionContext)
    │      └─ unregisterEnv()
    │             └─ TestStreamEnvironment.unsetAsContext()
    │
    └─ afterAll(ExtensionContext)
           └─ InternalMiniClusterExtension.afterAll()
                  └─ MiniCluster.close()
```

### データフロー図

```
[テスト設定]                [MiniClusterExtension]              [テストコード]

MiniClusterResourceConfiguration
┌─────────────────────────┐
│ numberOfTaskManagers: 1 │
│ numberOfSlotsPerTaskManager: 1 │
│ configuration: ...      │
└─────────────────────────┘
           │
           ▼
    beforeAll()
┌─────────────────────────┐
│ MiniCluster起動          │
└─────────────────────────┘
           │
           ▼
    beforeEach()                        StreamExecutionEnvironment
┌─────────────────────────┐            .getExecutionEnvironment()
│ TestStreamEnvironment   │────────────────▶ テスト実行
│ 登録                    │
└─────────────────────────┘
           │
           ▼
    afterEach()
┌─────────────────────────┐
│ Environment解除          │
└─────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MiniClusterExtension.java | `flink-test-utils-parent/flink-test-utils/src/main/java/.../junit5/MiniClusterExtension.java` | ソース | JUnit 5 MiniCluster拡張 |
| AbstractTestBase.java | `flink-test-utils-parent/flink-test-utils/src/main/java/.../util/AbstractTestBase.java` | ソース | テスト基底クラス |
| TestStreamEnvironment.java | `flink-test-utils-parent/flink-test-utils/src/main/java/.../streaming/util/TestStreamEnvironment.java` | ソース | テスト用Environment |
| InjectClusterClient.java | `flink-test-utils-parent/flink-test-utils/src/main/java/.../junit5/InjectClusterClient.java` | ソース | ClusterClientインジェクションアノテーション |
| MetricListener.java | `flink-test-utils-parent/flink-test-utils/src/main/java/.../metrics/testutils/MetricListener.java` | ソース | メトリクステストリスナー |
| PojoTestUtils.java | `flink-test-utils-parent/flink-test-utils/src/main/java/.../types/PojoTestUtils.java` | ソース | POJOテストユーティリティ |
| TestUtils.java | `flink-test-utils-parent/flink-test-utils/src/main/java/.../util/TestUtils.java` | ソース | 汎用テストユーティリティ |
| OneShotLatch.java | `flink-test-utils-parent/flink-test-utils-junit/src/main/java/.../testutils/OneShotLatch.java` | ソース | 同期ユーティリティ |
| RetryOnFailureExtension.java | `flink-test-utils-parent/flink-test-utils-junit/src/main/java/.../testutils/junit/RetryOnFailureExtension.java` | ソース | リトライ拡張 |
| SecureTestEnvironment.java | `flink-test-utils-parent/flink-test-utils/src/main/java/.../util/SecureTestEnvironment.java` | ソース | セキュアテスト環境 |
