Changes: - Detect the herdr multiplexer - Mark /gboom as non-production code - Bound peak memory when loading a large session - Add a subagent lifecycle soak bounding threads, fds, and heap - Stream inherited replay to bound fork memory - Copy full plan from plan approval with y - Stop armed signature verification from deleting the managed-deny smoke policy - Add source-tagged terminal version telemetry - Show the UI instantly and fetch models and settings in the background - Session test helpers - computer_reason on the ConversationHistoryDone trailer
87 lines
3.2 KiB
Rust
87 lines
3.2 KiB
Rust
//! Non-ignored guard for the testkit's core path: synthesize a small session
|
|
//! with [`synth::prepare_session`], then confirm the production replay reader
|
|
//! parses every persisted update back with the right per-kind counts.
|
|
//!
|
|
//! `load_updates_for_replay_at` is the typed reader and keeps every update
|
|
//! (only `Xai` updates are dropped); the redundant-ACU skip is a later
|
|
//! line-based step in the client replay path, not asserted here.
|
|
|
|
use agent_client_protocol as acp;
|
|
use tempfile::TempDir;
|
|
|
|
use xai_grok_shell::session::storage::{
|
|
JsonlStorageAdapter, StorageAdapter, load_updates_for_replay_at,
|
|
};
|
|
use xai_grok_shell::session::testkit::synth::{self, SessionSpec};
|
|
|
|
#[tokio::test]
|
|
async fn synth_replay_roundtrip_parses_every_persisted_update() {
|
|
let root = TempDir::new().unwrap();
|
|
let cwd = TempDir::new().unwrap();
|
|
// Distinct per-turn counts so a miscount of any kind is unambiguous.
|
|
let spec = SessionSpec {
|
|
turns: 3,
|
|
acu_per_turn: 2,
|
|
catalog_commands: 2,
|
|
catalog_desc_len: 8,
|
|
agent_chunks_per_turn: 4,
|
|
agent_chunk_len: 16,
|
|
rewind_points: 0,
|
|
files_per_rewind: 0,
|
|
file_content_len: 0,
|
|
};
|
|
|
|
let (info, _dir) = synth::prepare_session(root.path(), cwd.path(), &spec).await;
|
|
|
|
let replayed = load_updates_for_replay_at(info.id.0.as_ref(), root.path())
|
|
.expect("load_updates_for_replay_at")
|
|
.unwrap_or_default();
|
|
|
|
let count = |pred: fn(&acp::SessionUpdate) -> bool| replayed.iter().filter(|u| pred(u)).count();
|
|
let users = count(|u| matches!(u, acp::SessionUpdate::UserMessageChunk(_)));
|
|
let acus = count(|u| matches!(u, acp::SessionUpdate::AvailableCommandsUpdate(_)));
|
|
let agents = count(|u| matches!(u, acp::SessionUpdate::AgentMessageChunk(_)));
|
|
|
|
assert_eq!(users, spec.turns, "one user chunk per turn");
|
|
assert_eq!(
|
|
acus,
|
|
spec.turns * spec.acu_per_turn,
|
|
"every ACU is preserved"
|
|
);
|
|
assert_eq!(
|
|
agents,
|
|
spec.turns * spec.agent_chunks_per_turn,
|
|
"every agent chunk is preserved"
|
|
);
|
|
assert_eq!(
|
|
replayed.len(),
|
|
spec.turns * (1 + spec.acu_per_turn + spec.agent_chunks_per_turn),
|
|
"no update is dropped or duplicated by the typed replay reader"
|
|
);
|
|
}
|
|
|
|
/// The adapter-driven bench generator reaches its byte target and emits updates
|
|
/// the production reader parses. Synchronous because `synthesize_to_target_bytes`
|
|
/// drives the adapter on its own runtime.
|
|
#[test]
|
|
fn synthesize_to_target_bytes_reaches_target_and_parses() {
|
|
let root = TempDir::new().unwrap();
|
|
let target: u64 = 8 * 1024;
|
|
|
|
let info = synth::synthesize_to_target_bytes(root.path(), target);
|
|
|
|
let adapter = JsonlStorageAdapter::with_root(root.path().to_path_buf());
|
|
let updates_path = adapter.updates_file_path(&info).expect("updates path");
|
|
let len = std::fs::metadata(&updates_path)
|
|
.expect("stat updates.jsonl")
|
|
.len();
|
|
assert!(
|
|
len >= target,
|
|
"updates.jsonl ({len} B) reached the target ({target} B)"
|
|
);
|
|
|
|
let replayed = load_updates_for_replay_at(info.id.0.as_ref(), root.path())
|
|
.expect("load_updates_for_replay_at")
|
|
.unwrap_or_default();
|
|
assert!(!replayed.is_empty(), "the emitted updates parse back");
|
|
}
|