# テスト方針書

## 概要

本ドキュメントは、OpenSearch（バージョン3.5.0）のテスト方針を定義する。OpenSearchはApache Lucene 10.3.2をベースとした分散型検索・分析エンジンであり、大規模かつ多層的なテスト戦略を採用している。テストはGradleビルドシステムを通じて管理され、JUnit 4 + RandomizedTesting Runnerによるランダム化テスト、JaCoCo によるカバレッジ計測、GitHub Actions + Jenkins によるCI/CD自動化を基盤とする。

## テスト戦略

### テストレベル

| レベル | 目的 | 担当 |
| --- | --- | --- |
| 単体テスト（Unit Test） | 個々のクラス・メソッドの動作検証。`OpenSearchTestCase` を基底クラスとし、ランダム化パラメータによる多様な入力パターンでの検証を行う | 開発者 |
| 単一ノード結合テスト（Single Node Integration Test） | 単一ノードクラスタ上でのコンポーネント統合検証。`OpenSearchSingleNodeTestCase` を基底クラスとし、`IndicesService` 等のインスタンス化が困難なコンポーネントを含むテストに使用 | 開発者 |
| 内部クラスタ結合テスト（Internal Cluster Test） | 複数ノードクラスタ上での分散処理・クラスタ機能の検証。`OpenSearchIntegTestCase` を基底クラスとし、テスト毎にクラスタ構成を制御可能 | 開発者 |
| RESTテスト（REST API Test） | REST APIレイヤーの検証。`OpenSearchRestTestCase`（Java）および `OpenSearchClientYamlSuiteTestCase`（YAML DSL）を使用。外部クラスタに対して実行可能 | 開発者・QA |
| 後方互換性テスト（BWC Test） | バージョンアップグレード時の互換性検証。過去バージョンからのローリングアップグレード・フルクラスタリスタートを含む | 開発者・QA |
| パッケージングテスト（Packaging Test） | RPM/DEB/ZIP/TAR等のディストリビューションパッケージのインストール・起動検証。Vagrant VMを使用して複数OS上で実行 | QA・リリースチーム |
| セキュリティ静的解析（CodeQL） | GitHub CodeQLによるセキュリティ脆弱性の静的解析。mainブランチへのpush/PRおよび週次スケジュールで実行 | 自動（CI） |

### テスト種別

| 種別 | 概要 | 実施タイミング |
| --- | --- | --- |
| 機能テスト | 検索・インデキシング・集計・クラスタ管理等のコア機能の動作検証 | コミット時・PR時 |
| 性能テスト | JMH（Java Microbenchmark Harness）によるマイクロベンチマーク、および`benchmark-pull-request`ワークフローによるPR単位のパフォーマンス回帰検出 | PR時（ベンチマークワークフロー） |
| セキュリティテスト | CodeQL静的解析、ForbiddenAPIs チェック、FIPS 140-2対応テスト、サードパーティ監査（thirdPartyAudit） | PR時・mainブランチpush時・週次 |
| 回帰テスト | 全テストスイート（`./gradlew check`）の実行によるリグレッション検出。BWCテストによるバージョン互換性の回帰検出 | PR時（Jenkins gradle-check） |
| 互換性テスト | 後方互換性テスト（BWCTest）によるインデックス互換性・ワイヤープロトコル互換性の検証 | PR時（`./gradlew check` に含む） |

## テスト環境

| 環境 | 用途 | 構成 |
| --- | --- | --- |
| ローカル開発環境 | 開発者による単体テスト・結合テストの実行 | JDK 21〜25（Temurin）、Gradle 8.x、Docker |
| GitHub Actions | PR時のprecommit、assemble、CodeQL解析 | ubuntu-latest, windows-latest, macos-15, ubuntu-24.04-arm。JDK 21, 25 のマトリクスビルド |
| Jenkins（gradle-check） | 全テストスイートの実行（`./gradlew check`相当） | Jenkins環境でのGradle Check。タイムアウト130分。Codecovへのカバレッジレポートアップロード含む |
| Vagrant VM | パッケージングテスト | VirtualBox + Vagrant。Ubuntu, Debian, CentOS, RHEL, Fedora, OEL, SLES, openSUSE等の複数Linux ディストリビューション |
| 外部クラスタ | REST APIテストの外部クラスタ実行 | `tests.cluster`, `tests.rest.cluster`, `tests.clustername` プロパティで指定 |

