From cffdc8205b84fd0aa8eee4945b862c6e9d1e7696 Mon Sep 17 00:00:00 2001 From: Alex Snaps Date: Mon, 25 Nov 2024 14:49:35 -0500 Subject: [PATCH] Deal with syntax error of conditions Signed-off-by: Alex Snaps --- limitador-server/src/envoy_rls/server.rs | 15 +- .../src/http_api/request_types.rs | 14 +- limitador-server/src/http_api/server.rs | 3 +- limitador/src/errors.rs | 27 +++- limitador/src/lib.rs | 9 +- limitador/src/limit.rs | 92 +++++++----- limitador/src/storage/disk/rocksdb_storage.rs | 3 +- limitador/src/storage/in_memory.rs | 6 +- limitador/src/storage/keys.rs | 35 +++-- limitador/src/storage/redis/counters_cache.rs | 3 +- limitador/src/storage/redis/redis_cached.rs | 9 +- limitador/tests/integration_tests.rs | 136 +++++++++++------- 12 files changed, 227 insertions(+), 125 deletions(-) diff --git a/limitador-server/src/envoy_rls/server.rs b/limitador-server/src/envoy_rls/server.rs index 51d7e9d3..4eef9151 100644 --- a/limitador-server/src/envoy_rls/server.rs +++ b/limitador-server/src/envoy_rls/server.rs @@ -255,7 +255,8 @@ mod tests { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let limiter = RateLimiter::new(10_000); limiter.add_limit(limit); @@ -394,8 +395,10 @@ mod tests { let namespace = "test_namespace"; vec![ - Limit::new(namespace, 10, 60, vec!["x == '1'"], vec!["z"]), - Limit::new(namespace, 0, 60, vec!["x == '1'", "y == '2'"], vec!["z"]), + Limit::new(namespace, 10, 60, vec!["x == '1'"], vec!["z"]) + .expect("This must be a valid limit!"), + Limit::new(namespace, 0, 60, vec!["x == '1'", "y == '2'"], vec!["z"]) + .expect("This must be a valid limit!"), ] .into_iter() .for_each(|limit| { @@ -459,7 +462,8 @@ mod tests { #[tokio::test] async fn test_takes_into_account_the_hits_addend_param() { let namespace = "test_namespace"; - let limit = Limit::new(namespace, 10, 60, vec!["x == '1'"], vec!["y"]); + let limit = Limit::new(namespace, 10, 60, vec!["x == '1'"], vec!["y"]) + .expect("This must be a valid limit!"); let limiter = RateLimiter::new(10_000); limiter.add_limit(limit); @@ -528,7 +532,8 @@ mod tests { // "hits_addend" is optional according to the spec, and should default // to 1, However, with the autogenerated structs it defaults to 0. let namespace = "test_namespace"; - let limit = Limit::new(namespace, 1, 60, vec!["x == '1'"], vec!["y"]); + let limit = Limit::new(namespace, 1, 60, vec!["x == '1'"], vec!["y"]) + .expect("This must be a valid limit!"); let limiter = RateLimiter::new(10_000); limiter.add_limit(limit); diff --git a/limitador-server/src/http_api/request_types.rs b/limitador-server/src/http_api/request_types.rs index 6f2fb900..1cae899a 100644 --- a/limitador-server/src/http_api/request_types.rs +++ b/limitador-server/src/http_api/request_types.rs @@ -1,9 +1,9 @@ use limitador::counter::Counter as LimitadorCounter; +use limitador::errors::LimitadorError; use limitador::limit::Limit as LimitadorLimit; use paperclip::actix::Apiv2Schema; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; - // We need to define the Limit and Counter types. They're basically the same as // defined in the lib but with some modifications to be able to derive // Apiv2Schema (needed to generate the OpenAPI specs). @@ -41,8 +41,10 @@ impl From<&LimitadorLimit> for Limit { } } -impl From for LimitadorLimit { - fn from(limit: Limit) -> Self { +impl TryFrom for LimitadorLimit { + type Error = LimitadorError; + + fn try_from(limit: Limit) -> Result { let mut limitador_limit = if let Some(id) = limit.id { Self::with_id( id, @@ -51,7 +53,7 @@ impl From for LimitadorLimit { limit.seconds, limit.conditions, limit.variables, - ) + )? } else { Self::new( limit.namespace, @@ -59,14 +61,14 @@ impl From for LimitadorLimit { limit.seconds, limit.conditions, limit.variables, - ) + )? }; if let Some(name) = limit.name { limitador_limit.set_name(name) } - limitador_limit + Ok(limitador_limit) } } diff --git a/limitador-server/src/http_api/server.rs b/limitador-server/src/http_api/server.rs index bc3b91e6..25a1cd76 100644 --- a/limitador-server/src/http_api/server.rs +++ b/limitador-server/src/http_api/server.rs @@ -555,7 +555,8 @@ mod tests { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); match &limiter { Limiter::Blocking(limiter) => limiter.add_limit(limit.clone()), diff --git a/limitador/src/errors.rs b/limitador/src/errors.rs index d5204b62..d590aafa 100644 --- a/limitador/src/errors.rs +++ b/limitador/src/errors.rs @@ -1,18 +1,24 @@ +use crate::limit::ConditionParsingError; use crate::storage::StorageErr; +use std::convert::Infallible; use std::error::Error; use std::fmt::{Display, Formatter}; #[derive(Debug)] pub enum LimitadorError { - Storage(StorageErr), + StorageError(StorageErr), + InterpreterError(ConditionParsingError), } impl Display for LimitadorError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - LimitadorError::Storage(err) => { + LimitadorError::StorageError(err) => { write!(f, "error while accessing the limits storage: {err:?}") } + LimitadorError::InterpreterError(err) => { + write!(f, "error parsing condition: {err:?}") + } } } } @@ -20,13 +26,26 @@ impl Display for LimitadorError { impl Error for LimitadorError { fn source(&self) -> Option<&(dyn Error + 'static)> { match self { - LimitadorError::Storage(err) => Some(err), + LimitadorError::StorageError(err) => Some(err), + LimitadorError::InterpreterError(err) => Some(err), } } } impl From for LimitadorError { fn from(e: StorageErr) -> Self { - Self::Storage(e) + Self::StorageError(e) + } +} + +impl From for LimitadorError { + fn from(err: ConditionParsingError) -> Self { + LimitadorError::InterpreterError(err) + } +} + +impl From for LimitadorError { + fn from(value: Infallible) -> Self { + unreachable!("unexpected infallible value: {:?}", value) } } diff --git a/limitador/src/lib.rs b/limitador/src/lib.rs index 13179e11..69628052 100644 --- a/limitador/src/lib.rs +++ b/limitador/src/lib.rs @@ -73,7 +73,7 @@ //! 60, //! vec!["req.method == 'GET'"], //! vec!["user_id"], -//! ); +//! ).unwrap(); //! let mut rate_limiter = RateLimiter::new(1000); //! //! // Add a limit @@ -105,7 +105,7 @@ //! 60, //! vec!["req.method == 'GET'"], //! vec!["user_id"], -//! ); +//! ).unwrap(); //! rate_limiter.add_limit(limit); //! //! // We've defined a limit of 2. So we can report 2 times before being @@ -169,7 +169,7 @@ //! 60, //! vec!["req.method == 'GET'"], //! vec!["user_id"], -//! ); +//! ).unwrap(); //! //! async { //! let rate_limiter = AsyncRateLimiter::new_with_storage( @@ -708,7 +708,8 @@ mod test { 100, Vec::::default(), Vec::::default(), - ); + ) + .expect("This must be a valid limit!"); rl.add_limit(l.clone()); let limits = rl.get_limits(&namespace.into()); assert_eq!(limits.len(), 1); diff --git a/limitador/src/limit.rs b/limitador/src/limit.rs index 19dcaae7..94b95b1b 100644 --- a/limitador/src/limit.rs +++ b/limitador/src/limit.rs @@ -25,6 +25,8 @@ mod deprecated { } } +use crate::errors::LimitadorError; +use crate::LimitadorResult; #[cfg(feature = "lenient_conditions")] pub use deprecated::check_deprecated_syntax_usages_and_reset; @@ -296,23 +298,26 @@ impl Limit { seconds: u64, conditions: impl IntoIterator, variables: impl IntoIterator>, - ) -> Self + ) -> LimitadorResult where >::Error: core::fmt::Debug, >::Error: core::fmt::Debug, + LimitadorError: From<>::Error>, { // the above where-clause is needed in order to call unwrap(). - Self { - id: None, - namespace: namespace.into(), - max_value, - seconds, - name: None, - conditions: conditions - .into_iter() - .map(|cond| cond.try_into().expect("Invalid condition")) - .collect(), - variables: variables.into_iter().map(|var| var.into()).collect(), + let conditions: Result, _> = + conditions.into_iter().map(|cond| cond.try_into()).collect(); + match conditions { + Ok(conditions) => Ok(Self { + id: None, + namespace: namespace.into(), + max_value, + seconds, + name: None, + conditions, + variables: variables.into_iter().map(|var| var.into()).collect(), + }), + Err(err) => Err(err.into()), } } @@ -323,22 +328,21 @@ impl Limit { seconds: u64, conditions: impl IntoIterator, variables: impl IntoIterator>, - ) -> Self + ) -> LimitadorResult where - >::Error: core::fmt::Debug, - >::Error: core::fmt::Debug, + LimitadorError: From<>::Error>, { - Self { - id: Some(id.into()), - namespace: namespace.into(), - max_value, - seconds, - name: None, - conditions: conditions - .into_iter() - .map(|cond| cond.try_into().expect("Invalid condition")) - .collect(), - variables: variables.into_iter().map(|var| var.into()).collect(), + match conditions.into_iter().map(|cond| cond.try_into()).collect() { + Ok(conditions) => Ok(Self { + id: Some(id.into()), + namespace: namespace.into(), + max_value, + seconds, + name: None, + conditions, + variables: variables.into_iter().map(|var| var.into()).collect(), + }), + Err(err) => Err(err.into()), } } @@ -858,7 +862,8 @@ mod tests { #[test] fn limit_can_have_an_optional_name() { - let mut limit = Limit::new("test_namespace", 10, 60, vec!["x == \"5\""], vec!["y"]); + let mut limit = Limit::new("test_namespace", 10, 60, vec!["x == \"5\""], vec!["y"]) + .expect("This must be a valid limit!"); assert!(limit.name.is_none()); let name = "Test Limit"; @@ -868,7 +873,8 @@ mod tests { #[test] fn limit_applies() { - let limit = Limit::new("test_namespace", 10, 60, vec!["x == \"5\""], vec!["y"]); + let limit = Limit::new("test_namespace", 10, 60, vec!["x == \"5\""], vec!["y"]) + .expect("This must be a valid limit!"); let mut values: HashMap = HashMap::new(); values.insert("x".into(), "5".into()); @@ -879,7 +885,8 @@ mod tests { #[test] fn limit_does_not_apply_when_cond_is_false() { - let limit = Limit::new("test_namespace", 10, 60, vec!["x == \"5\""], vec!["y"]); + let limit = Limit::new("test_namespace", 10, 60, vec!["x == \"5\""], vec!["y"]) + .expect("This must be a valid limit!"); let mut values: HashMap = HashMap::new(); values.insert("x".into(), "1".into()); @@ -891,7 +898,8 @@ mod tests { #[test] #[cfg(feature = "lenient_conditions")] fn limit_does_not_apply_when_cond_is_false_deprecated_style() { - let limit = Limit::new("test_namespace", 10, 60, vec!["x == 5"], vec!["y"]); + let limit = Limit::new("test_namespace", 10, 60, vec!["x == 5"], vec!["y"]) + .expect("This must be a valid limit!"); let mut values: HashMap = HashMap::new(); values.insert("x".into(), "1".into()); @@ -901,7 +909,8 @@ mod tests { assert!(check_deprecated_syntax_usages_and_reset()); assert!(!check_deprecated_syntax_usages_and_reset()); - let limit = Limit::new("test_namespace", 10, 60, vec!["x == foobar"], vec!["y"]); + let limit = Limit::new("test_namespace", 10, 60, vec!["x == foobar"], vec!["y"]) + .expect("This must be a valid limit!"); let mut values: HashMap = HashMap::new(); values.insert("x".into(), "foobar".into()); @@ -914,7 +923,8 @@ mod tests { #[test] fn limit_does_not_apply_when_cond_var_is_not_set() { - let limit = Limit::new("test_namespace", 10, 60, vec!["x == \"5\""], vec!["y"]); + let limit = Limit::new("test_namespace", 10, 60, vec!["x == \"5\""], vec!["y"]) + .expect("This must be a valid limit!"); // Notice that "x" is not set let mut values: HashMap = HashMap::new(); @@ -926,7 +936,8 @@ mod tests { #[test] fn limit_does_not_apply_when_var_not_set() { - let limit = Limit::new("test_namespace", 10, 60, vec!["x == \"5\""], vec!["y"]); + let limit = Limit::new("test_namespace", 10, 60, vec!["x == \"5\""], vec!["y"]) + .expect("This must be a valid limit!"); // Notice that "y" is not set let mut values: HashMap = HashMap::new(); @@ -943,7 +954,8 @@ mod tests { 60, vec!["x == \"5\"", "y == \"2\""], vec!["z"], - ); + ) + .expect("This must be a valid limit!"); let mut values: HashMap = HashMap::new(); values.insert("x".into(), "5".into()); @@ -961,7 +973,8 @@ mod tests { 60, vec!["x == \"5\"", "y == \"2\""], vec!["z"], - ); + ) + .expect("This must be a valid limit!"); let mut values: HashMap = HashMap::new(); values.insert("x".into(), "3".into()); @@ -1045,7 +1058,8 @@ mod tests { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); assert_eq!(limit.id(), Some("test_id")) } @@ -1059,7 +1073,8 @@ mod tests { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let mut limit2 = Limit::new( limit1.namespace.clone(), @@ -1067,7 +1082,8 @@ mod tests { limit1.seconds, limit1.conditions.clone(), limit1.variables.clone(), - ); + ) + .expect("This must be a valid limit!"); limit2.set_name("Who cares?".to_string()); assert_eq!(limit1.partial_cmp(&limit2), Some(Equal)); diff --git a/limitador/src/storage/disk/rocksdb_storage.rs b/limitador/src/storage/disk/rocksdb_storage.rs index 6f2c743d..12aadce0 100644 --- a/limitador/src/storage/disk/rocksdb_storage.rs +++ b/limitador/src/storage/disk/rocksdb_storage.rs @@ -242,7 +242,8 @@ mod tests { #[test] fn opens_db_on_disk() { let namespace = "test_namespace"; - let limit = Limit::new(namespace, 1, 2, vec!["req.method == 'GET'"], vec!["app_id"]); + let limit = Limit::new(namespace, 1, 2, vec!["req.method == 'GET'"], vec!["app_id"]) + .expect("This must be a valid limit!"); let counter = Counter::new(limit, HashMap::default()); let tmp = TempDir::new().expect("We should have a dir!"); diff --git a/limitador/src/storage/in_memory.rs b/limitador/src/storage/in_memory.rs index b01eeb88..3148b6df 100644 --- a/limitador/src/storage/in_memory.rs +++ b/limitador/src/storage/in_memory.rs @@ -252,14 +252,16 @@ mod tests { fn counters_for_multiple_limit_per_ns() { let storage = InMemoryStorage::default(); let namespace = "test_namespace"; - let limit_1 = Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]); + let limit_1 = Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]) + .expect("This must be a valid limit!"); let limit_2 = Limit::new( namespace, 1, 10, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let counter_1 = Counter::new(limit_1, HashMap::default()); let counter_2 = Counter::new(limit_2, HashMap::default()); storage.update_counter(&counter_1, 1).unwrap(); diff --git a/limitador/src/storage/keys.rs b/limitador/src/storage/keys.rs index 037d5f9b..621eb202 100644 --- a/limitador/src/storage/keys.rs +++ b/limitador/src/storage/keys.rs @@ -121,7 +121,8 @@ mod tests { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); assert_eq!( "namespace:{example.com},counters_of_limit:{\"namespace\":\"example.com\",\"seconds\":60,\"conditions\":[\"req.method == \\\"GET\\\"\"],\"variables\":[\"app_id\"]}".as_bytes(), key_for_counters_of_limit(&limit)) @@ -136,7 +137,8 @@ mod tests { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); assert_eq!( "\u{2}\u{7}test_id".as_bytes(), key_for_counters_of_limit(&limit) @@ -146,7 +148,8 @@ mod tests { #[test] fn counter_key_and_counter_are_symmetric() { let namespace = "ns_counter:"; - let limit = Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]); + let limit = Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]) + .expect("This must be a valid limit!"); let counter = Counter::new(limit.clone(), HashMap::default()); let raw = key_for_counter(&counter); assert_eq!(counter, partial_counter_from_counter_key(&raw)); @@ -155,7 +158,8 @@ mod tests { #[test] fn counter_key_does_not_include_transient_state() { let namespace = "ns_counter:"; - let limit = Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]); + let limit = Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]) + .expect("This must be a valid limit!"); let counter = Counter::new(limit.clone(), HashMap::default()); let mut other = counter.clone(); other.set_remaining(123); @@ -268,7 +272,8 @@ pub mod bin { .into_iter() .map(|(var, value)| (var.to_string(), value.to_string())) .collect(); - let limit = Limit::new(ns, u64::default(), seconds, conditions, map.keys()); + let limit = + Limit::new(ns, u64::default(), seconds, conditions, map.keys()).unwrap(); Counter::new(limit, map) } 2u8 => { @@ -286,7 +291,8 @@ pub mod bin { 0, vec![], map.keys(), - ); + ) + .unwrap(); Counter::new(limit, map) } _ => panic!("Unknown version: {}", version), @@ -316,7 +322,7 @@ pub mod bin { .map(|(var, value)| (var.to_string(), value.to_string())) .collect(); let limit = Limit::new(ns, u64::default(), seconds, conditions, map.keys()); - Counter::new(limit, map) + Counter::new(limit.unwrap(), map) } #[cfg(test)] @@ -338,7 +344,8 @@ pub mod bin { 2, vec!["foo == 'bar'"], vec!["app_id", "role", "wat"], - ); + ) + .expect("This must be a valid limit!"); let mut vars = HashMap::default(); vars.insert("role".to_string(), "admin".to_string()); vars.insert("app_id".to_string(), "123".to_string()); @@ -355,7 +362,8 @@ pub mod bin { #[test] fn counter_key_and_counter_are_symmetric() { let namespace = "ns_counter:"; - let limit = Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]); + let limit = Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]) + .expect("This must be a valid limit!"); let mut variables = HashMap::default(); variables.insert("app_id".to_string(), "123".to_string()); let counter = Counter::new(limit.clone(), variables); @@ -366,7 +374,8 @@ pub mod bin { #[test] fn counter_key_starts_with_namespace_prefix() { let namespace = "ns_counter:"; - let limit = Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]); + let limit = Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]) + .expect("This must be a valid limit!"); let counter = Counter::new(limit, HashMap::default()); let serialized_counter = key_for_counter(&counter); @@ -378,7 +387,8 @@ pub mod bin { fn counters_with_id() { let namespace = "ns_counter:"; let limit_without_id = - Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]); + Limit::new(namespace, 1, 1, vec!["req.method == 'GET'"], vec!["app_id"]) + .expect("This must be a valid limit!"); let limit_with_id = Limit::with_id( "id200", namespace, @@ -386,7 +396,8 @@ pub mod bin { 1, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let counter_with_id = Counter::new(limit_with_id, HashMap::default()); let serialized_with_id_counter = key_for_counter(&counter_with_id); diff --git a/limitador/src/storage/redis/counters_cache.rs b/limitador/src/storage/redis/counters_cache.rs index 35152537..52e87136 100644 --- a/limitador/src/storage/redis/counters_cache.rs +++ b/limitador/src/storage/redis/counters_cache.rs @@ -682,7 +682,8 @@ mod tests { 60, vec!["req.method == 'POST'"], vec!["app_id"], - ), + ) + .expect("This must be a valid limit!"), values, ) } diff --git a/limitador/src/storage/redis/redis_cached.rs b/limitador/src/storage/redis/redis_cached.rs index fe47994f..8f1b58dc 100644 --- a/limitador/src/storage/redis/redis_cached.rs +++ b/limitador/src/storage/redis/redis_cached.rs @@ -446,7 +446,8 @@ mod tests { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ), + ) + .expect("This must be a valid limit!"), Default::default(), ); @@ -508,7 +509,8 @@ mod tests { 60, vec!["req.method == 'POST'"], vec!["app_id"], - ), + ) + .expect("This must be a valid limit!"), Default::default(), ); @@ -567,7 +569,8 @@ mod tests { 60, vec!["req.method == 'POST'"], vec!["app_id"], - ), + ) + .expect("This must be a valid limit!"), Default::default(), ); diff --git a/limitador/tests/integration_tests.rs b/limitador/tests/integration_tests.rs index 49fafc45..8c475df4 100644 --- a/limitador/tests/integration_tests.rs +++ b/limitador/tests/integration_tests.rs @@ -222,14 +222,16 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ), + ) + .expect("This must be a valid limit!"), Limit::new( "second_namespace", 20, 60, vec!["req.method == 'GET'"], vec!["app_id"], - ), + ) + .expect("This must be a valid limit!"), ]; for limit in limits { @@ -254,7 +256,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let lim2 = Limit::new( "second_namespace", @@ -262,7 +265,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); for limit in [&lim1, &lim2] { rate_limiter.add_limit(limit).await; @@ -286,7 +290,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -306,7 +311,8 @@ mod test { 60, vec!["req.method == 'GET'"], Vec::::new(), - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -328,7 +334,8 @@ mod test { 60, vec!["req.method == 'POST'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let limit_2 = Limit::new( namespace, @@ -336,7 +343,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit_1).await; rate_limiter.add_limit(&limit_2).await; @@ -355,7 +363,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -372,7 +381,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -407,14 +417,16 @@ mod test { 60, vec!["req.method == 'POST'"], vec!["app_id"], - ), + ) + .expect("This must be a valid limit!"), Limit::new( namespace, 5, 60, vec!["req.method == 'GET'"], vec!["app_id"], - ), + ) + .expect("This must be a valid limit!"), ]; for limit in limits.iter() { @@ -433,16 +445,16 @@ mod test { let namespace2 = "test_namespace_2"; rate_limiter - .add_limit(&Limit::new( - namespace1, - 10, - 60, - vec!["x == '10'"], - vec!["z"], - )) + .add_limit( + &Limit::new(namespace1, 10, 60, vec!["x == '10'"], vec!["z"]) + .expect("This must be a valid limit!"), + ) .await; rate_limiter - .add_limit(&Limit::new(namespace2, 5, 60, vec!["x == '10'"], vec!["z"])) + .add_limit( + &Limit::new(namespace2, 5, 60, vec!["x == '10'"], vec!["z"]) + .expect("This must be a valid limit!"), + ) .await; rate_limiter.delete_limits(namespace1).await.unwrap(); @@ -459,7 +471,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -493,7 +506,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -530,7 +544,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -567,14 +582,16 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ), + ) + .expect("This must be a valid limit!"), Limit::new( namespace, max_hits + 1, 60, vec!["req.method == 'POST'"], vec!["app_id"], - ), + ) + .expect("This must be a valid limit!"), ]; for limit in limits { @@ -635,7 +652,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -670,7 +688,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -693,7 +712,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -747,7 +767,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -771,7 +792,8 @@ mod test { 60, Vec::::new(), // unconditional vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -794,7 +816,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -831,7 +854,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -881,7 +905,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -910,7 +935,8 @@ mod test { 60, Vec::::new(), // unconditional vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -938,7 +964,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -995,7 +1022,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -1016,7 +1044,8 @@ mod test { limit_time, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -1041,7 +1070,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let second_limit = Limit::new( "second_namespace", @@ -1049,7 +1079,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter .configure_with(vec![first_limit.clone(), second_limit.clone()]) @@ -1080,7 +1111,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit).await; @@ -1119,7 +1151,8 @@ mod test { 1, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let limit_to_be_deleted = Limit::new( namespace, @@ -1127,7 +1160,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); for limit in [&limit_to_be_kept, &limit_to_be_deleted].iter() { rate_limiter.add_limit(limit).await; @@ -1153,7 +1187,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let limit_update = Limit::new( namespace, @@ -1161,7 +1196,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); rate_limiter.add_limit(&limit_orig).await; @@ -1185,7 +1221,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let limit_2 = Limit::new( namespace, @@ -1193,7 +1230,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); let mut limit_3 = Limit::new( namespace, @@ -1201,7 +1239,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); limit_3.set_name("Name is irrelevant too".to_owned()); assert!(rate_limiter.add_limit(&limit_1).await); @@ -1230,7 +1269,8 @@ mod test { 60, vec!["req.method == 'GET'"], vec!["app_id"], - ); + ) + .expect("This must be a valid limit!"); for rate_limiter in rate_limiters.iter() { rate_limiter.add_limit(&limit).await;