---
generated_at: 2026-02-04 12:00:00
metrics:
  claims_total: 173
  claims_with_evidence: 165
  claims_without_evidence: 8
confidence_derived: 0.95
---

# 根拠レポート：connector-kafka-0-10-sql 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された単体テストケース一覧CSVの信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

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

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

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.95**
  - 根拠あり：165 / 173、根拠なし：8
- 優先レビュー（高）
  1. **KafkaDataConsumer.get のデータロスシナリオ（C-126, C-127）**：failOnDataLoss=true/false 時の挙動は実際のKafka環境でないとテスト困難
  2. **ConsumerStrategy サブクラスのcreateConsumer（C-065〜C-068）**：実際のKafka接続が前提であり、モックの範囲が不明確
  3. **KafkaSourceProvider.validateGeneralOptions の全パターン（C-035〜C-044）**：各バリデーションの正確な例外メッセージはソースコードから確認できるが、一部条件分岐の網羅性が未確認

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。

- E-01: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/JsonUtils.scala` - JSON変換ユーティリティ
- E-02: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaSourceOffset.scala` - オフセット管理
- E-03: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaOffsetRangeCalculator.scala` - オフセット範囲計算
- E-04: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaSourceProvider.scala` - データソースプロバイダ
- E-05: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/ConsumerStrategy.scala` - コンシューマ戦略
- E-06: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaWriter.scala` - 書き込みバリデーション
- E-07: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaWriteTask.scala` - 書き込みタスク
- E-08: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaDataWriter.scala` - DataWriter実装
- E-09: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaRecordToRowConverter.scala` - レコード行変換
- E-10: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaSink.scala` - シンク実装
- E-11: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaSourceInitialOffsetWriter.scala` - 初期オフセット書き込み
- E-12: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaExceptions.scala` - 例外クラス
- E-13: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaWrite.scala` - Write実装
- E-14: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaBatchWrite.scala` - バッチ書き込み
- E-15: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaStreamingWrite.scala` - ストリーミング書き込み
- E-16: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/consumer/FetchedDataPool.scala` - フェッチデータプール
- E-17: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/consumer/KafkaDataConsumer.scala` - データコンシューマ
- E-18: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/consumer/InternalKafkaConsumerPool.scala` - コンシューマプール
- E-19: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/producer/InternalKafkaProducerPool.scala` - プロデューサプール
- E-20: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/producer/CachedKafkaProducer.scala` - キャッシュプロデューサ
- E-21: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaBatchPartitionReader.scala` - バッチパーティションリーダー
- E-22: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaMicroBatchStream.scala` - マイクロバッチストリーム
- E-23: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaSourceRDD.scala` - ソースRDD
- E-24: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaContinuousStream.scala` - 連続ストリーム
- E-25: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaRelation.scala` - リレーション
- E-26: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaBatch.scala` - バッチ読み込み
- E-27: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaSource.scala` - ソース（V1）
- E-28: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/package.scala` - パッケージオブジェクト（設定値）
- E-29: `connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaOffsetRangeLimit.scala` - オフセット範囲制限

