📅 2026年04月08日 18:17
Technical teardown of the Rust CLI that speeds up our tests by 6x - Rust CLIでテストを6倍速くした仕組みを徹底解剖
CI時間を劇的短縮する実戦的テクニック:Offloadが“テストを6倍速く”した内部アーキテクチャ
要約
Offloadはテストの発見をローカルで行い、準備済みのクラウド「サンドボックス」を大量に並列実行してCPUボトルネックを解消するRust製オーケストレータ。キャッシュ化されたイメージ・バッチ実行・並列リトライでスループットを大幅に改善する。
この記事を読むべき理由
日本でもモノリポ/大規模CIで「書くよりテストが遅い」課題が増加中。Offloadは並列実行とイメージ差分配布で回帰確認やE2Eの待ち時間を短縮でき、開発ループの高速化に直結する実運用ヒントが得られる。
詳細解説
- 概念:ローカルでテストIDを列挙(discovery)し、そのリストをクラウド上の多数の「サンドボックス」に割り振って並列実行。テスト結果はJUnit XMLにマージして報告する。
- サンドボックス:Modalを使ったエフェメラル環境。ベースイメージに差分(patch)だけを適用→スナップショット→多数複製することでイメージ構築コストを削減。
- スケジューリング:以前実行時間を元にLPT(Longest Processing Time)で負荷分散。バッチ化でI/Oとハーネス起動オーバーヘッドを低減。将来的にはワークスティーリング等も検討中。
- フレーク対策:同一テストを複数サンドボックスで並列に実行し、「どれか一つ成功したら終了」することでリトライ遅延をほぼゼロに。
- フレームワーク対応:pytest、cargo-nextest、vitest等に第一級対応。フレームワークは「テストIDを列挙し、個別実行できる」インターフェースが必要。重複IDは事前に解消する運用が推奨。
- 実装スタック:Rust+tokioで非同期オーケストレーション。結果はjunit.xmlが単一の真実源。ログ・アーティファクトはdownload_globs等で取得可能。
- 拡張性:RustのトレイトでTestFrameworkやSandboxProviderを実装すれば独自フレームワーク/プロバイダを追加可能(OSSコントリビュート歓迎)。
参考となる最小例(Rustのトレイト概念):
pub trait TestFramework {
async fn discover(&self, paths: &[PathBuf], filters: &str, group: &str)
-> FrameworkResult<Vec<TestRecord>>;
fn produce_test_execution_command(&self, tests: &[TestInstance], result_path: &str, fail_fast: bool) -> Command;
}
準備差分を使う例(概念的なbash):
BASE_COMMIT=$(cat .offload-base-commit)
mkdir -p /tmp/offload-upload
./scripts/generate_patch_for_offload.sh $BASE_COMMIT > /tmp/offload-upload/patch
offload run --copy-dir="/tmp/offload-upload:/offload-upload" {args}
実践ポイント
- 使うべきケース:CPU重め、分離が必要なE2Eやブラウザテスト、大規模テストスイート。軽量テストだけなら効果は薄い。
- 事前準備:テストIDの一意性を担保。ローカルでのdiscoveryとサンドボックス実行環境の整合性(Linux/Mac + bash)を確認。
- コスト管理:イメージ差分・キャッシュでコストを抑えられるが、並列数を踏まえたクラウド費用見積もりは必須。
- 日本チーム向け運用提案:まずは最も時間を消費するテスト群(E2EやUI)から段階導入し、download_globsで失敗時のログだけ取得する運用を試すとROIが高い。
興味があるチームは、既存CIでのボトルネック計測→Offloadでのプロトタイプ(数十〜百並列)を試してみることを推奨。