sbd_o_bahn_server_tester/
lib.rs1#![deny(missing_docs)]
2#![allow(clippy::manual_async_fn)]
4
5use std::io::Result;
16use tokio::io::AsyncBufReadExt;
17
18mod it;
19
20#[derive(Debug, Default)]
22pub struct Report {
23 pub passed: Vec<String>,
25
26 pub failed: Vec<(String, String)>,
28}
29
30pub async fn run<S: AsRef<std::ffi::OsStr>>(cmd: Vec<S>) -> Report {
32 let mut server = Server::spawn(cmd).await.unwrap();
33
34 it::exec_all(&mut server).await
35}
36
37struct Server {
38 _child: tokio::process::Child,
39 stdin: tokio::process::ChildStdin,
40 stdout: tokio::io::Lines<tokio::io::BufReader<tokio::process::ChildStdout>>,
41}
42
43impl Server {
44 pub async fn spawn<S: AsRef<std::ffi::OsStr>>(
45 mut args: Vec<S>,
46 ) -> Result<Self> {
47 let prog = args.remove(0);
48 let mut cmd = tokio::process::Command::new(prog);
49 cmd.args(args)
50 .kill_on_drop(true)
51 .stdin(std::process::Stdio::piped())
52 .stdout(std::process::Stdio::piped());
53
54 println!("RUNNING {cmd:?}");
55 let mut child = cmd.spawn()?;
56 let stdin = child.stdin.take().unwrap();
57
58 let mut stdout =
59 tokio::io::BufReader::new(child.stdout.take().unwrap()).lines();
60
61 if let Some(line) = stdout.next_line().await? {
62 if line != "CMD/READY" {
63 panic!("unexpected: {line}");
64 }
65 } else {
66 panic!("no stdout");
67 }
68
69 println!("GOT CMD/READY");
70
71 Ok(Self {
72 _child: child,
73 stdin,
74 stdout,
75 })
76 }
77
78 pub async fn start(&mut self) -> Vec<String> {
79 use tokio::io::AsyncWriteExt;
80 self.stdin.write_all(b"CMD/START\n").await.unwrap();
81 self.stdin.flush().await.unwrap();
82 let line = self.stdout.next_line().await.unwrap().unwrap();
83 if !line.starts_with("CMD/START/") {
84 panic!("unexpected: {line}");
85 }
86 line.split('/').skip(2).map(|s| s.to_string()).collect()
87 }
88}