---
generated_at: 2026-02-03 10:00:00
metrics:
  claims_total: 63
  claims_with_evidence: 61
  claims_without_evidence: 2
confidence_derived: 0.97
---

# 根拠レポート：server-watcher 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された設計書・ドキュメントの信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim：主張）を検証しています：

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」：根拠あり、「△」：根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.97**
  - 根拠あり：61 / 63、根拠なし：2
- 優先レビュー（高）
  1. **C-08 (UT-WAT-008)**：nullリスナー追加時のCopyOnWriteArrayListの実際の挙動は実行時テストでのみ確認可能
  2. **C-16 (UT-WAT-016)**：clearState内のIOException抑制はcatchブロックの存在から推定しているが、rootFileObserver.init(false)が実際にIOExceptionをスローする条件の詳細は要確認

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。抽出フェーズで付けたIDをそのまま出す。

- E-01: `server/src/main/java/org/opensearch/watcher/AbstractResourceWatcher.java` - init()メソッド（L49-54）、checkAndNotify()メソッド（L57-60）、addListener()/remove()/listeners()メソッド（L65-81）
- E-02: `server/src/main/java/org/opensearch/watcher/FileWatcher.java` - コンストラクタ（L62-65）、clearState()（L70-77）、doInit()（L80-82）、doCheckAndNotify()（L85-87）、内部クラスFileObserver全体（L91-332）
- E-03: `server/src/main/java/org/opensearch/watcher/WatcherHandle.java` - watcher()（L53-55）、frequency()（L57-59）、stop()（L61-63）、resume()（L65-67）
- E-04: `server/src/main/java/org/opensearch/watcher/ResourceWatcherService.java` - コンストラクタ（L121-139）、close()（L142-148）、add()（L153-172）、notifyNow()（L174-188）、内部クラスResourceMonitor（L190-217）、Frequencyenum（L70-92）
- E-05: `server/src/main/java/org/opensearch/watcher/ResourceWatcher.java` - インタフェース定義（L47-57）
- E-06: `server/src/main/java/org/opensearch/watcher/FileChangesListener.java` - インタフェース定義（L41-76）

