From 7f7aa3dc2c192a7de57239a4d33ded80382e08ad Mon Sep 17 00:00:00 2001 From: Dennis Date: Sun, 2 Jun 2024 16:34:05 +0200 Subject: [PATCH] Move starting of tasks into a helper struct --- tests/common/mod.rs | 1 + tests/common/task_starter.rs | 65 ++++++++++++++++++++++++++++++++++++ tests/cucumber.rs | 52 ++++++++--------------------- 3 files changed, 80 insertions(+), 38 deletions(-) create mode 100644 tests/common/task_starter.rs diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 158268150..f9f9f3557 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -5,3 +5,4 @@ pub mod osm; pub mod osm_db; pub mod osrm_world; pub mod scenario_id; +pub mod task_starter; \ No newline at end of file diff --git a/tests/common/task_starter.rs b/tests/common/task_starter.rs new file mode 100644 index 000000000..03d33fa2e --- /dev/null +++ b/tests/common/task_starter.rs @@ -0,0 +1,65 @@ +use std::{ + io::{BufRead, BufReader}, + process::{Child, Command, Stdio}, +}; + +#[derive(Default)] +pub struct TaskStarter { + ready: bool, + command: String, + arguments: Vec, + child: Option, +} + +impl TaskStarter { + pub fn new(command: &str) -> Self { + Self { + ready: false, + command: command.into(), + arguments: Vec::new(), + child: None, + } + } + pub fn is_ready(&self) -> bool { + self.ready + } + pub fn arg(&mut self, argument: &str) -> &mut Self { + self.arguments.push(argument.into()); + self + } + + pub fn spawn_wait_till_ready(&mut self, ready_token: &str) { + // TODO: move the child handling into a convenience struct + + let mut command = &mut Command::new(&self.command); + for argument in &self.arguments { + command = command.arg(argument); + } + + match command.stdout(Stdio::piped()).spawn() { + Ok(o) => self.child = Some(o), + Err(e) => panic!("cannot spawn task: {e}"), + } + + if let Some(output) = &mut self.child.as_mut().unwrap().stdout { + // implement with a timeout + let mut reader = BufReader::new(output); + let mut line = String::new(); + while let Ok(_count) = reader.read_line(&mut line) { + // println!("count: {count} ->{line}"); + if line.contains(ready_token) { + self.ready = true; + break; + } + } + } + } +} + +impl Drop for TaskStarter { + fn drop(&mut self) { + if let Err(e) = self.child.as_mut().expect("can't access child").kill() { + panic!("shutdown failed: {e}"); + } + } +} diff --git a/tests/cucumber.rs b/tests/cucumber.rs index e1397a1b4..356a0bb5a 100644 --- a/tests/cucumber.rs +++ b/tests/cucumber.rs @@ -9,15 +9,14 @@ use common::cli_arguments::Args; use common::lexicographic_file_walker::LexicographicFileWalker; use common::nearest_response::NearestResponse; use common::osm::OSMWay; +use common::task_starter::TaskStarter; use core::panic; use cucumber::{self, gherkin::Step, given, when, World}; use futures::{future, FutureExt}; use geo_types::{point, Point}; -use std::fmt::{format, Display}; use std::fs::{create_dir_all, File}; -use std::io::{BufRead, BufReader, Read, Write}; +use std::io::{Read, Write}; use std::path::PathBuf; -use std::process::{Command, Stdio}; use std::time::Duration; use std::{env, fs}; use ureq::Agent; @@ -163,11 +162,6 @@ fn request_nearest(world: &mut OSRMWorld, step: &Step) { println!("{cache_path:?} does not exist"); } - let routed_path = path.join("build").join("osrm-routed"); - if !routed_path.exists() { - panic!("osrm-routed binary not found"); - } - // parse query data let t = &step.table.as_ref().expect("no query table specified"); let test_cases: Vec<_> = t @@ -192,36 +186,18 @@ fn request_nearest(world: &mut OSRMWorld, step: &Step) { .collect(); let data_path = cache_path.join(world.scenario_id.to_owned() + ".osrm"); - println!("{routed_path:?} {}", data_path.to_str().unwrap()); - // TODO: move the child handling into a convenience struct - let mut handle = Command::new(routed_path) - .arg(data_path.to_str().unwrap()) - .stdout(Stdio::piped()) - .spawn(); - - let child = match &mut handle { - Ok(o) => o, - Err(e) => panic!("cannot access handle: {e}"), - }; - - let mut running = false; - if let Some(output) = &mut child.stdout { - // implement with a timeout - let mut reader = BufReader::new(output); - let mut line = String::new(); - while let Ok(_count) = reader.read_line(&mut line) { - // println!("count: {count} ->{line}"); - if line.contains("running and waiting for requests") { - running = true; - break; - } - } - } - if !running { - panic! {"routed not started"} + let routed_path = path.join("build").join("osrm-routed"); + if !routed_path.exists() { + panic!("osrm-routed binary not found"); } + // TODO: this should not require a temporary and behave like the API of std::process + let mut task = TaskStarter::new(routed_path.to_str().unwrap()); + task.arg(data_path.to_str().unwrap()); + task.spawn_wait_till_ready("running and waiting for requests"); + assert!(task.is_ready()); + // TODO: move to generic http request handling struct let agent: Agent = ureq::AgentBuilder::new() .timeout_read(Duration::from_secs(5)) @@ -260,9 +236,9 @@ fn request_nearest(world: &mut OSRMWorld, step: &Step) { assert!(approx_equal(result_location.y(), expected_location.y(), 5)); } - if let Err(e) = child.kill() { - panic!("shutdown failed: {e}"); - } + // if let Err(e) = child.kill() { + // panic!("shutdown failed: {e}"); + // } } pub fn approx_equal(a: f64, b: f64, dp: u8) -> bool {