From 4428e1664d8d897ce2f914777c0fe060cf334c84 Mon Sep 17 00:00:00 2001 From: Can Celik Date: Tue, 15 Sep 2026 21:17:32 +0300 Subject: fix: preserve unloaded sessions before replacement (#4190) refs #4125 --- tests/cli/sessions.rs | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'tests') diff --git a/tests/cli/sessions.rs b/tests/cli/sessions.rs index 5a887698..717f02ef 100644 --- a/tests/cli/sessions.rs +++ b/tests/cli/sessions.rs @@ -660,6 +660,75 @@ fn server_stop_then_restart_restores_pane_history() { cleanup_spawned_herdr(restarted, base); } +#[test] +fn unloaded_session_survives_autosave_and_shutdown_when_recovery_is_blocked() { + 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 data_dir = config_home.join(app_dir_name()); + fs::create_dir_all(&data_dir).unwrap(); + let session_path = data_dir.join("session.json"); + let original = b"{unreadable layout"; + fs::write(&session_path, original).unwrap(); + fs::write(data_dir.join("session-backups"), b"blocks recovery").unwrap(); + + let mut herdr = spawn_herdr(&config_home, &runtime_dir, &socket_path); + wait_for_socket(&socket_path, Duration::from_secs(5)); + run_cli_json( + &socket_path, + &["workspace", "create", "--cwd", base.to_str().unwrap()], + ); + assert!(wait_until( + Duration::from_secs(10), + Duration::from_millis(25), + || { + fs::read_to_string(data_dir.join("herdr-server.log")) + .is_ok_and(|log| log.contains("event=\"persist.save\"")) + } + )); + assert_eq!(fs::read(&session_path).unwrap(), original); + + assert!(run_cli(&socket_path, &["server", "stop"]).status.success()); + let pid = herdr.child.process_id(); + assert!(herdr.child.wait().unwrap().success()); + unregister_spawned_herdr_pid(pid); + assert_eq!(fs::read(&session_path).unwrap(), original); + cleanup_spawned_herdr(herdr, base); +} + +#[test] +fn session_appearing_after_startup_is_preserved_before_autosave() { + 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 data_dir = config_home.join(app_dir_name()); + let herdr = spawn_herdr(&config_home, &runtime_dir, &socket_path); + wait_for_socket(&socket_path, Duration::from_secs(5)); + // The server has already evaluated restore, but has not created any layout. + let original = include_bytes!("../fixtures/session/current-herdr-session.json"); + fs::write(data_dir.join("session.json"), original).unwrap(); + run_cli_json( + &socket_path, + &["workspace", "create", "--cwd", base.to_str().unwrap()], + ); + assert!(wait_until( + Duration::from_secs(10), + Duration::from_millis(25), + || { + fs::read_to_string(data_dir.join("herdr-server.log")) + .is_ok_and(|log| log.contains("event=\"persist.save\"")) + } + )); + let backups: Vec<_> = fs::read_dir(data_dir.join("session-backups")) + .expect("late session must be preserved before autosave") + .map(|entry| fs::read(entry.unwrap().path()).unwrap()) + .collect(); + assert_eq!(backups, vec![original.to_vec()]); + cleanup_spawned_herdr(herdr, base); +} + #[test] fn server_start_restores_legacy_session_through_api_identity() { let base = unique_test_dir(); -- cgit v1.2.3