#![cfg(feature = "async")]
use std::sync::Arc;
use trait_kit::prelude::*;
use dbnexus::integrations::kit::DbNexusModule;
use inklog::integrations::kit::InklogModule;
use limiteron::integrations::kit::LimiteronModule;
use oxcache::integrations::kit::{OxcacheConfig, OxcacheModule};
use sdforge::integrations::kit::SdforgeModule;
fn make_minimal_valid_flow_config() -> limiteron::config::FlowControlConfig {
use limiteron::config::{
Action, ActionConfig, FlowControlConfig, LimiterConfig, Matcher, Rule,
};
let mut config = FlowControlConfig::default();
config.rules.push(Rule {
id: "default".to_string(),
name: "default rule".to_string(),
priority: 0,
matchers: vec![Matcher::Ip {
ip_ranges: vec!["0.0.0.0/0".to_string()],
}],
limiters: vec![LimiterConfig::TokenBucket {
capacity: 100,
refill_rate: 10,
}],
action: ActionConfig {
on_exceed: Action::Reject,
ban: None,
},
});
config
}
fn make_memory_db_config() -> dbnexus::foundation::config::DbConfig {
dbnexus::foundation::config::DbConfig {
url: "sqlite::memory:".to_string(),
max_connections: 5,
min_connections: 1,
..Default::default()
}
}
#[tokio::test]
async fn e2e_full_async_kit_with_all_5_modules() {
let mut kit = AsyncKit::new();
kit.set_config(OxcacheConfig::default());
kit.set_config(make_minimal_valid_flow_config());
kit.set_config(make_memory_db_config());
kit.register::<OxcacheModule>()
.expect("register OxcacheModule");
kit.register::<LimiteronModule>()
.expect("register LimiteronModule");
kit.register::<DbNexusModule>()
.expect("register DbNexusModule");
kit.register::<SdforgeModule>()
.expect("register SdforgeModule");
kit.register::<InklogModule>()
.expect("register InklogModule");
let kit = kit.build().await.expect("AsyncKit::build should succeed");
let _: Arc<dyn oxcache::backend::CacheBackend + Send + Sync> = kit
.require::<OxcacheModule>()
.expect("require OxcacheModule");
let _: Arc<limiteron::governor::Governor> = kit
.require::<LimiteronModule>()
.expect("require LimiteronModule");
let _: Arc<dyn dbnexus::database::pool::ConnectionPool + Send + Sync> = kit
.require::<DbNexusModule>()
.expect("require DbNexusModule");
let _: Arc<dyn sdforge::domain::rate_limiter::ForgeRateLimiter + Send + Sync> = kit
.require::<SdforgeModule>()
.expect("require SdforgeModule");
let _: Arc<dyn inklog::LogDbProvider + Send + Sync> =
kit.require::<InklogModule>().expect("require InklogModule");
assert!(kit.contains::<OxcacheModule>(), "contains OxcacheModule");
assert!(
kit.contains::<LimiteronModule>(),
"contains LimiteronModule"
);
assert!(kit.contains::<DbNexusModule>(), "contains DbNexusModule");
assert!(kit.contains::<SdforgeModule>(), "contains SdforgeModule");
assert!(kit.contains::<InklogModule>(), "contains InklogModule");
assert!(
kit.contains_config::<OxcacheConfig>(),
"contains_config OxcacheConfig"
);
}
#[tokio::test]
async fn e2e_dependency_injection_chain_oxcache_dbnexus_inklog() {
let mut kit = AsyncKit::new();
kit.set_config(OxcacheConfig::default());
kit.set_config(make_memory_db_config());
kit.register::<OxcacheModule>()
.expect("register OxcacheModule");
kit.register::<DbNexusModule>()
.expect("register DbNexusModule");
kit.register::<InklogModule>()
.expect("register InklogModule");
let kit = kit.build().await.expect("AsyncKit::build should succeed");
let provider: Arc<dyn inklog::LogDbProvider + Send + Sync> =
kit.require::<InklogModule>().expect("require InklogModule");
provider
.execute_log("CREATE TABLE IF NOT EXISTS logs (id INTEGER PRIMARY KEY)")
.await
.expect("execute_log should succeed on injected ConnectionPool");
}
#[tokio::test]
async fn e2e_dependency_injection_chain_limiteron_sdforge() {
let mut kit = AsyncKit::new();
kit.set_config(make_minimal_valid_flow_config());
kit.register::<LimiteronModule>()
.expect("register LimiteronModule");
kit.register::<SdforgeModule>()
.expect("register SdforgeModule");
let kit = kit.build().await.expect("AsyncKit::build should succeed");
let limiter: Arc<dyn sdforge::domain::rate_limiter::ForgeRateLimiter + Send + Sync> = kit
.require::<SdforgeModule>()
.expect("require SdforgeModule");
let allowed = limiter
.check("1.2.3.4")
.await
.expect("check should succeed on injected Governor");
assert!(
allowed,
"first request must be allowed (TokenBucket 100 tokens)"
);
}
#[test]
fn e2e_all_modules_satisfy_async_auto_builder_bounds() {
fn assert_bounds<M: AsyncAutoBuilder>() {}
assert_bounds::<OxcacheModule>();
assert_bounds::<LimiteronModule>();
assert_bounds::<DbNexusModule>();
assert_bounds::<SdforgeModule>();
assert_bounds::<InklogModule>();
}