use figment::Figment;
use figment::providers::Serialized;
use modkit_db::{DbConnConfig, DbManager, GlobalDatabaseConfig, PoolCfg};
use std::collections::HashMap;
use std::time::Duration;
use tempfile::TempDir;
#[tokio::test]
async fn test_dbmanager_sqlite_with_file() {
let temp_dir = TempDir::new().unwrap();
let db_filename = format!("test_manager_{}.db", std::process::id());
let figment = Figment::new().merge(Serialized::defaults(serde_json::json!({
"modules": {
"test_module": {
"database": {
"engine": "sqlite",
"file": db_filename,
"params": {
"journal_mode": "WAL"
}
}
}
}
})));
let home_dir = temp_dir.path().to_path_buf();
let manager = DbManager::from_figment(figment, home_dir).unwrap();
let result = manager.get("test_module").await.unwrap();
assert!(result.is_some());
let db = result.unwrap();
assert_eq!(db.db_engine(), "sqlite");
let expected_path = temp_dir.path().join("test_module").join(&db_filename);
assert!(
expected_path.exists(),
"Expected SQLite file at {}",
expected_path.display()
);
}
#[tokio::test]
async fn test_dbmanager_sqlite_with_path() {
let temp_dir = TempDir::new().unwrap();
let db_path = temp_dir.path().join("absolute.db");
let figment = Figment::new().merge(Serialized::defaults(serde_json::json!({
"modules": {
"test_module": {
"database": {
"engine": "sqlite",
"path": db_path,
"params": {
"journal_mode": "DELETE"
}
}
}
}
})));
let home_dir = temp_dir.path().to_path_buf();
let manager = DbManager::from_figment(figment, home_dir).unwrap();
let result = manager.get("test_module").await.unwrap();
assert!(result.is_some());
let db = result.unwrap();
assert_eq!(db.db_engine(), "sqlite");
assert!(
db_path.exists(),
"Expected SQLite file at {}",
db_path.display()
);
}
#[cfg(feature = "sqlite")]
#[tokio::test]
async fn test_dbmanager_caching() {
let figment = Figment::new().merge(Serialized::defaults(serde_json::json!({
"modules": {
"test_module": {
"database": {
"engine": "sqlite",
"dsn": "sqlite::memory:",
"params": {
"journal_mode": "WAL"
}
}
}
}
})));
let temp_dir = TempDir::new().unwrap();
let home_dir = temp_dir.path().to_path_buf();
let manager = DbManager::from_figment(figment, home_dir).unwrap();
let result1 = manager.get("test_module").await.unwrap();
assert!(result1.is_some());
let result2 = manager.get("test_module").await.unwrap();
assert!(result2.is_some());
let db1 = result1.unwrap();
let db2 = result2.unwrap();
assert_eq!(db1.db_engine(), "sqlite");
assert_eq!(db2.db_engine(), "sqlite");
}
#[tokio::test]
async fn test_dbmanager_sqlite_server_without_dsn() {
let global_config = GlobalDatabaseConfig {
servers: {
let mut servers = HashMap::new();
servers.insert(
"sqlite_server".to_owned(),
DbConnConfig {
engine: Some(modkit_db::config::DbEngineCfg::Sqlite),
params: Some({
let mut params = HashMap::new();
params.insert("WAL".to_owned(), "true".to_owned());
params.insert("synchronous".to_owned(), "NORMAL".to_owned());
params
}),
pool: Some(PoolCfg {
max_conns: Some(10),
acquire_timeout: Some(Duration::from_secs(30)),
..Default::default()
}),
..Default::default() },
);
servers
},
auto_provision: Some(true),
};
let figment = Figment::new().merge(Serialized::defaults(serde_json::json!({
"database": global_config,
"modules": {
"test_module": {
"database": {
"engine": "sqlite",
"server": "sqlite_server",
"file": format!("module_{}.db", std::process::id()) }
}
}
})));
let temp_dir = TempDir::new().unwrap();
let home_dir = temp_dir.path().to_path_buf();
let manager = DbManager::from_figment(figment, home_dir.clone()).unwrap();
let result = manager.get("test_module").await.unwrap();
assert!(result.is_some());
let db = result.unwrap();
assert_eq!(db.db_engine(), "sqlite");
let module_dir = home_dir.join("test_module");
assert!(
module_dir.exists(),
"Module directory should be created at {module_dir:?}"
);
let db_files: Vec<_> = std::fs::read_dir(&module_dir)
.unwrap()
.filter_map(|entry| {
let entry = entry.ok()?;
let path = entry.path();
if path.extension()? == "db" {
Some(path)
} else {
None
}
})
.collect();
assert!(
!db_files.is_empty(),
"At least one .db file should be created in {module_dir:?}"
);
}