run_blocked_work_pass rides the liveness tick but probes on a slower cadence (DEFAULT_BLOCKED_WORK_INTERVAL, 15s): each probe is three git subprocesses per session. Sessions without a worktree are filtered out before any probe, so their indicator costs nothing. A failed probe keeps the previous value; settled exits clear it.
117 lines
3.8 KiB
Rust
117 lines
3.8 KiB
Rust
//! The performance contract of #83: the blocked-work pass must cost NO git
|
|
//! probe at all for a session without a worktree, while a session with one is
|
|
//! still probed.
|
|
//!
|
|
//! `git` itself is shimmed through PATH with a wrapper that logs every
|
|
//! invocation before exec'ing the real binary, so the assertion counts actual
|
|
//! probes rather than inferring them from state. This lives in its own test
|
|
//! binary because it mutates the process environment.
|
|
|
|
mod common;
|
|
|
|
use std::collections::HashMap;
|
|
use std::process::Command;
|
|
use std::time::Duration;
|
|
|
|
use common::{init_bare_repo, init_repo, push_all_to_origin, wait_for_async, DaemonFixture};
|
|
use maestro_protocol::{CreateSessionRequest, InTheWay, WorktreeSpec};
|
|
use tempfile::TempDir;
|
|
|
|
fn request(cwd: &std::path::Path, repo: &std::path::Path, branch: &str) -> CreateSessionRequest {
|
|
CreateSessionRequest {
|
|
cwd: cwd.to_path_buf(),
|
|
command: "sleep 30".into(),
|
|
env: HashMap::new(),
|
|
metadata: HashMap::new(),
|
|
worktree: Some(WorktreeSpec {
|
|
base_repo: repo.to_path_buf(),
|
|
branch: branch.into(),
|
|
create_branch: true,
|
|
}),
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn a_session_without_a_worktree_costs_no_probe() {
|
|
let fx = DaemonFixture::new();
|
|
let log = TempDir::new().unwrap();
|
|
let log_path = log.path().join("git-calls.log");
|
|
|
|
// Session A owns a real (pristine, pushed) worktree; session B has none.
|
|
let repo_a = TempDir::new().unwrap();
|
|
init_repo(repo_a.path());
|
|
init_bare_repo(&repo_a.path().join("origin.git"));
|
|
push_all_to_origin(repo_a.path(), &repo_a.path().join("origin.git"));
|
|
fx.manager
|
|
.create(request(repo_a.path(), repo_a.path(), "feat/probed"))
|
|
.await
|
|
.expect("create A");
|
|
|
|
let cwd_b = TempDir::new().unwrap();
|
|
let mut req_b = request(cwd_b.path(), cwd_b.path(), "feat/unused");
|
|
req_b.worktree = None;
|
|
fx.manager.create(req_b).await.expect("create B");
|
|
|
|
// Shim `git` AFTER setup so only watcher-driven probes get logged.
|
|
let real_git = String::from_utf8(
|
|
Command::new("sh")
|
|
.arg("-c")
|
|
.arg("command -v git")
|
|
.output()
|
|
.expect("locate git")
|
|
.stdout,
|
|
)
|
|
.unwrap()
|
|
.trim()
|
|
.to_string();
|
|
let shim_dir = TempDir::new().unwrap();
|
|
let script = format!(
|
|
"#!/bin/sh\nprintf '%s\\n' \"$*\" >> {}\nexec {} \"$@\"\n",
|
|
log_path.display(),
|
|
real_git,
|
|
);
|
|
std::fs::write(shim_dir.path().join("git"), script).unwrap();
|
|
#[cfg(unix)]
|
|
{
|
|
use std::os::unix::fs::PermissionsExt;
|
|
std::fs::set_permissions(
|
|
shim_dir.path().join("git"),
|
|
std::fs::Permissions::from_mode(0o755),
|
|
)
|
|
.unwrap();
|
|
}
|
|
let old_path = std::env::var("PATH").unwrap_or_default();
|
|
std::env::set_var(
|
|
"PATH",
|
|
format!("{}:{}", shim_dir.path().display(), old_path),
|
|
);
|
|
|
|
fx.manager.start_liveness_watcher_with_blocked_work(
|
|
Duration::from_millis(50),
|
|
Duration::from_millis(100),
|
|
);
|
|
|
|
// The pass demonstrably runs and probed A's tree...
|
|
wait_for_async(Duration::from_secs(5), || async {
|
|
fx.manager
|
|
.snapshot()
|
|
.await
|
|
.iter()
|
|
.any(|s| s.worktree.is_some() && s.blocked_work == Some(InTheWay::default()))
|
|
})
|
|
.await;
|
|
|
|
std::env::set_var("PATH", &old_path);
|
|
|
|
let calls = std::fs::read_to_string(&log_path).unwrap_or_default();
|
|
assert!(
|
|
!calls.is_empty(),
|
|
"the pass never probed anything — the shim saw no git call at all"
|
|
);
|
|
// ...while B — no worktree, so nothing to probe — was never touched.
|
|
assert!(
|
|
!calls.contains(cwd_b.path().to_str().unwrap()),
|
|
"a worktree-less session was probed:\n{calls}"
|
|
);
|
|
}
|