Make the first 3 nearest/pick.feature scenarios pass
This commit is contained in:
parent
59cbb08c0e
commit
5cf37a0c7c
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -548,6 +548,12 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "help"
|
||||
version = "0.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5d2c6714f78261bbacbd07338eb21943fa5a25c67760287aecb6aefbec89062"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
@ -740,6 +746,8 @@ dependencies = [
|
||||
"cucumber",
|
||||
"futures",
|
||||
"geo-types",
|
||||
"help",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"ureq",
|
||||
"xml-builder",
|
||||
|
@ -10,6 +10,8 @@ clap = "4.5.4"
|
||||
cucumber = "0.21.0"
|
||||
futures = "0.3.30"
|
||||
geo-types = "0.7.13"
|
||||
help = "0.0.0"
|
||||
serde = { version = "1.0.203", features = ["serde_derive"] }
|
||||
serde_json = "1.0.117"
|
||||
ureq = "2.9.7"
|
||||
xml-builder = "0.5.2"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace osrm::server::service
|
||||
{
|
||||
@ -30,11 +31,11 @@ std::string getWrongOptionHelp(const engine::api::NearestParameters ¶meters)
|
||||
return help;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
engine::Status NearestService::RunQuery(std::size_t prefix_length,
|
||||
std::string &query,
|
||||
osrm::engine::api::ResultT &result)
|
||||
{
|
||||
std::cout << "running query: " << query << "\n";
|
||||
result = util::json::Object();
|
||||
auto &json_result = std::get<util::json::Object>(result);
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
use std::{collections::VecDeque, fs, path::{Path, PathBuf}};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
// TODO: port into toolbox-rs
|
||||
pub struct LexicographicFileWalker {
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub mod lexicographic_file_walker;
|
||||
pub mod nearest_response;
|
||||
pub mod osm;
|
||||
pub mod osm_db;
|
||||
pub mod osrm_world;
|
||||
|
23
tests/common/nearest_response.rs
Normal file
23
tests/common/nearest_response.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use geo_types::{point, Point};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct Waypoint {
|
||||
hint: String,
|
||||
nodes: Vec<u64>,
|
||||
distance: f64,
|
||||
name: String,
|
||||
location: [f64; 2],
|
||||
}
|
||||
|
||||
impl Waypoint {
|
||||
pub fn location(&self) -> Point {
|
||||
point!(self.location)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct NearestResponse {
|
||||
code: String,
|
||||
pub waypoints: Vec<Waypoint>,
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use xml_builder::{XMLBuilder, XMLElement, XMLVersion};
|
||||
use super::osm::{OSMNode, OSMWay};
|
||||
use xml_builder::{XMLBuilder, XMLElement, XMLVersion};
|
||||
|
||||
// TODO: better error handling in XML creation
|
||||
#[derive(Debug, Default)]
|
||||
@ -124,4 +124,4 @@ mod tests {
|
||||
println!("{actual}");
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::{collections::HashMap, fs::File, path::PathBuf};
|
||||
use crate::Point;
|
||||
use cucumber::World;
|
||||
use std::{collections::HashMap, fs::File, path::PathBuf};
|
||||
|
||||
use super::{osm::OSMNode, osm_db::OSMDb};
|
||||
|
||||
@ -58,10 +58,17 @@ impl OSRMWorld {
|
||||
pub fn get_location(&self, name: char) -> Point {
|
||||
match name {
|
||||
// TODO: move lookup to world
|
||||
'0'..='9' => self.known_locations.get(&name).expect("test case specifies unknown location: {name}"),
|
||||
'a'..='z' => self.known_osm_nodes.get(&name).expect("test case specifies unknown osm node: {name}"),
|
||||
'0'..='9' => self
|
||||
.known_locations
|
||||
.get(&name)
|
||||
.expect("test case specifies unknown location: {name}"),
|
||||
'a'..='z' => self
|
||||
.known_osm_nodes
|
||||
.get(&name)
|
||||
.expect("test case specifies unknown osm node: {name}"),
|
||||
_ => unreachable!("nodes have to be name in [0-9][a-z]"),
|
||||
}.clone()
|
||||
}
|
||||
.clone()
|
||||
}
|
||||
|
||||
pub fn add_location(&mut self, name: char, location: Point) {
|
||||
@ -70,4 +77,4 @@ impl OSRMWorld {
|
||||
}
|
||||
self.known_locations.insert(name, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,20 +6,20 @@ use crate::common::osrm_world::OSRMWorld;
|
||||
use cheap_ruler::CheapRuler;
|
||||
use clap::Parser;
|
||||
use common::lexicographic_file_walker::LexicographicFileWalker;
|
||||
use common::nearest_response::NearestResponse;
|
||||
use common::osm::OSMWay;
|
||||
use serde_json::Value;
|
||||
use ureq::Agent;
|
||||
use core::panic;
|
||||
use std::time::Duration;
|
||||
use cucumber::{self, gherkin::Step, given, when, World};
|
||||
use futures::{future, FutureExt};
|
||||
use geo_types::{point, Point};
|
||||
use std::fmt::Display;
|
||||
use std::fmt::{format, Display};
|
||||
use std::fs::{create_dir_all, File};
|
||||
use std::io::{Read, Write};
|
||||
use std::io::{BufRead, BufReader, Read, Write};
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::time::Duration;
|
||||
use std::{env, fs};
|
||||
use ureq::Agent;
|
||||
|
||||
const DEFAULT_ORIGIN: [f64; 2] = [1., 1.]; // TODO: move to world?
|
||||
const DEFAULT_GRID_SIZE: f64 = 100.; // TODO: move to world?
|
||||
@ -192,18 +192,38 @@ fn request_nearest(world: &mut OSRMWorld, step: &Step) {
|
||||
|
||||
let data_path = cache_path.join(world.scenario_id.to_owned() + ".osrm");
|
||||
println!("{routed_path:?} {}", data_path.to_str().unwrap());
|
||||
let handle = Command::new(routed_path)
|
||||
|
||||
// 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();
|
||||
|
||||
if let Err(e) = handle {
|
||||
panic!("{e}");
|
||||
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 {
|
||||
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 agent: Agent = ureq::AgentBuilder::new()
|
||||
.timeout_read(Duration::from_secs(5))
|
||||
.timeout_write(Duration::from_secs(5))
|
||||
.build();
|
||||
.timeout_read(Duration::from_secs(5))
|
||||
.timeout_write(Duration::from_secs(5))
|
||||
.build();
|
||||
|
||||
// parse and run test cases
|
||||
for (query, expected) in test_cases {
|
||||
@ -213,23 +233,50 @@ fn request_nearest(world: &mut OSRMWorld, step: &Step) {
|
||||
println!("{query_location:?} => {expected_location:?}");
|
||||
// run queries
|
||||
// "http://localhost:5000/nearest/v1/testbot/1.0008984512067491,1.0"
|
||||
let url = format!("http://localhost:5000/nearest/v1/{}/{},{}", world.profile, query_location.x(), query_location.y());
|
||||
let body: String = agent.get(&url)
|
||||
.call().unwrap()
|
||||
.into_string().unwrap();
|
||||
let url = format!(
|
||||
"http://localhost:5000/nearest/v1/{}/{},{}",
|
||||
world.profile,
|
||||
query_location.x(),
|
||||
query_location.y()
|
||||
);
|
||||
let call = agent.get(&url).call();
|
||||
|
||||
let v: Value = serde_json::from_str(&body).unwrap();
|
||||
let result_location = point!{ x: v["location"][0].as_f64().unwrap(), y: v["location"][1].as_f64().unwrap()};
|
||||
assert_eq!(result_location, expected_location)
|
||||
let body = match call {
|
||||
Ok(response) => response.into_string().expect("response not parseable"),
|
||||
Err(e) => panic!("http error: {e}"),
|
||||
};
|
||||
|
||||
println!("body: {body}");
|
||||
|
||||
let v: NearestResponse = match serde_json::from_str(&body) {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic!("parsing error {e}"),
|
||||
};
|
||||
|
||||
let result_location = v.waypoints[0].location();
|
||||
// assert_eq!(result_location, expected_location)
|
||||
assert!(approx_equal(result_location.x(), expected_location.x(), 5));
|
||||
assert!(approx_equal(result_location.y(), expected_location.y(), 5));
|
||||
// println!("{body}");
|
||||
// check results
|
||||
}
|
||||
|
||||
if let Err(e) = handle.expect("osrm-routed died unexpectedly").kill() {
|
||||
if let Err(e) = child.kill() {
|
||||
panic!("shutdown failed: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
// matchLocation (got, want) {
|
||||
// if (got == null || want == null) return false;
|
||||
// return this.match(got[0], util.format('%d ~0.0025%', want.lon)) &&
|
||||
// this.match(got[1], util.format('%d ~0.0025%', want.lat));
|
||||
// }
|
||||
|
||||
pub fn approx_equal(a: f64, b: f64, dp: u8) -> bool {
|
||||
let p = 10f64.powi(-(dp as i32));
|
||||
(a - b).abs() < p
|
||||
}
|
||||
|
||||
// TODO: move to different file
|
||||
fn get_file_as_byte_vec(path: &PathBuf) -> Vec<u8> {
|
||||
println!("opening {path:?}");
|
||||
|
Loading…
Reference in New Issue
Block a user