fix: align Runtime restore diagnostics and socket test fixtures

This commit is contained in:
2026-10-22 03:46:46 +09:00
parent 533477c2e7
commit b860c67ea2
3 changed files with 42 additions and 17 deletions
@@ -682,8 +682,10 @@ fn runtime_v5_rejects_broken_or_future_source_without_rewriting_evidence() {
#[cfg(unix)] #[cfg(unix)]
#[test] #[test]
fn current_runtime_session_migration_still_rejects_live_worker_sockets() { fn current_runtime_session_migration_still_rejects_live_worker_sockets() {
let temp = tempfile::tempdir().unwrap(); // Relative socket names keep this fixture independent of the checkout/TMPDIR
let root = temp.path().join("runtime"); // length. The TempDir still owns the same tree; no process cwd is changed.
let temp = tempfile::tempdir_in(".").unwrap();
let root = Path::new(temp.path().file_name().unwrap()).join("runtime");
let (worker, _, _) = runtime_fixture(&root, 12); let (worker, _, _) = runtime_fixture(&root, 12);
let before = tree_bytes(&root); let before = tree_bytes(&root);
let runs = root.join("workers").join(worker.to_string()).join("runs"); let runs = root.join("workers").join(worker.to_string()).join("runs");
+23 -3
View File
@@ -9889,12 +9889,25 @@ mod tests {
}) })
.await; .await;
session.close().await.unwrap(); session.close().await.unwrap();
Ok(result.unwrap_err().to_string()) Ok(result.unwrap_err())
}) })
.unwrap(); .unwrap();
// The String-returning opener cannot safely classify its raw cause. The
// deferred boundary must preserve its typed stage without exposing that text.
assert_eq!(
error.failure_reason(),
Some(workdir::WorkdirFailureReason::SessionOpenFailed),
"{damage}: {error:?}"
);
assert!( assert!(
error.contains("working_directory_cleanup_"), matches!(error.classification_source(), workdir::WorkdirError::Unavailable(message)
"{damage}: {error}" if message == "Workdir session could not be opened"),
"{damage}: {error:?}"
);
assert_eq!(
error.denial_reason(),
None,
"{damage}: no guessed denial cause"
); );
assert_eq!( assert_eq!(
observed.lock().unwrap().len(), observed.lock().unwrap().len(),
@@ -9907,6 +9920,13 @@ mod tests {
"damaged checkout must be retained" "damaged checkout must be retained"
); );
assert!(backend.stop_worker(&request.worker_ref).is_accepted()); assert!(backend.stop_worker(&request.worker_ref).is_accepted());
println!(
"damage={damage}; reason={:?}; classification={:?}; cwd_bind_count={}; retained_files={}; retained_data_unchanged=true; stopped=true",
error.failure_reason(),
error.classification_source(),
observed.lock().unwrap().len(),
before.len(),
);
} }
} }
+15 -12
View File
@@ -3677,7 +3677,11 @@ mod tests {
#[test] #[test]
fn bound_ssh_workdir_uses_attachment_scoped_agent_and_cleans_it_up() { fn bound_ssh_workdir_uses_attachment_scoped_agent_and_cleans_it_up() {
let repo = create_clean_repo(); let repo = create_clean_repo();
let runtime_root = tempfile::tempdir().unwrap(); // ssh-agent and the broker receive relative socket paths in this owned
// fixture tree, so the test does not depend on checkout/TMPDIR length.
// Neither this process nor its peers change cwd.
let runtime_root = tempfile::tempdir_in(".").unwrap();
let runtime_path = Path::new(runtime_root.path().file_name().unwrap());
let key_root = tempfile::tempdir().unwrap(); let key_root = tempfile::tempdir().unwrap();
let key_path = key_root.path().join("id_ed25519"); let key_path = key_root.path().join("id_ed25519");
let fallback_key_path = key_root.path().join("id_ed25519_fallback"); let fallback_key_path = key_root.path().join("id_ed25519_fallback");
@@ -3689,7 +3693,7 @@ mod tests {
.unwrap(); .unwrap();
assert!(status.success()); assert!(status.success());
} }
let materializer = RuntimeGitMaterializer::new(runtime_root.path()); let materializer = RuntimeGitMaterializer::new(runtime_path);
let mut request = request(repo.path()); let mut request = request(repo.path());
request.materialization = Some(crate::catalog::RepositoryMaterializationContext { request.materialization = Some(crate::catalog::RepositoryMaterializationContext {
workspace_id: "workspace-1".to_string(), workspace_id: "workspace-1".to_string(),
@@ -3731,7 +3735,7 @@ mod tests {
kind: server_api::RepositorySourceKind::Ssh, kind: server_api::RepositorySourceKind::Ssh,
uri: "ssh://git@example.test/repo.git".to_string(), uri: "ssh://git@example.test/repo.git".to_string(),
}; };
let command_access = RepositoryCommandAccess::prepare(runtime_root.path(), &ssh_operation) let command_access = RepositoryCommandAccess::prepare(runtime_path, &ssh_operation)
.unwrap() .unwrap()
.unwrap(); .unwrap();
assert!(!command_access.root.join("identity").exists()); assert!(!command_access.root.join("identity").exists());
@@ -3873,18 +3877,17 @@ mod tests {
.unwrap(); .unwrap();
// Restore preflight must validate without consuming this one-shot SSH // Restore preflight must validate without consuming this one-shot SSH
// delivery or creating agent/session resources needed by actual bind. // delivery or creating agent/session resources needed by actual bind.
let record_before = let record_before = fs::read(runtime_path.join(&id).join(MATERIALIZATION_RECORD)).unwrap();
fs::read(runtime_root.path().join(&id).join(MATERIALIZATION_RECORD)).unwrap();
materializer materializer
.preflight_bind_working_directory(&id, None) .preflight_bind_working_directory(&id, None)
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
fs::read(runtime_root.path().join(&id).join(MATERIALIZATION_RECORD)).unwrap(), fs::read(runtime_path.join(&id).join(MATERIALIZATION_RECORD)).unwrap(),
record_before record_before
); );
assert_eq!(materializer.list_working_directories().unwrap().len(), 1); assert_eq!(materializer.list_working_directories().unwrap().len(), 1);
assert_eq!( assert_eq!(
fs::read_dir(runtime_root.path().join(".repository-agents")) fs::read_dir(runtime_path.join(".repository-agents"))
.map(|entries| entries.count()) .map(|entries| entries.count())
.unwrap_or_default(), .unwrap_or_default(),
0 0
@@ -3898,7 +3901,7 @@ mod tests {
assert!(ssh_policy.contains("__repository-ssh")); assert!(ssh_policy.contains("__repository-ssh"));
assert!(!ssh_policy.contains("SSH_AUTH_SOCK")); assert!(!ssh_policy.contains("SSH_AUTH_SOCK"));
assert_eq!( assert_eq!(
fs::read_dir(runtime_root.path().join(".repository-agents")) fs::read_dir(runtime_path.join(".repository-agents"))
.map(|entries| entries.count()) .map(|entries| entries.count())
.unwrap_or_default(), .unwrap_or_default(),
1 1
@@ -3916,7 +3919,7 @@ mod tests {
"consumed delivery expiry must not revoke a live Workdir session" "consumed delivery expiry must not revoke a live Workdir session"
); );
assert_eq!( assert_eq!(
fs::read_dir(runtime_root.path().join(".repository-agents")) fs::read_dir(runtime_path.join(".repository-agents"))
.map(|entries| entries.count()) .map(|entries| entries.count())
.unwrap_or_default(), .unwrap_or_default(),
1, 1,
@@ -3925,7 +3928,7 @@ mod tests {
drop(binding); drop(binding);
assert!(!ssh_command.exists()); assert!(!ssh_command.exists());
assert_eq!( assert_eq!(
fs::read_dir(runtime_root.path().join(".repository-agents")) fs::read_dir(runtime_path.join(".repository-agents"))
.map(|entries| entries.count()) .map(|entries| entries.count())
.unwrap_or_default(), .unwrap_or_default(),
0 0
@@ -3971,7 +3974,7 @@ mod tests {
], ],
&read_only_command_policy, &read_only_command_policy,
)); ));
let broker_socket = fs::read_dir(runtime_root.path().join(REPOSITORY_ACCESS_DIR)) let broker_socket = fs::read_dir(runtime_path.join(REPOSITORY_ACCESS_DIR))
.unwrap() .unwrap()
.filter_map(Result::ok) .filter_map(Result::ok)
.map(|entry| entry.path().join("b.sock")) .map(|entry| entry.path().join("b.sock"))
@@ -4104,7 +4107,7 @@ mod tests {
.code, .code,
"working_directory_repository_access_expired" "working_directory_repository_access_expired"
); );
let restored = RuntimeGitMaterializer::new(runtime_root.path()); let restored = RuntimeGitMaterializer::new(runtime_path);
assert_eq!( assert_eq!(
restored.bind_working_directory(&id, None).unwrap_err().code, restored.bind_working_directory(&id, None).unwrap_err().code,
"working_directory_remote_repository_access_required" "working_directory_remote_repository_access_required"