use memory databases for e2e tests

This commit is contained in:
2026-08-07 23:20:27 -04:00
parent f480407927
commit a13bc17629
3 changed files with 33 additions and 34 deletions
+20 -14
View File
@@ -39,26 +39,32 @@ impl SqliteDatabase {
Ok(Self { pool })
}
#[cfg(test)]
/// Opens an in-memory database. Every connection in the pool shares the same
/// in-memory database via a named shared-cache database, so the schema and
/// data are visible across the whole pool. Nothing is persisted to disk.
pub async fn open_in_memory() -> DomainResult<Self> {
// A pool of `:memory:` connections would each get a separate database,
// so use a unique temporary file that shares the schema across the pool.
// A plain `:memory:` database is private to each connection, so a pool
// would get a separate database per connection. Use a uniquely-named
// shared-cache in-memory database instead so the whole pool shares one.
//
// The name must be unique per call: shared-cache in-memory databases are
// keyed by name, so two calls with the same name within a process would
// resolve to the same database and share state. This matters for the
// unit tests, which run many `open_in_memory()` calls in parallel within
// a single process and need isolation from each other. The counter makes
// each call unique. (Shared-cache and in-memory databases are per-process,
// so there is no cross-process collision to guard against.)
use std::sync::atomic::{AtomicU64, Ordering};
static COUNTER: AtomicU64 = AtomicU64::new(0);
let unique = COUNTER.fetch_add(1, Ordering::Relaxed);
let path = std::env::temp_dir().join(format!(
"sustenance-test-{}-{}-{}.db",
std::process::id(),
now(),
unique
));
let path = path.to_str().unwrap();
let filename = format!("file:sustenance-in-memory-{}", unique);
let options = SqliteConnectOptions::new()
.filename(path)
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
.filename(filename)
.in_memory(true)
.shared_cache(true)
.journal_mode(sqlx::sqlite::SqliteJournalMode::Memory)
.foreign_keys(true)
.busy_timeout(std::time::Duration::from_secs(5))
.create_if_missing(true);
.busy_timeout(std::time::Duration::from_secs(5));
let pool = SqlitePool::connect_with(options).await.map_err(db_error)?;
MIGRATOR.run(&pool).await.map_err(migrate_error)?;
seed_default_categories(&pool).await?;