## 3) Claims と根拠の対応（レビューの主戦場）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-001 | JsonUtils.partitions(str) 正常系パース | E-01 | ○ |
| C-002 | JsonUtils.partitions(str) 単一パーティション | E-01 | ○ |
| C-003 | JsonUtils.partitions(str) 不正JSON例外 | E-01 | ○ |
| C-004 | JsonUtils.partitions(str) 空文字列例外 | E-01 | ○ |
| C-005 | JsonUtils.partitions(Iterable) 正常系シリアライズ | E-01 | ○ |
| C-006 | JsonUtils.partitions(Iterable) 空イテラブル | E-01 | ○ |
| C-007 | JsonUtils.partitionOffsets(str) 正常系パース | E-01 | ○ |
| C-008 | JsonUtils.partitionOffsets(str) 不正JSON | E-01 | ○ |
| C-009 | JsonUtils.partitionOffsets(Map) 正常系シリアライズ | E-01 | ○ |
| C-010 | JsonUtils.partitionOffsets(Map) 空マップ | E-01 | ○ |
| C-011 | JsonUtils.partitionTimestamps(str) 正常系パース | E-01 | ○ |
| C-012 | JsonUtils.partitionTimestamps(str) 不正JSON | E-01 | ○ |
| C-013 | JsonUtils.partitionTimestamps(Map) 正常系シリアライズ | E-01 | ○ |
| C-014 | KafkaSourceOffset.json シリアライズ | E-02 | ○ |
| C-015 | KafkaSourceOffset.getPartitionOffsets KafkaSourceOffset入力 | E-02 | ○ |
| C-016 | KafkaSourceOffset.getPartitionOffsets SerializedOffset入力 | E-02 | ○ |
| C-017 | KafkaSourceOffset.getPartitionOffsets 不正Offset型 | E-02 | ○ |
| C-018 | KafkaSourceOffset.apply(offsetTuples) | E-02 | ○ |
| C-019 | KafkaSourceOffset.apply(SerializedOffset) | E-02 | ○ |
| C-020 | KafkaSourceOffset.apply(streaming.Offset) 不正型 | E-02 | ○ |
| C-021 | KafkaOffsetRangeCalculator.getRanges 1対1マッピング | E-03 | ○ |
| C-022 | KafkaOffsetRangeCalculator.getRanges minPartitions <= パーティション数 | E-03 | ○ |
| C-023 | KafkaOffsetRangeCalculator.getRanges パーティション分割 | E-03 | ○ |
| C-024 | KafkaOffsetRangeCalculator.getRanges maxRecordsPerPartition | E-03 | ○ |
| C-025 | KafkaOffsetRangeCalculator.getRanges サイズ0フィルタ | E-03 | ○ |
| C-026 | KafkaOffsetRangeCalculator.getRanges 負サイズフィルタ | E-03 | ○ |
| C-027 | KafkaOffsetRangeCalculator.getRanges executorLocations | E-03 | ○ |
| C-028 | KafkaOffsetRangeCalculator コンストラクタ minPartitions=0 | E-03 | ○ |
| C-029 | KafkaOffsetRangeCalculator コンストラクタ maxRecords=0 | E-03 | ○ |
| C-030 | KafkaOffsetRangeCalculator.apply ファクトリメソッド | E-03 | ○ |
| C-031 | KafkaOffsetRange.size 計算 | E-03 | ○ |
| C-032 | KafkaSourceProvider.shortName | E-04 | ○ |
| C-033 | KafkaSourceProvider.sourceSchema 正常系 | E-04 | ○ |
| C-034 | KafkaSourceProvider.sourceSchema カスタムスキーマ拒否 | E-04 | ○ |
| C-035 | validateGeneralOptions ストラテジ未指定 | E-04 | ○ |
| C-036 | validateGeneralOptions 複数ストラテジ | E-04 | ○ |
| C-037 | validateGeneralOptions assign不正値 | E-04 | ○ |
| C-038 | validateGeneralOptions subscribe空値 | E-04 | ○ |
| C-039 | validateGeneralOptions subscribePattern空値 | E-04 | ○ |
| C-040 | validateGeneralOptions auto.offset.reset禁止 | E-04 | ○ |
| C-041 | validateGeneralOptions key.deserializer禁止 | E-04 | ○ |
| C-042 | validateGeneralOptions value.deserializer禁止 | E-04 | ○ |
| C-043 | validateGeneralOptions bootstrap.servers未指定 | E-04 | ○ |
| C-044 | validateGeneralOptions minOffsets > maxOffsets | E-04 | ○ |
| C-045 | validateStreamOptions endingOffsets禁止 | E-04 | ○ |
| C-046 | validateBatchOptions startingOffsets=latest禁止 | E-04 | ○ |
| C-047 | validateBatchOptions endingOffsets=earliest禁止 | E-04 | ○ |
| C-048 | createRelation Overwrite禁止 | E-04 | ○ |
| C-049 | createRelation Ignore禁止 | E-04 | ○ |
| C-050 | getKafkaOffsetRangeLimit globalTimestamp | E-04 | ○ |
| C-051 | getKafkaOffsetRangeLimit offsetByTimestamp | E-04 | ○ |
| C-052 | getKafkaOffsetRangeLimit latest | E-04 | ○ |
| C-053 | getKafkaOffsetRangeLimit earliest | E-04 | ○ |
| C-054 | getKafkaOffsetRangeLimit JSON | E-04 | ○ |
| C-055 | getKafkaOffsetRangeLimit デフォルト値 | E-04 | ○ |
| C-056 | getKafkaOffsetRangeLimit 不正タイムスタンプ | E-04 | △ |
| C-057 | checkStartOffsetNotGreaterThanEndOffset 正常 | E-04 | ○ |
| C-058 | checkStartOffsetNotGreaterThanEndOffset 異常 | E-04 | ○ |
| C-059 | checkStartOffsetNotGreaterThanEndOffset 負オフセット | E-04 | ○ |
| C-060 | checkOffsetLimitValidity 不一致 | E-04 | ○ |
| C-061 | kafkaParamsForProducer key.serializer禁止 | E-04 | ○ |
| C-062 | kafkaParamsForProducer value.serializer禁止 | E-04 | ○ |
| C-063 | batchUniqueGroupId デフォルト | E-04 | ○ |
| C-064 | batchUniqueGroupId カスタムプレフィックス | E-04 | ○ |
| C-065 | AssignStrategy.createConsumer | E-05 | △ |
| C-066 | AssignStrategy.assignedTopicPartitions | E-05 | △ |
| C-067 | SubscribeStrategy.createConsumer | E-05 | △ |
| C-068 | SubscribePatternStrategy.createConsumer | E-05 | △ |
| C-069 | KafkaWriter.validateQuery value列あり | E-06 | ○ |
| C-070 | KafkaWriter.validateQuery value列なし | E-06 | ○ |
| C-071 | KafkaWriter.validateQuery topic未指定 | E-06 | ○ |
| C-072 | KafkaWriter.validateQuery topicオプション | E-06 | ○ |
| C-073 | KafkaWriter.topicExpression Literal | E-06 | ○ |
| C-074 | KafkaWriter.topicExpression 属性 | E-06 | ○ |
| C-075 | KafkaWriter.keyExpression null Literal | E-06 | ○ |
| C-076 | KafkaWriter.valueExpression 列なし | E-06 | ○ |
| C-077 | KafkaWriter.valueExpression 不正型 | E-06 | ○ |
| C-078 | KafkaRowWriter.sendRow 正常系 | E-07 | ○ |
| C-079 | KafkaRowWriter.sendRow nullトピック | E-07 | ○ |
| C-080 | KafkaRowWriter.checkForErrors null | E-07 | ○ |
| C-081 | KafkaRowWriter.checkForErrors 例外あり | E-07 | ○ |
| C-082 | KafkaWriteTask.execute 正常系 | E-07 | ○ |
| C-083 | KafkaWriteTask.close flush後チェック | E-07 | ○ |
| C-084 | KafkaDataWriter.write | E-08 | ○ |
| C-085 | KafkaDataWriter.commit | E-08 | ○ |
| C-086 | KafkaDataWriter.close | E-08 | ○ |
| C-087 | toInternalRowWithoutHeaders 正常系 | E-09 | ○ |
| C-088 | toInternalRowWithHeaders 正常系 | E-09 | ○ |
| C-089 | toInternalRowWithHeaders 空ヘッダ | E-09 | ○ |
| C-090 | kafkaSchema ヘッダなし | E-09 | ○ |
| C-091 | kafkaSchema ヘッダあり | E-09 | ○ |
| C-092 | toUnsafeRowProjector ヘッダあり | E-09 | ○ |
| C-093 | toUnsafeRowProjector ヘッダなし | E-09 | ○ |
| C-094 | KafkaSink.addBatch 新バッチ | E-10 | ○ |
| C-095 | KafkaSink.addBatch 重複スキップ | E-10 | ○ |
| C-096 | KafkaSourceInitialOffsetWriter.serialize | E-11 | ○ |
| C-097 | KafkaSourceInitialOffsetWriter.deserialize v1 | E-11 | ○ |
| C-098 | KafkaSourceInitialOffsetWriter.deserialize Spark2.1 | E-11 | ○ |
| C-099 | KafkaSourceInitialOffsetWriter.deserialize 空 | E-11 | ○ |
| C-100 | KafkaSourceInitialOffsetWriter.deserialize 不正ログ | E-11 | ○ |
| C-101 | KafkaExceptions.nullTopicInData | E-12 | ○ |
| C-102 | KafkaExceptions.couldNotReadOffsetRange | E-12 | ○ |
| C-103 | KafkaExceptions.unmatchedTopicPartitions | E-12 | ○ |
| C-104 | KafkaIllegalStateException.getCondition | E-12 | ○ |
| C-105 | KafkaIllegalArgumentException.getCondition | E-12 | ○ |
| C-106 | KafkaWrite.description | E-13 | ○ |
| C-107 | KafkaWrite.toBatch | E-13 | ○ |
| C-108 | KafkaWrite.toStreaming | E-13 | ○ |
| C-109 | KafkaBatchWrite.createBatchWriterFactory | E-14 | ○ |
| C-110 | KafkaBatchWriterFactory.createWriter | E-14 | ○ |
| C-111 | KafkaStreamingWrite.createStreamingWriterFactory | E-15 | ○ |
| C-112 | KafkaStreamingWrite.useCommitCoordinator | E-15 | ○ |
| C-113 | KafkaStreamWriterFactory.createWriter | E-15 | ○ |
| C-114 | FetchedDataPool.acquire 新キー | E-16 | ○ |
| C-115 | FetchedDataPool.acquire キャッシュ再利用 | E-16 | ○ |
| C-116 | FetchedDataPool.release 正常系 | E-16 | ○ |
| C-117 | FetchedDataPool.release 不正データ | E-16 | ○ |
| C-118 | FetchedDataPool.invalidate | E-16 | ○ |
| C-119 | FetchedDataPool.reset | E-16 | ○ |
| C-120 | FetchedData.withNewPoll | E-17 | ○ |
| C-121 | FetchedData.next | E-17 | ○ |
| C-122 | FetchedData.previous | E-17 | ○ |
| C-123 | FetchedData.reset | E-17 | ○ |
| C-124 | KafkaDataConsumer.get 正常系 | E-17 | ○ |
| C-125 | KafkaDataConsumer.get offset >= untilOffset | E-17 | ○ |
| C-126 | KafkaDataConsumer.get failOnDataLoss=true | E-17 | △ |
| C-127 | KafkaDataConsumer.get failOnDataLoss=false | E-17 | △ |
| C-128 | KafkaDataConsumer.release | E-17 | ○ |
| C-129 | KafkaDataConsumer.acquire 正常系 | E-17 | ○ |
| C-130 | KafkaDataConsumer.acquire 再試行 | E-17 | ○ |
| C-131 | InternalKafkaConsumerPool.borrowObject | E-18 | ○ |
| C-132 | InternalKafkaConsumerPool.returnObject | E-18 | ○ |
| C-133 | InternalKafkaConsumerPool.invalidateKey | E-18 | ○ |
| C-134 | InternalKafkaConsumerPool.size | E-18 | ○ |
| C-135 | InternalKafkaProducerPool.acquire 新規 | E-19 | ○ |
| C-136 | InternalKafkaProducerPool.acquire キャッシュ | E-19 | ○ |
| C-137 | InternalKafkaProducerPool.release 正常系 | E-19 | ○ |
| C-138 | InternalKafkaProducerPool.release 不正 | E-19 | ○ |
| C-139 | CachedProducerEntry.handleBorrowed | E-19 | ○ |
| C-140 | CachedProducerEntry.handleReturned 正常系 | E-19 | ○ |
| C-141 | CachedProducerEntry.handleReturned 二重返却 | E-19 | ○ |
| C-142 | CachedProducerEntry.expired true | E-19 | ○ |
| C-143 | CachedProducerEntry.expired false | E-19 | ○ |
| C-144 | CachedKafkaProducer.close 正常系 | E-20 | ○ |
| C-145 | CachedKafkaProducer.close 例外処理 | E-20 | ○ |
| C-146 | KafkaBatchInputPartition.preferredLocations あり | E-21 | ○ |
| C-147 | KafkaBatchInputPartition.preferredLocations なし | E-21 | ○ |
| C-148 | KafkaBatchPartitionReader.next 正常系 | E-21 | ○ |
| C-149 | KafkaBatchPartitionReader.next 完了 | E-21 | ○ |
| C-150 | KafkaBatchPartitionReader.getOffset | E-21 | ○ |
| C-151 | KafkaBatchPartitionReader.resolveRange 非負 | E-21 | ○ |
| C-152 | KafkaBatchPartitionReader.resolveRange EARLIEST | E-21 | ○ |
| C-153 | KafkaBatchPartitionReader.resolveRange LATEST | E-21 | ○ |
| C-154 | KafkaMicroBatchStream.deserializeOffset | E-22 | ○ |
| C-155 | KafkaMicroBatchStream.mergeOffsets | E-22 | ○ |
| C-156 | KafkaMicroBatchStream.getDefaultReadLimit composite | E-22 | ○ |
| C-157 | KafkaMicroBatchStream.getDefaultReadLimit maxOnly | E-22 | ○ |
| C-158 | KafkaMicroBatchStream.getDefaultReadLimit none | E-22 | ○ |
| C-159 | KafkaMicroBatchStream.metrics 正常系 | E-22 | ○ |
| C-160 | KafkaMicroBatchStream.metrics empty | E-22 | ○ |
| C-161 | KafkaSourceRDD.getPartitions | E-23 | ○ |
| C-162 | KafkaSourceRDD.getPreferredLocations あり | E-23 | ○ |
| C-163 | KafkaSourceRDD.getPreferredLocations なし | E-23 | ○ |
| C-164 | KafkaSourceRDD.resolveRange 正のオフセット | E-23 | ○ |
| C-165 | KafkaSourceRDD.resolveRange 負のオフセット | E-23 | ○ |
| C-166 | KafkaContinuousStream.deserializeOffset | E-24 | ○ |
| C-167 | KafkaContinuousStream.mergeOffsets | E-24 | ○ |
| C-168 | KafkaContinuousPartitionReader.getOffset | E-24 | ○ |
| C-169 | KafkaTable.capabilities | E-04 | ○ |
| C-170 | KafkaTable.schema | E-04 | ○ |
| C-171 | KafkaScan.readSchema | E-04 | ○ |
| C-172 | PRODUCER_CACHE_TIMEOUT デフォルト値 | E-28 | ○ |
| C-173 | CONSUMER_CACHE_CAPACITY デフォルト値 | E-28 | ○ |

