//! Shared test helpers for the watchdog module. use std::path::Path; mod limits_tests; mod orphan_tests; /// Write a fake session log file with `n` assistant turn entries. /// /// The file is named `{agent_name}-{session_id}.log` to match the /// real naming convention used by `AgentLogWriter`. pub(super) fn write_fake_session_log( project_root: &Path, story_id: &str, agent_name: &str, session_id: &str, n_turns: u64, ) { let log_dir = project_root.join(".huskies").join("logs").join(story_id); std::fs::create_dir_all(&log_dir).unwrap(); let log_path = log_dir.join(format!("{agent_name}-{session_id}.log")); let mut content = String::new(); for _ in 0..n_turns { content.push_str( &serde_json::to_string(&serde_json::json!({ "timestamp": "2026-04-25T00:00:00Z", "type": "agent_json", "story_id": story_id, "agent_name": agent_name, "data": { "type": "assistant", "message": {} } })) .unwrap(), ); content.push('\n'); } std::fs::write(log_path, content).unwrap(); } /// Write a fake session log containing a `result` event with the given cost. /// /// Used to test budget enforcement via the watchdog's per-session log /// reading (not `token_usage.jsonl`). pub(super) fn write_fake_budget_session_log( project_root: &Path, story_id: &str, agent_name: &str, session_id: &str, cost_usd: f64, ) { let log_dir = project_root.join(".huskies").join("logs").join(story_id); std::fs::create_dir_all(&log_dir).unwrap(); let log_path = log_dir.join(format!("{agent_name}-{session_id}.log")); let content = serde_json::to_string(&serde_json::json!({ "timestamp": "2026-04-25T00:00:00Z", "type": "agent_json", "story_id": story_id, "agent_name": agent_name, "data": { "type": "result", "total_cost_usd": cost_usd } })) .unwrap() + "\n"; std::fs::write(log_path, content).unwrap(); } /// Write a minimal project.toml with the given agent config. pub(super) fn write_project_config(project_root: &Path, config_toml: &str) { let huskies_dir = project_root.join(".huskies"); std::fs::create_dir_all(&huskies_dir).unwrap(); std::fs::write(huskies_dir.join("project.toml"), config_toml).unwrap(); }