#![cfg(feature = "testing-statement-injection")]
use grafeo_common::testing::statement_failure::{
with_commit_failure, with_statement_failure_after,
};
use grafeo_engine::GrafeoDB;
fn db() -> GrafeoDB {
GrafeoDB::new_in_memory()
}
#[test]
fn injected_statement_failure_rolls_back_prior_writes_single_schema() {
let db = db();
let session = db.session();
with_statement_failure_after(4, || {
session.execute("START TRANSACTION").unwrap();
session.execute("INSERT (:Item {v: 1})").unwrap();
session.execute("INSERT (:Item {v: 2})").unwrap();
let failing = session.execute("INSERT (:Item {v: 3})");
assert!(
failing.is_err(),
"4th execute should be injected as failure"
);
});
session.execute("ROLLBACK").unwrap();
let remaining = session.execute("MATCH (n:Item) RETURN n").unwrap();
assert_eq!(
remaining.row_count(),
0,
"all in-transaction writes must be undone on ROLLBACK"
);
}
#[test]
fn injected_statement_failure_rolls_back_cross_schema_writes() {
let db = db();
let session = db.session();
session.execute("CREATE SCHEMA alpha").unwrap();
session.execute("CREATE SCHEMA beta").unwrap();
with_statement_failure_after(6, || {
session.execute("START TRANSACTION").unwrap();
session.execute("SESSION SET SCHEMA alpha").unwrap();
session.execute("INSERT (:Row {owner: 'alpha'})").unwrap();
session.execute("SESSION SET SCHEMA beta").unwrap();
session.execute("INSERT (:Row {owner: 'beta'})").unwrap();
let failing = session.execute("SESSION RESET SCHEMA");
assert!(
failing.is_err(),
"6th execute should be injected as failure"
);
});
session.execute("ROLLBACK").unwrap();
session.execute("SESSION SET SCHEMA alpha").unwrap();
let alpha = session.execute("MATCH (n:Row) RETURN n").unwrap();
assert_eq!(
alpha.row_count(),
0,
"alpha writes must be undone by cross-schema rollback after injected failure"
);
session.execute("SESSION SET SCHEMA beta").unwrap();
let beta = session.execute("MATCH (n:Row) RETURN n").unwrap();
assert_eq!(
beta.row_count(),
0,
"beta writes must be undone by cross-schema rollback after injected failure"
);
}
#[test]
fn injected_commit_failure_rolls_back_prior_writes() {
let db = db();
let session = db.session();
with_commit_failure(|| {
session.execute("START TRANSACTION").unwrap();
session.execute("INSERT (:Item {v: 1})").unwrap();
session.execute("INSERT (:Item {v: 2})").unwrap();
let commit_result = session.execute("COMMIT");
assert!(commit_result.is_err(), "injected commit failure expected");
});
let remaining = session.execute("MATCH (n:Item) RETURN n").unwrap();
assert_eq!(
remaining.row_count(),
0,
"injected commit failure must leave no writes visible"
);
}