Skip to content

Commit

Permalink
unittests for runtime actions
Browse files Browse the repository at this point in the history
Signed-off-by: Eguzki Astiz Lezaun <[email protected]>
  • Loading branch information
eguzki committed Nov 18, 2024
1 parent b4b1690 commit 7ba5ce9
Show file tree
Hide file tree
Showing 5 changed files with 462 additions and 9 deletions.
31 changes: 31 additions & 0 deletions src/auth_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,34 @@ impl AuthAction {
self.grpc_service.get_failure_mode()
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::configuration::{Action, FailureMode, Service, ServiceType, Timeout};

fn build_auth_action_with_predicates(predicates: Vec<String>) -> AuthAction {
let action = Action {
service: "some_service".into(),
scope: "some_scope".into(),
predicates,
data: Vec::default(),
};

let service = Service {
service_type: ServiceType::Auth,
endpoint: "some_endpoint".into(),
failure_mode: FailureMode::default(),
timeout: Timeout::default(),
};

AuthAction::new(&action, &service)
.expect("action building failed. Maybe predicates compilation?")
}

#[test]
fn empty_predicates_do_apply() {
let auth_action = build_auth_action_with_predicates(Vec::default());
assert!(auth_action.conditions_apply());
}
}
152 changes: 150 additions & 2 deletions src/ratelimit_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::cell::OnceCell;
use std::rc::Rc;

