#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn test_cache_config_default_values() {
let config = CacheConfig::default();
assert_eq!(config.max_memory_mb, 100);
assert!(config.enable_watch);
assert_eq!(config.ast_ttl_secs, 300); assert_eq!(config.template_ttl_secs, 600); assert_eq!(config.dag_ttl_secs, 180); assert_eq!(config.churn_ttl_secs, 1800); assert_eq!(config.git_stats_ttl_secs, 900);
assert!(!config.warmup_on_startup);
assert_eq!(config.warmup_patterns.len(), 3);
assert!(config.warmup_patterns.contains(&"src/**/*.rs".to_string()));
assert!(config.warmup_patterns.contains(&"**/*.ts".to_string()));
assert!(config.warmup_patterns.contains(&"**/*.py".to_string()));
assert!(config.git_cache_by_branch);
assert_eq!(config.git_cache_max_age_days, 7);
assert_eq!(config.parallel_warmup_threads, 4);
assert!(!config.cache_compression);
assert_eq!(config.eviction_batch_size, 10);
}
#[test]
fn test_ast_ttl_conversion() {
let config = CacheConfig::default();
assert_eq!(config.ast_ttl(), Duration::from_secs(300));
let mut custom_config = CacheConfig::default();
custom_config.ast_ttl_secs = 60;
assert_eq!(custom_config.ast_ttl(), Duration::from_secs(60));
}
#[test]
fn test_template_ttl_conversion() {
let config = CacheConfig::default();
assert_eq!(config.template_ttl(), Duration::from_secs(600));
let mut custom_config = CacheConfig::default();
custom_config.template_ttl_secs = 1200;
assert_eq!(custom_config.template_ttl(), Duration::from_secs(1200));
}
#[test]
fn test_dag_ttl_conversion() {
let config = CacheConfig::default();
assert_eq!(config.dag_ttl(), Duration::from_secs(180));
let mut custom_config = CacheConfig::default();
custom_config.dag_ttl_secs = 360;
assert_eq!(custom_config.dag_ttl(), Duration::from_secs(360));
}
#[test]
fn test_churn_ttl_conversion() {
let config = CacheConfig::default();
assert_eq!(config.churn_ttl(), Duration::from_secs(1800));
let mut custom_config = CacheConfig::default();
custom_config.churn_ttl_secs = 3600;
assert_eq!(custom_config.churn_ttl(), Duration::from_secs(3600));
}
#[test]
fn test_git_stats_ttl_conversion() {
let config = CacheConfig::default();
assert_eq!(config.git_stats_ttl(), Duration::from_secs(900));
let mut custom_config = CacheConfig::default();
custom_config.git_stats_ttl_secs = 450;
assert_eq!(custom_config.git_stats_ttl(), Duration::from_secs(450));
}
#[test]
fn test_max_memory_bytes_calculation() {
let config = CacheConfig::default();
assert_eq!(config.max_memory_bytes(), 104_857_600);
let mut custom_config = CacheConfig::default();
custom_config.max_memory_mb = 256;
assert_eq!(custom_config.max_memory_bytes(), 256 * 1024 * 1024);
custom_config.max_memory_mb = 1;
assert_eq!(custom_config.max_memory_bytes(), 1024 * 1024);
custom_config.max_memory_mb = 0;
assert_eq!(custom_config.max_memory_bytes(), 0);
}
#[test]
fn test_from_env_with_no_env_vars() {
std::env::remove_var("PAIML_CACHE_MAX_MB");
std::env::remove_var("PAIML_CACHE_TTL_AST");
std::env::remove_var("PAIML_CACHE_ENABLE_WATCH");
std::env::remove_var("PAIML_CACHE_GIT_BRANCH_AWARE");
let config = CacheConfig::from_env();
assert_eq!(config.max_memory_mb, 100);
assert_eq!(config.ast_ttl_secs, 300);
assert!(config.enable_watch);
assert!(config.git_cache_by_branch);
}
#[test]
fn test_from_env_with_max_mb_override() {
std::env::set_var("PAIML_CACHE_MAX_MB", "512");
let config = CacheConfig::from_env();
assert!(
config.max_memory_mb == 512 || config.max_memory_mb == 100,
"Expected 512 or 100, got {}",
config.max_memory_mb
);
std::env::remove_var("PAIML_CACHE_MAX_MB");
}
#[test]
fn test_from_env_with_invalid_max_mb() {
std::env::set_var("PAIML_CACHE_MAX_MB", "not_a_number");
let config = CacheConfig::from_env();
assert!(
config.max_memory_mb == 100 || config.max_memory_mb == 512,
"Expected 100 or 512, got {}",
config.max_memory_mb
);
std::env::remove_var("PAIML_CACHE_MAX_MB");
}
#[test]
fn test_from_env_with_ast_ttl_override() {
std::env::set_var("PAIML_CACHE_TTL_AST", "120");
let config = CacheConfig::from_env();
let _ = config.ast_ttl_secs; std::env::remove_var("PAIML_CACHE_TTL_AST");
}
#[test]
fn test_from_env_with_invalid_ast_ttl() {
std::env::set_var("PAIML_CACHE_TTL_AST", "invalid");
let config = CacheConfig::from_env();
let _ = config.ast_ttl_secs; std::env::remove_var("PAIML_CACHE_TTL_AST");
}
#[test]
fn test_from_env_enable_watch_true() {
std::env::set_var("PAIML_CACHE_ENABLE_WATCH", "true");
let config = CacheConfig::from_env();
let _ = config.enable_watch;
std::env::remove_var("PAIML_CACHE_ENABLE_WATCH");
}
#[test]
fn test_from_env_enable_watch_false() {
std::env::set_var("PAIML_CACHE_ENABLE_WATCH", "false");
let config = CacheConfig::from_env();
let _ = config.enable_watch;
std::env::remove_var("PAIML_CACHE_ENABLE_WATCH");
}
#[test]
fn test_from_env_enable_watch_one() {
std::env::set_var("PAIML_CACHE_ENABLE_WATCH", "1");
let config = CacheConfig::from_env();
let _ = config.enable_watch;
std::env::remove_var("PAIML_CACHE_ENABLE_WATCH");
}
#[test]
fn test_from_env_enable_watch_zero() {
std::env::set_var("PAIML_CACHE_ENABLE_WATCH", "0");
let config = CacheConfig::from_env();
let _ = config.enable_watch;
std::env::remove_var("PAIML_CACHE_ENABLE_WATCH");
}
#[test]
fn test_from_env_enable_watch_uppercase() {
std::env::set_var("PAIML_CACHE_ENABLE_WATCH", "TRUE");
let config = CacheConfig::from_env();
let _ = config.enable_watch;
std::env::remove_var("PAIML_CACHE_ENABLE_WATCH");
}
#[test]
fn test_from_env_git_branch_aware_true() {
std::env::set_var("PAIML_CACHE_GIT_BRANCH_AWARE", "true");
let config = CacheConfig::from_env();
let _ = config.git_cache_by_branch;
std::env::remove_var("PAIML_CACHE_GIT_BRANCH_AWARE");
}
#[test]
fn test_from_env_git_branch_aware_false() {
std::env::set_var("PAIML_CACHE_GIT_BRANCH_AWARE", "false");
let config = CacheConfig::from_env();
let _ = config.git_cache_by_branch;
std::env::remove_var("PAIML_CACHE_GIT_BRANCH_AWARE");
}
#[test]
fn test_from_env_git_branch_aware_one() {
std::env::set_var("PAIML_CACHE_GIT_BRANCH_AWARE", "1");
let config = CacheConfig::from_env();
assert!(config.git_cache_by_branch);
std::env::remove_var("PAIML_CACHE_GIT_BRANCH_AWARE");
}
#[test]
fn test_cache_config_serialization() {
let config = CacheConfig::default();
let json = serde_json::to_string(&config).unwrap();
assert!(json.contains("\"max_memory_mb\":100"));
assert!(json.contains("\"enable_watch\":true"));
assert!(json.contains("\"ast_ttl_secs\":300"));
}
#[test]
fn test_cache_config_deserialization() {
let json = r#"{
"max_memory_mb": 256,
"enable_watch": false,
"ast_ttl_secs": 120,
"template_ttl_secs": 300,
"dag_ttl_secs": 90,
"churn_ttl_secs": 900,
"git_stats_ttl_secs": 450,
"warmup_on_startup": true,
"warmup_patterns": ["*.rs"],
"git_cache_by_branch": false,
"git_cache_max_age_days": 14,
"parallel_warmup_threads": 8,
"cache_compression": true,
"eviction_batch_size": 20
}"#;
let config: CacheConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.max_memory_mb, 256);
assert!(!config.enable_watch);
assert_eq!(config.ast_ttl_secs, 120);
assert_eq!(config.template_ttl_secs, 300);
assert_eq!(config.dag_ttl_secs, 90);
assert_eq!(config.churn_ttl_secs, 900);
assert_eq!(config.git_stats_ttl_secs, 450);
assert!(config.warmup_on_startup);
assert_eq!(config.warmup_patterns, vec!["*.rs".to_string()]);
assert!(!config.git_cache_by_branch);
assert_eq!(config.git_cache_max_age_days, 14);
assert_eq!(config.parallel_warmup_threads, 8);
assert!(config.cache_compression);
assert_eq!(config.eviction_batch_size, 20);
}
#[test]
fn test_cache_config_roundtrip() {
let original = CacheConfig {
max_memory_mb: 512,
enable_watch: false,
ast_ttl_secs: 60,
template_ttl_secs: 120,
dag_ttl_secs: 30,
churn_ttl_secs: 600,
git_stats_ttl_secs: 300,
warmup_on_startup: true,
warmup_patterns: vec!["**/*.go".to_string(), "**/*.java".to_string()],
git_cache_by_branch: false,
git_cache_max_age_days: 30,
parallel_warmup_threads: 16,
cache_compression: true,
eviction_batch_size: 50,
};
let json = serde_json::to_string(&original).unwrap();
let deserialized: CacheConfig = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.max_memory_mb, original.max_memory_mb);
assert_eq!(deserialized.enable_watch, original.enable_watch);
assert_eq!(deserialized.ast_ttl_secs, original.ast_ttl_secs);
assert_eq!(deserialized.template_ttl_secs, original.template_ttl_secs);
assert_eq!(deserialized.dag_ttl_secs, original.dag_ttl_secs);
assert_eq!(deserialized.churn_ttl_secs, original.churn_ttl_secs);
assert_eq!(deserialized.git_stats_ttl_secs, original.git_stats_ttl_secs);
assert_eq!(deserialized.warmup_on_startup, original.warmup_on_startup);
assert_eq!(deserialized.warmup_patterns, original.warmup_patterns);
assert_eq!(
deserialized.git_cache_by_branch,
original.git_cache_by_branch
);
assert_eq!(
deserialized.git_cache_max_age_days,
original.git_cache_max_age_days
);
assert_eq!(
deserialized.parallel_warmup_threads,
original.parallel_warmup_threads
);
assert_eq!(deserialized.cache_compression, original.cache_compression);
assert_eq!(
deserialized.eviction_batch_size,
original.eviction_batch_size
);
}
#[test]
fn test_cache_config_clone() {
let original = CacheConfig::default();
let cloned = original.clone();
assert_eq!(cloned.max_memory_mb, original.max_memory_mb);
assert_eq!(cloned.enable_watch, original.enable_watch);
assert_eq!(cloned.warmup_patterns, original.warmup_patterns);
}
#[test]
fn test_cache_config_debug() {
let config = CacheConfig::default();
let debug_str = format!("{:?}", config);
assert!(debug_str.contains("CacheConfig"));
assert!(debug_str.contains("max_memory_mb"));
assert!(debug_str.contains("enable_watch"));
}
#[test]
fn test_zero_ttl_values() {
let mut config = CacheConfig::default();
config.ast_ttl_secs = 0;
config.template_ttl_secs = 0;
config.dag_ttl_secs = 0;
config.churn_ttl_secs = 0;
config.git_stats_ttl_secs = 0;
assert_eq!(config.ast_ttl(), Duration::from_secs(0));
assert_eq!(config.template_ttl(), Duration::from_secs(0));
assert_eq!(config.dag_ttl(), Duration::from_secs(0));
assert_eq!(config.churn_ttl(), Duration::from_secs(0));
assert_eq!(config.git_stats_ttl(), Duration::from_secs(0));
}
#[test]
fn test_large_ttl_values() {
let mut config = CacheConfig::default();
config.ast_ttl_secs = u64::MAX;
assert_eq!(config.ast_ttl(), Duration::from_secs(u64::MAX));
}
#[test]
fn test_empty_warmup_patterns() {
let mut config = CacheConfig::default();
config.warmup_patterns = vec![];
assert!(config.warmup_patterns.is_empty());
}
#[test]
fn test_large_memory_configuration() {
let mut config = CacheConfig::default();
config.max_memory_mb = 16384;
assert_eq!(config.max_memory_bytes(), 16384 * 1024 * 1024);
}
}