9.1 KiB
テスト妥当性レビュー: session-store
- 評価: 概ね良い
確認範囲
crates/session-store/README.mdcrates/session-store/Cargo.tomlcrates/session-store/src/lib.rsstore.rsfs_store.rssegment.rssegment_log.rslogged_item.rssystem_item.rsevent_trace.rs
crates/session-store/tests/fs_store_test.rssession_test.rscommon/mod.rs
- 実行確認:
cargo test -p session-store
現在のテストがよくカバーしていること
session-store の主要責務である「append-only JSONL session log を読み書きし、Worker 復元用 state に replay する」部分は、短時間レビューとしては十分に押さえられています。
良い点:
collect_stateの基本 replay が広くテストされている。- 空の log
SegmentStart- user / assistant / tool call / tool result
TurnEndConfigChangedLlmUsageInvokemarker が state を変えないことExtension- typed
protocol::Segmentの保存と flattened user message への復元
LoggedItemの stable mirror が比較的よく検証されている。- message
- tool call
- tool result content / error flag
- reasoning encrypted content
- reasoning signature
- legacy signature 欠落 JSON
- serde tag shape
SystemItemは、LLM に入るhistory_textが stored body 由来であること、reminder wrapping、legacy default source、JSON round-trip が確認されている。FsStoreは tempfile を使った実 FS の読み書きで確認されている。- append / read round-trip
create_segmentlist_sessionslist_segmentsexists- missing segment
- trace file が segment log と分離されること
read_entry_countlookup_session_of
session_test.rsは mock LLM + actualllm_worker::Workerを通して、単純応答・tool call・pause・restore・fork 系を実行している。単なる pure unit だけでなく、crate 境界上の使われ方もある程度守れている。- fork lineage について、fresh-session fork / in-session
fork_at/ live conflictensure_head_or_fork/ nested past fork まで触れているのは良いです。特に「source segment を mutate しない」方針をテストで固定できています。
不足・疑問のあるテスト
現状は「基本機能の回帰検出」としては強い一方で、session-store の重要 invariant に対して未検証の穴がいくつか残っています。
-
create_compacted_segmentが未テスト。- この crate の説明上、compaction は fork と並ぶ segment lineage 操作です。
compacted_from、同一session_id継承、seed history/config/system prompt の保存が直接検証されていません。
-
Store::truncateが未テスト。- trait default 実装で
read_all -> truncate -> create_segmentするため、empty-turn rollback などの重要用途で壊れてもこの crate 単体では検出しにくいです。 entries_len > lenのStoreError::Corruptも未検証です。
- trait default 実装で
-
corrupt JSONL の扱いが未テスト。
FsStore::parse_jsonlは blank line を無視し、serde failure をStoreError::Corrupt { line, message }に変換します。- line number、blank line skip、部分的に壊れた file で read が fail closed することは永続ログ store として重要ですが未確認です。
-
FsStoreの filtering / layout invariant が一部弱い。- top-level old flat files を
list_sessionsが無視すること。 - invalid UUID directory を無視すること。
.trace.jsonlをlist_segmentsが segment として拾わないこと。- invalid segment filename を無視すること。
list_segmentsの newest-first order はcontains中心で、順序を強く確認していません。
- top-level old flat files を
-
save_delta/classify_history_itemの直接テストが薄い。- user message を skip する contract は integration helper 経由では使われていますが、直接の単体テストがありません。
- reasoning が
AssistantItemになること、tool result error/content がToolResultとして保存されること、unknown/future-ish branch の defensive behavior は十分固定されていません。
-
RunErroredpath が未テスト。run_and_persisthelper には error branch がありますが、最後にresult.unwrap()するため、実際には error persistence の検証に使えません。save_run_erroredと replay 時のlast_run_interrupted反映は、失敗 turn の session 復元に関わるため追加価値が高いです。
-
SystemItemの replay path が直接弱い。SystemItem::history_text自体はテストされていますが、LogEntry::SystemItemをcollect_stateしたときにItem::system_messageへ入ること、append_system_item経由で store に保存されることは明示的にテストされていません。
-
fork 系の一部 assertion が弱い。
session_fork_at_truncates_within_sessionは fork state と source-at-fork のhistory.len()だけを比べています。content / item kind / config / system prompt / lineage まで比較した方が妥当です。at_turn_index == 0を、実際に turn 後の source segment に対して使うケースが薄いです。- 存在しない
at_turn_indexの扱いは未固定です。現実装はunwrap_or(entries.len())で末尾 fork になりますが、それが意図かどうかをテストで明確にした方がよいです。 ensure_head_or_forkの no-op branch(count equal)と、store count が writer tally より小さい場合の policy が未検証です。
-
integration tests の一部は smoke test 寄りで、壊れ方を見逃しやすい。
session_restore_round_tripは history の長さだけで、復元 item の content / role / tool call id までは比較していません。session_run_with_tool_callはToolResult/AssistantItemの存在だけを確認しており、順序・call id・tool result content・final assistant text を見ていません。session_run_logs_entriesはコメントでは最低 5 entry と書きつつ>= 4で、UserInputの存在も明示確認していません。
-
real concurrency / append atomicity は未テスト。
- この crate は append-mode JSONL を concurrency 境界として扱っていますが、複数 clone / thread からの append が line corruption しないことは未確認です。
- ただし OS/filesystem 依存が強いので、軽い regression test に留めるのが妥当です。
追加を提案するテスト
優先度順に追加するなら以下です。
-
create_compacted_segmentの lineage test- source session を作る
- compacted segment を作る
- first entry が
SegmentStart { session_id: source_sid, compacted_from: Some(...) } forked_fromはNone- history/config/system prompt が seed state から復元される
-
Store::truncatedefault behavior test- 3〜4 entries を作る
- 2 entries に truncate
read_allが prefix のみ返すread_entry_countが一致する- len 超過 truncate が
StoreError::Corruptになる
-
corrupt JSONL test
- tempfile 上に直接 invalid JSON line を置く
read_allがStoreError::Corrupt { line, .. }を返す- blank line が count / parse に影響しないことも併せて確認する
-
FsStorelayout filtering test- root 直下の
<uuid>.jsonlを無視 - invalid directory を無視
- session dir 内の
<segment>.trace.jsonlと invalid filename をlist_segmentsが無視 - segment order を newest-first で assertion
- root 直下の
-
save_deltadirect unit/integration test- input に user message / assistant message / reasoning / tool call / tool result を混ぜる
- user message が保存されないこと
- classification と order が期待通りなこと
-
RunErroredpersistence testsave_run_erroredを直接使うだけでもよい- 可能なら mock client error を発生させ、Pod 相当の persistence sequence で
RunErroredが書かれることを確認する collect_state/restoreでlast_run_interruptedが反映されることを確認する
-
SystemItemreplay/store testappend_system_itemで notification / task reminder などを保存restore後のhistoryにrole: systemの message と stored body が入ることを確認する
-
fork tests の assertion 強化
history.len()だけでなく、復元 content / role / item kind を比較するforked_fromのsegment_idとat_turn_indexをfork_attest でも確認するat_turn_index == 0on non-empty source と nonexistent turn index の policy を固定する
実行したコマンド
cd /home/hare/Projects/yoi && cargo test -p session-store
結果:
- unit tests: 29 passed
tests/fs_store_test.rs: 8 passedtests/session_test.rs: 9 passed- doctest: 1 ignored
- overall: passed