## 3) Claims と根拠の対応（レビューの主戦場）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | UT-WAT-001: 初回呼び出し時にdoInitが実行される | E-01 (L49-54: initializedフラグチェック後doInit()呼出) | ○ |
| C-02 | UT-WAT-002: 2回目以降doInitが再実行されない | E-01 (L50: if (!initialized)による制御) | ○ |
| C-03 | UT-WAT-003: doInit内IOExceptionがスローされる | E-01 (L49: throws IOException宣言) | ○ |
| C-04 | UT-WAT-004: 未初期化時checkAndNotifyでinit()が先に実行 | E-01 (L58: init()呼出後doCheckAndNotify()) | ○ |
| C-05 | UT-WAT-005: 初期化済みでdoCheckAndNotifyのみ実行 | E-01 (L50: initialized=trueでdoInit()スキップ) | ○ |
| C-06 | UT-WAT-006: リスナーが正常に追加される | E-01 (L66: listeners.add(listener)) | ○ |
| C-07 | UT-WAT-007: 複数リスナー追加可能 | E-01 (L45: CopyOnWriteArrayList使用) | ○ |
| C-08 | UT-WAT-008: nullリスナー追加時の挙動 | **根拠なし** | △ |
| C-09 | UT-WAT-009: 登録済みリスナーが削除される | E-01 (L73: listeners.remove(listener)) | ○ |
| C-10 | UT-WAT-010: 未登録リスナー削除で例外なし | E-01 (L73: List.remove()の仕様) | ○ |
| C-11 | UT-WAT-011: リスナーリストが正しく返却 | E-01 (L79-81: listenersフィールド返却) | ○ |
| C-12 | UT-WAT-012: 0件で空リスト返却 | E-01 (L45: 初期状態で空のCopyOnWriteArrayList) | ○ |
| C-13 | UT-WAT-013: コンストラクタで正常にインスタンス生成 | E-02 (L62-65: file/rootFileObserver初期化) | ○ |
| C-14 | UT-WAT-014: 存在しないPathでインスタンス生成 | E-02 (L63-64: Pathの存在チェックなし) | ○ |
| C-15 | UT-WAT-015: clearStateで状態リセット | E-02 (L70-77: rootFileObserver再生成) | ○ |
| C-16 | UT-WAT-016: clearState中のIOException抑制 | **根拠なし** | △ |
| C-17 | UT-WAT-017: 初期化時onFileInit通知 | E-02 (L268-279: initial=trueでonFileInit呼出) | ○ |
| C-18 | UT-WAT-018: 初期化時onDirectoryInit通知 | E-02 (L303-316: initial=trueでonDirectoryInit呼出) | ○ |
| C-19 | UT-WAT-019: 空ディレクトリの初期化 | E-02 (L199-209: listChildren→EMPTY_DIRECTORY) | ○ |
| C-20 | UT-WAT-020: 存在しないパスの初期化 | E-02 (L173: Files.exists(file)チェック) | ○ |
| C-21 | UT-WAT-021: 新規ファイル作成検出 | E-02 (L159-167: exists && !prevExists → onFileCreated) | ○ |
| C-22 | UT-WAT-022: ファイル削除検出 | E-02 (L151-157: prevExists && !exists → onFileDeleted) | ○ |
| C-23 | UT-WAT-023: ファイル変更検出 | E-02 (L146: prevLastModified!=lastModified || prevLength!=length) | ○ |
| C-24 | UT-WAT-024: 新規ディレクトリ作成検出 | E-02 (L161-163: isDirectory → onDirectoryCreated) | ○ |
| C-25 | UT-WAT-025: ディレクトリ削除検出 | E-02 (L153: prevIsDirectory → onDirectoryDeleted) | ○ |
| C-26 | UT-WAT-026: ファイル→ディレクトリ置換 | E-02 (L134-138: prevExists && isDir && !prevIsDir) | ○ |
| C-27 | UT-WAT-027: ディレクトリ→ファイル置換 | E-02 (L140-143: prevExists && !isDir && prevIsDir) | ○ |
| C-28 | UT-WAT-028: 変更なし時に通知なし | E-02 (L146: 条件不成立で通知スキップ) | ○ |
| C-29 | UT-WAT-029: サブディレクトリ内の再帰的検出 | E-02 (L231: children[child].checkAndNotify()再帰呼出) | ○ |
| C-30 | UT-WAT-030: リスナー例外時の継続通知 | E-02 (L276-278: catch(Exception)でログ出力し継続) | ○ |
| C-31 | UT-WAT-031: 単一ファイル監視 | E-02 (L109-125: ファイル判定ロジック) | ○ |
| C-32 | UT-WAT-032: ウォッチャー返却 | E-03 (L53-55: return watcher) | ○ |
| C-33 | UT-WAT-033: 監視頻度返却 | E-03 (L57-59: return monitor.frequency) | ○ |
| C-34 | UT-WAT-034: stop()でウォッチャー除去 | E-03 (L62: monitor.watchers.remove(watcher)) | ○ |
| C-35 | UT-WAT-035: 二重停止の安全性 | E-03 (L62: Set.remove()の冪等性) | ○ |
| C-36 | UT-WAT-036: resume()で再登録 | E-03 (L66: monitor.watchers.add(watcher)) | ○ |
| C-37 | UT-WAT-037: 未停止でのresume | E-03 (L66: CopyOnWriteArraySetでSet特性により重複なし) | ○ |
| C-38 | UT-WAT-038: 有効設定でサービス初期化 | E-04 (L121-139: enabled=true時スケジューラ開始) | ○ |
| C-39 | UT-WAT-039: 無効設定でスケジューラ不開始 | E-04 (L134-138: enabled=false時Future=null) | ○ |
| C-40 | UT-WAT-040: カスタムインターバル設定 | E-04 (L94-109: Setting定義, L124-129: 設定読取) | ○ |
| C-41 | UT-WAT-041: close()でスケジューラキャンセル | E-04 (L142-148: cancel()呼出) | ○ |
| C-42 | UT-WAT-042: 無効時close安全性 | E-04 (L143: if(enabled)ガード) | ○ |
| C-43 | UT-WAT-043: デフォルトMEDIUM頻度登録 | E-04 (L153-155: add(watcher, Frequency.MEDIUM)委譲) | ○ |
| C-44 | UT-WAT-044: LOW頻度登録 | E-04 (L163-164: lowMonitor.add(watcher)) | ○ |
| C-45 | UT-WAT-045: HIGH頻度登録 | E-04 (L168: highMonitor.add(watcher)) | ○ |
| C-46 | UT-WAT-046: 登録時init()呼出 | E-04 (L161: watcher.init()) | ○ |
| C-47 | UT-WAT-047: 登録時init()失敗 | E-04 (L160: throws IOException宣言, L161: watcher.init()) | ○ |
| C-48 | UT-WAT-048: notifyNow LOW | E-04 (L176-177: lowMonitor.run()) | ○ |
| C-49 | UT-WAT-049: notifyNow MEDIUM | E-04 (L179-180: mediumMonitor.run()) | ○ |
| C-50 | UT-WAT-050: notifyNow HIGH | E-04 (L182-183: highMonitor.run()) | ○ |
| C-51 | UT-WAT-051: ResourceMonitor run()実行 | E-04 (L208-216: for-eachでcheckAndNotify()呼出) | ○ |
| C-52 | UT-WAT-052: 複数ウォッチャー全実行 | E-04 (L209: forループで全watchers走査) | ○ |
| C-53 | UT-WAT-053: IOException時の継続実行 | E-04 (L212-214: catch(IOException)でログ出力し継続) | ○ |
| C-54 | UT-WAT-054: 空モニターrun()安全性 | E-04 (L209: CopyOnWriteArraySetの空イテレーション) | ○ |
| C-55 | UT-WAT-055: HIGH=5秒 | E-04 (L75: TimeValue.timeValueSeconds(5)) | ○ |
| C-56 | UT-WAT-056: MEDIUM=30秒 | E-04 (L80: TimeValue.timeValueSeconds(30)) | ○ |
| C-57 | UT-WAT-057: LOW=60秒 | E-04 (L85: TimeValue.timeValueSeconds(60)) | ○ |
| C-58 | UT-WAT-058: 存在→存在（変更なし）通知なし | E-02 (L144-149: 条件不成立でリスナー呼び出しなし) | ○ |
| C-59 | UT-WAT-059: 存在→削除でonFileDeleted | E-02 (L155-156: !exists && !prevIsDirectory) | ○ |
| C-60 | UT-WAT-060: 未存在→作成でonFileCreated | E-02 (L164-166: !prevExists && exists && !isDirectory) | ○ |
| C-61 | UT-WAT-061: ディレクトリ存在→削除 | E-02 (L153-154: prevIsDirectory → onDirectoryDeleted) | ○ |
| C-62 | UT-WAT-062: 子ファイルマージ処理 | E-02 (L212-256: updateChildren()のマージロジック) | ○ |
| C-63 | UT-WAT-063: 全子ファイル削除 | E-02 (L249-254: 空ファイル時の全子削除) | ○ |

