Auto merge of #105145 - Ayush1325:sequential-remote-server, r=Mark-Simulacrum

Add batch flag to remote-test-server

When using this flag, the stdout and stderr are sent in a single batch instead of being streamed. It also used `Command::output` instead of `Command::spawn`. This is useful for targets that might support std but not threading (Eg: UEFI).

Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
This commit is contained in:
bors 2022-12-17 20:47:14 +00:00
commit 0468a00ae3

View File

@ -46,6 +46,7 @@ const NUMBER_OF_RETRIES: usize = 5;
struct Config {
verbose: bool,
sequential: bool,
batch: bool,
bind: SocketAddr,
}
@ -54,6 +55,7 @@ impl Config {
Config {
verbose: false,
sequential: false,
batch: false,
bind: if cfg!(target_os = "android") || cfg!(windows) {
([0, 0, 0, 0], 12345).into()
} else {
@ -75,6 +77,7 @@ impl Config {
}
"--bind" => next_is_bind = true,
"--sequential" => config.sequential = true,
"--batch" => config.batch = true,
"--verbose" | "-v" => config.verbose = true,
"--help" | "-h" => {
show_help();
@ -100,6 +103,7 @@ fn show_help() {
OPTIONS:
--bind <IP>:<PORT> Specify IP address and port to listen for requests, e.g. "0.0.0.0:12345"
--sequential Run only one test at a time
--batch Send stdout and stderr in batch instead of streaming
-v, --verbose Show status messages
-h, --help Show this help screen
"#,
@ -280,22 +284,30 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf
// Some tests assume RUST_TEST_TMPDIR exists
cmd.env("RUST_TEST_TMPDIR", tmp.to_owned());
// Spawn the child and ferry over stdout/stderr to the socket in a framed
// fashion (poor man's style)
let mut child =
t!(cmd.stdin(Stdio::null()).stdout(Stdio::piped()).stderr(Stdio::piped()).spawn());
drop(lock);
let mut stdout = child.stdout.take().unwrap();
let mut stderr = child.stderr.take().unwrap();
let socket = Arc::new(Mutex::new(reader.into_inner()));
let socket2 = socket.clone();
let thread = thread::spawn(move || my_copy(&mut stdout, 0, &*socket2));
my_copy(&mut stderr, 1, &*socket);
thread.join().unwrap();
let status = if config.batch {
let child =
t!(cmd.stdin(Stdio::null()).stdout(Stdio::piped()).stderr(Stdio::piped()).output());
batch_copy(&child.stdout, 0, &*socket);
batch_copy(&child.stderr, 1, &*socket);
child.status
} else {
// Spawn the child and ferry over stdout/stderr to the socket in a framed
// fashion (poor man's style)
let mut child =
t!(cmd.stdin(Stdio::null()).stdout(Stdio::piped()).stderr(Stdio::piped()).spawn());
drop(lock);
let mut stdout = child.stdout.take().unwrap();
let mut stderr = child.stderr.take().unwrap();
let socket2 = socket.clone();
let thread = thread::spawn(move || my_copy(&mut stdout, 0, &*socket2));
my_copy(&mut stderr, 1, &*socket);
thread.join().unwrap();
t!(child.wait())
};
// Finally send over the exit status.
let status = t!(child.wait());
let (which, code) = get_status_code(&status);
t!(socket.lock().unwrap().write_all(&[
@ -368,6 +380,17 @@ fn my_copy(src: &mut dyn Read, which: u8, dst: &Mutex<dyn Write>) {
}
}
fn batch_copy(buf: &[u8], which: u8, dst: &Mutex<dyn Write>) {
let n = buf.len();
let mut dst = dst.lock().unwrap();
t!(dst.write_all(&[which, (n >> 24) as u8, (n >> 16) as u8, (n >> 8) as u8, (n >> 0) as u8,]));
if n > 0 {
t!(dst.write_all(buf));
// Marking buf finished
t!(dst.write_all(&[which, 0, 0, 0, 0,]));
}
}
fn read_u32(r: &mut dyn Read) -> u32 {
let mut len = [0; 4];
t!(r.read_exact(&mut len));