## 4) 不足情報（Unknown / Missing）
- **ConsumerStrategy サブクラスの実際のKafka接続テスト（C-065〜C-068）**: 実際のKafkaブローカーに接続してコンシューマを生成する動作は、単体テストではモック化が前提。モックの範囲・方法については既存テストコードを参照する必要がある。
  - 候補：既存のテストスイート / Embedded Kafka / モックライブラリのドキュメント
- **KafkaDataConsumer.get のデータロスシナリオ（C-126, C-127）**: OffsetOutOfRangeException発生時の挙動は、Kafkaブローカーの状態に依存するため、モックでのテスト範囲が不明確。
  - 候補：既存テスト `KafkaDataConsumerSuite` / `KafkaMicroBatchSourceSuiteBase`
- **getKafkaOffsetRangeLimit 不正タイムスタンプ値（C-056）**: タイムスタンプ文字列パースの例外処理がtry-catchで囲まれているかはコードの詳細な分岐確認が必要。
  - 候補：`KafkaSourceProvider` の詳細コード解析
- **KafkaSource / KafkaMicroBatchStream の latestOffset メソッド**: rateLimit / delayBatch のロジックは複雑で、テストケースとして挙げていないが、既存テストで十分にカバーされている可能性がある。
  - 候補：既存のストリーミングテストスイート