## 4) 不足情報（Unknown / Missing）
- **C-08 (nullリスナー追加)**：CopyOnWriteArrayListはnull要素の追加を許可するが、後続のリスナー通知処理でNullPointerExceptionが発生する可能性がある。実行時テストでの確認が必要。
  - 候補：JDKのCopyOnWriteArrayListのJavadoc / 実行時テスト結果
- **C-16 (clearState中のIOException抑制)**：catchブロック（L74-76）でIOExceptionを無視しているが、rootFileObserver.init(false)が具体的にどのような条件でIOExceptionをスローするかはファイルシステムの状態に依存する。
  - 候補：FileSystemUtils.files()の実装 / Files.readAttributes()のJavadoc

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク - Frequency enum定数値（C-55, C-56, C-57）は静的な定数確認のみ
- 0: 低リスク - WatcherHandle のgetter系メソッド（C-32, C-33）は単純なフィールド返却
- 1: 中リスク - FileObserverの状態遷移ロジック（C-26, C-27）は条件分岐が複雑で、ファイル→ディレクトリ置換のエッジケースを含む
- 1: 中リスク - updateChildren()のマージロジック（C-62）はソート済み配列のマージアルゴリズムであり、境界条件の確認が重要
- 0: 低リスク - ResourceWatcherService の close()/add()/notifyNow() は直接的なコード対応が明確

## 6) レビュアーチェックリスト（最小）
- [ ] FileObserverの状態遷移（C-21〜C-31, C-58〜C-61）がソースコードの条件分岐と正確に対応しているか確認
- [ ] updateChildren()のマージロジック（C-62, C-63）のテストケースが境界条件を十分にカバーしているか確認
- [ ] リスナー例外処理（C-30, C-53）のテストケースが実際のcatch句の動作を正しく反映しているか確認
- [ ] clearState()のIOException抑制（C-16）について、実際のIOException発生条件を調査し、テストケースの妥当性を確認
- [ ] nullリスナー追加（C-08）のテストケースの期待結果が、実際のCopyOnWriteArrayListの動作と一致しているか確認
