From f969d92b2270927017ec0bc69ebc5e763b96bfca Mon Sep 17 00:00:00 2001 From: James Tomlinson Date: Thu, 14 Nov 2024 17:07:44 +0000 Subject: [PATCH] refactor(tests): Refactor tests into integration tests. (#287) Move the test models into proper `tests` folder as proper integration tests. Test functions are generated using a macro in a consistent manner. These tests no also read JSON models and CSV results from file rather than including them in the test binary. Where original unit tests had assertion recorders to test outputs these have been converted to expected CSV output files. --- pywr-core/src/test_utils.rs | 21 +- pywr-schema/src/model.rs | 54 +- pywr-schema/src/nodes/core.rs | 195 +------ pywr-schema/src/nodes/delay.rs | 42 -- pywr-schema/src/nodes/loss_link.rs | 81 --- pywr-schema/src/nodes/piecewise_link.rs | 64 --- pywr-schema/src/nodes/piecewise_storage.rs | 132 ----- pywr-schema/src/nodes/river.rs | 45 -- pywr-schema/src/nodes/river_gauge.rs | 37 -- .../src/nodes/river_split_with_gauge.rs | 37 -- .../src/nodes/rolling_virtual_storage.rs | 34 -- .../src/nodes/water_treatment_works.rs | 91 ---- pywr-schema/src/outputs/csv.rs | 178 ------- pywr-schema/src/outputs/hdf.rs | 9 +- pywr-schema/src/outputs/memory.rs | 9 +- pywr-schema/src/parameters/python.rs | 4 +- pywr-schema/src/timeseries/mod.rs | 70 --- .../test_models => tests}/30-day-licence.json | 0 .../csv1-outputs-long.csv | 0 .../csv1-outputs-wide.csv | 0 .../{src/test_models => tests}/csv1.json | 4 +- .../csv2-outputs-long.csv | 0 .../csv2-outputs-wide.csv | 0 .../{src/test_models => tests}/csv2.json | 4 +- .../csv3-outputs-long.csv | 0 .../{src/test_models => tests}/csv3.json | 2 +- pywr-schema/tests/delay1-expected.csv | 63 +++ .../{src/test_models => tests}/delay1.json | 30 +- .../{src/test_models => tests}/hdf1.json | 0 .../{src/test_models => tests}/inflow.csv | 0 .../link_with_soft_max.json | 0 .../link_with_soft_min.json | 0 .../loss_link1-expected.csv | 0 .../test_models => tests}/loss_link1.json | 2 +- .../loss_link2-expected.csv | 0 .../test_models => tests}/loss_link2.json | 2 +- .../{src/test_models => tests}/memory1.json | 0 .../test_models => tests}/multi1/model.json | 0 .../multi1/network1.json | 0 .../multi1/network2.json | 0 .../test_models => tests}/multi2/model.json | 0 .../multi2/network1.json | 0 .../multi2/network2.json | 0 .../mutual-exclusivity1.csv | 0 .../mutual-exclusivity1.json | 2 +- .../mutual-exclusivity2.csv | 0 .../mutual-exclusivity2.json | 2 +- .../mutual-exclusivity3.csv | 0 .../mutual-exclusivity3.json | 2 +- .../piecewise-link1-edges.csv | 0 .../piecewise-link1-nodes.csv | 0 .../piecewise_link1.json | 0 .../tests/piecewise_storage1-expected.csv | 91 ++++ .../piecewise_storage1.json | 25 +- .../tests/piecewise_storage2-expected.csv | 487 ++++++++++++++++++ .../piecewise_storage2.json | 29 +- .../test_models => tests}/river_gauge1.json | 0 .../river_loss1-expected.csv | 0 .../test_models => tests}/river_loss1.json | 2 +- .../river_split_with_gauge1.json | 0 .../{src/test_models => tests}/simple1.json | 0 .../storage_max_volumes.json | 0 pywr-schema/tests/test_models.rs | 143 +++++ .../test_models => tests}/test_parameters.py | 0 pywr-schema/tests/timeseries-expected.csv | 366 +++++++++++++ .../test_models => tests}/timeseries.json | 20 + .../timeseries_pandas.json | 0 .../v1/timeseries-converted.json | 0 .../test_models => tests}/v1/timeseries.json | 0 .../test_models => tests}/wtw1-expected.csv | 0 .../{src/test_models => tests}/wtw1.json | 2 +- .../test_models => tests}/wtw2-expected.csv | 0 .../{src/test_models => tests}/wtw2.json | 2 +- 73 files changed, 1319 insertions(+), 1064 deletions(-) rename pywr-schema/{src/test_models => tests}/30-day-licence.json (100%) rename pywr-schema/{src/test_models => tests}/csv1-outputs-long.csv (100%) rename pywr-schema/{src/test_models => tests}/csv1-outputs-wide.csv (100%) rename pywr-schema/{src/test_models => tests}/csv1.json (94%) rename pywr-schema/{src/test_models => tests}/csv2-outputs-long.csv (100%) rename pywr-schema/{src/test_models => tests}/csv2-outputs-wide.csv (100%) rename pywr-schema/{src/test_models => tests}/csv2.json (95%) rename pywr-schema/{src/test_models => tests}/csv3-outputs-long.csv (100%) rename pywr-schema/{src/test_models => tests}/csv3.json (97%) create mode 100644 pywr-schema/tests/delay1-expected.csv rename pywr-schema/{src/test_models => tests}/delay1.json (63%) rename pywr-schema/{src/test_models => tests}/hdf1.json (100%) rename pywr-schema/{src/test_models => tests}/inflow.csv (100%) rename pywr-schema/{src/test_models => tests}/link_with_soft_max.json (100%) rename pywr-schema/{src/test_models => tests}/link_with_soft_min.json (100%) rename pywr-schema/{src/test_models => tests}/loss_link1-expected.csv (100%) rename pywr-schema/{src/test_models => tests}/loss_link1.json (98%) rename pywr-schema/{src/test_models => tests}/loss_link2-expected.csv (100%) rename pywr-schema/{src/test_models => tests}/loss_link2.json (97%) rename pywr-schema/{src/test_models => tests}/memory1.json (100%) rename pywr-schema/{src/test_models => tests}/multi1/model.json (100%) rename pywr-schema/{src/test_models => tests}/multi1/network1.json (100%) rename pywr-schema/{src/test_models => tests}/multi1/network2.json (100%) rename pywr-schema/{src/test_models => tests}/multi2/model.json (100%) rename pywr-schema/{src/test_models => tests}/multi2/network1.json (100%) rename pywr-schema/{src/test_models => tests}/multi2/network2.json (100%) rename pywr-schema/{src/test_models => tests}/mutual-exclusivity1.csv (100%) rename pywr-schema/{src/test_models => tests}/mutual-exclusivity1.json (98%) rename pywr-schema/{src/test_models => tests}/mutual-exclusivity2.csv (100%) rename pywr-schema/{src/test_models => tests}/mutual-exclusivity2.json (98%) rename pywr-schema/{src/test_models => tests}/mutual-exclusivity3.csv (100%) rename pywr-schema/{src/test_models => tests}/mutual-exclusivity3.json (98%) rename pywr-schema/{src/test_models => tests}/piecewise-link1-edges.csv (100%) rename pywr-schema/{src/test_models => tests}/piecewise-link1-nodes.csv (100%) rename pywr-schema/{src/test_models => tests}/piecewise_link1.json (100%) create mode 100644 pywr-schema/tests/piecewise_storage1-expected.csv rename pywr-schema/{src/test_models => tests}/piecewise_storage1.json (77%) create mode 100644 pywr-schema/tests/piecewise_storage2-expected.csv rename pywr-schema/{src/test_models => tests}/piecewise_storage2.json (82%) rename pywr-schema/{src/test_models => tests}/river_gauge1.json (100%) rename pywr-schema/{src/test_models => tests}/river_loss1-expected.csv (100%) rename pywr-schema/{src/test_models => tests}/river_loss1.json (97%) rename pywr-schema/{src/test_models => tests}/river_split_with_gauge1.json (100%) rename pywr-schema/{src/test_models => tests}/simple1.json (100%) rename pywr-schema/{src/test_models => tests}/storage_max_volumes.json (100%) create mode 100644 pywr-schema/tests/test_models.rs rename pywr-schema/{src/test_models => tests}/test_parameters.py (100%) create mode 100644 pywr-schema/tests/timeseries-expected.csv rename pywr-schema/{src/test_models => tests}/timeseries.json (84%) rename pywr-schema/{src/test_models => tests}/timeseries_pandas.json (100%) rename pywr-schema/{src/test_models => tests}/v1/timeseries-converted.json (100%) rename pywr-schema/{src/test_models => tests}/v1/timeseries.json (100%) rename pywr-schema/{src/test_models => tests}/wtw1-expected.csv (100%) rename pywr-schema/{src/test_models => tests}/wtw1.json (98%) rename pywr-schema/{src/test_models => tests}/wtw2-expected.csv (100%) rename pywr-schema/{src/test_models => tests}/wtw2.json (98%) diff --git a/pywr-core/src/test_utils.rs b/pywr-core/src/test_utils.rs index 2181b350..e0c89930 100644 --- a/pywr-core/src/test_utils.rs +++ b/pywr-core/src/test_utils.rs @@ -169,22 +169,26 @@ pub fn run_and_assert_parameter( /// A struct to hold the expected outputs for a test. pub struct ExpectedOutputs { - actual_path: PathBuf, - expected_str: &'static str, + output_path: PathBuf, + expected_str: String, } impl ExpectedOutputs { - pub fn new(actual_path: PathBuf, expected_str: &'static str) -> Self { + pub fn new(output_path: PathBuf, expected_str: String) -> Self { Self { - actual_path, + output_path, expected_str, } } fn verify(&self) { - assert!(self.actual_path.exists()); - let actual_str = std::fs::read_to_string(&self.actual_path).unwrap(); - assert_eq!(actual_str, self.expected_str); + assert!( + self.output_path.exists(), + "Output file does not exist: {:?}", + self.output_path + ); + let actual_str = std::fs::read_to_string(&self.output_path).unwrap(); + assert_eq!(actual_str, self.expected_str, "Output file contents do not match"); } } @@ -193,18 +197,15 @@ impl ExpectedOutputs { /// The model will only be run if the solver has the required solver features (and /// is also enabled as a Cargo feature). pub fn run_all_solvers(model: &Model, solvers_without_features: &[&str], expected_outputs: &[ExpectedOutputs]) { - println!("Running CLP"); check_features_and_run::(model, !solvers_without_features.contains(&"clp"), expected_outputs); #[cfg(feature = "cbc")] { - println!("Running CBC"); check_features_and_run::(model, !solvers_without_features.contains(&"cbc"), expected_outputs); } #[cfg(feature = "highs")] { - println!("Running Highs"); check_features_and_run::(model, !solvers_without_features.contains(&"highs"), expected_outputs); } diff --git a/pywr-schema/src/model.rs b/pywr-schema/src/model.rs index bf45acd8..8da5a710 100644 --- a/pywr-schema/src/model.rs +++ b/pywr-schema/src/model.rs @@ -532,7 +532,7 @@ pub enum PywrNetworkRef { /// The simplest model is given in the example below: /// /// ```json -#[doc = include_str!("test_models/simple1.json")] +#[doc = include_str!("../tests/simple1.json")] /// ``` /// /// @@ -733,11 +733,11 @@ pub struct PywrMultiNetworkEntry { /// /// ```json5 /// // model.json -#[doc = include_str!("test_models/multi1/model.json")] +#[doc = include_str!("../tests/multi1/model.json")] /// // network1.json -#[doc = include_str!("test_models/multi1/network1.json")] +#[doc = include_str!("../tests/multi1/network1.json")] /// // network2.json -#[doc = include_str!("test_models/multi1/network2.json")] +#[doc = include_str!("../tests/multi1/network2.json")] /// ``` /// /// @@ -892,16 +892,17 @@ mod tests { use super::PywrModel; use crate::model::Timestepper; use crate::visit::VisitPaths; + use std::fs::read_to_string; use std::path::PathBuf; - fn model_str() -> &'static str { - include_str!("./test_models/simple1.json") + fn model_str() -> String { + read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/simple1.json")).unwrap() } #[test] fn test_simple1_schema() { let data = model_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); + let schema: PywrModel = serde_json::from_str(&data).unwrap(); assert_eq!(schema.network.nodes.len(), 3); assert_eq!(schema.network.edges.len(), 2); @@ -977,11 +978,11 @@ mod tests { #[test] fn test_visit_paths() { let mut model_fn = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - model_fn.push("src/test_models/timeseries.json"); + model_fn.push("tests/timeseries.json"); let mut schema = PywrModel::from_path(model_fn.as_path()).unwrap(); - let expected_paths = vec![PathBuf::from("inflow.csv")]; + let expected_paths = vec![PathBuf::from("inflow.csv"), PathBuf::from("timeseries-expected.csv")]; let mut paths: Vec = Vec::new(); @@ -1002,26 +1003,6 @@ mod tests { panic!("Expected an error due to missing file: {str}"); } } - - #[test] - fn test_v1_conversion() { - let v1_str = include_str!("./test_models/v1/timeseries.json"); - let v1: pywr_v1_schema::PywrModel = serde_json::from_str(v1_str).unwrap(); - - let (v2, errors) = PywrModel::from_v1(v1); - - assert_eq!(errors.len(), 0); - - std::fs::write("tmp.json", serde_json::to_string_pretty(&v2).unwrap()).unwrap(); - - let v2_converted: serde_json::Value = - serde_json::from_str(&serde_json::to_string_pretty(&v2).unwrap()).unwrap(); - - let v2_expected: serde_json::Value = - serde_json::from_str(include_str!("./test_models/v1/timeseries-converted.json")).unwrap(); - - assert_eq!(v2_converted, v2_expected); - } } #[cfg(test)] @@ -1032,16 +1013,17 @@ mod core_tests { use crate::parameters::{AggFunc, AggregatedParameter, ConstantParameter, ConstantValue, Parameter, ParameterMeta}; use ndarray::{Array1, Array2, Axis}; use pywr_core::{metric::MetricF64, recorders::AssertionRecorder, solvers::ClpSolver, test_utils::run_all_solvers}; + use std::fs::read_to_string; use std::path::PathBuf; - fn model_str() -> &'static str { - include_str!("./test_models/simple1.json") + fn model_str() -> String { + read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/simple1.json")).unwrap() } #[test] fn test_simple1_run() { let data = model_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); + let schema: PywrModel = serde_json::from_str(&data).unwrap(); let mut model = schema.build_model(None, None).unwrap(); let network = model.network_mut(); @@ -1070,7 +1052,7 @@ mod core_tests { #[test] fn test_cycle_error() { let data = model_str(); - let mut schema: PywrModel = serde_json::from_str(data).unwrap(); + let mut schema: PywrModel = serde_json::from_str(&data).unwrap(); // Add additional parameters for the test if let Some(parameters) = &mut schema.network.parameters { @@ -1128,7 +1110,7 @@ mod core_tests { #[test] fn test_ordering() { let data = model_str(); - let mut schema: PywrModel = serde_json::from_str(data).unwrap(); + let mut schema: PywrModel = serde_json::from_str(&data).unwrap(); if let Some(parameters) = &mut schema.network.parameters { parameters.extend(vec![ @@ -1175,7 +1157,7 @@ mod core_tests { #[test] fn test_multi1_model() { let mut model_fn = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - model_fn.push("src/test_models/multi1/model.json"); + model_fn.push("tests/multi1/model.json"); let schema = PywrMultiNetworkModel::from_path(model_fn.as_path()).unwrap(); let mut model = schema.build_model(model_fn.parent(), None).unwrap(); @@ -1225,7 +1207,7 @@ mod core_tests { #[test] fn test_multi2_model() { let mut model_fn = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - model_fn.push("src/test_models/multi2/model.json"); + model_fn.push("tests/multi2/model.json"); let schema = PywrMultiNetworkModel::from_path(model_fn.as_path()).unwrap(); let mut model = schema.build_model(model_fn.parent(), None).unwrap(); diff --git a/pywr-schema/src/nodes/core.rs b/pywr-schema/src/nodes/core.rs index 1fd3c530..15b1863b 100644 --- a/pywr-schema/src/nodes/core.rs +++ b/pywr-schema/src/nodes/core.rs @@ -173,7 +173,7 @@ pub struct SoftConstraint { /// ``` /// ## Implementation /// -/// +/// /// ### Only `soft_min` is defined /// Normally the minimum flow is delivered through `L_min` depending on the cost `soft_min.cost`. Any /// additional flow goes through `L`. Depending on the network demand and the value of `soft_min.cost`, @@ -181,53 +181,53 @@ pub struct SoftConstraint { /// ```svgbob /// U D /// - - -*----------->L ------------>*- - - -/// | | -/// | | () .aggregated_node -/// '------>L_min -----' [ L_min, L ] +/// | | +/// | | () .aggregated_node +/// '------>L_min -----' [ L_min, L ] /// .soft_min /// ``` -/// +/// /// The network is set up as follows: /// - `L_max` is not added to the network /// - `L_min` is added with `soft_min` data /// - `L` is added with `cost`, `min_flow` is set to 0 and `max_flow` is unconstrained. /// - An aggregated node is added to ensure that combined flow in `L_min` and `L` never exceeds -/// the hard constraints `min_flow` and `max_flow`. +/// the hard constraints `min_flow` and `max_flow`. /// /// ### Only `soft_max` is defined /// Normally the maximum flow `soft_max.max` is delivered through the `L_max` node and no flow /// goes through `L`. When needed, based on the value of `soft_max.cost`, the maximum `soft_max.max` -/// value can be breached up to a combined flow of `max_flow`. +/// value can be breached up to a combined flow of `max_flow`. /// ```svgbob /// U D /// - - -*----------->L ------------>*- - - -/// | | -/// | | () .aggregated_node -/// '------>L_max -----' [ L_max, L ] +/// | | +/// | | () .aggregated_node +/// '------>L_max -----' [ L_max, L ] /// .soft_max /// ``` -/// +/// /// The network is set up as follows: /// - `L_min` is not added to the network. /// - `L` is added with the cost in `soft_max.cost` (i.e. cost of going above soft max). /// - `L_max` is added with max flow of `soft_max.max` and cost of `cost`. /// - An aggregated node is added to ensure that combined flow in `L_max` and `L` never exceeds -/// the hard constraints `min_flow` and `max_flow`. +/// the hard constraints `min_flow` and `max_flow`. /// /// ### Both `soft_min` and `soft_max` are defined /// /// ```svgbob /// .soft_max /// .------>L_max -----. -/// | | () .aggregated_node +/// | | () .aggregated_node /// U | | D [ L_max, L_min, L ] /// - - -*--|-------->L --------|--->*- - - -/// | | () .aggregate_node_l_l_min +/// | | () .aggregate_node_l_l_min /// | | [ L_min, L ] /// '------>L_min -----' /// .soft_min /// ``` -/// +/// /// The network is set up as follows: /// - `L_max`'s flow is unconstrained with a cost equal to `soft_max.cost`. /// - `L`'s flow is unconstrained with a cost equal to `cost`. @@ -236,7 +236,7 @@ pub struct SoftConstraint { /// `soft_max.flow`. /// - An aggregated node is added with `L`, `L_max` and `L_min` to ensure the flow is between /// `min_flow` and `max_flow`. -/// +/// /// ## Examples /// Link soft constraints may be used in the following scenarios: /// 1) If the link represents a works and its `max_flow` is constrained by a reservoir rule curve, @@ -244,7 +244,7 @@ pub struct SoftConstraint { /// ensure that demand is always met. By setting a high tuned cost via [`SoftConstraint`], this will /// ensure that the abstraction is breached only when needed. /// 2) If the link represents a works and a minimum flow must be guaranteed, `soft_min` may be set -/// with a negative cost to allow the minimum flow requirement. However, when this cannot be met +/// with a negative cost to allow the minimum flow requirement. However, when this cannot be met /// (for example when the abstraction license or the source runs out), the minimum flow will not /// be honoured and the solver will find a solution. )] @@ -1347,13 +1347,6 @@ mod tests { use crate::nodes::core::StorageInitialVolume; use crate::nodes::InputNode; use crate::nodes::StorageNode; - use crate::PywrModel; - #[cfg(feature = "core")] - use pywr_core::test_utils::{run_all_solvers, ExpectedOutputs}; - #[cfg(feature = "core")] - use std::str::FromStr; - #[cfg(feature = "core")] - use tempfile::TempDir; #[test] fn test_input() { @@ -1417,158 +1410,4 @@ mod tests { assert_eq!(storage.initial_volume, StorageInitialVolume::Proportional(0.5)); } - - #[cfg(feature = "core")] - fn storage_max_volumes_str() -> &'static str { - include_str!("../test_models/storage_max_volumes.json") - } - - #[test] - #[cfg(feature = "core")] - fn test_storage_max_volumes_run() { - let data = storage_max_volumes_str(); - let schema = PywrModel::from_str(data).unwrap(); - let model: pywr_core::models::Model = schema.build_model(None, None).unwrap(); - // Test all solvers - run_all_solvers(&model, &[], &[]); - } - - fn me1_str() -> &'static str { - include_str!("../test_models/mutual-exclusivity1.json") - } - fn me2_str() -> &'static str { - include_str!("../test_models/mutual-exclusivity2.json") - } - - #[cfg(feature = "core")] - fn me3_str() -> &'static str { - include_str!("../test_models/mutual-exclusivity3.json") - } - #[cfg(feature = "core")] - fn me1_outputs_str() -> &'static str { - include_str!("../test_models/mutual-exclusivity1.csv") - } - #[cfg(feature = "core")] - fn me2_outputs_str() -> &'static str { - include_str!("../test_models/mutual-exclusivity2.csv") - } - #[cfg(feature = "core")] - fn me3_outputs_str() -> &'static str { - include_str!("../test_models/mutual-exclusivity3.csv") - } - #[test] - fn test_me1_model_schema() { - let data = me1_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 6); - assert_eq!(schema.network.edges.len(), 4); - } - #[test] - fn test_me2_model_schema() { - let data = me2_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 6); - assert_eq!(schema.network.edges.len(), 4); - } - #[test] - #[cfg(feature = "core")] - fn test_me1_model_run() { - let data = me1_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let temp_dir = TempDir::new().unwrap(); - - let mut model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - - let network = model.network_mut(); - assert_eq!(network.nodes().len(), 5); - assert_eq!(network.edges().len(), 4); - - // After model run there should be an output file. - let expected_outputs = [ExpectedOutputs::new( - temp_dir.path().join("output.csv"), - me1_outputs_str(), - )]; - - // Test all solvers - run_all_solvers(&model, &["clp"], &expected_outputs); - } - #[test] - #[cfg(feature = "core")] - fn test_me2_model_run() { - let data = me2_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let temp_dir = TempDir::new().unwrap(); - - let mut model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - - let network = model.network_mut(); - assert_eq!(network.nodes().len(), 10); - assert_eq!(network.edges().len(), 11); - - // After model run there should be an output file. - let expected_outputs = [ExpectedOutputs::new( - temp_dir.path().join("output.csv"), - me2_outputs_str(), - )]; - - // Test all solvers - run_all_solvers(&model, &["clp"], &expected_outputs); - } - - #[cfg(feature = "core")] - fn link_with_soft_min_str() -> &'static str { - include_str!("../test_models/link_with_soft_min.json") - } - - #[test] - #[cfg(feature = "core")] - fn test_link_with_soft_min() { - let data = link_with_soft_min_str(); - let schema = PywrModel::from_str(data).unwrap(); - let model: pywr_core::models::Model = schema.build_model(None, None).unwrap(); - - // Test all solvers - run_all_solvers(&model, &[], &[]); - } - - #[cfg(feature = "core")] - fn link_with_soft_max_str() -> &'static str { - include_str!("../test_models/link_with_soft_max.json") - } - - #[test] - #[cfg(feature = "core")] - fn test_link_with_soft_max() { - let data = link_with_soft_max_str(); - let schema = PywrModel::from_str(data).unwrap(); - let model: pywr_core::models::Model = schema.build_model(None, None).unwrap(); - - // Test all solvers - run_all_solvers(&model, &[], &[]); - } - - #[test] - #[cfg(feature = "core")] - fn test_me3_model_run() { - let data = me3_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let temp_dir = TempDir::new().unwrap(); - - let mut model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - - let network = model.network_mut(); - assert_eq!(network.nodes().len(), 7); - assert_eq!(network.edges().len(), 8); - - // After model run there should be an output file. - let expected_outputs = [ExpectedOutputs::new( - temp_dir.path().join("output.csv"), - me3_outputs_str(), - )]; - - // Test all solvers - run_all_solvers(&model, &["clp"], &expected_outputs); - } } diff --git a/pywr-schema/src/nodes/delay.rs b/pywr-schema/src/nodes/delay.rs index 6be0e61d..ae725cd0 100644 --- a/pywr-schema/src/nodes/delay.rs +++ b/pywr-schema/src/nodes/delay.rs @@ -161,45 +161,3 @@ impl TryFrom for DelayNode { Ok(n) } } - -#[cfg(test)] -#[cfg(feature = "core")] -mod tests { - use crate::model::PywrModel; - use ndarray::{concatenate, Array2, Axis}; - use pywr_core::{metric::MetricF64, recorders::AssertionRecorder, test_utils::run_all_solvers}; - - fn model_str() -> &'static str { - include_str!("../test_models/delay1.json") - } - - #[test] - - fn test_model_run() { - let data = model_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let mut model: pywr_core::models::Model = schema.build_model(None, None).unwrap(); - - let network = model.network_mut(); - assert_eq!(network.nodes().len(), 4); - assert_eq!(network.edges().len(), 2); - - // TODO put this assertion data in the test model file. - let idx = network.get_node_by_name("link1", Some("inflow")).unwrap().index(); - let expected = Array2::from_elem((366, 1), 15.0); - let recorder = AssertionRecorder::new("link1-inflow", MetricF64::NodeInFlow(idx), expected, None, None); - network.add_recorder(Box::new(recorder)).unwrap(); - - let idx = network.get_node_by_name("link1", Some("outflow")).unwrap().index(); - let expected = concatenate![ - Axis(0), - Array2::from_elem((3, 1), 0.0), - Array2::from_elem((363, 1), 15.0) - ]; - let recorder = AssertionRecorder::new("link1-outflow", MetricF64::NodeOutFlow(idx), expected, None, None); - network.add_recorder(Box::new(recorder)).unwrap(); - - // Test all solvers - run_all_solvers(&model, &[], &[]); - } -} diff --git a/pywr-schema/src/nodes/loss_link.rs b/pywr-schema/src/nodes/loss_link.rs index 3c0c84f6..7843ead6 100644 --- a/pywr-schema/src/nodes/loss_link.rs +++ b/pywr-schema/src/nodes/loss_link.rs @@ -277,84 +277,3 @@ impl TryFrom for LossLinkNode { Ok(n) } } - -#[cfg(test)] -mod tests { - use crate::model::PywrModel; - #[cfg(feature = "core")] - use pywr_core::test_utils::{run_all_solvers, ExpectedOutputs}; - #[cfg(feature = "core")] - use tempfile::TempDir; - - fn loss_link1_str() -> &'static str { - include_str!("../test_models/loss_link1.json") - } - - #[cfg(feature = "core")] - fn loss_link1_outputs_str() -> &'static str { - include_str!("../test_models/loss_link1-expected.csv") - } - - #[test] - fn test_loss_link1_schema() { - let data = loss_link1_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 7); - assert_eq!(schema.network.edges.len(), 6); - } - - #[test] - #[cfg(feature = "core")] - fn test_loss_link1_run() { - let data = loss_link1_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let temp_dir = TempDir::new().unwrap(); - - let model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - // After model run there should be an output file. - let expected_outputs = [ExpectedOutputs::new( - temp_dir.path().join("loss_link1.csv"), - loss_link1_outputs_str(), - )]; - - // Test all solvers - run_all_solvers(&model, &[], &expected_outputs); - } - - fn loss_link2_str() -> &'static str { - include_str!("../test_models/loss_link2.json") - } - - #[cfg(feature = "core")] - fn loss_link2_outputs_str() -> &'static str { - include_str!("../test_models/loss_link2-expected.csv") - } - - #[test] - fn test_loss_link2_schema() { - let data = loss_link2_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 4); - assert_eq!(schema.network.edges.len(), 3); - } - - #[test] - #[cfg(feature = "core")] - fn test_loss_link2_run() { - let data = loss_link2_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let temp_dir = TempDir::new().unwrap(); - - let model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - // After model run there should be an output file. - let expected_outputs = [ExpectedOutputs::new( - temp_dir.path().join("loss_link2.csv"), - loss_link2_outputs_str(), - )]; - - // Test all solvers - run_all_solvers(&model, &[], &expected_outputs); - } -} diff --git a/pywr-schema/src/nodes/piecewise_link.rs b/pywr-schema/src/nodes/piecewise_link.rs index 945aa671..0d9e1419 100644 --- a/pywr-schema/src/nodes/piecewise_link.rs +++ b/pywr-schema/src/nodes/piecewise_link.rs @@ -197,67 +197,3 @@ impl TryFrom for PiecewiseLinkNode { Ok(n) } } - -#[cfg(test)] -#[cfg(feature = "core")] -mod tests { - use crate::model::PywrModel; - use ndarray::Array2; - use pywr_core::test_utils::ExpectedOutputs; - use pywr_core::{metric::MetricF64, recorders::AssertionRecorder, test_utils::run_all_solvers}; - use tempfile::TempDir; - - fn model_str() -> &'static str { - include_str!("../test_models/piecewise_link1.json") - } - - fn pwl_node_outputs_str() -> &'static str { - include_str!("../test_models/piecewise-link1-nodes.csv") - } - - fn pwl_edges_outputs_str() -> &'static str { - include_str!("../test_models/piecewise-link1-edges.csv") - } - - #[test] - fn test_model_run() { - let data = model_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let temp_dir = TempDir::new().unwrap(); - - let mut model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - - let network = model.network_mut(); - assert_eq!(network.nodes().len(), 5); - assert_eq!(network.edges().len(), 6); - - let idx = network.get_node_by_name("link1", Some("step-00")).unwrap().index(); - let expected = Array2::from_elem((366, 1), 1.0); - let recorder = AssertionRecorder::new("link1-s0-flow", MetricF64::NodeOutFlow(idx), expected, None, None); - network.add_recorder(Box::new(recorder)).unwrap(); - - let idx = network.get_node_by_name("link1", Some("step-01")).unwrap().index(); - let expected = Array2::from_elem((366, 1), 3.0); - let recorder = AssertionRecorder::new("link1-s0-flow", MetricF64::NodeOutFlow(idx), expected, None, None); - network.add_recorder(Box::new(recorder)).unwrap(); - - let idx = network.get_node_by_name("link1", Some("step-02")).unwrap().index(); - let expected = Array2::from_elem((366, 1), 0.0); - let recorder = AssertionRecorder::new("link1-s0-flow", MetricF64::NodeOutFlow(idx), expected, None, None); - network.add_recorder(Box::new(recorder)).unwrap(); - - let expected_outputs = [ - ExpectedOutputs::new( - temp_dir.path().join("piecewise-link1-nodes.csv"), - pwl_node_outputs_str(), - ), - ExpectedOutputs::new( - temp_dir.path().join("piecewise-link1-edges.csv"), - pwl_edges_outputs_str(), - ), - ]; - - // Test all solvers - run_all_solvers(&model, &[], &expected_outputs); - } -} diff --git a/pywr-schema/src/nodes/piecewise_storage.rs b/pywr-schema/src/nodes/piecewise_storage.rs index 93a6c784..b633f9aa 100644 --- a/pywr-schema/src/nodes/piecewise_storage.rs +++ b/pywr-schema/src/nodes/piecewise_storage.rs @@ -244,135 +244,3 @@ impl PiecewiseStorageNode { Ok(metric) } } - -#[cfg(test)] -#[cfg(feature = "core")] -mod tests { - use crate::model::PywrModel; - use crate::nodes::PiecewiseStorageNode; - use ndarray::{concatenate, Array, Array2, Axis}; - use pywr_core::metric::MetricF64; - use pywr_core::recorders::{AssertionRecorder, IndexAssertionRecorder}; - use pywr_core::test_utils::run_all_solvers; - - fn piecewise_storage1_str() -> &'static str { - include_str!("../test_models/piecewise_storage1.json") - } - - fn piecewise_storage2_str() -> &'static str { - include_str!("../test_models/piecewise_storage2.json") - } - - /// Test running `piecewise_storage1.json` - #[test] - fn test_piecewise_storage1() { - let data = piecewise_storage1_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let mut model = schema.build_model(None, None).unwrap(); - - let network = model.network_mut(); - assert_eq!(network.nodes().len(), 5); - assert_eq!(network.edges().len(), 6); - - // TODO put this assertion data in the test model file. - let idx = network - .get_aggregated_storage_node_index_by_name("storage1", PiecewiseStorageNode::agg_sub_name()) - .unwrap(); - - let expected = Array2::from_shape_fn((366, 1), |(i, _)| { - if i < 33 { - // Draw-down top store at 15 until it is emptied - 985.0 - i as f64 * 15.0 - } else if i < 58 { - // The second store activates the input (via costs) such that the net draw down is now 10 - 495.0 - (i as f64 - 33.0) * 10.0 - } else { - // Finally the abstraction stops to maintain the bottom store at 250 - 250.0 - } - }); - - let recorder = AssertionRecorder::new( - "storage1-volume", - MetricF64::AggregatedNodeVolume(idx), - expected, - None, - None, - ); - network.add_recorder(Box::new(recorder)).unwrap(); - - // Test all solvers - run_all_solvers(&model, &[], &[]); - } - - /// Test running `piecewise_storage2.json` - #[test] - fn test_piecewise_storage2() { - let data = piecewise_storage2_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let mut model = schema.build_model(None, None).unwrap(); - - let network = model.network_mut(); - assert_eq!(network.nodes().len(), 5); - assert_eq!(network.edges().len(), 6); - - // TODO put this assertion data in the test model file. - let idx = network - .get_aggregated_storage_node_index_by_name("storage1", PiecewiseStorageNode::agg_sub_name()) - .unwrap(); - - let expected_volume = Array2::from_shape_fn((366, 1), |(i, _)| { - if i < 49 { - // Draw-down top store at 5 until it is emptied (control curve starts at 75%) - 995.0 - i as f64 * 5.0 - } else if i < 89 { - // The second store activates the input (via costs) such that the net draw down is now 2 - 750.0 - (i as f64 - 49.0) * 2.0 - } else if i < 123 { - // The control curve lowers such that the first store re-activates and therefore - // disables the input (via costs). The net draw down returns to 5 - 670.0 - (i as f64 - 89.0) * 5.0 - } else if i < 180 { - // The second store re-activates the input (via costs) such that the net draw down is now 2 - 500.0 - (i as f64 - 123.0) * 2.0 - } else if i < 198 { - // The control curve lowers (again) such that the first store re-activates and therefore - // disables the input (via costs). The net draw down returns to 5 - 386.0 - (i as f64 - 180.0) * 5.0 - } else if i < 223 { - // The second store re-activates the input (via costs) such that the net draw down is now 2 - 299.0 - (i as f64 - 198.0) * 2.0 - } else { - // Finally the abstraction stops to maintain the bottom store at 250 - 250.0 - } - }); - - // The drought index should register the time-step after storage is below 500 - let expected_drought_index = expected_volume.mapv(|v| if v < 500.0 { 1 } else { 0 }); - // The initial time-step has zero drought index because the initial volume is above the control curve - let initial_drought_index: Array = Array2::zeros((1, 1)); - - let expected_drought_index = - concatenate(Axis(0), &[initial_drought_index.view(), expected_drought_index.view()]).unwrap(); - - let recorder = AssertionRecorder::new( - "storage1-volume", - MetricF64::AggregatedNodeVolume(idx), - expected_volume, - None, - None, - ); - network.add_recorder(Box::new(recorder)).unwrap(); - - let idx = network - .get_index_parameter_index_by_name(&"storage1-drought-index".into()) - .unwrap(); - - let recorder = IndexAssertionRecorder::new("storage1-drought-index", idx.into(), expected_drought_index); - network.add_recorder(Box::new(recorder)).unwrap(); - - // Test all solvers - run_all_solvers(&model, &[], &[]); - } -} diff --git a/pywr-schema/src/nodes/river.rs b/pywr-schema/src/nodes/river.rs index 8e9b8896..4f3421f3 100644 --- a/pywr-schema/src/nodes/river.rs +++ b/pywr-schema/src/nodes/river.rs @@ -207,48 +207,3 @@ impl TryFrom for RiverNode { Ok(n) } } - -#[cfg(test)] -mod tests { - use crate::model::PywrModel; - #[cfg(feature = "core")] - use pywr_core::test_utils::{run_all_solvers, ExpectedOutputs}; - #[cfg(feature = "core")] - use tempfile::TempDir; - - fn river_loss1_str() -> &'static str { - include_str!("../test_models/river_loss1.json") - } - - #[cfg(feature = "core")] - fn river_loss1_outputs_str() -> &'static str { - include_str!("../test_models/river_loss1-expected.csv") - } - - #[test] - fn test_river_loss1_schema() { - let data = river_loss1_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 4); - assert_eq!(schema.network.edges.len(), 3); - } - - #[test] - #[cfg(feature = "core")] - fn test_river_loss1_run() { - let data = river_loss1_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let temp_dir = TempDir::new().unwrap(); - - let model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - // After model run there should be an output file. - let expected_outputs = [ExpectedOutputs::new( - temp_dir.path().join("river_loss1.csv"), - river_loss1_outputs_str(), - )]; - - // Test all solvers - run_all_solvers(&model, &[], &expected_outputs); - } -} diff --git a/pywr-schema/src/nodes/river_gauge.rs b/pywr-schema/src/nodes/river_gauge.rs index e2875f46..88107faa 100644 --- a/pywr-schema/src/nodes/river_gauge.rs +++ b/pywr-schema/src/nodes/river_gauge.rs @@ -173,40 +173,3 @@ impl TryFrom for RiverGaugeNode { Ok(n) } } - -#[cfg(test)] -mod tests { - use crate::model::PywrModel; - #[cfg(feature = "core")] - use pywr_core::test_utils::run_all_solvers; - - fn model_str() -> &'static str { - include_str!("../test_models/river_gauge1.json") - } - - #[test] - fn test_model_schema() { - let data = model_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 4); - assert_eq!(schema.network.edges.len(), 3); - } - - #[test] - #[cfg(feature = "core")] - fn test_model_run() { - let data = model_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let model = schema.build_model(None, None).unwrap(); - - let network = model.network(); - assert_eq!(network.nodes().len(), 5); - assert_eq!(network.edges().len(), 6); - - // Test all solvers - run_all_solvers(&model, &[], &[]); - - // TODO assert the results! - } -} diff --git a/pywr-schema/src/nodes/river_split_with_gauge.rs b/pywr-schema/src/nodes/river_split_with_gauge.rs index f9d4e068..49a62af9 100644 --- a/pywr-schema/src/nodes/river_split_with_gauge.rs +++ b/pywr-schema/src/nodes/river_split_with_gauge.rs @@ -268,40 +268,3 @@ impl TryFrom for RiverSplitWithGaugeNode { Ok(n) } } - -#[cfg(test)] -mod tests { - use crate::model::PywrModel; - #[cfg(feature = "core")] - use pywr_core::test_utils::run_all_solvers; - - fn model_str() -> &'static str { - include_str!("../test_models/river_split_with_gauge1.json") - } - - #[test] - fn test_model_schema() { - let data = model_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 4); - assert_eq!(schema.network.edges.len(), 3); - } - - #[test] - #[cfg(feature = "core")] - fn test_model_run() { - let data = model_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let model = schema.build_model(None, None).unwrap(); - - let network = model.network(); - assert_eq!(network.nodes().len(), 5); - assert_eq!(network.edges().len(), 6); - - // Test all solvers - run_all_solvers(&model, &[], &[]); - - // TODO assert the results! - } -} diff --git a/pywr-schema/src/nodes/rolling_virtual_storage.rs b/pywr-schema/src/nodes/rolling_virtual_storage.rs index 8a3ee394..e2dcdfbd 100644 --- a/pywr-schema/src/nodes/rolling_virtual_storage.rs +++ b/pywr-schema/src/nodes/rolling_virtual_storage.rs @@ -261,37 +261,3 @@ impl TryFrom for RollingVirtualStorageNode { Ok(n) } } - -#[cfg(test)] -#[cfg(feature = "core")] -mod tests { - use crate::model::PywrModel; - use ndarray::Array2; - use pywr_core::metric::MetricF64; - use pywr_core::recorders::AssertionRecorder; - use pywr_core::test_utils::run_all_solvers; - - fn model_str() -> &'static str { - include_str!("../test_models/30-day-licence.json") - } - - #[test] - fn test_model_run() { - let data = model_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let mut model: pywr_core::models::Model = schema.build_model(None, None).unwrap(); - - let network = model.network_mut(); - assert_eq!(network.nodes().len(), 3); - assert_eq!(network.edges().len(), 2); - - // TODO put this assertion data in the test model file. - let idx = network.get_node_by_name("link1", None).unwrap().index(); - let expected = Array2::from_elem((366, 1), 10.0); - let recorder = AssertionRecorder::new("link1-inflow", MetricF64::NodeInFlow(idx), expected, None, None); - network.add_recorder(Box::new(recorder)).unwrap(); - - // Test all solvers - run_all_solvers(&model, &[], &[]); - } -} diff --git a/pywr-schema/src/nodes/water_treatment_works.rs b/pywr-schema/src/nodes/water_treatment_works.rs index a827b981..8092610d 100644 --- a/pywr-schema/src/nodes/water_treatment_works.rs +++ b/pywr-schema/src/nodes/water_treatment_works.rs @@ -240,94 +240,3 @@ impl WaterTreatmentWorks { Ok(metric) } } - -#[cfg(test)] -mod tests { - use crate::model::PywrModel; - #[cfg(feature = "core")] - use pywr_core::test_utils::{run_all_solvers, ExpectedOutputs}; - #[cfg(feature = "core")] - use tempfile::TempDir; - - fn wtw1_str() -> &'static str { - include_str!("../test_models/wtw1.json") - } - - #[cfg(feature = "core")] - fn wtw1_outputs_str() -> &'static str { - include_str!("../test_models/wtw1-expected.csv") - } - - #[test] - fn test_wtw1_schema() { - let data = wtw1_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 5); - assert_eq!(schema.network.edges.len(), 4); - } - - #[test] - #[cfg(feature = "core")] - fn test_wtw1_run() { - let data = wtw1_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let temp_dir = TempDir::new().unwrap(); - - let mut model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - - let network = model.network_mut(); - assert_eq!(network.nodes().len(), 10); - assert_eq!(network.edges().len(), 11); - - // After model run there should be an output file. - let expected_outputs = [ExpectedOutputs::new( - temp_dir.path().join("wtw1.csv"), - wtw1_outputs_str(), - )]; - - // Test all solvers - run_all_solvers(&model, &[], &expected_outputs); - } - - fn wtw2_str() -> &'static str { - include_str!("../test_models/wtw2.json") - } - - #[cfg(feature = "core")] - fn wtw2_outputs_str() -> &'static str { - include_str!("../test_models/wtw2-expected.csv") - } - - #[test] - fn test_wtw2_schema() { - let data = wtw2_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 4); - assert_eq!(schema.network.edges.len(), 3); - } - - #[test] - #[cfg(feature = "core")] - fn test_wtw2_run() { - let data = wtw2_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let temp_dir = TempDir::new().unwrap(); - - let mut model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - - let network = model.network_mut(); - assert_eq!(network.nodes().len(), 7); - assert_eq!(network.edges().len(), 7); - - // After model run there should be an output file. - let expected_outputs = [ExpectedOutputs::new( - temp_dir.path().join("wtw2.csv"), - wtw2_outputs_str(), - )]; - - // Test all solvers - run_all_solvers(&model, &[], &expected_outputs); - } -} diff --git a/pywr-schema/src/outputs/csv.rs b/pywr-schema/src/outputs/csv.rs index c850f6f2..82a3218b 100644 --- a/pywr-schema/src/outputs/csv.rs +++ b/pywr-schema/src/outputs/csv.rs @@ -94,181 +94,3 @@ impl CsvOutput { Ok(()) } } - -#[cfg(test)] -mod tests { - use crate::visit::VisitPaths; - use crate::PywrModel; - use std::path::PathBuf; - use std::str::FromStr; - - fn csv1_str() -> &'static str { - include_str!("../test_models/csv1.json") - } - - fn csv2_str() -> &'static str { - include_str!("../test_models/csv2.json") - } - - fn csv3_str() -> &'static str { - include_str!("../test_models/csv3.json") - } - - #[test] - fn test_schema() { - let data = csv1_str(); - let schema = PywrModel::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 3); - assert_eq!(schema.network.edges.len(), 2); - assert!(schema.network.outputs.is_some_and(|o| o.len() == 2)); - } - - #[test] - fn test_csv1_run() { - let data = csv1_str(); - let schema = PywrModel::from_str(data).unwrap(); - - let expected_paths = vec![ - PathBuf::from_str("outputs-long.csv").unwrap(), - PathBuf::from_str("outputs-wide.csv").unwrap(), - ]; - let mut found_paths = Vec::new(); - schema.visit_paths(&mut |path| { - found_paths.push(path.to_path_buf()); - }); - assert_eq!(found_paths, expected_paths); - } - - #[test] - fn test_csv2_run() { - let data = csv2_str(); - let schema = PywrModel::from_str(data).unwrap(); - - let expected_paths = vec![ - PathBuf::from_str("outputs-long.csv").unwrap(), - PathBuf::from_str("outputs-wide.csv").unwrap(), - ]; - let mut found_paths = Vec::new(); - schema.visit_paths(&mut |path| { - found_paths.push(path.to_path_buf()); - }); - assert_eq!(found_paths, expected_paths); - } - - #[test] - fn test_csv3_run() { - let data = csv3_str(); - let schema = PywrModel::from_str(data).unwrap(); - - let expected_paths = vec![PathBuf::from_str("outputs-long.csv").unwrap()]; - let mut found_paths = Vec::new(); - schema.visit_paths(&mut |path| { - found_paths.push(path.to_path_buf()); - }); - assert_eq!(found_paths, expected_paths); - } - - #[cfg(test)] - #[cfg(feature = "core")] - mod core { - use super::{csv1_str, csv2_str, csv3_str}; - use crate::PywrModel; - use pywr_core::solvers::{ClpSolver, ClpSolverSettings}; - use std::str::FromStr; - use tempfile::TempDir; - - fn csv1_outputs_long_str() -> &'static str { - include_str!("../test_models/csv1-outputs-long.csv") - } - - fn csv1_outputs_wide_str() -> &'static str { - include_str!("../test_models/csv1-outputs-wide.csv") - } - - fn csv3_outputs_long_str() -> &'static str { - include_str!("../test_models/csv3-outputs-long.csv") - } - - fn csv2_outputs_long_str() -> &'static str { - include_str!("../test_models/csv2-outputs-long.csv") - } - - fn csv2_outputs_wide_str() -> &'static str { - include_str!("../test_models/csv2-outputs-wide.csv") - } - - #[test] - fn test_schema() { - let data = csv1_str(); - let schema = PywrModel::from_str(data).unwrap(); - - assert_eq!(schema.network.nodes.len(), 3); - assert_eq!(schema.network.edges.len(), 2); - assert!(schema.network.outputs.is_some_and(|o| o.len() == 2)); - } - - #[test] - fn test_csv1_run() { - let data = csv1_str(); - let schema = PywrModel::from_str(data).unwrap(); - - let temp_dir = TempDir::new().unwrap(); - - let model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - - model.run::(&ClpSolverSettings::default()).unwrap(); - - // After model run there should be two output files. - let expected_long_path = temp_dir.path().join("outputs-long.csv"); - assert!(expected_long_path.exists()); - let long_content = std::fs::read_to_string(&expected_long_path).unwrap(); - assert_eq!(&long_content, csv1_outputs_long_str()); - - let expected_wide_path = temp_dir.path().join("outputs-wide.csv"); - assert!(expected_wide_path.exists()); - let wide_content = std::fs::read_to_string(&expected_wide_path).unwrap(); - assert_eq!(&wide_content, csv1_outputs_wide_str()); - } - - #[test] - fn test_csv2_run() { - let data = csv2_str(); - let schema = PywrModel::from_str(data).unwrap(); - - let temp_dir = TempDir::new().unwrap(); - - let model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - - model.run::(&ClpSolverSettings::default()).unwrap(); - - // After model run there should be two output files. - let expected_long_path = temp_dir.path().join("outputs-long.csv"); - assert!(expected_long_path.exists()); - let long_content = std::fs::read_to_string(&expected_long_path).unwrap(); - assert_eq!(&long_content, csv2_outputs_long_str()); - - let expected_wide_path = temp_dir.path().join("outputs-wide.csv"); - assert!(expected_wide_path.exists()); - let wide_content = std::fs::read_to_string(&expected_wide_path).unwrap(); - assert_eq!(&wide_content, csv2_outputs_wide_str()); - } - - #[test] - fn test_csv3_run() { - let data = csv3_str(); - let schema = PywrModel::from_str(data).unwrap(); - - let temp_dir = TempDir::new().unwrap(); - - let model = schema.build_model(None, Some(temp_dir.path())).unwrap(); - - model.run::(&ClpSolverSettings::default()).unwrap(); - - let expected_long_path = temp_dir.path().join("outputs-long.csv"); - assert!(expected_long_path.exists()); - let long_content = std::fs::read_to_string(&expected_long_path).unwrap(); - assert_eq!(&long_content, csv3_outputs_long_str()); - } - } -} diff --git a/pywr-schema/src/outputs/hdf.rs b/pywr-schema/src/outputs/hdf.rs index 816aaafc..db132ee3 100644 --- a/pywr-schema/src/outputs/hdf.rs +++ b/pywr-schema/src/outputs/hdf.rs @@ -44,19 +44,20 @@ mod tests { use crate::PywrModel; #[cfg(feature = "core")] use pywr_core::solvers::{ClpSolver, ClpSolverSettings}; + use std::fs::read_to_string; use std::path::PathBuf; use std::str::FromStr; #[cfg(feature = "core")] use tempfile::TempDir; - fn model_str() -> &'static str { - include_str!("../test_models/hdf1.json") + fn model_str() -> String { + read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/hdf1.json")).expect("Failed to read hdf1.json") } #[test] fn test_schema() { let data = model_str(); - let schema = PywrModel::from_str(data).unwrap(); + let schema = PywrModel::from_str(&data).unwrap(); assert_eq!(schema.network.nodes.len(), 3); assert_eq!(schema.network.edges.len(), 2); @@ -76,7 +77,7 @@ mod tests { #[cfg(feature = "core")] fn test_run() { let data = model_str(); - let schema = PywrModel::from_str(data).unwrap(); + let schema = PywrModel::from_str(&data).unwrap(); let temp_dir = TempDir::new().unwrap(); diff --git a/pywr-schema/src/outputs/memory.rs b/pywr-schema/src/outputs/memory.rs index 8dbe5955..fb3ed5b3 100644 --- a/pywr-schema/src/outputs/memory.rs +++ b/pywr-schema/src/outputs/memory.rs @@ -74,18 +74,19 @@ mod tests { use float_cmp::assert_approx_eq; #[cfg(feature = "core")] use pywr_core::solvers::{ClpSolver, ClpSolverSettings}; + use std::fs::read_to_string; use std::str::FromStr; #[cfg(feature = "core")] use tempfile::TempDir; - fn memory1_str() -> &'static str { - include_str!("../test_models/memory1.json") + fn memory1_str() -> String { + read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/memory1.json")).expect("Failed to read memory1.json") } #[test] fn test_schema() { let data = memory1_str(); - let schema = PywrModel::from_str(data).unwrap(); + let schema = PywrModel::from_str(&data).unwrap(); assert_eq!(schema.network.nodes.len(), 3); assert_eq!(schema.network.edges.len(), 2); @@ -96,7 +97,7 @@ mod tests { #[cfg(feature = "core")] fn test_run() { let data = memory1_str(); - let schema = PywrModel::from_str(data).unwrap(); + let schema = PywrModel::from_str(&data).unwrap(); let temp_dir = TempDir::new().unwrap(); diff --git a/pywr-schema/src/parameters/python.rs b/pywr-schema/src/parameters/python.rs index 8bd18c39..86609310 100644 --- a/pywr-schema/src/parameters/python.rs +++ b/pywr-schema/src/parameters/python.rs @@ -282,7 +282,7 @@ mod tests { #[test] fn test_python_float_parameter() { let mut py_fn = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - py_fn.push("src/test_models/test_parameters.py"); + py_fn.push("tests/test_parameters.py"); let data = json!( { @@ -328,7 +328,7 @@ mod tests { #[test] fn test_python_int_parameter() { let mut py_fn = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - py_fn.push("src/test_models/test_parameters.py"); + py_fn.push("tests/test_parameters.py"); let data = json!( { diff --git a/pywr-schema/src/timeseries/mod.rs b/pywr-schema/src/timeseries/mod.rs index 24eb2cf4..12859fa9 100644 --- a/pywr-schema/src/timeseries/mod.rs +++ b/pywr-schema/src/timeseries/mod.rs @@ -294,73 +294,3 @@ pub fn convert_from_v1_data( } ts.into_values().collect::>() } - -#[cfg(test)] -#[cfg(feature = "core")] -mod tests { - use crate::PywrModel; - use chrono::{Datelike, NaiveDate}; - use ndarray::Array; - use pywr_core::{metric::MetricF64, recorders::AssertionRecorder, test_utils::run_all_solvers}; - use std::path::PathBuf; - - fn model_str() -> &'static str { - include_str!("../test_models/timeseries.json") - } - - #[test] - fn test_timeseries_polars() { - let cargo_manifest_dir = env!("CARGO_MANIFEST_DIR"); - - let model_dir = PathBuf::from(cargo_manifest_dir).join("src/test_models"); - - let data = model_str(); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let mut model = schema.build_model(Some(model_dir.as_path()), None).unwrap(); - - let expected = Array::from_shape_fn((365, 1), |(x, _)| { - let month_day = NaiveDate::from_yo_opt(2021, (x + 1) as u32).unwrap().day() as f64; - month_day + month_day * 0.5 - }); - - let idx = model.network().get_node_by_name("output1", None).unwrap().index(); - - let recorder = AssertionRecorder::new("output-flow", MetricF64::NodeInFlow(idx), expected.clone(), None, None); - model.network_mut().add_recorder(Box::new(recorder)).unwrap(); - - run_all_solvers(&model, &[], &[]) - } - - fn model_pandas_str() -> &'static str { - include_str!("../test_models/timeseries_pandas.json") - } - - #[test] - fn test_timeseries_pandas() { - let data = model_pandas_str(); - #[cfg(not(feature = "test-python"))] - let _: PywrModel = serde_json::from_str(data).unwrap(); - - // Can only build this model within a Python environment that has pandas. - #[cfg(feature = "test-python")] - { - let cargo_manifest_dir = env!("CARGO_MANIFEST_DIR"); - let schema: PywrModel = serde_json::from_str(data).unwrap(); - let model_dir = PathBuf::from(cargo_manifest_dir).join("src/test_models"); - let mut model = schema.build_model(Some(model_dir.as_path()), None).unwrap(); - - let expected = Array::from_shape_fn((365, 1), |(x, _)| { - let month_day = NaiveDate::from_yo_opt(2021, (x + 1) as u32).unwrap().day() as f64; - month_day + month_day * 0.5 - }); - - let idx = model.network().get_node_by_name("output1", None).unwrap().index(); - - let recorder = - AssertionRecorder::new("output-flow", MetricF64::NodeInFlow(idx), expected.clone(), None, None); - model.network_mut().add_recorder(Box::new(recorder)).unwrap(); - - run_all_solvers(&model, &[], &[]) - } - } -} diff --git a/pywr-schema/src/test_models/30-day-licence.json b/pywr-schema/tests/30-day-licence.json similarity index 100% rename from pywr-schema/src/test_models/30-day-licence.json rename to pywr-schema/tests/30-day-licence.json diff --git a/pywr-schema/src/test_models/csv1-outputs-long.csv b/pywr-schema/tests/csv1-outputs-long.csv similarity index 100% rename from pywr-schema/src/test_models/csv1-outputs-long.csv rename to pywr-schema/tests/csv1-outputs-long.csv diff --git a/pywr-schema/src/test_models/csv1-outputs-wide.csv b/pywr-schema/tests/csv1-outputs-wide.csv similarity index 100% rename from pywr-schema/src/test_models/csv1-outputs-wide.csv rename to pywr-schema/tests/csv1-outputs-wide.csv diff --git a/pywr-schema/src/test_models/csv1.json b/pywr-schema/tests/csv1.json similarity index 94% rename from pywr-schema/src/test_models/csv1.json rename to pywr-schema/tests/csv1.json index fad38875..eaad9fa3 100644 --- a/pywr-schema/src/test_models/csv1.json +++ b/pywr-schema/tests/csv1.json @@ -77,14 +77,14 @@ "name": "my-outputs", "type": "CSV", "format": "long", - "filename": "outputs-long.csv", + "filename": "csv1-outputs-long.csv", "metric_set": "nodes" }, { "name": "my-outputs", "type": "CSV", "format": "wide", - "filename": "outputs-wide.csv", + "filename": "csv1-outputs-wide.csv", "metric_set": "nodes" } ] diff --git a/pywr-schema/src/test_models/csv2-outputs-long.csv b/pywr-schema/tests/csv2-outputs-long.csv similarity index 100% rename from pywr-schema/src/test_models/csv2-outputs-long.csv rename to pywr-schema/tests/csv2-outputs-long.csv diff --git a/pywr-schema/src/test_models/csv2-outputs-wide.csv b/pywr-schema/tests/csv2-outputs-wide.csv similarity index 100% rename from pywr-schema/src/test_models/csv2-outputs-wide.csv rename to pywr-schema/tests/csv2-outputs-wide.csv diff --git a/pywr-schema/src/test_models/csv2.json b/pywr-schema/tests/csv2.json similarity index 95% rename from pywr-schema/src/test_models/csv2.json rename to pywr-schema/tests/csv2.json index 0d9346c6..bc52ac68 100644 --- a/pywr-schema/src/test_models/csv2.json +++ b/pywr-schema/tests/csv2.json @@ -85,14 +85,14 @@ "name": "monthly-avg-outputs", "type": "CSV", "format": "long", - "filename": "outputs-long.csv", + "filename": "csv2-outputs-long.csv", "metric_set": "nodes" }, { "name": "monthly-avg-outputs", "type": "CSV", "format": "wide", - "filename": "outputs-wide.csv", + "filename": "csv2-outputs-wide.csv", "metric_set": "nodes" } ] diff --git a/pywr-schema/src/test_models/csv3-outputs-long.csv b/pywr-schema/tests/csv3-outputs-long.csv similarity index 100% rename from pywr-schema/src/test_models/csv3-outputs-long.csv rename to pywr-schema/tests/csv3-outputs-long.csv diff --git a/pywr-schema/src/test_models/csv3.json b/pywr-schema/tests/csv3.json similarity index 97% rename from pywr-schema/src/test_models/csv3.json rename to pywr-schema/tests/csv3.json index 5e58b60f..30cc37d8 100644 --- a/pywr-schema/src/test_models/csv3.json +++ b/pywr-schema/tests/csv3.json @@ -102,7 +102,7 @@ "name": "monthly-avg-outputs", "type": "CSV", "format": "long", - "filename": "outputs-long.csv", + "filename": "csv3-outputs-long.csv", "metric_set": [ "nodes-monthly-mean", "nodes-annual-mean" diff --git a/pywr-schema/tests/delay1-expected.csv b/pywr-schema/tests/delay1-expected.csv new file mode 100644 index 00000000..19f8695f --- /dev/null +++ b/pywr-schema/tests/delay1-expected.csv @@ -0,0 +1,63 @@ +time_start,time_end,scenario_index,metric_set,name,attribute,value +2021-01-01T00:00:00,2021-01-02T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-01T00:00:00,2021-01-02T00:00:00,0,nodes,link1,Outflow,0.0 +2021-01-02T00:00:00,2021-01-03T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-02T00:00:00,2021-01-03T00:00:00,0,nodes,link1,Outflow,0.0 +2021-01-03T00:00:00,2021-01-04T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-03T00:00:00,2021-01-04T00:00:00,0,nodes,link1,Outflow,0.0 +2021-01-04T00:00:00,2021-01-05T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-04T00:00:00,2021-01-05T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-05T00:00:00,2021-01-06T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-05T00:00:00,2021-01-06T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-06T00:00:00,2021-01-07T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-06T00:00:00,2021-01-07T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-07T00:00:00,2021-01-08T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-07T00:00:00,2021-01-08T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-08T00:00:00,2021-01-09T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-08T00:00:00,2021-01-09T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-09T00:00:00,2021-01-10T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-09T00:00:00,2021-01-10T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-10T00:00:00,2021-01-11T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-10T00:00:00,2021-01-11T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-11T00:00:00,2021-01-12T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-11T00:00:00,2021-01-12T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-12T00:00:00,2021-01-13T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-12T00:00:00,2021-01-13T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-13T00:00:00,2021-01-14T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-13T00:00:00,2021-01-14T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-14T00:00:00,2021-01-15T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-14T00:00:00,2021-01-15T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-15T00:00:00,2021-01-16T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-15T00:00:00,2021-01-16T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-16T00:00:00,2021-01-17T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-16T00:00:00,2021-01-17T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-17T00:00:00,2021-01-18T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-17T00:00:00,2021-01-18T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-18T00:00:00,2021-01-19T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-18T00:00:00,2021-01-19T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-19T00:00:00,2021-01-20T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-19T00:00:00,2021-01-20T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-20T00:00:00,2021-01-21T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-20T00:00:00,2021-01-21T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-21T00:00:00,2021-01-22T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-21T00:00:00,2021-01-22T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-22T00:00:00,2021-01-23T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-22T00:00:00,2021-01-23T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-23T00:00:00,2021-01-24T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-23T00:00:00,2021-01-24T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-24T00:00:00,2021-01-25T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-24T00:00:00,2021-01-25T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-25T00:00:00,2021-01-26T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-25T00:00:00,2021-01-26T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-26T00:00:00,2021-01-27T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-26T00:00:00,2021-01-27T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-27T00:00:00,2021-01-28T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-27T00:00:00,2021-01-28T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-28T00:00:00,2021-01-29T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-28T00:00:00,2021-01-29T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-29T00:00:00,2021-01-30T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-29T00:00:00,2021-01-30T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-30T00:00:00,2021-01-31T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-30T00:00:00,2021-01-31T00:00:00,0,nodes,link1,Outflow,15.0 +2021-01-31T00:00:00,2021-02-01T00:00:00,0,nodes,link1,Inflow,15.0 +2021-01-31T00:00:00,2021-02-01T00:00:00,0,nodes,link1,Outflow,15.0 diff --git a/pywr-schema/src/test_models/delay1.json b/pywr-schema/tests/delay1.json similarity index 63% rename from pywr-schema/src/test_models/delay1.json rename to pywr-schema/tests/delay1.json index 723afd67..6ab54201 100644 --- a/pywr-schema/src/test_models/delay1.json +++ b/pywr-schema/tests/delay1.json @@ -5,8 +5,8 @@ "minimum_version": "0.1" }, "timestepper": { - "start": "2015-01-01", - "end": "2015-12-31", + "start": "2021-01-01", + "end": "2021-01-31", "timestep": 1 }, "network": { @@ -53,6 +53,32 @@ "from_node": "link1", "to_node": "demand1" } + ], + "metric_sets": [ + { + "name": "nodes", + "metrics": [ + { + "type": "Node", + "name": "link1", + "attribute": "Inflow" + }, + { + "type": "Node", + "name": "link1", + "attribute": "Outflow" + } + ] + } + ], + "outputs": [ + { + "name": "nodes", + "type": "CSV", + "format": "long", + "filename": "delay1-expected.csv", + "metric_set": "nodes" + } ] } } diff --git a/pywr-schema/src/test_models/hdf1.json b/pywr-schema/tests/hdf1.json similarity index 100% rename from pywr-schema/src/test_models/hdf1.json rename to pywr-schema/tests/hdf1.json diff --git a/pywr-schema/src/test_models/inflow.csv b/pywr-schema/tests/inflow.csv similarity index 100% rename from pywr-schema/src/test_models/inflow.csv rename to pywr-schema/tests/inflow.csv diff --git a/pywr-schema/src/test_models/link_with_soft_max.json b/pywr-schema/tests/link_with_soft_max.json similarity index 100% rename from pywr-schema/src/test_models/link_with_soft_max.json rename to pywr-schema/tests/link_with_soft_max.json diff --git a/pywr-schema/src/test_models/link_with_soft_min.json b/pywr-schema/tests/link_with_soft_min.json similarity index 100% rename from pywr-schema/src/test_models/link_with_soft_min.json rename to pywr-schema/tests/link_with_soft_min.json diff --git a/pywr-schema/src/test_models/loss_link1-expected.csv b/pywr-schema/tests/loss_link1-expected.csv similarity index 100% rename from pywr-schema/src/test_models/loss_link1-expected.csv rename to pywr-schema/tests/loss_link1-expected.csv diff --git a/pywr-schema/src/test_models/loss_link1.json b/pywr-schema/tests/loss_link1.json similarity index 98% rename from pywr-schema/src/test_models/loss_link1.json rename to pywr-schema/tests/loss_link1.json index d0073c60..37cb078c 100644 --- a/pywr-schema/src/test_models/loss_link1.json +++ b/pywr-schema/tests/loss_link1.json @@ -175,7 +175,7 @@ "name": "node-outputs", "type": "CSV", "format": "long", - "filename": "loss_link1.csv", + "filename": "loss_link1-expected.csv", "metric_set": [ "nodes" ], diff --git a/pywr-schema/src/test_models/loss_link2-expected.csv b/pywr-schema/tests/loss_link2-expected.csv similarity index 100% rename from pywr-schema/src/test_models/loss_link2-expected.csv rename to pywr-schema/tests/loss_link2-expected.csv diff --git a/pywr-schema/src/test_models/loss_link2.json b/pywr-schema/tests/loss_link2.json similarity index 97% rename from pywr-schema/src/test_models/loss_link2.json rename to pywr-schema/tests/loss_link2.json index e233e7ac..232f32ab 100644 --- a/pywr-schema/src/test_models/loss_link2.json +++ b/pywr-schema/tests/loss_link2.json @@ -105,7 +105,7 @@ "name": "node-outputs", "type": "CSV", "format": "long", - "filename": "loss_link2.csv", + "filename": "loss_link2-expected.csv", "metric_set": [ "nodes" ], diff --git a/pywr-schema/src/test_models/memory1.json b/pywr-schema/tests/memory1.json similarity index 100% rename from pywr-schema/src/test_models/memory1.json rename to pywr-schema/tests/memory1.json diff --git a/pywr-schema/src/test_models/multi1/model.json b/pywr-schema/tests/multi1/model.json similarity index 100% rename from pywr-schema/src/test_models/multi1/model.json rename to pywr-schema/tests/multi1/model.json diff --git a/pywr-schema/src/test_models/multi1/network1.json b/pywr-schema/tests/multi1/network1.json similarity index 100% rename from pywr-schema/src/test_models/multi1/network1.json rename to pywr-schema/tests/multi1/network1.json diff --git a/pywr-schema/src/test_models/multi1/network2.json b/pywr-schema/tests/multi1/network2.json similarity index 100% rename from pywr-schema/src/test_models/multi1/network2.json rename to pywr-schema/tests/multi1/network2.json diff --git a/pywr-schema/src/test_models/multi2/model.json b/pywr-schema/tests/multi2/model.json similarity index 100% rename from pywr-schema/src/test_models/multi2/model.json rename to pywr-schema/tests/multi2/model.json diff --git a/pywr-schema/src/test_models/multi2/network1.json b/pywr-schema/tests/multi2/network1.json similarity index 100% rename from pywr-schema/src/test_models/multi2/network1.json rename to pywr-schema/tests/multi2/network1.json diff --git a/pywr-schema/src/test_models/multi2/network2.json b/pywr-schema/tests/multi2/network2.json similarity index 100% rename from pywr-schema/src/test_models/multi2/network2.json rename to pywr-schema/tests/multi2/network2.json diff --git a/pywr-schema/src/test_models/mutual-exclusivity1.csv b/pywr-schema/tests/mutual-exclusivity1.csv similarity index 100% rename from pywr-schema/src/test_models/mutual-exclusivity1.csv rename to pywr-schema/tests/mutual-exclusivity1.csv diff --git a/pywr-schema/src/test_models/mutual-exclusivity1.json b/pywr-schema/tests/mutual-exclusivity1.json similarity index 98% rename from pywr-schema/src/test_models/mutual-exclusivity1.json rename to pywr-schema/tests/mutual-exclusivity1.json index f9592b14..17f531bb 100644 --- a/pywr-schema/src/test_models/mutual-exclusivity1.json +++ b/pywr-schema/tests/mutual-exclusivity1.json @@ -133,7 +133,7 @@ "name": "node-outputs", "type": "CSV", "format": "long", - "filename": "output.csv", + "filename": "mutual-exclusivity1.csv", "metric_set": [ "nodes" ], diff --git a/pywr-schema/src/test_models/mutual-exclusivity2.csv b/pywr-schema/tests/mutual-exclusivity2.csv similarity index 100% rename from pywr-schema/src/test_models/mutual-exclusivity2.csv rename to pywr-schema/tests/mutual-exclusivity2.csv diff --git a/pywr-schema/src/test_models/mutual-exclusivity2.json b/pywr-schema/tests/mutual-exclusivity2.json similarity index 98% rename from pywr-schema/src/test_models/mutual-exclusivity2.json rename to pywr-schema/tests/mutual-exclusivity2.json index 10545983..22c41434 100644 --- a/pywr-schema/src/test_models/mutual-exclusivity2.json +++ b/pywr-schema/tests/mutual-exclusivity2.json @@ -150,7 +150,7 @@ "name": "node-outputs", "type": "CSV", "format": "long", - "filename": "output.csv", + "filename": "mutual-exclusivity2.csv", "metric_set": [ "nodes" ], diff --git a/pywr-schema/src/test_models/mutual-exclusivity3.csv b/pywr-schema/tests/mutual-exclusivity3.csv similarity index 100% rename from pywr-schema/src/test_models/mutual-exclusivity3.csv rename to pywr-schema/tests/mutual-exclusivity3.csv diff --git a/pywr-schema/src/test_models/mutual-exclusivity3.json b/pywr-schema/tests/mutual-exclusivity3.json similarity index 98% rename from pywr-schema/src/test_models/mutual-exclusivity3.json rename to pywr-schema/tests/mutual-exclusivity3.json index 591e849d..4a503bae 100644 --- a/pywr-schema/src/test_models/mutual-exclusivity3.json +++ b/pywr-schema/tests/mutual-exclusivity3.json @@ -153,7 +153,7 @@ "name": "node-outputs", "type": "CSV", "format": "long", - "filename": "output.csv", + "filename": "mutual-exclusivity3.csv", "metric_set": [ "nodes" ], diff --git a/pywr-schema/src/test_models/piecewise-link1-edges.csv b/pywr-schema/tests/piecewise-link1-edges.csv similarity index 100% rename from pywr-schema/src/test_models/piecewise-link1-edges.csv rename to pywr-schema/tests/piecewise-link1-edges.csv diff --git a/pywr-schema/src/test_models/piecewise-link1-nodes.csv b/pywr-schema/tests/piecewise-link1-nodes.csv similarity index 100% rename from pywr-schema/src/test_models/piecewise-link1-nodes.csv rename to pywr-schema/tests/piecewise-link1-nodes.csv diff --git a/pywr-schema/src/test_models/piecewise_link1.json b/pywr-schema/tests/piecewise_link1.json similarity index 100% rename from pywr-schema/src/test_models/piecewise_link1.json rename to pywr-schema/tests/piecewise_link1.json diff --git a/pywr-schema/tests/piecewise_storage1-expected.csv b/pywr-schema/tests/piecewise_storage1-expected.csv new file mode 100644 index 00000000..1d7e4ac1 --- /dev/null +++ b/pywr-schema/tests/piecewise_storage1-expected.csv @@ -0,0 +1,91 @@ +time_start,time_end,scenario_index,metric_set,name,attribute,value +2021-01-01T00:00:00,2021-01-02T00:00:00,0,nodes,storage1,Volume,985.0 +2021-01-02T00:00:00,2021-01-03T00:00:00,0,nodes,storage1,Volume,970.0 +2021-01-03T00:00:00,2021-01-04T00:00:00,0,nodes,storage1,Volume,955.0 +2021-01-04T00:00:00,2021-01-05T00:00:00,0,nodes,storage1,Volume,940.0 +2021-01-05T00:00:00,2021-01-06T00:00:00,0,nodes,storage1,Volume,925.0 +2021-01-06T00:00:00,2021-01-07T00:00:00,0,nodes,storage1,Volume,910.0 +2021-01-07T00:00:00,2021-01-08T00:00:00,0,nodes,storage1,Volume,895.0 +2021-01-08T00:00:00,2021-01-09T00:00:00,0,nodes,storage1,Volume,880.0 +2021-01-09T00:00:00,2021-01-10T00:00:00,0,nodes,storage1,Volume,865.0 +2021-01-10T00:00:00,2021-01-11T00:00:00,0,nodes,storage1,Volume,850.0 +2021-01-11T00:00:00,2021-01-12T00:00:00,0,nodes,storage1,Volume,835.0 +2021-01-12T00:00:00,2021-01-13T00:00:00,0,nodes,storage1,Volume,820.0 +2021-01-13T00:00:00,2021-01-14T00:00:00,0,nodes,storage1,Volume,805.0 +2021-01-14T00:00:00,2021-01-15T00:00:00,0,nodes,storage1,Volume,790.0 +2021-01-15T00:00:00,2021-01-16T00:00:00,0,nodes,storage1,Volume,775.0 +2021-01-16T00:00:00,2021-01-17T00:00:00,0,nodes,storage1,Volume,760.0 +2021-01-17T00:00:00,2021-01-18T00:00:00,0,nodes,storage1,Volume,745.0 +2021-01-18T00:00:00,2021-01-19T00:00:00,0,nodes,storage1,Volume,730.0 +2021-01-19T00:00:00,2021-01-20T00:00:00,0,nodes,storage1,Volume,715.0 +2021-01-20T00:00:00,2021-01-21T00:00:00,0,nodes,storage1,Volume,700.0 +2021-01-21T00:00:00,2021-01-22T00:00:00,0,nodes,storage1,Volume,685.0 +2021-01-22T00:00:00,2021-01-23T00:00:00,0,nodes,storage1,Volume,670.0 +2021-01-23T00:00:00,2021-01-24T00:00:00,0,nodes,storage1,Volume,655.0 +2021-01-24T00:00:00,2021-01-25T00:00:00,0,nodes,storage1,Volume,640.0 +2021-01-25T00:00:00,2021-01-26T00:00:00,0,nodes,storage1,Volume,625.0 +2021-01-26T00:00:00,2021-01-27T00:00:00,0,nodes,storage1,Volume,610.0 +2021-01-27T00:00:00,2021-01-28T00:00:00,0,nodes,storage1,Volume,595.0 +2021-01-28T00:00:00,2021-01-29T00:00:00,0,nodes,storage1,Volume,580.0 +2021-01-29T00:00:00,2021-01-30T00:00:00,0,nodes,storage1,Volume,565.0 +2021-01-30T00:00:00,2021-01-31T00:00:00,0,nodes,storage1,Volume,550.0 +2021-01-31T00:00:00,2021-02-01T00:00:00,0,nodes,storage1,Volume,535.0 +2021-02-01T00:00:00,2021-02-02T00:00:00,0,nodes,storage1,Volume,520.0 +2021-02-02T00:00:00,2021-02-03T00:00:00,0,nodes,storage1,Volume,505.0 +2021-02-03T00:00:00,2021-02-04T00:00:00,0,nodes,storage1,Volume,495.0 +2021-02-04T00:00:00,2021-02-05T00:00:00,0,nodes,storage1,Volume,485.0 +2021-02-05T00:00:00,2021-02-06T00:00:00,0,nodes,storage1,Volume,475.0 +2021-02-06T00:00:00,2021-02-07T00:00:00,0,nodes,storage1,Volume,465.0 +2021-02-07T00:00:00,2021-02-08T00:00:00,0,nodes,storage1,Volume,455.0 +2021-02-08T00:00:00,2021-02-09T00:00:00,0,nodes,storage1,Volume,445.0 +2021-02-09T00:00:00,2021-02-10T00:00:00,0,nodes,storage1,Volume,435.0 +2021-02-10T00:00:00,2021-02-11T00:00:00,0,nodes,storage1,Volume,425.0 +2021-02-11T00:00:00,2021-02-12T00:00:00,0,nodes,storage1,Volume,415.0 +2021-02-12T00:00:00,2021-02-13T00:00:00,0,nodes,storage1,Volume,405.0 +2021-02-13T00:00:00,2021-02-14T00:00:00,0,nodes,storage1,Volume,395.0 +2021-02-14T00:00:00,2021-02-15T00:00:00,0,nodes,storage1,Volume,385.0 +2021-02-15T00:00:00,2021-02-16T00:00:00,0,nodes,storage1,Volume,375.0 +2021-02-16T00:00:00,2021-02-17T00:00:00,0,nodes,storage1,Volume,365.0 +2021-02-17T00:00:00,2021-02-18T00:00:00,0,nodes,storage1,Volume,355.0 +2021-02-18T00:00:00,2021-02-19T00:00:00,0,nodes,storage1,Volume,345.0 +2021-02-19T00:00:00,2021-02-20T00:00:00,0,nodes,storage1,Volume,335.0 +2021-02-20T00:00:00,2021-02-21T00:00:00,0,nodes,storage1,Volume,325.0 +2021-02-21T00:00:00,2021-02-22T00:00:00,0,nodes,storage1,Volume,315.0 +2021-02-22T00:00:00,2021-02-23T00:00:00,0,nodes,storage1,Volume,305.0 +2021-02-23T00:00:00,2021-02-24T00:00:00,0,nodes,storage1,Volume,295.0 +2021-02-24T00:00:00,2021-02-25T00:00:00,0,nodes,storage1,Volume,285.0 +2021-02-25T00:00:00,2021-02-26T00:00:00,0,nodes,storage1,Volume,275.0 +2021-02-26T00:00:00,2021-02-27T00:00:00,0,nodes,storage1,Volume,265.0 +2021-02-27T00:00:00,2021-02-28T00:00:00,0,nodes,storage1,Volume,255.0 +2021-02-28T00:00:00,2021-03-01T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-01T00:00:00,2021-03-02T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-02T00:00:00,2021-03-03T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-03T00:00:00,2021-03-04T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-04T00:00:00,2021-03-05T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-05T00:00:00,2021-03-06T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-06T00:00:00,2021-03-07T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-07T00:00:00,2021-03-08T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-08T00:00:00,2021-03-09T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-09T00:00:00,2021-03-10T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-10T00:00:00,2021-03-11T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-11T00:00:00,2021-03-12T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-12T00:00:00,2021-03-13T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-13T00:00:00,2021-03-14T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-14T00:00:00,2021-03-15T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-15T00:00:00,2021-03-16T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-16T00:00:00,2021-03-17T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-17T00:00:00,2021-03-18T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-18T00:00:00,2021-03-19T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-19T00:00:00,2021-03-20T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-20T00:00:00,2021-03-21T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-21T00:00:00,2021-03-22T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-22T00:00:00,2021-03-23T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-23T00:00:00,2021-03-24T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-24T00:00:00,2021-03-25T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-25T00:00:00,2021-03-26T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-26T00:00:00,2021-03-27T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-27T00:00:00,2021-03-28T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-28T00:00:00,2021-03-29T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-29T00:00:00,2021-03-30T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-30T00:00:00,2021-03-31T00:00:00,0,nodes,storage1,Volume,250.0 +2021-03-31T00:00:00,2021-04-01T00:00:00,0,nodes,storage1,Volume,250.0 diff --git a/pywr-schema/src/test_models/piecewise_storage1.json b/pywr-schema/tests/piecewise_storage1.json similarity index 77% rename from pywr-schema/src/test_models/piecewise_storage1.json rename to pywr-schema/tests/piecewise_storage1.json index 66af9787..3e596b1a 100644 --- a/pywr-schema/src/test_models/piecewise_storage1.json +++ b/pywr-schema/tests/piecewise_storage1.json @@ -5,8 +5,8 @@ "minimum_version": "0.1" }, "timestepper": { - "start": "2015-01-01", - "end": "2015-12-31", + "start": "2021-01-01", + "end": "2021-03-31", "timestep": 1 }, "network": { @@ -81,6 +81,27 @@ "from_node": "storage1", "to_node": "demand1" } + ], + "metric_sets": [ + { + "name": "nodes", + "metrics": [ + { + "type": "Node", + "name": "storage1" + } + ] + } + ], + "outputs": [ + { + "name": "nodes", + "type": "CSV", + "format": "long", + "filename": "piecewise_storage1-expected.csv", + "metric_set": "nodes", + "decimal_places": 1 + } ] } } diff --git a/pywr-schema/tests/piecewise_storage2-expected.csv b/pywr-schema/tests/piecewise_storage2-expected.csv new file mode 100644 index 00000000..b241cd02 --- /dev/null +++ b/pywr-schema/tests/piecewise_storage2-expected.csv @@ -0,0 +1,487 @@ +time_start,time_end,scenario_index,metric_set,name,attribute,value +2021-01-01T00:00:00,2021-01-02T00:00:00,0,nodes,storage1,Volume,995.0 +2021-01-01T00:00:00,2021-01-02T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-02T00:00:00,2021-01-03T00:00:00,0,nodes,storage1,Volume,990.0 +2021-01-02T00:00:00,2021-01-03T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-03T00:00:00,2021-01-04T00:00:00,0,nodes,storage1,Volume,985.0 +2021-01-03T00:00:00,2021-01-04T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-04T00:00:00,2021-01-05T00:00:00,0,nodes,storage1,Volume,980.0 +2021-01-04T00:00:00,2021-01-05T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-05T00:00:00,2021-01-06T00:00:00,0,nodes,storage1,Volume,975.0 +2021-01-05T00:00:00,2021-01-06T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-06T00:00:00,2021-01-07T00:00:00,0,nodes,storage1,Volume,970.0 +2021-01-06T00:00:00,2021-01-07T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-07T00:00:00,2021-01-08T00:00:00,0,nodes,storage1,Volume,965.0 +2021-01-07T00:00:00,2021-01-08T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-08T00:00:00,2021-01-09T00:00:00,0,nodes,storage1,Volume,960.0 +2021-01-08T00:00:00,2021-01-09T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-09T00:00:00,2021-01-10T00:00:00,0,nodes,storage1,Volume,955.0 +2021-01-09T00:00:00,2021-01-10T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-10T00:00:00,2021-01-11T00:00:00,0,nodes,storage1,Volume,950.0 +2021-01-10T00:00:00,2021-01-11T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-11T00:00:00,2021-01-12T00:00:00,0,nodes,storage1,Volume,945.0 +2021-01-11T00:00:00,2021-01-12T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-12T00:00:00,2021-01-13T00:00:00,0,nodes,storage1,Volume,940.0 +2021-01-12T00:00:00,2021-01-13T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-13T00:00:00,2021-01-14T00:00:00,0,nodes,storage1,Volume,935.0 +2021-01-13T00:00:00,2021-01-14T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-14T00:00:00,2021-01-15T00:00:00,0,nodes,storage1,Volume,930.0 +2021-01-14T00:00:00,2021-01-15T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-15T00:00:00,2021-01-16T00:00:00,0,nodes,storage1,Volume,925.0 +2021-01-15T00:00:00,2021-01-16T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-16T00:00:00,2021-01-17T00:00:00,0,nodes,storage1,Volume,920.0 +2021-01-16T00:00:00,2021-01-17T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-17T00:00:00,2021-01-18T00:00:00,0,nodes,storage1,Volume,915.0 +2021-01-17T00:00:00,2021-01-18T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-18T00:00:00,2021-01-19T00:00:00,0,nodes,storage1,Volume,910.0 +2021-01-18T00:00:00,2021-01-19T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-19T00:00:00,2021-01-20T00:00:00,0,nodes,storage1,Volume,905.0 +2021-01-19T00:00:00,2021-01-20T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-20T00:00:00,2021-01-21T00:00:00,0,nodes,storage1,Volume,900.0 +2021-01-20T00:00:00,2021-01-21T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-21T00:00:00,2021-01-22T00:00:00,0,nodes,storage1,Volume,895.0 +2021-01-21T00:00:00,2021-01-22T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-22T00:00:00,2021-01-23T00:00:00,0,nodes,storage1,Volume,890.0 +2021-01-22T00:00:00,2021-01-23T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-23T00:00:00,2021-01-24T00:00:00,0,nodes,storage1,Volume,885.0 +2021-01-23T00:00:00,2021-01-24T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-24T00:00:00,2021-01-25T00:00:00,0,nodes,storage1,Volume,880.0 +2021-01-24T00:00:00,2021-01-25T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-25T00:00:00,2021-01-26T00:00:00,0,nodes,storage1,Volume,875.0 +2021-01-25T00:00:00,2021-01-26T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-26T00:00:00,2021-01-27T00:00:00,0,nodes,storage1,Volume,870.0 +2021-01-26T00:00:00,2021-01-27T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-27T00:00:00,2021-01-28T00:00:00,0,nodes,storage1,Volume,865.0 +2021-01-27T00:00:00,2021-01-28T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-28T00:00:00,2021-01-29T00:00:00,0,nodes,storage1,Volume,860.0 +2021-01-28T00:00:00,2021-01-29T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-29T00:00:00,2021-01-30T00:00:00,0,nodes,storage1,Volume,855.0 +2021-01-29T00:00:00,2021-01-30T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-30T00:00:00,2021-01-31T00:00:00,0,nodes,storage1,Volume,850.0 +2021-01-30T00:00:00,2021-01-31T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-01-31T00:00:00,2021-02-01T00:00:00,0,nodes,storage1,Volume,845.0 +2021-01-31T00:00:00,2021-02-01T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-01T00:00:00,2021-02-02T00:00:00,0,nodes,storage1,Volume,840.0 +2021-02-01T00:00:00,2021-02-02T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-02T00:00:00,2021-02-03T00:00:00,0,nodes,storage1,Volume,835.0 +2021-02-02T00:00:00,2021-02-03T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-03T00:00:00,2021-02-04T00:00:00,0,nodes,storage1,Volume,830.0 +2021-02-03T00:00:00,2021-02-04T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-04T00:00:00,2021-02-05T00:00:00,0,nodes,storage1,Volume,825.0 +2021-02-04T00:00:00,2021-02-05T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-05T00:00:00,2021-02-06T00:00:00,0,nodes,storage1,Volume,820.0 +2021-02-05T00:00:00,2021-02-06T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-06T00:00:00,2021-02-07T00:00:00,0,nodes,storage1,Volume,815.0 +2021-02-06T00:00:00,2021-02-07T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-07T00:00:00,2021-02-08T00:00:00,0,nodes,storage1,Volume,810.0 +2021-02-07T00:00:00,2021-02-08T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-08T00:00:00,2021-02-09T00:00:00,0,nodes,storage1,Volume,805.0 +2021-02-08T00:00:00,2021-02-09T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-09T00:00:00,2021-02-10T00:00:00,0,nodes,storage1,Volume,800.0 +2021-02-09T00:00:00,2021-02-10T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-10T00:00:00,2021-02-11T00:00:00,0,nodes,storage1,Volume,795.0 +2021-02-10T00:00:00,2021-02-11T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-11T00:00:00,2021-02-12T00:00:00,0,nodes,storage1,Volume,790.0 +2021-02-11T00:00:00,2021-02-12T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-12T00:00:00,2021-02-13T00:00:00,0,nodes,storage1,Volume,785.0 +2021-02-12T00:00:00,2021-02-13T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-13T00:00:00,2021-02-14T00:00:00,0,nodes,storage1,Volume,780.0 +2021-02-13T00:00:00,2021-02-14T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-14T00:00:00,2021-02-15T00:00:00,0,nodes,storage1,Volume,775.0 +2021-02-14T00:00:00,2021-02-15T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-15T00:00:00,2021-02-16T00:00:00,0,nodes,storage1,Volume,770.0 +2021-02-15T00:00:00,2021-02-16T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-16T00:00:00,2021-02-17T00:00:00,0,nodes,storage1,Volume,765.0 +2021-02-16T00:00:00,2021-02-17T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-17T00:00:00,2021-02-18T00:00:00,0,nodes,storage1,Volume,760.0 +2021-02-17T00:00:00,2021-02-18T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-18T00:00:00,2021-02-19T00:00:00,0,nodes,storage1,Volume,755.0 +2021-02-18T00:00:00,2021-02-19T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-19T00:00:00,2021-02-20T00:00:00,0,nodes,storage1,Volume,750.0 +2021-02-19T00:00:00,2021-02-20T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-20T00:00:00,2021-02-21T00:00:00,0,nodes,storage1,Volume,748.0 +2021-02-20T00:00:00,2021-02-21T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-21T00:00:00,2021-02-22T00:00:00,0,nodes,storage1,Volume,746.0 +2021-02-21T00:00:00,2021-02-22T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-22T00:00:00,2021-02-23T00:00:00,0,nodes,storage1,Volume,744.0 +2021-02-22T00:00:00,2021-02-23T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-23T00:00:00,2021-02-24T00:00:00,0,nodes,storage1,Volume,742.0 +2021-02-23T00:00:00,2021-02-24T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-24T00:00:00,2021-02-25T00:00:00,0,nodes,storage1,Volume,740.0 +2021-02-24T00:00:00,2021-02-25T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-25T00:00:00,2021-02-26T00:00:00,0,nodes,storage1,Volume,738.0 +2021-02-25T00:00:00,2021-02-26T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-26T00:00:00,2021-02-27T00:00:00,0,nodes,storage1,Volume,736.0 +2021-02-26T00:00:00,2021-02-27T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-27T00:00:00,2021-02-28T00:00:00,0,nodes,storage1,Volume,734.0 +2021-02-27T00:00:00,2021-02-28T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-02-28T00:00:00,2021-03-01T00:00:00,0,nodes,storage1,Volume,732.0 +2021-02-28T00:00:00,2021-03-01T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-01T00:00:00,2021-03-02T00:00:00,0,nodes,storage1,Volume,730.0 +2021-03-01T00:00:00,2021-03-02T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-02T00:00:00,2021-03-03T00:00:00,0,nodes,storage1,Volume,728.0 +2021-03-02T00:00:00,2021-03-03T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-03T00:00:00,2021-03-04T00:00:00,0,nodes,storage1,Volume,726.0 +2021-03-03T00:00:00,2021-03-04T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-04T00:00:00,2021-03-05T00:00:00,0,nodes,storage1,Volume,724.0 +2021-03-04T00:00:00,2021-03-05T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-05T00:00:00,2021-03-06T00:00:00,0,nodes,storage1,Volume,722.0 +2021-03-05T00:00:00,2021-03-06T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-06T00:00:00,2021-03-07T00:00:00,0,nodes,storage1,Volume,720.0 +2021-03-06T00:00:00,2021-03-07T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-07T00:00:00,2021-03-08T00:00:00,0,nodes,storage1,Volume,718.0 +2021-03-07T00:00:00,2021-03-08T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-08T00:00:00,2021-03-09T00:00:00,0,nodes,storage1,Volume,716.0 +2021-03-08T00:00:00,2021-03-09T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-09T00:00:00,2021-03-10T00:00:00,0,nodes,storage1,Volume,714.0 +2021-03-09T00:00:00,2021-03-10T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-10T00:00:00,2021-03-11T00:00:00,0,nodes,storage1,Volume,712.0 +2021-03-10T00:00:00,2021-03-11T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-11T00:00:00,2021-03-12T00:00:00,0,nodes,storage1,Volume,710.0 +2021-03-11T00:00:00,2021-03-12T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-12T00:00:00,2021-03-13T00:00:00,0,nodes,storage1,Volume,708.0 +2021-03-12T00:00:00,2021-03-13T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-13T00:00:00,2021-03-14T00:00:00,0,nodes,storage1,Volume,706.0 +2021-03-13T00:00:00,2021-03-14T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-14T00:00:00,2021-03-15T00:00:00,0,nodes,storage1,Volume,704.0 +2021-03-14T00:00:00,2021-03-15T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-15T00:00:00,2021-03-16T00:00:00,0,nodes,storage1,Volume,702.0 +2021-03-15T00:00:00,2021-03-16T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-16T00:00:00,2021-03-17T00:00:00,0,nodes,storage1,Volume,700.0 +2021-03-16T00:00:00,2021-03-17T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-17T00:00:00,2021-03-18T00:00:00,0,nodes,storage1,Volume,698.0 +2021-03-17T00:00:00,2021-03-18T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-18T00:00:00,2021-03-19T00:00:00,0,nodes,storage1,Volume,696.0 +2021-03-18T00:00:00,2021-03-19T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-19T00:00:00,2021-03-20T00:00:00,0,nodes,storage1,Volume,694.0 +2021-03-19T00:00:00,2021-03-20T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-20T00:00:00,2021-03-21T00:00:00,0,nodes,storage1,Volume,692.0 +2021-03-20T00:00:00,2021-03-21T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-21T00:00:00,2021-03-22T00:00:00,0,nodes,storage1,Volume,690.0 +2021-03-21T00:00:00,2021-03-22T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-22T00:00:00,2021-03-23T00:00:00,0,nodes,storage1,Volume,688.0 +2021-03-22T00:00:00,2021-03-23T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-23T00:00:00,2021-03-24T00:00:00,0,nodes,storage1,Volume,686.0 +2021-03-23T00:00:00,2021-03-24T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-24T00:00:00,2021-03-25T00:00:00,0,nodes,storage1,Volume,684.0 +2021-03-24T00:00:00,2021-03-25T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-25T00:00:00,2021-03-26T00:00:00,0,nodes,storage1,Volume,682.0 +2021-03-25T00:00:00,2021-03-26T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-26T00:00:00,2021-03-27T00:00:00,0,nodes,storage1,Volume,680.0 +2021-03-26T00:00:00,2021-03-27T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-27T00:00:00,2021-03-28T00:00:00,0,nodes,storage1,Volume,678.0 +2021-03-27T00:00:00,2021-03-28T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-28T00:00:00,2021-03-29T00:00:00,0,nodes,storage1,Volume,676.0 +2021-03-28T00:00:00,2021-03-29T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-29T00:00:00,2021-03-30T00:00:00,0,nodes,storage1,Volume,674.0 +2021-03-29T00:00:00,2021-03-30T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-30T00:00:00,2021-03-31T00:00:00,0,nodes,storage1,Volume,672.0 +2021-03-30T00:00:00,2021-03-31T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-03-31T00:00:00,2021-04-01T00:00:00,0,nodes,storage1,Volume,670.0 +2021-03-31T00:00:00,2021-04-01T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-01T00:00:00,2021-04-02T00:00:00,0,nodes,storage1,Volume,665.0 +2021-04-01T00:00:00,2021-04-02T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-02T00:00:00,2021-04-03T00:00:00,0,nodes,storage1,Volume,660.0 +2021-04-02T00:00:00,2021-04-03T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-03T00:00:00,2021-04-04T00:00:00,0,nodes,storage1,Volume,655.0 +2021-04-03T00:00:00,2021-04-04T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-04T00:00:00,2021-04-05T00:00:00,0,nodes,storage1,Volume,650.0 +2021-04-04T00:00:00,2021-04-05T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-05T00:00:00,2021-04-06T00:00:00,0,nodes,storage1,Volume,645.0 +2021-04-05T00:00:00,2021-04-06T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-06T00:00:00,2021-04-07T00:00:00,0,nodes,storage1,Volume,640.0 +2021-04-06T00:00:00,2021-04-07T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-07T00:00:00,2021-04-08T00:00:00,0,nodes,storage1,Volume,635.0 +2021-04-07T00:00:00,2021-04-08T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-08T00:00:00,2021-04-09T00:00:00,0,nodes,storage1,Volume,630.0 +2021-04-08T00:00:00,2021-04-09T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-09T00:00:00,2021-04-10T00:00:00,0,nodes,storage1,Volume,625.0 +2021-04-09T00:00:00,2021-04-10T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-10T00:00:00,2021-04-11T00:00:00,0,nodes,storage1,Volume,620.0 +2021-04-10T00:00:00,2021-04-11T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-11T00:00:00,2021-04-12T00:00:00,0,nodes,storage1,Volume,615.0 +2021-04-11T00:00:00,2021-04-12T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-12T00:00:00,2021-04-13T00:00:00,0,nodes,storage1,Volume,610.0 +2021-04-12T00:00:00,2021-04-13T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-13T00:00:00,2021-04-14T00:00:00,0,nodes,storage1,Volume,605.0 +2021-04-13T00:00:00,2021-04-14T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-14T00:00:00,2021-04-15T00:00:00,0,nodes,storage1,Volume,600.0 +2021-04-14T00:00:00,2021-04-15T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-15T00:00:00,2021-04-16T00:00:00,0,nodes,storage1,Volume,595.0 +2021-04-15T00:00:00,2021-04-16T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-16T00:00:00,2021-04-17T00:00:00,0,nodes,storage1,Volume,590.0 +2021-04-16T00:00:00,2021-04-17T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-17T00:00:00,2021-04-18T00:00:00,0,nodes,storage1,Volume,585.0 +2021-04-17T00:00:00,2021-04-18T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-18T00:00:00,2021-04-19T00:00:00,0,nodes,storage1,Volume,580.0 +2021-04-18T00:00:00,2021-04-19T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-19T00:00:00,2021-04-20T00:00:00,0,nodes,storage1,Volume,575.0 +2021-04-19T00:00:00,2021-04-20T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-20T00:00:00,2021-04-21T00:00:00,0,nodes,storage1,Volume,570.0 +2021-04-20T00:00:00,2021-04-21T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-21T00:00:00,2021-04-22T00:00:00,0,nodes,storage1,Volume,565.0 +2021-04-21T00:00:00,2021-04-22T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-22T00:00:00,2021-04-23T00:00:00,0,nodes,storage1,Volume,560.0 +2021-04-22T00:00:00,2021-04-23T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-23T00:00:00,2021-04-24T00:00:00,0,nodes,storage1,Volume,555.0 +2021-04-23T00:00:00,2021-04-24T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-24T00:00:00,2021-04-25T00:00:00,0,nodes,storage1,Volume,550.0 +2021-04-24T00:00:00,2021-04-25T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-25T00:00:00,2021-04-26T00:00:00,0,nodes,storage1,Volume,545.0 +2021-04-25T00:00:00,2021-04-26T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-26T00:00:00,2021-04-27T00:00:00,0,nodes,storage1,Volume,540.0 +2021-04-26T00:00:00,2021-04-27T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-27T00:00:00,2021-04-28T00:00:00,0,nodes,storage1,Volume,535.0 +2021-04-27T00:00:00,2021-04-28T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-28T00:00:00,2021-04-29T00:00:00,0,nodes,storage1,Volume,530.0 +2021-04-28T00:00:00,2021-04-29T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-29T00:00:00,2021-04-30T00:00:00,0,nodes,storage1,Volume,525.0 +2021-04-29T00:00:00,2021-04-30T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-04-30T00:00:00,2021-05-01T00:00:00,0,nodes,storage1,Volume,520.0 +2021-04-30T00:00:00,2021-05-01T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-05-01T00:00:00,2021-05-02T00:00:00,0,nodes,storage1,Volume,515.0 +2021-05-01T00:00:00,2021-05-02T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-05-02T00:00:00,2021-05-03T00:00:00,0,nodes,storage1,Volume,510.0 +2021-05-02T00:00:00,2021-05-03T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-05-03T00:00:00,2021-05-04T00:00:00,0,nodes,storage1,Volume,505.0 +2021-05-03T00:00:00,2021-05-04T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-05-04T00:00:00,2021-05-05T00:00:00,0,nodes,storage1,Volume,500.0 +2021-05-04T00:00:00,2021-05-05T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-05-05T00:00:00,2021-05-06T00:00:00,0,nodes,storage1,Volume,498.0 +2021-05-05T00:00:00,2021-05-06T00:00:00,0,nodes,storage1-drought-index,value,0.0 +2021-05-06T00:00:00,2021-05-07T00:00:00,0,nodes,storage1,Volume,496.0 +2021-05-06T00:00:00,2021-05-07T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-07T00:00:00,2021-05-08T00:00:00,0,nodes,storage1,Volume,494.0 +2021-05-07T00:00:00,2021-05-08T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-08T00:00:00,2021-05-09T00:00:00,0,nodes,storage1,Volume,492.0 +2021-05-08T00:00:00,2021-05-09T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-09T00:00:00,2021-05-10T00:00:00,0,nodes,storage1,Volume,490.0 +2021-05-09T00:00:00,2021-05-10T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-10T00:00:00,2021-05-11T00:00:00,0,nodes,storage1,Volume,488.0 +2021-05-10T00:00:00,2021-05-11T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-11T00:00:00,2021-05-12T00:00:00,0,nodes,storage1,Volume,486.0 +2021-05-11T00:00:00,2021-05-12T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-12T00:00:00,2021-05-13T00:00:00,0,nodes,storage1,Volume,484.0 +2021-05-12T00:00:00,2021-05-13T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-13T00:00:00,2021-05-14T00:00:00,0,nodes,storage1,Volume,482.0 +2021-05-13T00:00:00,2021-05-14T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-14T00:00:00,2021-05-15T00:00:00,0,nodes,storage1,Volume,480.0 +2021-05-14T00:00:00,2021-05-15T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-15T00:00:00,2021-05-16T00:00:00,0,nodes,storage1,Volume,478.0 +2021-05-15T00:00:00,2021-05-16T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-16T00:00:00,2021-05-17T00:00:00,0,nodes,storage1,Volume,476.0 +2021-05-16T00:00:00,2021-05-17T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-17T00:00:00,2021-05-18T00:00:00,0,nodes,storage1,Volume,474.0 +2021-05-17T00:00:00,2021-05-18T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-18T00:00:00,2021-05-19T00:00:00,0,nodes,storage1,Volume,472.0 +2021-05-18T00:00:00,2021-05-19T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-19T00:00:00,2021-05-20T00:00:00,0,nodes,storage1,Volume,470.0 +2021-05-19T00:00:00,2021-05-20T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-20T00:00:00,2021-05-21T00:00:00,0,nodes,storage1,Volume,468.0 +2021-05-20T00:00:00,2021-05-21T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-21T00:00:00,2021-05-22T00:00:00,0,nodes,storage1,Volume,466.0 +2021-05-21T00:00:00,2021-05-22T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-22T00:00:00,2021-05-23T00:00:00,0,nodes,storage1,Volume,464.0 +2021-05-22T00:00:00,2021-05-23T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-23T00:00:00,2021-05-24T00:00:00,0,nodes,storage1,Volume,462.0 +2021-05-23T00:00:00,2021-05-24T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-24T00:00:00,2021-05-25T00:00:00,0,nodes,storage1,Volume,460.0 +2021-05-24T00:00:00,2021-05-25T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-25T00:00:00,2021-05-26T00:00:00,0,nodes,storage1,Volume,458.0 +2021-05-25T00:00:00,2021-05-26T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-26T00:00:00,2021-05-27T00:00:00,0,nodes,storage1,Volume,456.0 +2021-05-26T00:00:00,2021-05-27T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-27T00:00:00,2021-05-28T00:00:00,0,nodes,storage1,Volume,454.0 +2021-05-27T00:00:00,2021-05-28T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-28T00:00:00,2021-05-29T00:00:00,0,nodes,storage1,Volume,452.0 +2021-05-28T00:00:00,2021-05-29T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-29T00:00:00,2021-05-30T00:00:00,0,nodes,storage1,Volume,450.0 +2021-05-29T00:00:00,2021-05-30T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-30T00:00:00,2021-05-31T00:00:00,0,nodes,storage1,Volume,448.0 +2021-05-30T00:00:00,2021-05-31T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-05-31T00:00:00,2021-06-01T00:00:00,0,nodes,storage1,Volume,446.0 +2021-05-31T00:00:00,2021-06-01T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-01T00:00:00,2021-06-02T00:00:00,0,nodes,storage1,Volume,444.0 +2021-06-01T00:00:00,2021-06-02T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-02T00:00:00,2021-06-03T00:00:00,0,nodes,storage1,Volume,442.0 +2021-06-02T00:00:00,2021-06-03T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-03T00:00:00,2021-06-04T00:00:00,0,nodes,storage1,Volume,440.0 +2021-06-03T00:00:00,2021-06-04T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-04T00:00:00,2021-06-05T00:00:00,0,nodes,storage1,Volume,438.0 +2021-06-04T00:00:00,2021-06-05T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-05T00:00:00,2021-06-06T00:00:00,0,nodes,storage1,Volume,436.0 +2021-06-05T00:00:00,2021-06-06T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-06T00:00:00,2021-06-07T00:00:00,0,nodes,storage1,Volume,434.0 +2021-06-06T00:00:00,2021-06-07T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-07T00:00:00,2021-06-08T00:00:00,0,nodes,storage1,Volume,432.0 +2021-06-07T00:00:00,2021-06-08T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-08T00:00:00,2021-06-09T00:00:00,0,nodes,storage1,Volume,430.0 +2021-06-08T00:00:00,2021-06-09T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-09T00:00:00,2021-06-10T00:00:00,0,nodes,storage1,Volume,428.0 +2021-06-09T00:00:00,2021-06-10T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-10T00:00:00,2021-06-11T00:00:00,0,nodes,storage1,Volume,426.0 +2021-06-10T00:00:00,2021-06-11T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-11T00:00:00,2021-06-12T00:00:00,0,nodes,storage1,Volume,424.0 +2021-06-11T00:00:00,2021-06-12T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-12T00:00:00,2021-06-13T00:00:00,0,nodes,storage1,Volume,422.0 +2021-06-12T00:00:00,2021-06-13T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-13T00:00:00,2021-06-14T00:00:00,0,nodes,storage1,Volume,420.0 +2021-06-13T00:00:00,2021-06-14T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-14T00:00:00,2021-06-15T00:00:00,0,nodes,storage1,Volume,418.0 +2021-06-14T00:00:00,2021-06-15T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-15T00:00:00,2021-06-16T00:00:00,0,nodes,storage1,Volume,416.0 +2021-06-15T00:00:00,2021-06-16T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-16T00:00:00,2021-06-17T00:00:00,0,nodes,storage1,Volume,414.0 +2021-06-16T00:00:00,2021-06-17T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-17T00:00:00,2021-06-18T00:00:00,0,nodes,storage1,Volume,412.0 +2021-06-17T00:00:00,2021-06-18T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-18T00:00:00,2021-06-19T00:00:00,0,nodes,storage1,Volume,410.0 +2021-06-18T00:00:00,2021-06-19T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-19T00:00:00,2021-06-20T00:00:00,0,nodes,storage1,Volume,408.0 +2021-06-19T00:00:00,2021-06-20T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-20T00:00:00,2021-06-21T00:00:00,0,nodes,storage1,Volume,406.0 +2021-06-20T00:00:00,2021-06-21T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-21T00:00:00,2021-06-22T00:00:00,0,nodes,storage1,Volume,404.0 +2021-06-21T00:00:00,2021-06-22T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-22T00:00:00,2021-06-23T00:00:00,0,nodes,storage1,Volume,402.0 +2021-06-22T00:00:00,2021-06-23T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-23T00:00:00,2021-06-24T00:00:00,0,nodes,storage1,Volume,400.0 +2021-06-23T00:00:00,2021-06-24T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-24T00:00:00,2021-06-25T00:00:00,0,nodes,storage1,Volume,398.0 +2021-06-24T00:00:00,2021-06-25T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-25T00:00:00,2021-06-26T00:00:00,0,nodes,storage1,Volume,396.0 +2021-06-25T00:00:00,2021-06-26T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-26T00:00:00,2021-06-27T00:00:00,0,nodes,storage1,Volume,394.0 +2021-06-26T00:00:00,2021-06-27T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-27T00:00:00,2021-06-28T00:00:00,0,nodes,storage1,Volume,392.0 +2021-06-27T00:00:00,2021-06-28T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-28T00:00:00,2021-06-29T00:00:00,0,nodes,storage1,Volume,390.0 +2021-06-28T00:00:00,2021-06-29T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-29T00:00:00,2021-06-30T00:00:00,0,nodes,storage1,Volume,388.0 +2021-06-29T00:00:00,2021-06-30T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-06-30T00:00:00,2021-07-01T00:00:00,0,nodes,storage1,Volume,386.0 +2021-06-30T00:00:00,2021-07-01T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-01T00:00:00,2021-07-02T00:00:00,0,nodes,storage1,Volume,381.0 +2021-07-01T00:00:00,2021-07-02T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-02T00:00:00,2021-07-03T00:00:00,0,nodes,storage1,Volume,376.0 +2021-07-02T00:00:00,2021-07-03T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-03T00:00:00,2021-07-04T00:00:00,0,nodes,storage1,Volume,371.0 +2021-07-03T00:00:00,2021-07-04T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-04T00:00:00,2021-07-05T00:00:00,0,nodes,storage1,Volume,366.0 +2021-07-04T00:00:00,2021-07-05T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-05T00:00:00,2021-07-06T00:00:00,0,nodes,storage1,Volume,361.0 +2021-07-05T00:00:00,2021-07-06T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-06T00:00:00,2021-07-07T00:00:00,0,nodes,storage1,Volume,356.0 +2021-07-06T00:00:00,2021-07-07T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-07T00:00:00,2021-07-08T00:00:00,0,nodes,storage1,Volume,351.0 +2021-07-07T00:00:00,2021-07-08T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-08T00:00:00,2021-07-09T00:00:00,0,nodes,storage1,Volume,346.0 +2021-07-08T00:00:00,2021-07-09T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-09T00:00:00,2021-07-10T00:00:00,0,nodes,storage1,Volume,341.0 +2021-07-09T00:00:00,2021-07-10T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-10T00:00:00,2021-07-11T00:00:00,0,nodes,storage1,Volume,336.0 +2021-07-10T00:00:00,2021-07-11T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-11T00:00:00,2021-07-12T00:00:00,0,nodes,storage1,Volume,331.0 +2021-07-11T00:00:00,2021-07-12T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-12T00:00:00,2021-07-13T00:00:00,0,nodes,storage1,Volume,326.0 +2021-07-12T00:00:00,2021-07-13T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-13T00:00:00,2021-07-14T00:00:00,0,nodes,storage1,Volume,321.0 +2021-07-13T00:00:00,2021-07-14T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-14T00:00:00,2021-07-15T00:00:00,0,nodes,storage1,Volume,316.0 +2021-07-14T00:00:00,2021-07-15T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-15T00:00:00,2021-07-16T00:00:00,0,nodes,storage1,Volume,311.0 +2021-07-15T00:00:00,2021-07-16T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-16T00:00:00,2021-07-17T00:00:00,0,nodes,storage1,Volume,306.0 +2021-07-16T00:00:00,2021-07-17T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-17T00:00:00,2021-07-18T00:00:00,0,nodes,storage1,Volume,301.0 +2021-07-17T00:00:00,2021-07-18T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-18T00:00:00,2021-07-19T00:00:00,0,nodes,storage1,Volume,299.0 +2021-07-18T00:00:00,2021-07-19T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-19T00:00:00,2021-07-20T00:00:00,0,nodes,storage1,Volume,297.0 +2021-07-19T00:00:00,2021-07-20T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-20T00:00:00,2021-07-21T00:00:00,0,nodes,storage1,Volume,295.0 +2021-07-20T00:00:00,2021-07-21T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-21T00:00:00,2021-07-22T00:00:00,0,nodes,storage1,Volume,293.0 +2021-07-21T00:00:00,2021-07-22T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-22T00:00:00,2021-07-23T00:00:00,0,nodes,storage1,Volume,291.0 +2021-07-22T00:00:00,2021-07-23T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-23T00:00:00,2021-07-24T00:00:00,0,nodes,storage1,Volume,289.0 +2021-07-23T00:00:00,2021-07-24T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-24T00:00:00,2021-07-25T00:00:00,0,nodes,storage1,Volume,287.0 +2021-07-24T00:00:00,2021-07-25T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-25T00:00:00,2021-07-26T00:00:00,0,nodes,storage1,Volume,285.0 +2021-07-25T00:00:00,2021-07-26T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-26T00:00:00,2021-07-27T00:00:00,0,nodes,storage1,Volume,283.0 +2021-07-26T00:00:00,2021-07-27T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-27T00:00:00,2021-07-28T00:00:00,0,nodes,storage1,Volume,281.0 +2021-07-27T00:00:00,2021-07-28T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-28T00:00:00,2021-07-29T00:00:00,0,nodes,storage1,Volume,279.0 +2021-07-28T00:00:00,2021-07-29T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-29T00:00:00,2021-07-30T00:00:00,0,nodes,storage1,Volume,277.0 +2021-07-29T00:00:00,2021-07-30T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-30T00:00:00,2021-07-31T00:00:00,0,nodes,storage1,Volume,275.0 +2021-07-30T00:00:00,2021-07-31T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-07-31T00:00:00,2021-08-01T00:00:00,0,nodes,storage1,Volume,273.0 +2021-07-31T00:00:00,2021-08-01T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-01T00:00:00,2021-08-02T00:00:00,0,nodes,storage1,Volume,271.0 +2021-08-01T00:00:00,2021-08-02T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-02T00:00:00,2021-08-03T00:00:00,0,nodes,storage1,Volume,269.0 +2021-08-02T00:00:00,2021-08-03T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-03T00:00:00,2021-08-04T00:00:00,0,nodes,storage1,Volume,267.0 +2021-08-03T00:00:00,2021-08-04T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-04T00:00:00,2021-08-05T00:00:00,0,nodes,storage1,Volume,265.0 +2021-08-04T00:00:00,2021-08-05T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-05T00:00:00,2021-08-06T00:00:00,0,nodes,storage1,Volume,263.0 +2021-08-05T00:00:00,2021-08-06T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-06T00:00:00,2021-08-07T00:00:00,0,nodes,storage1,Volume,261.0 +2021-08-06T00:00:00,2021-08-07T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-07T00:00:00,2021-08-08T00:00:00,0,nodes,storage1,Volume,259.0 +2021-08-07T00:00:00,2021-08-08T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-08T00:00:00,2021-08-09T00:00:00,0,nodes,storage1,Volume,257.0 +2021-08-08T00:00:00,2021-08-09T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-09T00:00:00,2021-08-10T00:00:00,0,nodes,storage1,Volume,255.0 +2021-08-09T00:00:00,2021-08-10T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-10T00:00:00,2021-08-11T00:00:00,0,nodes,storage1,Volume,253.0 +2021-08-10T00:00:00,2021-08-11T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-11T00:00:00,2021-08-12T00:00:00,0,nodes,storage1,Volume,251.0 +2021-08-11T00:00:00,2021-08-12T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-12T00:00:00,2021-08-13T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-12T00:00:00,2021-08-13T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-13T00:00:00,2021-08-14T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-13T00:00:00,2021-08-14T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-14T00:00:00,2021-08-15T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-14T00:00:00,2021-08-15T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-15T00:00:00,2021-08-16T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-15T00:00:00,2021-08-16T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-16T00:00:00,2021-08-17T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-16T00:00:00,2021-08-17T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-17T00:00:00,2021-08-18T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-17T00:00:00,2021-08-18T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-18T00:00:00,2021-08-19T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-18T00:00:00,2021-08-19T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-19T00:00:00,2021-08-20T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-19T00:00:00,2021-08-20T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-20T00:00:00,2021-08-21T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-20T00:00:00,2021-08-21T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-21T00:00:00,2021-08-22T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-21T00:00:00,2021-08-22T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-22T00:00:00,2021-08-23T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-22T00:00:00,2021-08-23T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-23T00:00:00,2021-08-24T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-23T00:00:00,2021-08-24T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-24T00:00:00,2021-08-25T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-24T00:00:00,2021-08-25T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-25T00:00:00,2021-08-26T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-25T00:00:00,2021-08-26T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-26T00:00:00,2021-08-27T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-26T00:00:00,2021-08-27T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-27T00:00:00,2021-08-28T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-27T00:00:00,2021-08-28T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-28T00:00:00,2021-08-29T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-28T00:00:00,2021-08-29T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-29T00:00:00,2021-08-30T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-29T00:00:00,2021-08-30T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-30T00:00:00,2021-08-31T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-30T00:00:00,2021-08-31T00:00:00,0,nodes,storage1-drought-index,value,1.0 +2021-08-31T00:00:00,2021-09-01T00:00:00,0,nodes,storage1,Volume,250.0 +2021-08-31T00:00:00,2021-09-01T00:00:00,0,nodes,storage1-drought-index,value,1.0 diff --git a/pywr-schema/src/test_models/piecewise_storage2.json b/pywr-schema/tests/piecewise_storage2.json similarity index 82% rename from pywr-schema/src/test_models/piecewise_storage2.json rename to pywr-schema/tests/piecewise_storage2.json index bf9e7295..3b2b8ce0 100644 --- a/pywr-schema/src/test_models/piecewise_storage2.json +++ b/pywr-schema/tests/piecewise_storage2.json @@ -5,8 +5,8 @@ "minimum_version": "0.1" }, "timestepper": { - "start": "2015-01-01", - "end": "2015-12-31", + "start": "2021-01-01", + "end": "2021-08-31", "timestep": 1 }, "network": { @@ -125,6 +125,31 @@ } ] } + ], + "metric_sets": [ + { + "name": "nodes", + "metrics": [ + { + "type": "Node", + "name": "storage1" + }, + { + "type": "Parameter", + "name": "storage1-drought-index" + } + ] + } + ], + "outputs": [ + { + "name": "nodes", + "type": "CSV", + "format": "long", + "filename": "piecewise_storage2-expected.csv", + "metric_set": "nodes", + "decimal_places": 1 + } ] } } diff --git a/pywr-schema/src/test_models/river_gauge1.json b/pywr-schema/tests/river_gauge1.json similarity index 100% rename from pywr-schema/src/test_models/river_gauge1.json rename to pywr-schema/tests/river_gauge1.json diff --git a/pywr-schema/src/test_models/river_loss1-expected.csv b/pywr-schema/tests/river_loss1-expected.csv similarity index 100% rename from pywr-schema/src/test_models/river_loss1-expected.csv rename to pywr-schema/tests/river_loss1-expected.csv diff --git a/pywr-schema/src/test_models/river_loss1.json b/pywr-schema/tests/river_loss1.json similarity index 97% rename from pywr-schema/src/test_models/river_loss1.json rename to pywr-schema/tests/river_loss1.json index 500b40fb..224a366c 100644 --- a/pywr-schema/src/test_models/river_loss1.json +++ b/pywr-schema/tests/river_loss1.json @@ -103,7 +103,7 @@ "name": "node-outputs", "type": "CSV", "format": "long", - "filename": "river_loss1.csv", + "filename": "river_loss1-expected.csv", "metric_set": [ "nodes" ], diff --git a/pywr-schema/src/test_models/river_split_with_gauge1.json b/pywr-schema/tests/river_split_with_gauge1.json similarity index 100% rename from pywr-schema/src/test_models/river_split_with_gauge1.json rename to pywr-schema/tests/river_split_with_gauge1.json diff --git a/pywr-schema/src/test_models/simple1.json b/pywr-schema/tests/simple1.json similarity index 100% rename from pywr-schema/src/test_models/simple1.json rename to pywr-schema/tests/simple1.json diff --git a/pywr-schema/src/test_models/storage_max_volumes.json b/pywr-schema/tests/storage_max_volumes.json similarity index 100% rename from pywr-schema/src/test_models/storage_max_volumes.json rename to pywr-schema/tests/storage_max_volumes.json diff --git a/pywr-schema/tests/test_models.rs b/pywr-schema/tests/test_models.rs new file mode 100644 index 00000000..52946b43 --- /dev/null +++ b/pywr-schema/tests/test_models.rs @@ -0,0 +1,143 @@ +#[cfg(feature = "core")] +use pywr_core::test_utils::{run_all_solvers, ExpectedOutputs}; +use pywr_schema::PywrModel; +use std::fs; +use std::path::Path; +#[cfg(feature = "core")] +use std::path::PathBuf; +#[cfg(feature = "core")] +use tempfile::TempDir; + +macro_rules! model_tests { + ($($test_func:ident: $value:expr,)*) => { + $( + #[test] + fn $test_func() { + + // Deserialise the schema and run it + #[cfg(feature = "core")] + { + let (input, expected, solvers_without_features): (&str, Vec<&str>, Vec<&str>) = $value; + let input_pth = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join(input); + let expected_paths = expected.iter().map(|p| Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join(p)).collect::>(); + let schema = deserialise_test_model(&input_pth); + run_test_model(&schema, &expected_paths, &solvers_without_features); + } + + // Just deserialise the schema + #[cfg(not(feature = "core"))] + { + let (input, _expected, _solvers_without_features): (&str, Vec<&str>, Vec<&str>) = $value; + let input_pth = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join(input); + let _schema = deserialise_test_model(&input_pth); + } + } + )* + } +} + +model_tests! { + test_simple1: ("simple1.json", vec![], vec![]), + test_csv1: ("csv1.json", vec!["csv1-outputs-long.csv", "csv1-outputs-wide.csv"], vec![]), + test_csv2: ("csv2.json", vec!["csv2-outputs-long.csv", "csv2-outputs-wide.csv"], vec![]), + test_csv3: ("csv3.json", vec!["csv3-outputs-long.csv"], vec![]), + test_hdf1: ("hdf1.json", vec![], vec![]), // TODO asserting h5 results not possible with this framework + test_memory1: ("memory1.json", vec![], vec![]), // TODO asserting memory results not possible with this framework + test_timeseries: ("timeseries.json", vec!["timeseries-expected.csv"], vec![]), + test_storage_max_volumes: ("storage_max_volumes.json", vec![], vec![]), + test_mutual_exclusivity1: ("mutual-exclusivity1.json", vec!["mutual-exclusivity1.csv"], vec!["clp"]), + test_mutual_exclusivity2: ("mutual-exclusivity2.json", vec!["mutual-exclusivity2.csv"], vec!["clp"]), + test_mutual_exclusivity3: ("mutual-exclusivity3.json", vec!["mutual-exclusivity3.csv"], vec!["clp"]), + test_link_with_soft_min: ("link_with_soft_min.json", vec![], vec![]), + test_link_with_soft_max: ("link_with_soft_max.json", vec![], vec![]), + test_delay1: ("delay1.json", vec!["delay1-expected.csv"], vec![]), + test_loss_link1: ("loss_link1.json", vec!["loss_link1-expected.csv"], vec![]), + test_loss_link2: ("loss_link2.json", vec!["loss_link2-expected.csv"], vec![]), + // TODO this asserted internal flows in the previous test + test_piecewise_link1: ("piecewise_link1.json", vec!["piecewise-link1-nodes.csv", "piecewise-link1-edges.csv"], vec![]), + test_piecewise_storage1: ("piecewise_storage1.json", vec!["piecewise_storage1-expected.csv"], vec![]), + test_piecewise_storage2: ("piecewise_storage2.json", vec!["piecewise_storage2-expected.csv"], vec![]), + test_river_loss1: ("river_loss1.json", vec!["river_loss1-expected.csv"], vec![]), + test_river_gauge1: ("river_gauge1.json", vec![], vec![]), + test_river_split_with_gauge1: ("river_split_with_gauge1.json", vec![], vec![]), + test_thirty_day_licence: ("30-day-licence.json", vec![], vec![]), + test_wtw1: ("wtw1.json", vec!["wtw1-expected.csv"], vec![]), + test_wtw2: ("wtw2.json", vec!["wtw2-expected.csv"], vec![]), + +} + +/// Test Pandas backend for reading timeseries data. +/// +/// This test requires Python environment with Pandas#[test] +#[cfg(feature = "test-python")] +fn test_timeseries_pandas() { + let input = "timeseries_pandas.json"; + let input_pth = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join(input); + let expected = vec!["timeseries-expected.csv"]; + let expected_paths = expected + .iter() + .map(|p| Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join(p)) + .collect::>(); + let schema = deserialise_test_model(&input_pth); + run_test_model(&schema, &expected_paths, &[]); +} + +fn deserialise_test_model(model_path: &Path) -> PywrModel { + let data = fs::read_to_string(model_path).expect("Unable to read file"); + serde_json::from_str(&data).expect("Failed to deserialize model") +} + +#[cfg(feature = "core")] +fn run_test_model(schema: &PywrModel, result_paths: &[PathBuf], solvers_without_features: &[&str]) { + let temp_dir = TempDir::new().unwrap(); + let data_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests"); + let model = schema.build_model(Some(&data_dir), Some(temp_dir.path())).unwrap(); + // After model run there should be an output file. + let expected_outputs: Vec<_> = result_paths + .iter() + .map(|pth| { + ExpectedOutputs::new( + temp_dir.path().join(pth.file_name().unwrap()), + fs::read_to_string(pth).unwrap_or_else(|_| panic!("Failed to read expected output: {}", pth.display())), + ) + }) + .collect(); + + // Test all solvers + run_all_solvers(&model, solvers_without_features, &expected_outputs); +} + +macro_rules! convert_tests { + ($($func_name:ident: $value:expr,)*) => { + $( + + #[test] + fn $func_name() { + let (v1, v2) = $value; + let v1_pth = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join(v1); + let v2_pth = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join(v2); + convert_model(&v1_pth, &v2_pth); + } + )* + } +} + +convert_tests! { + test_convert_timeseries: ("v1/timeseries.json", "v1/timeseries-converted.json"), +} + +fn convert_model(v1_path: &Path, v2_path: &Path) { + let v1_str = fs::read_to_string(v1_path).unwrap(); + let v1: pywr_v1_schema::PywrModel = serde_json::from_str(&v1_str).unwrap(); + + let (v2, errors) = PywrModel::from_v1(v1); + + assert_eq!(errors.len(), 0); + + let v2_converted: serde_json::Value = serde_json::from_str(&serde_json::to_string_pretty(&v2).unwrap()).unwrap(); + + let v2_expected_str = fs::read_to_string(v2_path).unwrap(); + let v2_expected: serde_json::Value = serde_json::from_str(&v2_expected_str).unwrap(); + + assert_eq!(v2_converted, v2_expected); +} diff --git a/pywr-schema/src/test_models/test_parameters.py b/pywr-schema/tests/test_parameters.py similarity index 100% rename from pywr-schema/src/test_models/test_parameters.py rename to pywr-schema/tests/test_parameters.py diff --git a/pywr-schema/tests/timeseries-expected.csv b/pywr-schema/tests/timeseries-expected.csv new file mode 100644 index 00000000..0460d695 --- /dev/null +++ b/pywr-schema/tests/timeseries-expected.csv @@ -0,0 +1,366 @@ +time_start,time_end,scenario_index,metric_set,name,attribute,value +2021-01-01T00:00:00,2021-01-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-01-02T00:00:00,2021-01-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-01-03T00:00:00,2021-01-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-01-04T00:00:00,2021-01-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-01-05T00:00:00,2021-01-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-01-06T00:00:00,2021-01-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-01-07T00:00:00,2021-01-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-01-08T00:00:00,2021-01-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-01-09T00:00:00,2021-01-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-01-10T00:00:00,2021-01-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-01-11T00:00:00,2021-01-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-01-12T00:00:00,2021-01-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-01-13T00:00:00,2021-01-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-01-14T00:00:00,2021-01-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-01-15T00:00:00,2021-01-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-01-16T00:00:00,2021-01-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-01-17T00:00:00,2021-01-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-01-18T00:00:00,2021-01-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-01-19T00:00:00,2021-01-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-01-20T00:00:00,2021-01-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-01-21T00:00:00,2021-01-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-01-22T00:00:00,2021-01-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-01-23T00:00:00,2021-01-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-01-24T00:00:00,2021-01-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-01-25T00:00:00,2021-01-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-01-26T00:00:00,2021-01-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-01-27T00:00:00,2021-01-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-01-28T00:00:00,2021-01-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-01-29T00:00:00,2021-01-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-01-30T00:00:00,2021-01-31T00:00:00,0,nodes,output1,Inflow,45.0 +2021-01-31T00:00:00,2021-02-01T00:00:00,0,nodes,output1,Inflow,46.5 +2021-02-01T00:00:00,2021-02-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-02-02T00:00:00,2021-02-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-02-03T00:00:00,2021-02-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-02-04T00:00:00,2021-02-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-02-05T00:00:00,2021-02-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-02-06T00:00:00,2021-02-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-02-07T00:00:00,2021-02-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-02-08T00:00:00,2021-02-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-02-09T00:00:00,2021-02-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-02-10T00:00:00,2021-02-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-02-11T00:00:00,2021-02-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-02-12T00:00:00,2021-02-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-02-13T00:00:00,2021-02-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-02-14T00:00:00,2021-02-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-02-15T00:00:00,2021-02-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-02-16T00:00:00,2021-02-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-02-17T00:00:00,2021-02-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-02-18T00:00:00,2021-02-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-02-19T00:00:00,2021-02-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-02-20T00:00:00,2021-02-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-02-21T00:00:00,2021-02-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-02-22T00:00:00,2021-02-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-02-23T00:00:00,2021-02-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-02-24T00:00:00,2021-02-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-02-25T00:00:00,2021-02-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-02-26T00:00:00,2021-02-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-02-27T00:00:00,2021-02-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-02-28T00:00:00,2021-03-01T00:00:00,0,nodes,output1,Inflow,42.0 +2021-03-01T00:00:00,2021-03-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-03-02T00:00:00,2021-03-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-03-03T00:00:00,2021-03-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-03-04T00:00:00,2021-03-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-03-05T00:00:00,2021-03-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-03-06T00:00:00,2021-03-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-03-07T00:00:00,2021-03-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-03-08T00:00:00,2021-03-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-03-09T00:00:00,2021-03-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-03-10T00:00:00,2021-03-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-03-11T00:00:00,2021-03-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-03-12T00:00:00,2021-03-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-03-13T00:00:00,2021-03-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-03-14T00:00:00,2021-03-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-03-15T00:00:00,2021-03-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-03-16T00:00:00,2021-03-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-03-17T00:00:00,2021-03-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-03-18T00:00:00,2021-03-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-03-19T00:00:00,2021-03-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-03-20T00:00:00,2021-03-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-03-21T00:00:00,2021-03-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-03-22T00:00:00,2021-03-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-03-23T00:00:00,2021-03-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-03-24T00:00:00,2021-03-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-03-25T00:00:00,2021-03-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-03-26T00:00:00,2021-03-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-03-27T00:00:00,2021-03-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-03-28T00:00:00,2021-03-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-03-29T00:00:00,2021-03-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-03-30T00:00:00,2021-03-31T00:00:00,0,nodes,output1,Inflow,45.0 +2021-03-31T00:00:00,2021-04-01T00:00:00,0,nodes,output1,Inflow,46.5 +2021-04-01T00:00:00,2021-04-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-04-02T00:00:00,2021-04-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-04-03T00:00:00,2021-04-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-04-04T00:00:00,2021-04-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-04-05T00:00:00,2021-04-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-04-06T00:00:00,2021-04-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-04-07T00:00:00,2021-04-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-04-08T00:00:00,2021-04-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-04-09T00:00:00,2021-04-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-04-10T00:00:00,2021-04-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-04-11T00:00:00,2021-04-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-04-12T00:00:00,2021-04-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-04-13T00:00:00,2021-04-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-04-14T00:00:00,2021-04-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-04-15T00:00:00,2021-04-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-04-16T00:00:00,2021-04-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-04-17T00:00:00,2021-04-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-04-18T00:00:00,2021-04-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-04-19T00:00:00,2021-04-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-04-20T00:00:00,2021-04-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-04-21T00:00:00,2021-04-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-04-22T00:00:00,2021-04-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-04-23T00:00:00,2021-04-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-04-24T00:00:00,2021-04-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-04-25T00:00:00,2021-04-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-04-26T00:00:00,2021-04-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-04-27T00:00:00,2021-04-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-04-28T00:00:00,2021-04-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-04-29T00:00:00,2021-04-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-04-30T00:00:00,2021-05-01T00:00:00,0,nodes,output1,Inflow,45.0 +2021-05-01T00:00:00,2021-05-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-05-02T00:00:00,2021-05-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-05-03T00:00:00,2021-05-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-05-04T00:00:00,2021-05-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-05-05T00:00:00,2021-05-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-05-06T00:00:00,2021-05-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-05-07T00:00:00,2021-05-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-05-08T00:00:00,2021-05-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-05-09T00:00:00,2021-05-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-05-10T00:00:00,2021-05-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-05-11T00:00:00,2021-05-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-05-12T00:00:00,2021-05-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-05-13T00:00:00,2021-05-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-05-14T00:00:00,2021-05-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-05-15T00:00:00,2021-05-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-05-16T00:00:00,2021-05-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-05-17T00:00:00,2021-05-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-05-18T00:00:00,2021-05-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-05-19T00:00:00,2021-05-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-05-20T00:00:00,2021-05-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-05-21T00:00:00,2021-05-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-05-22T00:00:00,2021-05-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-05-23T00:00:00,2021-05-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-05-24T00:00:00,2021-05-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-05-25T00:00:00,2021-05-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-05-26T00:00:00,2021-05-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-05-27T00:00:00,2021-05-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-05-28T00:00:00,2021-05-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-05-29T00:00:00,2021-05-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-05-30T00:00:00,2021-05-31T00:00:00,0,nodes,output1,Inflow,45.0 +2021-05-31T00:00:00,2021-06-01T00:00:00,0,nodes,output1,Inflow,46.5 +2021-06-01T00:00:00,2021-06-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-06-02T00:00:00,2021-06-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-06-03T00:00:00,2021-06-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-06-04T00:00:00,2021-06-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-06-05T00:00:00,2021-06-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-06-06T00:00:00,2021-06-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-06-07T00:00:00,2021-06-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-06-08T00:00:00,2021-06-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-06-09T00:00:00,2021-06-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-06-10T00:00:00,2021-06-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-06-11T00:00:00,2021-06-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-06-12T00:00:00,2021-06-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-06-13T00:00:00,2021-06-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-06-14T00:00:00,2021-06-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-06-15T00:00:00,2021-06-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-06-16T00:00:00,2021-06-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-06-17T00:00:00,2021-06-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-06-18T00:00:00,2021-06-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-06-19T00:00:00,2021-06-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-06-20T00:00:00,2021-06-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-06-21T00:00:00,2021-06-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-06-22T00:00:00,2021-06-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-06-23T00:00:00,2021-06-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-06-24T00:00:00,2021-06-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-06-25T00:00:00,2021-06-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-06-26T00:00:00,2021-06-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-06-27T00:00:00,2021-06-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-06-28T00:00:00,2021-06-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-06-29T00:00:00,2021-06-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-06-30T00:00:00,2021-07-01T00:00:00,0,nodes,output1,Inflow,45.0 +2021-07-01T00:00:00,2021-07-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-07-02T00:00:00,2021-07-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-07-03T00:00:00,2021-07-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-07-04T00:00:00,2021-07-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-07-05T00:00:00,2021-07-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-07-06T00:00:00,2021-07-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-07-07T00:00:00,2021-07-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-07-08T00:00:00,2021-07-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-07-09T00:00:00,2021-07-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-07-10T00:00:00,2021-07-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-07-11T00:00:00,2021-07-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-07-12T00:00:00,2021-07-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-07-13T00:00:00,2021-07-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-07-14T00:00:00,2021-07-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-07-15T00:00:00,2021-07-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-07-16T00:00:00,2021-07-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-07-17T00:00:00,2021-07-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-07-18T00:00:00,2021-07-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-07-19T00:00:00,2021-07-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-07-20T00:00:00,2021-07-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-07-21T00:00:00,2021-07-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-07-22T00:00:00,2021-07-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-07-23T00:00:00,2021-07-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-07-24T00:00:00,2021-07-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-07-25T00:00:00,2021-07-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-07-26T00:00:00,2021-07-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-07-27T00:00:00,2021-07-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-07-28T00:00:00,2021-07-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-07-29T00:00:00,2021-07-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-07-30T00:00:00,2021-07-31T00:00:00,0,nodes,output1,Inflow,45.0 +2021-07-31T00:00:00,2021-08-01T00:00:00,0,nodes,output1,Inflow,46.5 +2021-08-01T00:00:00,2021-08-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-08-02T00:00:00,2021-08-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-08-03T00:00:00,2021-08-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-08-04T00:00:00,2021-08-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-08-05T00:00:00,2021-08-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-08-06T00:00:00,2021-08-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-08-07T00:00:00,2021-08-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-08-08T00:00:00,2021-08-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-08-09T00:00:00,2021-08-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-08-10T00:00:00,2021-08-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-08-11T00:00:00,2021-08-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-08-12T00:00:00,2021-08-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-08-13T00:00:00,2021-08-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-08-14T00:00:00,2021-08-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-08-15T00:00:00,2021-08-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-08-16T00:00:00,2021-08-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-08-17T00:00:00,2021-08-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-08-18T00:00:00,2021-08-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-08-19T00:00:00,2021-08-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-08-20T00:00:00,2021-08-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-08-21T00:00:00,2021-08-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-08-22T00:00:00,2021-08-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-08-23T00:00:00,2021-08-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-08-24T00:00:00,2021-08-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-08-25T00:00:00,2021-08-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-08-26T00:00:00,2021-08-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-08-27T00:00:00,2021-08-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-08-28T00:00:00,2021-08-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-08-29T00:00:00,2021-08-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-08-30T00:00:00,2021-08-31T00:00:00,0,nodes,output1,Inflow,45.0 +2021-08-31T00:00:00,2021-09-01T00:00:00,0,nodes,output1,Inflow,46.5 +2021-09-01T00:00:00,2021-09-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-09-02T00:00:00,2021-09-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-09-03T00:00:00,2021-09-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-09-04T00:00:00,2021-09-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-09-05T00:00:00,2021-09-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-09-06T00:00:00,2021-09-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-09-07T00:00:00,2021-09-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-09-08T00:00:00,2021-09-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-09-09T00:00:00,2021-09-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-09-10T00:00:00,2021-09-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-09-11T00:00:00,2021-09-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-09-12T00:00:00,2021-09-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-09-13T00:00:00,2021-09-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-09-14T00:00:00,2021-09-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-09-15T00:00:00,2021-09-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-09-16T00:00:00,2021-09-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-09-17T00:00:00,2021-09-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-09-18T00:00:00,2021-09-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-09-19T00:00:00,2021-09-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-09-20T00:00:00,2021-09-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-09-21T00:00:00,2021-09-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-09-22T00:00:00,2021-09-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-09-23T00:00:00,2021-09-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-09-24T00:00:00,2021-09-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-09-25T00:00:00,2021-09-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-09-26T00:00:00,2021-09-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-09-27T00:00:00,2021-09-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-09-28T00:00:00,2021-09-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-09-29T00:00:00,2021-09-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-09-30T00:00:00,2021-10-01T00:00:00,0,nodes,output1,Inflow,45.0 +2021-10-01T00:00:00,2021-10-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-10-02T00:00:00,2021-10-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-10-03T00:00:00,2021-10-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-10-04T00:00:00,2021-10-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-10-05T00:00:00,2021-10-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-10-06T00:00:00,2021-10-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-10-07T00:00:00,2021-10-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-10-08T00:00:00,2021-10-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-10-09T00:00:00,2021-10-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-10-10T00:00:00,2021-10-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-10-11T00:00:00,2021-10-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-10-12T00:00:00,2021-10-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-10-13T00:00:00,2021-10-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-10-14T00:00:00,2021-10-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-10-15T00:00:00,2021-10-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-10-16T00:00:00,2021-10-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-10-17T00:00:00,2021-10-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-10-18T00:00:00,2021-10-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-10-19T00:00:00,2021-10-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-10-20T00:00:00,2021-10-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-10-21T00:00:00,2021-10-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-10-22T00:00:00,2021-10-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-10-23T00:00:00,2021-10-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-10-24T00:00:00,2021-10-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-10-25T00:00:00,2021-10-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-10-26T00:00:00,2021-10-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-10-27T00:00:00,2021-10-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-10-28T00:00:00,2021-10-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-10-29T00:00:00,2021-10-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-10-30T00:00:00,2021-10-31T00:00:00,0,nodes,output1,Inflow,45.0 +2021-10-31T00:00:00,2021-11-01T00:00:00,0,nodes,output1,Inflow,46.5 +2021-11-01T00:00:00,2021-11-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-11-02T00:00:00,2021-11-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-11-03T00:00:00,2021-11-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-11-04T00:00:00,2021-11-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-11-05T00:00:00,2021-11-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-11-06T00:00:00,2021-11-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-11-07T00:00:00,2021-11-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-11-08T00:00:00,2021-11-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-11-09T00:00:00,2021-11-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-11-10T00:00:00,2021-11-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-11-11T00:00:00,2021-11-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-11-12T00:00:00,2021-11-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-11-13T00:00:00,2021-11-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-11-14T00:00:00,2021-11-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-11-15T00:00:00,2021-11-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-11-16T00:00:00,2021-11-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-11-17T00:00:00,2021-11-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-11-18T00:00:00,2021-11-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-11-19T00:00:00,2021-11-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-11-20T00:00:00,2021-11-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-11-21T00:00:00,2021-11-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-11-22T00:00:00,2021-11-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-11-23T00:00:00,2021-11-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-11-24T00:00:00,2021-11-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-11-25T00:00:00,2021-11-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-11-26T00:00:00,2021-11-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-11-27T00:00:00,2021-11-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-11-28T00:00:00,2021-11-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-11-29T00:00:00,2021-11-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-11-30T00:00:00,2021-12-01T00:00:00,0,nodes,output1,Inflow,45.0 +2021-12-01T00:00:00,2021-12-02T00:00:00,0,nodes,output1,Inflow,1.5 +2021-12-02T00:00:00,2021-12-03T00:00:00,0,nodes,output1,Inflow,3.0 +2021-12-03T00:00:00,2021-12-04T00:00:00,0,nodes,output1,Inflow,4.5 +2021-12-04T00:00:00,2021-12-05T00:00:00,0,nodes,output1,Inflow,6.0 +2021-12-05T00:00:00,2021-12-06T00:00:00,0,nodes,output1,Inflow,7.5 +2021-12-06T00:00:00,2021-12-07T00:00:00,0,nodes,output1,Inflow,9.0 +2021-12-07T00:00:00,2021-12-08T00:00:00,0,nodes,output1,Inflow,10.5 +2021-12-08T00:00:00,2021-12-09T00:00:00,0,nodes,output1,Inflow,12.0 +2021-12-09T00:00:00,2021-12-10T00:00:00,0,nodes,output1,Inflow,13.5 +2021-12-10T00:00:00,2021-12-11T00:00:00,0,nodes,output1,Inflow,15.0 +2021-12-11T00:00:00,2021-12-12T00:00:00,0,nodes,output1,Inflow,16.5 +2021-12-12T00:00:00,2021-12-13T00:00:00,0,nodes,output1,Inflow,18.0 +2021-12-13T00:00:00,2021-12-14T00:00:00,0,nodes,output1,Inflow,19.5 +2021-12-14T00:00:00,2021-12-15T00:00:00,0,nodes,output1,Inflow,21.0 +2021-12-15T00:00:00,2021-12-16T00:00:00,0,nodes,output1,Inflow,22.5 +2021-12-16T00:00:00,2021-12-17T00:00:00,0,nodes,output1,Inflow,24.0 +2021-12-17T00:00:00,2021-12-18T00:00:00,0,nodes,output1,Inflow,25.5 +2021-12-18T00:00:00,2021-12-19T00:00:00,0,nodes,output1,Inflow,27.0 +2021-12-19T00:00:00,2021-12-20T00:00:00,0,nodes,output1,Inflow,28.5 +2021-12-20T00:00:00,2021-12-21T00:00:00,0,nodes,output1,Inflow,30.0 +2021-12-21T00:00:00,2021-12-22T00:00:00,0,nodes,output1,Inflow,31.5 +2021-12-22T00:00:00,2021-12-23T00:00:00,0,nodes,output1,Inflow,33.0 +2021-12-23T00:00:00,2021-12-24T00:00:00,0,nodes,output1,Inflow,34.5 +2021-12-24T00:00:00,2021-12-25T00:00:00,0,nodes,output1,Inflow,36.0 +2021-12-25T00:00:00,2021-12-26T00:00:00,0,nodes,output1,Inflow,37.5 +2021-12-26T00:00:00,2021-12-27T00:00:00,0,nodes,output1,Inflow,39.0 +2021-12-27T00:00:00,2021-12-28T00:00:00,0,nodes,output1,Inflow,40.5 +2021-12-28T00:00:00,2021-12-29T00:00:00,0,nodes,output1,Inflow,42.0 +2021-12-29T00:00:00,2021-12-30T00:00:00,0,nodes,output1,Inflow,43.5 +2021-12-30T00:00:00,2021-12-31T00:00:00,0,nodes,output1,Inflow,45.0 +2021-12-31T00:00:00,2022-01-01T00:00:00,0,nodes,output1,Inflow,46.5 diff --git a/pywr-schema/src/test_models/timeseries.json b/pywr-schema/tests/timeseries.json similarity index 84% rename from pywr-schema/src/test_models/timeseries.json rename to pywr-schema/tests/timeseries.json index 93a0d32e..d082b56e 100644 --- a/pywr-schema/src/test_models/timeseries.json +++ b/pywr-schema/tests/timeseries.json @@ -105,6 +105,26 @@ "url": "inflow.csv" } } + ], + "metric_sets": [ + { + "name": "nodes", + "metrics": [ + { + "type": "Node", + "name": "output1" + } + ] + } + ], + "outputs": [ + { + "name": "nodes", + "type": "CSV", + "format": "long", + "filename": "timeseries-expected.csv", + "metric_set": "nodes" + } ] } } diff --git a/pywr-schema/src/test_models/timeseries_pandas.json b/pywr-schema/tests/timeseries_pandas.json similarity index 100% rename from pywr-schema/src/test_models/timeseries_pandas.json rename to pywr-schema/tests/timeseries_pandas.json diff --git a/pywr-schema/src/test_models/v1/timeseries-converted.json b/pywr-schema/tests/v1/timeseries-converted.json similarity index 100% rename from pywr-schema/src/test_models/v1/timeseries-converted.json rename to pywr-schema/tests/v1/timeseries-converted.json diff --git a/pywr-schema/src/test_models/v1/timeseries.json b/pywr-schema/tests/v1/timeseries.json similarity index 100% rename from pywr-schema/src/test_models/v1/timeseries.json rename to pywr-schema/tests/v1/timeseries.json diff --git a/pywr-schema/src/test_models/wtw1-expected.csv b/pywr-schema/tests/wtw1-expected.csv similarity index 100% rename from pywr-schema/src/test_models/wtw1-expected.csv rename to pywr-schema/tests/wtw1-expected.csv diff --git a/pywr-schema/src/test_models/wtw1.json b/pywr-schema/tests/wtw1.json similarity index 98% rename from pywr-schema/src/test_models/wtw1.json rename to pywr-schema/tests/wtw1.json index d69e24c5..40af1e27 100644 --- a/pywr-schema/src/test_models/wtw1.json +++ b/pywr-schema/tests/wtw1.json @@ -133,7 +133,7 @@ "name": "node-outputs", "type": "CSV", "format": "long", - "filename": "wtw1.csv", + "filename": "wtw1-expected.csv", "metric_set": [ "nodes" ], diff --git a/pywr-schema/src/test_models/wtw2-expected.csv b/pywr-schema/tests/wtw2-expected.csv similarity index 100% rename from pywr-schema/src/test_models/wtw2-expected.csv rename to pywr-schema/tests/wtw2-expected.csv diff --git a/pywr-schema/src/test_models/wtw2.json b/pywr-schema/tests/wtw2.json similarity index 98% rename from pywr-schema/src/test_models/wtw2.json rename to pywr-schema/tests/wtw2.json index bce185c2..2bd09232 100644 --- a/pywr-schema/src/test_models/wtw2.json +++ b/pywr-schema/tests/wtw2.json @@ -105,7 +105,7 @@ "name": "node-outputs", "type": "CSV", "format": "long", - "filename": "wtw2.csv", + "filename": "wtw2-expected.csv", "metric_set": [ "nodes" ],