feat: harden community production foundation through story 1.5
This commit is contained in:
@@ -1,8 +1,4 @@
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
sync::{Mutex, MutexGuard},
|
||||
time::Duration,
|
||||
};
|
||||
use std::time::Duration;
|
||||
|
||||
use crank_core::{
|
||||
CacheBackend, CacheScope, CacheStoreError, CachedHeader, CachedResponse,
|
||||
@@ -17,62 +13,29 @@ use crank_runtime::{
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
const CACHE_ENV_NAMES: [&str; 3] = [
|
||||
"CRANK_CACHE_BACKEND",
|
||||
"CRANK_CACHE_URL",
|
||||
"CRANK_CACHE_DEFAULT_TTL_MS",
|
||||
];
|
||||
static CACHE_ENV_LOCK: Mutex<()> = Mutex::new(());
|
||||
|
||||
#[test]
|
||||
fn defaults_to_in_memory_cache_without_url() {
|
||||
let config = RuntimeCacheConfig::default();
|
||||
|
||||
assert_eq!(config.backend, CacheBackend::Memory);
|
||||
assert_eq!(config.url, None);
|
||||
assert_eq!(config.default_ttl_ms, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn treats_blank_optional_cache_values_as_unset() {
|
||||
let _env = IsolatedCacheEnv::new();
|
||||
unsafe {
|
||||
std::env::set_var("CRANK_CACHE_URL", " ");
|
||||
std::env::set_var("CRANK_CACHE_DEFAULT_TTL_MS", " ");
|
||||
}
|
||||
|
||||
let config = RuntimeCacheConfig::from_env().unwrap();
|
||||
|
||||
assert_eq!(config.backend, CacheBackend::Memory);
|
||||
assert_eq!(config.url, None);
|
||||
assert_eq!(config.default_ttl_ms, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loads_valkey_config_from_env() {
|
||||
let _env = IsolatedCacheEnv::new();
|
||||
unsafe {
|
||||
std::env::set_var("CRANK_CACHE_BACKEND", "valkey");
|
||||
std::env::set_var("CRANK_CACHE_URL", "redis://cache:6379/0");
|
||||
std::env::set_var("CRANK_CACHE_DEFAULT_TTL_MS", "15000");
|
||||
}
|
||||
|
||||
let config = RuntimeCacheConfig::from_env().unwrap();
|
||||
fn accepts_validated_valkey_values() {
|
||||
let config = RuntimeCacheConfig::try_new(
|
||||
CacheBackend::Valkey,
|
||||
Some("redis://cache:6379/0".to_owned()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(config.backend, CacheBackend::Valkey);
|
||||
assert_eq!(config.url.as_deref(), Some("redis://cache:6379/0"));
|
||||
assert_eq!(config.default_ttl_ms, Some(15_000));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_external_backend_without_url() {
|
||||
let _env = IsolatedCacheEnv::new();
|
||||
unsafe {
|
||||
std::env::set_var("CRANK_CACHE_BACKEND", "redis");
|
||||
std::env::remove_var("CRANK_CACHE_URL");
|
||||
}
|
||||
|
||||
let error = RuntimeCacheConfig::from_env().unwrap_err();
|
||||
let error = RuntimeCacheConfig::try_new(CacheBackend::Redis, None).unwrap_err();
|
||||
|
||||
assert!(matches!(
|
||||
error,
|
||||
@@ -83,59 +46,11 @@ fn rejects_external_backend_without_url() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_zero_ttl() {
|
||||
let _env = IsolatedCacheEnv::new();
|
||||
unsafe {
|
||||
std::env::set_var("CRANK_CACHE_DEFAULT_TTL_MS", "0");
|
||||
}
|
||||
|
||||
let error = RuntimeCacheConfig::from_env().unwrap_err();
|
||||
|
||||
assert!(matches!(
|
||||
error,
|
||||
RuntimeCacheConfigError::ZeroTtl {
|
||||
name: "CRANK_CACHE_DEFAULT_TTL_MS"
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
struct IsolatedCacheEnv {
|
||||
_lock: MutexGuard<'static, ()>,
|
||||
previous: Vec<(&'static str, Option<OsString>)>,
|
||||
}
|
||||
|
||||
impl IsolatedCacheEnv {
|
||||
fn new() -> Self {
|
||||
let lock = CACHE_ENV_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||
let previous = CACHE_ENV_NAMES
|
||||
.iter()
|
||||
.map(|name| (*name, std::env::var_os(name)))
|
||||
.collect();
|
||||
for name in CACHE_ENV_NAMES {
|
||||
unsafe {
|
||||
std::env::remove_var(name);
|
||||
}
|
||||
}
|
||||
Self {
|
||||
_lock: lock,
|
||||
previous,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for IsolatedCacheEnv {
|
||||
fn drop(&mut self) {
|
||||
for (name, value) in &self.previous {
|
||||
unsafe {
|
||||
match value {
|
||||
Some(value) => std::env::set_var(name, value),
|
||||
None => std::env::remove_var(name),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn rejects_url_for_memory_backend() {
|
||||
let error =
|
||||
RuntimeCacheConfig::try_new(CacheBackend::Memory, Some("redis://cache:6379".to_owned()))
|
||||
.unwrap_err();
|
||||
assert!(matches!(error, RuntimeCacheConfigError::UnexpectedUrl));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -410,7 +325,6 @@ fn runtime_cache_stores_report_missing_external_url() {
|
||||
let future = RuntimeCacheStores::from_config(&RuntimeCacheConfig {
|
||||
backend: CacheBackend::Valkey,
|
||||
url: None,
|
||||
default_ttl_ms: None,
|
||||
});
|
||||
|
||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user