Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions ostool/src/run/httpboot_board.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ use crate::{
output_matcher::{
ByteStreamMatcher, MATCH_DRAIN_DURATION, compile_regexes, print_match_event,
},
shell_init::{SHELL_INIT_DELAY, ShellAutoInitMatcher},
shell_init::{
SHELL_INIT_CHUNK_DELAY, SHELL_INIT_CHUNK_SIZE, SHELL_INIT_DELAY, ShellAutoInitMatcher,
},
uboot::UbootRunInput,
},
sterm::{AsyncTerminal, TerminalConfig},
Expand Down Expand Up @@ -385,7 +387,12 @@ where
if let Some(shell_init) = shell_init.as_mut()
&& let Some(command) = shell_init.observe_byte(byte)
{
handle.send_after(SHELL_INIT_DELAY, command);
handle.send_after_chunks(
SHELL_INIT_DELAY,
command,
SHELL_INIT_CHUNK_SIZE,
SHELL_INIT_CHUNK_DELAY,
);
}

if matcher.should_stop() {
Expand Down
12 changes: 10 additions & 2 deletions ostool/src/run/qemu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ use crate::{
output_matcher::{ByteStreamMatcher, compile_regexes, print_match_event},
ovmf_prebuilt::{Arch, FileType, Prebuilt, Source},
qemu_plan::{QemuBootSource, QemuCommandPlanInput, build_qemu_command_plan},
shell_init::{SHELL_INIT_DELAY, ShellAutoInitMatcher, normalize_shell_init_config},
shell_init::{
SHELL_INIT_CHUNK_DELAY, SHELL_INIT_CHUNK_SIZE, SHELL_INIT_DELAY, ShellAutoInitMatcher,
normalize_shell_init_config,
},
},
sterm::{AsyncTerminal, TerminalConfig},
utils::PathResultExt,
Expand Down Expand Up @@ -555,7 +558,12 @@ impl QemuRunner {
if let Some(shell_auto_init) = shell_auto_init.as_mut()
&& let Some(command) = shell_auto_init.observe_byte(byte)
{
handle.send_after(SHELL_INIT_DELAY, command);
handle.send_after_chunks(
SHELL_INIT_DELAY,
command,
SHELL_INIT_CHUNK_SIZE,
SHELL_INIT_CHUNK_DELAY,
);
}

if matcher.should_stop() {
Expand Down
2 changes: 2 additions & 0 deletions ostool/src/run/shell_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::time::Duration;
use anyhow::{Result, bail};

pub(crate) const SHELL_INIT_DELAY: Duration = Duration::from_millis(100);
pub(crate) const SHELL_INIT_CHUNK_SIZE: usize = 64;
pub(crate) const SHELL_INIT_CHUNK_DELAY: Duration = Duration::from_millis(2);

pub(crate) fn normalize_shell_init_config(
shell_prefix: &mut Option<String>,
Expand Down
12 changes: 10 additions & 2 deletions ostool/src/run/uboot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ use crate::{
output_matcher::{
ByteStreamMatcher, MATCH_DRAIN_DURATION, compile_regexes, print_match_event,
},
shell_init::{SHELL_INIT_DELAY, ShellAutoInitMatcher, normalize_shell_init_config},
shell_init::{
SHELL_INIT_CHUNK_DELAY, SHELL_INIT_CHUNK_SIZE, SHELL_INIT_DELAY, ShellAutoInitMatcher,
normalize_shell_init_config,
},
tftp,
},
sterm::{AsyncTerminal, TerminalConfig},
Expand Down Expand Up @@ -1270,7 +1273,12 @@ where
if let Some(shell_init) = shell_init.as_mut()
&& let Some(command) = shell_init.observe_byte(byte)
{
h.send_after(SHELL_INIT_DELAY, command);
h.send_after_chunks(
SHELL_INIT_DELAY,
command,
SHELL_INIT_CHUNK_SIZE,
SHELL_INIT_CHUNK_DELAY,
);
}

if matcher.should_stop() {
Expand Down
40 changes: 40 additions & 0 deletions ostool/src/sterm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,29 @@ impl TerminalHandle {
});
}

pub fn send_after_chunks(
&self,
duration: Duration,
bytes: Vec<u8>,
chunk_size: usize,
chunk_delay: Duration,
) {
let handle = self.clone();
let chunk_size = chunk_size.max(1);
tokio::spawn(async move {
tokio::time::sleep(duration).await;
for chunk in bytes.chunks(chunk_size) {
if !handle.is_running() {
break;
}
if handle.send(chunk.to_vec()).is_err() {
break;
}
tokio::time::sleep(chunk_delay).await;
}
});
}

pub fn is_running(&self) -> bool {
self.inner.running.load(Ordering::Acquire)
}
Expand Down Expand Up @@ -842,6 +865,23 @@ mod tests {
assert!(handle.timeout_deadline().is_some());
}

#[tokio::test]
async fn send_after_chunks_splits_long_terminal_input() {
let (tx, mut rx) = mpsc::unbounded_channel();
let handle = TerminalHandle::new(tx);

handle.send_after_chunks(
Duration::ZERO,
b"abcdef".to_vec(),
2,
Duration::from_millis(1),
);

assert_eq!(rx.recv().await.unwrap(), b"ab");
assert_eq!(rx.recv().await.unwrap(), b"cd");
assert_eq!(rx.recv().await.unwrap(), b"ef");
}

#[tokio::test]
async fn non_tty_mode_consumes_output_without_event_stream() {
let terminal = super::AsyncTerminal::new(super::TerminalConfig {
Expand Down