use RAII guard in tests

This commit is contained in:
Johann150 2021-02-25 17:30:12 +01:00
parent 1059f8b94a
commit 8b4692b08b
No known key found for this signature in database
GPG key ID: 9EE6577A2A06F8F1

View file

@ -16,48 +16,68 @@ fn addr(port: u16) -> SocketAddr {
.unwrap()
}
fn get(args: &[&str], addr: SocketAddr, url: &str) -> Result<Page, anyhow::Error> {
// start the server
let mut server = Command::new(BINARY_PATH)
.stderr(Stdio::piped())
.current_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/data"))
.args(args)
.spawn()
.expect("failed to start binary");
struct Server {
server: std::process::Child,
buf: u8,
}
// the first output is when Agate is listening, so we only have to wait
// until the first byte is output
let mut buffer = [0; 1];
server
.stderr
.as_mut()
.unwrap()
.read_exact(&mut buffer)
.unwrap();
impl Server {
pub fn new(args: &[&str]) -> Self {
// start the server
let mut server = Command::new(BINARY_PATH)
.stderr(Stdio::piped())
.current_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/data"))
.args(args)
.spawn()
.expect("failed to start binary");
// the first output is when Agate is listening, so we only have to wait
// until the first byte is output
let mut buffer = [0; 1];
server
.stderr
.as_mut()
.unwrap()
.read_exact(&mut buffer)
.unwrap();
Self {
server,
buf: buffer[0],
}
}
}
impl Drop for Server {
fn drop(&mut self) {
// try to stop the server again
match self.server.try_wait() {
Err(e) => panic!("cannot access orchestrated program: {:?}", e),
// everything fine, still running as expected, kill it now
Ok(None) => self.server.kill().unwrap(),
Ok(Some(_)) => {
// forward stderr so we have a chance to understand the problem
let buffer = std::iter::once(Ok(self.buf))
.chain(self.server.stderr.take().unwrap().bytes())
.collect::<Result<Vec<u8>, _>>()
.unwrap();
eprintln!("{}", String::from_utf8_lossy(&buffer));
// make the test fail
panic!("program had crashed");
}
}
}
}
fn get(args: &[&str], addr: SocketAddr, url: &str) -> Result<Page, anyhow::Error> {
let _server = Server::new(args);
// actually perform the request
let page = tokio::runtime::Runtime::new()
.unwrap()
.block_on(async { Page::fetch_from(&Url::parse(url).unwrap(), addr, None).await });
// try to stop the server again
match server.try_wait() {
Err(e) => panic!("cannot access orchestrated program: {:?}", e),
// everything fine, still running as expected, kill it now
Ok(None) => server.kill().unwrap(),
Ok(Some(_)) => {
// forward stderr so we have a chance to understand the problem
let buffer = std::iter::once(Ok(buffer[0]))
.chain(server.stderr.take().unwrap().bytes())
.collect::<Result<Vec<u8>, _>>()
.unwrap();
eprintln!("{}", String::from_utf8_lossy(&buffer));
// make the test fail
panic!("program had crashed");
}
}
page
}