fix(tests): do not read stdin until we started reading from pty

This commit is contained in:
Aram Drevekenin 2020-11-26 10:49:53 +01:00
parent 3c43675fb1
commit d4d54450a1

View file

@ -4,6 +4,7 @@ use ::std::io::{Read, Write};
use ::std::os::unix::io::RawFd; use ::std::os::unix::io::RawFd;
use ::std::path::PathBuf; use ::std::path::PathBuf;
use ::std::sync::{Arc, Mutex}; use ::std::sync::{Arc, Mutex};
use ::std::sync::atomic::{AtomicBool, Ordering};
use ::std::time::{Duration, Instant}; use ::std::time::{Duration, Instant};
use crate::os_input_output::OsApi; use crate::os_input_output::OsApi;
@ -24,14 +25,16 @@ pub struct FakeStdinReader {
pub input_chars: Vec<[u8; 10]>, pub input_chars: Vec<[u8; 10]>,
pub read_position: usize, pub read_position: usize,
last_snapshot_time: Arc<Mutex<Instant>>, last_snapshot_time: Arc<Mutex<Instant>>,
started_reading_from_pty: Arc<AtomicBool>,
} }
impl FakeStdinReader { impl FakeStdinReader {
pub fn new(input_chars: Vec<[u8; 10]>, last_snapshot_time: Arc<Mutex<Instant>>) -> Self { pub fn new(input_chars: Vec<[u8; 10]>, last_snapshot_time: Arc<Mutex<Instant>>, started_reading_from_pty: Arc<AtomicBool>) -> Self {
FakeStdinReader { FakeStdinReader {
input_chars, input_chars,
read_position: 0, read_position: 0,
last_snapshot_time, last_snapshot_time,
started_reading_from_pty,
} }
} }
} }
@ -39,6 +42,9 @@ impl FakeStdinReader {
impl Read for FakeStdinReader { impl Read for FakeStdinReader {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> { fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
loop { loop {
if self.started_reading_from_pty.load(Ordering::SeqCst) == false {
::std::thread::sleep(MIN_TIME_BETWEEN_SNAPSHOTS);
} else {
let last_snapshot_time = { *self.last_snapshot_time.lock().unwrap() }; let last_snapshot_time = { *self.last_snapshot_time.lock().unwrap() };
if last_snapshot_time.elapsed() > MIN_TIME_BETWEEN_SNAPSHOTS { if last_snapshot_time.elapsed() > MIN_TIME_BETWEEN_SNAPSHOTS {
break; break;
@ -46,6 +52,7 @@ impl Read for FakeStdinReader {
::std::thread::sleep(MIN_TIME_BETWEEN_SNAPSHOTS - last_snapshot_time.elapsed()); ::std::thread::sleep(MIN_TIME_BETWEEN_SNAPSHOTS - last_snapshot_time.elapsed());
} }
} }
}
let read_position = self.read_position; let read_position = self.read_position;
match self.input_chars.get(read_position) { match self.input_chars.get(read_position) {
Some(bytes_to_read) => { Some(bytes_to_read) => {
@ -120,6 +127,7 @@ pub struct FakeInputOutput {
win_sizes: Arc<Mutex<HashMap<RawFd, PositionAndSize>>>, win_sizes: Arc<Mutex<HashMap<RawFd, PositionAndSize>>>,
possible_tty_inputs: HashMap<u16, Bytes>, possible_tty_inputs: HashMap<u16, Bytes>,
last_snapshot_time: Arc<Mutex<Instant>>, last_snapshot_time: Arc<Mutex<Instant>>,
started_reading_from_pty: Arc<AtomicBool>,
} }
impl FakeInputOutput { impl FakeInputOutput {
@ -137,6 +145,7 @@ impl FakeInputOutput {
io_events: Arc::new(Mutex::new(vec![])), io_events: Arc::new(Mutex::new(vec![])),
win_sizes: Arc::new(Mutex::new(win_sizes)), win_sizes: Arc::new(Mutex::new(win_sizes)),
possible_tty_inputs: get_possible_tty_inputs(), possible_tty_inputs: get_possible_tty_inputs(),
started_reading_from_pty: Arc::new(AtomicBool::new(false)),
} }
} }
pub fn with_tty_inputs(mut self, tty_inputs: HashMap<u16, Bytes>) -> Self { pub fn with_tty_inputs(mut self, tty_inputs: HashMap<u16, Bytes>) -> Self {
@ -200,6 +209,7 @@ impl OsApi for FakeInputOutput {
// them fail // them fail
::std::thread::sleep(::std::time::Duration::from_millis(25)); ::std::thread::sleep(::std::time::Duration::from_millis(25));
} else if attempts_left == 0 { } else if attempts_left == 0 {
self.started_reading_from_pty.store(true, Ordering::SeqCst);
return Ok(0); return Ok(0);
} }
let mut read_buffers = self.read_buffers.lock().unwrap(); let mut read_buffers = self.read_buffers.lock().unwrap();
@ -213,6 +223,7 @@ impl OsApi for FakeInputOutput {
if bytes_read > bytes.read_position { if bytes_read > bytes.read_position {
bytes.set_read_position(bytes_read); bytes.set_read_position(bytes_read);
} }
self.started_reading_from_pty.store(true, Ordering::SeqCst);
return Ok(bytes_read); return Ok(bytes_read);
} }
None => { None => {
@ -245,7 +256,7 @@ impl OsApi for FakeInputOutput {
input_chars.push(*bytes); input_chars.push(*bytes);
} }
} }
let reader = FakeStdinReader::new(input_chars, self.last_snapshot_time.clone()); let reader = FakeStdinReader::new(input_chars, self.last_snapshot_time.clone(), self.started_reading_from_pty.clone());
Box::new(reader) Box::new(reader)
} }
fn get_stdout_writer(&self) -> Box<dyn Write> { fn get_stdout_writer(&self) -> Box<dyn Write> {