## テストツール

| ツール | 用途 | バージョン |
| --- | --- | --- |
| JUnit 4 | テストフレームワーク | 4.13.2 |
| RandomizedTesting Runner | ランダム化テスト実行。シード指定による再現可能なテスト | 2.7.1 |
| Apache Lucene Test Framework | Lucene関連コンポーネントのテストユーティリティ | 10.3.2 |
| Mockito | モックフレームワーク | 5.20.0 |
| Hamcrest | アサーションライブラリ | 2.1 |
| ByteBuddy | 動的クラス生成（Mockito依存） | 1.17.7 |
| Objenesis | オブジェクト生成（Mockito依存） | 3.3 |
| JaCoCo | コードカバレッジ計測 | 0.8.13 |
| Codecov | カバレッジレポートの集約・可視化 | CI統合 |
| JMH | マイクロベンチマーク | 1.35 |
| Gradle Test Retry Plugin | Flakyテストのリトライ | 1.6.2 |
| ForbiddenAPIs | 禁止APIの使用検出 | Gradleプラグイン |
| CodeQL | セキュリティ静的解析 | GitHub Actions統合（v4） |
| Spotless | コードフォーマット検証 | 8.0.0 |
| Docker / Docker Compose | テストフィクスチャ（GCS, S3, Azure, MinIO, HDFS, Kerberos等） | 開発環境依存 |
| Vagrant / VirtualBox | パッケージングテスト用VM管理 | 開発環境依存 |

## カバレッジ目標

| 対象 | 目標値 |
| --- | --- |
| 行カバレッジ | 明示的な数値目標は設定されていない。Codecov統合によりPR単位でカバレッジ変動を追跡 |
| 分岐カバレッジ | 明示的な数値目標は設定されていない。JaCoCo XML/HTML/CSVレポートで確認可能 |

備考: OpenSearchではカバレッジの絶対値目標よりも、テストの質（ランダム化テストによる多様なパターン網羅、適切なテストレベルの選択）を重視する方針を採っている。JaCoCo による計測は `./gradlew check -Dtests.coverage=true` で有効化され、`test`, `internalClusterTest`, `javaRestTest`, `yamlRestTest` の4種類のテスト実行データが集約される。

## テストデータ

- **ランダム化テスト**: RandomizedTesting Runnerにより、テストパラメータ（シャード数、レプリカ数、ストアタイプ等）がランダムに生成される。シード値（`-Dtests.seed=DEADBEEF`）を指定することで再現可能
- **テストフィクスチャ**: `test/fixtures/` ディレクトリに Docker Compose ベースのフィクスチャを配置。GCS, S3, Azure, MinIO, HDFS, Kerberos（krb5kdc）等の外部サービスをエミュレート
- **YAMLテストスイート**: `rest-api-spec/src/main/resources/rest-api-spec/test/` にYAML形式のRESTテストケースを配置。クライアント間で共有される標準テストデータ
- **BWCテストデータ**: 過去バージョンのOpenSearchディストリビューションを自動ダウンロードまたはソースからビルドして使用

## 不具合管理

- **Flakyテスト管理**: GitHubの `flaky-test` ラベルで追跡。Gradle Test Retry Plugin（`org.gradle.test-retry`）によりCI環境で最大3回リトライ（最大10失敗まで）。リトライ対象テストは `build.gradle` の `retry.filter.includeClasses` に明示的にリスト化
- **テスト失敗のPR通知**: Jenkins gradle-check ワークフローがPRにコメントでテスト結果を通知。成功（:white_check_mark:）、Flaky（:grey_exclamation:）、失敗（:x:）の3段階で報告
- **不具合チケット**: GitHub Issues で管理。Flakyテストは専用ラベル `flaky-test` で追跡し、根本原因の修正を推奨。新規テストのリトライリスト追加には厳格な根拠が必要
- **@AwaitsFix アノテーション**: 既知の不具合待ちテストに付与。デフォルトでスキップされ、`-Dtests.awaitsfix=true` で実行可能

## CI/CD連携

### パイプライン構成

