diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-13 13:47:53 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-13 13:47:53 +0300 |
| commit | fc44f61a10ac04688b2fedfa670f38a463ca25ac (patch) | |
| tree | 29ca9c5411a444c051a7f9ea3db456d113a080d6 /src/server/headless/tests | |
| parent | bafbc0949dd996cf7fd0848c8965e254348cc11e (diff) | |
fix: disconnect stalled terminal observers (#4039)
Diffstat (limited to 'src/server/headless/tests')
| -rw-r--r-- | src/server/headless/tests/mod.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/server/headless/tests/mod.rs b/src/server/headless/tests/mod.rs index 2c13dc8b..bb196be5 100644 --- a/src/server/headless/tests/mod.rs +++ b/src/server/headless/tests/mod.rs @@ -3509,6 +3509,53 @@ fn terminal_attach_disconnect_restores_client_shell_pane_size() { rt.shutdown_timeout(Duration::from_millis(100)); } +#[cfg(unix)] +#[test] +fn backpressured_observer_skips_runtime_access_and_recovers_without_new_output() { + with_terminal_session_test_server(|server, terminal_id, target, _| { + let (writer, control, frames) = test_client_writer(); + server.handle_server_event(ServerEvent::ClientConnected { + client_id: 7, + cols: 80, + rows: 24, + cell_width_px: 0, + cell_height_px: 0, + pixel_mouse: false, + writer, + }); + server.handle_server_event(ServerEvent::ClientObserveTerminal { + client_id: 7, + target, + }); + server.render_and_stream(); + server.app.terminal_runtimes.insert( + terminal_id.clone(), + crate::terminal::TerminalRuntime::test_with_screen_bytes(80, 24, b"LATEST"), + ); + server.render_and_stream(); + assert_eq!(server.clients[&7].deferred_render(), DeferredRender::Full); + + // An absent runtime makes any attempted rendering observable without timing a lock. + let runtime = server.app.terminal_runtimes.remove(&terminal_id).unwrap(); + server.render_and_stream(); + server.app.terminal_runtimes.insert(terminal_id, runtime); + assert!( + server.clients.contains_key(&7), + "backpressure must skip runtime access" + ); + assert!(control.try_recv().is_err()); + + let _ = frames.recv().expect("previously accepted frame"); + assert!(server.handle_server_event(ServerEvent::ClientWriterDrained { client_id: 7 })); + server.render_and_stream(); + let ServerMessage::Terminal(frame) = read_server_message(frames.recv().unwrap()) else { + panic!("terminal update"); + }; + assert!(String::from_utf8_lossy(&frame.bytes).contains("LATEST")); + assert_eq!(server.clients[&7].deferred_render(), DeferredRender::None); + }); +} + #[test] fn terminal_observe_allows_multiple_clients_without_attach_ownership() { with_terminal_session_test_server(|server, terminal_id, terminal_id_string, _| { |
