#![allow(missing_docs)]
#[cfg(feature = "wal")]
mod session_wal_durability {
use grafeo_common::types::{PropertyKey, Value};
use grafeo_engine::config::StorageFormat;
use grafeo_engine::{Config, GrafeoDB};
#[test]
fn session_create_node_with_props_survives_reopen() {
let dir = tempfile::tempdir().expect("create temp dir");
let path = dir.path().join("testdb");
{
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("open for write");
let mut session = db.session();
session.begin_transaction().expect("begin");
session
.create_node_with_props(&["Probe"], [("name", Value::String("Alix".into()))])
.expect("create node");
session.commit().expect("commit");
drop(session);
db.close().expect("close");
}
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("reopen");
assert_eq!(
db.node_count(),
1,
"node created via Session::create_node_with_props was lost on reopen"
);
}
#[test]
fn session_create_edge_with_props_survives_reopen() {
let dir = tempfile::tempdir().expect("create temp dir");
let path = dir.path().join("testdb");
{
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("open for write");
let alix = db.create_node(&["Person"]);
let gus = db.create_node(&["Person"]);
let mut session = db.session();
session.begin_transaction().expect("begin");
session
.create_edge_with_props(alix, gus, "KNOWS", [("since", Value::Int64(2026))])
.expect("create edge");
session.commit().expect("commit");
drop(session);
db.close().expect("close");
}
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("reopen");
assert_eq!(
db.node_count(),
2,
"anchor nodes lost (DB-direct path should always survive)"
);
assert_eq!(
db.edge_count(),
1,
"edge created via Session::create_edge_with_props was lost on reopen"
);
}
#[test]
fn session_set_node_property_survives_reopen() {
let dir = tempfile::tempdir().expect("create temp dir");
let path = dir.path().join("testdb");
let alix;
{
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("open for write");
alix = db.create_node(&["Person"]);
let mut session = db.session();
session.begin_transaction().expect("begin");
session
.set_node_property(alix, "name", Value::String("Alix".into()))
.expect("set property");
session.commit().expect("commit");
drop(session);
db.close().expect("close");
}
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("reopen");
let node = db.get_node(alix).expect("anchor node lost on reopen");
let name_key = PropertyKey::from("name");
assert_eq!(
node.properties.get(&name_key).cloned(),
Some(Value::String("Alix".into())),
"property set via Session::set_node_property was lost on reopen"
);
}
#[test]
fn session_set_edge_property_survives_reopen() {
let dir = tempfile::tempdir().expect("create temp dir");
let path = dir.path().join("testdb");
let edge_id;
{
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("open for write");
let alix = db.create_node(&["Person"]);
let gus = db.create_node(&["Person"]);
edge_id = db.create_edge(alix, gus, "KNOWS");
let mut session = db.session();
session.begin_transaction().expect("begin");
session
.set_edge_property(edge_id, "since", Value::Int64(2026))
.expect("set edge property");
session.commit().expect("commit");
drop(session);
db.close().expect("close");
}
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("reopen");
let edge = db.get_edge(edge_id).expect("anchor edge lost on reopen");
let since_key = PropertyKey::from("since");
assert_eq!(
edge.properties.get(&since_key).cloned(),
Some(Value::Int64(2026)),
"property set via Session::set_edge_property was lost on reopen"
);
}
#[test]
fn cypher_create_node_with_props_survives_reopen() {
let dir = tempfile::tempdir().expect("create temp dir");
let path = dir.path().join("testdb");
{
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("open for write");
db.execute_language("CREATE (:Probe {name: 'cypher'});", "cypher", None)
.expect("cypher create");
db.close().expect("close");
}
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("reopen");
assert_eq!(
db.node_count(),
1,
"Cypher-created node was lost on reopen (oracle test failed; bug is broader than #327)"
);
}
#[test]
fn session_create_node_no_props_survives_reopen() {
let dir = tempfile::tempdir().expect("create temp dir");
let path = dir.path().join("testdb");
{
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("open for write");
let mut session = db.session();
session.begin_transaction().expect("begin");
session.create_node(&["Probe"]);
session.commit().expect("commit");
drop(session);
db.close().expect("close");
}
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("reopen");
assert_eq!(
db.node_count(),
1,
"node from Session::create_node was lost on reopen"
);
}
#[test]
fn session_create_edge_no_props_survives_reopen() {
let dir = tempfile::tempdir().expect("create temp dir");
let path = dir.path().join("testdb");
{
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("open for write");
let alix = db.create_node(&["Person"]);
let gus = db.create_node(&["Person"]);
let mut session = db.session();
session.begin_transaction().expect("begin");
session.create_edge(alix, gus, "KNOWS");
session.commit().expect("commit");
drop(session);
db.close().expect("close");
}
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("reopen");
assert_eq!(
db.edge_count(),
1,
"edge from Session::create_edge was lost on reopen"
);
}
#[test]
fn session_delete_node_survives_reopen() {
let dir = tempfile::tempdir().expect("create temp dir");
let path = dir.path().join("testdb");
{
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("open for write");
let alix = db.create_node(&["Person"]);
let _gus = db.create_node(&["Person"]);
let mut session = db.session();
session.begin_transaction().expect("begin");
let removed = session.delete_node(alix);
session.commit().expect("commit");
assert!(removed, "delete_node should report it removed alix");
drop(session);
db.close().expect("close");
}
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("reopen");
assert_eq!(
db.node_count(),
1,
"delete via Session::delete_node was not durable across reopen"
);
}
#[test]
fn session_delete_edge_survives_reopen() {
let dir = tempfile::tempdir().expect("create temp dir");
let path = dir.path().join("testdb");
{
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("open for write");
let alix = db.create_node(&["Person"]);
let gus = db.create_node(&["Person"]);
let _kept = db.create_edge(alix, gus, "KNOWS");
let to_delete = db.create_edge(alix, gus, "ALSO_KNOWS");
let mut session = db.session();
session.begin_transaction().expect("begin");
let removed = session.delete_edge(to_delete);
session.commit().expect("commit");
assert!(removed, "delete_edge should report it removed the edge");
drop(session);
db.close().expect("close");
}
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("reopen");
assert_eq!(
db.edge_count(),
1,
"delete via Session::delete_edge was not durable across reopen"
);
}
#[test]
fn session_rollback_does_not_resurrect_on_next_commit() {
let dir = tempfile::tempdir().expect("create temp dir");
let path = dir.path().join("testdb");
{
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("open for write");
let mut session = db.session();
session.begin_transaction().expect("begin tx1");
session
.create_node_with_props(&["RolledBack"], [("name", Value::String("ghost".into()))])
.expect("create rolled-back node");
session.rollback().expect("rollback tx1");
session.begin_transaction().expect("begin tx2");
session
.create_node_with_props(&["Committed"], [("name", Value::String("kept".into()))])
.expect("create committed node");
session.commit().expect("commit tx2");
drop(session);
db.close().expect("close");
}
let config = Config::persistent(&path).with_storage_format(StorageFormat::WalDirectory);
let db = GrafeoDB::with_config(config).expect("reopen");
assert_eq!(
db.node_count(),
1,
"rolled-back node was resurrected by a later commit (TransactionAbort missing from rollback path)"
);
}
}