diff options
Diffstat (limited to 'tests/api_ping.rs')
| -rw-r--r-- | tests/api_ping.rs | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/tests/api_ping.rs b/tests/api_ping.rs index fcfaf41f..b86d0378 100644 --- a/tests/api_ping.rs +++ b/tests/api_ping.rs @@ -356,6 +356,78 @@ contains = ["server-reload-marker"] cleanup_spawned_herdr(child, base); } +#[cfg(target_os = "linux")] +#[test] +fn shutdown_preserves_session_after_shell_is_signaled() { + let _lock = test_lock(); + let base = unique_test_dir(); + let config_home = base.join("config"); + let runtime_dir = base.join("runtime"); + let socket_path = runtime_dir.join("herdr.sock"); + + let mut child = spawn_herdr_with_shell(&config_home, &runtime_dir, &socket_path, "/bin/sh"); + wait_for_socket(&socket_path, Duration::from_secs(5)); + + let created = send_request( + &socket_path, + &format!( + r#"{{"id":"create","method":"workspace.create","params":{{"cwd":"{}","focus":true}}}}"#, + base.display() + ), + ); + let pane_id = created["result"]["root_pane"]["pane_id"] + .as_str() + .expect("root pane id"); + let process_info = send_request( + &socket_path, + &format!( + r#"{{"id":"process","method":"pane.process_info","params":{{"pane_id":"{pane_id}"}}}}"# + ), + ); + let shell_pid = process_info["result"]["process_info"]["shell_pid"] + .as_u64() + .expect("shell pid") as libc::pid_t; + + assert_eq!(unsafe { libc::kill(shell_pid, libc::SIGHUP) }, 0); + + let deadline = Instant::now() + Duration::from_secs(2); + loop { + let panes = send_request( + &socket_path, + r#"{"id":"panes","method":"pane.list","params":{}}"#, + ); + if panes["result"]["panes"] + .as_array() + .is_some_and(Vec::is_empty) + { + break; + } + assert!(Instant::now() < deadline, "signaled pane was not removed"); + thread::sleep(Duration::from_millis(20)); + } + + let stopped = send_request( + &socket_path, + r#"{"id":"stop","method":"server.stop","params":{}}"#, + ); + assert_eq!(stopped["result"]["type"], "ok"); + child.child.wait().expect("server should stop cleanly"); + + let session: serde_json::Value = serde_json::from_slice( + &fs::read(config_home.join("herdr-dev/session.json")).expect("saved session"), + ) + .expect("valid session json"); + assert_eq!(session["workspaces"].as_array().map(Vec::len), Some(1)); + assert_eq!( + session["workspaces"][0]["tabs"][0]["panes"] + .as_object() + .map(serde_json::Map::len), + Some(1) + ); + + cleanup_spawned_herdr(child, base); +} + #[cfg(not(target_os = "macos"))] #[test] fn workspace_list_and_create_round_trip() { |