| ワークフロー | トリガー | 実行内容 |
| --- | --- | --- |
| `gradle-check.yml` | push（mainブランチ等）、pull_request_target | Jenkins経由で `./gradlew check` を実行。全テストスイート（単体・結合・REST・BWC）を網羅。Codecovへのカバレッジアップロード |
| `precommit.yml` | pull_request | `./gradlew javadoc precommit --parallel` を実行。JDK 21, 25 × 5 OS（ubuntu, windows, macos, macos-intel, ubuntu-arm）のマトリクス |
| `assemble.yml` | pull_request | `./gradlew assemble --parallel` を実行。ビルド成功の確認。JDK 21, 25 × 4 OS |
| `codeql-analysis.yml` | push（main）、pull_request（main）、週次 | CodeQLによるJavaセキュリティ静的解析 |
| `benchmark-pull-request.yml` | pull_request | パフォーマンスベンチマークの実行 |

### テスト実行の流れ

1. 開発者がPRを作成
2. GitHub Actionsが `precommit` および `assemble` ワークフローを自動実行（マルチOS・マルチJDKマトリクス）
3. `gradle-check` ワークフローがJenkinsにテスト実行を委譲し、全テストスイートを実行
4. テスト結果がPRにコメントとして通知される
5. カバレッジレポートがCodecovにアップロードされる
6. mainブランチへのpush時にCodeQL解析が実行される

### テストリトライ戦略

CI環境（`BuildParams.isCi()` がtrue）では、Gradle Test Retry Plugin により以下の設定でリトライが行われる:

- 最大リトライ回数: 3
- 最大許容失敗数: 10
- リトライ後に成功したテストは失敗として扱わない（`failOnPassedAfterRetry = false`）
- リトライ対象は明示的にリスト化された既知のFlakyテストのみ

## 備考

### テスト基底クラスの階層

- `OpenSearchTestCase`: 全テストの基底。単体テスト向け
- `OpenSearchSingleNodeTestCase`: 単一ノードクラスタでのテスト。コンポーネント統合テスト向け
- `OpenSearchIntegTestCase`: マルチノードクラスタでのテスト。分散機能テスト向け
- `OpenSearchRestTestCase`: 外部REST APIテスト。Java REST テスト向け
- `OpenSearchClientYamlSuiteTestCase`: `OpenSearchRestTestCase` のサブクラス。YAMLベースRESTテスト向け
- `OpenSearchTokenStreamTestCase`: Lucene TokenStream テスト向け

### テスト命名規則

- 単体テスト: `*Tests.java`（例: `IndexSettingsTests.java`）
- 結合テスト（Internal Cluster）: `*IT.java`（例: `ClusterHealthIT.java`）
- RESTテスト（Java）: `*IT.java`（`javaRestTest` ソースセット内）
- RESTテスト（YAML）: `*IT.java`（`yamlRestTest` ソースセット内）

### テスト実行コマンド一覧

| コマンド | 説明 |
| --- | --- |
| `./gradlew check` | 全検証タスク（静的チェック・テスト・結合テスト）を実行 |
| `./gradlew precommit` | プリコミットチェック（フォーマット・ForbiddenAPIs・Javadoc等） |
| `./gradlew test` | 単体テストを実行 |
| `./gradlew internalClusterTest` | 内部クラスタ結合テストを実行 |
| `./gradlew :rest-api-spec:yamlRestTest` | YAML REST テストを実行 |
| `./gradlew bwcTest` | 後方互換性テストを実行 |
| `./gradlew packagingTest` | パッケージングテストを実行 |
| `./gradlew jacocoTestReport` | JaCoCo カバレッジレポートを生成 |
| `./gradlew check -Dtests.coverage=true` | カバレッジ計測付きで全テストを実行 |

### セキュリティ関連テスト

- **ForbiddenAPIs**: `jdk-signatures`, `opensearch-all-signatures`, `opensearch-test-signatures` に基づく禁止API検出
- **thirdPartyAudit**: サードパーティライブラリの不正クラスアクセス検出
- **FIPS 140-2テスト**: `BuildParams.isInFipsJvm()` によるFIPS環境でのテスト実行。BouncyCastle FIPS プロバイダを使用
- **Security Manager Agent**: `libs/agent-sm/agent` によるJavaセキュリティサンドボックスエージェントを全テストJVMに適用