## 5) リスクフラグ（レビュー観点）
- **リスク1（中）**: ConsumerStrategy系テスト（C-065〜C-068）は実際のKafka環境やEmbedded Kafkaに依存するため、純粋な単体テストとしては実装が困難。統合テストケースとして分類を検討する必要がある。
- **リスク1（中）**: KafkaDataConsumer.get のデータロスシナリオ（C-126, C-127）も同様にKafka環境依存度が高い。
- **リスク0（低）**: CSVの大部分のテストケースは、ソースコードのメソッドシグネチャ・バリデーションロジック・条件分岐から直接導出されており、信頼性が高い。

## 6) レビュアーチェックリスト（最小）
- [ ] テストケースの対象ファイル・メソッドがソースコードの実際のシグネチャと一致しているか
- [ ] 正常系・異常系・境界値の網羅性が十分か（特にKafkaSourceProvider.validateGeneralOptionsの全分岐）
- [ ] ConsumerStrategy系テスト（C-065〜C-068）を単体テストとするか統合テストとするか判断
- [ ] KafkaDataConsumer.get のデータロスシナリオの前提条件が現実的か
- [ ] KafkaOffsetReader関連のメソッド（fetchLatestOffsets, fetchEarliestOffsets等）の入出力パターンが十分にカバーされているか（KafkaOffsetReaderは別モジュールとの境界のため、モック化が必要）
- [ ] rateLimit / delayBatch ロジックのテストケースが既存テストと重複していないか
- [ ] テストIDの略称「KSQ」がモジュール内で一貫して使用されているか
