From f23da9769169bbb69a333eff105eafc3c830ef58 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Thu, 12 Jan 2023 11:48:15 -0500 Subject: [PATCH] tests, report unknown cfg, rm catalog vector flds (#551) * clean up reporting of the un-used config params - instead of printing, collect them and print in one place if needed (allows testing too) * remove `vector_layer` in catalog - too verbose, not needed - can be received via tilejson for individual source * clean up tests so that they all use the same config yaml --- src/config.rs | 33 +- src/file_config.rs | 12 +- src/pg/config.rs | 11 +- src/srv/server.rs | 5 +- tests/expected/auto/catalog_auto.json | 13 +- tests/pg_function_source_test.rs | 21 - tests/pg_server_test.rs | 886 ++++++++++++++------------ tests/utils/mod.rs | 3 +- tests/utils/pg_utils.rs | 31 +- 9 files changed, 517 insertions(+), 498 deletions(-) diff --git a/src/config.rs b/src/config.rs index 356b5bdd..31481415 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,7 +6,6 @@ use std::path::Path; use std::pin::Pin; use futures::future::try_join_all; -use log::warn; use serde::{Deserialize, Serialize}; use serde_yaml::Value; use subst::VariableMap; @@ -40,12 +39,13 @@ pub struct Config { impl Config { /// Apply defaults to the config, and validate if there is a connection string - pub fn finalize(&mut self) -> Result<()> { - report_unrecognized_config("", &self.unrecognized); + pub fn finalize(&mut self) -> Result { + let mut res = Unrecognized::new(); + copy_unrecognized_config(&mut res, "", &self.unrecognized); let mut any = if let Some(pg) = &mut self.postgres { for pg in pg.iter_mut() { - pg.finalize()?; + res.extend(pg.finalize()?); } !pg.is_empty() } else { @@ -53,21 +53,21 @@ impl Config { }; any |= if let Some(cfg) = &mut self.pmtiles { - cfg.finalize("pmtiles.")?; + res.extend(cfg.finalize("pmtiles.")?); !cfg.is_empty() } else { false }; any |= if let Some(cfg) = &mut self.mbtiles { - cfg.finalize("mbtiles.")?; + res.extend(cfg.finalize("mbtiles.")?); !cfg.is_empty() } else { false }; if any { - Ok(()) + Ok(res) } else { Err(NoSources) } @@ -103,10 +103,18 @@ impl Config { } } -pub fn report_unrecognized_config(prefix: &str, unrecognized: &HashMap) { - for key in unrecognized.keys() { - warn!("Unrecognized config key: {prefix}{key}"); - } +pub type Unrecognized = HashMap; + +pub fn copy_unrecognized_config( + result: &mut Unrecognized, + prefix: &str, + unrecognized: &Unrecognized, +) { + result.extend( + unrecognized + .iter() + .map(|(k, v)| (format!("{prefix}{k}"), v.clone())), + ); } /// Read config from a file @@ -142,7 +150,8 @@ pub mod tests { pub fn assert_config(yaml: &str, expected: &Config) { let mut config = parse_cfg(yaml); - config.finalize().unwrap(); + let res = config.finalize().unwrap(); + assert!(res.is_empty(), "unrecognized config: {res:?}"); assert_eq!(&config, expected); } } diff --git a/src/file_config.rs b/src/file_config.rs index 80ca4262..e41af79e 100644 --- a/src/file_config.rs +++ b/src/file_config.rs @@ -8,7 +8,7 @@ use log::{info, warn}; use serde::{Deserialize, Serialize}; use serde_yaml::Value; -use crate::config::report_unrecognized_config; +use crate::config::{copy_unrecognized_config, Unrecognized}; use crate::file_config::FileError::{InvalidFilePath, InvalidSourceFilePath}; use crate::utils::sorted_opt_map; use crate::OneOrMany::{Many, One}; @@ -84,11 +84,12 @@ pub struct FileConfigSource { } impl FileConfigEnum { - pub fn finalize(&self, prefix: &str) -> Result<&Self, Error> { + pub fn finalize(&self, prefix: &str) -> Result { + let mut res = Unrecognized::new(); if let Self::Config(cfg) = self { - report_unrecognized_config(prefix, &cfg.unrecognized); + copy_unrecognized_config(&mut res, prefix, &cfg.unrecognized); } - Ok(self) + Ok(res) } #[must_use] @@ -239,7 +240,8 @@ mod tests { path: /tmp/file.ext "}) .unwrap(); - cfg.finalize("").unwrap(); + let res = cfg.finalize("").unwrap(); + assert!(res.is_empty(), "unrecognized config: {res:?}"); let FileConfigEnum::Config(cfg) = cfg else { panic!(); }; diff --git a/src/pg/config.rs b/src/pg/config.rs index ad461f4d..5cec2f1d 100644 --- a/src/pg/config.rs +++ b/src/pg/config.rs @@ -2,7 +2,7 @@ use futures::future::try_join; use serde::{Deserialize, Serialize}; use tilejson::TileJSON; -use crate::config::report_unrecognized_config; +use crate::config::{copy_unrecognized_config, Unrecognized}; use crate::pg::config_function::FuncInfoSources; use crate::pg::config_table::TableInfoSources; use crate::pg::configurator::PgBuilder; @@ -55,22 +55,23 @@ pub struct PgCfgPublishType { impl PgConfig { /// Apply defaults to the config, and validate if there is a connection string - pub fn finalize(&mut self) -> Result<&Self> { + pub fn finalize(&mut self) -> Result { + let mut res = Unrecognized::new(); if let Some(ref ts) = self.tables { for (k, v) in ts { - report_unrecognized_config(&format!("tables.{k}."), &v.unrecognized); + copy_unrecognized_config(&mut res, &format!("tables.{k}."), &v.unrecognized); } } if let Some(ref fs) = self.functions { for (k, v) in fs { - report_unrecognized_config(&format!("functions.{k}."), &v.unrecognized); + copy_unrecognized_config(&mut res, &format!("functions.{k}."), &v.unrecognized); } } if self.tables.is_none() && self.functions.is_none() && self.auto_publish.is_none() { self.auto_publish = Some(BoolOrObject::Bool(true)); } - Ok(self) + Ok(res) } pub async fn resolve(&mut self, id_resolver: IdResolver) -> crate::Result { diff --git a/src/srv/server.rs b/src/srv/server.rs index 5fc32597..ccf92554 100755 --- a/src/srv/server.rs +++ b/src/srv/server.rs @@ -18,7 +18,7 @@ use itertools::Itertools; use log::{debug, error}; use martin_tile_utils::DataFormat; use serde::{Deserialize, Serialize}; -use tilejson::{TileJSON, VectorLayer}; +use tilejson::TileJSON; use crate::source::{Source, Sources, UrlQuery, Xyz}; use crate::srv::config::{SrvConfig, KEEP_ALIVE_DEFAULT, LISTEN_ADDRESSES_DEFAULT}; @@ -106,8 +106,6 @@ pub struct IndexEntry { pub description: Option, #[serde(skip_serializing_if = "Option::is_none")] pub attribution: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub vector_layer: Option>, } impl PartialOrd for IndexEntry { @@ -159,7 +157,6 @@ async fn get_catalog(state: Data) -> impl Responder { name: tilejson.name, description: tilejson.description, attribution: tilejson.attribution, - vector_layer: tilejson.vector_layers, } }) .sorted() diff --git a/tests/expected/auto/catalog_auto.json b/tests/expected/auto/catalog_auto.json index da3784e2..47c07c1f 100644 --- a/tests/expected/auto/catalog_auto.json +++ b/tests/expected/auto/catalog_auto.json @@ -126,17 +126,6 @@ "content_type": "application/x-protobuf", "description": "Major cities from Natural Earth data", "id": "world_cities", - "name": "Major cities from Natural Earth data", - "vector_layer": [ - { - "description": "", - "fields": { - "name": "String" - }, - "id": "cities", - "maxzoom": 6, - "minzoom": 0 - } - ] + "name": "Major cities from Natural Earth data" } ] diff --git a/tests/pg_function_source_test.rs b/tests/pg_function_source_test.rs index e047452a..3ef32305 100644 --- a/tests/pg_function_source_test.rs +++ b/tests/pg_function_source_test.rs @@ -1,7 +1,6 @@ use ctor::ctor; use indoc::indoc; use itertools::Itertools; -use martin::pg::get_function_sources; use martin::Xyz; pub mod utils; @@ -12,26 +11,6 @@ fn init() { let _ = env_logger::builder().is_test(true).try_init(); } -#[actix_rt::test] -async fn get_function_sources_ok() { - let pool = mock_pool().await; - let sources = get_function_sources(&pool).await.unwrap(); - - assert!(!sources.is_empty()); - - let funcs = sources.get("public").unwrap(); - let source = funcs.get("function_zxy_query").unwrap(); - assert_eq!(source.1.schema, "public"); - assert_eq!(source.1.function, "function_zxy_query"); - assert_eq!(source.1.minzoom, None); - assert_eq!(source.1.maxzoom, None); - assert_eq!(source.1.bounds, None); - - let source = funcs.get("function_zxy_query_jsonb").unwrap(); - assert_eq!(source.1.schema, "public"); - assert_eq!(source.1.function, "function_zxy_query_jsonb"); -} - #[actix_rt::test] async fn function_source_tilejson() { let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await; diff --git a/tests/pg_server_test.rs b/tests/pg_server_test.rs index ab544211..eb9446b8 100644 --- a/tests/pg_server_test.rs +++ b/tests/pg_server_test.rs @@ -16,8 +16,9 @@ fn init() { } macro_rules! create_app { - ($sources:literal) => {{ - let sources = mock_sources(mock_pgcfg($sources)).await.0; + ($sources:expr) => {{ + let cfg = mock_cfg(indoc::indoc!($sources)); + let sources = mock_sources(cfg).await.0; let state = crate::utils::mock_app_data(sources).await; ::actix_web::test::init_service( ::actix_web::App::new() @@ -34,7 +35,10 @@ fn test_get(path: &str) -> Request { #[actix_rt::test] async fn pg_get_catalog_ok() { - let app = create_app! { "connection_string: $DATABASE_URL" }; + let app = create_app! { " +postgres: + connection_string: $DATABASE_URL +"}; let req = test_get("/catalog"); let response = call_service(&app, req).await; @@ -55,26 +59,27 @@ async fn pg_get_catalog_ok() { #[actix_rt::test] async fn pg_get_table_source_ok() { let app = create_app! { " -connection_string: $DATABASE_URL -tables: - bad_srid: - schema: public - table: table_source - srid: 3857 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 - table_source: - schema: public - table: table_source - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 +postgres: + connection_string: $DATABASE_URL + tables: + bad_srid: + schema: public + table: table_source + srid: 3857 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 + table_source: + schema: public + table: table_source + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 " }; let req = test_get("/non_existent"); @@ -84,6 +89,24 @@ tables: let req = test_get("/bad_srid"); let response = call_service(&app, req).await; assert_eq!(response.status(), StatusCode::NOT_FOUND); +} + +#[actix_rt::test] +async fn pg_get_table_source_ok_rewrite() { + let app = create_app! { " +postgres: + connection_string: $DATABASE_URL + tables: + table_source: + schema: public + table: table_source + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 +" }; let req = TestRequest::get() .uri("/table_source?token=martin") @@ -101,83 +124,84 @@ tables: #[actix_rt::test] async fn pg_get_table_source_tile_ok() { let app = create_app! { " -connection_string: $DATABASE_URL -tables: - points2: - schema: public - table: points2 - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - points1: - schema: public - table: points1 - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - points_empty_srid: - schema: public - table: points_empty_srid - srid: 900973 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 - table_source: - schema: public - table: table_source - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 - points3857: - schema: public - table: points3857 - srid: 3857 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - table_source_multiple_geom.geom1: - schema: public - table: table_source_multiple_geom - srid: 4326 - geometry_column: geom1 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - geom2: geometry - gid: int4 - table_source_multiple_geom.geom2: - schema: public - table: table_source_multiple_geom - srid: 4326 - geometry_column: geom2 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - geom1: geometry - gid: int4 - MIXPOINTS: - schema: MIXEDCASE - table: mixPoints - srid: 4326 - geometry_column: geoM - id_column: giD - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - tAble: text +postgres: + connection_string: $DATABASE_URL + tables: + points2: + schema: public + table: points2 + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + points1: + schema: public + table: points1 + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + points_empty_srid: + schema: public + table: points_empty_srid + srid: 900973 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 + table_source: + schema: public + table: table_source + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 + points3857: + schema: public + table: points3857 + srid: 3857 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + table_source_multiple_geom.geom1: + schema: public + table: table_source_multiple_geom + srid: 4326 + geometry_column: geom1 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + geom2: geometry + gid: int4 + table_source_multiple_geom.geom2: + schema: public + table: table_source_multiple_geom + srid: 4326 + geometry_column: geom2 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + geom1: geometry + gid: int4 + MIXPOINTS: + schema: MIXEDCASE + table: mixPoints + srid: 4326 + geometry_column: geoM + id_column: giD + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + tAble: text " }; let req = test_get("/non_existent/0/0/0"); @@ -192,83 +216,84 @@ tables: #[actix_rt::test] async fn pg_get_table_source_multiple_geom_tile_ok() { let app = create_app! { " -connection_string: $DATABASE_URL -tables: - points2: - schema: public - table: points2 - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - table_source_multiple_geom.geom2: - schema: public - table: table_source_multiple_geom - srid: 4326 - geometry_column: geom2 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - geom1: geometry - table_source: - schema: public - table: table_source - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 - points1: - schema: public - table: points1 - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - MIXPOINTS: - schema: MIXEDCASE - table: mixPoints - srid: 4326 - geometry_column: geoM - id_column: giD - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - tAble: text - points_empty_srid: - schema: public - table: points_empty_srid - srid: 900973 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 - points3857: - schema: public - table: points3857 - srid: 3857 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - table_source_multiple_geom.geom1: - schema: public - table: table_source_multiple_geom - srid: 4326 - geometry_column: geom1 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - geom2: geometry - gid: int4 +postgres: + connection_string: $DATABASE_URL + tables: + points2: + schema: public + table: points2 + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + table_source_multiple_geom.geom2: + schema: public + table: table_source_multiple_geom + srid: 4326 + geometry_column: geom2 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + geom1: geometry + table_source: + schema: public + table: table_source + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 + points1: + schema: public + table: points1 + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + MIXPOINTS: + schema: MIXEDCASE + table: mixPoints + srid: 4326 + geometry_column: geoM + id_column: giD + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + tAble: text + points_empty_srid: + schema: public + table: points_empty_srid + srid: 900973 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 + points3857: + schema: public + table: points3857 + srid: 3857 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + table_source_multiple_geom.geom1: + schema: public + table: table_source_multiple_geom + srid: 4326 + geometry_column: geom1 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + geom2: geometry + gid: int4 "}; let req = test_get("/table_source_multiple_geom.geom1/0/0/0"); @@ -283,48 +308,49 @@ tables: #[actix_rt::test] async fn pg_get_table_source_tile_minmax_zoom_ok() { let app = create_app! { " -connection_string: $DATABASE_URL -tables: - points3857: - schema: public - table: points3857 - srid: 3857 - geometry_column: geom - minzoom: 6 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - points2: - schema: public - table: points2 - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - points1: - schema: public - table: points1 - srid: 4326 - geometry_column: geom - minzoom: 6 - maxzoom: 12 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - table_source: - schema: public - table: table_source - srid: 4326 - geometry_column: geom - maxzoom: 6 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 +postgres: + connection_string: $DATABASE_URL + tables: + points3857: + schema: public + table: points3857 + srid: 3857 + geometry_column: geom + minzoom: 6 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + points2: + schema: public + table: points2 + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + points1: + schema: public + table: points1 + srid: 4326 + geometry_column: geom + minzoom: 6 + maxzoom: 12 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + table_source: + schema: public + table: table_source + srid: 4326 + geometry_column: geom + maxzoom: 6 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 "}; // zoom = 0 (nothing) let req = test_get("/points1/0/0/0"); @@ -389,7 +415,10 @@ tables: #[actix_rt::test] async fn pg_get_function_tiles() { - let app = create_app! { "connection_string: $DATABASE_URL" }; + let app = create_app! { " +postgres: + connection_string: $DATABASE_URL +"}; let req = test_get("/function_zoom_xy/6/38/20"); assert!(call_service(&app, req).await.status().is_success()); @@ -419,83 +448,84 @@ async fn pg_get_function_tiles() { #[actix_rt::test] async fn pg_get_composite_source_ok() { let app = create_app! { " -connection_string: $DATABASE_URL -tables: - table_source_multiple_geom.geom2: - schema: public - table: table_source_multiple_geom - srid: 4326 - geometry_column: geom2 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - geom1: geometry - points2: - schema: public - table: points2 - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - points_empty_srid: - schema: public - table: points_empty_srid - srid: 900973 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 - table_source: - schema: public - table: table_source - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 - MIXPOINTS: - schema: MIXEDCASE - table: mixPoints - srid: 4326 - geometry_column: geoM - id_column: giD - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - tAble: text - table_source_multiple_geom.geom1: - schema: public - table: table_source_multiple_geom - srid: 4326 - geometry_column: geom1 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - geom2: geometry - points1: - schema: public - table: points1 - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - points3857: - schema: public - table: points3857 - srid: 3857 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 +postgres: + connection_string: $DATABASE_URL + tables: + table_source_multiple_geom.geom2: + schema: public + table: table_source_multiple_geom + srid: 4326 + geometry_column: geom2 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + geom1: geometry + points2: + schema: public + table: points2 + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + points_empty_srid: + schema: public + table: points_empty_srid + srid: 900973 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 + table_source: + schema: public + table: table_source + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 + MIXPOINTS: + schema: MIXEDCASE + table: mixPoints + srid: 4326 + geometry_column: geoM + id_column: giD + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + tAble: text + table_source_multiple_geom.geom1: + schema: public + table: table_source_multiple_geom + srid: 4326 + geometry_column: geom1 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + geom2: geometry + points1: + schema: public + table: points1 + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + points3857: + schema: public + table: points3857 + srid: 3857 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 "}; let req = test_get("/non_existent1,non_existent2"); let response = call_service(&app, req).await; @@ -509,83 +539,84 @@ tables: #[actix_rt::test] async fn pg_get_composite_source_tile_ok() { let app = create_app! { " -connection_string: $DATABASE_URL -tables: - points_empty_srid: - schema: public - table: points_empty_srid - srid: 900973 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 - table_source_multiple_geom.geom1: - schema: public - table: table_source_multiple_geom - srid: 4326 - geometry_column: geom1 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - geom2: geometry - gid: int4 - table_source_multiple_geom.geom2: - schema: public - table: table_source_multiple_geom - srid: 4326 - geometry_column: geom2 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - geom1: geometry - gid: int4 - table_source: - schema: public - table: table_source - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: GEOMETRY - properties: - gid: int4 - points1: - schema: public - table: points1 - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - MIXPOINTS: - schema: MIXEDCASE - table: mixPoints - srid: 4326 - geometry_column: geoM - id_column: giD - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - tAble: text - points2: - schema: public - table: points2 - srid: 4326 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - points3857: - schema: public - table: points3857 - srid: 3857 - geometry_column: geom - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 +postgres: + connection_string: $DATABASE_URL + tables: + points_empty_srid: + schema: public + table: points_empty_srid + srid: 900973 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 + table_source_multiple_geom.geom1: + schema: public + table: table_source_multiple_geom + srid: 4326 + geometry_column: geom1 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + geom2: geometry + gid: int4 + table_source_multiple_geom.geom2: + schema: public + table: table_source_multiple_geom + srid: 4326 + geometry_column: geom2 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + geom1: geometry + gid: int4 + table_source: + schema: public + table: table_source + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: GEOMETRY + properties: + gid: int4 + points1: + schema: public + table: points1 + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + MIXPOINTS: + schema: MIXEDCASE + table: mixPoints + srid: 4326 + geometry_column: geoM + id_column: giD + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + tAble: text + points2: + schema: public + table: points2 + srid: 4326 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + points3857: + schema: public + table: points3857 + srid: 3857 + geometry_column: geom + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 "}; let req = test_get("/non_existent1,non_existent2/0/0/0"); @@ -600,30 +631,31 @@ tables: #[actix_rt::test] async fn pg_get_composite_source_tile_minmax_zoom_ok() { let app = create_app! { " -connection_string: $DATABASE_URL -tables: - points1: - schema: public - table: points1 - srid: 4326 - geometry_column: geom - minzoom: 6 - maxzoom: 13 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 - points2: - schema: public - table: points2 - srid: 4326 - geometry_column: geom - minzoom: 13 - maxzoom: 20 - bounds: [-180.0, -90.0, 180.0, 90.0] - geometry_type: POINT - properties: - gid: int4 +postgres: + connection_string: $DATABASE_URL + tables: + points1: + schema: public + table: points1 + srid: 4326 + geometry_column: geom + minzoom: 6 + maxzoom: 13 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 + points2: + schema: public + table: points2 + srid: 4326 + geometry_column: geom + minzoom: 13 + maxzoom: 20 + bounds: [-180.0, -90.0, 180.0, 90.0] + geometry_type: POINT + properties: + gid: int4 "}; // zoom = 0 (nothing) @@ -664,7 +696,10 @@ tables: #[actix_rt::test] async fn pg_null_functions() { - let app = create_app! { "connection_string: $DATABASE_URL" }; + let app = create_app! { " +postgres: + connection_string: $DATABASE_URL +"}; let req = test_get("/function_null/0/0/0"); let response = call_service(&app, req).await; @@ -681,7 +716,10 @@ async fn pg_null_functions() { #[actix_rt::test] async fn pg_get_function_source_ok() { - let app = create_app! { "connection_string: $DATABASE_URL" }; + let app = create_app! { " +postgres: + connection_string: $DATABASE_URL +"}; let req = test_get("/non_existent"); let response = call_service(&app, req).await; @@ -718,6 +756,14 @@ async fn pg_get_function_source_ok() { let req = test_get("/function_zxy_row_key"); let response = call_service(&app, req).await; assert!(response.status().is_success()); +} + +#[actix_rt::test] +async fn pg_get_function_source_ok_rewrite() { + let app = create_app! { " +postgres: + connection_string: $DATABASE_URL +"}; let req = TestRequest::get() .uri("/function_zxy_query?token=martin") @@ -745,7 +791,10 @@ async fn pg_get_function_source_ok() { #[actix_rt::test] async fn pg_get_function_source_tile_ok() { - let app = create_app! { "connection_string: $DATABASE_URL" }; + let app = create_app! { " +postgres: + connection_string: $DATABASE_URL +"}; let req = test_get("/function_zxy_query/0/0/0"); let response = call_service(&app, req).await; @@ -755,17 +804,18 @@ async fn pg_get_function_source_tile_ok() { #[actix_rt::test] async fn pg_get_function_source_tile_minmax_zoom_ok() { let app = create_app! {" -connection_string: $DATABASE_URL -functions: - function_source1: - schema: public - function: function_zxy_query - function_source2: - schema: public - function: function_zxy_query - minzoom: 6 - maxzoom: 12 - bounds: [-180.0, -90.0, 180.0, 90.0] +postgres: + connection_string: $DATABASE_URL + functions: + function_source1: + schema: public + function: function_zxy_query + function_source2: + schema: public + function: function_zxy_query + minzoom: 6 + maxzoom: 12 + bounds: [-180.0, -90.0, 180.0, 90.0] "}; // zoom = 0 (function_source1) @@ -811,7 +861,10 @@ functions: #[actix_rt::test] async fn pg_get_function_source_query_params_ok() { - let app = create_app! { "connection_string: $DATABASE_URL" }; + let app = create_app! { " +postgres: + connection_string: $DATABASE_URL +"}; let req = test_get("/function_zxy_query_test/0/0/0"); let response = call_service(&app, req).await; @@ -825,7 +878,10 @@ async fn pg_get_function_source_query_params_ok() { #[actix_rt::test] async fn pg_get_health_returns_ok() { - let app = create_app! { "connection_string: $DATABASE_URL" }; + let app = create_app! { " +postgres: + connection_string: $DATABASE_URL +"}; let req = test_get("/health"); let response = call_service(&app, req).await; @@ -903,7 +959,7 @@ tables: // -------------------------------------------- - let state = crate::utils::mock_app_data(mock.0).await; + let state = mock_app_data(mock.0).await; let app = ::actix_web::test::init_service( ::actix_web::App::new() .app_data(state) diff --git a/tests/utils/mod.rs b/tests/utils/mod.rs index e49edc99..e393a70e 100644 --- a/tests/utils/mod.rs +++ b/tests/utils/mod.rs @@ -25,6 +25,7 @@ pub fn mock_cfg(yaml: &str) -> Config { }; let env = FauxEnv(vec![("DATABASE_URL", db_url.into())].into_iter().collect()); let mut cfg: Config = subst::yaml::from_str(yaml, &env).unwrap(); - cfg.finalize().unwrap(); + let res = cfg.finalize().unwrap(); + assert!(res.is_empty(), "unrecognized config: {res:?}"); cfg } diff --git a/tests/utils/pg_utils.rs b/tests/utils/pg_utils.rs index f6a1c535..b5c729d3 100644 --- a/tests/utils/pg_utils.rs +++ b/tests/utils/pg_utils.rs @@ -1,9 +1,9 @@ +use indoc::formatdoc; pub use martin::args::Env; -use martin::pg::{PgConfig, Pool, TableInfo}; -use martin::OneOrMany::One; -use martin::{Config, IdResolver, OneOrMany, Source, Sources}; +use martin::pg::TableInfo; +use martin::{Config, IdResolver, Source, Sources}; -use crate::FauxEnv; +use crate::mock_cfg; // // This file is used by many tests and benchmarks. @@ -15,25 +15,10 @@ pub type MockSource = (Sources, Config); #[allow(dead_code)] #[must_use] pub fn mock_pgcfg(yaml: &str) -> Config { - let Ok(db_url) = std::env::var("DATABASE_URL") else { - panic!("DATABASE_URL env var is not set. Unable to do integration tests"); - }; - let env = FauxEnv(vec![("DATABASE_URL", db_url.into())].into_iter().collect()); - let cfg: PgConfig = subst::yaml::from_str(yaml, &env).unwrap(); - let mut config = Config { - postgres: Some(One(cfg)), - ..Default::default() - }; - config.finalize().unwrap(); - config -} - -#[allow(dead_code)] -pub async fn mock_pool() -> Pool { - let cfg = mock_pgcfg("connection_string: $DATABASE_URL"); - let OneOrMany::One(cfg) = cfg.postgres.unwrap() else { panic!() }; - let res = Pool::new(&cfg).await; - res.expect("Failed to create pool") + mock_cfg(&formatdoc! {" + postgres: + {} + ", yaml.replace('\n', "\n ")}) } #[allow(dead_code)]