use tempfile::TempDir;
use super::manager::ManagedError;
use super::record::{ManagedSessionId, ManagedSessionState};
use super::tests::make_manager;
#[tokio::test]
async fn mark_reactivated_flips_stopped_to_active() {
let dir = TempDir::new().unwrap();
let workspace_dir = TempDir::new().unwrap();
let (mgr, fake) = make_manager(&dir).await;
let record = mgr
.create(
"task".into(),
Some(workspace_dir.path().to_owned()),
None,
Some(workspace_dir.path().to_owned()),
None,
None,
)
.await
.expect("create");
mgr.stop(&record.id).await.expect("stop");
let kill_calls_before = fake.kill_calls.lock().unwrap().len();
let create_calls_before = fake.create_cwd_calls.lock().unwrap().len();
let reactivated = mgr.mark_reactivated(&record.id).await.expect("reactivate");
assert_eq!(
reactivated.state,
ManagedSessionState::Active,
"mark_reactivated must flip Stopped -> Active"
);
assert_eq!(
fake.kill_calls.lock().unwrap().len(),
kill_calls_before,
"mark_reactivated must NEVER call kill_session (#2023 C)"
);
assert_eq!(
fake.create_cwd_calls.lock().unwrap().len(),
create_calls_before,
"mark_reactivated must NEVER call create_session (#2023 C)"
);
let after = mgr.get(&record.id).await.unwrap();
assert_eq!(after.state, ManagedSessionState::Active);
}
#[tokio::test]
async fn mark_reactivated_flips_decommissioned_to_active() {
let dir = TempDir::new().unwrap();
let workspace_dir = TempDir::new().unwrap();
let (mgr, fake) = make_manager(&dir).await;
let record = mgr
.create(
"task".into(),
Some(workspace_dir.path().to_owned()),
None,
Some(workspace_dir.path().to_owned()),
None,
None,
)
.await
.expect("create");
mgr.set_workspace(
&record.id,
workspace_dir.path().to_owned(),
ManagedSessionState::Decommissioned,
)
.await
.expect("force Decommissioned");
let kill_calls_before = fake.kill_calls.lock().unwrap().len();
let create_calls_before = fake.create_cwd_calls.lock().unwrap().len();
let reactivated = mgr
.mark_reactivated(&record.id)
.await
.expect("reactivate decommissioned");
assert_eq!(
reactivated.state,
ManagedSessionState::Active,
"mark_reactivated must flip Decommissioned -> Active (#2777)"
);
assert_eq!(
fake.kill_calls.lock().unwrap().len(),
kill_calls_before,
"mark_reactivated must NEVER call kill_session"
);
assert_eq!(
fake.create_cwd_calls.lock().unwrap().len(),
create_calls_before,
"mark_reactivated must NEVER call create_session"
);
}
#[tokio::test]
async fn mark_reactivated_refuses_when_workspace_removed_by_decommission() {
let dir = TempDir::new().unwrap();
let (mgr, _fake) = make_manager(&dir).await;
let managed_root = TempDir::new().unwrap();
let workspace_path = managed_root.path().join("owner").join("repo").join("sess");
std::fs::create_dir_all(&workspace_path).unwrap();
let record = mgr
.create_with_id(
ManagedSessionId::new(),
"task".into(),
Some(workspace_path.clone()),
None,
Some(workspace_path.clone()),
None,
None,
crate::runtime::RuntimeKind::default(),
false,
true, )
.await
.expect("create");
let (tombstone, workspace_removed) = mgr
.decommission_with_root(&record.id, managed_root.path(), None)
.await
.expect("decommission");
assert!(
workspace_removed,
"precondition: the workspace must actually be removed from disk"
);
assert_eq!(tombstone.state, ManagedSessionState::Decommissioned);
assert!(
!workspace_path.exists(),
"precondition: workspace directory must be gone from disk"
);
let err = mgr
.mark_reactivated(&record.id)
.await
.expect_err("reactivating a session whose workspace is gone must fail");
assert!(
matches!(err, ManagedError::InvalidState(_, _)),
"expected InvalidState, got {err:?}"
);
let after = mgr
.get(&record.id)
.await
.expect("get after refused reactivate");
assert_eq!(
after.state,
ManagedSessionState::Decommissioned,
"the record must NOT be flipped to Active when its workspace is gone"
);
}
#[tokio::test]
async fn mark_reactivated_rejects_non_stopped() {
let dir = TempDir::new().unwrap();
let workspace_dir = TempDir::new().unwrap();
let (mgr, _fake) = make_manager(&dir).await;
let record = mgr
.create(
"task".into(),
Some(workspace_dir.path().to_owned()),
None,
Some(workspace_dir.path().to_owned()),
None,
None,
)
.await
.expect("create");
mgr.stop(&record.id).await.expect("stop");
mgr.mark_reactivated(&record.id)
.await
.expect("first reactivate");
let err = mgr
.mark_reactivated(&record.id)
.await
.expect_err("reactivating an already-Active session must fail");
assert!(
matches!(err, ManagedError::InvalidState(_, _)),
"expected InvalidState, got {err:?}"
);
}