Keploy — eBPFでトラフィックを傍受しAPIテストを自動生成する仕組み
eBPFがカーネルでconnect()の宛先をこっそり書き換える透過プロキシパターン
Go製のCNCFプロジェクト。17k+スター。コード変更ゼロでAPIテストを自動生成する。
核心原理:eBPF宛先リダイレクト
全てのアプリは外部通信にカーネルsyscallを使う。connect(postgres:5432)を呼ぶとカーネルがTCP接続を作る。KeployはここにeBPFを付ける。
eBPFプログラムがSockOps(cgroup付着)とconnect4/6フックでアウトバウンド接続を監視。アプリがpostgres:5432にconnectしようとすると、eBPFが宛先を127.0.0.1:proxyPortに書き換える。元の宛先はredirectProxyMap共有マップに保存。
アプリはpostgresに接続したつもり。実際はKeployのプロキシに接続している。プロキシが元の宛先を照会して実際のpostgresに転送しつつ、往来するトラフィックを全て録画。
透過プロキシのプロトコル解析
プロキシは接続の先頭バイトでプロトコルを判別。HTTP、MySQL、PostgreSQL、MongoDB、Redis、Kafka、gRPC — それぞれ専用パーサーがリクエスト/レスポンスペアを捕捉。
録画結果:
インバウンドHTTP → TestCase(YAML)
アウトバウンドDB/外部API → Mock(YAML)
マッピング → どのMockがどのTestCaseに属するか
テスト(再生)モード
keploy testで実行すると録画済みHTTPリクエストをアプリに再送信。アプリのDB呼び出しにはプロキシがMockで応答。実DBなしでテストが動く。
限界
Linux専用 — eBPFはカーネル5.15+必要。macOS/WindowsはDocker経由のみ。
SQLite捕捉不可 — ネットワークソケットを使わない通信はeBPFフックに引っかからない。PostgreSQL/MySQLのみ。
統合テストのみ — ビジネスロジックの単体テストは生成しない。
スキーマ変更に脆弱 — DBカラム追加/削除でMockが壊れる。再録画が必要。
トラフィック依存 — 叩いてないAPIにはテストもない。エラーケース、エッジケースは手動で作成が必要。
動作フロー
eBPFがconnect() syscallを傍受して宛先をプロキシにリダイレクト(アプリは知らない)
透過プロキシが先頭バイトでプロトコル判別→専用パーサーでリクエスト/レスポンス捕捉
インバウンド(TestCase)+アウトバウンド(Mock)をgoroutineチャネルで同時収集→YAML保存
再生時MockがDB/外部APIを代替 — 実インフラなしでオフラインテスト
メリット
- ✓ コード変更ゼロ — eBPFがカーネルで動作するためSDK不要、言語非依存
- ✓ HTTP/gRPC/MySQL/Postgres/MongoDB/Redis/Kafka+TLS透過処理
デメリット
- ✗ Linux専用(カーネル5.15+)。macOS/WindowsはDocker必須
- ✗ SQLite等ネットワーク不使用DBは捕捉不可。統合テストのみ生成(単体テスト不可)