use mentedb::MenteDb;
use mentedb::prelude::*;
use mentedb_core::types::AgentId;
fn open(dir: &std::path::Path) -> MenteDb {
MenteDb::open(dir).expect("open")
}
fn store_one(db: &MenteDb, content: &str, embedding: Vec<f32>) -> MemoryId {
let node = MemoryNode::new(
AgentId::nil(),
MemoryType::Semantic,
content.to_string(),
embedding,
);
let id = node.id;
db.store(node).expect("store");
id
}
#[test]
fn second_open_of_live_database_is_rejected() {
let dir = tempfile::tempdir().unwrap();
let db1 = open(dir.path());
let second = MenteDb::open(dir.path());
assert!(second.is_err(), "second concurrent open must fail");
let msg = second.err().unwrap().to_string();
assert!(msg.contains("locked"), "error names the lock: {msg}");
db1.close().expect("close");
let db2 = open(dir.path());
db2.simulate_crash();
let db3 = open(dir.path());
db3.close().expect("close");
}
#[test]
fn forget_survives_clean_reopen() {
let dir = tempfile::tempdir().unwrap();
let keep;
let doomed;
{
let db = open(dir.path());
keep = store_one(&db, "memory that stays", vec![0.9, 0.1, 0.0, 0.0]);
doomed = store_one(
&db,
"memory that must not resurrect",
vec![0.1, 0.9, 0.0, 0.0],
);
db.flush().expect("flush");
db.close().expect("close");
}
{
let db = open(dir.path());
assert!(db.get_memory(doomed).is_ok(), "exists before forget");
db.forget(doomed).expect("forget");
assert!(db.get_memory(doomed).is_err(), "gone in same session");
db.close().expect("close");
}
{
let db = open(dir.path());
assert!(db.get_memory(keep).is_ok(), "kept memory survives");
assert!(
db.get_memory(doomed).is_err(),
"forgotten memory resurrected after clean close and reopen"
);
assert_eq!(db.memory_count(), 1);
}
}
#[test]
fn forget_then_flush_survives_reopen() {
let dir = tempfile::tempdir().unwrap();
let keep;
let doomed;
{
let db = open(dir.path());
keep = store_one(&db, "flush test keeper", vec![0.9, 0.1, 0.0, 0.0]);
doomed = store_one(&db, "flush test zombie", vec![0.1, 0.9, 0.0, 0.0]);
db.flush().expect("flush");
db.close().expect("close");
}
{
let db = open(dir.path());
db.forget(doomed).expect("forget");
db.flush().expect("flush after forget");
db.close().expect("close");
}
{
let db = open(dir.path());
assert!(db.get_memory(keep).is_ok(), "kept memory survives");
assert!(
db.get_memory(doomed).is_err(),
"forgotten memory resurrected after forget+flush+reopen"
);
}
}
#[test]
fn forget_then_flush_then_crash_survives_reopen() {
let dir = tempfile::tempdir().unwrap();
let keep;
let doomed;
{
let db = open(dir.path());
keep = store_one(&db, "checkpoint keeper", vec![0.9, 0.1, 0.0, 0.0]);
doomed = store_one(&db, "checkpoint zombie", vec![0.1, 0.9, 0.0, 0.0]);
db.flush().expect("flush");
db.close().expect("close");
}
{
let db = open(dir.path());
db.forget(doomed).expect("forget");
db.flush().expect("flush after forget");
db.simulate_crash();
}
{
let db = open(dir.path());
assert!(db.get_memory(keep).is_ok(), "kept memory survives");
assert!(
db.get_memory(doomed).is_err(),
"forgotten memory resurrected after forget+flush+crash"
);
}
}
#[test]
fn forget_survives_crash_without_close() {
let dir = tempfile::tempdir().unwrap();
let keep;
let doomed;
{
let db = open(dir.path());
keep = store_one(&db, "crash test keeper", vec![0.9, 0.1, 0.0, 0.0]);
doomed = store_one(&db, "crash test zombie candidate", vec![0.1, 0.9, 0.0, 0.0]);
db.flush().expect("flush");
db.close().expect("close");
}
{
let db = open(dir.path());
db.forget(doomed).expect("forget");
db.simulate_crash();
}
{
let db = open(dir.path());
assert!(db.get_memory(keep).is_ok(), "kept memory survives crash");
assert!(
db.get_memory(doomed).is_err(),
"forgotten memory resurrected after crash-style stop"
);
}
}