#[derive(Clone, Debug)]
pub struct DescriptorEntryBuilder {
struct DescriptorEntryBuilder {
pub key: String,
pub expression: Expression,
}
Expand Down Expand Up @@ -58,7 +58,7 @@ impl DescriptorEntryBuilder {
}

#[derive(Clone, Debug)]
pub struct ConditionalData {
struct ConditionalData {
pub data: OnceCell<Vec<DescriptorEntryBuilder>>,
pub predicates: OnceCell<Vec<Predicate>>,
}
Expand Down Expand Up @@ -182,3 +182,151 @@ impl RateLimitAction {
.extend_from_slice(&other.conditional_data_sets);
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::configuration::{
Action, DataItem, DataType, ExpressionItem, FailureMode, Service, ServiceType, StaticItem,
Timeout,
};

fn build_service() -> Service {
Service {
service_type: ServiceType::RateLimit,
endpoint: "some_endpoint".into(),
failure_mode: FailureMode::default(),
timeout: Timeout::default(),
}
}

fn build_action(predicates: Vec<String>, data: Vec<DataItem>) -> Action {
Action {
service: "some_service".into(),
scope: "some_scope".into(),
predicates,
data,
}
}

#[test]
fn empty_predicates_do_apply() {
let action = build_action(Vec::default(), Vec::default());
let service = build_service();
let rl_action = RateLimitAction::new(&action, &service)
.expect("action building failed. Maybe predicates compilation?");
assert!(rl_action.conditions_apply());
}

#[test]
fn empty_data_generates_empty_descriptor() {
let action = build_action(Vec::default(), Vec::default());
let service = build_service();
let rl_action = RateLimitAction::new(&action, &service)
.expect("action building failed. Maybe predicates compilation?");
assert_eq!(rl_action.build_descriptor(), RateLimitDescriptor::default());
}

#[test]
fn descriptor_entry_from_expression() {
let data = vec![DataItem {
item: DataType::Expression(ExpressionItem {
key: "key_1".into(),
value: "'value_1'".into(),
}),
}];
let action = build_action(Vec::default(), data);
let service = build_service();
let rl_action = RateLimitAction::new(&action, &service)
.expect("action building failed. Maybe predicates compilation?");
let descriptor = rl_action.build_descriptor();
assert_eq!(descriptor.get_entries().len(), 1);
assert_eq!(descriptor.get_entries()[0].key, String::from("key_1"));
assert_eq!(descriptor.get_entries()[0].value, String::from("value_1"));
}

#[test]
fn descriptor_entry_from_static() {
let data = vec![DataItem {
item: DataType::Static(StaticItem {
key: "key_1".into(),
value: "value_1".into(),
}),
}];
let action = build_action(Vec::default(), data);
let service = build_service();
let rl_action = RateLimitAction::new(&action, &service)
.expect("action building failed. Maybe predicates compilation?");
let descriptor = rl_action.build_descriptor();
assert_eq!(descriptor.get_entries().len(), 1);
assert_eq!(descriptor.get_entries()[0].key, String::from("key_1"));
assert_eq!(descriptor.get_entries()[0].value, String::from("value_1"));
}

#[test]
fn descriptor_entries_not_generated_when_predicates_evaluate_to_false() {
let data = vec![DataItem {
item: DataType::Expression(ExpressionItem {
key: "key_1".into(),
value: "'value_1'".into(),
}),
}];

let predicates = vec!["false".into(), "true".into()];
let action = build_action(predicates, data);
let service = build_service();
let rl_action = RateLimitAction::new(&action, &service)
.expect("action building failed. Maybe predicates compilation?");
assert_eq!(rl_action.build_descriptor(), RateLimitDescriptor::default());
}

#[test]
fn merged_actions_generate_descriptor_entries_for_truthy_predicates() {
let service = build_service();

let data_1 = vec![DataItem {
item: DataType::Expression(ExpressionItem {
key: "key_1".into(),
value: "'value_1'".into(),
}),
}];
let predicates_1 = vec!["true".into()];
let action_1 = build_action(predicates_1, data_1);
let mut rl_action_1 = RateLimitAction::new(&action_1, &service)
.expect("action building failed. Maybe predicates compilation?");

let data_2 = vec![DataItem {
item: DataType::Expression(ExpressionItem {
key: "key_2".into(),
value: "'value_2'".into(),
}),
}];
let predicates_2 = vec!["false".into()];
let action_2 = build_action(predicates_2, data_2);
let rl_action_2 = RateLimitAction::new(&action_2, &service)
.expect("action building failed. Maybe predicates compilation?");

let data_3 = vec![DataItem {
item: DataType::Expression(ExpressionItem {
key: "key_3".into(),
value: "'value_3'".into(),
}),
}];
let predicates_3 = vec!["true".into()];
let action_3 = build_action(predicates_3, data_3);
let rl_action_3 = RateLimitAction::new(&action_3, &service)
.expect("action building failed. Maybe predicates compilation?");

rl_action_1.merge(&rl_action_2);
rl_action_1.merge(&rl_action_3);

// it should generate descriptor entries from action 1 and action 3

let descriptor = rl_action_1.build_descriptor();
assert_eq!(descriptor.get_entries().len(), 2);
assert_eq!(descriptor.get_entries()[0].key, String::from("key_1"));
assert_eq!(descriptor.get_entries()[0].value, String::from("value_1"));
assert_eq!(descriptor.get_entries()[1].key, String::from("key_3"));
assert_eq!(descriptor.get_entries()[1].value, String::from("value_3"));
}
}
48 changes: 48 additions & 0 deletions src/runtime_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,51 @@ impl RuntimeAction {
self.grpc_service().get_service_type()
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::configuration::{Action, FailureMode, ServiceType, Timeout};

fn build_auth_action_with_predicates(predicates: Vec<String>) -> RuntimeAction {
build_action_with_predicates(ServiceType::Auth, predicates)
}

fn build_rl_action_with_predicates(predicates: Vec<String>) -> RuntimeAction {
build_action_with_predicates(ServiceType::Auth, predicates)
}

fn build_action_with_predicates(
service_type: ServiceType,
predicates: Vec<String>,
) -> RuntimeAction {
let action = Action {
service: "some_service".into(),
scope: "some_scope".into(),
predicates,
data: Vec::default(),
};

let service = Service {
service_type,
endpoint: "some_endpoint".into(),
failure_mode: FailureMode::default(),
timeout: Timeout::default(),
};

let mut services = HashMap::new();
services.insert(String::from("some_service"), service);

RuntimeAction::new(&action, &services)
.expect("runtime action building failed. Maybe prodicates compilation?")
}

#[test]
fn empty_predicates_do_apply() {
let auth_action = build_auth_action_with_predicates(Vec::default());
assert!(auth_action.conditions_apply());

let rl_action = build_rl_action_with_predicates(Vec::default());
assert!(rl_action.conditions_apply());
}
}
Loading

0 comments on commit 7ba5ce9

Please sign in to comment.